This is an automated email from the ASF dual-hosted git repository.
ffang pushed a commit to branch 4.1.x-fixes
in repository https://gitbox.apache.org/repos/asf/cxf.git
The following commit(s) were added to refs/heads/4.1.x-fixes by this push:
new 7fbcaabd6bd [CXF-9147]To accommodate the behaviour that several schema
namespaces… (#3093)
7fbcaabd6bd is described below
commit 7fbcaabd6bd417afe4292cef2cae0bd92a8b9c09
Author: Freeman(Yue) Fang <[email protected]>
AuthorDate: Fri May 8 15:01:39 2026 -0400
[CXF-9147]To accommodate the behaviour that several schema namespaces…
(#3093)
* [CXF-9147]To accommodate the behaviour that several schema namespaces are
explicitly mapped to the same Java package
* [CXF-9147]remove unnecessary fallback code
(cherry picked from commit a04c05c22f81dea96be28228852d14897d0b806d)
---
.../wsdlto/databinding/jaxb/JAXBDataBinding.java | 85 ++++++++++++++
.../wsdlto/jaxb/JAXBCodeGenNamespaceTest.java | 57 ++++++++++
.../cxf9147/cxf9147-shared-package.wsdl | 123 +++++++++++++++++++++
3 files changed, 265 insertions(+)
diff --git
a/tools/wsdlto/databinding/jaxb/src/main/java/org/apache/cxf/tools/wsdlto/databinding/jaxb/JAXBDataBinding.java
b/tools/wsdlto/databinding/jaxb/src/main/java/org/apache/cxf/tools/wsdlto/databinding/jaxb/JAXBDataBinding.java
index e897581bd93..c2c371395db 100644
---
a/tools/wsdlto/databinding/jaxb/src/main/java/org/apache/cxf/tools/wsdlto/databinding/jaxb/JAXBDataBinding.java
+++
b/tools/wsdlto/databinding/jaxb/src/main/java/org/apache/cxf/tools/wsdlto/databinding/jaxb/JAXBDataBinding.java
@@ -72,6 +72,7 @@ import org.xml.sax.helpers.XMLFilterImpl;
import com.sun.codemodel.ClassType;
import com.sun.codemodel.CodeWriter;
+import com.sun.codemodel.JAnnotationUse;
import com.sun.codemodel.JClass;
import com.sun.codemodel.JCodeModel;
import com.sun.codemodel.JDefinedClass;
@@ -126,6 +127,8 @@ import org.apache.cxf.wsdl.WSDLConstants;
import org.apache.ws.commons.schema.XmlSchema;
import org.apache.ws.commons.schema.XmlSchemaSerializer;
import
org.apache.ws.commons.schema.XmlSchemaSerializer.XmlSchemaSerializerException;
+import org.apache.ws.commons.schema.XmlSchemaType;
+
public class JAXBDataBinding implements DataBindingProfile {
static final String XJCVERSION;
@@ -833,6 +836,7 @@ public class JAXBDataBinding implements DataBindingProfile {
}
JCodeModel jcodeModel = schem2JavaJaxbModel.generateCode(null,
null);
+ fixXmlTypeNamespacesForSharedPackages(schem2JavaJaxbModel,
jcodeModel);
if (!isSuppressCodeGen()) {
jcodeModel.build(fileCodeWriter);
@@ -851,6 +855,87 @@ public class JAXBDataBinding implements DataBindingProfile
{
}
}
+
+ private void fixXmlTypeNamespacesForSharedPackages(S2JJAXBModel model,
JCodeModel codeModel) {
+ Map<String, Set<String>> packageToNamespaces = new HashMap<>();
+ for (Map.Entry<String, String> entry :
context.getNamespacePackageMap().entrySet()) {
+ packageToNamespaces.computeIfAbsent(entry.getValue(), k -> new
HashSet<>()).add(entry.getKey());
+ }
+
+ Set<String> sharedPackageNamespaces = new HashSet<>();
+ for (Set<String> namespaces : packageToNamespaces.values()) {
+ if (namespaces.size() > 1) {
+ sharedPackageNamespaces.addAll(namespaces);
+ }
+ }
+ if (sharedPackageNamespaces.isEmpty()) {
+ return;
+ }
+
+ SchemaCollection schemas = (SchemaCollection)
context.get(ToolConstants.XML_SCHEMA_COLLECTION);
+ if (schemas == null) {
+ return;
+ }
+
+ Map<String, String> classToNamespace = new HashMap<>();
+ for (XmlSchema schema : schemas.getXmlSchemas()) {
+ String namespace = schema.getTargetNamespace();
+ if (StringUtils.isEmpty(namespace) ||
!sharedPackageNamespaces.contains(namespace)) {
+ continue;
+ }
+ for (QName typeName : schema.getSchemaTypes().keySet()) {
+ XmlSchemaType schemaType = schema.getTypeByName(typeName);
+ if (schemaType == null) {
+ continue;
+ }
+ TypeAndAnnotation type = model.getJavaType(typeName);
+ if (type != null && type.getTypeClass() instanceof
JDefinedClass) {
+ JDefinedClass cls = (JDefinedClass)type.getTypeClass();
+ classToNamespace.put(cls.fullName(), namespace);
+ }
+ }
+ }
+
+ for (Map.Entry<String, String> entry : classToNamespace.entrySet()) {
+ JDefinedClass cls = codeModel._getClass(entry.getKey());
+ if (cls == null) {
+ continue;
+ }
+ JAnnotationUse xmlType = getAnnotation(cls,
"jakarta.xml.bind.annotation.XmlType");
+ if (xmlType != null && !hasAnnotationMember(xmlType, "namespace"))
{
+ xmlType.param("namespace", entry.getValue());
+ }
+ }
+ }
+
+ private JAnnotationUse getAnnotation(JDefinedClass cls, String
annotationClassName) {
+ for (JAnnotationUse annotation : cls.annotations()) {
+ if
(annotation.getAnnotationClass().fullName().equals(annotationClassName)) {
+ return annotation;
+ }
+ }
+ return null;
+ }
+
+ private boolean hasAnnotationMember(JAnnotationUse annotation, String
name) {
+ try {
+ return annotation.getAnnotationMembers().containsKey(name);
+ } catch (NoSuchMethodError ex) {
+ return hasAnnotationMemberUsingReflection(annotation, name);
+ }
+ }
+
+ private boolean hasAnnotationMemberUsingReflection(JAnnotationUse
annotation, String name) {
+ try {
+ Field f = annotation.getClass().getDeclaredField("memberValues");
+ ReflectionUtil.setAccessible(f);
+ Map<?, ?> map = (Map<?, ?>)f.get(annotation);
+ return map.containsKey(name);
+ } catch (IllegalAccessException | NoSuchFieldException |
SecurityException ex) {
+ return false;
+ }
+ }
+
public String getType(QName qname, boolean element) {
TypeAndAnnotation typeAnno = rawJaxbModelGenCode.getJavaType(qname);
if (element) {
diff --git
a/tools/wsdlto/test/src/test/java/org/apache/cxf/tools/wsdlto/jaxb/JAXBCodeGenNamespaceTest.java
b/tools/wsdlto/test/src/test/java/org/apache/cxf/tools/wsdlto/jaxb/JAXBCodeGenNamespaceTest.java
new file mode 100644
index 00000000000..8191f830712
--- /dev/null
+++
b/tools/wsdlto/test/src/test/java/org/apache/cxf/tools/wsdlto/jaxb/JAXBCodeGenNamespaceTest.java
@@ -0,0 +1,57 @@
+/**
+ * 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.cxf.tools.wsdlto.jaxb;
+
+import java.io.File;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+
+import org.apache.cxf.tools.common.ToolConstants;
+import org.apache.cxf.tools.wsdlto.AbstractCodeGenTest;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertTrue;
+
+public class JAXBCodeGenNamespaceTest extends AbstractCodeGenTest {
+ private static final String PERMISSION_SET_NS =
+ "http://cxf.apache.org/cxf9147/data/PermissionSet";
+
+ @Test
+ public void testXmlTypeNamespaceWithSharedPackageMappings() throws
Exception {
+ env.put(ToolConstants.CFG_WSDLURL,
+
getLocation("/wsdl2java_wsdl/cxf9147/cxf9147-shared-package.wsdl"));
+ env.put(ToolConstants.CFG_PACKAGENAME, new String[] {
+
"http://cxf.apache.org/cxf9147/service=org.apache.cxf.cxf9147.service",
+
"http://cxf.apache.org/cxf9147/request=org.apache.cxf.cxf9147.request",
+ PERMISSION_SET_NS + "=org.apache.cxf.cxf9147.shared",
+
"http://cxf.apache.org/cxf9147/data/Permission=org.apache.cxf.cxf9147.shared",
+
"http://cxf.apache.org/cxf9147/data/UserPermission=org.apache.cxf.cxf9147.shared"
+ });
+
+ processor.setContext(env);
+ processor.execute();
+
+ File generated = new File(output,
"org/apache/cxf/cxf9147/shared/ArrayOfPermissionSet.java");
+ assertTrue(generated.getAbsolutePath(), generated.exists());
+
+ String source = Files.readString(generated.toPath(),
StandardCharsets.UTF_8);
+ assertTrue(source, source.contains("namespace = \"" +
PERMISSION_SET_NS + "\""));
+ }
+}
diff --git
a/tools/wsdlto/test/src/test/resources/wsdl2java_wsdl/cxf9147/cxf9147-shared-package.wsdl
b/tools/wsdlto/test/src/test/resources/wsdl2java_wsdl/cxf9147/cxf9147-shared-package.wsdl
new file mode 100644
index 00000000000..811ae26e621
--- /dev/null
+++
b/tools/wsdlto/test/src/test/resources/wsdl2java_wsdl/cxf9147/cxf9147-shared-package.wsdl
@@ -0,0 +1,123 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<wsdl:definitions
+ xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
+ xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ xmlns:tns="http://cxf.apache.org/cxf9147/service"
+ xmlns:req="http://cxf.apache.org/cxf9147/request"
+ xmlns:ps="http://cxf.apache.org/cxf9147/data/PermissionSet"
+ targetNamespace="http://cxf.apache.org/cxf9147/service"
+ name="Cxf9147Service">
+
+ <wsdl:types>
+ <xs:schema
+ targetNamespace="http://cxf.apache.org/cxf9147/data/PermissionSet"
+ xmlns:tns="http://cxf.apache.org/cxf9147/data/PermissionSet"
+ elementFormDefault="qualified">
+ <xs:complexType name="PermissionSet">
+ <xs:sequence>
+ <xs:element name="name" type="xs:string" minOccurs="0"/>
+ </xs:sequence>
+ </xs:complexType>
+ <xs:complexType name="ArrayOfPermissionSet">
+ <xs:sequence>
+ <xs:element name="permissionSet" type="tns:PermissionSet"
+ minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:schema>
+
+ <xs:schema
+ targetNamespace="http://cxf.apache.org/cxf9147/data/Permission"
+ xmlns:tns="http://cxf.apache.org/cxf9147/data/Permission"
+ elementFormDefault="qualified">
+ <xs:complexType name="Permission">
+ <xs:sequence>
+ <xs:element name="value" type="xs:string" minOccurs="0"/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:schema>
+
+ <xs:schema
+ targetNamespace="http://cxf.apache.org/cxf9147/data/UserPermission"
+ xmlns:tns="http://cxf.apache.org/cxf9147/data/UserPermission"
+ elementFormDefault="qualified">
+ <xs:complexType name="UserPermission">
+ <xs:sequence>
+ <xs:element name="user" type="xs:string" minOccurs="0"/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:schema>
+
+ <xs:schema
+ targetNamespace="http://cxf.apache.org/cxf9147/request"
+ xmlns:tns="http://cxf.apache.org/cxf9147/request"
+ xmlns:ps="http://cxf.apache.org/cxf9147/data/PermissionSet"
+ elementFormDefault="qualified">
+ <xs:import
namespace="http://cxf.apache.org/cxf9147/data/PermissionSet"/>
+ <xs:element name="getPermissions" type="tns:GetPermissions"/>
+ <xs:element name="getPermissionsResponse"
type="tns:GetPermissionsResponse"/>
+ <xs:complexType name="GetPermissions">
+ <xs:sequence>
+ <xs:element name="id" type="xs:string" minOccurs="0"/>
+ </xs:sequence>
+ </xs:complexType>
+ <xs:complexType name="GetPermissionsResponse">
+ <xs:sequence>
+ <xs:element name="permissionSets"
type="ps:ArrayOfPermissionSet" minOccurs="0"/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:schema>
+ </wsdl:types>
+
+ <wsdl:message name="GetPermissionsRequest">
+ <wsdl:part name="parameters" element="req:getPermissions"/>
+ </wsdl:message>
+ <wsdl:message name="GetPermissionsResponse">
+ <wsdl:part name="parameters" element="req:getPermissionsResponse"/>
+ </wsdl:message>
+
+ <wsdl:portType name="Cxf9147PortType">
+ <wsdl:operation name="getPermissions">
+ <wsdl:input message="tns:GetPermissionsRequest"/>
+ <wsdl:output message="tns:GetPermissionsResponse"/>
+ </wsdl:operation>
+ </wsdl:portType>
+
+ <wsdl:binding name="Cxf9147Binding" type="tns:Cxf9147PortType">
+ <soap:binding style="document"
transport="http://schemas.xmlsoap.org/soap/http"/>
+ <wsdl:operation name="getPermissions">
+ <soap:operation soapAction="urn:getPermissions"/>
+ <wsdl:input>
+ <soap:body use="literal"/>
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+ </wsdl:binding>
+
+ <wsdl:service name="Cxf9147Service">
+ <wsdl:port name="Cxf9147Port" binding="tns:Cxf9147Binding">
+ <soap:address location="http://localhost/cxf9147"/>
+ </wsdl:port>
+ </wsdl:service>
+</wsdl:definitions>