diff --git a/src/main/java/org/apache/xmlbeans/XmlOptions.java b/src/main/java/org/apache/xmlbeans/XmlOptions.java index 3d055b867..bbc53fc21 100644 --- a/src/main/java/org/apache/xmlbeans/XmlOptions.java +++ b/src/main/java/org/apache/xmlbeans/XmlOptions.java @@ -156,7 +156,8 @@ public enum XmlOptionsKeys { LOAD_USE_LOCALE_CHAR_UTIL, XPATH_USE_SAXON, XPATH_USE_XMLBEANS, - ATTRIBUTE_VALIDATION_COMPAT_MODE + ATTRIBUTE_VALIDATION_COMPAT_MODE, + USE_JAVA_SHORT_NAME } @@ -1068,6 +1069,21 @@ public boolean isCompileDownloadUrls() { return hasOption(XmlOptionsKeys.COMPILE_DOWNLOAD_URLS); } + /** + * If this option is set, then the schema compiler will use the java_short_name to generate file name + * + */ + public XmlOptions setCompileUseShortJavaName() { + return setCompileUseShortJavaName(true); + } + + public XmlOptions setCompileUseShortJavaName(boolean b) { + return set(XmlOptionsKeys.USE_JAVA_SHORT_NAME, b); + } + + public boolean isCompileUseShortJavaName() { + return hasOption(XmlOptionsKeys.USE_JAVA_SHORT_NAME); + } /** * If this option is set, then the schema compiler will permit and * ignore multiple definitions of the same component (element, attribute, diff --git a/src/main/java/org/apache/xmlbeans/impl/schema/SchemaTypePool.java b/src/main/java/org/apache/xmlbeans/impl/schema/SchemaTypePool.java index 60e6d333e..2171a57f2 100644 --- a/src/main/java/org/apache/xmlbeans/impl/schema/SchemaTypePool.java +++ b/src/main/java/org/apache/xmlbeans/impl/schema/SchemaTypePool.java @@ -89,7 +89,17 @@ String handleForElement(SchemaGlobalElement element) { } String handle = _componentsToHandles.get(element); if (handle == null) { - handle = addUniqueHandle(element, NameUtil.upperCamelCase(element.getName().getLocalPart()) + "Element"); + if(typeSystem.isUseShortJavaName()) { + SchemaType type = element.getType(); + String javaName = type.getShortJavaName(); + if (javaName != null && !javaName.isEmpty()) { + handle = addUniqueHandle(element, NameUtil.upperCamelCase(javaName) + "Element"); + } else { + handle = addUniqueHandle(element, NameUtil.upperCamelCase(element.getName().getLocalPart()) + "Element"); + } + } else { + handle = addUniqueHandle(element, NameUtil.upperCamelCase(element.getName().getLocalPart()) + "Element"); + } } return handle; } @@ -179,7 +189,15 @@ String handleForType(SchemaType type) { if (name == null) { baseName = "Anon" + uniq + "Type"; } else { - baseName = NameUtil.upperCamelCase(name.getLocalPart()) + uniq + suffix + "Type"; + if(typeSystem.isUseShortJavaName()) { + String javaName = type.getShortJavaName(); + if (javaName == null || javaName.isEmpty()) + javaName = name.getLocalPart(); + baseName = NameUtil.upperCamelCase(javaName) + uniq + suffix + "Type"; + } + else { + baseName = NameUtil.upperCamelCase(name.getLocalPart()) + uniq + suffix + "Type"; + } } handle = addUniqueHandle(type, baseName); diff --git a/src/main/java/org/apache/xmlbeans/impl/schema/SchemaTypeSystemImpl.java b/src/main/java/org/apache/xmlbeans/impl/schema/SchemaTypeSystemImpl.java index ed6b7919f..88b203723 100644 --- a/src/main/java/org/apache/xmlbeans/impl/schema/SchemaTypeSystemImpl.java +++ b/src/main/java/org/apache/xmlbeans/impl/schema/SchemaTypeSystemImpl.java @@ -166,6 +166,7 @@ public class SchemaTypeSystemImpl extends SchemaTypeLoaderBase implements Schema // the additional config option private String _sourceCodeEncoding ; + private boolean _useShortJavaName; static String nameToPathString(String nameForSystem) { nameForSystem = nameForSystem.replace('.', '/'); @@ -318,7 +319,25 @@ void savePointers() { void savePointersForComponents(SchemaComponent[] components, String dir) { for (SchemaComponent component : components) { - savePointerFile(dir + QNameHelper.hexsafedir(component.getName()), _name); + if(_useShortJavaName) { + String javaName = _localHandles.handleForComponent(component); + if (javaName != null && !javaName.isEmpty()) + { + QName nameTemp = component.getName(); + String resultName; + if (nameTemp.getNamespaceURI() == null || nameTemp.getNamespaceURI().length() == 0) { + resultName = "_nons/" + QNameHelper.hexsafe(javaName); + } else { + resultName = QNameHelper.hexsafe(nameTemp.getNamespaceURI()) + "/" + + QNameHelper.hexsafe(javaName); + } + savePointerFile(dir + resultName, _name); + } else { + savePointerFile(dir + QNameHelper.hexsafedir(component.getName()), _name); + } + } else { + savePointerFile(dir + QNameHelper.hexsafedir(component.getName()), _name); + } } } @@ -421,6 +440,10 @@ String getSourceCodeEncoding() { return _sourceCodeEncoding ; } + boolean isUseShortJavaName(){ + return _useShortJavaName; + } + @SuppressWarnings("unchecked") private void buildContainersHelper(Map elements, BiConsumer adder) { elements.forEach((k, v) -> adder.accept(getContainerNonNull(k.getNamespaceURI()), (T) v)); @@ -625,6 +648,7 @@ public void loadFromStscState(StscState state) { _annotations = state.annotations(); _namespaces = new HashSet<>(Arrays.asList(state.getNamespaces())); _containers = state.getContainerMap(); + _useShortJavaName = state.useShortName(); _sourceCodeEncoding = state.sourceCodeEncoding(); fixupContainers(); // Checks that data in the containers matches the lookup maps diff --git a/src/main/java/org/apache/xmlbeans/impl/schema/StscState.java b/src/main/java/org/apache/xmlbeans/impl/schema/StscState.java index eb9ad1003..fe800b831 100644 --- a/src/main/java/org/apache/xmlbeans/impl/schema/StscState.java +++ b/src/main/java/org/apache/xmlbeans/impl/schema/StscState.java @@ -103,6 +103,7 @@ public class StscState { private boolean _noPvr; private boolean _noAnn; private boolean _mdefAll; + private boolean _useShortJavaName; private String _sourceCodeEncoding ; private final Set _mdefNamespaces = buildDefaultMdefNamespaces(); private EntityResolver _entityResolver; @@ -464,6 +465,8 @@ public void setOptions(XmlOptions options) { if (_sourceCodeEncoding == null || _sourceCodeEncoding.isEmpty()) { _sourceCodeEncoding = SystemProperties.getProperty("xmlbean.sourcecodeencoding"); } + _useShortJavaName = options.isCompileUseShortJavaName() || + "true".equals(SystemProperties.getProperty("xmlbean.useshortjavaname", "false")); _entityResolver = options.getEntityResolver(); if (_entityResolver == null) { @@ -536,6 +539,14 @@ public String sourceCodeEncoding() { return _sourceCodeEncoding ; } + /** + * True if use the java_short_name to generate file name + */ + // EXPERIMENTAL + public boolean useShortName() { + return _useShortJavaName; + } + /** * Get count of recovered errors. Not for public. */ diff --git a/src/main/java/org/apache/xmlbeans/impl/tool/MavenPlugin.java b/src/main/java/org/apache/xmlbeans/impl/tool/MavenPlugin.java index 8a7e2f9ae..0dec82056 100644 --- a/src/main/java/org/apache/xmlbeans/impl/tool/MavenPlugin.java +++ b/src/main/java/org/apache/xmlbeans/impl/tool/MavenPlugin.java @@ -192,6 +192,14 @@ public class MavenPlugin extends AbstractMojo { @Parameter private String sourceCodeEncoding; + /** + * Used for File Names. + * + * @since 5.2.2 + */ + @Parameter( defaultValue = "false" ) + private boolean useShortJavaName; + @Parameter private List extensions; @@ -312,6 +320,7 @@ public void execute() throws MojoExecutionException, MojoFailureException { if (sourceCodeEncoding != null && !sourceCodeEncoding.isEmpty()) { params.setSourceCodeEncoding(sourceCodeEncoding); } + params.setUseShortJavaName(useShortJavaName); boolean result = SchemaCompiler.compile(params); diff --git a/src/main/java/org/apache/xmlbeans/impl/tool/Parameters.java b/src/main/java/org/apache/xmlbeans/impl/tool/Parameters.java index dd6340fb2..a37a7ae24 100644 --- a/src/main/java/org/apache/xmlbeans/impl/tool/Parameters.java +++ b/src/main/java/org/apache/xmlbeans/impl/tool/Parameters.java @@ -54,6 +54,7 @@ public class Parameters { private boolean noExt; private boolean debug; private boolean copyAnn; + private boolean useShortJavaName; private String sourceCodeEncoding; private boolean incrementalSrcGen; private String repackage; @@ -204,6 +205,10 @@ public boolean isNoAnn() { return noAnn; } + public boolean isUseShortJavaName() { + return useShortJavaName; + } + public String getSourceCodeEncoding() { return sourceCodeEncoding; } @@ -244,6 +249,10 @@ public void setDebug(boolean debug) { this.debug = debug; } + public void setUseShortJavaName(boolean useShortJavaName) { + this.useShortJavaName = useShortJavaName; + } + public void setSourceCodeEncoding(String sourceCodeEncoding) { this.sourceCodeEncoding = sourceCodeEncoding; } diff --git a/src/main/java/org/apache/xmlbeans/impl/tool/SchemaCompiler.java b/src/main/java/org/apache/xmlbeans/impl/tool/SchemaCompiler.java index c5340bb6f..c2b442c9b 100644 --- a/src/main/java/org/apache/xmlbeans/impl/tool/SchemaCompiler.java +++ b/src/main/java/org/apache/xmlbeans/impl/tool/SchemaCompiler.java @@ -68,6 +68,7 @@ public static void printUsage() { System.out.println(" -repackage - repackage specification, e.g. \"org.apache.xmlbeans.metadata:mypackage.metadata\" to change the metadata directory"); System.out.println(" -copyann - copy schema annotations to javadoc (default false) - don't activate on untrusted schema sources!"); System.out.println(" -sourcecodeencoding [encodingName] - Generate Java source code with the specified encoding (ISO-8859-1 is the legacy default)"); + System.out.println(" -useshortjavaname - Generate file name using Short Java Name"); /* Undocumented feature - pass in one schema compiler extension and related parameters System.out.println(" -extension - registers a schema compiler extension"); System.out.println(" -extensionParms - specify parameters for the compiler extension"); @@ -99,6 +100,7 @@ public static void main(String[] args) { flags.add("noext"); flags.add("srconly"); flags.add("debug"); + flags.add("useshortjavaname"); Set opts = new HashSet<>(); opts.add("out"); @@ -189,6 +191,7 @@ public static void main(String[] args) { boolean debug = (cl.getOpt("debug") != null); boolean copyAnn = (cl.getOpt("copyann") != null); String sourceCodeEncoding = cl.getOpt("sourcecodeencoding"); + boolean useShortJavaName = (cl.getOpt("useshortjavaname") != null); String allowmdef = cl.getOpt("allowmdef"); Set mdefNamespaces = (allowmdef == null ? Collections.emptySet() : @@ -337,6 +340,7 @@ public static void main(String[] args) { params.setNoExt(noExt); params.setDebug(debug); params.setSourceCodeEncoding(sourceCodeEncoding); + params.setUseShortJavaName(useShortJavaName); params.setErrorListener(err); params.setRepackage(repackage); params.setExtensions(extensions); @@ -360,7 +364,7 @@ public static void main(String[] args) { private static SchemaTypeSystem loadTypeSystem(String name, File[] xsdFiles, File[] wsdlFiles, URL[] urlFiles, File[] configFiles, File[] javaFiles, ResourceLoader cpResourceLoader, - boolean download, boolean noUpa, boolean noPvr, boolean noAnn, boolean noVDoc, boolean noExt, String sourceCodeEncoding, + boolean download, boolean noUpa, boolean noPvr, boolean noAnn, boolean noVDoc, boolean noExt, String sourceCodeEncoding, boolean useShortName, Set mdefNamespaces, File baseDir, Map sourcesToCopyMap, Collection outerErrorListener, File schemasDir, EntityResolver entResolver, File[] classpath) { XmlErrorWatcher errorListener = new XmlErrorWatcher(outerErrorListener); @@ -528,6 +532,9 @@ private static SchemaTypeSystem loadTypeSystem(String name, File[] xsdFiles, Fil if (sourceCodeEncoding != null ) { opts.setCharacterEncoding(sourceCodeEncoding); } + if (useShortName) { + opts.setCompileUseShortJavaName(); + } if (mdefNamespaces != null) { opts.setCompileMdefNamespaces(mdefNamespaces); } @@ -622,6 +629,7 @@ public static boolean compile(Parameters params) { boolean incrSrcGen = params.isIncrementalSrcGen(); boolean copyAnn = params.isCopyAnn(); String sourceCodeEncoding = params.getSourceCodeEncoding(); + boolean useShortName = params.isUseShortJavaName(); Collection outerErrorListener = params.getErrorListener(); Set partialMethods = params.getPartialMethods(); @@ -674,7 +682,7 @@ public static boolean compile(Parameters params) { // build the in-memory type system XmlErrorWatcher errorListener = new XmlErrorWatcher(outerErrorListener); SchemaTypeSystem system = loadTypeSystem(name, xsdFiles, wsdlFiles, urlFiles, configFiles, - javaFiles, cpResourceLoader, download, noUpa, noPvr, noAnn, noVDoc, noExt, sourceCodeEncoding, mdefNamespaces, + javaFiles, cpResourceLoader, download, noUpa, noPvr, noAnn, noVDoc, noExt, sourceCodeEncoding, useShortName, mdefNamespaces, baseDir, sourcesToCopyMap, errorListener, schemasDir, cmdLineEntRes, classpath); if (errorListener.hasError()) { result = false; @@ -702,6 +710,7 @@ public static boolean compile(Parameters params) { options.setCompileNoAnnotations(noAnn); options.setCompileAnnotationAsJavadoc(copyAnn); options.setCharacterEncoding(sourceCodeEncoding); + options.setCompileUseShortJavaName(useShortName); // save .xsb files system.save(filer); diff --git a/src/test/java/compile/scomp/checkin/XmlBeansCompCheckinTests.java b/src/test/java/compile/scomp/checkin/XmlBeansCompCheckinTests.java index 1b443c06b..327877c76 100644 --- a/src/test/java/compile/scomp/checkin/XmlBeansCompCheckinTests.java +++ b/src/test/java/compile/scomp/checkin/XmlBeansCompCheckinTests.java @@ -99,6 +99,25 @@ void test_Filer_compilation() throws Exception { MatcherAssert.assertThat(f.getSrcFileVec(), is(expSrcType)); } + @Test + void test_Filer_shortname_compilation() throws Exception { + XmlObject obj1 = XmlObject.Factory.parse(FOR_XSD); + XmlObject[] schemas = new XmlObject[]{obj1}; + + TestFiler f = new TestFiler(); + xm_opts.setCompileUseShortJavaName(); + XmlBeans.compileXmlBeans("apiCompile", null, schemas, null, XmlBeans.getBuiltinTypeSystem(), f, xm_opts); + + assertTrue(f.isCreateBinaryFile(), "Binary File method not invoked"); + assertTrue(f.isCreateSourceFile(), "Source File method not invoked"); + + assertNotNull(f.getBinFileVec()); + MatcherAssert.assertThat(f.getBinFileVec(), is(expBinShortnameType)); + + assertNotNull(f.getSrcFileVec()); + MatcherAssert.assertThat(f.getSrcFileVec(), is(expSrcType)); + } + /** * Verify Partial SOM cannot be saved to file system */