/******************************************************************************* * 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)); } }