org.eclipse.pde.ds.internal.annotations.ComponentPropertyTester.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.pde.ds.internal.annotations.ComponentPropertyTester.java

Source

/*******************************************************************************
 * Copyright (c) 2015, 2016 Ecliptical Software Inc. and others.
 * 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:
 *     Ecliptical Software Inc. - initial API and implementation
 *******************************************************************************/
package org.eclipse.pde.ds.internal.annotations;

import org.eclipse.core.expressions.PropertyTester;
import org.eclipse.core.resources.ProjectScope;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.preferences.DefaultScope;
import org.eclipse.core.runtime.preferences.IScopeContext;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.jdt.core.IAnnotation;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IMemberValuePair;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.pde.internal.ds.core.IDSConstants;
import org.osgi.service.component.annotations.Component;

/**
 * Tests if a type (or any nested type) has a {@link Component} annotation with
 * no <code>name</code> attribute.
 */
@SuppressWarnings("restriction")
public class ComponentPropertyTester extends PropertyTester {

    private static final String COMPONENT_ANNOTATION = DSAnnotationCompilationParticipant.COMPONENT_ANNOTATION;

    private static final String COMPONENT_PACKAGE = COMPONENT_ANNOTATION.substring(0,
            COMPONENT_ANNOTATION.lastIndexOf('.'));

    private static final String COMPONENT_NAME = Component.class.getSimpleName();

    private static final Debug debug = Debug.getDebug("component-property-tester"); //$NON-NLS-1$

    @Override
    public boolean test(Object receiver, String property, Object[] args, Object expectedValue) {
        if (!"containsComponentWithImplicitName".equals(property)) //$NON-NLS-1$
            return false;

        if (!(receiver instanceof IType) && !(receiver instanceof IPackageFragment))
            return false;

        IJavaElement element = (IJavaElement) receiver;
        IJavaProject javaProject = element.getJavaProject();

        boolean enabled = Platform.getPreferencesService().getBoolean(Activator.PLUGIN_ID, Activator.PREF_ENABLED,
                false, new IScopeContext[] { new ProjectScope(javaProject.getProject()), InstanceScope.INSTANCE,
                        DefaultScope.INSTANCE });
        if (!enabled)
            return false;

        try {
            return element.getElementType() == IJavaElement.TYPE ? containsImplicitName((IType) receiver)
                    : containsImplicitName((IPackageFragment) receiver);
        } catch (JavaModelException e) {
            if (debug.isDebugging())
                debug.trace(
                        String.format("Error searching for components with implicit names in element: %s", element), //$NON-NLS-1$
                        e);
        }

        return false;
    }

    private boolean containsImplicitName(IPackageFragment fragment) throws JavaModelException {
        if (!fragment.containsJavaResources())
            return false;

        for (ICompilationUnit cu : fragment.getCompilationUnits()) {
            for (IType type : cu.getAllTypes()) {
                if (hasImplicitName(type))
                    return true;
            }
        }

        return false;
    }

    private boolean containsImplicitName(IType type) throws JavaModelException {
        if (hasImplicitName(type))
            return true;

        for (IType child : type.getTypes()) {
            if (hasImplicitName(child))
                return true;
        }

        return false;
    }

    public static boolean hasImplicitName(IType type) throws JavaModelException {
        IAnnotation[] annotations = type.getAnnotations();
        for (IAnnotation annotation : annotations) {
            boolean isComponent = COMPONENT_ANNOTATION.equals(annotation.getElementName());
            if (!isComponent) {
                String[][] resolved = type.resolveType(annotation.getElementName());
                if (resolved != null) {
                    for (String[] pair : resolved) {
                        if (pair.length == 2 && COMPONENT_PACKAGE.equals(pair[0])
                                && COMPONENT_NAME.equals(pair[1])) {
                            isComponent = true;
                            break;
                        }
                    }
                }
            }

            if (isComponent) {
                IMemberValuePair[] attrs = annotation.getMemberValuePairs();
                for (IMemberValuePair attr : attrs) {
                    if (IDSConstants.ATTRIBUTE_COMPONENT_NAME.equals(attr.getMemberName())) {
                        return false;
                    }
                }

                return true;
            }
        }

        return false;
    }
}