Permalink
Browse files

[SMA-1] Add support for scanning mutiple archives at a time

The inputPath may now point to a single archive or to a directory. In the event
of it pointing to a directory the directory structure is scanned and every
archive that's found is analyzed. An archive is identified by the file being in
Zip format, i.e. there's no requirement for an archive to have a well-known
file suffix for it to be analyzed.

A separate report is produced for each archive that's analyzed. Each report is
written into its own directory beneath the configured outputPath location. In
the case of multiple archives being scanned, the directory structure of the
reports that are produced will mirror the structure of the directory that was
provided as input.
  • Loading branch information...
1 parent 09ce1b7 commit 93dcbb6f4880e799abcb0fa008cef9d781174267 @wilkinsona wilkinsona committed Dec 9, 2011
View
@@ -38,6 +38,11 @@
<scope>test</scope>
</dependency>
<dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-core</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2011 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.migrationanalyzer.commandline;
+
+import java.io.File;
+import java.util.List;
+
+interface ArchiveDiscoverer {
+
+ /**
+ * Discovers the archives that are to be analyzed by examining the given <code>location</code>. If no archives are
+ * found, an empty list must be returned, <strong>not</strong> null.
+ *
+ * @param location The location to examine
+ *
+ * @return the discovered archives that are to be analyzed
+ */
+ List<File> discover(File location);
+}
@@ -18,6 +18,7 @@
import java.io.File;
import java.io.IOException;
+import java.util.List;
import org.springframework.migrationanalyzer.analyze.AnalysisEngine;
import org.springframework.migrationanalyzer.analyze.AnalysisResult;
@@ -38,6 +39,8 @@
private final FileSystemFactory fileSystemFactory;
+ private final ArchiveDiscoverer archiveDiscoverer;
+
private final String inputPath;
private final String outputPath;
@@ -50,41 +53,60 @@
private static final String DEFAULT_OUTPUT_PATH = ".";
- CommandLineMigrationAnalysisExecutor(String inputPath, String outputType, String outputPath, String[] excludes) {
- this(inputPath, outputType, outputPath, excludes, new StandardAnalysisEngineFactory(), new StandardRenderEngineFactory(),
- new DirectoryFileSystemFactory());
+ CommandLineMigrationAnalysisExecutor(String inputPath, String outputType, String outputDirectory, String[] excludes) {
+ this(inputPath, outputType, outputDirectory, excludes, new StandardAnalysisEngineFactory(), new StandardRenderEngineFactory(),
+ new DirectoryFileSystemFactory(), new ZipArchiveDiscoverer());
}
- CommandLineMigrationAnalysisExecutor(String inputPath, String outputType, String outputPath, String[] excludes,
- AnalysisEngineFactory analysisEngineFactory, RenderEngineFactory renderEngineFactory, FileSystemFactory fileSystemFactory) {
+ CommandLineMigrationAnalysisExecutor(String inputPath, String outputType, String outputDirectory, String[] excludes,
+ AnalysisEngineFactory analysisEngineFactory, RenderEngineFactory renderEngineFactory, FileSystemFactory fileSystemFactory,
+ ArchiveDiscoverer archiveDiscoverer) {
this.analysisEngineFactory = analysisEngineFactory;
this.renderEngineFactory = renderEngineFactory;
this.fileSystemFactory = fileSystemFactory;
+ this.archiveDiscoverer = archiveDiscoverer;
this.inputPath = inputPath;
this.outputType = outputType;
- this.outputPath = outputPath == null ? DEFAULT_OUTPUT_PATH : outputPath;
+ this.outputPath = outputDirectory == null ? DEFAULT_OUTPUT_PATH : outputDirectory;
this.excludes = excludes == null ? DEFAULT_EXCLUDES : excludes;
}
@Override
public void execute() {
- FileSystem fileSystem = createFileSystem();
+ File inputFile = new File(this.inputPath);
+
+ List<File> discoveredArchives = this.archiveDiscoverer.discover(inputFile);
+
@snehalmistry

snehalmistry Dec 13, 2011

In case of many files, user would want to see progress of analysis. We can at least notify messages like: x no of archives found, analyzing x package.

@wilkinsona

wilkinsona via email Dec 13, 2011

Member
+ for (File discoveredArchive : discoveredArchives) {
+ analyzeArchive(discoveredArchive, inputFile);
+ }
+ }
+
+ private void analyzeArchive(File archive, File inputFile) {
+ FileSystem fileSystem = createFileSystem(archive);
AnalysisEngine analysisEngine = this.analysisEngineFactory.createAnalysisEngine(fileSystem, this.excludes);
- RenderEngine renderEngine = this.renderEngineFactory.create(this.outputType, this.outputPath);
+ RenderEngine renderEngine = this.renderEngineFactory.create(this.outputType, getOutputPath(inputFile, archive));
AnalysisResult analysis = analysisEngine.analyze();
renderEngine.render(analysis);
fileSystem.cleanup();
}
- private FileSystem createFileSystem() {
+ private String getOutputPath(File inputFile, File archive) {
+ if (inputFile.equals(archive)) {
+ return new File(this.outputPath, archive.getName()).getAbsolutePath();
+ } else {
+ return new File(this.outputPath, inputFile.toURI().relativize(archive.toURI()).getPath()).getAbsolutePath();
+ }
+ }
+
+ private FileSystem createFileSystem(File archive) {
FileSystem fileSystem;
- File inputFile = new File(this.inputPath);
try {
- fileSystem = this.fileSystemFactory.createFileSystem(inputFile);
+ fileSystem = this.fileSystemFactory.createFileSystem(archive);
} catch (IOException e) {
- throw new IllegalArgumentException(String.format("Failed to create FileSystem for input '" + inputFile.getAbsolutePath() + "'"), e);
+ throw new IllegalArgumentException(String.format("Failed to create FileSystem for archive '%s'", archive), e);
}
return fileSystem;
}
@@ -34,7 +34,8 @@ Options create() {
Options options = new Options();
options.addOption(OptionBuilder //
- .withDescription("The path to the input location") //
+ .withDescription(
+ "The path of the input location; either a single archive or a directory. In the case of a directory, the entire directory structure is examined and all archives that are found are analyzed") //
.isRequired() //
.hasArg() //
.withArgName("inputPath") //
@@ -48,7 +49,7 @@ Options create() {
.create(OPTION_KEY_OUTPUT_TYPE));
options.addOption(OptionBuilder //
- .withDescription("The path to the output location. Defaults to the current working directory") //
+ .withDescription("The path of the output directory. Defaults to the current working directory") //
.hasArg() //
.withArgName("outputPath") //
.create(OPTION_KEY_OUTPUT_PATH));
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2011 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.migrationanalyzer.commandline;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.migrationanalyzer.util.IoUtils;
+import org.springframework.migrationanalyzer.util.ZipUtils;
+
+final class ZipArchiveDiscoverer implements ArchiveDiscoverer {
+
+ private final Logger logger = LoggerFactory.getLogger(ZipArchiveDiscoverer.class);
+
+ @Override
+ public List<File> discover(File location) {
+ List<File> discovered = new ArrayList<File>();
+ doDiscover(location, discovered);
+ return discovered;
+ }
+
+ private void doDiscover(File candidate, List<File> discovered) {
+ if (candidate.isDirectory()) {
+ for (File inDirectory : candidate.listFiles()) {
+ doDiscover(inDirectory, discovered);
+ }
+ } else {
+ FileInputStream in = null;
+ try {
+ in = new FileInputStream(candidate);
+ if (ZipUtils.isZipFile(in)) {
+ discovered.add(candidate);
+ }
+ } catch (IOException ioe) {
+ this.logger.warn("Unable to examine candidate archive '{}', it will not be analyzed", candidate);
+ } finally {
+ IoUtils.closeQuietly(in);
+ }
+ }
+ }
+}
Oops, something went wrong.

0 comments on commit 93dcbb6

Please sign in to comment.