package org.bndtools.builder.decorator.ui;
import org.bndtools.api.BndtoolsConstants;
import org.bndtools.api.ILogger;
import org.bndtools.api.Logger;
import org.bndtools.builder.BndtoolsBuilder;
import org.bndtools.builder.ComponentMarker;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IImportDeclaration;
import org.eclipse.jdt.core.IPackageDeclaration;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.internal.core.CompilationUnit;
import org.eclipse.jdt.internal.core.SourceType;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.IDecoration;
import org.eclipse.jface.viewers.ILightweightLabelDecorator;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.ui.plugin.AbstractUIPlugin;
/**
* A decorator for {@link CompilationUnit}'s that adds an icon if the class contains an OSGi
* {@link org.osgi.service.component.annotations.Component} annotation.
*
* @author wodencafe
*/
public class ComponentDecorator extends LabelProvider implements ILightweightLabelDecorator {
private static final ILogger logger = Logger.getLogger(ComponentDecorator.class);
private final ImageDescriptor componentIcon = AbstractUIPlugin.imageDescriptorFromPlugin(BndtoolsBuilder.PLUGIN_ID, "icons/component_s_flip.png");
@Override
public void decorate(Object element, IDecoration decoration) {
try {
if (element instanceof CompilationUnit) {
CompilationUnit unit = (CompilationUnit) element;
if (!unit.getJavaProject().getProject().hasNature(BndtoolsConstants.NATURE_ID)) {
return;
}
if (!isComponentInImports(unit)) {
return;
}
IPackageDeclaration[] decs = unit.getPackageDeclarations();
if (decs != null && decs.length > 0) {
IPackageDeclaration dec = decs[0];
if (dec != null) {
boolean found = false;
String customText = null;
for (IMarker marker : unit.getResource().findMarkers(BndtoolsConstants.MARKER_COMPONENT, true, IResource.DEPTH_ONE)) {
found = true;
customText = marker.getAttribute(IMarker.MESSAGE).toString();
}
if (found) {
decoration.addOverlay(componentIcon);
if (customText != null) {
if (customText.equals("OSGi Component")) {
decoration.addSuffix(" [Component]");
} else {
decoration.addSuffix(" [" + customText + "]");
}
}
}
}
}
} else if (element instanceof SourceType) {
SourceType type = (SourceType) element;
if (!type.getJavaProject().getProject().hasNature(BndtoolsConstants.NATURE_ID)) {
return;
}
if (!isComponentInImports(type.getCompilationUnit())) {
return;
}
boolean found = false;
String customText = null;
for (IMarker marker : type.getCompilationUnit().getResource().findMarkers(BndtoolsConstants.MARKER_COMPONENT, true, IResource.DEPTH_ONE)) {
found = true;
customText = marker.getAttribute(IMarker.MESSAGE).toString();
}
if (found) {
decoration.addOverlay(componentIcon);
if (customText != null) {
if (customText.equals("OSGi Component")) {
decoration.addSuffix(" [Component]");
} else {
decoration.addSuffix(" [" + customText + "]");
}
}
}
} else if (element instanceof IPackageFragment) {
IPackageFragment frag = (IPackageFragment) element;
if (!frag.getJavaProject().getProject().hasNature(BndtoolsConstants.NATURE_ID)) {
return;
}
IResource resource = (IResource) frag.getAdapter(IResource.class);
if (resource != null && countComponents(resource)) {
decoration.addOverlay(componentIcon);
}
}
} catch (CoreException e) {
logger.logError("Component Decorator error", e);
}
}
private static boolean countComponents(IResource resource) {
boolean found = false;
try {
if (resource.findMarkers(BndtoolsConstants.MARKER_COMPONENT, true, IResource.DEPTH_INFINITE).length > 0) {
found = true;
}
} catch (CoreException e) {
logger.logError("Component Package Decorator error", e);
}
return found;
}
private static boolean isComponentInImports(ICompilationUnit unit) throws CoreException {
boolean annotationInImports = false;
if (unit != null) {
for (IImportDeclaration importDecl : unit.getImports()) {
annotationInImports = importDecl.getElementName().equals(ComponentMarker.ANNOTATION_COMPONENT_FQN) || importDecl.getElementName().equals(ComponentMarker.ANNOTATION_COMPONENT_PACKAGE + ".*");
if (annotationInImports) {
break;
}
}
}
return annotationInImports;
}
}