package blade.migrate.provider; import blade.migrate.api.FileMigrator; import blade.migrate.api.Migration; import blade.migrate.api.MigrationListener; import blade.migrate.api.Problem; import blade.migrate.api.ProgressMonitor; import blade.migrate.api.ProjectMigrator; import blade.migrate.api.Reporter; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.nio.file.FileVisitResult; import java.nio.file.FileVisitor; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.SimpleFileVisitor; import java.nio.file.attribute.BasicFileAttributes; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; import org.osgi.framework.BundleContext; import org.osgi.framework.InvalidSyntaxException; import org.osgi.framework.ServiceReference; import org.osgi.service.component.annotations.Activate; import org.osgi.service.component.annotations.Component; import org.osgi.util.tracker.ServiceTracker; @Component(immediate = true) public class ProjectMigrationService implements Migration { @Activate public void activate(BundleContext context) { this.context = context; _migrationListenerTracker = new ServiceTracker<MigrationListener, MigrationListener>(context, MigrationListener.class, null); _migrationListenerTracker.open(); _fileMigratorTracker = new ServiceTracker<FileMigrator, FileMigrator>(context, FileMigrator.class, null); _fileMigratorTracker.open(); _projectMigratorTracker = new ServiceTracker<ProjectMigrator, ProjectMigrator>(context, ProjectMigrator.class, null); _projectMigratorTracker.open(); } @Override public List<Problem> findProblems(final File projectDir, final ProgressMonitor monitor) { monitor.beginTask("Searching for migration problems in " + projectDir, -1); final List<Problem> problems = new ArrayList<>(); ServiceReference<ProjectMigrator>[] projectMigrators = _projectMigratorTracker.getServiceReferences(); if (projectMigrators != null && projectMigrators.length > 0) { for (ServiceReference<ProjectMigrator> projectMigratorRef : projectMigrators) { if (!monitor.isCanceled()) { try { ProjectMigrator projectMigrator = context.getService(projectMigratorRef); List<Problem> migrationProblems = projectMigrator.analyze(projectDir); problems.addAll(migrationProblems); } catch (Exception e) { e.printStackTrace(); } } } } monitor.beginTask("Analyzing files", -1); walkFiles(projectDir, problems, monitor); monitor.done(); final MigrationListener[] listeners = _migrationListenerTracker .getServices(new MigrationListener[0]); for (MigrationListener listener : listeners) { try { listener.problemsFound(problems); } catch (Exception e) { // ignore } } return problems; } @Override public void reportProblems(List<Problem> problems, int detail, String format, Object... args) { Reporter reporter = null; try { Collection<ServiceReference<Reporter>> references = this.context.getServiceReferences(Reporter.class, "(format=" + format + ")"); if( references.size() > 0 ) { reporter = this.context.getService(references.iterator().next()); } else { ServiceReference<Reporter> sr = this.context.getServiceReference(Reporter.class); reporter = this.context.getService(sr); } } catch (InvalidSyntaxException e) { e.printStackTrace(); } OutputStream fos = null; if (args != null && args.length > 0) { if(args[0] instanceof File) { File outputFile = (File) args[0]; try { outputFile.getParentFile().mkdirs(); outputFile.createNewFile(); fos = new FileOutputStream(outputFile); } catch (IOException e) { e.printStackTrace(); } } else if(args[0] instanceof OutputStream) { fos = (OutputStream) args[0]; } } if (problems.size() != 0) { reporter.beginReporting(detail, fos); for (Problem problem : problems) { reporter.report(problem); } reporter.endReporting(); } } private void walkFiles(final File dir, final List<Problem> problems, final ProgressMonitor monitor) { final FileVisitor<Path> visitor = new SimpleFileVisitor<Path>() { @Override public FileVisitResult visitFile( Path path, BasicFileAttributes attrs) throws IOException { if (monitor.isCanceled()) { return FileVisitResult.TERMINATE; } File file = path.toFile(); if (file.isFile()) { String fileName = file.toPath().getFileName().toString(); String extension = fileName.substring( fileName.lastIndexOf('.')+1); monitor.setTaskName("Analyzing file " + fileName); ServiceReference<FileMigrator>[] fileMigrators = _fileMigratorTracker.getServiceReferences(); if(fileMigrators != null && fileMigrators.length > 0) { for (ServiceReference<FileMigrator> fm : fileMigrators) { if (monitor.isCanceled()) { return FileVisitResult.TERMINATE; } final List<String> fileExtensions = Arrays.asList( ((String) fm.getProperty("file.extensions")) .split(",")); if (fileExtensions != null && fileExtensions.contains(extension)) { final FileMigrator fmigrator = context.getService(fm); try { final List<Problem> fileProblems = fmigrator.analyze( file); if ( fileProblems != null && fileProblems.size() > 0) { problems.addAll(fileProblems); } } catch (Exception e) { e.printStackTrace(); } context.ungetService(fm); } } } } return super.visitFile(path, attrs); } }; try { Files.walkFileTree(dir.toPath(), visitor); } catch (IOException e) { e.printStackTrace(); } } private BundleContext context; private ServiceTracker<MigrationListener, MigrationListener> _migrationListenerTracker; private ServiceTracker<FileMigrator, FileMigrator> _fileMigratorTracker; private ServiceTracker<ProjectMigrator, ProjectMigrator> _projectMigratorTracker; }