blob: c6e4069a5b145d9ba6e3a42ec72a7c9b8479f4be [file] [log] [blame]
/***********************************************************************
* 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();
}
}