Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/*
* Copyright (c) 1997, 2023 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2025 Contributors to the Eclipse Foundation. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Distribution License v. 1.0, which is available at
Expand Down Expand Up @@ -67,6 +68,9 @@ public final class JCodeModel {
/** The packages that this JCodeWriter contains. */
private final HashMap<String,JPackage> packages = new HashMap<>();

/** The adapters that this JCodeWriter contains. */
private final HashMap<String,JDefinedClass> adapters = new HashMap<>();

/** Java module in {@code module-info.java} file. */
private JModule module;

Expand Down Expand Up @@ -242,6 +246,22 @@ public JDefinedClass _getClass(String fullyQualifiedName) {
._getClass( fullyQualifiedName.substring(idx+1) );
}

/**
* Adds an adapter to this code writer
* @param adapter the adapter to reference in this code writer
*/
public void _adapter(JDefinedClass adapter) {
this.adapters.put(adapter.name(), adapter);
}

/**
* Returns an iterator that walks the adapters defined using this code writer.
* @return an iterator of the adapters used by this code writer
*/
public Iterator<JDefinedClass> adapters() {
return adapters.values().iterator();
}

/**
* Creates a new anonymous class.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/*
* Copyright (c) 1997, 2021 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2025 Contributors to the Eclipse Foundation. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Distribution License v. 1.0, which is available at
Expand All @@ -13,6 +14,7 @@
import com.sun.codemodel.JAnnotatable;
import com.sun.codemodel.JAnnotationUse;
import com.sun.codemodel.JClass;
import com.sun.codemodel.JDefinedClass;
import com.sun.codemodel.JFieldVar;
import com.sun.codemodel.JMethod;
import com.sun.tools.xjc.BadCommandLineException;
Expand All @@ -26,6 +28,7 @@
import java.io.IOException;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Iterator;

import org.xml.sax.ErrorHandler;

Expand Down Expand Up @@ -72,33 +75,39 @@ public boolean run( Outline model, Options opt, ErrorHandler errorHandler ) {
annotation = model.getCodeModel().ref(genAnnotation);

for (ClassOutline co : model.getClasses()) {
augument(co);
augment(co);
}
for (EnumOutline eo : model.getEnums()) {
augument(eo);
augment(eo);
}
for (PackageOutline po : model.getAllPackageContexts()) {
augument(po);
augment(po);
}

// annotate XmlAdapter generated-classes
Iterator<JDefinedClass> it = model.getCodeModel().adapters();
while (it.hasNext()) {
annotate(it.next());
}
return true;
}

private void augument(EnumOutline eo) {
private void augment(EnumOutline eo) {
annotate(eo.clazz);
}

/**
* Adds "@Generated" to the classes, methods, and fields.
*/
private void augument(ClassOutline co) {
private void augment(ClassOutline co) {
annotate(co.implClass);
for (JMethod m : co.implClass.methods())
annotate(m);
for (JFieldVar f : co.implClass.fields().values())
annotate(f);
}

private void augument(PackageOutline po) {
private void augment(PackageOutline po) {
annotate(po.objectFactory());
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/*
* Copyright (c) 1997, 2024 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2025 Contributors to the Eclipse Foundation. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Distribution License v. 1.0, which is available at
Expand Down Expand Up @@ -168,6 +169,8 @@ private JDefinedClass generateAdapter(String parseMethod, String printMethod,XSS
try {
JPackage pkg = Ring.get(ClassSelector.class).getClassScope().getOwnerPackage();
adapter = pkg._class("Adapter"+id);
// reference adapter in the CodeModel instance
pkg.owner()._adapter(adapter);
} catch (JClassAlreadyExistsException e) {
// try another name in search for an unique name.
// this isn't too efficient, but we expect people to usually use
Expand Down
51 changes: 51 additions & 0 deletions jaxb-ri/xjc/src/test/java/com/sun/tools/xjc/CodeGenTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

package com.sun.tools.xjc;

import com.sun.codemodel.JAnnotationUse;
import com.sun.codemodel.JCodeModel;
import com.sun.codemodel.JDeclaration;
import com.sun.codemodel.JDefinedClass;
Expand Down Expand Up @@ -223,6 +224,56 @@ public void testIssue1788() throws FileNotFoundException, URISyntaxException {
}
}


/**
* Test issues #1440 for mark-generated on adapters
*
* @throws FileNotFoundException When the test schema or binding file cannot be read.
* @throws URISyntaxException When the test {@link InputSource} cannot be parsed.
*
* @see <a href="https://github.com/eclipse-ee4j/jaxb-ri/issues/1440">Issue #1440</a>
*/
public void testIssue1440() throws FileNotFoundException, URISyntaxException, BadCommandLineException {
String schemaFileName = "/schemas/issue1440/schema.xsd";
String bindingFileName = "/schemas/issue1440/binding.xjb";
String packageName = "org.example.issue1440";
String someClassName = packageName + ".Gh1440Type";

ErrorListener errorListener = new ConsoleErrorReporter();

// Parse the XML schema.
SchemaCompiler sc = XJC.createSchemaCompiler();
sc.setErrorListener(errorListener);
sc.forcePackageName(packageName);
sc.parseSchema(getInputSource(schemaFileName));
sc.getOptions().addGrammar(getInputSource(schemaFileName));
sc.getOptions().addBindFile(getInputSource(bindingFileName));
sc.getOptions().parseArguments(new String[] { "-mark-generated" });

// Generate the defined class.
S2JJAXBModel model = sc.bind();
Plugin[] extensions = new Plugin[]{ new com.sun.tools.xjc.addon.at_generated.PluginImpl() };
JCodeModel cm = model.generateCode(extensions, errorListener);
JDefinedClass dc = cm._getClass(someClassName);
assertNotNull(someClassName, dc);

// Assert Class includes narrow type
Iterator<JMethod> conIter = dc.constructors();
while (conIter.hasNext()) {
JMethod con = conIter.next();
assertTrue(toString(con).contains("java.lang.Class<java.lang.String>"));
}

Iterator<JDefinedClass> adaptersIt = cm.adapters();
assertTrue("Should have one adapter", adaptersIt.hasNext());
JDefinedClass adapter = adaptersIt.next();
assertNotNull("Adapter should not be null", adapter);
assertEquals("Should have one annotations", 1, adapter.annotations().size());
JAnnotationUse annotation = adapter.annotations().iterator().next();
assertNotNull("Annotation should not be null", annotation);
assertEquals("Annotation should be @Generated", "jakarta.annotation.Generated", annotation.getAnnotationClass().fullName());
}

private void assertNonEmptyJavadocBlocks(String cmString) throws IOException {
int lineNo = 0;
try ( LineNumberReader lnr = new LineNumberReader(new StringReader(cmString)) ) {
Expand Down
21 changes: 21 additions & 0 deletions jaxb-ri/xjc/src/test/resources/schemas/issue1440/binding.xjb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!--

Copyright (c) 2025 Contributors to the Eclipse Foundation. All rights reserved.

This program and the accompanying materials are made available under the
terms of the Eclipse Distribution License v. 1.0, which is available at
http://www.eclipse.org/org/documents/edl-v10.php.

SPDX-License-Identifier: BSD-3-Clause

-->

<!-- See https://github.com/eclipse-ee4j/jaxb-ri/issues/1440 -->
<jaxb:bindings xmlns:jaxb="https://jakarta.ee/xml/ns/jaxb" xmlns:xs="http://www.w3.org/2001/XMLSchema" version="3.0">
<jaxb:bindings schemaLocation="schema.xsd" node="/xs:schema">
<jaxb:globalBindings typesafeEnumBase="xs:string">
<jaxb:javaType name="long" xmlType="xs:unsignedLong" parseMethod="java.lang.Long.parseLong" printMethod="java.lang.Long.toString"/>
</jaxb:globalBindings>
</jaxb:bindings>
</jaxb:bindings>
29 changes: 29 additions & 0 deletions jaxb-ri/xjc/src/test/resources/schemas/issue1440/schema.xsd
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!--

Copyright (c) 2025 Contributors to the Eclipse Foundation. All rights reserved.

This program and the accompanying materials are made available under the
terms of the Eclipse Distribution License v. 1.0, which is available at
http://www.eclipse.org/org/documents/edl-v10.php.

SPDX-License-Identifier: BSD-3-Clause

-->

<!-- See https://github.com/eclipse-ee4j/jaxb-ri/issues/1440 -->
<xs:schema
targetNamespace="http://example.org/document"
xmlns:tns="http://example.org/document"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
>

<xs:complexType name="gh1440Type">
<xs:sequence>
<xs:element name="Value" type="xs:unsignedLong"/>
</xs:sequence>
</xs:complexType>

<xs:element name="gh1440" type="tns:gh1440Type"/>

</xs:schema>