/******************************************************************************* | |
* Copyright (c) 2009 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.ws.jaxws.dom.runtime.persistence.sync; | |
import static org.eclipse.jst.ws.jaxws.dom.runtime.persistence.WSAnnotationFeatures.WS_ANNOTATION; | |
import org.eclipse.core.runtime.CoreException; | |
import org.eclipse.jdt.core.ElementChangedEvent; | |
import org.eclipse.jdt.core.ICompilationUnit; | |
import org.eclipse.jdt.core.IElementChangedListener; | |
import org.eclipse.jdt.core.IJavaElement; | |
import org.eclipse.jdt.core.IJavaElementDelta; | |
import org.eclipse.jdt.core.IJavaProject; | |
import org.eclipse.jdt.core.IPackageFragment; | |
import org.eclipse.jdt.core.IPackageFragmentRoot; | |
import org.eclipse.jdt.core.IType; | |
import org.eclipse.jdt.core.JavaModelException; | |
import org.eclipse.jst.ws.jaxws.dom.runtime.api.IDOM; | |
import org.eclipse.jst.ws.jaxws.dom.runtime.api.IJavaWebServiceElement; | |
import org.eclipse.jst.ws.jaxws.dom.runtime.api.IServiceEndpointInterface; | |
import org.eclipse.jst.ws.jaxws.dom.runtime.api.IWebService; | |
import org.eclipse.jst.ws.jaxws.dom.runtime.api.IWebServiceProject; | |
import org.eclipse.jst.ws.jaxws.dom.runtime.api.WsDOMLoadCanceledException; | |
import org.eclipse.jst.ws.jaxws.dom.runtime.persistence.ICompilationUnitFinder; | |
import org.eclipse.jst.ws.jaxws.dom.runtime.persistence.IProjectSelector; | |
import org.eclipse.jst.ws.jaxws.dom.runtime.persistence.JaxWsWorkspaceResource; | |
import org.eclipse.jst.ws.jaxws.dom.runtime.persistence.WorkspaceCUFinder; | |
import org.eclipse.jst.ws.jaxws.dom.runtime.persistence.JaxWsWorkspaceResource.ServiceModelData; | |
import org.eclipse.jst.ws.jaxws.utils.annotations.IAnnotation; | |
public class OnEventModelSynchronizer extends AbstractModelSynchronizer implements IElementChangedListener | |
{ | |
@Override | |
public IDOM getDomBeingLoaded() | |
{ | |
return resource().getDOM(); | |
} | |
public OnEventModelSynchronizer(JaxWsWorkspaceResource resource, ServiceModelData serviceData) | |
{ | |
super(resource, serviceData); | |
} | |
public void elementChanged(final ElementChangedEvent event) | |
{ | |
try | |
{ | |
if (logger().isDebug()) | |
{ | |
logger().logDebug("ElementChangedEvent has been delivered. Event details: " + event.toString());//$NON-NLS-1$ | |
} | |
// no processing if DOM load has been canceled | |
if (resource().isLoadCnaceled()) { | |
return; | |
} | |
resource().disableSaving(); | |
// handles ElementChangedEvent.POST_RECONCILE - the case when the editor sends reconcile event | |
if (event.getType() == ElementChangedEvent.POST_RECONCILE) | |
{ | |
handleReconcileEvent(event); | |
} | |
// handles ElementChangedEvent.POST_CHANGE - the case when the compilation unit has been changed | |
if (event.getDelta().getElement() != resource().javaModel()) | |
{ | |
return; | |
} | |
assert (event.getDelta().getFlags() & (IJavaElementDelta.F_CHILDREN | IJavaElementDelta.F_CONTENT)) != 0; | |
for (IJavaElementDelta child : event.getDelta().getAffectedChildren()) | |
{ | |
if (child.getElement() instanceof IJavaProject) | |
{ | |
handleChangedProject(child); | |
} | |
} | |
} | |
catch (CoreException ce) { | |
logger().logError("Unable to synchronize Web Service model upon java element delta "+ event.getDelta(), ce); //$NON-NLS-1$ | |
} | |
catch (WsDOMLoadCanceledException e) { | |
logger().logError("Unable to synchronize Web Service model upon java element delta " + event.getDelta(), e); //$NON-NLS-1$ | |
} | |
finally { | |
resource().enableSaving(); | |
} | |
} | |
protected void handleReconcileEvent(final ElementChangedEvent event) throws JavaModelException | |
{ | |
if(!(event.getDelta().getElement() instanceof ICompilationUnit )) { | |
return; | |
} | |
int requiredFlags = IJavaElementDelta.F_CONTENT | IJavaElementDelta.F_CHILDREN; | |
if ((event.getDelta().getFlags() & requiredFlags) == 0) { | |
return; | |
} | |
final ICompilationUnit cu = (ICompilationUnit)event.getDelta().getElement(); | |
if (!resource().approveProject(cu.getJavaProject())) { | |
return; | |
} | |
if (isJavaResource(cu)) { | |
handleChangedContentCompilationUnit(cu); | |
} | |
} | |
private boolean isJavaResource(ICompilationUnit cu) throws JavaModelException | |
{ | |
IJavaElement javaElement = cu; | |
while ((javaElement = javaElement.getParent()) != null) | |
{ | |
if (!javaElement.exists()) { | |
return false; | |
} | |
} | |
return true; | |
} | |
void handleChangedProject(IJavaElementDelta projectDelta) throws CoreException, WsDOMLoadCanceledException | |
{ | |
assert (projectDelta.getElement() instanceof IJavaProject); | |
if ((((projectDelta.getFlags() & IJavaElementDelta.F_CLOSED) != 0) || projectDelta.getKind() == IJavaElementDelta.REMOVED) | |
&& null != util().findProjectByName(getDomBeingLoaded(), projectDelta.getElement().getElementName())) | |
{ | |
//if the project has been closed then it's facet's could not be read. Thus the approve method | |
//will always return false. That's why we check if the project has already been in the | |
handleClosedProject(projectDelta); | |
} | |
if (!resource().approveProject((IJavaProject)projectDelta.getElement())) | |
{ | |
return; | |
} | |
if (((projectDelta.getFlags() & IJavaElementDelta.F_OPENED) != 0) || projectDelta.getKind() == IJavaElementDelta.ADDED) | |
{ | |
handleOpenedProject(projectDelta); | |
} | |
for (IJavaElementDelta childDelta : projectDelta.getAffectedChildren()) | |
{ | |
if (!(childDelta.getElement() instanceof IPackageFragmentRoot)) | |
{ | |
continue; | |
} | |
if ((childDelta.getFlags() & IJavaElementDelta.F_ADDED_TO_CLASSPATH) != 0) | |
{ | |
handleClosedProject(projectDelta); | |
handleOpenedProject(projectDelta); | |
} | |
if ((childDelta.getFlags() & IJavaElementDelta.F_REMOVED_FROM_CLASSPATH) != 0) | |
{ | |
handleClosedProject(projectDelta); | |
handleOpenedProject(projectDelta); | |
} | |
if ((childDelta.getFlags() & IJavaElementDelta.F_CHILDREN) != 0) | |
{ | |
recursevilyHandleRemovedPackages(childDelta); | |
recursevilyHandleAddedPackages(childDelta); | |
recursevilyHandleCompilationUnits(childDelta); | |
} | |
} | |
} | |
protected void recursevilyHandleAddedPackages(IJavaElementDelta rootDelta) throws JavaModelException | |
{ | |
final IWebServiceProject wsPrj = findProjectByDelta(rootDelta); | |
if (wsPrj == null) { | |
return; | |
} | |
for (IJavaElementDelta childDelta : rootDelta.getAffectedChildren()) | |
{ | |
if (childDelta.getElement() instanceof IPackageFragment && childDelta.getKind() == IJavaElementDelta.ADDED) | |
{ | |
for (ICompilationUnit cu : ((IPackageFragment)childDelta.getElement()).getCompilationUnits()) | |
{ | |
processCompilationUnit(wsPrj, cu); | |
} | |
recursevilyHandleAddedPackages(childDelta); | |
} | |
} | |
} | |
protected IWebServiceProject findProjectByDelta(IJavaElementDelta rootDelta) { | |
return util().findProjectByName(getDomBeingLoaded(), rootDelta.getElement().getJavaProject().getElementName()); | |
} | |
private void recursevilyHandleRemovedPackages(IJavaElementDelta rootDelta) throws JavaModelException | |
{ | |
for (IJavaElementDelta childDelta : rootDelta.getAffectedChildren()) | |
{ | |
if (childDelta.getElement() instanceof IPackageFragment) | |
{ | |
if (childDelta.getKind() == IJavaElementDelta.REMOVED) | |
{ | |
final IWebServiceProject wsPrj = findProjectByDelta(rootDelta); | |
if (wsPrj != null) { | |
removeModelElements(wsPrj, childDelta.getElement().getElementName(), true); | |
} | |
} else | |
{ | |
recursevilyHandleRemovedPackages(childDelta); | |
} | |
} | |
} | |
} | |
private void handleOpenedProject(IJavaElementDelta projectDelta) throws CoreException, WsDOMLoadCanceledException | |
{ | |
assert projectDelta.getElement() instanceof IJavaProject; | |
final IJavaProject changedProject = (IJavaProject) projectDelta.getElement(); | |
newProjectCUFinder(changedProject).find(null, new LoaderCompilationUnitHandler()); | |
} | |
private void handleClosedProject(IJavaElementDelta projectDelta) throws CoreException | |
{ | |
assert projectDelta.getElement() instanceof IJavaProject; | |
final IWebServiceProject wsPrj = util().findProjectByName(getDomBeingLoaded(), projectDelta.getElement().getElementName()); | |
if (wsPrj==null) { | |
return; | |
} | |
for (IServiceEndpointInterface sei : wsPrj.getServiceEndpointInterfaces()) | |
{ | |
sei.getImplementingWebServices().clear(); | |
} | |
for (IWebService ws : wsPrj.getWebServices()) | |
{ | |
serviceData().unmap(ws); | |
} | |
getDomBeingLoaded().getWebServiceProjects().remove(wsPrj); | |
} | |
private ICompilationUnitFinder newProjectCUFinder(final IJavaProject prj) | |
{ | |
return new WorkspaceCUFinder(resource().javaModel(), new IProjectSelector[] { new IProjectSelector() | |
{ | |
public boolean approve(IJavaProject toApprove) | |
{ | |
return prj.getElementName().equals(toApprove.getElementName()); | |
} | |
} }); | |
} | |
// handles compilation units - skips working copies | |
private void recursevilyHandleCompilationUnits(IJavaElementDelta delta) | |
{ | |
if (delta.getElement() instanceof ICompilationUnit) | |
{ | |
final ICompilationUnit cu = (ICompilationUnit) delta.getElement(); | |
if (util().findProjectByName(getDomBeingLoaded(), cu.getJavaProject().getElementName())==null) | |
{ | |
return; | |
} | |
try | |
{ | |
if (delta.getKind() == IJavaElementDelta.ADDED && (delta.getFlags() & IJavaElementDelta.F_MOVED_FROM) == 0) | |
{ | |
handleAddedCompilationUnit(cu); | |
} | |
if (delta.getKind() == IJavaElementDelta.REMOVED && (delta.getFlags() & IJavaElementDelta.F_MOVED_TO) == 0) | |
{ | |
handleRemovedCompilationUnit(cu); | |
} | |
if (delta.getKind() == IJavaElementDelta.REMOVED && (delta.getFlags() & IJavaElementDelta.F_MOVED_TO) != 0) | |
{ | |
handleMovedToCompilationUnit(cu, (ICompilationUnit) delta.getMovedToElement()); | |
} | |
if (delta.getKind() == IJavaElementDelta.CHANGED && | |
((delta.getFlags() & IJavaElementDelta.F_PRIMARY_RESOURCE) != 0) || | |
((delta.getFlags() & IJavaElementDelta.F_PRIMARY_WORKING_COPY) != 0)) | |
{ | |
handleChangedContentCompilationUnit(cu); | |
} | |
} catch (JavaModelException jme) | |
{ | |
logger().logError("Unable to parse the content of compilation unit" + delta.getElement(), jme); //$NON-NLS-1$ | |
} | |
} else | |
{ | |
for (IJavaElementDelta childDelta : delta.getAffectedChildren()) | |
{ | |
recursevilyHandleCompilationUnits(childDelta); | |
} | |
} | |
} | |
private void handleChangedContentCompilationUnit(ICompilationUnit cu) throws JavaModelException | |
{ | |
final IType type = cu.findPrimaryType(); | |
final IAnnotation<IType> annotation = type==null ? null : resource().newAnnotationInspector(type).inspectType(WS_ANNOTATION); | |
if (type == null || annotation == null) | |
{ | |
updateSubclassingWSElements(cu); | |
handleRemovedCompilationUnit(cu); | |
} else | |
{ | |
final IWebServiceProject wsProject = util().findProjectByName(getDomBeingLoaded(), cu.getJavaProject().getElementName()); | |
assert wsProject != null; | |
processCompilationUnit(wsProject, cu); | |
} | |
} | |
private void updateSubclassingWSElements(ICompilationUnit cu) throws JavaModelException | |
{ | |
for (IWebServiceProject wsPrj : getDomBeingLoaded().getWebServiceProjects()) | |
{ | |
final IJavaProject javaPrj = javaModel().getJavaProject(wsPrj.getName()); | |
for (IServiceEndpointInterface sei : wsPrj.getServiceEndpointInterfaces()) | |
{ | |
if(serviceData().getHierarchy(sei.getImplementation())==null) { | |
continue; | |
} | |
if (serviceData().getHierarchy(sei.getImplementation()).contains(cu)) | |
{ | |
processCompilationUnit(wsPrj, javaPrj.findType(sei.getImplementation()).getCompilationUnit()); | |
} | |
} | |
for (IWebService ws : wsPrj.getWebServices()) | |
{ | |
if(serviceData().getHierarchy(ws.getImplementation())==null) { | |
continue; | |
} | |
if (serviceData().getHierarchy(ws.getImplementation()).contains(cu)) | |
{ | |
processCompilationUnit(wsPrj, javaPrj.findType(ws.getImplementation()).getCompilationUnit()); | |
} | |
} | |
} | |
} | |
private void handleAddedCompilationUnit(ICompilationUnit addedCU) throws JavaModelException | |
{ | |
final IWebServiceProject wsPrj = util().findProjectByName(getDomBeingLoaded(), addedCU.getJavaProject().getElementName()); | |
this.processCompilationUnit(wsPrj, addedCU); | |
} | |
void handleMovedToCompilationUnit(ICompilationUnit fromCU, ICompilationUnit toCU) throws JavaModelException | |
{ | |
final IJavaWebServiceElement wsElem = guessContainedWSElement(fromCU); | |
if (wsElem == null) | |
{ | |
return; | |
} | |
final boolean fqNameChanged = !toCU.getElementName().equals(fromCU.getElementName()) | |
|| !toCU.getParent().getElementName().equals(fromCU.getParent().getElementName()); | |
if (fqNameChanged) | |
{ | |
handleRemovedCompilationUnit(fromCU); | |
handleAddedCompilationUnit(toCU); | |
} else | |
// then assume that the project only has changed. | |
{ | |
final IWebServiceProject toPrj = util().findProjectByName(getDomBeingLoaded(), toCU.getJavaProject().getElementName()); | |
if (wsElem instanceof IWebService) | |
{ | |
toPrj.getWebServices().add((IWebService) wsElem); | |
} else | |
{ | |
toPrj.getServiceEndpointInterfaces().add((IServiceEndpointInterface) wsElem); | |
} | |
} | |
} | |
private void handleRemovedCompilationUnit(ICompilationUnit remCU) throws JavaModelException | |
{ | |
final IWebServiceProject wsPrj = util().findProjectByName(getDomBeingLoaded(), remCU.getJavaProject().getElementName()); | |
removeModelElements(wsPrj, guessPrimaryTypeName(remCU), false); | |
} | |
private void removeModelElements(IWebServiceProject wsPrj, String implBaseName, boolean isForPackage) throws JavaModelException | |
{ | |
if (wsPrj == null) { | |
return; | |
} | |
removeWsModelElements(wsPrj, implBaseName, isForPackage); | |
removeSeiModelElements(wsPrj, implBaseName, isForPackage, false); | |
} | |
private IJavaWebServiceElement guessContainedWSElement(ICompilationUnit cu) | |
{ | |
final IWebServiceProject wsPrj = util().findProjectByName(getDomBeingLoaded(), cu.getJavaProject().getElementName()); | |
return util().findJavaWebServiceElemByImplName(wsPrj, guessPrimaryTypeName(cu)); | |
} | |
protected String guessPrimaryTypeName(ICompilationUnit cu) | |
{ | |
final String parentName = cu.getParent().getElementName(); | |
final StringBuilder assumedPrimaryTypeName = new StringBuilder(); | |
if (parentName.length() > 0) { | |
assumedPrimaryTypeName .append(parentName).append('.'); | |
} | |
return assumedPrimaryTypeName.append(cu.getElementName()). | |
delete(assumedPrimaryTypeName.lastIndexOf(".java"), assumedPrimaryTypeName.length()).toString();//$NON-NLS-1$ | |
} | |
} |