/** * Deletes the given ITD, either now or later. * * @param metadataId the ITD's metadata ID * @param itdFilename the ITD's filename * @param reason the reason for deletion; ignored if now is <code>false</code> * @param now whether to delete the ITD immediately; <code>false</code> schedules it for later * deletion; this is preferable when it's possible that the ITD might need to be re-created in * the meantime (e.g. because some ancestor metadata has changed to that effect), otherwise * there will be spurious console messages about the ITD being deleted and created */ private void deleteItd( final String metadataId, final String itdFilename, final String reason, final boolean now) { if (now) { fileManager.delete(itdFilename, reason); } else { fileManager.createOrUpdateTextFileIfRequired(itdFilename, "", false); } itdDiscoveryService.removeItdTypeDetails(metadataId); // TODO do we need to notify downstream dependencies that this ITD has gone away? }
public final MetadataItem get(final String metadataIdentificationString) { Assert.isTrue( MetadataIdentificationUtils.getMetadataClass(metadataIdentificationString) .equals(MetadataIdentificationUtils.getMetadataClass(getProvidesType())), "Unexpected request for '" + metadataIdentificationString + "' to this provider (which uses '" + getProvidesType() + "'"); // Remove the upstream dependencies for this instance (we'll be recreating them later, if // needed) metadataDependencyRegistry.deregisterDependencies(metadataIdentificationString); // Compute the identifier for the Physical Type Metadata we're correlated with String governorPhysicalTypeIdentifier = getGovernorPhysicalTypeIdentifier(metadataIdentificationString); // Obtain the physical type PhysicalTypeMetadata governorPhysicalTypeMetadata = (PhysicalTypeMetadata) metadataService.get(governorPhysicalTypeIdentifier); if (governorPhysicalTypeMetadata == null || !governorPhysicalTypeMetadata.isValid()) { // We can't get even basic information about the physical type, so abort (the ITD will be // deleted by ItdFileDeletionService) return null; } // Flag to indicate whether we'll even try to create this metadata boolean produceMetadata = false; // Determine if we should generate the metadata on the basis of it containing a trigger // annotation ClassOrInterfaceTypeDetails cid = null; if (governorPhysicalTypeMetadata.getMemberHoldingTypeDetails() instanceof ClassOrInterfaceTypeDetails) { cid = (ClassOrInterfaceTypeDetails) governorPhysicalTypeMetadata.getMemberHoldingTypeDetails(); // Only create metadata if the type is annotated with one of the metadata triggers for (JavaType trigger : metadataTriggers) { if (cid.getAnnotation(trigger) != null) { produceMetadata = true; break; } } } // Fall back to ignoring trigger annotations if (ignoreTriggerAnnotations) { produceMetadata = true; } // Cancel production if the governor type details are required, but aren't available if (dependsOnGovernorTypeDetailAvailability && cid == null) { produceMetadata = false; } // Cancel production if the governor is not a class, and the subclass only wants to know about // classes if (cid != null && dependsOnGovernorBeingAClass && cid.getPhysicalTypeCategory() != PhysicalTypeCategory.CLASS) { produceMetadata = false; } String itdFilename = governorPhysicalTypeMetadata.getItdCanonicalPath(this); if (!produceMetadata && isGovernor(cid) && fileManager.exists(itdFilename)) { // We don't seem to want metadata anymore, yet the ITD physically exists, so get rid of it // This might be because the trigger annotation has been removed, the governor is missing a // class declaration, etc. deleteItd( metadataIdentificationString, itdFilename, "not required for governor " + cid.getName(), true); return null; } if (produceMetadata) { // This type contains an annotation we were configured to detect, or there is an ITD (which // may need deletion), so we need to produce the metadata JavaType aspectName = governorPhysicalTypeMetadata.getItdJavaType(this); ItdTypeDetailsProvidingMetadataItem metadata = getMetadata( metadataIdentificationString, aspectName, governorPhysicalTypeMetadata, itdFilename); // There is no requirement to register a direct connection with the physical type and this // metadata because changes will // trickle down via the class-level notification registered by convention by // AbstractItdMetadataProvider subclasses (BPA 10 Dec 2010) if (metadata == null || !metadata.isValid()) { // The metadata couldn't be created properly deleteItd(metadataIdentificationString, itdFilename, "", false); return null; } // By this point we have a valid MetadataItem, but it might not contain any members for the // resulting ITD etc // Handle the management of the ITD file boolean deleteItdFile = false; ItdTypeDetails itdTypeDetails = metadata.getMemberHoldingTypeDetails(); if (itdTypeDetails == null) { // The ITD has no members deleteItdFile = true; } if (!deleteItdFile) { // We have some members in the ITD, so decide if we're to write something to disk ItdSourceFileComposer itdSourceFileComposer = new ItdSourceFileComposer(metadata.getMemberHoldingTypeDetails()); // Decide whether the get an ITD on-disk based on whether there is physical content to write if (itdSourceFileComposer.isContent()) { // We have content to write itdDiscoveryService.addItdTypeDetails(itdTypeDetails); String itd = itdSourceFileComposer.getOutput(); fileManager.createOrUpdateTextFileIfRequired(itdFilename, itd, false); } else { // We don't have content to write deleteItdFile = true; } } if (deleteItdFile) { deleteItd(metadataIdentificationString, itdFilename, null, false); } // Eagerly notify that the metadata has been updated; this also registers the metadata hash // code in the superclass' cache to avoid // unnecessary subsequent notifications if it hasn't changed notifyIfRequired(metadata); return metadata; } return null; }