| /*********************************************************************** |
| * Copyright (c) 2008 by SAP AG, Walldorf. |
| * 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: |
| * SAP AG - initial API and implementation |
| ***********************************************************************/ |
| package org.eclipse.jst.jee.model.internal; |
| |
| import java.util.Collection; |
| import java.util.HashSet; |
| import java.util.Iterator; |
| |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IPath; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.emf.ecore.EObject; |
| import org.eclipse.emf.ecore.util.EcoreUtil; |
| import org.eclipse.jdt.core.ICompilationUnit; |
| import org.eclipse.jdt.core.IJavaElementDelta; |
| import org.eclipse.jdt.core.IJavaProject; |
| import org.eclipse.jdt.core.IPackageFragmentRoot; |
| import org.eclipse.jdt.core.IType; |
| import org.eclipse.jdt.core.JavaCore; |
| import org.eclipse.jdt.core.JavaModelException; |
| import org.eclipse.jst.j2ee.model.IModelProviderEvent; |
| import org.eclipse.jst.javaee.core.EjbLocalRef; |
| import org.eclipse.jst.javaee.core.JavaEEObject; |
| import org.eclipse.jst.javaee.core.Listener; |
| import org.eclipse.jst.javaee.core.ResourceRef; |
| import org.eclipse.jst.javaee.core.SecurityRole; |
| import org.eclipse.jst.javaee.core.SecurityRoleRef; |
| import org.eclipse.jst.javaee.ejb.SecurityIdentityType; |
| import org.eclipse.jst.javaee.web.Filter; |
| import org.eclipse.jst.javaee.web.Servlet; |
| import org.eclipse.jst.javaee.web.WebApp; |
| import org.eclipse.jst.javaee.web.WebFactory; |
| import org.eclipse.jst.jee.model.internal.common.AbstractAnnotationModelProvider; |
| import org.eclipse.jst.jee.model.internal.common.ManyToOneRelation; |
| import org.eclipse.jst.jee.model.internal.common.Result; |
| import org.eclipse.wst.common.project.facet.core.IFacetedProject; |
| |
| /** |
| * @author Kiril Mitov k.mitov@sap.com |
| * |
| */ |
| public class WebAnnotationReader extends AbstractAnnotationModelProvider<WebApp> { |
| |
| private ManyToOneRelation<JavaEEObject, ICompilationUnit> modelToUnit; |
| |
| private ManyToOneRelation<JavaEEObject, ICompilationUnit> modelToInterfaceUnit; |
| |
| private WebAnnotationFactory annotationFactory; |
| |
| private WebApp ddApp; |
| |
| public WebAnnotationReader(IFacetedProject facetedProject, WebApp ddApp) { |
| super(facetedProject); |
| if (ddApp == null) |
| throw new IllegalArgumentException("The deployment descriptor model can not be null!"); //$NON-NLS-1$ |
| this.ddApp = ddApp; |
| } |
| |
| @Override |
| protected void preLoad() { |
| modelObject = WebFactory.eINSTANCE.createWebApp(); |
| annotationFactory = WebAnnotationFactory.createFactory(); |
| } |
| |
| @Override |
| protected void loadModel() throws CoreException { |
| IJavaProject javaProject = JavaCore.create(facetedProject.getProject()); |
| final Collection<ICompilationUnit> javaUnits = new HashSet<ICompilationUnit>(); |
| for (final IPackageFragmentRoot root : javaProject.getAllPackageFragmentRoots()) { |
| visitJavaFiles(javaUnits, root); |
| } |
| annotationFactory = WebAnnotationFactory.createFactory(); |
| |
| modelToInterfaceUnit = new ManyToOneRelation<JavaEEObject, ICompilationUnit>(); |
| modelToUnit = new ManyToOneRelation<JavaEEObject, ICompilationUnit>(); |
| for (ICompilationUnit unit : javaUnits) { |
| Result result = analyzeCompilationUnit(unit); |
| if (result == null) |
| continue; |
| processResult(unit, result); |
| } |
| } |
| |
| /** |
| * Analyze this unit for a web artifact. If the file is not a valid java |
| * compilation unit or it does not contain a class the method returns |
| * <code>null</code> |
| * |
| * Only the primary type of the compilation unit is processed. |
| * |
| * @param unit |
| * the unit to be processed. |
| * @return result from processing the file |
| * @throws JavaModelException |
| */ |
| private Result analyzeCompilationUnit(ICompilationUnit unit) throws JavaModelException { |
| IType rootType = unit.findPrimaryType(); |
| /* |
| * If the compilation unit is not valid and can not be compiled the |
| * rootType may be null. This can happen if a class is define as follows |
| * <code> @Stateless public SomeClass implements SomeInterface{}</code>. |
| * Here the "class" word is missed and the type is not valid. |
| */ |
| if (rootType == null || !rootType.isClass()) |
| return null; |
| for (Iterator iter = ddApp.getServlets().iterator(); iter.hasNext();) { |
| Servlet servlet = (Servlet) iter.next(); |
| if (rootType.getFullyQualifiedName().equals(servlet.getServletClass())) |
| return annotationFactory.createServlet(rootType, servlet.getServletName()); |
| } |
| for (Iterator iter = ddApp.getListeners().iterator(); iter.hasNext();) { |
| Listener listener = (Listener) iter.next(); |
| if (rootType.getFullyQualifiedName().equals(listener.getListenerClass())) |
| return annotationFactory.createListener(rootType); |
| } |
| for (Iterator iter = ddApp.getFilters().iterator(); iter.hasNext();) { |
| Filter filter = (Filter) iter.next(); |
| if (rootType.getFullyQualifiedName().equals(filter.getFilterClass())) { |
| return annotationFactory.createFilter(rootType, filter.getFilterName()); |
| } |
| } |
| return null; |
| } |
| |
| /** |
| * Process the result from parsing the unit. Depending on the result this |
| * might include adding a session bean, message driven bean, securityRole |
| * etc. |
| * |
| * @param unit |
| * @param result |
| * @throws JavaModelException |
| */ |
| private void processResult(ICompilationUnit unit, Result result) throws JavaModelException { |
| JavaEEObject mainObject = result.getMainObject(); |
| if (Servlet.class.isInstance(mainObject)) |
| servletFound(unit, (Servlet) result.getMainObject(), result.getDependedTypes()); |
| for (JavaEEObject additional : result.getAdditional()) { |
| if (EjbLocalRef.class.isInstance(additional)) { |
| ejbLocalRefFound(unit, (EjbLocalRef) additional, result.getDependedTypes()); |
| } else if (ResourceRef.class.isInstance(additional)) { |
| resourceRefFound(unit, (ResourceRef) additional, result.getDependedTypes()); |
| } else if (SecurityRole.class.isInstance(additional)) { |
| securityRoleFound(result.getMainObject(), (SecurityRole) additional); |
| } else if (SecurityIdentityType.class.isInstance(additional)) { |
| securityIdentityTypeFound(unit, (SecurityIdentityType) additional); |
| } |
| } |
| } |
| |
| private void servletFound(ICompilationUnit unit, Servlet servlet, Collection<IType> dependedTypes) |
| throws JavaModelException { |
| modelObject.getServlets().add(servlet); |
| connectObjectWithFile(unit, servlet, dependedTypes); |
| } |
| |
| private void securityIdentityTypeFound(ICompilationUnit file, SecurityIdentityType additional) { |
| } |
| |
| private void resourceRefFound(ICompilationUnit unit, ResourceRef resourceRef, Collection<IType> dependedTypes) |
| throws JavaModelException { |
| modelObject.getResourceRefs().add(resourceRef); |
| connectObjectWithFile(unit, resourceRef, dependedTypes); |
| } |
| |
| private void ejbLocalRefFound(ICompilationUnit unit, EjbLocalRef localRef, Collection<IType> dependedTypes) |
| throws JavaModelException { |
| modelObject.getEjbLocalRefs().add(localRef); |
| connectObjectWithFile(unit, localRef, dependedTypes); |
| } |
| |
| private void connectObjectWithFile(ICompilationUnit unit, JavaEEObject localRef, Collection<IType> dependedTypes) |
| throws JavaModelException { |
| modelToUnit.connect(localRef, unit); |
| for (IType type : dependedTypes) { |
| if (type.isBinary() || type.isInterface() == false) |
| continue; |
| modelToInterfaceUnit.connect(localRef, type.getCompilationUnit()); |
| } |
| } |
| |
| @Override |
| protected void processAddedCompilationUnit(IModelProviderEvent modelEvent, ICompilationUnit unit) |
| throws CoreException { |
| Result result = analyzeCompilationUnit(unit); |
| if (result == null || result.isEmpty()) |
| return; |
| processResult(unit, result); |
| modelEvent.addResource(unit); |
| } |
| |
| @Override |
| protected void processChangedCompilationUnit(IModelProviderEvent modelEvent, ICompilationUnit unit) |
| throws CoreException { |
| if (modelToUnit.containsTarget(unit)) |
| processChangedModelUnit(modelEvent, unit); |
| else |
| processAddedCompilationUnit(modelEvent, unit); |
| } |
| |
| private void processChangedModelUnit(IModelProviderEvent modelEvent, ICompilationUnit unit) throws CoreException { |
| processRemovedCompilationUnit(modelEvent, unit); |
| processAddedCompilationUnit(modelEvent, unit); |
| } |
| |
| @Override |
| protected void processRemovedCompilationUnit(IModelProviderEvent modelEvent, ICompilationUnit unit) |
| throws CoreException { |
| if (modelToUnit.containsTarget(unit)) |
| processRemovedModelResource(modelEvent, unit); |
| else if (modelToInterfaceUnit.containsTarget(unit)) |
| processRemoveInterface(modelEvent, unit); |
| } |
| |
| private void processRemoveInterface(IModelProviderEvent event, ICompilationUnit unit) { |
| } |
| |
| @Override |
| protected void processRemovedPackage(IModelProviderEvent modelEvent, IJavaElementDelta delta) throws CoreException { |
| for (ICompilationUnit unit : modelToUnit.getTargets()) { |
| if (unit.getParent().getElementName().equals(delta.getElement().getElementName())) { |
| processRemovedCompilationUnit(modelEvent, unit); |
| } |
| } |
| } |
| |
| private void processRemovedModelResource(IModelProviderEvent event, ICompilationUnit file) { |
| Collection<JavaEEObject> modelObjects = modelToUnit.getSources(file); |
| for (JavaEEObject o : modelObjects) { |
| if (Servlet.class.isInstance(o)) |
| disconnectFromRoles(o); |
| EcoreUtil.remove((EObject) o); |
| } |
| modelToUnit.disconnect(file); |
| event.setEventCode(event.getEventCode() | IModelProviderEvent.REMOVED_RESOURCE); |
| event.addResource(file); |
| } |
| |
| public void modify(Runnable runnable, IPath modelPath) { |
| } |
| |
| public IStatus validateEdit(IPath modelPath, Object context) { |
| return null; |
| } |
| |
| @Override |
| protected Collection<SecurityRoleRef> getSecurityRoleRefs(JavaEEObject target) { |
| if (Servlet.class.isInstance(target)) |
| return ((Servlet) target).getSecurityRoleRefs(); |
| return null; |
| } |
| |
| @Override |
| protected Collection<SecurityRole> getSecurityRoles() { |
| return modelObject.getSecurityRoles(); |
| } |
| |
| } |