package org.eclipse.bpel.validator; | |
/** | |
* Java JDK dependencies | |
*/ | |
import java.util.ArrayList; | |
import java.util.Date; | |
import java.util.Iterator; | |
import java.util.List; | |
import java.util.Map; | |
import org.eclipse.bpel.model.Import; | |
import org.eclipse.bpel.model.Process; | |
import org.eclipse.bpel.model.resource.BPELResourceSetImpl; | |
import org.eclipse.bpel.model.resource.SAXParseDiagnostic; | |
import org.eclipse.bpel.validator.factory.AdapterFactory; | |
import org.eclipse.bpel.validator.helpers.ModelQueryImpl; | |
import org.eclipse.bpel.validator.model.INode; | |
import org.eclipse.bpel.validator.model.IProblem; | |
import org.eclipse.bpel.validator.model.Messages; | |
import org.eclipse.bpel.validator.model.Problem; | |
import org.eclipse.bpel.validator.model.Runner; | |
import org.eclipse.core.resources.IContainer; | |
import org.eclipse.core.resources.IFile; | |
import org.eclipse.core.resources.IFolder; | |
import org.eclipse.core.resources.IMarker; | |
import org.eclipse.core.resources.IProject; | |
import org.eclipse.core.resources.IResource; | |
import org.eclipse.core.resources.IResourceDelta; | |
import org.eclipse.core.resources.IResourceVisitor; | |
import org.eclipse.core.resources.IncrementalProjectBuilder; | |
import org.eclipse.core.runtime.CoreException; | |
import org.eclipse.core.runtime.IAdapterManager; | |
import org.eclipse.core.runtime.IConfigurationElement; | |
import org.eclipse.core.runtime.IProgressMonitor; | |
import org.eclipse.core.runtime.Path; | |
import org.eclipse.core.runtime.Platform; | |
import org.eclipse.core.runtime.content.IContentDescription; | |
import org.eclipse.core.runtime.content.IContentType; | |
import org.eclipse.emf.ecore.EObject; | |
import org.eclipse.emf.ecore.resource.Resource; | |
import org.eclipse.emf.ecore.resource.Resource.Diagnostic; | |
import org.eclipse.wst.wsdl.WSDLElement; | |
import org.w3c.dom.Element; | |
/** | |
* A builder which is invoked to build (in this case validate), the BPEL files | |
* in the projects in which the builder is installed. | |
* | |
* @author Michal Chmielewski (michal.chmielewski@oracle.com) | |
* @date Sep 19, 2006 | |
* | |
*/ | |
@SuppressWarnings("nls") | |
public class Builder extends IncrementalProjectBuilder { | |
// https://jira.jboss.org/jira/browse/JBIDE-6006 | |
// Content Type ID for org.eclipse.bpel editor files | |
public static final String BPEL_CONTENT_TYPE = "org.eclipse.bpel.contenttype"; //$NON-NLS-1$ | |
Date created = new Date(); | |
boolean bDebug = false; | |
/** Empty problems list */ | |
IProblem[] EMPTY_PROBLEMS = {}; | |
/** The adapter manager for the platform */ | |
IAdapterManager fAdapterManager = Platform.getAdapterManager(); | |
BPELResourceSetImpl fResourceSet = new BPELResourceSetImpl(); | |
BPELReader fReader = new BPELReader(); | |
/** | |
* Create brand new shiny BPEL Builder. | |
*/ | |
public Builder() { | |
p("Created on " + this.created); | |
} | |
/** (non-Javadoc) | |
* @see org.eclipse.core.resources.IncrementalProjectBuilder#setInitializationData(org.eclipse.core.runtime.IConfigurationElement, java.lang.String, java.lang.Object) | |
*/ | |
@Override | |
public void setInitializationData(IConfigurationElement config, String propertyName, Object data) throws CoreException { | |
super.setInitializationData(config, propertyName, data); | |
} | |
@Override | |
protected IProject[] build (int kind, Map args, IProgressMonitor monitor) | |
throws CoreException { | |
long started = System.currentTimeMillis(); | |
if (args != null) { | |
this.bDebug = toBoolean(args.get("debug"),false); | |
} | |
AdapterFactory.DEBUG = this.bDebug; | |
if (this.bDebug) { | |
p("Clear error messages from the cache ... (will re-load)"); | |
Messages.clear(); | |
} | |
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=330813 | |
// https://jira.jboss.org/browse/JBIDE-7116 | |
clearCach(); | |
IProject myProject = this.getProject(); | |
IResourceDelta resourceDelta = this.getDelta(myProject); | |
if (resourceDelta == null) { | |
// Now find all the BPEL files in the project and validate them | |
validate ( myProject, monitor ); | |
} else { | |
processDeltas(resourceDelta.getAffectedChildren( IResourceDelta.CHANGED ), monitor ); | |
} | |
long ended = System.currentTimeMillis(); | |
p(" Validation Ended " + (ended-started) + "ms"); | |
return new IProject[] { myProject }; | |
} | |
void processDeltas ( IResourceDelta [] deltas , IProgressMonitor monitor ) throws CoreException { | |
for(IResourceDelta delta : deltas) { | |
processDeltas( delta.getAffectedChildren(IResourceDelta.CHANGED, IResource.FILE), monitor ); | |
IResource resource = delta.getResource(); | |
if (resource.getType () != IResource.FILE) { | |
continue; | |
} | |
// * @see IResourceDelta#CONTENT | |
// * @see IResourceDelta#DESCRIPTION | |
// * @see IResourceDelta#ENCODING | |
// * @see IResourceDelta#OPEN | |
// * @see IResourceDelta#MOVED_TO | |
// * @see IResourceDelta#MOVED_FROM | |
// * @see IResourceDelta#TYPE | |
// * @see IResourceDelta#SYNC | |
// * @see IResourceDelta#MARKERS | |
// * @see IResourceDelta#REPLACED | |
if ((delta.getFlags() & IResourceDelta.CONTENT) != IResourceDelta.CONTENT ) { | |
continue; | |
} | |
this.fResourceSet.resourceChanged((IFile)resource); | |
validate ( resource, monitor ); | |
} | |
} | |
/** | |
* @see org.eclipse.core.resources.IncrementalProjectBuilder#clean(org.eclipse.core.runtime.IProgressMonitor) | |
*/ | |
@Override | |
protected void clean (IProgressMonitor monitor) throws CoreException { | |
removeProblemsAndTasksFor(getProject()); | |
} | |
public static void removeProblemsAndTasksFor(IResource resource) { | |
try { | |
if (resource != null && resource.exists()) { | |
resource.deleteMarkers(IBPELMarker.ID, false, IResource.DEPTH_INFINITE); | |
} | |
} catch (CoreException e) { | |
// assume there were no problems | |
} | |
} | |
/** | |
* Validate the resource using the monitor passed. | |
* | |
* @param resource (File or Folder) | |
* @param monitor the monitor to use. | |
* @throws CoreException | |
*/ | |
public void validate (IResource resource, IProgressMonitor monitor) throws CoreException { | |
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=330813 | |
// https://jira.jboss.org/browse/JBIDE-7116 | |
// enable element location tracking for error reporting | |
// TODO: move this to somewhere more appropriate when fixing JBIDE-6839 | |
Map<Object, Object> loadOptions = this.fResourceSet.getLoadOptions(); | |
loadOptions.put("TRACK_LOCATION", Boolean.TRUE); | |
this.fResourceSet.setLoadOptions(loadOptions); | |
switch (resource.getType()) { | |
case IResource.FOLDER : | |
IFolder folder = (IFolder) resource; | |
for(IResource next : folder.members() ) { | |
validate (next,monitor); | |
} | |
break; | |
case IResource.FILE : | |
IFile file = (IFile) resource; | |
p("File Resource : " + file.getName() ); | |
// https://jira.jboss.org/jira/browse/JBIDE-6006 | |
// use content type to check for BPEL files | |
if ( isBPELFile(file) || "wsdl".equalsIgnoreCase(file.getFileExtension()) ) { | |
IProject project = file.getProject(); | |
validate(project, monitor); | |
// file.deleteMarkers(IBPELMarker.ID, true, IResource.DEPTH_INFINITE); | |
// deleteMarkersInReferencialResources(file); | |
// makeMarkers ( validate ( file, monitor ) ); | |
} | |
break; | |
case IResource.PROJECT: | |
for(IFile bpelFile : getBPELFilesByProject((IProject)resource)){ | |
p("File Resource : " + bpelFile.getName() ); | |
bpelFile.deleteMarkers(IBPELMarker.ID, true, IResource.DEPTH_INFINITE); | |
deleteMarkersInReferencialResources(bpelFile); | |
makeMarkers ( validate ( bpelFile, monitor ) ); | |
} | |
} | |
} | |
private List<IFile> getBPELFilesByProject(IProject project){ | |
final List<IFile> bpelFolders = new ArrayList<IFile>(); | |
IResourceVisitor bpelFolderFinder = new IResourceVisitor() { | |
@Override | |
public boolean visit(IResource resource) throws CoreException { | |
if( resource.getType() == IResource.FILE){ | |
// https://jira.jboss.org/jira/browse/JBIDE-6006 | |
if(isBPELFile(resource)){ | |
bpelFolders.add((IFile)resource); | |
return false; | |
} | |
} | |
return true; | |
} | |
}; | |
try { | |
project.accept(bpelFolderFinder); | |
} catch (CoreException e) { | |
e.printStackTrace(); | |
} | |
return bpelFolders; | |
} | |
private void deleteMarkersInReferencialResources(IFile bpelFile) throws CoreException{ | |
this.fResourceSet.resourceChanged(bpelFile); | |
this.fReader.read( bpelFile, this.fResourceSet ); | |
Process process = this.fReader.getProcess(); | |
p("Delete markers"); | |
// https://jira.jboss.org/browse/JBIDE-6825 | |
// in case of XML parse errors, the Process will be null! | |
if (process == null) { | |
p ("Cannot read BPEL Process !!!"); | |
return; | |
} | |
IContainer container = bpelFile.getParent(); | |
for(Import impt : process.getImports()){ | |
String fileLocation = impt.getLocation(); | |
IFile importedFile = container.getFile(new Path(fileLocation)); | |
if(importedFile != null && importedFile.exists()){ | |
importedFile.deleteMarkers(IBPELMarker.ID, false, IResource.DEPTH_ZERO); | |
} | |
} | |
} | |
public void clearCach(){ | |
this.fResourceSet.getResources().clear(); | |
} | |
/** | |
* @param file | |
* @param monitor | |
* @return return the list of problems found | |
*/ | |
public IProblem[] validate (IFile file, IProgressMonitor monitor ) { | |
p("Validating BPEL Resource : " + file.getName() ); | |
// Step 1. Read the BPEL process using the Model API. | |
this.fResourceSet.resourceChanged(file); | |
this.fReader.read( file, this.fResourceSet ); | |
Process process = this.fReader.getProcess(); | |
if (process == null) { | |
// https://jira.jboss.org/browse/JBIDE-6825 | |
// if the resource failed to parse because of malformed XML, the Process | |
// will be null. Fetch the SAXParseDiagnostics from the resource and build | |
// problem markers for this resource. | |
Resource resource = this.fReader.getProcessResource(); | |
if ( resource!=null && !resource.getErrors().isEmpty() ) | |
{ | |
ArrayList<IProblem> problems = new ArrayList<IProblem>(resource.getErrors().size()); | |
for ( Diagnostic d : resource.getErrors()) | |
{ | |
IProblem problem = new Problem(); | |
problem.setAttribute(IProblem.ERESOURCE,resource); | |
if (d instanceof SAXParseDiagnostic && | |
((SAXParseDiagnostic)d).getSeverity() == SAXParseDiagnostic.WARNING) | |
{ | |
problem.setAttribute(IProblem.SEVERITY, IProblem.SEVERITY_WARNING); | |
} | |
else | |
problem.setAttribute(IProblem.SEVERITY, IProblem.SEVERITY_ERROR); | |
problem.setAttribute(IProblem.LINE_NUMBER, d.getLine()); | |
problem.setAttribute(IProblem.COLUMN_NUMBER, d.getColumn()); | |
problem.setAttribute(IProblem.MESSAGE, d.getMessage()); | |
problems.add(problem); | |
} | |
return problems.toArray( new Problem[problems.size()] ); | |
} | |
p ("Cannot read BPEL Process !!!"); | |
return this.EMPTY_PROBLEMS ; | |
} | |
p("Read in BPEL Model OK" ); | |
// Step 2. Preparation for the validator. | |
linkModels ( process ); | |
p("Models Linked" ); | |
// Process as INode | |
INode node = (INode) this.fAdapterManager.getAdapter( process.getElement(), INode.class ); | |
// Debug: Dump the dom from the reader, just to see what we have | |
// p( org.eclipse.bpel.model.util.BPELUtils.elementToString(process.getElement())); | |
// Step 4. Run the validator. | |
IProblem[] problemList = new Runner (ModelQueryImpl.getModelQuery(), node ).run(); | |
p("Validator Executed" ); | |
return problemList; | |
} | |
/** | |
* @param problemList | |
*/ | |
public void makeMarkers ( IProblem [] problemList ) { | |
if (problemList.length < 1) { | |
return ; | |
} | |
// Step 5. Adapt problems to markers. | |
for(IProblem problem : problemList) { | |
this.fAdapterManager.getAdapter(problem, IMarker.class); | |
} | |
p( "Markers Created " ); | |
p( " ------ Done" ); | |
// done. | |
} | |
void linkModels ( EObject process ) { | |
// | |
// Each extensible element points to the DOM element that | |
// comprises it. This is done in the BPEL reader as well as | |
// the WSDL readers. Here we add a pointer to the | |
// emf objects from the DOM objects. | |
Iterator<?> emfIterator = process.eAllContents(); | |
while (emfIterator.hasNext()) { | |
Object obj = emfIterator.next(); | |
// This is because only WSDLElement has a reference to | |
// a DOM element. | |
if (obj instanceof WSDLElement) { | |
WSDLElement wsdle = (WSDLElement) obj; | |
Element el = wsdle.getElement(); | |
if (el != null) { | |
// System.out.println(el.getOwnerDocument().getDocumentURI() + " " + el.getLocalName() + "----" + obj); | |
el.setUserData("emf.model", obj, null); //$NON-NLS-1$ | |
} | |
} | |
} | |
} | |
@SuppressWarnings("boxing") | |
boolean toBoolean ( Object obj , boolean def) { | |
if (obj instanceof String) { | |
return Boolean.valueOf((String)obj); | |
} | |
return def; | |
} | |
void p (String msg ) { | |
if (this.bDebug) { | |
System.out.printf( "[%1$s]>> %2$s\n", getClass().getName(), msg); | |
System.out.flush(); | |
} | |
} | |
// https://jira.jboss.org/jira/browse/JBIDE-6006 | |
public static boolean isBPELFile(IResource res) | |
{ | |
try | |
{ | |
if (res.getType() == IResource.FILE) { | |
IContentDescription desc = ((IFile) res).getContentDescription(); | |
if (desc != null) { | |
IContentType type = desc.getContentType(); | |
if (type.getId().equals(BPEL_CONTENT_TYPE)) | |
return true; | |
} | |
} | |
} | |
catch(Exception ex) | |
{ | |
} | |
return false; | |
} | |
} |