Skip to content

Commit

Permalink
fix a bug in handling XmlEnums, make moxy more android friendly
Browse files Browse the repository at this point in the history
Signed-off-by: Lukas Jungmann <lukas.jungmann@oracle.com>
  • Loading branch information
lukasj committed Aug 15, 2023
1 parent 9ea90e3 commit 58f1330
Show file tree
Hide file tree
Showing 7 changed files with 94 additions and 49 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2022 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2023 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2022 IBM Corporation. All rights reserved.
*
* This program and the accompanying materials are made available under the
Expand Down Expand Up @@ -2326,7 +2326,22 @@ public static String getAttributeNameFromMethodName(String methodName) {
restOfName = methodName.substring(POSITION_AFTER_IS_PREFIX);
}
//added for bug 234222 - property name generation differs from Introspector.decapitalize
return java.beans.Introspector.decapitalize(restOfName);
return decapitalize(restOfName);
}

public static String decapitalize(String s) {
// XXX - behaviour of this method must be same as of Introspector.decapitalize
// which is not used to avoid dependency on java.desktop
if (s == null || s.isEmpty()) {
return s;
}
if (s.length() > 1 && Character.isUpperCase(s.charAt(1))
&& Character.isUpperCase(s.charAt(0))) {
return s;
}
char[] chars = s.toCharArray();
chars[0] = Character.toLowerCase(chars[0]);
return new String(chars);
}

public static String getDefaultStartDatabaseDelimiter(){
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2023 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
Expand Down Expand Up @@ -28,17 +28,17 @@
* @author mmacivor
*
*/
public class WrappedValue extends JAXBElement {
public class WrappedValue<T> extends JAXBElement<T> {

private boolean setValue;

public WrappedValue(QName name, Class<?> declaredType, Object value) {
public WrappedValue(QName name, Class<T> declaredType, T value) {
super(name, declaredType, value);
this.setValue = false;
}

@Override
public void setValue(Object value) {
public void setValue(T value) {
super.setValue(value);
setValue = true;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2022 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2023 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
Expand All @@ -16,7 +16,6 @@
// Dmitry Kornilov - 2.6.1 - BeanValidationHelper refactoring
package org.eclipse.persistence.jaxb;

import java.awt.Image;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
Expand Down Expand Up @@ -1478,7 +1477,7 @@ private QName getSchemaTypeForTypeMappingInfo(Type type) {
if (name == null) {
Class<?> theClass = (Class) type;
//Change default for byte[] to Base64 (JAXB 2.0 default)
if (type == CoreClassConstants.ABYTE || type == CoreClassConstants.APBYTE || type == Image.class || type == Source.class || theClass.getCanonicalName().equals("jakarta.activation.DataHandler")) {
if (type == CoreClassConstants.ABYTE || type == CoreClassConstants.APBYTE || theClass.getCanonicalName().equals("java.awt.Image") || type == Source.class || theClass.getCanonicalName().equals("jakarta.activation.DataHandler")) {
name = Constants.BASE_64_BINARY_QNAME;
} else if (type == CoreClassConstants.OBJECT) {
name = Constants.ANY_TYPE_QNAME;
Expand Down Expand Up @@ -1729,6 +1728,17 @@ private static void openToCore(Collection<Class<?>> classes) {
}
}

private static final boolean NEEDS_OPEN = JAXBContext.class.getModule() != Version.class.getModule();
private static final boolean NEEDS_OPEN;

static {
boolean b = false;
try {
b = JAXBContext.class.getModule() != Version.class.getModule();
} catch (NoSuchMethodError nsme) {
//android
b = false;
}
NEEDS_OPEN = b;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@
// Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.jaxb.compiler;

import java.awt.Image;
import java.beans.Introspector;
import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
Expand Down Expand Up @@ -200,6 +198,7 @@ public final class AnnotationsProcessor {
static final String ARRAY_PACKAGE_NAME = "jaxb.dev.java.net.array";
static final String JAVAX_ACTIVATION_DATAHANDLER = "jakarta.activation.DataHandler";
static final String JAVAX_MAIL_INTERNET_MIMEMULTIPART = "jakarta.mail.internet.MimeMultipart";
private static final String AWT_IMAGE = "java.awt.Image";
private static final String JAVAX_XML_BIND_JAXBELEMENT = "jakarta.xml.bind.JAXBElement";
private static final String JAVAX_XML_BIND_ANNOTATION = "jakarta.xml.bind.annotation";
private static final String OXM_ANNOTATIONS = "org.eclipse.persistence.oxm.annotations";
Expand Down Expand Up @@ -363,7 +362,7 @@ public void createElementsForTypeMappingInfo() {
} else {
qname = getUserDefinedSchemaTypes().get(nextClassName);
if (qname == null) {
if (nextClassName.equals(ClassConstants.APBYTE.getName()) || nextClassName.equals(Image.class.getName()) || nextClassName.equals(Source.class.getName()) || nextClassName.equals("jakarta.activation.DataHandler")) {
if (nextClassName.equals(ClassConstants.APBYTE.getName()) || nextClassName.equals(AWT_IMAGE) || nextClassName.equals(Source.class.getName()) || nextClassName.equals(JAVAX_ACTIVATION_DATAHANDLER)) {
if (xmlAttachmentRef) {
qname = Constants.SWA_REF_QNAME;
} else {
Expand Down Expand Up @@ -1229,7 +1228,7 @@ private void processAdditionalClasses(JavaClass cls, TypeMappingInfo tmi, ArrayL
}
}

if (areEquals(javaClass, byte[].class) || areEquals(javaClass, JAVAX_ACTIVATION_DATAHANDLER) || areEquals(javaClass, Source.class) || areEquals(javaClass, Image.class) || areEquals(javaClass, JAVAX_MAIL_INTERNET_MIMEMULTIPART)) {
if (areEquals(javaClass, byte[].class) || areEquals(javaClass, JAVAX_ACTIVATION_DATAHANDLER) || areEquals(javaClass, Source.class) || areEquals(javaClass, AWT_IMAGE) || areEquals(javaClass, JAVAX_MAIL_INTERNET_MIMEMULTIPART)) {
if (tmi == null || tmi.getXmlTagName() == null) {
ElementDeclaration declaration = new ElementDeclaration(null, javaClass, javaClass.getQualifiedName(), false, XmlElementDecl.GLOBAL.class);
declaration.setTypeMappingInfo(tmi);
Expand Down Expand Up @@ -2977,7 +2976,7 @@ public ArrayList<Property> getPropertyPropertiesForClass(JavaClass cls, TypeInfo

// use the JavaBean API to correctly decapitalize the first
// character, if necessary
propertyName = Introspector.decapitalize(propertyName);
propertyName = org.eclipse.persistence.internal.helper.Helper.decapitalize(propertyName);

JavaClass[] paramTypes = { getMethod.getReturnType() };
setMethod = cls.getDeclaredMethod(setMethodName, paramTypes);
Expand Down Expand Up @@ -3079,7 +3078,7 @@ public ArrayList<Property> getPropertyPropertiesForClass(JavaClass cls, TypeInfo
}
// use the JavaBean API to correctly decapitalize the first
// character, if necessary
propertyName = Introspector.decapitalize(propertyName);
propertyName = org.eclipse.persistence.internal.helper.Helper.decapitalize(propertyName);
}

JavaClass ptype = null;
Expand Down Expand Up @@ -5014,7 +5013,7 @@ private Map<Object, Object> createUserPropertiesMap(XmlProperty[] properties) {
*/
public boolean isMtomAttachment(Property property) {
JavaClass ptype = property.getActualType();
return (areEquals(ptype, JAVAX_ACTIVATION_DATAHANDLER) || areEquals(ptype, byte[].class) || areEquals(ptype, Image.class) || areEquals(ptype, Source.class) || areEquals(ptype, JAVAX_MAIL_INTERNET_MIMEMULTIPART));
return (areEquals(ptype, JAVAX_ACTIVATION_DATAHANDLER) || areEquals(ptype, byte[].class) || areEquals(ptype, AWT_IMAGE) || areEquals(ptype, Source.class) || areEquals(ptype, JAVAX_MAIL_INTERNET_MIMEMULTIPART));
}

public boolean hasSwaRef() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@
// Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.jaxb.compiler;

import java.awt.Image;
import java.beans.Introspector;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Deque;
Expand Down Expand Up @@ -44,6 +42,7 @@
import jakarta.xml.bind.annotation.adapters.CollapsedStringAdapter;
import jakarta.xml.bind.annotation.adapters.NormalizedStringAdapter;

import org.eclipse.persistence.Version;
import org.eclipse.persistence.asm.ClassWriter;
import org.eclipse.persistence.asm.EclipseLinkASMClassWriter;
import org.eclipse.persistence.asm.MethodVisitor;
Expand Down Expand Up @@ -110,6 +109,7 @@
import org.eclipse.persistence.internal.queries.ContainerPolicy;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.jaxb.JAXBContext;
import org.eclipse.persistence.jaxb.JAXBEnumTypeConverter;
import org.eclipse.persistence.jaxb.TypeMappingInfo;
import org.eclipse.persistence.jaxb.javamodel.Helper;
Expand Down Expand Up @@ -1386,7 +1386,7 @@ public Mapping generateMappingForReferenceProperty(Property property, Descriptor
QName elementName = element.getElementName();
JavaClass pType = element.getJavaType();
String pTypeName = element.getJavaTypeName();
boolean isBinaryType = (areEquals(pType, AnnotationsProcessor.JAVAX_ACTIVATION_DATAHANDLER) || areEquals(pType, byte[].class) || areEquals(pType, Image.class) || areEquals(pType, Source.class) || areEquals(pType, AnnotationsProcessor.JAVAX_MAIL_INTERNET_MIMEMULTIPART));
boolean isBinaryType = (areEquals(pType, AnnotationsProcessor.JAVAX_ACTIVATION_DATAHANDLER) || areEquals(pType, byte[].class) || areEquals(pType, "java.awt.Image") || areEquals(pType, Source.class) || areEquals(pType, AnnotationsProcessor.JAVAX_MAIL_INTERNET_MIMEMULTIPART));
boolean isText = pType.isEnum() || (!isBinaryType && !(this.typeInfo.containsKey(element.getJavaTypeName())) && !(element.getJavaTypeName().equals(OBJECT_CLASS_NAME)));
String xPath = wrapperXPath;

Expand Down Expand Up @@ -1721,7 +1721,7 @@ public BinaryDataMapping generateBinaryMapping(Property property, Descriptor des
} else {
if(areEquals(property.getType(), javax.xml.transform.Source.class)) {
mapping.setMimeTypePolicy(new FixedMimeTypePolicy("application/xml", (DatabaseMapping)mapping));
} else if(areEquals(property.getType(), java.awt.Image.class)) {
} else if(areEquals(property.getType(), "java.awt.Image")) {
mapping.setMimeTypePolicy(new FixedMimeTypePolicy("image/png", (DatabaseMapping)mapping));
} else {
mapping.setMimeTypePolicy(new FixedMimeTypePolicy("application/octet-stream", (DatabaseMapping)mapping));
Expand Down Expand Up @@ -2069,6 +2069,16 @@ private Class<?> generateMapEntryClass(String className, String keyType, String
cw.visitEnd();

byte[] classBytes =cw.toByteArray();

if (NEEDS_OPEN) {
Module moxyModule = MappingsGenerator.class.getModule();
if (moxyModule.isNamed() && !moxyModule.isExported(WrappedValue.class.getPackageName(), getJaxbClassLoader().getUnnamedModule())) {
// our generated classes live in unnamed module, therefore we need to export our private class
// to the unnamed module as we don't want to export internal package from eclipselink.jar
moxyModule.addExports(WrappedValue.class.getPackageName(), getJaxbClassLoader().getUnnamedModule());
}
}

Class<?> generatedClass = getJaxbClassLoader().generateClass(className, classBytes);
return generatedClass;
}
Expand Down Expand Up @@ -2928,8 +2938,7 @@ public Property getXmlValueFieldForSimpleContent(ArrayList<Property> properties)
}

public String getSchemaTypeNameForClassName(String className) {
String typeName = Introspector.decapitalize(className.substring(className.lastIndexOf('.') + 1));
return typeName;
return org.eclipse.persistence.internal.helper.Helper.decapitalize(className.substring(className.lastIndexOf('.') + 1));
}

public void processGlobalElements(CoreProject project) {
Expand Down Expand Up @@ -2973,17 +2982,7 @@ public void processGlobalElements(CoreProject project) {
if(nextElement.getJavaType().isEnum()) {
if(!(helper.getClassLoader() instanceof DynamicClassLoader)) {
// Only generate enum wrappers in non-dynamic case.
Class<?> generatedClass = addEnumerationWrapperAndDescriptor(type, nextElement.getJavaType().getRawName(), nextElement, nextClassName, attributeTypeName);
this.qNamesToGeneratedClasses.put(next, generatedClass);
if(nextElement.getTypeMappingInfo() != null) {
typeMappingInfoToGeneratedClasses.put(nextElement.getTypeMappingInfo(), generatedClass);
}
try{
Class<Object> declaredClass = PrivilegedAccessHelper.getClassForName(nextClassName, false, helper.getClassLoader());
this.qNamesToDeclaredClasses.put(next, declaredClass);
}catch(Exception ex) {

}
addEnumerationWrapperAndDescriptor(type, nextElement.getJavaType().getRawName(), nextElement, nextClassName, attributeTypeName);
}

}
Expand Down Expand Up @@ -3026,7 +3025,11 @@ private Class<?> addByteArrayWrapperAndDescriptor(TypeInfo type , String javaCla
private Class<?> addEnumerationWrapperAndDescriptor(TypeInfo type, String javaClassName, ElementDeclaration nextElement, String nextClassName, String attributeTypeName) {
Class<?> generatedClass = classToGeneratedClasses.get(javaClassName);
if(generatedClass == null){
generatedClass = generateWrapperClassAndDescriptor(type, nextElement.getElementName(), nextElement, nextClassName, attributeTypeName);
QName q = nextElement.getElementName();
if (q == null) {
q = new QName(type.getClassNamespace(), type.getSchemaTypeName());
}
generatedClass = generateWrapperClassAndDescriptor(type, q, nextElement, nextClassName, attributeTypeName);
classToGeneratedClasses.put(javaClassName, generatedClass);
}
return generatedClass;
Expand Down Expand Up @@ -3286,11 +3289,13 @@ public Class<?> generateWrapperClass(String className, String attributeType, boo
byte[] classBytes = cw.toByteArray();
//byte[] classBytes = new byte[]{};

Module moxyModule = MappingsGenerator.class.getModule();
if (moxyModule.isNamed() && !moxyModule.isExported(WrappedValue.class.getPackageName(), getJaxbClassLoader().getUnnamedModule())) {
// our generated classes live in unnamed module, therefore we need to export our private class
// to the unnamed module as we don't want to export internal package from eclipselink.jar
moxyModule.addExports(WrappedValue.class.getPackageName(), getJaxbClassLoader().getUnnamedModule());
if (NEEDS_OPEN) {
Module moxyModule = MappingsGenerator.class.getModule();
if (moxyModule.isNamed() && !moxyModule.isExported(WrappedValue.class.getPackageName(), getJaxbClassLoader().getUnnamedModule())) {
// our generated classes live in unnamed module, therefore we need to export our private class
// to the unnamed module as we don't want to export internal package from eclipselink.jar
moxyModule.addExports(WrappedValue.class.getPackageName(), getJaxbClassLoader().getUnnamedModule());
}
}
Class<?> generatedClass = getJaxbClassLoader().generateClass(className, classBytes);
return generatedClass;
Expand Down Expand Up @@ -3529,4 +3534,17 @@ private void logMappingGeneration(Descriptor xmlDescriptor) {
AbstractSessionLog.getLog().log(SessionLog.FINEST, SessionLog.MOXY, xmlMapping.toString(), new Object[0], false);
}
}

private static final boolean NEEDS_OPEN;

static {
boolean b = false;
try {
b = JAXBContext.class.getModule() != Version.class.getModule();
} catch (NoSuchMethodError nsme) {
//android
b = false;
}
NEEDS_OPEN = b;
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2023 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
Expand All @@ -14,8 +14,6 @@
// Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.jaxb.compiler;

import java.awt.Image;
import java.beans.Introspector;
import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
Expand Down Expand Up @@ -115,6 +113,7 @@ public class SchemaGenerator {

private static final String JAVAX_ACTIVATION_DATAHANDLER = "jakarta.activation.DataHandler";
private static final String JAVAX_MAIL_INTERNET_MIMEMULTIPART = "jakarta.mail.internet.MimeMultipart";
private static final String AWT_IMAGE = "java.awt.Image";
private static final String SWA_REF_IMPORT = "http://ws-i.org/profiles/basic/1.1/swaref.xsd";

private static final String COLON = ":";
Expand Down Expand Up @@ -611,7 +610,7 @@ public void populateSchemaTypes() {
}

public String getSchemaTypeNameForClassName(String className) {
return Introspector.decapitalize(className.substring(className.lastIndexOf(DOT_CHAR) + 1));
return org.eclipse.persistence.internal.helper.Helper.decapitalize(className.substring(className.lastIndexOf(DOT_CHAR) + 1));
}

public ArrayList<Object> getEnumerationFacetsFor(EnumTypeInfo info) {
Expand Down Expand Up @@ -822,7 +821,7 @@ public void addGlobalElements(Map<QName, ElementDeclaration> additionalElements)
QName schemaType = helper.getXMLToJavaTypeMap().get(javaClass.getRawName());
if (schemaType != null) {
element.setType(Constants.SCHEMA_PREFIX + COLON + schemaType.getLocalPart());
} else if (areEquals(javaClass, JAVAX_ACTIVATION_DATAHANDLER) || areEquals(javaClass, byte[].class) || areEquals(javaClass, Byte[].class) || areEquals(javaClass, Image.class) || areEquals(javaClass, Source.class) || areEquals(javaClass, JAVAX_MAIL_INTERNET_MIMEMULTIPART)) {
} else if (areEquals(javaClass, JAVAX_ACTIVATION_DATAHANDLER) || areEquals(javaClass, byte[].class) || areEquals(javaClass, Byte[].class) || areEquals(javaClass, AWT_IMAGE) || areEquals(javaClass, Source.class) || areEquals(javaClass, JAVAX_MAIL_INTERNET_MIMEMULTIPART)) {
schemaType = Constants.BASE_64_BINARY_QNAME;
if(nextElement.getTypeMappingInfo() != null) {
if(nextElement.isXmlAttachmentRef()) {
Expand Down

0 comments on commit 58f1330

Please sign in to comment.