/* * JBoss, Home of Professional Open Source. * * See the LEGAL.txt file distributed with this work for information regarding copyright ownership and licensing. * * See the AUTHORS.txt file distributed with this work for a full listing of individual contributors. */ package org.teiid.designer.ui; import static org.teiid.designer.ui.UiConstants.TableEditorAttributes.COLUMN_ORDER; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.IPath; import org.eclipse.emf.common.notify.Notification; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.resource.ImageRegistry; import org.eclipse.jface.util.IPropertyChangeListener; import org.eclipse.jface.util.PropertyChangeEvent; import org.eclipse.jface.viewers.ISelection; import org.eclipse.swt.graphics.Image; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.ISelectionListener; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchPart; import org.osgi.framework.BundleContext; import org.teiid.core.designer.PluginUtil; import org.teiid.core.designer.event.EventBroker; import org.teiid.core.designer.event.SynchEventBroker; import org.teiid.core.designer.util.PluginUtilImpl; import org.teiid.designer.core.ModelerCore; import org.teiid.designer.core.notification.util.NotificationUtilities; import org.teiid.designer.core.workspace.ModelResource; import org.teiid.designer.core.workspace.ModelWorkspaceManager; import org.teiid.designer.core.workspace.ModelWorkspaceNotification; import org.teiid.designer.core.workspace.ModelWorkspaceNotificationListener; import org.teiid.designer.ui.actions.ModelerActionService; import org.teiid.designer.ui.common.AbstractUiPlugin; import org.teiid.designer.ui.common.PreferenceKeyAndDefaultValue; import org.teiid.designer.ui.common.actions.ActionService; import org.teiid.designer.ui.common.product.ProductCustomizerMgr; import org.teiid.designer.ui.editors.ModelEditorProjectListener; import org.teiid.designer.ui.event.ModelResourceEvent; import org.teiid.designer.ui.favorites.EObjectModelerCache; import org.teiid.designer.ui.product.IModelerProductContexts; import org.teiid.designer.ui.table.EObjectPropertiesOrderPreferences; import org.teiid.designer.ui.undo.ModelerUndoManager; import org.teiid.designer.ui.viewsupport.ModelerNotificationHelper; /** * The main plugin class to be used in the desktop. * * @since 8.0 */ public final class UiPlugin extends AbstractUiPlugin implements PluginConstants, UiConstants, IModelerProductContexts { // The shared instance. private static UiPlugin plugin; /** * Returns the shared instance. * * @since 4.0 */ public static UiPlugin getDefault() { return UiPlugin.plugin; } // This plugin's EventBroker. private EventBroker eventBroker; private EObjectModelerCache eObjCache; // The previous selection in this plugin's workbench ISelection cachedSelection = null; private final ModelEditorProjectListener projectListener = new ModelEditorProjectListener(); private EObjectPropertiesOrderPreferences eObjectPropertiesOrderPreferences; private ModelerActionService service; private IPropertyChangeListener tablePrefPropListener; /** * The constructor. * * @since 4.0 */ public UiPlugin() { UiPlugin.plugin = this; } private void addToRegistry(ImageRegistry registry, final String imagePath) { registry.put(imagePath, getImageDescriptor(imagePath)); } @Override protected void initializeImageRegistry(ImageRegistry registry) { super.initializeImageRegistry(registry); /* * Initilialise these descriptors since they are required frequently and from app start */ addToRegistry(registry, Images.EDIT_DOCUMENT_ICON); addToRegistry(registry, Images.TEIID_SERVER_DEFAULT_ICON); addToRegistry(registry, Images.TEIID_SERVER_DISCONNECTED_ICON); addToRegistry(registry, Images.ERROR_DECORATOR); addToRegistry(registry, Images.WARNING_DECORATOR); addToRegistry(registry, Images.EXTENSION_DECORATOR); addToRegistry(registry, Images.PREVIEWABLE_DECORATOR); } /** * @see org.teiid.designer.ui.common.AbstractUiPlugin#createActionService(org.eclipse.ui.IWorkbenchPage) * @since 4.0 */ @Override protected ActionService createActionService( final IWorkbenchPage page ) { if (this.service == null) { page.getWorkbenchWindow().getSelectionService().addSelectionListener(new ViewSelectionCache()); this.service = new ModelerActionService(page); this.service.initializeGlobalActions(); } return this.service; } public void extractModelTableColumnUtilsToPreferenceStore() { getPreferenceStore().setValue(COLUMN_ORDER, getEObjectPropertiesOrderPreferences().toString()); } /** * Obtains the cache used to hold {@link org.eclipse.emf.ecore.EObject}s. * * @return the shared cache * @since 4.2 */ public EObjectModelerCache getEObjectCache() { if (this.eObjCache == null) this.eObjCache = new EObjectModelerCache(); return this.eObjCache; } public EObjectPropertiesOrderPreferences getEObjectPropertiesOrderPreferences() { if (this.eObjectPropertiesOrderPreferences == null) { this.eObjectPropertiesOrderPreferences = new EObjectPropertiesOrderPreferences(); this.tablePrefPropListener = new IPropertyChangeListener() { @Override public void propertyChange( PropertyChangeEvent event ) { // update if new prefs have been imported if (event.getProperty().equals(COLUMN_ORDER)) { initializeModelTableColumnUtilsFromPreferenceStore(); } } }; getPreferenceStore().addPropertyChangeListener(this.tablePrefPropListener); } return this.eObjectPropertiesOrderPreferences; } public ImageDescriptor getErrorDecoratorImage() { ImageRegistry imageRegistry = plugin.getImageRegistry(); return imageRegistry.getDescriptor(Images.ERROR_DECORATOR); } public EventBroker getEventBroker() { if (this.eventBroker == null) eventBroker = new SynchEventBroker(); // only visible in debug return eventBroker; } /** * @see org.teiid.designer.ui.common.AbstractUiPlugin#getPluginUtil() * @since 4.0 */ @Override public PluginUtil getPluginUtil() { return Util; } /** * Return the last selection that occurred in a ViewPart (rather than in an editor). * * @return */ public ISelection getPreviousViewSelection() { return cachedSelection; } public Image getProjectImage() { return getImage(Images.MODEL_PROJECT); } public Image getSimpleProjectImage() { return getImage(Images.SIMPLE_PROJECT); } public ImageDescriptor getWarningDecoratorImage() { ImageRegistry imageRegistry = plugin.getImageRegistry(); return imageRegistry.getDescriptor(Images.WARNING_DECORATOR); } public ImageDescriptor getExtensionDecoratorImage() { ImageRegistry imageRegistry = plugin.getImageRegistry(); return imageRegistry.getDescriptor(Images.EXTENSION_DECORATOR); } public ImageDescriptor getPreviewableDecoratorImage() { ImageRegistry imageRegistry = plugin.getImageRegistry(); return imageRegistry.getDescriptor(Images.PREVIEWABLE_DECORATOR); } /** * @return * @since 4.0 */ public static void registerActionForSelection( ISelectionListener action ) { ActionService actionService = UiPlugin.getDefault().getActionService(UiPlugin.getDefault().getCurrentWorkbenchWindow().getActivePage()); actionService.addWorkbenchSelectionListener(action); } /** * @return * @since 4.0 */ public static void unregisterActionForSelection( ISelectionListener action ) { ActionService actionService = UiPlugin.getDefault().getActionService(UiPlugin.getDefault().getCurrentWorkbenchWindow().getActivePage()); actionService.removeWorkbenchSelectionListener(action); } void initializeModelTableColumnUtilsFromPreferenceStore() { getEObjectPropertiesOrderPreferences().initializeFromString(getPreferenceStore().getString(COLUMN_ORDER)); } /** * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext) * @since 5.0 */ @Override public void start( final BundleContext context ) throws Exception { super.start(context); // Initialize logging/i18n utility ((PluginUtilImpl)Util).initializePlatformLogger(this); // Initialize product customizer try { ProductCustomizerMgr.getInstance().loadCustomizations(); } catch (final Exception theException) { // just log. no need to stop plugin startup for customization problem Util.log(theException); } // Initialize the ModelerUndoManager ModelerUndoManager.getInstance(); // Initialize the ModelEditorProjectListener ModelerCore.getWorkspace().addResourceChangeListener(projectListener); // Initialize the NotificationUtilities INotificationHandler to the modeler; NotificationUtilities.setNotificationHelper(new ModelerNotificationHelper()); // Initialize the ModelWorkspaceManager ModelWorkspaceManager.getModelWorkspaceManager(); // Register a listener for ModelWorkspaceNotifications ... final ModelWorkspaceNotificationListener modelWsListener = new ModelWorkspaceNotificationListener() { protected ModelResource getModelResource( final Notification notification ) { final IResource resource = (IResource)notification.getNotifier(); return ModelerCore.getModelWorkspace().findModelResource(resource); } @Override public void notifyAdd( final ModelWorkspaceNotification notification ) { // act on event only if a "final," after-change event: if (notification.isPostChange()) { final ModelResource modelResource = getModelResource(notification); // Fire an event ...if the modelResource != null if (modelResource != null) { final ModelResourceEvent event = new ModelResourceEvent(modelResource, ModelResourceEvent.ADDED, this); UiPlugin.getDefault().getEventBroker().processEvent(event); } // endif -- mRes found } // endif -- isPostChange } @Override public void notifyChanged( final Notification notification ) { if (notification instanceof ModelWorkspaceNotification && ((ModelWorkspaceNotification)notification).isPreAutoBuild()) { final ModelResource modelResource = getModelResource(notification); // Fire a closing event ...if the modelResource != null if (modelResource != null) { final ModelResourceEvent event = new ModelResourceEvent(modelResource, ModelResourceEvent.CHANGED, this); UiPlugin.getDefault().getEventBroker().processEvent(event); } } } @Override public void notifyClean( final IProject proj ) { // Project clean does nothing here... } @Override public void notifyClosing( final ModelWorkspaceNotification notification ) { final ModelResource modelResource = getModelResource(notification); // Fire a closing event ...if the modelResource != null if (modelResource != null) { final ModelResourceEvent event = new ModelResourceEvent(modelResource, ModelResourceEvent.CLOSING, this); UiPlugin.getDefault().getEventBroker().processEvent(event); } } @Override public void notifyMove( final ModelWorkspaceNotification notification ) { // act on event only if a "final," after-change event: if (notification.isPostChange()) { final ModelResource modelResource = getModelResource(notification); // Fire an event ...if the modelResource != null if (modelResource != null) { /* * - use a new kind of ModelResourceEvent for Move and Rename, that takes an extra * IPath parm representing the Old path, * - Old path is: notification.getDelta().getMovedFromPath() * - Then go to the code that handles MOVED (see VdbView.java) */ final IPath oldPath = notification.getDelta().getMovedFromPath(); final ModelResourceEvent event = new ModelResourceEvent(modelResource, ModelResourceEvent.MOVED, this, oldPath); UiPlugin.getDefault().getEventBroker().processEvent(event); } // endif -- mRes found } // endif -- isPostChange } @Override public void notifyOpen( final ModelWorkspaceNotification notification ) { final ModelResource modelResource = getModelResource(notification); // Fire an opening event ...if the modelResource != null if (modelResource != null) { final ModelResourceEvent event = new ModelResourceEvent(modelResource, ModelResourceEvent.OPENED, this); UiPlugin.getDefault().getEventBroker().processEvent(event); } } @Override public void notifyReloaded( final ModelWorkspaceNotification notification ) { final ModelResource modelResource = getModelResource(notification); // Fire a closing event ...if the modelResource != null if (modelResource != null) { final ModelResourceEvent event = new ModelResourceEvent(modelResource, ModelResourceEvent.RELOADED, this); UiPlugin.getDefault().getEventBroker().processEvent(event); } } @Override public void notifyRemove( final ModelWorkspaceNotification notification ) { // act on event only if a "final," after-change event: if (notification.isPostChange()) { final Object notifier = notification.getNotifier(); if (notifier instanceof IResource) { // don't bother trying to get the ModelResource.. doesn't exist. // use the source instead: final IResource srcFile = (IResource)notifier; final ModelResourceEvent event = new ModelResourceEvent(srcFile, ModelResourceEvent.REMOVED, this); UiPlugin.getDefault().getEventBroker().processEvent(event); } // endif -- ifile instance } // endif -- isPostChange } @Override public void notifyRename( final ModelWorkspaceNotification notification ) { // act on event only if a "final," after-change event: if (notification.isPostChange()) { final ModelResource modelResource = getModelResource(notification); // Fire an event ...if the modelResource != null if (modelResource != null) { /* * - use a new kind of ModelResourceEvent for Move and Rename, that takes an extra * IPath parm representing the Old path, * - Old path is: notification.getDelta().getMovedFromPath() * - Then go to the code that handles MOVED (see VdbView.java) */ final IPath oldPath = notification.getDelta().getMovedFromPath(); final ModelResourceEvent event = new ModelResourceEvent(modelResource, ModelResourceEvent.MOVED, this, oldPath); UiPlugin.getDefault().getEventBroker().processEvent(event); } // endif -- mRes found } // endif -- isPostChange } }; ModelerCore.getModelWorkspace().addNotificationListener(modelWsListener); // Store default preference values if necessary storeDefaultPreferenceValues(); initializeModelTableColumnUtilsFromPreferenceStore(); } /** * {@inheritDoc} * * @see org.teiid.designer.ui.common.AbstractUiPlugin#stop(org.osgi.framework.BundleContext) */ @Override public void stop( final BundleContext context ) throws Exception { // unregister property change listener before saving table prefs if (this.tablePrefPropListener != null) { getPreferenceStore().removePropertyChangeListener(this.tablePrefPropListener); } extractModelTableColumnUtilsToPreferenceStore(); ModelerCore.getWorkspace().removeResourceChangeListener(projectListener); super.stop(context); } private void storeDefaultPreferenceValues() { // Store default values of preferences. Needs to be done once. Does not change current // values of preferences if any are already stored. final IPreferenceStore preferenceStore = UiPlugin.getDefault().getPreferenceStore(); for (final PreferenceKeyAndDefaultValue element : PluginConstants.Prefs.General.PREFERENCES) PreferenceKeyAndDefaultValue.storePreferenceDefault(preferenceStore, element); UiPlugin.getDefault().savePreferences(); } /** * SelectionCache is a mechanism for hanging onto the previous selection. This was implemented for the active help actions, * since clicking on active help in the welcome page fires a selection that overrides a desired selection elsewhere in the * workbench. */ class ViewSelectionCache implements ISelectionListener { @Override public void selectionChanged( final IWorkbenchPart part, final ISelection selection ) { if (!(part instanceof IEditorPart)) cachedSelection = selection; } } }