public final void notify(final String upstreamDependency, String downstreamDependency) { if (downstreamDependency == null) { notifyForGenericListener(upstreamDependency); return; } // Handle if the downstream dependency is "class level", meaning we need to figure out the // specific downstream MID this metadata provider wants to update/refresh. if (MetadataIdentificationUtils.isIdentifyingClass(downstreamDependency)) { // We have not identified an instance-specific downstream MID, so we'll need to calculate an // instance-specific downstream MID to retrieve. downstreamDependency = resolveDownstreamDependencyIdentifier(upstreamDependency); // We skip if the resolution method returns null, as it doesn't want to continue for some // reason if (downstreamDependency == null) { return; } Assert.isTrue( MetadataIdentificationUtils.isIdentifyingInstance(downstreamDependency), "An instance-specific downstream MID was required by '" + getClass().getName() + "' (not '" + downstreamDependency + "')"); // We only need to proceed if the downstream dependency relationship is not already // registered. // It is unusual to register a direct downstream relationship given it costs dependency // registration memory and class-level notifications will always occur anyway. if (metadataDependencyRegistry .getDownstream(upstreamDependency) .contains(downstreamDependency)) { return; } } // We should now have an instance-specific "downstream dependency" that can be processed by this // class Assert.isTrue( MetadataIdentificationUtils.getMetadataClass(downstreamDependency) .equals(MetadataIdentificationUtils.getMetadataClass(getProvidesType())), "Unexpected downstream notification for '" + downstreamDependency + "' to this provider (which uses '" + getProvidesType() + "'"); // We no longer notify downstreams here, as the "get" operation with eviction will ensure the // main get(String) method below will be fired and it // directly notified downstreams as part of that method (BPA 10 Dec 2010) metadataService.get(downstreamDependency, true); }
public void notifyDownstream(final String upstreamDependency) { try { metadataLogger.startEvent(); if (metadataService != null) { // First dispatch the fine-grained, instance-specific // dependencies. Set<String> notifiedDownstreams = new HashSet<String>(); for (final String downstream : getDownstream(upstreamDependency)) { if (metadataLogger.getTraceLevel() > 0) { metadataLogger.log(upstreamDependency + " -> " + downstream); } // No need to ensure upstreamDependency is different from // downstream, as that's taken care of in the // isValidDependency() method try { final String responsibleClass = MetadataIdentificationUtils.getMetadataClass(downstream); metadataLogger.startTimer(responsibleClass); metadataService.notify(upstreamDependency, downstream); } finally { metadataLogger.stopTimer(); } notifiedDownstreams.add(downstream); } // Next dispatch the coarse-grained, class-specific // dependencies. // We only do it if the upstream is not class specific, as // otherwise we'd have handled class-specific dispatch in // previous loop if (!MetadataIdentificationUtils.isIdentifyingClass(upstreamDependency)) { final String asClass = MetadataIdentificationUtils.getMetadataClassId(upstreamDependency); for (final String downstream : getDownstream(asClass)) { // We don't notify a downstream if it had a direct // instance-specific dependency and was already notified // in previous loop // We also don't notify if upstream is the same as // downstream, as it doesn't make sense to notify // yourself of an event // (such a condition is only possible if an instance // registered to receive class-specific notifications // and that instance // caused an event to fire) if (!notifiedDownstreams.contains(downstream) && !upstreamDependency.equals(downstream)) { if (metadataLogger.getTraceLevel() > 0) { metadataLogger.log(upstreamDependency + " -> " + downstream + " [via class]"); } try { final String responsibleClass = MetadataIdentificationUtils.getMetadataClass(downstream); metadataLogger.startTimer(responsibleClass); metadataService.notify(upstreamDependency, downstream); } finally { metadataLogger.stopTimer(); } } } } notifiedDownstreams = null; } // Finally dispatch the general-purpose additional listeners for (final MetadataNotificationListener listener : listeners) { if (metadataLogger.getTraceLevel() > 1) { metadataLogger.log( upstreamDependency + " -> " + upstreamDependency + " [" + listener.getClass().getSimpleName() + "]"); } try { final String responsibleClass = listener.getClass().getName(); metadataLogger.startTimer(responsibleClass); listener.notify(upstreamDependency, null); } finally { metadataLogger.stopTimer(); } } } finally { metadataLogger.stopEvent(); } }
public void notify(String upstreamDependency, String downstreamDependency) { ProjectMetadata projectMetadata = projectOperations.getProjectMetadata(); if (projectMetadata == null) { return; } if (MetadataIdentificationUtils.isIdentifyingClass(downstreamDependency)) { Assert.isTrue( MetadataIdentificationUtils.getMetadataClass(upstreamDependency) .equals( MetadataIdentificationUtils.getMetadataClass( PhysicalTypeIdentifier.getMetadataIdentiferType())), "Expected class-level notifications only for PhysicalTypeIdentifier (not '" + upstreamDependency + "')"); ClassOrInterfaceTypeDetails cid = typeLocationService.getTypeForIdentifier(upstreamDependency); boolean processed = false; if (MemberFindingUtils.getAnnotationOfType(cid.getAnnotations(), RooJavaType.ROO_GWT_REQUEST) != null) { ClassOrInterfaceTypeDetails proxy = gwtTypeService.lookupProxyFromRequest(cid); if (proxy != null) { JavaType typeName = PhysicalTypeIdentifier.getJavaType(proxy.getDeclaredByMetadataId()); Path typePath = PhysicalTypeIdentifier.getPath(proxy.getDeclaredByMetadataId()); downstreamDependency = GwtLocatorMetadata.createIdentifier(typeName, typePath); processed = true; } } if (!processed && MemberFindingUtils.getAnnotationOfType(cid.getAnnotations(), RooJavaType.ROO_GWT_PROXY) == null) { boolean found = false; for (ClassOrInterfaceTypeDetails classOrInterfaceTypeDetails : typeLocationService.findClassesOrInterfaceDetailsWithAnnotation( RooJavaType.ROO_GWT_PROXY)) { AnnotationMetadata annotationMetadata = GwtUtils.getFirstAnnotation( classOrInterfaceTypeDetails, GwtUtils.ROO_PROXY_REQUEST_ANNOTATIONS); if (annotationMetadata != null) { AnnotationAttributeValue<?> attributeValue = annotationMetadata.getAttribute("value"); if (attributeValue != null) { String mirrorName = GwtUtils.getStringValue(attributeValue); if (mirrorName != null && cid.getName().getFullyQualifiedTypeName().equals(attributeValue.getValue())) { found = true; JavaType typeName = PhysicalTypeIdentifier.getJavaType( classOrInterfaceTypeDetails.getDeclaredByMetadataId()); Path typePath = PhysicalTypeIdentifier.getPath( classOrInterfaceTypeDetails.getDeclaredByMetadataId()); downstreamDependency = GwtLocatorMetadata.createIdentifier(typeName, typePath); break; } } } } if (!found) { return; } } else if (!processed) { // A physical Java type has changed, and determine what the corresponding local metadata // identification string would have been JavaType typeName = PhysicalTypeIdentifier.getJavaType(upstreamDependency); Path typePath = PhysicalTypeIdentifier.getPath(upstreamDependency); downstreamDependency = GwtLocatorMetadata.createIdentifier(typeName, typePath); } // We only need to proceed if the downstream dependency relationship is not already registered // (if it's already registered, the event will be delivered directly later on) if (metadataDependencyRegistry .getDownstream(upstreamDependency) .contains(downstreamDependency)) { return; } } // We should now have an instance-specific "downstream dependency" that can be processed by this // class Assert.isTrue( MetadataIdentificationUtils.getMetadataClass(downstreamDependency) .equals(MetadataIdentificationUtils.getMetadataClass(getProvidesType())), "Unexpected downstream notification for '" + downstreamDependency + "' to this provider (which uses '" + getProvidesType() + "'"); metadataService.get(downstreamDependency, true); }