
org.apache.tapestry5.versionmigrator.Main Maven / Gradle / Ivy
The newest version!
// 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.apache.tapestry5.versionmigrator;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Formatter;
import java.util.List;
import java.util.Optional;
import java.util.Properties;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import org.apache.tapestry5.versionmigrator.internal.ArtifactChangeRefactorCommitParser;
import org.apache.tapestry5.versionmigrator.internal.PackageAndArtifactChangeRefactorCommitParser;
import org.apache.tapestry5.versionmigrator.internal.PackageChangeRefactorCommitParser;
public class Main
{
public static void main(String[] args)
{
if (args.length == 0)
{
printHelp();
}
else
{
TapestryVersion version = getTapestryVersion(args[1]);
switch (args[0])
{
case "generate":
createVersionFile(version);
break;
case "upgrade":
upgrade(version);
break;
default:
printHelp();
}
}
}
private static void upgrade(TapestryVersion version)
{
String path = "/" + getFileRelativePath(getSimpleFileName(version));
Properties properties = new Properties();
try (InputStream inputStream = Main.class.getResourceAsStream(path))
{
properties.load(inputStream);
} catch (IOException e) {
throw new RuntimeException(e);
}
List sourceFiles = getJavaFiles();
System.out.println("Number of renamed or moved classes: " + properties.size());
System.out.println("Number of source files found: " + sourceFiles.size());
int totalCount = 0;
int totalChanged = 0;
for (File file : sourceFiles)
{
boolean changed = upgrade(file, properties);
if (changed) {
totalChanged++;
try {
System.out.println("Changed and upgraded file " + file.getCanonicalPath());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
totalCount++;
if (totalCount % 100 == 0)
{
System.out.printf("Processed %5d out of %d files (%.1f%%)\n",
totalCount, sourceFiles.size(), totalCount * 100.0 / sourceFiles.size());
}
}
System.out.printf("Upgrade finished successfully. %s files changed out of %s.", totalChanged, totalCount);
}
private static boolean upgrade(File file, Properties properties)
{
Path path = Paths.get(file.toURI());
String content;
boolean changed = false;
try {
content = new String(Files.readAllBytes(path));
String newContent = content;
String newClassName;
for (String oldClassName : properties.stringPropertyNames())
{
newClassName = properties.getProperty(oldClassName);
newContent = newContent.replace(oldClassName, newClassName);
}
if (!newContent.equals(content))
{
changed = true;
Files.write(path, newContent.getBytes());
}
} catch (IOException e) {
throw new RuntimeException(e);
}
return changed;
}
private static List getJavaFiles()
{
ArrayList files = new ArrayList<>();
collectJavaFiles(new File("."), files);
return files;
}
private static void collectJavaFiles(File currentFolder, List javaFiles)
{
File[] javaFilesInFolder = currentFolder.listFiles((f) -> f.isFile() && (f.getName().endsWith(".java") || f.getName().endsWith(".groovy")));
for (File file : javaFilesInFolder) {
javaFiles.add(file);
}
File[] subfolders = currentFolder.listFiles((f) -> f.isDirectory());
for (File subfolder : subfolders) {
collectJavaFiles(subfolder, javaFiles);
}
}
private static void printHelp()
{
System.out.println("Apache Tapestry version migrator options:");
System.out.println("\t upgrade [version number]: updates references to classes which have been moved or renamed in Java source files in the current folder and its subfolders.");
System.out.println("\t generate [version number]: analyzes version control and outputs information about moved classes.");
System.out.println("Apache Tapestry versions available in this tool: " +
Arrays.stream(TapestryVersion.values())
.map(TapestryVersion::getNumber)
.collect(Collectors.joining(", ")));
}
private static TapestryVersion getTapestryVersion(String versionNumber) {
final TapestryVersion tapestryVersion = Arrays.stream(TapestryVersion.values())
.filter(v -> versionNumber.equals(v.getNumber()))
.findFirst()
.orElseThrow(() -> new IllegalArgumentException("Unknown Tapestry version: " + versionNumber + ". "));
return tapestryVersion;
}
private static void createVersionFile(TapestryVersion version)
{
final String commandLine = String.format("git diff --summary %s %s",
version.getPreviousVersionGitHash(), version.getVersionGitHash());
final Process process;
System.out.printf("Running command line '%s'\n", commandLine);
List lines = new ArrayList<>();
try
{
process = Runtime.getRuntime().exec(commandLine);
} catch (IOException e) {
throw new RuntimeException(e);
}
try (
final InputStream inputStream = process.getInputStream();
final InputStreamReader isr = new InputStreamReader(inputStream);
final BufferedReader reader = new BufferedReader(isr))
{
String line = reader.readLine();
while (line != null)
{
lines.add(line);
line = reader.readLine();
}
} catch (IOException e) {
throw new RuntimeException(e);
}
List refactors = parse(lines);
AtomicInteger packageChange = new AtomicInteger();
AtomicInteger artifactChange = new AtomicInteger();
AtomicInteger packageAndArtifactChange = new AtomicInteger();
refactors.stream().forEach(r -> {
if (r.isMovedBetweenArtifacts() && r.isRenamed()) {
packageAndArtifactChange.incrementAndGet();
}
if (r.isMovedBetweenArtifacts()) {
artifactChange.incrementAndGet();
}
if (r.isRenamed()) {
packageChange.incrementAndGet();
}
});
System.out.println("Stats:");
System.out.printf("\t%d classes changed package or artifact\n", refactors.size());
System.out.printf("\t%d classes changed packages\n", packageChange.get());
System.out.printf("\t%d classes changed artifacts\n", artifactChange.get());
System.out.printf("\t%d classes changed both package and artifact\n", packageAndArtifactChange.get());
writeVersionFile(version, refactors);
writeRefactorsFile(version, refactors);
}
private static void writeRefactorsFile(TapestryVersion version, List refactors)
{
File file = getFile("change-report-" + version.getNumber() + ".html");
List sorted = new ArrayList<>(refactors);
sorted.sort(Comparator.comparing(
ClassRefactor::isInternal).thenComparing(
ClassRefactor::getSimpleOldClassName));
try (Formatter formatter = new Formatter(file))
{
formatter.format("");
formatter.format("\t");
formatter.format("\t\tChanges introduced in Apache Tapestry %s ", version.getNumber());
formatter.format("\t");
formatter.format("\t");
formatter.format("\t\t");
formatter.format("\t\t\t");
formatter.format("\t\t\t\tOld class name ");
formatter.format("\t\t\t\tRenamed or moved? ");
formatter.format("\t\t\t\tNew package location ");
formatter.format("\t\t\t\tMoved artifacts? ");
formatter.format("\t\t\t\tOld artifact location ");
formatter.format("\t\t\t\tNew artifact location ");
formatter.format("\t\t\t");
formatter.format("\t\t\t");
sorted.stream().forEach(r -> {
formatter.format("\t\t\t\t");
formatter.format("\t\t\t\t\t%s ", r.getSimpleOldClassName());
boolean renamed = r.isRenamed();
boolean movedBetweenArtifacts = r.isMovedBetweenArtifacts();
formatter.format("\t\t\t\t\t%s ", renamed ? "yes" : "no");
formatter.format("\t\t\t\t\t%s ", renamed ? r.getNewPackageName() : "");
formatter.format("\t\t\t\t\t%s ", movedBetweenArtifacts ? "yes" : "no");
formatter.format("\t\t\t\t\t%s ", movedBetweenArtifacts ? r.getSourceArtifact() : "");
formatter.format("\t\t\t\t\t%s ", movedBetweenArtifacts ? r.getDestinationArtifact() : "");
formatter.format("\t\t\t\t\t ");
});
formatter.format("\t\t\t");
formatter.format("\t\t
");
formatter.format("\t");
formatter.format("");
System.out.println("Change report file successfully written to " + file.getAbsolutePath());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private static void writeVersionFile(TapestryVersion version, List refactors)
{
Properties properties = new Properties();
refactors.stream()
.filter(ClassRefactor::isRenamed)
.forEach(r -> properties.setProperty(r.getOldClassName(), r.getNewClassName()));
final File file = getChangesFile(version);
try (
OutputStream outputStream = new FileOutputStream(file);
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outputStream))
{
properties.store(bufferedOutputStream, version.toString());
} catch (Exception e) {
throw new RuntimeException(e);
}
System.out.println("Version file successfully written to " + file.getAbsolutePath());
}
private static File getChangesFile(TapestryVersion version) {
String filename = getSimpleFileName(version);
final File file = getFile(filename);
return file;
}
private static String getSimpleFileName(TapestryVersion version) {
return version.getNumber() + ".properties";
}
private static File getFile(String filename) {
final String fileRelativePath = getFileRelativePath(filename);
final File file = new File("src/main/resources/" + fileRelativePath);
file.getParentFile().mkdirs();
return file;
}
private static String getFileRelativePath(String filename) {
final String fileRelativePath =
Main.class.getPackage().getName().replace('.', '/')
+ "/" + filename;
return fileRelativePath;
}
private static List parse(List lines)
{
System.out.println("Lines to process: " + lines.size());
lines = lines.stream()
.map(s -> s.trim())
.filter(s -> s.startsWith("rename"))
.filter(s -> !s.contains("test"))
.filter(s -> !s.contains("package-info"))
.filter(s -> !s.contains("/resources/"))
.filter(s -> !s.contains("/filtered-resources/"))
.map(s -> s.replaceFirst("rename", "").trim())
.collect(Collectors.toList());
List refactors = new ArrayList<>(lines.size());
for (String line : lines)
{
PackageAndArtifactChangeRefactorCommitParser packageAndArtifactParser = new PackageAndArtifactChangeRefactorCommitParser();
ArtifactChangeRefactorCommitParser artifactParser = new ArtifactChangeRefactorCommitParser();
PackageChangeRefactorCommitParser packageParser = new PackageChangeRefactorCommitParser();
Optional maybeMove = packageAndArtifactParser.apply(line);
if (!maybeMove.isPresent()) {
maybeMove = packageParser.apply(line);
}
if (!maybeMove.isPresent()) {
maybeMove = artifactParser.apply(line);
}
ClassRefactor move = maybeMove.orElseThrow(() -> new RuntimeException("Commit not handled: " + line));
refactors.add(move);
}
return refactors;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy