This is an automated email from the ASF dual-hosted git repository. lihan pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/tomcat-jakartaee-migration.git
commit 12cfba68ab42ca06e99bf585656d1aa4936a9d7a Author: Danny Thomas <dan...@netflix.com> AuthorDate: Mon Oct 24 11:48:16 2022 +1100 Improve composability of the migration tool when using from other tools --- .../apache/tomcat/jakartaee/ClassConverter.java | 10 +- .../org/apache/tomcat/jakartaee/Converter.java | 3 +- .../org/apache/tomcat/jakartaee/EESpecProfile.java | 96 ++---------------- .../apache/tomcat/jakartaee/EESpecProfiles.java | 112 +++++++++++++++++++++ .../apache/tomcat/jakartaee/ManifestConverter.java | 19 ++-- .../org/apache/tomcat/jakartaee/Migration.java | 40 ++++++-- .../org/apache/tomcat/jakartaee/MigrationCLI.java | 2 +- .../org/apache/tomcat/jakartaee/MigrationTask.java | 4 +- .../tomcat/jakartaee/PassThroughConverter.java | 3 +- .../org/apache/tomcat/jakartaee/TextConverter.java | 17 ++-- .../tomcat/jakartaee/LocalStrings.properties | 2 + .../tomcat/jakartaee/ClassConverterTest.java | 2 +- .../apache/tomcat/jakartaee/EESpecProfileTest.java | 4 +- .../org/apache/tomcat/jakartaee/MigrationTest.java | 7 ++ .../apache/tomcat/jakartaee/TextConverterTest.java | 2 +- 15 files changed, 197 insertions(+), 126 deletions(-) diff --git a/src/main/java/org/apache/tomcat/jakartaee/ClassConverter.java b/src/main/java/org/apache/tomcat/jakartaee/ClassConverter.java index 8b4116d..decb208 100644 --- a/src/main/java/org/apache/tomcat/jakartaee/ClassConverter.java +++ b/src/main/java/org/apache/tomcat/jakartaee/ClassConverter.java @@ -39,7 +39,7 @@ public class ClassConverter implements Converter, ClassFileTransformer { protected final EESpecProfile profile; public ClassConverter() { - this(EESpecProfile.TOMCAT); + this(EESpecProfiles.TOMCAT); } public ClassConverter(EESpecProfile profile) { this.profile = profile; @@ -58,8 +58,8 @@ public class ClassConverter implements Converter, ClassFileTransformer { @Override - public void convert(String path, InputStream src, OutputStream dest, EESpecProfile profile) throws IOException { - convertInternal(path, src, dest, profile, null); + public boolean convert(String path, InputStream src, OutputStream dest, EESpecProfile profile) throws IOException { + return convertInternal(path, src, dest, profile, null); } @@ -78,7 +78,7 @@ public class ClassConverter implements Converter, ClassFileTransformer { } - protected void convertInternal(String path, InputStream src, OutputStream dest, EESpecProfile profile, ClassLoader loader) + protected boolean convertInternal(String path, InputStream src, OutputStream dest, EESpecProfile profile, ClassLoader loader) throws IOException { ClassParser parser = new ClassParser(src, "unknown"); JavaClass javaClass = parser.parse(); @@ -146,5 +146,7 @@ public class ClassConverter implements Converter, ClassFileTransformer { } javaClass.dump(dest); + + return converted; } } diff --git a/src/main/java/org/apache/tomcat/jakartaee/Converter.java b/src/main/java/org/apache/tomcat/jakartaee/Converter.java index e05c232..1bba1a1 100644 --- a/src/main/java/org/apache/tomcat/jakartaee/Converter.java +++ b/src/main/java/org/apache/tomcat/jakartaee/Converter.java @@ -34,6 +34,7 @@ public interface Converter { * @param profile The profile that defines the conversion required * * @throws IOException If the conversion fails + * @return true if the converter made a conversion to the file */ - void convert(String path, InputStream src, OutputStream dest, EESpecProfile profile) throws IOException; + boolean convert(String path, InputStream src, OutputStream dest, EESpecProfile profile) throws IOException; } diff --git a/src/main/java/org/apache/tomcat/jakartaee/EESpecProfile.java b/src/main/java/org/apache/tomcat/jakartaee/EESpecProfile.java index 8ed0d91..321e8cb 100644 --- a/src/main/java/org/apache/tomcat/jakartaee/EESpecProfile.java +++ b/src/main/java/org/apache/tomcat/jakartaee/EESpecProfile.java @@ -14,100 +14,22 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.apache.tomcat.jakartaee; import java.util.regex.Matcher; import java.util.regex.Pattern; -/** - * Specification profile defining the replacements performed. - */ -public enum EESpecProfile { - - TOMCAT("javax", "jakarta", - "javax([/\\.](annotation(?![/\\.]processing)" + - "|ejb" + - "|el" + - "|mail" + - "|persistence" + - "|security[/\\.]auth[/\\.]message" + - "|servlet" + - "|transaction(?![/\\.]xa)" + - "|websocket))"), - - EE("javax", "jakarta", - "javax([/\\.](activation" + - "|annotation(?![/\\.]processing)" + - "|batch" + - "|decorator" + - "|ejb" + - "|el" + - "|enterprise" + - "|faces" + - "|jms" + - "|json" + - "|jws" + - "|interceptor" + - "|inject" + - "|mail" + - "|management[/\\.]j2ee" + - "|persistence" + - "|resource" + - "|security[/\\.](auth[/\\.]message|enterprise|jacc)" + - "|servlet" + - "|transaction(?![/\\.]xa)" + - "|validation" + - "|websocket" + - "|ws[/\\.]rs" + - "|xml[/\\.](bind|soap|ws)))"), - JEE8("jakarta", "javax", - "jakarta([/\\.](activation" + - "|annotation(?![/\\.]processing)" + - "|batch" + - "|decorator" + - "|ejb" + - "|el" + - "|enterprise" + - "|faces" + - "|jms" + - "|json" + - "|jws" + - "|interceptor" + - "|inject" + - "|mail" + - "|management[/\\.]j2ee" + - "|persistence" + - "|resource" + - "|security[/\\.](auth[/\\.]message|enterprise|jacc)" + - "|servlet" + - "|transaction(?![/\\.]xa)" + - "|validation" + - "|websocket" + - "|ws[/\\.]rs" + - "|xml[/\\.](bind|soap|ws)))"); - - private String source; - private String target; - private Pattern pattern; - - EESpecProfile(String source, String target, String pattern) { - this.source = source; - this.target = target; - this.pattern = Pattern.compile(pattern); +public interface EESpecProfile { + default String convert(String name) { + Matcher m = getPattern().matcher(name); + return m.replaceAll(getTarget() + "$1"); } - public String convert(String name) { - Matcher m = pattern.matcher(name); - return m.replaceAll(target + "$1"); - } + String getSource(); - public String getSource() - { - return source; - } + String getTarget(); - public String getTarget() - { - return target; - } + Pattern getPattern(); } + diff --git a/src/main/java/org/apache/tomcat/jakartaee/EESpecProfiles.java b/src/main/java/org/apache/tomcat/jakartaee/EESpecProfiles.java new file mode 100644 index 0000000..effc43a --- /dev/null +++ b/src/main/java/org/apache/tomcat/jakartaee/EESpecProfiles.java @@ -0,0 +1,112 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.tomcat.jakartaee; + +import java.util.regex.Pattern; + +/** + * Specification profile defining the replacements performed. + */ +public enum EESpecProfiles implements EESpecProfile { + + TOMCAT("javax", "jakarta", + "javax([/\\.](annotation(?![/\\.]processing)" + + "|ejb" + + "|el" + + "|mail" + + "|persistence" + + "|security[/\\.]auth[/\\.]message" + + "|servlet" + + "|transaction(?![/\\.]xa)" + + "|websocket))"), + + EE("javax", "jakarta", + "javax([/\\.](activation" + + "|annotation(?![/\\.]processing)" + + "|batch" + + "|decorator" + + "|ejb" + + "|el" + + "|enterprise" + + "|faces" + + "|jms" + + "|json" + + "|jws" + + "|interceptor" + + "|inject" + + "|mail" + + "|management[/\\.]j2ee" + + "|persistence" + + "|resource" + + "|security[/\\.](auth[/\\.]message|enterprise|jacc)" + + "|servlet" + + "|transaction(?![/\\.]xa)" + + "|validation" + + "|websocket" + + "|ws[/\\.]rs" + + "|xml[/\\.](bind|soap|ws)))"), + JEE8("jakarta", "javax", + "jakarta([/\\.](activation" + + "|annotation(?![/\\.]processing)" + + "|batch" + + "|decorator" + + "|ejb" + + "|el" + + "|enterprise" + + "|faces" + + "|jms" + + "|json" + + "|jws" + + "|interceptor" + + "|inject" + + "|mail" + + "|management[/\\.]j2ee" + + "|persistence" + + "|resource" + + "|security[/\\.](auth[/\\.]message|enterprise|jacc)" + + "|servlet" + + "|transaction(?![/\\.]xa)" + + "|validation" + + "|websocket" + + "|ws[/\\.]rs" + + "|xml[/\\.](bind|soap|ws)))"); + private String source; + private String target; + private Pattern pattern; + + EESpecProfiles(String source, String target, String pattern) { + this.source = source; + this.target = target; + this.pattern = Pattern.compile(pattern); + } + + @Override + public String getSource() { + return source; + } + + @Override + public String getTarget() { + return target; + } + + @Override + public Pattern getPattern() { + return pattern; + } +} diff --git a/src/main/java/org/apache/tomcat/jakartaee/ManifestConverter.java b/src/main/java/org/apache/tomcat/jakartaee/ManifestConverter.java index 19099c2..7d344cf 100644 --- a/src/main/java/org/apache/tomcat/jakartaee/ManifestConverter.java +++ b/src/main/java/org/apache/tomcat/jakartaee/ManifestConverter.java @@ -48,20 +48,16 @@ public class ManifestConverter implements Converter { } @Override - public void convert(String path, InputStream src, OutputStream dest, EESpecProfile profile) throws IOException { + public boolean convert(String path, InputStream src, OutputStream dest, EESpecProfile profile) throws IOException { Manifest srcManifest = new Manifest(src); Manifest destManifest = new Manifest(srcManifest); - boolean result = false; - - result = result | removeSignatures(destManifest); + boolean result = removeSignatures(destManifest); result = result | updateValues(destManifest, profile); - if (result) { - destManifest.write(dest); - } else { - srcManifest.write(dest); - } + destManifest.write(dest); + + return result; } @@ -97,8 +93,7 @@ public class ManifestConverter implements Converter { private boolean updateValues(Manifest manifest, EESpecProfile profile) { - boolean result = false; - result = result | updateValues(manifest.getMainAttributes(), profile); + boolean result = updateValues(manifest.getMainAttributes(), profile); for (Attributes attributes : manifest.getEntries().values()) { result = result | updateValues(attributes, profile); } @@ -112,7 +107,7 @@ public class ManifestConverter implements Converter { if (attributes.containsKey(Attributes.Name.IMPLEMENTATION_VERSION)) { String newValue = attributes.get(Attributes.Name.IMPLEMENTATION_VERSION) + "-" + Info.getVersion(); attributes.put(Attributes.Name.IMPLEMENTATION_VERSION, newValue); - result = true; + // Purposefully avoid setting result } // Update package names in values for (Entry<Object,Object> entry : attributes.entrySet()) { diff --git a/src/main/java/org/apache/tomcat/jakartaee/Migration.java b/src/main/java/org/apache/tomcat/jakartaee/Migration.java index 35bfcbe..ae95f41 100644 --- a/src/main/java/org/apache/tomcat/jakartaee/Migration.java +++ b/src/main/java/org/apache/tomcat/jakartaee/Migration.java @@ -88,8 +88,12 @@ public class Migration { DEFAULT_EXCLUDES.add("spring-security-rsa-*.jar"); } - private EESpecProfile profile = EESpecProfile.TOMCAT; + private EESpecProfile profile = EESpecProfiles.TOMCAT; + + private boolean enableDefaultExcludes = true; private boolean zipInMemory; + private boolean converted; + private State state = State.NOT_STARTED; private File source; private File destination; private final List<Converter> converters; @@ -107,6 +111,12 @@ public class Migration { converters.add(new PassThroughConverter()); } + public enum State { + NOT_STARTED, + RUNNING, + COMPLETE + } + /** * Set the Jakarta EE specifications that should be used. * @@ -125,6 +135,10 @@ public class Migration { return profile; } + public void setEnableDefaultExcludes(boolean enableDefaultExcludes) { + this.enableDefaultExcludes = enableDefaultExcludes; + } + public void setZipInMemory(boolean zipInMemory) { this.zipInMemory = zipInMemory; } @@ -147,7 +161,21 @@ public class Migration { } + public boolean hasConverted() { + if (state != State.COMPLETE) { + throw new IllegalStateException(sm.getString("migration.notCompleted")); + } + return converted; + } + + public void execute() throws IOException { + if (state == State.RUNNING) { + throw new IllegalStateException(sm.getString("migration.alreadyRunning")); + } + state = State.RUNNING; + converted = false; + logger.log(Level.INFO, sm.getString("migration.execute", source.getAbsolutePath(), destination.getAbsolutePath(), profile.toString())); @@ -159,7 +187,7 @@ public class Migration { throw new IOException(sm.getString("migration.mkdirError", destination.getAbsolutePath())); } } else { - // Single file + // Single file` File parentDestination = destination.getAbsoluteFile().getParentFile(); if (parentDestination.exists() || parentDestination.mkdirs()) { migrateFile(source, destination); @@ -168,10 +196,9 @@ public class Migration { } } logger.log(Level.INFO, sm.getString("migration.done", - Long.valueOf(TimeUnit.MILLISECONDS.convert(System.nanoTime() - t1, TimeUnit.NANOSECONDS)))); + TimeUnit.MILLISECONDS.convert(System.nanoTime() - t1, TimeUnit.NANOSECONDS))); } - private void migrateDirectory(File src, File dest) throws IOException { // Won't return null because src is known to be a directory String[] files = src.list(); @@ -309,14 +336,13 @@ public class Migration { } else { for (Converter converter : converters) { if (converter.accepts(name)) { - converter.convert(name, src, dest, profile); + converted = converted | converter.convert(name, src, dest, profile); break; } } } } - private boolean isArchive(String fileName) { return fileName.endsWith(".jar") || fileName.endsWith(".war") || fileName.endsWith(".zip"); } @@ -326,7 +352,7 @@ public class Migration { File f = new File(name); String filename = f.getName(); - if (GlobMatcher.matchName(DEFAULT_EXCLUDES, filename, true)) { + if (enableDefaultExcludes && GlobMatcher.matchName(DEFAULT_EXCLUDES, filename, true)) { return true; } diff --git a/src/main/java/org/apache/tomcat/jakartaee/MigrationCLI.java b/src/main/java/org/apache/tomcat/jakartaee/MigrationCLI.java index 1b7c92f..05c50cb 100644 --- a/src/main/java/org/apache/tomcat/jakartaee/MigrationCLI.java +++ b/src/main/java/org/apache/tomcat/jakartaee/MigrationCLI.java @@ -69,7 +69,7 @@ public class MigrationCLI { iter.remove(); String profileName = argument.substring(PROFILE_ARG.length()); try { - EESpecProfile profile = EESpecProfile.valueOf(profileName.toUpperCase(Locale.ENGLISH)); + EESpecProfile profile = EESpecProfiles.valueOf(profileName.toUpperCase(Locale.ENGLISH)); migration.setEESpecProfile(profile); } catch (IllegalArgumentException e) { // Invalid profile value diff --git a/src/main/java/org/apache/tomcat/jakartaee/MigrationTask.java b/src/main/java/org/apache/tomcat/jakartaee/MigrationTask.java index 39f31dd..f5fd264 100644 --- a/src/main/java/org/apache/tomcat/jakartaee/MigrationTask.java +++ b/src/main/java/org/apache/tomcat/jakartaee/MigrationTask.java @@ -31,7 +31,7 @@ public class MigrationTask extends Task { private File src; private File dest; - private String profile = EESpecProfile.TOMCAT.toString(); + private String profile = EESpecProfiles.TOMCAT.toString(); private boolean zipInMemory = false; private String excludes; @@ -74,7 +74,7 @@ public class MigrationTask extends Task { // check the parameters EESpecProfile profile = null; try { - profile = EESpecProfile.valueOf(this.profile.toUpperCase()); + profile = EESpecProfiles.valueOf(this.profile.toUpperCase()); } catch (IllegalArgumentException e) { throw new BuildException("Invalid profile specified: " + this.profile, getLocation()); // todo i18n } diff --git a/src/main/java/org/apache/tomcat/jakartaee/PassThroughConverter.java b/src/main/java/org/apache/tomcat/jakartaee/PassThroughConverter.java index 8da2d9b..1d6a48c 100644 --- a/src/main/java/org/apache/tomcat/jakartaee/PassThroughConverter.java +++ b/src/main/java/org/apache/tomcat/jakartaee/PassThroughConverter.java @@ -34,11 +34,12 @@ public class PassThroughConverter implements Converter { } @Override - public void convert(String path, InputStream src, OutputStream dest, EESpecProfile profile) throws IOException { + public boolean convert(String path, InputStream src, OutputStream dest, EESpecProfile profile) throws IOException { // This simply copies the source to the destination Util.copy(src, dest); if (logger.isLoggable(Level.FINEST)) { logger.log(Level.FINEST, sm.getString("passThroughConverter.noConversion", path)); } + return false; } } diff --git a/src/main/java/org/apache/tomcat/jakartaee/TextConverter.java b/src/main/java/org/apache/tomcat/jakartaee/TextConverter.java index 80036ba..3c91117 100644 --- a/src/main/java/org/apache/tomcat/jakartaee/TextConverter.java +++ b/src/main/java/org/apache/tomcat/jakartaee/TextConverter.java @@ -66,22 +66,25 @@ public class TextConverter implements Converter { * execution. */ @Override - public void convert(String path, InputStream src, OutputStream dest, EESpecProfile profile) throws IOException { + public boolean convert(String path, InputStream src, OutputStream dest, EESpecProfile profile) throws IOException { String srcString = Util.toString(src, StandardCharsets.ISO_8859_1); String destString = profile.convert(srcString); - // Object comparison is deliberate here - if (srcString == destString) { - if (logger.isLoggable(Level.FINEST)) { - logger.log(Level.FINEST, sm.getString("classConverter.noConversion", path)); - } - } else { + boolean converted = srcString != destString; + + if (converted) { if (logger.isLoggable(Level.FINE)) { logger.log(Level.FINE, sm.getString("textConverter.converted", path)); } + } else { + if (logger.isLoggable(Level.FINEST)) { + logger.log(Level.FINEST, sm.getString("classConverter.noConversion", path)); + } } ByteArrayInputStream bais = new ByteArrayInputStream(destString.getBytes(StandardCharsets.ISO_8859_1)); Util.copy(bais, dest); + + return converted; } } diff --git a/src/main/resources/org/apache/tomcat/jakartaee/LocalStrings.properties b/src/main/resources/org/apache/tomcat/jakartaee/LocalStrings.properties index 6ee3665..f803338 100644 --- a/src/main/resources/org/apache/tomcat/jakartaee/LocalStrings.properties +++ b/src/main/resources/org/apache/tomcat/jakartaee/LocalStrings.properties @@ -21,6 +21,8 @@ migration.archive.complete=Migration finished for archive [{0}] migration.archive.memory=Migration starting for archive [{0}] using in memory copy migration.archive.stream=Migration starting for archive [{0}] using streaming migration.cannotReadSource=Cannot read source location [{0}] +migration.notCompleted=Migration has not completed +migration.alreadyRunning=Migration is already running migration.done=Migration completed successfully in [{0}] milliseconds migration.error=Error performing migration migration.execute=Performing migration from source [{0}] to destination [{1}] with Jakarta EE specification profile [{2}] diff --git a/src/test/java/org/apache/tomcat/jakartaee/ClassConverterTest.java b/src/test/java/org/apache/tomcat/jakartaee/ClassConverterTest.java index bf0b29e..0df49a2 100644 --- a/src/test/java/org/apache/tomcat/jakartaee/ClassConverterTest.java +++ b/src/test/java/org/apache/tomcat/jakartaee/ClassConverterTest.java @@ -65,7 +65,7 @@ public class ClassConverterTest { } // Transform - ClassConverter convertor = new ClassConverter(EESpecProfile.TOMCAT); + ClassConverter convertor = new ClassConverter(EESpecProfiles.TOMCAT); transformed = convertor.transform(this.getClass().getClassLoader(), "org.apache.tomcat.jakartaee.TesterConstants", null, null, original); diff --git a/src/test/java/org/apache/tomcat/jakartaee/EESpecProfileTest.java b/src/test/java/org/apache/tomcat/jakartaee/EESpecProfileTest.java index 4073334..bdc3b48 100644 --- a/src/test/java/org/apache/tomcat/jakartaee/EESpecProfileTest.java +++ b/src/test/java/org/apache/tomcat/jakartaee/EESpecProfileTest.java @@ -25,7 +25,7 @@ public class EESpecProfileTest { @Test public void testProfileTomcat() { - EESpecProfile profile = EESpecProfile.TOMCAT; + EESpecProfile profile = EESpecProfiles.TOMCAT; assertEquals("jakarta.annotation", profile.convert("javax.annotation")); assertEquals("jakarta.ejb", profile.convert("javax.ejb")); @@ -75,7 +75,7 @@ public class EESpecProfileTest { @Test public void testProfileEE() { - EESpecProfile profile = EESpecProfile.EE; + EESpecProfile profile = EESpecProfiles.EE; assertEquals("jakarta.activation", profile.convert("javax.activation")); assertEquals("jakarta.annotation", profile.convert("javax.annotation")); diff --git a/src/test/java/org/apache/tomcat/jakartaee/MigrationTest.java b/src/test/java/org/apache/tomcat/jakartaee/MigrationTest.java index 0d61442..1217177 100644 --- a/src/test/java/org/apache/tomcat/jakartaee/MigrationTest.java +++ b/src/test/java/org/apache/tomcat/jakartaee/MigrationTest.java @@ -164,6 +164,13 @@ public class MigrationTest { } } + @Test + public void testHasConversionsThrowsWhenNotComplete() { + Migration migration = new Migration(); + IllegalStateException exception = assertThrows(IllegalStateException.class, migration::hasConverted); + assertEquals("Migration has not completed", exception.getMessage()); + } + @Test public void testMigrateSignedJarFileRSA() throws Exception { testMigrateSignedJarFile("rsa"); diff --git a/src/test/java/org/apache/tomcat/jakartaee/TextConverterTest.java b/src/test/java/org/apache/tomcat/jakartaee/TextConverterTest.java index f8d029b..f136567 100644 --- a/src/test/java/org/apache/tomcat/jakartaee/TextConverterTest.java +++ b/src/test/java/org/apache/tomcat/jakartaee/TextConverterTest.java @@ -22,7 +22,7 @@ public class TextConverterTest { TextConverter converter = new TextConverter(); ByteArrayInputStream in = new ByteArrayInputStream(INPUT.getBytes(StandardCharsets.ISO_8859_1)); ByteArrayOutputStream out = new ByteArrayOutputStream(); - EESpecProfile profile = EESpecProfile.EE; + EESpecProfile profile = EESpecProfiles.EE; // test converter.convert(TEST_FILENAME, in, out, profile); --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org