### Eclipse Workspace Patch 1.0 #P org.jboss.tools.ws.jaxrs.ui Index: src/org/jboss/tools/ws/jaxrs/ui/internal/utils/Logger.java =================================================================== --- src/org/jboss/tools/ws/jaxrs/ui/internal/utils/Logger.java (revision 37078) +++ src/org/jboss/tools/ws/jaxrs/ui/internal/utils/Logger.java (working copy) @@ -11,6 +11,10 @@ package org.jboss.tools.ws.jaxrs.ui.internal.utils; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; + import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Status; import org.jboss.tools.ws.jaxrs.ui.JBossJaxrsUIPlugin; @@ -26,6 +30,13 @@ /** The debug name, matching the .options file. */ private static final String DEBUG = JBossJaxrsUIPlugin.PLUGIN_ID + "/debug"; + private static final ThreadLocal dateFormatter = new ThreadLocal() { + @Override + protected DateFormat initialValue() { + return new SimpleDateFormat("HH:mm:ss.SSS"); + } + }; + /** * The private constructor of the static class. */ @@ -85,9 +96,30 @@ * the message to trace. */ public static void debug(final String message) { + debug(message, (Object[])null); + + } + + /** + * Outputs a debug message in the trace file (not the error view of the + * runtime workbench). Traces must be activated for this plugin in order to + * see the output messages. + * + * @param message + * the message to trace. + */ + public static void debug(final String message, Object... items) { String debugOption = Platform.getDebugOption(DEBUG); - if (JBossJaxrsUIPlugin.getDefault().isDebugging() && "true".equalsIgnoreCase(debugOption)) { - System.out.println("[" + Thread.currentThread().getName() + "] " + message); + String valuedMessage = message; + if (JBossJaxrsUIPlugin.getDefault() != null && JBossJaxrsUIPlugin.getDefault().isDebugging() + && "true".equalsIgnoreCase(debugOption)) { + if (items != null) { + for (Object item : items) { + valuedMessage = valuedMessage.replaceFirst("\\{\\}", (item != null ? item.toString() : "null")); + } + } + System.out.println(dateFormatter.get().format(new Date()) + " [" + Thread.currentThread().getName() + "] " + + valuedMessage); } } #P org.jboss.tools.ws.jaxrs.core Index: src/org/jboss/tools/ws/jaxrs/core/jdt/CompilationUnitsRepository.java =================================================================== --- src/org/jboss/tools/ws/jaxrs/core/jdt/CompilationUnitsRepository.java (revision 37078) +++ src/org/jboss/tools/ws/jaxrs/core/jdt/CompilationUnitsRepository.java (working copy) @@ -7,6 +7,7 @@ import java.util.Map.Entry; import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.jdt.core.IAnnotation; import org.eclipse.jdt.core.ICompilationUnit; @@ -16,6 +17,7 @@ import org.eclipse.jdt.core.compiler.IProblem; import org.eclipse.jdt.core.dom.CompilationUnit; import org.jboss.tools.ws.jaxrs.core.internal.utils.CollectionUtils; +import org.jboss.tools.ws.jaxrs.core.internal.utils.Logger; public class CompilationUnitsRepository { @@ -23,7 +25,7 @@ private final Map> methodDeclarationsMap = new HashMap>(); - private final Map astMap = new HashMap(); + private final Map astMap = new HashMap(); private final Map> problemsMap = new HashMap>(); @@ -47,15 +49,19 @@ * @return * @throws JavaModelException */ public CompilationUnit getAST(final ICompilationUnit compilationUnit) throws JavaModelException { - if(compilationUnit == null) { + if(compilationUnit == null || compilationUnit.getResource() == null) { return null; } final IResource resource = compilationUnit.getResource(); - if (!astMap.containsKey(resource)) { + final IPath resourcePath = resource.getFullPath(); + if (!astMap.containsKey(resourcePath)) { + Logger.debug("Adding {}'s AST in CompilationUnitsRepository cache.", compilationUnit.getElementName()); recordUnit(compilationUnit); + } else { + Logger.debug("CompilationUnitsRepository cache contains {}'s AST.", compilationUnit.getElementName()); } - - return astMap.get(resource); + + return astMap.get(resourcePath); } @@ -77,7 +83,7 @@ return null; } CompilationUnit compilationUnitAST = JdtUtils.parse(compilationUnit, new NullProgressMonitor()); - astMap.put(compilationUnit.getResource(), compilationUnitAST); + astMap.put(compilationUnit.getResource().getFullPath(), compilationUnitAST); JavaMethodSignaturesVisitor methodsVisitor = new JavaMethodSignaturesVisitor(compilationUnit); compilationUnitAST.accept(methodsVisitor); methodDeclarationsMap.put(compilationUnit, methodsVisitor.getMethodSignatures()); @@ -97,7 +103,7 @@ diffs = new ArrayList(); } // replace old values in "cache" - astMap.put(compilationUnit.getResource(), compilationUnitAST); + astMap.put(compilationUnit.getResource().getFullPath(), compilationUnitAST); // TODO : improve performances here : do not override all method // declaration, but only those that changed, because reparsing method // signatures (annotated parameters, etc.) may be expensive. @@ -119,8 +125,10 @@ } public void removeAST(final ICompilationUnit compilationUnit) { + final IPath fullPath = compilationUnit.getResource().getFullPath(); + Logger.debug("Removing {}'s AST from CompilationUnitsRepository (path={})", compilationUnit, fullPath); methodDeclarationsMap.remove(compilationUnit); - astMap.remove(compilationUnit); + astMap.remove(fullPath); problemsMap.remove(compilationUnit); } Index: src/org/jboss/tools/ws/jaxrs/core/internal/metamodel/builder/JaxrsElementChangedProcessor.java =================================================================== --- src/org/jboss/tools/ws/jaxrs/core/internal/metamodel/builder/JaxrsElementChangedProcessor.java (revision 37078) +++ src/org/jboss/tools/ws/jaxrs/core/internal/metamodel/builder/JaxrsElementChangedProcessor.java (working copy) @@ -38,6 +38,7 @@ IProgressMonitor progressMonitor) { final List changes = new ArrayList(); try { + Logger.debug("Processing {} Jaxrs change(s)...", jaxrsElementChanges.size()); for (JaxrsElementChangedEvent jaxrsElementChange : jaxrsElementChanges) { Logger.debug("Processing {}", jaxrsElementChange); final List endpointChanges = processEvent(jaxrsElementChange); @@ -46,15 +47,15 @@ } changes.addAll(endpointChanges); } - Logger.debug("Done processing JAX-RS change(s)."); } catch (CoreException e) { Logger.error("Failed to process JAX-RS element changes", e); + } finally { + Logger.debug("Done processing JAX-RS change(s)."); } return changes; } private List processEvent(final JaxrsElementChangedEvent event) throws CoreException { - Logger.debug("Processing JAX-RS change {}", event); final IJaxrsElement element = event.getElement(); final EnumElementKind elementKind = element.getElementKind(); final int flags = event.getFlags(); Index: src/org/jboss/tools/ws/jaxrs/core/internal/metamodel/builder/JaxrsMetamodelBuildJob.java =================================================================== --- src/org/jboss/tools/ws/jaxrs/core/internal/metamodel/builder/JaxrsMetamodelBuildJob.java (revision 37078) +++ src/org/jboss/tools/ws/jaxrs/core/internal/metamodel/builder/JaxrsMetamodelBuildJob.java (working copy) @@ -3,6 +3,7 @@ */ package org.jboss.tools.ws.jaxrs.core.internal.metamodel.builder; +import java.util.ArrayList; import java.util.List; import org.eclipse.core.resources.IProject; @@ -19,7 +20,10 @@ import org.eclipse.jdt.internal.core.JavaElementDelta; import org.jboss.tools.ws.jaxrs.core.internal.metamodel.domain.JaxrsMetamodel; import org.jboss.tools.ws.jaxrs.core.internal.utils.Logger; +import org.jboss.tools.ws.jaxrs.core.metamodel.IJaxrsEndpoint; import org.jboss.tools.ws.jaxrs.core.pubsub.EventService; +import static org.eclipse.jdt.core.IJavaElementDelta.REMOVED; + /** @author xcoulon */ @SuppressWarnings("restriction") @@ -43,7 +47,16 @@ if (metamodel == null) { JaxrsMetamodel.create(javaProject); } else if (requiresReset) { + // copying the references to the endpoints into a new list before it is reset + final List allEndpoints = new ArrayList(metamodel.getAllEndpoints()); metamodel.reset(); + // now, notifying of the actual removals to the UI + for (IJaxrsEndpoint endpoint : allEndpoints) { + JaxrsEndpointChangedEvent change = new JaxrsEndpointChangedEvent(endpoint, REMOVED); + Logger.debug(change.toString()); + EventService.getInstance().publish(change); + } + } } @@ -60,8 +73,9 @@ @Override protected IStatus run(IProgressMonitor progressMonitor) { try { - progressMonitor.beginTask("Build JAX-RS Metamodel", 8 * SCALE); + progressMonitor.beginTask("Building JAX-RS Metamodel", 8 * SCALE); progressMonitor.worked(SCALE); + Logger.debug("Building JAX-RS Metamodel after {}", event); // create fake event at the JavaProject level: // scan and filter delta, retrieve a list of java changes final List events = new ElementChangedEventScanner().scanAndFilterEvent(event, @@ -74,13 +88,13 @@ events, progressMonitor); final List jaxrsEndpointChanges = jaxrsElementChangedProcessor.processEvents( jaxrsElementChanges, progressMonitor); - if(jaxrsEndpointChanges == null || jaxrsEndpointChanges.isEmpty()) { + if (jaxrsEndpointChanges == null || jaxrsEndpointChanges.isEmpty()) { Logger.debug("No JAX-RS change to publish to the UI"); } else { - for (JaxrsEndpointChangedEvent change : jaxrsEndpointChanges) { - Logger.debug(change.toString()); - EventService.getInstance().publish(change); - } + for (JaxrsEndpointChangedEvent change : jaxrsEndpointChanges) { + Logger.debug(change.toString()); + EventService.getInstance().publish(change); + } } } catch (Throwable e) { Logger.error("Failed to build or refresh the JAX-RS metamodel", e); Index: src/org/jboss/tools/ws/jaxrs/core/internal/metamodel/builder/JavaElementChangedProcessor.java =================================================================== --- src/org/jboss/tools/ws/jaxrs/core/internal/metamodel/builder/JavaElementChangedProcessor.java (revision 37078) +++ src/org/jboss/tools/ws/jaxrs/core/internal/metamodel/builder/JavaElementChangedProcessor.java (working copy) @@ -53,7 +53,8 @@ IProgressMonitor progressMonitor) { final List impacts = new ArrayList(); try { - progressMonitor.beginTask("Processing Java changes...", events.size()); + progressMonitor.beginTask("Processing {} Java change(s)...", events.size()); + Logger.debug("Processing {} Java change(s)...", events.size()); for (JavaElementChangedEvent event : events) { impacts.addAll(processEvent(event, progressMonitor)); progressMonitor.worked(1); @@ -63,6 +64,8 @@ impacts.clear(); } finally { progressMonitor.done(); + Logger.debug("Done processing Java changes."); + } return impacts; } @@ -146,23 +149,26 @@ private List processAddition(final IJavaElement scope, final JaxrsMetamodel metamodel, final IProgressMonitor progressMonitor) throws CoreException { final List impacts = new ArrayList(); - // let's see if the given project contains JAX-RS HTTP Methods - final List matchingHttpMethodTypes = JaxrsAnnotationsScanner.findHTTPMethodTypes(scope, progressMonitor); - for (IType type : matchingHttpMethodTypes) { - final CompilationUnit ast = JdtUtils.parse(type, progressMonitor); - final Annotation annotation = JdtUtils.resolveAnnotation(type, ast, HttpMethod.class); - final JaxrsHttpMethod httpMethod = factory.createHttpMethod(annotation, ast, metamodel); - if (httpMethod != null) { - impacts.add(new JaxrsElementChangedEvent(httpMethod, ADDED)); + if(metamodel.getElement(scope) == null) { + // process this type as it is not already known from the metamodel + // let's see if the given project contains JAX-RS HTTP Methods + final List matchingHttpMethodTypes = JaxrsAnnotationsScanner.findHTTPMethodTypes(scope, progressMonitor); + for (IType type : matchingHttpMethodTypes) { + final CompilationUnit ast = JdtUtils.parse(type, progressMonitor); + final Annotation annotation = JdtUtils.resolveAnnotation(type, ast, HttpMethod.class); + final JaxrsHttpMethod httpMethod = factory.createHttpMethod(annotation, ast, metamodel); + if (httpMethod != null) { + impacts.add(new JaxrsElementChangedEvent(httpMethod, ADDED)); + } } - } - // let's see if the given project contains JAX-RS HTTP Resources - final List matchingResourceTypes = JaxrsAnnotationsScanner.findResources(scope, progressMonitor); - for (IType type : matchingResourceTypes) { - final CompilationUnit ast = JdtUtils.parse(type, progressMonitor); - final JaxrsResource resource = factory.createResource(type, ast, metamodel); - if (resource != null) { - impacts.add(new JaxrsElementChangedEvent(resource, ADDED)); + // let's see if the given project contains JAX-RS HTTP Resources + final List matchingResourceTypes = JaxrsAnnotationsScanner.findResources(scope, progressMonitor); + for (IType type : matchingResourceTypes) { + final CompilationUnit ast = JdtUtils.parse(type, progressMonitor); + final JaxrsResource resource = factory.createResource(type, ast, metamodel); + if (resource != null) { + impacts.add(new JaxrsElementChangedEvent(resource, ADDED)); + } } } @@ -328,6 +334,7 @@ final List> elements = metamodel.getElements(compilationUnit); for (IJaxrsElement element : elements) { metamodel.remove(element); + CompilationUnitsRepository.getInstance().removeAST(compilationUnit); impacts.add(new JaxrsElementChangedEvent(element, REMOVED)); } return impacts; Index: src/org/jboss/tools/ws/jaxrs/core/internal/metamodel/builder/JaxrsElementChangedEvent.java =================================================================== --- src/org/jboss/tools/ws/jaxrs/core/internal/metamodel/builder/JaxrsElementChangedEvent.java (revision 37078) +++ src/org/jboss/tools/ws/jaxrs/core/internal/metamodel/builder/JaxrsElementChangedEvent.java (working copy) @@ -90,7 +90,9 @@ @Override public String toString() { StringBuilder s = new StringBuilder(); - s.append("JaxrsElementChange: [").append(ConstantUtils.getStaticFieldName(IJavaElementDelta.class, deltaKind)) + s.append("JaxrsElementChange: [") + .append(ConstantUtils.toCamelCase(element.getElementKind().toString())) + .append(" ").append(ConstantUtils.getStaticFieldName(IJavaElementDelta.class, deltaKind)) .append("] ").append(element.getJavaElement().getElementName()); try { Index: src/org/jboss/tools/ws/jaxrs/core/internal/metamodel/domain/JaxrsMetamodel.java =================================================================== --- src/org/jboss/tools/ws/jaxrs/core/internal/metamodel/domain/JaxrsMetamodel.java (revision 37078) +++ src/org/jboss/tools/ws/jaxrs/core/internal/metamodel/domain/JaxrsMetamodel.java (working copy) @@ -246,6 +246,13 @@ /** @param jaxrsElement */ protected void unindexElement(final IJaxrsElement jaxrsElement) { + // if the given element is a JAX-RS Resource, also unindex its children ResourceMethod + if(jaxrsElement.getElementKind() == EnumElementKind.RESOURCE) { + for(IJaxrsResourceMethod resourceMethod : ((IJaxrsResource)jaxrsElement).getAllMethods()) { + unindexElement(resourceMethod); + } + } + // unindex the given element, whatever its kind for (Iterator>>> iterator = elementsIndex.entrySet().iterator(); iterator .hasNext();) { final Entry>> entry = iterator.next(); @@ -385,6 +392,7 @@ this.providers.clear(); this.resources.clear(); this.elementsIndex.clear(); + this.endpoints.clear(); } /** Index: src/org/jboss/tools/ws/jaxrs/core/internal/metamodel/domain/JaxrsElementFactory.java =================================================================== --- src/org/jboss/tools/ws/jaxrs/core/internal/metamodel/domain/JaxrsElementFactory.java (revision 37078) +++ src/org/jboss/tools/ws/jaxrs/core/internal/metamodel/domain/JaxrsElementFactory.java (working copy) @@ -220,7 +220,7 @@ } } if (httpMethod == null && pathAnnotation == null) { - Logger.debug("Cannot create ResourceMethod: no Path annotation nor HttpMethod found on that method !"); + Logger.debug("Cannot create ResourceMethod: no Path annotation nor HttpMethod found on method {}.{}()", javaMethod.getParent().getElementName(), javaMethod.getElementName()); } else { final Annotation producesAnnotation = annotations.get(Produces.class.getName()); final Annotation consumesAnnotation = annotations.get(Consumes.class.getName()); Index: src/org/jboss/tools/ws/jaxrs/core/internal/utils/ConstantUtils.java =================================================================== --- src/org/jboss/tools/ws/jaxrs/core/internal/utils/ConstantUtils.java (revision 37078) +++ src/org/jboss/tools/ws/jaxrs/core/internal/utils/ConstantUtils.java (working copy) @@ -52,7 +52,7 @@ return result; } - static String toCamelCase(String s) { + public static String toCamelCase(String s) { String[] parts = s.split("_"); String camelCaseString = ""; for (String part : parts) { Index: src/org/jboss/tools/ws/jaxrs/core/internal/utils/Logger.java =================================================================== --- src/org/jboss/tools/ws/jaxrs/core/internal/utils/Logger.java (revision 37078) +++ src/org/jboss/tools/ws/jaxrs/core/internal/utils/Logger.java (working copy) @@ -119,10 +119,7 @@ * the message to trace. */ public static void debug(final String message) { - String debugOption = Platform.getDebugOption(DEBUG); - if (JBossJaxrsCorePlugin.getDefault().isDebugging() && "true".equalsIgnoreCase(debugOption)) { - System.out.println("[" + Thread.currentThread().getName() + "] " + message); - } + debug(message, (Object[])null); } @@ -139,10 +136,11 @@ String valuedMessage = message; if (JBossJaxrsCorePlugin.getDefault() != null && JBossJaxrsCorePlugin.getDefault().isDebugging() && "true".equalsIgnoreCase(debugOption)) { - for (Object item : items) { - valuedMessage = valuedMessage.replaceFirst("\\{\\}", (item != null ? item.toString() : "null")); + if (items != null) { + for (Object item : items) { + valuedMessage = valuedMessage.replaceFirst("\\{\\}", (item != null ? item.toString() : "null")); + } } - System.out.println(dateFormatter.get().format(new Date()) + " [" + Thread.currentThread().getName() + "] " + valuedMessage); }