This is an automated email from the ASF dual-hosted git repository. orpiske pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/main by this push: new f0b4bb23733 (chores) camel-jaxb: break large and complex methods f0b4bb23733 is described below commit f0b4bb237331c5f9d595286dd0f2097cee8c43f7 Author: Otavio Rodolfo Piske <angusyo...@gmail.com> AuthorDate: Thu May 2 14:33:45 2024 +0200 (chores) camel-jaxb: break large and complex methods --- .../converter/jaxb/FallbackTypeConverter.java | 37 ++--- .../camel/converter/jaxb/JaxbDataFormat.java | 185 ++++++++++++--------- .../jaxb/JaxbRestBindingJaxbDataFormatFactory.java | 34 ++-- 3 files changed, 151 insertions(+), 105 deletions(-) diff --git a/components/camel-jaxb/src/main/java/org/apache/camel/converter/jaxb/FallbackTypeConverter.java b/components/camel-jaxb/src/main/java/org/apache/camel/converter/jaxb/FallbackTypeConverter.java index 5b9d9f6b3ee..e6dba9c4e90 100644 --- a/components/camel-jaxb/src/main/java/org/apache/camel/converter/jaxb/FallbackTypeConverter.java +++ b/components/camel-jaxb/src/main/java/org/apache/camel/converter/jaxb/FallbackTypeConverter.java @@ -94,27 +94,10 @@ public class FallbackTypeConverter { @Converter(fallback = true) public Object convertTo(Class<?> type, Exchange exchange, Object value, TypeConverterRegistry registry) { - - boolean prettyPrint = defaultPrettyPrint; - String property = exchange != null ? exchange.getContext().getGlobalOption(PRETTY_PRINT) : null; - if (property != null) { - if (property.equalsIgnoreCase("false")) { - prettyPrint = false; - } else { - prettyPrint = true; - } - } + final boolean prettyPrint = isPrettyPrint(exchange); // configure object factory - boolean objectFactory = defaultObjectFactory; - property = exchange != null ? exchange.getContext().getGlobalOption(OBJECT_FACTORY) : null; - if (property != null) { - if (property.equalsIgnoreCase("false")) { - objectFactory = false; - } else { - objectFactory = true; - } - } + final boolean objectFactory = isObjectFactory(exchange); TypeConverter converter = null; if (registry instanceof TypeConverter) { @@ -147,6 +130,22 @@ public class FallbackTypeConverter { return null; } + private boolean isPrettyPrint(Exchange exchange) { + final String property = exchange != null ? exchange.getContext().getGlobalOption(PRETTY_PRINT) : null; + if (property != null) { + return Boolean.parseBoolean(property); + } + return defaultPrettyPrint; + } + + private boolean isObjectFactory(Exchange exchange) { + final String property = exchange != null ? exchange.getContext().getGlobalOption(OBJECT_FACTORY) : null; + if (property != null) { + return Boolean.parseBoolean(property); + } + return defaultObjectFactory; + } + private <T> boolean hasXmlRootElement(Class<T> type) { boolean answer = type.getAnnotation(XmlRootElement.class) != null; if (!answer && LOG.isTraceEnabled()) { diff --git a/components/camel-jaxb/src/main/java/org/apache/camel/converter/jaxb/JaxbDataFormat.java b/components/camel-jaxb/src/main/java/org/apache/camel/converter/jaxb/JaxbDataFormat.java index dbd845c19c6..48def5c620a 100644 --- a/components/camel-jaxb/src/main/java/org/apache/camel/converter/jaxb/JaxbDataFormat.java +++ b/components/camel-jaxb/src/main/java/org/apache/camel/converter/jaxb/JaxbDataFormat.java @@ -22,6 +22,7 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.Reader; +import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.MalformedURLException; import java.net.URL; @@ -34,6 +35,7 @@ import jakarta.xml.bind.JAXBException; import jakarta.xml.bind.JAXBIntrospector; import jakarta.xml.bind.MarshalException; import jakarta.xml.bind.Marshaller; +import jakarta.xml.bind.PropertyException; import jakarta.xml.bind.Unmarshaller; import jakarta.xml.bind.ValidationEvent; @@ -156,18 +158,7 @@ public class JaxbDataFormat extends ServiceSupport marshaller.setProperty(namespacePrefixMapper.getRegistrationKey(), namespacePrefixMapper); } // Inject any JAX-RI custom properties from the exchange or from the instance into the marshaller - Map<String, Object> customProperties = exchange.getProperty(JaxbConstants.JAXB_PROVIDER_PROPERTIES, Map.class); - if (customProperties == null) { - customProperties = getJaxbProviderProperties(); - } - if (customProperties != null) { - for (Entry<String, Object> property : customProperties.entrySet()) { - if (LOG.isDebugEnabled()) { - LOG.debug("Using JAXB Provider Property {}={}", property.getKey(), property.getValue()); - } - marshaller.setProperty(property.getKey(), property.getValue()); - } - } + injectCustomProperties(exchange, marshaller); doMarshal(exchange, graph, stream, marshaller, charset); if (contentTypeHeader) { @@ -178,6 +169,21 @@ public class JaxbDataFormat extends ServiceSupport } } + private void injectCustomProperties(Exchange exchange, Marshaller marshaller) throws PropertyException { + Map<String, Object> customProperties = exchange.getProperty(JaxbConstants.JAXB_PROVIDER_PROPERTIES, Map.class); + if (customProperties == null) { + customProperties = getJaxbProviderProperties(); + } + if (customProperties != null) { + for (Entry<String, Object> property : customProperties.entrySet()) { + if (LOG.isDebugEnabled()) { + LOG.debug("Using JAXB Provider Property {}={}", property.getKey(), property.getValue()); + } + marshaller.setProperty(property.getKey(), property.getValue()); + } + } + } + void doMarshal(Exchange exchange, Object graph, OutputStream stream, Marshaller marshaller, String charset) throws Exception { @@ -187,85 +193,116 @@ public class JaxbDataFormat extends ServiceSupport String partNamespaceFromHeader = exchange.getIn().getHeader(JaxbConstants.JAXB_PART_NAMESPACE, String.class); if ((partClass != null || partClassFromHeader != null) && (partNamespaceOnDataFormat != null || partNamespaceFromHeader != null)) { - if (partClassFromHeader != null) { - try { - partClass = camelContext.getClassResolver().resolveMandatoryClass(partClassFromHeader, Object.class); - } catch (ClassNotFoundException e) { - throw new JAXBException(e); - } - } - if (partNamespaceFromHeader != null) { - partNamespaceOnDataFormat = QName.valueOf(partNamespaceFromHeader); - } - element = new JAXBElement<>(partNamespaceOnDataFormat, (Class<Object>) partClass, graph); + element = toElement(graph, partClassFromHeader, partNamespaceFromHeader, partNamespaceOnDataFormat); } // only marshal if its possible if (introspector.isElement(element)) { - if (asXmlStreamWriter(exchange)) { - XMLStreamWriter writer = typeConverter.convertTo(XMLStreamWriter.class, exchange, stream); - if (needFiltering(exchange)) { - writer = new FilteringXmlStreamWriter(writer, charset); - } - if (xmlStreamWriterWrapper != null) { - writer = xmlStreamWriterWrapper.wrapWriter(writer); - } - marshaller.marshal(element, writer); - } else { - marshaller.marshal(element, stream); - } + tryMarshal(exchange, stream, marshaller, charset, element); return; } else if (objectFactory && element != null) { - Method objectFactoryMethod = JaxbHelper.getJaxbElementFactoryMethod(camelContext, element.getClass()); - if (objectFactoryMethod != null) { - try { - Object instance = objectFactoryMethod.getDeclaringClass().newInstance(); - if (instance != null) { - Object toMarshall = objectFactoryMethod.invoke(instance, element); - if (asXmlStreamWriter(exchange)) { - XMLStreamWriter writer = typeConverter.convertTo(XMLStreamWriter.class, exchange, stream); - if (needFiltering(exchange)) { - writer = new FilteringXmlStreamWriter(writer, charset); - } - if (xmlStreamWriterWrapper != null) { - writer = xmlStreamWriterWrapper.wrapWriter(writer); - } - marshaller.marshal(toMarshall, writer); - } else { - marshaller.marshal(toMarshall, stream); - } - return; - } - } catch (Exception e) { - // if a schema is set then an MarshallException is thrown when the XML is not valid - // and the method must throw this exception as it would when the object in the body is a root element - // or a partial class (the other alternatives above) - // - // it would be best to completely remove the exception handler here but it's left for backwards compatibility reasons. - if (MarshalException.class.isAssignableFrom(e.getClass()) && schema != null) { - throw e; - } - - LOG.debug("Unable to create JAXBElement object for type {} due to {}", element.getClass(), - e.getMessage(), e); - } + if (tryFromFactory(exchange, stream, marshaller, charset, element)) { + return; } } // cannot marshal if (!mustBeJAXBElement) { // write the graph as is to the output stream - if (LOG.isDebugEnabled()) { - LOG.debug("Attempt to marshalling non JAXBElement with type {} as InputStream", - ObjectHelper.classCanonicalName(graph)); - } - InputStream is = exchange.getContext().getTypeConverter().mandatoryConvertTo(InputStream.class, exchange, graph); - IOHelper.copyAndCloseInput(is, stream); + writeGraph(exchange, graph, stream); } else { throw new InvalidPayloadException(exchange, JAXBElement.class); } } + private boolean tryFromFactory( + Exchange exchange, OutputStream stream, Marshaller marshaller, String charset, Object element) + throws IllegalAccessException, InvocationTargetException, JAXBException, InstantiationException { + Method objectFactoryMethod = JaxbHelper.getJaxbElementFactoryMethod(camelContext, element.getClass()); + if (objectFactoryMethod != null) { + try { + tryMarshallFromInstance(exchange, stream, marshaller, charset, objectFactoryMethod, element); + return true; + } catch (Exception e) { + // if a schema is set then an MarshallException is thrown when the XML is not valid + // and the method must throw this exception as it would when the object in the body is a root element + // or a partial class (the other alternatives above) + // + // it would be best to completely remove the exception handler here but it's left for backwards compatibility reasons. + if (MarshalException.class.isAssignableFrom(e.getClass()) && schema != null) { + throw e; + } + + LOG.debug("Unable to create JAXBElement object for type {} due to {}", element.getClass(), + e.getMessage(), e); + } + } + return false; + } + + private static void writeGraph(Exchange exchange, Object graph, OutputStream stream) + throws NoTypeConversionAvailableException, IOException { + if (LOG.isDebugEnabled()) { + LOG.debug("Attempt to marshalling non JAXBElement with type {} as InputStream", + ObjectHelper.classCanonicalName(graph)); + } + InputStream is = exchange.getContext().getTypeConverter().mandatoryConvertTo(InputStream.class, exchange, graph); + IOHelper.copyAndCloseInput(is, stream); + } + + private void tryMarshallFromInstance( + Exchange exchange, OutputStream stream, Marshaller marshaller, String charset, Method objectFactoryMethod, + Object element) + throws IllegalAccessException, InvocationTargetException, JAXBException, InstantiationException { + Object instance = objectFactoryMethod.getDeclaringClass().newInstance(); + Object toMarshall = objectFactoryMethod.invoke(instance, element); + if (asXmlStreamWriter(exchange)) { + XMLStreamWriter writer = typeConverter.convertTo(XMLStreamWriter.class, exchange, stream); + if (needFiltering(exchange)) { + writer = new FilteringXmlStreamWriter(writer, charset); + } + if (xmlStreamWriterWrapper != null) { + writer = xmlStreamWriterWrapper.wrapWriter(writer); + } + marshaller.marshal(toMarshall, writer); + } else { + marshaller.marshal(toMarshall, stream); + } + return; + } + + private void tryMarshal(Exchange exchange, OutputStream stream, Marshaller marshaller, String charset, Object element) + throws JAXBException { + if (asXmlStreamWriter(exchange)) { + XMLStreamWriter writer = typeConverter.convertTo(XMLStreamWriter.class, exchange, stream); + if (needFiltering(exchange)) { + writer = new FilteringXmlStreamWriter(writer, charset); + } + if (xmlStreamWriterWrapper != null) { + writer = xmlStreamWriterWrapper.wrapWriter(writer); + } + marshaller.marshal(element, writer); + } else { + marshaller.marshal(element, stream); + } + } + + private Object toElement( + Object graph, String partClassFromHeader, String partNamespaceFromHeader, QName partNamespaceOnDataFormat) + throws JAXBException { + if (partClassFromHeader != null) { + try { + partClass = camelContext.getClassResolver().resolveMandatoryClass(partClassFromHeader, Object.class); + } catch (ClassNotFoundException e) { + throw new JAXBException(e); + } + } + if (partNamespaceFromHeader != null) { + partNamespaceOnDataFormat = QName.valueOf(partNamespaceFromHeader); + } + return new JAXBElement<>(partNamespaceOnDataFormat, (Class<Object>) partClass, graph); + } + private boolean asXmlStreamWriter(Exchange exchange) { return needFiltering(exchange) || xmlStreamWriterWrapper != null; } diff --git a/components/camel-jaxb/src/main/java/org/apache/camel/converter/jaxb/JaxbRestBindingJaxbDataFormatFactory.java b/components/camel-jaxb/src/main/java/org/apache/camel/converter/jaxb/JaxbRestBindingJaxbDataFormatFactory.java index da877ab199d..970bc8a3640 100644 --- a/components/camel-jaxb/src/main/java/org/apache/camel/converter/jaxb/JaxbRestBindingJaxbDataFormatFactory.java +++ b/components/camel-jaxb/src/main/java/org/apache/camel/converter/jaxb/JaxbRestBindingJaxbDataFormatFactory.java @@ -55,12 +55,7 @@ public class JaxbRestBindingJaxbDataFormatFactory implements RestBindingJaxbData .withConfigurer(configurer) .withTarget(jaxb); - String typeName = null; - if (typeClass != null) { - typeName = typeClass.isArray() ? typeClass.getComponentType().getName() : typeClass.getName(); - } else if (type != null) { - typeName = type.endsWith("[]") ? type.substring(0, type.length() - 2) : type; - } + final String typeName = getTypeName(type, typeClass); if (typeName != null) { builder.withProperty("contextPath", typeName); builder.withProperty("contextPathIsClassName", "true"); @@ -78,6 +73,18 @@ public class JaxbRestBindingJaxbDataFormatFactory implements RestBindingJaxbData .withConfigurer(configurer) .withTarget(outJaxb); + final String outTypeName = getOutTypeName(outType, outTypeClass, typeName); + + if (outTypeName != null) { + outBuilder.withProperty("contextPath", outTypeName); + outBuilder.withProperty("contextPathIsClassName", "true"); + } + + setAdditionalConfiguration(config, "xml.out.", outBuilder); + outBuilder.bind(); + } + + private static String getOutTypeName(String outType, Class<?> outTypeClass, String typeName) { String outTypeName = null; if (outTypeClass != null) { outTypeName = outTypeClass.isArray() ? outTypeClass.getComponentType().getName() : outTypeClass.getName(); @@ -87,14 +94,17 @@ public class JaxbRestBindingJaxbDataFormatFactory implements RestBindingJaxbData // fallback and use the context from the input outTypeName = typeName; } + return outTypeName; + } - if (outTypeName != null) { - outBuilder.withProperty("contextPath", outTypeName); - outBuilder.withProperty("contextPathIsClassName", "true"); + private static String getTypeName(String type, Class<?> typeClass) { + String typeName = null; + if (typeClass != null) { + typeName = typeClass.isArray() ? typeClass.getComponentType().getName() : typeClass.getName(); + } else if (type != null) { + typeName = type.endsWith("[]") ? type.substring(0, type.length() - 2) : type; } - - setAdditionalConfiguration(config, "xml.out.", outBuilder); - outBuilder.bind(); + return typeName; } private void setAdditionalConfiguration(RestConfiguration config, String prefix, PropertyBindingSupport.Builder builder) {