package org.springframework.roo.project;
import static org.springframework.roo.file.monitor.event.FileOperation.CREATED;
import static org.springframework.roo.file.monitor.event.FileOperation.DELETED;
import static org.springframework.roo.file.monitor.event.FileOperation.MONITORING_FINISH;
import static org.springframework.roo.file.monitor.event.FileOperation.MONITORING_START;
import static org.springframework.roo.file.monitor.event.FileOperation.RENAMED;
import static org.springframework.roo.file.monitor.event.FileOperation.UPDATED;
import java.io.File;
import org.apache.commons.lang3.StringUtils;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.Service;
import org.osgi.service.component.ComponentContext;
import org.springframework.roo.file.monitor.DirectoryMonitoringRequest;
import org.springframework.roo.file.monitor.MonitoringRequest;
import org.springframework.roo.file.monitor.NotifiableFileMonitorService;
import org.springframework.roo.file.monitor.event.FileOperation;
import org.springframework.roo.file.undo.UndoManager;
import org.springframework.roo.metadata.MetadataDependencyRegistry;
import org.springframework.roo.metadata.MetadataNotificationListener;
import org.springframework.roo.metadata.internal.MetadataDependencyRegistryTracker;
/**
*
*/
@Component
@Service
public class ProjectPathMonitoringInitializer implements MetadataNotificationListener {
private static final FileOperation[] MONITORED_OPERATIONS = {MONITORING_START, MONITORING_FINISH,
CREATED, RENAMED, UPDATED, DELETED};
@Reference
private NotifiableFileMonitorService fileMonitorService;
@Reference
private PathResolver pathResolver;
private boolean pathsRegistered;
@Reference
private UndoManager undoManager;
protected MetadataDependencyRegistryTracker registryTracker = null;
/**
* This service is being activated so setup it:
* <ul>
* <li>Create and open the {@link MetadataDependencyRegistryTracker}.</li>
* </ul>
*/
protected void activate(final ComponentContext context) {
this.registryTracker = new MetadataDependencyRegistryTracker(context.getBundleContext(), this);
this.registryTracker.open();
}
/**
* This service is being deactivated so unregister upstream-downstream
* dependencies, triggers, matchers and listeners.
*
* @param context
*/
protected void deactivate(final ComponentContext context) {
MetadataDependencyRegistry registry = this.registryTracker.getService();
registry.removeNotificationListener(this);
this.registryTracker.close();
}
private void monitorPathIfExists(final LogicalPath logicalPath) {
final String canonicalPath = pathResolver.getRoot(logicalPath);
// The path can be blank if a sub-folder contains a POM that doesn't
// belong to a module
if (StringUtils.isNotBlank(canonicalPath)) {
final File directory = new File(canonicalPath);
if (directory.isDirectory()) {
final MonitoringRequest request =
new DirectoryMonitoringRequest(directory, true, MONITORED_OPERATIONS);
new UndoableMonitoringRequest(undoManager, fileMonitorService, request, true);
}
}
}
private void monitorProjectPaths() {
for (final LogicalPath logicalPath : pathResolver.getPaths()) {
if (requiresMonitoring(logicalPath)) {
monitorPathIfExists(logicalPath);
}
}
}
public void notify(final String upstreamDependency, final String downstreamDependency) {
if (pathsRegistered) {
return;
}
monitorProjectPaths();
pathsRegistered = true;
}
private boolean requiresMonitoring(final LogicalPath logicalPath) {
if (logicalPath.isProjectRoot()) {
return false; // already monitored by ProcessManager
}
if (StringUtils.isBlank(logicalPath.getModule())) {
return true; // non-root path within root module
}
return logicalPath.isModuleRoot();
}
}