/******************************************************************************* * Copyright (c) 2006, 2009 Spring IDE Developers * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Spring IDE Developers - initial API and implementation *******************************************************************************/ package org.springframework.ide.eclipse.beans.ui.model; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IResource; import org.eclipse.jdt.core.IClassFile; import org.eclipse.jdt.core.ICompilationUnit; import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.IPackageFragmentRoot; import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.viewers.IBaseLabelProvider; import org.eclipse.jface.viewers.IDecoration; import org.eclipse.jface.viewers.ILabelDecorator; import org.eclipse.jface.viewers.ILightweightLabelDecorator; import org.eclipse.jface.viewers.LabelProviderChangedEvent; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.widgets.Display; import org.eclipse.ui.PlatformUI; import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.ide.eclipse.beans.core.BeansCorePlugin; import org.springframework.ide.eclipse.beans.core.internal.model.Bean; import org.springframework.ide.eclipse.beans.core.internal.model.BeansModelUtils; import org.springframework.ide.eclipse.beans.core.model.IBeansConfig; import org.springframework.ide.eclipse.beans.core.model.IBeansConfigSet; import org.springframework.ide.eclipse.beans.core.model.IBeansImport; import org.springframework.ide.eclipse.beans.core.model.IBeansModel; import org.springframework.ide.eclipse.beans.core.model.IBeansModelElement; import org.springframework.ide.eclipse.beans.core.model.IBeansProject; import org.springframework.ide.eclipse.beans.ui.BeansUIImages; import org.springframework.ide.eclipse.beans.ui.BeansUIPlugin; import org.springframework.ide.eclipse.core.MarkerUtils; import org.springframework.ide.eclipse.core.io.ZipEntryStorage; import org.springframework.ide.eclipse.core.model.ILazyInitializedModelElement; import org.springframework.ide.eclipse.core.model.IModelChangeListener; import org.springframework.ide.eclipse.core.model.IResourceModelElement; import org.springframework.ide.eclipse.core.model.ISourceModelElement; import org.springframework.ide.eclipse.core.model.ModelChangeEvent; import org.springframework.ide.eclipse.ui.SpringLabelDecorator; /** * This decorator adds an overlay image to all Spring beans config files and their corresponding folders and bean * classes (Java source and class files). This decoration is refreshed on every modification to the Spring Beans model. * Therefore the decorator adds a {@link IModelChangeListener change listener} to the beans model. * @author Torsten Juergeleit * @author Christian Dupuis */ public class BeansModelLabelDecorator extends SpringLabelDecorator implements ILightweightLabelDecorator, ILabelDecorator { public static final String DECORATOR_ID = BeansUIPlugin.PLUGIN_ID + ".model.beansModelLabelDecorator"; public static void update() { if (PlatformUI.isWorkbenchRunning()) { IBaseLabelProvider provider = PlatformUI.getWorkbench().getDecoratorManager() .getBaseLabelProvider(DECORATOR_ID); if (provider instanceof BeansModelLabelDecorator) { ((BeansModelLabelDecorator) provider).internalUpdate(); } } } private void internalUpdate() { Display.getDefault().asyncExec(new Runnable() { public void run() { IBaseLabelProvider provider = PlatformUI.getWorkbench().getDecoratorManager().getBaseLabelProvider( SpringLabelDecorator.DECORATOR_ID); if (provider != null) { fireLabelProviderChanged(new LabelProviderChangedEvent(provider)); } fireLabelProviderChanged(new LabelProviderChangedEvent(BeansModelLabelDecorator.this)); } }); } private IModelChangeListener listener; public BeansModelLabelDecorator() { listener = new IModelChangeListener() { public void elementChanged(ModelChangeEvent event) { if ((event.getElement() instanceof IBeansProject || event.getElement() instanceof IBeansConfig) && event.getType() != ModelChangeEvent.Type.REMOVED) { internalUpdate(); } } }; BeansCorePlugin.getModel().addChangeListener(listener); } public void decorate(Object element, IDecoration decoration) { if (element instanceof IFolder) { decorateFolder((IFolder) element, decoration); } else if (element instanceof IFile) { decorateFile((IFile) element, decoration); } else if (element instanceof IJavaElement) { decorateJavaElement(((IJavaElement) element), decoration); } else if (element instanceof IBeansModelElement) { if (element instanceof Bean) { decorateBean((Bean) element, decoration); } decorateBeansModelElement(((IBeansModelElement) element), decoration); } } /** * Adds decorations to {@link Bean}s. * @since 2.0.1 */ private void decorateBean(Bean bean, IDecoration decoration) { BeanDefinition bd = bean.getBeanDefinition(); if (bean.isChildBean()) { decoration.addOverlay(BeansUIImages.DESC_OVR_CHILD, IDecoration.TOP_RIGHT); } if (bean.isFactory()) { decoration.addOverlay(BeansUIImages.DESC_OVR_FACTORY, IDecoration.TOP_LEFT); } if (bean.isAbstract()) { decoration.addOverlay(BeansUIImages.DESC_OVR_ABSTRACT, IDecoration.BOTTOM_RIGHT); } if (!bean.isSingleton()) { decoration.addOverlay(BeansUIImages.DESC_OVR_PROTOTYPE, IDecoration.BOTTOM_RIGHT); } if (bd instanceof AnnotatedBeanDefinition) { decoration.addOverlay(BeansUIImages.DESC_OVR_ANNOTATION, IDecoration.BOTTOM_LEFT); } } /** * Adds error and warning decorations to {@link IBeansModelElement}. * @since 2.0.1 */ private void decorateBeansModelElement(IBeansModelElement element, IDecoration decoration) { addErrorOverlay(decoration, getSeverity(element)); } protected void decorateFile(IFile file, IDecoration decoration) { IBeansModel model = BeansCorePlugin.getModel(); IBeansProject project = model.getProject(file.getProject()); if (project instanceof ILazyInitializedModelElement && !((ILazyInitializedModelElement) project).isInitialized()) { return; } IBeansConfig config = model.getConfig(file, true); if (config != null) { addErrorOverlay(decoration, getSeverity(config)); decoration.addOverlay(BeansUIImages.DESC_OVR_SPRING); } } protected void decorateFolder(IFolder folder, IDecoration decoration) { IBeansModel model = BeansCorePlugin.getModel(); IBeansProject project = model.getProject(folder.getProject()); if (project instanceof ILazyInitializedModelElement && !((ILazyInitializedModelElement) project).isInitialized()) { return; } if (project != null) { String path = folder.getProjectRelativePath().toString() + '/'; for (IBeansConfig config : project.getConfigs()) { if (config.getElementName().startsWith(path)) { decoration.addOverlay(BeansUIImages.DESC_OVR_SPRING); break; } } } } protected void decorateJavaElement(IJavaElement element, IDecoration decoration) { int type = element.getElementType(); if (type == IJavaElement.PACKAGE_FRAGMENT_ROOT || type == IJavaElement.CLASS_FILE || type == IJavaElement.COMPILATION_UNIT) { IBeansModel model = BeansCorePlugin.getModel(); IBeansProject project = model.getProject(element.getJavaProject().getProject()); if (project instanceof ILazyInitializedModelElement && ((ILazyInitializedModelElement) project).isInitialized()) { try { if (type == IJavaElement.PACKAGE_FRAGMENT_ROOT) { // Decorate JAR file IResource resource = ((IPackageFragmentRoot) element).getResource(); if (resource instanceof IFile) { for (IBeansConfig config : project.getConfigs()) { if (config.getElementResource().equals(resource)) { decoration.addOverlay(BeansUIImages.DESC_OVR_SPRING); break; } } } } else if (type == IJavaElement.CLASS_FILE) { // Decorate Java class file IType javaType = ((IClassFile) element).getType(); if (BeansModelUtils.isBeanClass(javaType)) { decoration.addOverlay(BeansUIImages.DESC_OVR_SPRING); } } else if (type == IJavaElement.COMPILATION_UNIT) { // Decorate Java source file for (IType javaType : ((ICompilationUnit) element).getTypes()) { if (BeansModelUtils.isBeanClass(javaType)) { decoration.addOverlay(BeansUIImages.DESC_OVR_SPRING); break; } } } } catch (JavaModelException e) { // Ignore } } } } @Override public void dispose() { BeansCorePlugin.getModel().removeChangeListener(listener); } protected int getSeverity(Object element) { int severity = 0; if (element instanceof ILazyInitializedModelElement && !((ILazyInitializedModelElement) element).isInitialized()) { return 0; } if (element instanceof IBeansImport) { severity = getSeverityForImport((IBeansImport) element); } else if (element instanceof ISourceModelElement) { ISourceModelElement source = (ISourceModelElement) element; severity = MarkerUtils.getHighestSeverityFromMarkersInRange(source.getElementResource(), source .getElementStartLine(), source.getElementEndLine()); } else if (element instanceof IResourceModelElement) { if (element instanceof IBeansProject) { int s = 0; for (IBeansConfig config : ((IBeansProject) element).getConfigs()) { s = getSeverityForConfig(config); if (s > severity) { severity = s; } if (severity == IMarker.SEVERITY_ERROR) { break; } } } else if (element instanceof IBeansConfigSet) { int s = 0; for (IBeansConfig config : ((IBeansConfigSet) element).getConfigs()) { severity = MarkerUtils.getHighestSeverityFromMarkersInRange(config.getElementResource(), -1, -1); if (s > severity) { severity = s; } if (severity == IMarker.SEVERITY_ERROR) { break; } } } else if (element instanceof IBeansConfig) { severity = getSeverityForConfig((IBeansConfig) element); } else { severity = MarkerUtils.getHighestSeverityFromMarkersInRange(((IResourceModelElement) element) .getElementResource(), -1, -1); } } else if (element instanceof IResource) { severity = MarkerUtils.getHighestSeverityFromMarkersInRange((IResource) element, -1, -1); } else if (element instanceof ZipEntryStorage) { IResource resource = ((ZipEntryStorage) element).getFile(); severity = MarkerUtils.getHighestSeverityFromMarkersInRange(resource, -1, -1); } return severity; } private int getSeverityForConfig(IBeansConfig beansConfig) { int severity = MarkerUtils.getHighestSeverityFromMarkersInRange(beansConfig.getElementResource(), -1, -1); // Check imported configs for (IBeansImport beanImport : beansConfig.getImports()) { int importedSeverity = getSeverityForImport(beanImport); if (importedSeverity == IMarker.SEVERITY_WARNING) { severity = importedSeverity; } else if (importedSeverity == IMarker.SEVERITY_ERROR) { severity = importedSeverity; break; } } return severity; } private int getSeverityForImport(IBeansImport beanImport) { int severity = 0; for (IBeansConfig importedConfig : beanImport.getImportedBeansConfigs()) { int importedSeverity = getSeverityForConfig(importedConfig); if (importedSeverity == IMarker.SEVERITY_WARNING) { severity = importedSeverity; } else if (importedSeverity == IMarker.SEVERITY_ERROR) { severity = importedSeverity; break; } } return severity; } @Override public boolean isLabelProperty(Object element, String property) { return false; } public Image decorateImage(Image image, Object element) { int severity = getSeverity(element); int flags = 0; if (severity == IMarker.SEVERITY_WARNING) { flags |= BeansModelImageDescriptor.FLAG_WARNING; } else if (severity == IMarker.SEVERITY_ERROR) { flags |= BeansModelImageDescriptor.FLAG_ERROR; } if (element instanceof IBeansModelElement && image != null) { ImageDescriptor descriptor = new BeansModelImageDescriptor(image, (IBeansModelElement) element, flags); image = BeansUIPlugin.getImageDescriptorRegistry().get(descriptor); } return image; } public String decorateText(String text, Object element) { return text; } }