package org.springframework.roo.classpath.itd; import java.io.File; import org.apache.commons.lang3.Validate; import org.apache.felix.scr.annotations.Component; import org.apache.felix.scr.annotations.Reference; import org.apache.felix.scr.annotations.Service; import org.springframework.roo.classpath.PhysicalTypeMetadata; import org.springframework.roo.file.monitor.event.FileDetails; import org.springframework.roo.file.monitor.event.FileEvent; import org.springframework.roo.file.monitor.event.FileEventListener; import org.springframework.roo.process.manager.FileManager; /** * Automatically deletes any ITD that should not exist due to the non-existence * of the {@link PhysicalTypeMetadata} that the ITD would have been introduced * into. * <p> * This service will only delete files matching the syntax *_Roo_*.aj, and then * only if the leftmost wildcard represents a filename that does not have a * .java file in the same directory. For example, if the file * src/main/java/com/foo/Bar_Roo_Hello.aj was detected as existing, it will be * deleted unless src/main/java/com/foo/Bar.java also presently exists. * * @author Ben Alex * @since 1.0 */ @Component @Service public class ItdFileDeletionService implements FileEventListener { private static String ANT_PATH_ALL_ITD_SOURCE = "**" + File.separator + "*_Roo_*.aj"; private static String ANT_PATH_ALL_JAVA_SOURCE = "**" + File.separator + "*.java"; static { if ("/".equals(File.separator)) { // This is a *nix box and thus starts all paths with a slash // (ROO-34) ANT_PATH_ALL_ITD_SOURCE = File.separator + ANT_PATH_ALL_ITD_SOURCE; ANT_PATH_ALL_JAVA_SOURCE = File.separator + ANT_PATH_ALL_JAVA_SOURCE; } } @Reference private FileManager fileManager; public void onFileEvent(final FileEvent fileEvent) { Validate.notNull(fileEvent, "File event required"); if (fileEvent.getFileDetails().matchesAntPath(ANT_PATH_ALL_ITD_SOURCE)) { // It's a ROO ITD, but check it really exists if (!fileEvent.getFileDetails().getFile().exists()) { return; } // It exists, so compute the governor filename final String path = fileEvent.getFileDetails().getCanonicalPath(); final int lastIndex = path.lastIndexOf("_Roo_"); final String governorName = path.substring(0, lastIndex) + ".java"; if (!fileManager.exists(governorName)) { // We just checked the disk, and the governor does not exist, so // blow away the ITD fileManager.delete(fileEvent.getFileDetails().getCanonicalPath(), fileEvent .getFileDetails().getFile().getName() + " not found"); } } else if (fileEvent.getFileDetails().matchesAntPath(ANT_PATH_ALL_JAVA_SOURCE)) { // It's a Java file, but we only cleanup on deletion in this case if (!fileEvent.getFileDetails().getFile().exists()) { // Java file was deleted, so let's get rid of any ITDs that are // laying around final String governorName = fileEvent.getFileDetails().getCanonicalPath(); final int lastIndex = governorName.lastIndexOf(".java"); final String itdAntPath = governorName.substring(0, lastIndex) + "_Roo_*.aj"; for (final FileDetails itd : fileManager.findMatchingAntPath(itdAntPath)) { final String itdCanonicalPath = itd.getCanonicalPath(); if (fileManager.exists(itdCanonicalPath)) { fileManager.delete(itdCanonicalPath, fileEvent.getFileDetails().getFile().getName() + " not found"); } } } } } }