org.eclipse.jst.jsf.core.jsfappconfig.AnnotationJSFAppConfigProvider.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.jst.jsf.core.jsfappconfig.AnnotationJSFAppConfigProvider.java

Source

/*******************************************************************************
 * Copyright (c) 2011 Oracle Corporation.
 * 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:
 *    Andrew McCulloch - initial API and implementation
 *    Ian Trimble/Oracle - maintenance
 *******************************************************************************/
package org.eclipse.jst.jsf.core.jsfappconfig;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.search.IJavaSearchConstants;
import org.eclipse.jdt.core.search.IJavaSearchScope;
import org.eclipse.jdt.core.search.SearchEngine;
import org.eclipse.jdt.core.search.SearchParticipant;
import org.eclipse.jdt.core.search.SearchPattern;
import org.eclipse.jdt.core.search.SearchRequestor;
import org.eclipse.jst.jsf.core.internal.JSFCorePlugin;
import org.eclipse.jst.jsf.core.jsfappconfig.AbstractJSFAppConfigProvider;
import org.eclipse.jst.jsf.facesconfig.emf.FacesConfigFactory;
import org.eclipse.jst.jsf.facesconfig.emf.FacesConfigType;

/**
 * Provides a configuration model specified as JSF 2.x annotations.
 * 
 * <p><b>Provisional API - subject to change</b></p>
 * 
 * @author Andrew McCulloch - Oracle 
 */
public class AnnotationJSFAppConfigProvider extends AbstractJSFAppConfigProvider {

    static final String MANAGED_BEAN_ANNOTATION_CLASS = "javax.faces.bean.ManagedBean"; //$NON-NLS-1$
    static final String REFERENCED_BEAN_ANNOTATION_CLASS = "javax.faces.bean.ReferencedBean"; //$NON-NLS-1$
    static final String FACES_COMPONENT_ANNOTATION_CLASS = "javax.faces.component.FacesComponent"; //$NON-NLS-1$
    static final String FACES_CONVERTER_ANNOTATION_CLASS = "javax.faces.convert.FacesConverter"; //$NON-NLS-1$
    static final String FACES_RENDERER_ANNOTATION_CLASS = "javax.faces.render.FacesRenderer"; //$NON-NLS-1$
    static final String FACES_VALIDATOR_ANNOTATION_CLASS = "javax.faces.validator.FacesValidator"; //$NON-NLS-1$

    static final String NONE_SCOPED_ANNOTATION_CLASS = "javax.faces.bean.NoneScoped"; //$NON-NLS-1$
    static final String VIEW_SCOPED_ANNOTATION_CLASS = "javax.faces.bean.ViewScoped"; //$NON-NLS-1$
    static final String SESSION_SCOPED_ANNOTATION_CLASS = "javax.faces.bean.SessionScoped"; //$NON-NLS-1$
    static final String APPLICATION_SCOPED_ANNOTATION_CLASS = "javax.faces.bean.ApplicationScoped"; //$NON-NLS-1$
    static final String CUSTOM_SCOPED_ANNOTATION_CLASS = "javax.faces.bean.CustomScoped"; //$NON-NLS-1$

    static final String CDI_NAMED_BEAN_ANNOTATION_CLASS = "javax.inject.Named"; //$NON-NLS-1$
    static final String CDI_MODEL_BEAN_ANNOTATION_CLASS = "javax.enterprise.inject.Model"; //$NON-NLS-1$

    static final String CDI_REQUEST_SCOPED_ANNOTATION_CLASS = "javax.enterprise.context.RequestScoped"; //$NON-NLS-1$
    static final String CDI_CONVERSATION_SCOPED_ANNOTATION_CLASS = "javax.enterprise.context.ConversationScoped"; //$NON-NLS-1$
    static final String CDI_SESSION_SCOPED_ANNOTATION_CLASS = "javax.enterprise.context.SessionScoped"; //$NON-NLS-1$
    static final String CDI_APPLICATION_SCOPED_ANNOTATION_CLASS = "javax.enterprise.context.ApplicationScoped"; //$NON-NLS-1$

    /**
     * Cached {@link FacesConfigType} instance.
     */
    private FacesConfigType facesConfig = null;

    @Override
    public synchronized FacesConfigType getFacesConfigModel() {
        if (facesConfig == null) {
            try {
                discoverFacesConfig();
            } catch (CoreException ce) {
                JSFCorePlugin.log(IStatus.ERROR, ce.getLocalizedMessage(), ce);
                facesConfig = null;
            }

            if (facesConfig != null) {
                jsfAppConfigLocater.getJSFAppConfigManager().addFacesConfigChangeAdapter(facesConfig);
            }
        }
        return facesConfig;
    }

    @Override
    public void releaseFacesConfigModel() {
        jsfAppConfigLocater.getJSFAppConfigManager().removeFacesConfigChangeAdapter(facesConfig);
        facesConfig = null;
    }

    private void discoverFacesConfig() throws CoreException {
        facesConfig = FacesConfigFactory.eINSTANCE.createFacesConfigType();
        IJavaProject jProject = JavaCore.create(this.jsfAppConfigLocater.getJSFAppConfigManager().getProject());
        IPackageFragmentRoot[] roots = jProject.getAllPackageFragmentRoots();
        List<IPackageFragmentRoot> scannableRoots = new ArrayList<IPackageFragmentRoot>();
        if (roots != null) {
            for (IPackageFragmentRoot root : roots) {
                AnnotationPackageFragmentRoot facesRoot = new AnnotationPackageFragmentRoot(root);
                if (facesRoot.canContainAnnotatedComponents()) {
                    scannableRoots.add(root);
                }
            }
        }

        if (!scannableRoots.isEmpty()) {
            findAnnotatedComponents(jProject, scannableRoots);
        }
    }

    private final void findAnnotatedComponents(final IJavaProject jProject,
            final List<IPackageFragmentRoot> scannableRoots) throws CoreException {
        SearchPattern pattern = orPattern(null, jProject.findType(MANAGED_BEAN_ANNOTATION_CLASS));
        pattern = orPattern(pattern, jProject.findType(REFERENCED_BEAN_ANNOTATION_CLASS));
        pattern = orPattern(pattern, jProject.findType(FACES_COMPONENT_ANNOTATION_CLASS));
        pattern = orPattern(pattern, jProject.findType(FACES_CONVERTER_ANNOTATION_CLASS));
        pattern = orPattern(pattern, jProject.findType(FACES_RENDERER_ANNOTATION_CLASS));
        pattern = orPattern(pattern, jProject.findType(FACES_VALIDATOR_ANNOTATION_CLASS));
        pattern = orPattern(pattern, jProject.findType(CDI_NAMED_BEAN_ANNOTATION_CLASS));
        pattern = orPattern(pattern, jProject.findType(CDI_MODEL_BEAN_ANNOTATION_CLASS));

        if (pattern != null) {
            SearchEngine engine = new SearchEngine();
            SearchParticipant[] participants = new SearchParticipant[] {
                    SearchEngine.getDefaultSearchParticipant() };
            IJavaSearchScope scope = SearchEngine.createJavaSearchScope(
                    scannableRoots.toArray(new IJavaElement[scannableRoots.size()]),
                    IJavaSearchScope.SOURCES | IJavaSearchScope.APPLICATION_LIBRARIES);

            SearchRequestor requestor = new AnnotationSearchRequestor(facesConfig);
            engine.search(pattern, participants, scope, requestor, new NullProgressMonitor());
        }
    }

    private SearchPattern orPattern(SearchPattern pattern, IJavaElement element) {
        if (element == null) {
            return pattern;
        }
        if (pattern == null) {
            return SearchPattern.createPattern(element, IJavaSearchConstants.REFERENCES);
        }
        return SearchPattern.createOrPattern(pattern,
                SearchPattern.createPattern(element, IJavaSearchConstants.REFERENCES));
    }
}