You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by jl...@apache.org on 2021/04/02 17:38:07 UTC
[tomee-jakarta] branch master updated: CXF update comes with a
Factory creator helper, so we probably don't need this anymore. We'll see
This is an automated email from the ASF dual-hosted git repository.
jlmonteiro pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/tomee-jakarta.git
The following commit(s) were added to refs/heads/master by this push:
new 64907ef CXF update comes with a Factory creator helper, so we probably don't need this anymore. We'll see
64907ef is described below
commit 64907eff2966854fa54197e2cfe5d97d1d9b5210
Author: Jean-Louis Monteiro <jl...@tomitribe.com>
AuthorDate: Fri Apr 2 19:36:23 2021 +0200
CXF update comes with a Factory creator helper, so we probably don't need this anymore. We'll see
---
.../apache/cxf/jaxb/JAXBContextInitializer.java | 614 ---------------------
1 file changed, 614 deletions(-)
diff --git a/transform/src/patch/java/org/apache/cxf/jaxb/JAXBContextInitializer.java b/transform/src/patch/java/org/apache/cxf/jaxb/JAXBContextInitializer.java
deleted file mode 100644
index 6e247aa..0000000
--- a/transform/src/patch/java/org/apache/cxf/jaxb/JAXBContextInitializer.java
+++ /dev/null
@@ -1,614 +0,0 @@
-/**
- * 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.jaxb;
-
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Array;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Field;
-import java.lang.reflect.GenericArrayType;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
-import java.lang.reflect.TypeVariable;
-import java.lang.reflect.WildcardType;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import jakarta.xml.bind.annotation.XmlAccessType;
-import jakarta.xml.bind.annotation.XmlAttribute;
-import jakarta.xml.bind.annotation.XmlElement;
-import jakarta.xml.bind.annotation.XmlRootElement;
-import jakarta.xml.bind.annotation.XmlSeeAlso;
-import jakarta.xml.bind.annotation.XmlTransient;
-import jakarta.xml.bind.annotation.XmlType;
-import jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
-import jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapters;
-import javax.xml.namespace.QName;
-
-import org.apache.cxf.common.classloader.ClassLoaderUtils;
-import org.apache.cxf.common.jaxb.JAXBUtils;
-import org.apache.cxf.common.logging.LogUtils;
-import org.apache.cxf.common.spi.ClassGeneratorClassLoader;
-import org.apache.cxf.common.util.ASMHelper;
-import org.apache.cxf.common.util.ASMHelper.ClassWriter;
-import org.apache.cxf.common.util.ASMHelper.MethodVisitor;
-import org.apache.cxf.common.util.ASMHelperImpl;
-import org.apache.cxf.common.util.OpcodesProxy;
-import org.apache.cxf.common.util.ReflectionUtil;
-import org.apache.cxf.common.util.StringUtils;
-import org.apache.cxf.service.ServiceModelVisitor;
-import org.apache.cxf.service.model.MessageInfo;
-import org.apache.cxf.service.model.MessagePartInfo;
-import org.apache.cxf.service.model.OperationInfo;
-import org.apache.cxf.service.model.ServiceInfo;
-import org.apache.cxf.service.model.UnwrappedOperationInfo;
-
-/**
- * Walks the service model and sets up the classes for the context.
- */
-class JAXBContextInitializer extends ServiceModelVisitor {
- private static final Logger LOG = LogUtils.getL7dLogger(JAXBContextInitializer.class);
- private Set<Class<?>> classes;
- private Collection<Object> typeReferences;
- private Set<Class<?>> globalAdapters = new HashSet<>();
- private Map<String, Object> unmarshallerProperties;
-
- JAXBContextInitializer(ServiceInfo serviceInfo,
- Set<Class<?>> classes,
- Collection<Object> typeReferences,
- Map<String, Object> unmarshallerProperties) {
- super(serviceInfo);
- this.classes = classes;
- this.typeReferences = typeReferences;
- this.unmarshallerProperties = unmarshallerProperties;
- }
-
- @Override
- public void begin(MessagePartInfo part) {
- Class<?> clazz = part.getTypeClass();
- if (clazz == null) {
- return;
- }
-
- if (Exception.class.isAssignableFrom(clazz)) {
- //exceptions are handled special, make sure we mark it
- part.setProperty(JAXBDataBinding.class.getName() + ".CUSTOM_EXCEPTION",
- Boolean.TRUE);
- }
- boolean isFromWrapper = part.getMessageInfo().getOperation().isUnwrapped();
- if (isFromWrapper
- && !Boolean.TRUE.equals(part.getProperty("messagepart.isheader"))) {
- UnwrappedOperationInfo uop = (UnwrappedOperationInfo)part.getMessageInfo().getOperation();
- OperationInfo op = uop.getWrappedOperation();
- MessageInfo inf = null;
- if (uop.getInput() == part.getMessageInfo()) {
- inf = op.getInput();
- } else if (uop.getOutput() == part.getMessageInfo()) {
- inf = op.getOutput();
- }
- if (inf != null
- && inf.getFirstMessagePart().getTypeClass() != null) {
- //if the wrapper has a type class, we don't need to do anything
- //as everything would have been discovered when walking the
- //wrapper type (unless it's a header which wouldn't be in the wrapper)
- return;
- }
- }
- if (isFromWrapper
- && clazz.isArray()
- && !Byte.TYPE.equals(clazz.getComponentType())) {
- clazz = clazz.getComponentType();
- }
-
- Annotation[] a = (Annotation[])part.getProperty("parameter.annotations");
- checkForAdapter(clazz, a);
-
- Type genericType = (Type) part.getProperty("generic.type");
- if (genericType != null) {
- boolean isList = Collection.class.isAssignableFrom(clazz);
- if (isFromWrapper) {
- if (genericType instanceof Class
- && ((Class<?>)genericType).isArray()) {
- Class<?> cl2 = (Class<?>)genericType;
- if (cl2.isArray()
- && !Byte.TYPE.equals(cl2.getComponentType())) {
- genericType = cl2.getComponentType();
- }
- addType(genericType);
- } else if (!isList) {
- addType(genericType);
- }
- } else {
- addType(genericType, true);
- }
-
- if (isList
- && genericType instanceof ParameterizedType) {
- ParameterizedType pt = (ParameterizedType) genericType;
- if (pt.getActualTypeArguments().length > 0
- && pt.getActualTypeArguments()[0] instanceof Class) {
-
- Class<? extends Object> arrayCls =
- Array.newInstance((Class<?>) pt.getActualTypeArguments()[0], 0).getClass();
- clazz = arrayCls;
- part.setTypeClass(clazz);
- if (isFromWrapper) {
- addType(clazz.getComponentType(), true);
- }
- } else if (pt.getActualTypeArguments().length > 0
- && pt.getActualTypeArguments()[0] instanceof GenericArrayType) {
- GenericArrayType gat = (GenericArrayType)pt.getActualTypeArguments()[0];
- gat.getGenericComponentType();
- Class<? extends Object> arrayCls =
- Array.newInstance((Class<?>) gat.getGenericComponentType(), 0).getClass();
- clazz = Array.newInstance(arrayCls, 0).getClass();
- part.setTypeClass(clazz);
- if (isFromWrapper) {
- addType(clazz.getComponentType(), true);
- }
- }
- }
- if (isFromWrapper && isList) {
- clazz = null;
- }
- }
- if (clazz != null) {
- if (!isFromWrapper
- && clazz.getAnnotation(XmlRootElement.class) == null
- && clazz.getAnnotation(XmlType.class) != null
- && StringUtils.isEmpty(clazz.getAnnotation(XmlType.class).name())) {
- Object ref = createTypeReference(part.getName(), clazz);
- if (ref != null) {
- typeReferences.add(ref);
- }
- }
-
- addClass(clazz);
- }
- }
-
- private void checkForAdapter(Class<?> clazz, Annotation[] anns) {
- if (anns != null) {
- for (Annotation a : anns) {
- if (XmlJavaTypeAdapter.class.isAssignableFrom(a.annotationType())) {
- Type t = Utils.getTypeFromXmlAdapter((XmlJavaTypeAdapter)a);
- if (t != null) {
- addType(t);
- }
- }
- }
- }
- XmlJavaTypeAdapter xjta = clazz.getAnnotation(XmlJavaTypeAdapter.class);
- if (xjta != null) {
- Type t = Utils.getTypeFromXmlAdapter(xjta);
- if (t != null) {
- addType(t);
- }
- }
- if (clazz.getPackage() != null) {
- XmlJavaTypeAdapters adapt = clazz.getPackage().getAnnotation(XmlJavaTypeAdapters.class);
- if (adapt != null) {
- for (XmlJavaTypeAdapter a : adapt.value()) {
- globalAdapters.add(a.type());
- }
- for (XmlJavaTypeAdapter a : adapt.value()) {
- Type t = Utils.getTypeFromXmlAdapter(a);
- if (t != null) {
- addType(t);
- }
- }
- }
- }
- }
-
- private void addType(Type cls) {
- addType(cls, false);
- }
- private void addType(Type cls, boolean allowArray) {
- if (cls instanceof Class) {
- if (globalAdapters.contains(cls)) {
- return;
- }
- if (((Class<?>)cls).isArray() && !allowArray) {
- addClass(((Class<?>)cls).getComponentType());
- } else {
- addClass((Class<?>)cls);
- }
- } else if (cls instanceof ParameterizedType) {
- final ParameterizedType parameterizedType = (ParameterizedType)cls;
- addType(parameterizedType.getRawType());
- if (!parameterizedType.getRawType().equals(Enum.class)) {
- for (Type t2 : parameterizedType.getActualTypeArguments()) {
- if (shouldTypeBeAdded(t2, parameterizedType)) {
- addType(t2);
- }
- }
- }
- } else if (cls instanceof GenericArrayType) {
- Class<?> ct;
- GenericArrayType gt = (GenericArrayType)cls;
- Type componentType = gt.getGenericComponentType();
- if (componentType instanceof Class) {
- ct = (Class<?>)componentType;
- } else if (componentType instanceof ParameterizedType) {
- final ParameterizedType parameterizedType = (ParameterizedType)componentType;
- final Type rawType = parameterizedType.getRawType();
- if (rawType instanceof Class) {
- ct = (Class<?>)rawType;
- } else {
- throw new IllegalArgumentException("Unable to determine type for " + rawType);
- }
- if (!parameterizedType.getRawType().equals(Enum.class)) {
- for (Type t2 : parameterizedType.getActualTypeArguments()) {
- if (shouldTypeBeAdded(t2, parameterizedType)) {
- addType(t2);
- }
- }
- }
- } else {
- TypeVariable<?> tv = (TypeVariable<?>)componentType;
- Type[] bounds = tv.getBounds();
- if (bounds != null && bounds.length == 1) {
- if (bounds[0] instanceof Class) {
- ct = (Class<?>)bounds[0];
- } else {
- throw new IllegalArgumentException("Unable to determine type for: " + tv);
- }
- } else {
- throw new IllegalArgumentException("Unable to determine type for: " + tv);
- }
- }
- ct = Array.newInstance(ct, 0).getClass();
-
- addClass(ct);
- } else if (cls instanceof WildcardType) {
- for (Type t : ((WildcardType)cls).getUpperBounds()) {
- addType(t);
- }
- for (Type t : ((WildcardType)cls).getLowerBounds()) {
- addType(t);
- }
- } else if (cls instanceof TypeVariable) {
- for (Type t : ((TypeVariable<?>)cls).getBounds()) {
- addType(t);
- }
- }
- }
-
- private boolean shouldTypeBeAdded(final Type t2, final ParameterizedType parameterizedType) {
- if (!(t2 instanceof TypeVariable)) {
- return true;
- }
- TypeVariable<?> typeVariable = (TypeVariable<?>) t2;
- final Type[] bounds = typeVariable.getBounds();
- for (Type bound : bounds) {
- if (bound instanceof ParameterizedType && bound.equals(parameterizedType)) {
- return false;
- }
- }
- return true;
- }
-
- void addClass(Class<?> claz) {
- if (Throwable.class.isAssignableFrom(claz)) {
- if (!Throwable.class.equals(claz)
- && !Exception.class.equals(claz)) {
- walkReferences(claz);
- }
- addClass(String.class);
- } else if (claz.getName().startsWith("java.")
- || claz.getName().startsWith("javax.")
- || claz.getName().startsWith("jakarta.")) {
- return;
- } else {
- Class<?> cls = JAXBUtils.getValidClass(claz);
- if (cls == null
- && ReflectionUtil.getDeclaredConstructors(claz).length > 0
- && !Modifier.isAbstract(claz.getModifiers())) {
- if (LOG.isLoggable(Level.INFO)) {
- LOG.info("Class " + claz.getName() + " does not have a default constructor which JAXB requires.");
- }
- //there is no init(), but other constructors
- Object factory = createFactory(claz, ReflectionUtil.getDeclaredConstructors(claz)[0]);
- unmarshallerProperties.put("com.sun.xml.bind.ObjectFactory", factory);
- cls = claz;
- }
- if (null != cls) {
- if (classes.contains(cls)) {
- return;
- }
-
- if (!cls.isInterface()) {
- classes.add(cls);
- }
-
- XmlSeeAlso xsa = cls.getAnnotation(XmlSeeAlso.class);
- if (xsa != null) {
- for (Class<?> c : xsa.value()) {
- addClass(c);
- }
- }
- XmlJavaTypeAdapter xjta = cls.getAnnotation(XmlJavaTypeAdapter.class);
- if (xjta != null) {
- //has an adapter. We need to inspect the adapter and then
- //return as the adapter will handle the superclass
- //and interfaces and such
- Type t = Utils.getTypeFromXmlAdapter(xjta);
- if (t != null) {
- addType(t);
- }
- return;
- }
-
- if (cls.getSuperclass() != null) {
- //JAXB should do this, but it doesn't always.
- //in particular, older versions of jaxb don't
- addClass(cls.getSuperclass());
- }
-
- if (!cls.isInterface()) {
- walkReferences(cls);
- }
- }
- }
- }
-
- private void walkReferences(Class<?> cls) {
- if (cls == null) {
- return;
- }
- if (cls.getName().startsWith("java.")
- || cls.getName().startsWith("javax.")
- || cls.getName().startsWith("jakarta.")) {
- return;
- }
- //walk the public fields/methods to try and find all the classes. JAXB will only load the
- //EXACT classes in the fields/methods if they are in a different package. Thus,
- //subclasses won't be found and the xsi:type stuff won't work at all.
- //We'll grab the public field/method types and then add the ObjectFactory stuff
- //as well as look for jaxb.index files in those packages.
-
- XmlAccessType accessType = Utils.getXmlAccessType(cls);
-
- if (accessType != XmlAccessType.PROPERTY) { // only look for fields if we are instructed to
- //fields are accessible even if not public, must look at the declared fields
- //then walk to parents declared fields, etc...
- Field[] fields = ReflectionUtil.getDeclaredFields(cls);
- for (Field f : fields) {
- if (isFieldAccepted(f, accessType)) {
- XmlJavaTypeAdapter xjta = Utils.getFieldXJTA(f);
- if (xjta != null) {
- Type t = Utils.getTypeFromXmlAdapter(xjta);
- if (t != null) {
- addType(t);
- continue;
- }
- }
- addType(f.getGenericType());
- }
- }
- walkReferences(cls.getSuperclass());
- }
-
- if (accessType != XmlAccessType.FIELD) { // only look for methods if we are instructed to
- Method[] methods = ReflectionUtil.getDeclaredMethods(cls);
- for (Method m : methods) {
- if (isMethodAccepted(m, accessType)) {
- XmlJavaTypeAdapter xjta = Utils.getMethodXJTA(m);
- if (xjta != null) {
- Type t = Utils.getTypeFromXmlAdapter(xjta);
- if (t != null) {
- addType(t);
- continue;
- }
- }
- addType(m.getGenericReturnType());
- for (Type t : m.getGenericParameterTypes()) {
- addType(t);
- }
- }
- }
- }
- }
-
- /**
- * Checks if the field is accepted as a JAXB property.
- */
- static boolean isFieldAccepted(Field field, XmlAccessType accessType) {
- // We only accept non static fields which are not marked @XmlTransient or has transient modifier
- if (field.isAnnotationPresent(XmlTransient.class)
- || Modifier.isTransient(field.getModifiers())) {
- return false;
- }
- if (Modifier.isStatic(field.getModifiers())) {
- return field.isAnnotationPresent(XmlAttribute.class);
- }
- if (accessType == XmlAccessType.PUBLIC_MEMBER
- && !Modifier.isPublic(field.getModifiers())) {
- return false;
- }
- if (accessType == XmlAccessType.NONE
- || accessType == XmlAccessType.PROPERTY) {
- return checkJaxbAnnotation(field.getAnnotations());
- }
- return true;
- }
-
- /**
- * Checks if the method is accepted as a JAXB property getter.
- */
- static boolean isMethodAccepted(Method method, XmlAccessType accessType) {
- // We only accept non static property getters which are not marked @XmlTransient
- if (Modifier.isStatic(method.getModifiers())
- || method.isAnnotationPresent(XmlTransient.class)
- || !Modifier.isPublic(method.getModifiers())
- || "getClass".equals(method.getName())) {
- return false;
- }
-
- // must not have parameters and return type must not be void
- if (method.getReturnType() == Void.class || method.getReturnType() == Void.TYPE
- || method.getParameterTypes().length != 0
- || (method.getDeclaringClass().equals(Throwable.class)
- && !("getMessage".equals(method.getName())))
- || !(method.getName().startsWith("get")
- || method.getName().startsWith("is"))) {
- return false;
- }
- int beginIndex = 3;
- if (method.getName().startsWith("is")) {
- beginIndex = 2;
- }
-
- Method setter = null;
- try {
- setter = method.getDeclaringClass()
- .getMethod("set" + method.getName().substring(beginIndex),
- new Class[] {method.getReturnType()});
- } catch (Exception e) {
- //getter, but no setter
- }
- if (setter != null) {
- if (setter.isAnnotationPresent(XmlTransient.class)
- || !Modifier.isPublic(setter.getModifiers())) {
- return false;
- }
- } else if (!Collection.class.isAssignableFrom(method.getReturnType())
- && !Throwable.class.isAssignableFrom(method.getDeclaringClass())) {
- //no setter, it's not a collection (thus getter().add(...)), and
- //not an Exception,
- return false;
- }
-
- if (accessType == XmlAccessType.NONE
- || accessType == XmlAccessType.FIELD) {
- return checkJaxbAnnotation(method.getAnnotations());
- }
- return true;
- }
-
- /**
- * Checks if there are JAXB annotations among the annotations of the class member.
- * @param annotations the array of annotations from the class member
- * @return true if JAXB annotations are present, false otherwise
- */
- static boolean checkJaxbAnnotation(Annotation[] annotations) {
- // must check if there are any jaxb annotations
- Package jaxbAnnotationsPackage = XmlElement.class.getPackage();
- for (Annotation annotation : annotations) {
- if (annotation.annotationType().getPackage() == jaxbAnnotationsPackage) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * The TypeReference class is a sun specific class that is found in two different
- * locations depending on environment. In IBM JDK the class is not available at all.
- * So we have to load it at runtime.
- *
- * @param n
- * @param cls
- * @return initiated TypeReference
- */
- private static Object createTypeReference(QName n, Class<?> cls) {
- Class<?> refClass = null;
- try {
- refClass = ClassLoaderUtils.loadClass("com.sun.xml.bind.api.TypeReference",
- JAXBContextInitializer.class);
- } catch (Throwable ex) {
- try {
- refClass = ClassLoaderUtils.loadClass("com.sun.xml.internal.bind.api.TypeReference",
- JAXBContextInitializer.class);
- } catch (Throwable ex2) {
- //ignore
- }
- }
- if (refClass != null) {
- try {
- return refClass.getConstructor(QName.class, Type.class, new Annotation[0].getClass()) //NOPMD
- .newInstance(n, cls, new Annotation[0]);
- } catch (Throwable e) {
- //ignore
- }
- }
- return null;
- }
-
- @SuppressWarnings("unused")
- private Object createFactory(Class<?> cls, Constructor<?> contructor) {
- final String newClassName = cls.getName() + "Factory";
- final ASMHelper helper = new ASMHelperImpl();
- final ClassWriter cw = helper.createClassWriter();
- final OpcodesProxy opCodes = helper.getOpCodes();
- MethodVisitor mv;
-
- cw.visit(opCodes.V1_6, opCodes.ACC_PUBLIC + opCodes.ACC_SUPER,
- StringUtils.periodToSlashes(newClassName), null, "java/lang/Object", null);
-
- cw.visitSource(cls.getSimpleName() + "Factory" + ".java", null);
-
- mv = cw.visitMethod(opCodes.ACC_PUBLIC, "<init>", "()V", null, null);
- mv.visitCode();
- mv.visitVarInsn(opCodes.ALOAD, 0);
- mv.visitMethodInsn(opCodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
- mv.visitInsn(opCodes.RETURN);
- mv.visitMaxs(1, 1);
- mv.visitEnd();
-
- mv = cw.visitMethod(opCodes.ACC_PUBLIC, "create" + cls.getSimpleName(),
- "()L" + StringUtils.periodToSlashes(cls.getName()) + ";", null, null);
- mv.visitCode();
- String name = cls.getName().replace(".", "/");
- mv.visitTypeInsn(opCodes.NEW, name);
- mv.visitInsn(opCodes.DUP);
- StringBuilder paraString = new StringBuilder(32).append("(");
-
- for (Class<?> paraClass : contructor.getParameterTypes()) {
- mv.visitInsn(opCodes.ACONST_NULL);
- paraString.append("Ljava/lang/Object;");
- }
- paraString.append(")V");
-
- mv.visitMethodInsn(opCodes.INVOKESPECIAL, name, "<init>", paraString.toString(), false);
-
- mv.visitInsn(opCodes.ARETURN);
- mv.visitMaxs(1, 1);
- mv.visitEnd();
-
- cw.visitEnd();
- Class<?> factoryClass = ClassGeneratorClassLoader.loadClass(newClassName, cls, cw.toByteArray());
- try {
- return factoryClass.newInstance();
- } catch (Exception e) {
- //ignore
- }
- return null;
- }
-
-
-}
\ No newline at end of file