/* * 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.explorer; import java.io.File; import java.util.HashSet; import java.util.Set; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IMarkerDelta; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResourceChangeEvent; import org.eclipse.core.resources.IResourceChangeListener; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.ListenerList; import org.eclipse.emf.ecore.EObject; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.viewers.IBaseLabelProvider; import org.eclipse.jface.viewers.IDecoration; import org.eclipse.jface.viewers.ILabelProvider; import org.eclipse.jface.viewers.ILabelProviderListener; import org.eclipse.jface.viewers.ILightweightLabelDecorator; import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.jface.viewers.LabelProviderChangedEvent; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.widgets.Display; import org.eclipse.ui.model.WorkbenchLabelProvider; import org.teiid.core.designer.util.StringConstants; import org.teiid.designer.core.ModelerCore; import org.teiid.designer.core.workspace.ModelUtil; import org.teiid.designer.extension.ExtensionPlugin; import org.teiid.designer.extension.definition.ModelExtensionAssistant; import org.teiid.designer.extension.definition.ModelObjectExtensionAssistant; import org.teiid.designer.extension.registry.ModelExtensionRegistry; import org.teiid.designer.metamodels.diagram.Diagram; import org.teiid.designer.metamodels.transformation.TransformationMappingRoot; import org.teiid.designer.ui.PluginConstants; import org.teiid.designer.ui.UiConstants; import org.teiid.designer.ui.UiPlugin; import org.teiid.designer.ui.common.product.ProductCustomizerMgr; import org.teiid.designer.ui.viewsupport.DiagramLabelProvider; import org.teiid.designer.ui.viewsupport.ExtendedModelObjectLabelProvider; import org.teiid.designer.ui.viewsupport.ImportContainer; import org.teiid.designer.ui.viewsupport.MarkerUtilities; import org.teiid.designer.ui.viewsupport.ModelIdentifier; import org.teiid.designer.ui.viewsupport.ModelUtilities; /** * ModelExplorerLabelProvider * * @since 8.0 */ public class ModelExplorerLabelProvider extends LabelProvider implements ILightweightLabelDecorator, UiConstants, PluginConstants.Images { @SuppressWarnings("javadoc") public static boolean debug = false; private static int instanceCounter = 0; private ILabelProvider defaultProvider; private ExtendedModelObjectLabelProvider extendedModelObjectLabelProvider; private IResourceChangeListener resrcChgListener; private DiagramLabelProvider diagramLabelProvider; private IBaseLabelProvider eventSource; // Defect 23509 - caching our own listener list so we can prevent unnecessary event processing. ListenerList myListeners = new ListenerList(ListenerList.IDENTITY); /** * @since 4.0 */ public ModelExplorerLabelProvider() { if (debug) { System.err.println("ModelExplorerLabelProvider instantiated: " + ++instanceCounter + " instance(s) in memory."); //$NON-NLS-1$ //$NON-NLS-2$ } this.eventSource = this; // Add listener for model validation completion events this.resrcChgListener = new IResourceChangeListener() { @Override public void resourceChanged( final IResourceChangeEvent event ) { final Display display = Display.getDefault(); if (display.isDisposed()) { return; } // Defect 23509 - preventing unnecessary event processing. // Don't do any work if ther are no listeners.... :) if (myListeners == null || myListeners.isEmpty()) { return; } final IMarkerDelta[] deltas = event.findMarkerDeltas(null, true); if ((deltas != null) && (deltas.length > 0)) { Set resources = new HashSet(); for (int i = 0; i < deltas.length; i++) { resources.add(deltas[i].getResource()); } final Object[] resourcesToUpdate = resources.toArray(); display.asyncExec(new Runnable() { @Override public void run() { changeLabel(resourcesToUpdate); } }); } } }; ModelerCore.getWorkspace().addResourceChangeListener(this.resrcChgListener); diagramLabelProvider = new DiagramLabelProvider(); extendedModelObjectLabelProvider = new ExtendedModelObjectLabelProvider(); } void changeLabel( Object[] resourcesToUpdate ) { fireLabelProviderChanged(new LabelProviderChangedEvent(getLabelProviderChangedEventSource(), resourcesToUpdate)); } /** * Set this label provider's event source * * @param theSource the source of the event (can be <code>null</code>) */ public void setLabelProviderChangedEventSource( IBaseLabelProvider theSource ) { this.eventSource = theSource; } /** * @return this label provider's event source */ public IBaseLabelProvider getLabelProviderChangedEventSource() { return this.eventSource; } /** * Method declared on IBaseLabelProvider. Defect 23509 - we need to keep track of # of listeners in this class because super * does not have a getter */ @Override public void addListener( ILabelProviderListener listener ) { super.addListener(listener); myListeners.add(listener); } /** * Method declared on IBaseLabelProvider. Defect 23509 - we need to keep track of # of listeners in this class because super * does not have a getter */ @Override public void removeListener( ILabelProviderListener listener ) { super.removeListener(listener); myListeners.remove(listener); } /** * @since 4.0 */ IResourceChangeListener getResourceChangeListener() { return this.resrcChgListener; } /** * @since 4.0 */ private ILabelProvider getDefaultProvider() { if (defaultProvider == null) { defaultProvider = new WorkbenchLabelProvider(); } return defaultProvider; } /** * Removes listeners registered by this instance. * * @see org.eclipse.jface.viewers.IBaseLabelProvider#dispose() * @since 4.0 */ @Override public void dispose() { if (debug) { System.err.println("ModelExplorerLabelProvider disposed: " + --instanceCounter + " instance(s) in memory."); //$NON-NLS-1$ //$NON-NLS-2$ } ModelerCore.getWorkspace().removeResourceChangeListener(getResourceChangeListener()); } /** * Figures out which provider to delegate to. * * @see org.eclipse.jface.viewers.ILabelProvider#getImage(java.lang.Object) * @since 4.0 */ @Override public Image getImage( Object element ) { Image result = null; final boolean startedTxn = ModelerCore.startTxn(false, false, null, this); boolean succeeded = false; try { if (element instanceof Diagram) { result = diagramLabelProvider.getImage(element); if (result == null) { result = UiPlugin.getDefault().getImage("icons/full/obj16/Diagram.gif"); //$NON-NLS-1$ } } else if (element instanceof ImportContainer) { result = UiPlugin.getDefault().getImage(IMPORT_CONTAINER); } else if (element instanceof EObject) { if (element instanceof TransformationMappingRoot) { result = UiPlugin.getDefault().getImage("icons/full/obj16/Transform.gif"); //$NON-NLS-1$ } else { result = ModelUtilities.getEMFLabelProvider().getImage( element); } } else if (element instanceof IFile && ModelUtilities.isModelFile((IFile) element) && ((IFile) element).exists()) { result = ModelIdentifier.getModelImage((IResource) element); } else { result = extendedModelObjectLabelProvider.getImage(element); } if (result == null) { result = getDefaultProvider().getImage(element); } succeeded = true; } catch (final Exception err) { Util.log(err); } finally { if (startedTxn) { if (succeeded) ModelerCore.commitTxn(); else ModelerCore.rollbackTxn(); } } if (result != null) return result; return super.getImage(element); } /** * Figures out which provider to delegate to. * * @see org.eclipse.jface.viewers.ILabelProvider#getText(java.lang.Object) * @since 4.0 */ @Override public String getText( Object element ) { String result = null; final boolean startedTxn = ModelerCore.startTxn(false, false, null, this); boolean succeeded = false; try { if (element instanceof Diagram) { result = diagramLabelProvider.getText(element); if (result == null) { result = UiConstants.Util.getString("ModelExplorerLabelProvider.genericDiagramLabel"); //$NON-NLS-1$ } } else if (element instanceof ImportContainer) { result = element.toString(); } else if (element instanceof EObject) { if (element instanceof TransformationMappingRoot) { result = UiConstants.Util.getString("ModelExplorerLabelProvider.genericTransformationLabel"); //$NON-NLS-1$ } else { ILabelProvider p = ModelUtilities.getEMFLabelProvider(); result = p.getText(element); } } else { result = extendedModelObjectLabelProvider.getText(element); if (result == null) { // ------------------------------------------------------------ // Defect 22319 - Hide the .xmi file extension in Dimension // Utilizing the hidden-project centric characteristics // That way Enterprise doesn't hide the extension // ------------------------------------------------------------ String defaultText = getDefaultProvider().getText(element); if (ProductCustomizerMgr.getInstance().getProductCharacteristics().isHiddenProjectCentric()) { if (defaultText.endsWith(StringConstants.DOT_XMI)) { int len = defaultText.lastIndexOf(StringConstants.DOT_XMI); defaultText = defaultText.substring(0, len); } } result = defaultText; } } succeeded = true; } finally { if (startedTxn) { if (succeeded) ModelerCore.commitTxn(); else ModelerCore.rollbackTxn(); } } return result; } /** * @see org.eclipse.jface.viewers.ILightweightLabelDecorator#decorate(java.lang.Object, org.eclipse.jface.viewers.IDecoration) * @since 4.0 */ @Override public void decorate( final Object element, final IDecoration decoration ) { final Display display = Display.getDefault(); if (display.isDisposed()) { return; } final IResource resrc = getResource(element); if (resrc == null || !resrc.exists() || ((resrc instanceof IProject) && !((IProject)resrc).isOpen())) { return; } IMarker[] markers = null; boolean errorOccurred = false; try { if( ModelUtil.isVdbArchiveFile(resrc) ) { markers = resrc.findMarkers("org.teiid.designer.vdb.ui.vdbMarker", false, IResource.DEPTH_INFINITE); //$NON-NLS-1$ } else { markers = resrc.findMarkers(IMarker.PROBLEM, false, IResource.DEPTH_INFINITE); } } catch (CoreException ex) { Util.log(ex); errorOccurred = true; } if (!errorOccurred) { ImageDescriptor decorationIcon = getDecorationIcon(markers); if (decorationIcon != null) { decoration.addOverlay(decorationIcon); } } try { // add suffix for special warnings: IMarker[] problems = resrc.findMarkers(IMarker.PROBLEM, true, IResource.DEPTH_ZERO); for (int i = 0; i < problems.length; i++) { IMarker marker = problems[i]; String value = marker.getAttribute(ModelerCore.MARKER_PROBLEM_DECORATOR_TEXT, null); if (value != null) { String message = UiConstants.Util.getString("ModelExplorerLabelProvider.problemMarkerBrackets", //$NON-NLS-1$ value); decoration.addSuffix(message); break; } // endif } // endfor } catch (CoreException ex) { Util.log(ex); } // endtry // Lastly, decorate with Extension if applicable if( element instanceof IFile && ModelUtilities.isModelFile((IFile)element)) { File file = ((IFile)element).getLocation().toFile(); ModelExtensionRegistry registry = ExtensionPlugin.getInstance().getRegistry(); try { for (String namespacePrefix : registry.getAllNamespacePrefixes()) { ModelExtensionAssistant assistant = registry.getModelExtensionAssistant(namespacePrefix); if (!assistant.getModelExtensionDefinition().isBuiltIn() && (assistant instanceof ModelObjectExtensionAssistant) && ((ModelObjectExtensionAssistant)assistant).supportsMyNamespace(element)) { decoration.addOverlay(UiPlugin.getDefault().getExtensionDecoratorImage(), IDecoration.TOP_LEFT); break; } } } catch (Exception e) { Util.log(IStatus.INFO, e, Util.getString("ModelExplorerLabelProvider.modelExtensionError", file.getName())); //$NON-NLS-1$ } } } private ImageDescriptor getDecorationIcon( IMarker[] markers ) { final boolean startedTxn = ModelerCore.startTxn(false, false, null, this); ImageDescriptor icon = null; for (int ndx = markers.length; --ndx >= 0;) { final Object attr = MarkerUtilities.getMarkerAttribute(markers[ndx], IMarker.SEVERITY); // markers[ndx].getAttribute(IMarker.SEVERITY); if (attr == null) { continue; } // Asserting attr is an Integer... final int severity = ((Integer)attr).intValue(); if (severity == IMarker.SEVERITY_ERROR) { icon = UiPlugin.getDefault().getErrorDecoratorImage(); break; } if (icon == null && severity == IMarker.SEVERITY_WARNING) { icon = UiPlugin.getDefault().getWarningDecoratorImage(); } } if (startedTxn) { ModelerCore.commitTxn(); } return icon; } /** * Returns the resource for the specified element, or null if there is no resource associated with it. * * @param element The element for which to find an associated resource * @return The resource for the specified element; may be null. * @since 4.0 */ private IResource getResource( final Object element ) { if (element instanceof IResource) { return (IResource)element; } if (element instanceof IAdaptable) { return (IResource)((IAdaptable)element).getAdapter(IResource.class); } return null; } }