package com.cedarsoft.spring;
import com.cedarsoft.lookup.DynamicLookup;
import com.cedarsoft.lookup.Lookups;
import com.cedarsoft.spring.rcp.prefetch.Prefetcher;
import com.cedarsoft.spring.rcp.async.BackgroundAction;
import com.cedarsoft.spring.rcp.async.BlockingBackgroundActionRunner;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.springframework.binding.convert.ConversionService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.NoSuchMessageException;
import org.springframework.richclient.application.Application;
import org.springframework.richclient.application.ApplicationServices;
import org.springframework.richclient.application.ApplicationServicesLocator;
import org.springframework.richclient.application.ApplicationWindow;
import org.springframework.richclient.application.ServiceNotFoundException;
import org.springframework.richclient.application.docking.jide.editor.OpenEditorEvent;
import org.springframework.richclient.application.event.LifecycleApplicationEvent;
import org.springframework.richclient.command.config.CommandConfigurer;
import org.springframework.richclient.factory.ComponentFactory;
import javax.swing.SwingUtilities;
import java.util.Locale;
/**
* Offers some methods (delegating) with convinience spring access
*/
public class SpringSupport {
private static final Log log = LogFactory.getLog( SpringSupport.class );
@NotNull
public static final SpringSupport INSTANCE = new SpringSupport();
@NotNull
public CommandConfigurer getCommandConfigurer() {
return getService( CommandConfigurer.class );
}
@NotNull
public ConversionService getConversionService() {
return getService( ConversionService.class );
}
@NotNull
public ComponentFactory getComponentFactory() {
return getService( ComponentFactory.class );
}
@NotNull
public String getMessageStrip( @NotNull @NonNls String messageCode, @Nullable Object... args ) {
ApplicationContext applicationContext = getApplicationContext();
Locale locale = Locale.getDefault();
String actual = messageCode;
while ( actual != null ) {
try {
return applicationContext.getMessage( actual, args, locale );
} catch ( NoSuchMessageException ignore ) {
}
int pointIndex = actual.indexOf( '.' );
if ( pointIndex < 0 ) {
break;
}
actual = actual.substring( pointIndex + 1 );
}
return messageCode; //nothing more to strip...
}
@NotNull
public String getMessage( @NotNull @NonNls String messageCode ) {
return getMessageStrip( messageCode );
}
@NotNull
public String getMessage( @NotNull @NonNls Enum<?> enumeration ) {
String key = enumeration.getDeclaringClass().getName() + '.' + enumeration.name();
return getMessage( key );
}
@NotNull
public String getMessage( @NotNull @NonNls String messageCode, Object... args ) {
return getMessageStrip( messageCode, args );
}
@NotNull
public <S> S getService( Class<S> serviceType ) throws ServiceNotFoundException {
return serviceType.cast( getApplicationServices().getService( serviceType ) );
}
@NotNull
public ApplicationServices getApplicationServices() {
return ApplicationServicesLocator.services();
}
@NotNull
public Application getApplication() {
return Application.instance();
}
@NotNull
public ApplicationContext getApplicationContext() {
return getApplication().getApplicationContext();
}
public void publishEvent( @NotNull ApplicationEvent event ) {
getApplicationContext().publishEvent( event );
}
public void publishCreated( @NotNull Object object ) {
publishEvent( new LifecycleApplicationEvent( LifecycleApplicationEvent.CREATED, object ) );
}
public void publishDeleted( @NotNull Object object ) {
publishEvent( new LifecycleApplicationEvent( LifecycleApplicationEvent.DELETED, object ) );
}
public void publishModified( @NotNull Object object ) {
publishEvent( new LifecycleApplicationEvent( LifecycleApplicationEvent.MODIFIED, object ) );
}
public void openEditor( @NotNull final Object editorRoot ) {
//Prefetch it
final BlockingBackgroundActionRunner actionRunner = new BlockingBackgroundActionRunner( getApplication().getActiveWindow(), new BackgroundAction( "prefetching.data" ) {
@Override
protected void executeInBackground() throws Exception {
prepareOpenEditor( editorRoot );
}
@Override
protected void finished() {
//First get the object (from terracotta)
log.info( "----> Opening Editor for " + editorRoot );
publishEvent( new OpenEditorEvent( editorRoot ) );
}
} );
SwingUtilities.invokeLater( new Runnable() {
@Override
public void run() {
actionRunner.run();
}
} );
}
/**
* Is called before the editor is opened
*
* @param editorRoot the editor root the editor will be opened for
*/
protected void prepareOpenEditor( @NotNull Object editorRoot ) {
try {
getService( Prefetcher.class ).prefetch( editorRoot );
} catch ( ServiceNotFoundException ignore ) {
}
}
/**
* Returns the active window
*
* @return the active window
*/
@NotNull
public ApplicationWindow getActiveApplicationWindow() {
return getApplication().getActiveWindow();
}
/**
* Creates the default context with the active application window
*
* @return the context
*/
@NotNull
public static DynamicLookup createDefaultContext() { //todo rename
return Lookups.dynamicLookup( INSTANCE.getActiveApplicationWindow().getControl() );
}
}