Bug 472475: Make bean validation dependency optional is OSGi environment
Signed-off-by: Lukas Jungmann <lukas.jungmann@oracle.com>
Reviewed-by: Petros, Ondrej
diff --git a/moxy/eclipselink.moxy.test/antbuild.xml b/moxy/eclipselink.moxy.test/antbuild.xml
index f20dbbb..2013b80 100644
--- a/moxy/eclipselink.moxy.test/antbuild.xml
+++ b/moxy/eclipselink.moxy.test/antbuild.xml
@@ -328,6 +328,47 @@
<target name="compile-and-run-oxm-deploymentxml-tl-tests" depends="compile-tests" description="build and run moxy (oxm) tl deployment xml tests">
<run_oxm_deploymentxml_tl_tests runpathref="oxm.run.path"/>
</target>
+
+ <target name="init-osgi">
+ <property environment="env"/>
+ <condition property="m2.home.exists" value="true">
+ <isset property="env.M2_HOME"/>
+ </condition>
+ <condition property="M2_HOME" value="${env.M2_HOME}">
+ <isset property="m2.home.exists"/>
+ </condition>
+ </target>
+ <target name="check-osgi" unless="m2.home.exists">
+ <echo message="Skipping OSGi Tests. M2_HOME is not set."/>
+ </target>
+ <target name="compile-and-run-osgi-tests">
+ <condition property="version.qualifier" value="${version.qualifier}" else="qualifier">
+ <isset property="version.qualifier"/>
+ </condition>
+ <echo message="Launching Maven build with the following parameters:"/>
+ <echo message=" -Dclassworlds.conf=${M2_HOME}/bin/m2.conf"/>
+ <echo message=" -Dmaven.home=${M2_HOME}"/>
+ <echo message=" -Dbuild.qualifier=${version.qualifier}"/>
+ <java dir="${basedir}" fork="true" failonerror="true" classname="org.codehaus.plexus.classworlds.launcher.Launcher">
+ <jvmarg value="-Dclassworlds.conf=${M2_HOME}/bin/m2.conf"/>
+ <jvmarg value="-Dmaven.home=${M2_HOME}"/>
+ <!--<arg line="-Dmaven.surefire.debug clean install"/>-->
+ <arg line="clean install"/>
+ <arg line="-Dmoxytest.2.common.plugins.dir=${basedir}/../../plugins/"/>
+ <arg line="-Djavax.validation.lib=${basedir}/${javax.validation.lib}"/>
+ <arg line="-Dbuild.qualifier=${version.qualifier}"/>
+ <arg line="-Drelease.version=${release.version}"/>
+ <arg line="-Djaxb-api.jar=${jaxb-api.jar}"/>
+ <arg line="-Djaxrs.jar=${jaxrs.jar}"/>
+ <arg line="-Dasm.jar=${asm.jar}"/>
+ <classpath>
+ <fileset dir="${M2_HOME}/boot">
+ <include name="plexus-classworlds-*.jar"/>
+ </fileset>
+ </classpath>
+ </java>
+ </target>
+
<target name="run-installer-tests">
<tempfile property="unzip.temp.file" destDir="${java.io.tmpdir}" prefix="build"/>
<mkdir dir="${unzip.temp.file}"/>
diff --git a/moxy/eclipselink.moxy.test/moxy.test.iml b/moxy/eclipselink.moxy.test/moxy.test.iml
index 5015693..3b095b3 100644
--- a/moxy/eclipselink.moxy.test/moxy.test.iml
+++ b/moxy/eclipselink.moxy.test/moxy.test.iml
@@ -257,5 +257,52 @@
<SOURCES />
</library>
</orderEntry>
+ <orderEntry type="module-library">
+ <library>
+ <CLASSES>
+ <root url="jar://$MAVEN_REPOSITORY$/org/ops4j/pax/exam/pax-exam/4.5.0/pax-exam-4.5.0.jar!/" />
+ </CLASSES>
+ <JAVADOC />
+ <SOURCES />
+ </library>
+ </orderEntry>
+ <orderEntry type="module-library">
+ <library>
+ <CLASSES>
+ <root url="jar://$MAVEN_REPOSITORY$/org/ops4j/pax/exam/pax-exam-junit4/4.5.0/pax-exam-junit4-4.5.0.jar!/" />
+ </CLASSES>
+ <JAVADOC />
+ <SOURCES />
+ </library>
+ </orderEntry>
+ <orderEntry type="module-library">
+ <library>
+ <CLASSES>
+ <root url="jar://$MAVEN_REPOSITORY$/org/ops4j/pax/exam/pax-exam-spi/4.5.0/pax-exam-spi-4.5.0.jar!/" />
+ </CLASSES>
+ <JAVADOC />
+ <SOURCES />
+ </library>
+ </orderEntry>
+ <orderEntry type="module-library">
+ <library>
+ <CLASSES>
+ <root url="jar://$MAVEN_REPOSITORY$/org/osgi/org.osgi.core/6.0.0/org.osgi.core-6.0.0.jar!/" />
+ </CLASSES>
+ <JAVADOC />
+ <SOURCES>
+ <root url="jar://$MAVEN_REPOSITORY$/org/osgi/org.osgi.core/6.0.0/org.osgi.core-6.0.0.jar!/OSGI-OPT/src" />
+ </SOURCES>
+ </library>
+ </orderEntry>
+ <orderEntry type="module-library">
+ <library>
+ <CLASSES>
+ <root url="jar://$MAVEN_REPOSITORY$/org/glassfish/hk2/external/javax.inject/2.1.64/javax.inject-2.1.64.jar!/" />
+ </CLASSES>
+ <JAVADOC />
+ <SOURCES />
+ </library>
+ </orderEntry>
</component>
</module>
\ No newline at end of file
diff --git a/moxy/eclipselink.moxy.test/pom.xml b/moxy/eclipselink.moxy.test/pom.xml
new file mode 100644
index 0000000..9a60c3c
--- /dev/null
+++ b/moxy/eclipselink.moxy.test/pom.xml
@@ -0,0 +1,154 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <modelVersion>4.0.0</modelVersion>
+
+ <name>EclipseLink MOXy OSGi Tests</name>
+ <groupId>org.eclipse.persistence</groupId>
+ <artifactId>eclipselink.moxy.test</artifactId>
+ <description>Tests for MOXy OSGi bundles</description>
+ <version>2.6.3-SNAPSHOT</version>
+
+ <properties>
+ <exam.version>4.5.0</exam.version>
+ <url.version>2.4.1</url.version>
+ <logback.version>1.1.3</logback.version>
+ <eclipselink.version>2.6.3-SNAPSHOT</eclipselink.version>
+ </properties>
+
+ <dependencies>
+ <!-- EclipseLink -->
+ <dependency>
+ <groupId>org.eclipse.persistence</groupId>
+ <artifactId>eclipselink</artifactId>
+ <version>${eclipselink.version}</version>
+ <scope>system</scope>
+ <systemPath>${basedir}/../../eclipselink.jar</systemPath>
+ </dependency>
+
+ <!-- Bean validation API -->
+ <dependency>
+ <groupId>javax.validation</groupId>
+ <artifactId>validation</artifactId>
+ <version>1.1</version>
+ <scope>system</scope>
+ <systemPath>${javax.validation.lib}</systemPath>
+ </dependency>
+
+ <!-- Hibernate validator and it's dependencies -->
+ <dependency>
+ <groupId>org.hibernate</groupId>
+ <artifactId>hibernate-validator</artifactId>
+ <version>5.2.0.CR1</version>
+ </dependency>
+ <dependency>
+ <groupId>javax.el</groupId>
+ <artifactId>javax.el-api</artifactId>
+ <version>3.0.0</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-api</artifactId>
+ <version>2.3</version>
+ </dependency>
+
+ <!-- javax.inject -->
+ <dependency>
+ <groupId>javax.inject</groupId>
+ <artifactId>javax.inject</artifactId>
+ <version>1</version>
+ </dependency>
+
+ <!-- Felix -->
+ <dependency>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.apache.felix.framework</artifactId>
+ <version>5.0.0</version>
+ <scope>test</scope>
+ </dependency>
+
+ <!-- PaxExam -->
+ <dependency>
+ <groupId>org.ops4j.pax.exam</groupId>
+ <artifactId>pax-exam</artifactId>
+ <version>${exam.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.ops4j.pax.exam</groupId>
+ <artifactId>pax-exam-container-native</artifactId>
+ <version>${exam.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.ops4j.pax.exam</groupId>
+ <artifactId>pax-exam-junit4</artifactId>
+ <version>${exam.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.ops4j.pax.exam</groupId>
+ <artifactId>pax-exam-link-mvn</artifactId>
+ <version>${exam.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.ops4j.pax.url</groupId>
+ <artifactId>pax-url-aether</artifactId>
+ <version>${url.version}</version>
+ <scope>test</scope>
+ </dependency>
+
+ <!-- Logging, required by Pax -->
+ <dependency>
+ <groupId>ch.qos.logback</groupId>
+ <artifactId>logback-core</artifactId>
+ <version>${logback.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>ch.qos.logback</groupId>
+ <artifactId>logback-classic</artifactId>
+ <version>${logback.version}</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <testSourceDirectory>src/org/eclipse/persistence/testing/osgi</testSourceDirectory>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>3.3</version>
+ <configuration>
+ <source>1.7</source>
+ <target>1.7</target>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>prepare-osgi-bundles</id>
+ <phase>generate-test-resources</phase>
+ <goals>
+ <goal>copy-dependencies</goal>
+ </goals>
+ <configuration>
+ <outputDirectory>${project.build.directory}/testedBundles</outputDirectory>
+ <stripVersion>true</stripVersion>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>2.13</version>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
diff --git a/moxy/eclipselink.moxy.test/src/org/eclipse/persistence/testing/jaxb/beanvalidation/BeanValidationRuntimeTestCase.java b/moxy/eclipselink.moxy.test/src/org/eclipse/persistence/testing/jaxb/beanvalidation/BeanValidationRuntimeTestCase.java
index 3b0ca0a..15088a9 100644
--- a/moxy/eclipselink.moxy.test/src/org/eclipse/persistence/testing/jaxb/beanvalidation/BeanValidationRuntimeTestCase.java
+++ b/moxy/eclipselink.moxy.test/src/org/eclipse/persistence/testing/jaxb/beanvalidation/BeanValidationRuntimeTestCase.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016 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 v1.0 and Eclipse Distribution License v. 1.0
* which accompanies this distribution.
@@ -14,6 +14,7 @@
import org.eclipse.persistence.exceptions.BeanValidationException;
import org.eclipse.persistence.jaxb.BeanValidationMode;
+import org.eclipse.persistence.jaxb.ConstraintViolationWrapper;
import org.eclipse.persistence.jaxb.JAXBContextFactory;
import org.eclipse.persistence.jaxb.JAXBContextProperties;
import org.eclipse.persistence.jaxb.JAXBMarshaller;
@@ -27,7 +28,6 @@
import org.junit.After;
import org.junit.Before;
-import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.ValidatorFactory;
import javax.validation.groups.Default;
@@ -155,7 +155,7 @@
/* Marshal w/o validation - creates file for the next part of the test. */
marshallerValidOff.marshal(employeeInvalid, fileInvalid);
- Set<? extends ConstraintViolation<?>> marshalCV = marshallerValidOff.getConstraintViolations();
+ Set<ConstraintViolationWrapper<Object>> marshalCV = marshallerValidOff.getConstraintViolations();
assertTrue(marshalCV.isEmpty());
/* Unmarshal w/ validation - doesn't pass (we want to check that). */
@@ -187,11 +187,12 @@
assertEquals(employeeInvalid, employeeUnm);
}
- private void checkValidationMessages(Set<? extends ConstraintViolation<?>> constraintViolations,
+ private void checkValidationMessages(Set<ConstraintViolationWrapper<Object>> constraintViolations,
List<String> expectedMessages) {
List<String> violationMessages = new ArrayList<>();
- for (final ConstraintViolation<?> cv : constraintViolations)
+ for (final ConstraintViolationWrapper cv : constraintViolations) {
violationMessages.add(cv.getMessageTemplate());
+ }
assertSame(expectedMessages.size(), violationMessages.size());
assertTrue(violationMessages.containsAll(expectedMessages));
diff --git a/moxy/eclipselink.moxy.test/src/org/eclipse/persistence/testing/jaxb/beanvalidation/BeanValidationSpecialtiesTestCase.java b/moxy/eclipselink.moxy.test/src/org/eclipse/persistence/testing/jaxb/beanvalidation/BeanValidationSpecialtiesTestCase.java
index 675bc51..04e1508 100644
--- a/moxy/eclipselink.moxy.test/src/org/eclipse/persistence/testing/jaxb/beanvalidation/BeanValidationSpecialtiesTestCase.java
+++ b/moxy/eclipselink.moxy.test/src/org/eclipse/persistence/testing/jaxb/beanvalidation/BeanValidationSpecialtiesTestCase.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016 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 v1.0 and Eclipse Distribution License v. 1.0
* which accompanies this distribution.
@@ -12,16 +12,11 @@
******************************************************************************/
package org.eclipse.persistence.testing.jaxb.beanvalidation;
-import org.eclipse.persistence.exceptions.BeanValidationException;
-import org.eclipse.persistence.jaxb.BeanValidationHelper;
-import org.eclipse.persistence.jaxb.JAXBContext;
-import org.eclipse.persistence.jaxb.JAXBContextFactory;
-import org.eclipse.persistence.jaxb.JAXBContextProperties;
-import org.eclipse.persistence.jaxb.JAXBMarshaller;
-import org.eclipse.persistence.testing.jaxb.beanvalidation.special.ConstructorAnnotatedEmployee;
-import org.eclipse.persistence.testing.jaxb.beanvalidation.special.CustomAnnotatedEmployee;
-import org.eclipse.persistence.testing.jaxb.beanvalidation.special.MethodAnnotatedEmployee;
-import org.eclipse.persistence.testing.jaxb.beanvalidation.special.NonConstrainedClass;
+import java.io.StringWriter;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
import javax.validation.ConstraintValidatorFactory;
import javax.validation.ConstraintViolation;
@@ -35,11 +30,18 @@
import javax.validation.executable.ExecutableValidator;
import javax.validation.metadata.BeanDescriptor;
import javax.validation.metadata.ConstraintDescriptor;
-import java.io.StringWriter;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Set;
+
+import org.eclipse.persistence.exceptions.BeanValidationException;
+import org.eclipse.persistence.jaxb.BeanValidationHelper;
+import org.eclipse.persistence.jaxb.ConstraintViolationWrapper;
+import org.eclipse.persistence.jaxb.JAXBContext;
+import org.eclipse.persistence.jaxb.JAXBContextFactory;
+import org.eclipse.persistence.jaxb.JAXBContextProperties;
+import org.eclipse.persistence.jaxb.JAXBMarshaller;
+import org.eclipse.persistence.testing.jaxb.beanvalidation.special.ConstructorAnnotatedEmployee;
+import org.eclipse.persistence.testing.jaxb.beanvalidation.special.CustomAnnotatedEmployee;
+import org.eclipse.persistence.testing.jaxb.beanvalidation.special.MethodAnnotatedEmployee;
+import org.eclipse.persistence.testing.jaxb.beanvalidation.special.NonConstrainedClass;
/**
* Test case storing non-standard tests, i.e. those that didn't fit neither in
@@ -67,13 +69,13 @@
} catch (BeanValidationException ignored) {
}
- Set<? extends ConstraintViolation<?>> violations = marshaller.getConstraintViolations();
+ Set<ConstraintViolationWrapper<Object>> violations = marshaller.getConstraintViolations();
assertFalse("Some constraints were not validated, even though they should have been.", violations.isEmpty());
// For all, i.e. one constraintViolations.
- for (ConstraintViolation constraintViolation : violations) {
- assertEquals(CUSTOM_ANNOTATION_MESSAGE, constraintViolation.getMessage());
+ for (ConstraintViolationWrapper cv : violations) {
+ assertEquals(CUSTOM_ANNOTATION_MESSAGE, cv.getMessage());
}
}
@@ -88,16 +90,17 @@
try {
marshaller.marshal(employee, new StringWriter());
+ assertFalse("Constraints-breaking class escaped validation -> fail.", true);
} catch (BeanValidationException ignored) {
}
- Set<? extends ConstraintViolation<?>> violations = marshaller.getConstraintViolations();
+ Set<ConstraintViolationWrapper<Object>> violations = marshaller.getConstraintViolations();
assertFalse(violations.isEmpty());
// For all, i.e. one constraintViolations.
- for (ConstraintViolation constraintViolation : violations) {
- assertEquals(NOT_NULL_MESSAGE, constraintViolation.getMessageTemplate());
+ for (ConstraintViolationWrapper cv : violations) {
+ assertEquals(NOT_NULL_MESSAGE, cv.getMessageTemplate());
}
}
@@ -149,7 +152,7 @@
} catch (BeanValidationException ignored) {
}
- Set<? extends ConstraintViolation<?>> violations = marshaller.getConstraintViolations();
+ Set<ConstraintViolationWrapper<Object>> violations = marshaller.getConstraintViolations();
assertFalse(violations.isEmpty());
}
diff --git a/moxy/eclipselink.moxy.test/src/org/eclipse/persistence/testing/jaxb/beanvalidation/ValidationXMLTestCase.java b/moxy/eclipselink.moxy.test/src/org/eclipse/persistence/testing/jaxb/beanvalidation/ValidationXMLTestCase.java
index 47c2c05..4901aaf 100644
--- a/moxy/eclipselink.moxy.test/src/org/eclipse/persistence/testing/jaxb/beanvalidation/ValidationXMLTestCase.java
+++ b/moxy/eclipselink.moxy.test/src/org/eclipse/persistence/testing/jaxb/beanvalidation/ValidationXMLTestCase.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016 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 v1.0 and Eclipse Distribution License v. 1.0
* which accompanies this distribution.
@@ -13,6 +13,8 @@
package org.eclipse.persistence.testing.jaxb.beanvalidation;
import org.eclipse.persistence.exceptions.BeanValidationException;
+import org.eclipse.persistence.internal.cache.AdvancedProcessor;
+import org.eclipse.persistence.jaxb.ConstraintViolationWrapper;
import org.eclipse.persistence.jaxb.JAXBContextFactory;
import org.eclipse.persistence.jaxb.JAXBMarshaller;
import org.eclipse.persistence.testing.jaxb.beanvalidation.special.ExternallyConstrainedEmployee;
@@ -20,7 +22,6 @@
import org.junit.After;
import org.junit.Before;
-import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import java.io.File;
import java.io.IOException;
@@ -85,7 +86,7 @@
} catch (BeanValidationException ignored) {
}
- Set<ConstraintViolation<Object>> violations = marshaller.getConstraintViolations();
+ Set<ConstraintViolationWrapper<Object>> violations = marshaller.getConstraintViolations();
try {
marshaller.marshal(employee2, new StringWriter());
@@ -97,9 +98,9 @@
assertFalse("Some constraints were not validated, even though they should have been.", violations.isEmpty());
int i = 0;
- for (ConstraintViolation constraintViolation : violations) {
- if (NOT_NULL_MESSAGE.equals(constraintViolation.getMessageTemplate())) i += 0b1000;
- if (MIN_MESSAGE.equals(constraintViolation.getMessageTemplate())) i += 0b0001;
+ for (ConstraintViolationWrapper<Object> cv : violations) {
+ if (NOT_NULL_MESSAGE.equals(cv.getMessageTemplate())) i += 0b1000;
+ if (MIN_MESSAGE.equals(cv.getMessageTemplate())) i += 0b0001;
}
assertTrue(i == 0b1001);
}
diff --git a/moxy/eclipselink.moxy.test/src/org/eclipse/persistence/testing/osgi/OSGITestHelper.java b/moxy/eclipselink.moxy.test/src/org/eclipse/persistence/testing/osgi/OSGITestHelper.java
new file mode 100644
index 0000000..68e9396
--- /dev/null
+++ b/moxy/eclipselink.moxy.test/src/org/eclipse/persistence/testing/osgi/OSGITestHelper.java
@@ -0,0 +1,81 @@
+/*******************************************************************************
+ * Copyright (c) 2015, 2016 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 v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ * Dmitry Kornilov - initial implementation
+ ******************************************************************************/
+package org.eclipse.persistence.testing.osgi;
+
+import org.ops4j.pax.exam.Option;
+
+import static org.ops4j.pax.exam.CoreOptions.bundle;
+import static org.ops4j.pax.exam.CoreOptions.cleanCaches;
+import static org.ops4j.pax.exam.CoreOptions.junitBundles;
+import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
+import static org.ops4j.pax.exam.CoreOptions.options;
+
+/**
+ * Helper class with PAX options for different kind of OSGi tests.
+ *
+ * @author Dmitry Kornilov
+ * @since 2.7.0
+ */
+public class OSGITestHelper {
+ // Environment variables defined in antbuild.properties/antbuild.xml
+ private static final String PLUGINS_DIR = System.getProperty("moxytest.2.common.plugins.dir");
+ private static final String QUALIFIER = System.getProperty("build.qualifier", "qualifier");
+ private static final String RELEASE_VERSION = System.getProperty("release.version", "2.7.0");
+ private static final String JAXB_API_JAR = System.getProperty("jaxb-api.jar", "javax.xml.bind_2.2.12.v201410011542.jar");
+ private static final String JAXRS_JAR = System.getProperty("jaxrs.jar", "javax.ws.rs_1.1.1.v20101004-1200.jar");
+ private static final String ASM_JAR = System.getProperty("asm.jar", "org.eclipse.persistence.asm_5.0.1.v201405080102.jar");
+ private static final String BEAN_VALIDATION_LIB = System.getProperty("javax.validation.lib", "javax.validation_1.1.0.v201304101302.jar");
+
+ public static Option[] getDefaultOptions() {
+ return options(
+ // JAXB API
+ bundle("file:" + PLUGINS_DIR + JAXB_API_JAR),
+
+ // JAX-RS API
+ bundle("file:" + PLUGINS_DIR + JAXRS_JAR),
+
+ // EclipseLink bundles
+ bundle("file:" + PLUGINS_DIR + "org.eclipse.persistence.moxy_" + RELEASE_VERSION + "." + QUALIFIER + ".jar"),
+ bundle("file:" + PLUGINS_DIR + "org.eclipse.persistence.core_" + RELEASE_VERSION + "." + QUALIFIER + ".jar"),
+ bundle("file:" + PLUGINS_DIR + ASM_JAR),
+
+ cleanCaches(),
+ junitBundles());
+ }
+
+ public static Option[] getOptionsWithBeanValidation() {
+ return options(
+ mavenBundle().groupId("org.hibernate").artifactId("hibernate-validator").version("5.2.0.CR1"),
+ mavenBundle().groupId("com.fasterxml").artifactId("classmate").version("1.1.0"),
+ mavenBundle().groupId("javax.el").artifactId("javax.el-api").version("3.0.0"),
+ mavenBundle().groupId("org.jboss.logging").artifactId("jboss-logging").version("3.2.1.Final"),
+ mavenBundle().groupId("org.apache.logging.log4j").artifactId("log4j-api").version("2.3"),
+ mavenBundle().groupId("org.apache.logging.log4j").artifactId("log4j-core").version("2.3"),
+
+ // JAXB API
+ bundle("file:" + PLUGINS_DIR + JAXB_API_JAR),
+
+ // JAX-RS API
+ bundle("file:" + PLUGINS_DIR + JAXRS_JAR),
+
+ // EclipseLink bundles
+ bundle("file:" + PLUGINS_DIR + "org.eclipse.persistence.moxy_" + RELEASE_VERSION + "." + QUALIFIER + ".jar"),
+ bundle("file:" + PLUGINS_DIR + "org.eclipse.persistence.core_" + RELEASE_VERSION + "." + QUALIFIER + ".jar"),
+ bundle("file:" + PLUGINS_DIR + ASM_JAR),
+ bundle("file:" + BEAN_VALIDATION_LIB),
+
+ cleanCaches(),
+ junitBundles()
+ );
+ }
+}
diff --git a/moxy/eclipselink.moxy.test/src/org/eclipse/persistence/testing/osgi/OSGiBundleTest.java b/moxy/eclipselink.moxy.test/src/org/eclipse/persistence/testing/osgi/OSGiBundleTest.java
new file mode 100644
index 0000000..69393c7
--- /dev/null
+++ b/moxy/eclipselink.moxy.test/src/org/eclipse/persistence/testing/osgi/OSGiBundleTest.java
@@ -0,0 +1,213 @@
+/*******************************************************************************
+ * Copyright (c) 2015, 2016 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 v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ * Marcel Valovy - 2.6 - initial implementation
+ ******************************************************************************/
+package org.eclipse.persistence.testing.osgi;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.inject.Inject;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.Configuration;
+
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
+import org.ops4j.pax.exam.spi.reactors.PerClass;
+import org.ops4j.pax.exam.junit.PaxExam;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.Version;
+
+/**
+ * Tests that all MOXy exported bundles can be properly loaded by OSGi framework.
+ *
+ * @author Marcel Valovy - marcel.valovy@oracle.com
+ * @since 2.7.0
+ */
+@RunWith(PaxExam.class)
+@ExamReactorStrategy(PerClass.class)
+public class OSGiBundleTest {
+ // MOXy bundle symbolic name
+ private static final String MOXY_BUNDLE_NAME = "org.eclipse.persistence.moxy";
+
+ // MOXy bundle
+ private Bundle moxyBundle;
+
+ @Inject
+ private static BundleContext ctx;
+
+ @Configuration
+ public static Option[] config() {
+ return OSGITestHelper.getDefaultOptions();
+ }
+
+ @Test
+ public void testAsmVersion() {
+ Class<?> c = loadClass("org.eclipse.persistence.internal.libraries.asm.AnnotationVisitor");
+ assertClassLoadedByBundle(c, "org.eclipse.persistence.asm", "5.0.1.v201405080102");
+ }
+
+ @Test
+ public void testInternalJaxb() {
+ Class<?> c = loadClass("org.eclipse.persistence.internal.jaxb.AttributeNodeImpl");
+ assertClassLoadedByBundle(c, MOXY_BUNDLE_NAME);
+ }
+
+ @Test
+ public void testInternalJaxbMany() {
+ Class<?> c = loadClass("org.eclipse.persistence.internal.jaxb.many.ArrayValue");
+ assertClassLoadedByBundle(c, MOXY_BUNDLE_NAME);
+ }
+
+ @Test
+ public void testJaxb() {
+ Class<?> c = loadClass("org.eclipse.persistence.jaxb.JAXBContext");
+ assertClassLoadedByBundle(c, MOXY_BUNDLE_NAME);
+ }
+
+ @Test
+ public void testJaxbAttachment() {
+ Class<?> c = loadClass("org.eclipse.persistence.jaxb.attachment.AttachmentMarshallerAdapter");
+ assertClassLoadedByBundle(c, MOXY_BUNDLE_NAME);
+ }
+
+ @Test
+ public void testJaxbCompiler() {
+ Class<?> c = loadClass("org.eclipse.persistence.jaxb.compiler.AnnotationsProcessor");
+ assertClassLoadedByBundle(c, MOXY_BUNDLE_NAME);
+ }
+
+ @Test
+ public void testJaxbDynamic() {
+ Class<?> c = loadClass("org.eclipse.persistence.jaxb.dynamic.DynamicJAXBContext");
+ assertClassLoadedByBundle(c, MOXY_BUNDLE_NAME);
+ }
+
+ @Test
+ public void testJaxbDynamicMetadata() {
+ Class<?> c = loadClass("org.eclipse.persistence.jaxb.dynamic.metadata.Metadata");
+ assertClassLoadedByBundle(c, MOXY_BUNDLE_NAME);
+ }
+
+ @Test
+ public void testJaxbJavamodel() {
+ Class<?> c = loadClass("org.eclipse.persistence.jaxb.javamodel.AnnotationProxy");
+ assertClassLoadedByBundle(c, MOXY_BUNDLE_NAME);
+ }
+
+ @Test
+ public void testJaxbJavamodelOxm() {
+ Class<?> c = loadClass("org.eclipse.persistence.jaxb.javamodel.oxm.OXMJavaClassImpl");
+ assertClassLoadedByBundle(c, MOXY_BUNDLE_NAME);
+ }
+
+ @Test
+ public void testJaxbJavamodelReflection() {
+ Class<?> c = loadClass("org.eclipse.persistence.jaxb.javamodel.reflection.AnnotationHelper");
+ assertClassLoadedByBundle(c, MOXY_BUNDLE_NAME);
+ }
+
+ @Test
+ public void testJaxbMetadata() throws ClassNotFoundException {
+ Class<?> c = loadClass("org.eclipse.persistence.jaxb.metadata.MetadataSource");
+ assertClassLoadedByBundle(c, MOXY_BUNDLE_NAME);
+ }
+
+ @Test
+ public void testJaxbRs() {
+ Class<?> c = loadClass("org.eclipse.persistence.jaxb.rs.MOXyJsonProvider");
+ assertClassLoadedByBundle(c, MOXY_BUNDLE_NAME);
+ }
+
+ @Test
+ public void testJaxbXmlmodel() {
+ Class<?> c = loadClass("org.eclipse.persistence.jaxb.xmlmodel.JavaAttribute");
+ assertClassLoadedByBundle(c, MOXY_BUNDLE_NAME);
+ }
+
+ @Test
+ public void testJavaxXmlParsers() {
+ Class<?> c = loadClass("javax.xml.parsers.ParserConfigurationException");
+ assertClassLoadedBySystemBundle(c);
+ }
+
+ @Test
+ public void testJavaxNaming() {
+ Class<?> c = loadClass("javax.naming.InitialContext");
+ assertClassLoadedBySystemBundle(c);
+ }
+
+ @Test
+ public void testOrgXmlSaxHelpers() {
+ Class<?> c = loadClass("org.xml.sax.helpers.DefaultHandler");
+ assertClassLoadedBySystemBundle(c);
+ }
+
+ /**
+ * Loads a class from MOXy bundle. Fails the test if not loaded.
+ */
+ private Class<?> loadClass(String className) {
+ try {
+ return getMoxyBundle().loadClass(className);
+ } catch (ClassNotFoundException ex) {
+ Logger.getLogger(OSGiBundleTest.class.getName()).log(Level.SEVERE, ex.getMessage(), ex);
+ Assert.fail("Cannot find and load class: " + className);
+ }
+ return null;
+ }
+
+ /**
+ * Returns MOXy bundle ('org.eclipse.persistence.moxy').
+ */
+ private Bundle getMoxyBundle() {
+ if (this.moxyBundle != null) {
+ return this.moxyBundle;
+ }
+
+ for (Bundle b : ctx.getBundles()) {
+ if (b.getSymbolicName().equals(MOXY_BUNDLE_NAME)) {
+ this.moxyBundle = b;
+ return b;
+ }
+ }
+
+ return null;
+ }
+
+ private void assertClassLoadedBySystemBundle(Class<?> c) {
+ Assert.assertNotNull(c);
+
+ // Class is there but loaded from the system bundle
+ Assert.assertNull("Class " + c.getName() + " was not loaded from JDK", FrameworkUtil.getBundle(c));
+ }
+
+ private void assertClassLoadedByBundle(Class<?> c, String bundle) {
+ Assert.assertNotNull(c);
+ Bundle b = FrameworkUtil.getBundle(c);
+ Assert.assertEquals("Class '" + c.getName() + "' was loaded by '" + b.getSymbolicName() +
+ "', expected was '" + bundle + "'", bundle, b.getSymbolicName());
+ Assert.assertEquals("Bundle '" + bundle + "' is not running", Bundle.ACTIVE, b.getState());
+ }
+
+ private void assertClassLoadedByBundle(Class<?> c, String bundle, String version) {
+ Bundle b = FrameworkUtil.getBundle(c);
+ Version v = b.getVersion();
+ Assert.assertEquals("Class '" + c.getName() + "' was loaded by '" + b.getSymbolicName() +
+ "', expected was '" + bundle + "'", bundle, b.getSymbolicName());
+ Assert.assertEquals("Class '" + c.getName() + "' was loaded by '" + b.getSymbolicName() + "', version '"
+ + v.toString() + "' expected was '" + bundle + "', version '" + v.toString() + "'.", version, v.toString());
+ Assert.assertEquals("Bundle '" + bundle + "' is not running", Bundle.ACTIVE, b.getState());
+ }
+}
\ No newline at end of file
diff --git a/moxy/eclipselink.moxy.test/src/org/eclipse/persistence/testing/osgi/beanvalidation/BaseBeanValidationTest.java b/moxy/eclipselink.moxy.test/src/org/eclipse/persistence/testing/osgi/beanvalidation/BaseBeanValidationTest.java
new file mode 100644
index 0000000..1b499cc
--- /dev/null
+++ b/moxy/eclipselink.moxy.test/src/org/eclipse/persistence/testing/osgi/beanvalidation/BaseBeanValidationTest.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2015, 2016 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 v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ * Dmitry Kornilov - initial implementation
+ ******************************************************************************/
+package org.eclipse.persistence.testing.osgi.beanvalidation;
+
+/**
+ * Base class for OSGi bean validation tests. Contains test data.
+ *
+ * @author Dmitry Kornilov
+ * @since 2.7.0
+ */
+public class BaseBeanValidationTest {
+ static final String CUSTOMER_VALID_XML = "<customer id=\"1\"><name>John Doe</name></customer>";
+ static final String CUSTOMER_INVALID_XML = "<customer><name>X</name></customer>";
+
+ Customer createInvalidCustomer() {
+ Customer customer = new Customer();
+ customer.setId(null);
+ customer.setName("X");
+ return customer;
+ }
+
+ Customer createValidCustomer() {
+ Customer customer = new Customer();
+ customer.setId("1");
+ customer.setName("John Doe");
+ return customer;
+ }
+}
diff --git a/moxy/eclipselink.moxy.test/src/org/eclipse/persistence/testing/osgi/beanvalidation/BeanValidationTest.java b/moxy/eclipselink.moxy.test/src/org/eclipse/persistence/testing/osgi/beanvalidation/BeanValidationTest.java
new file mode 100644
index 0000000..4060f2f
--- /dev/null
+++ b/moxy/eclipselink.moxy.test/src/org/eclipse/persistence/testing/osgi/beanvalidation/BeanValidationTest.java
@@ -0,0 +1,116 @@
+/*******************************************************************************
+ * Copyright (c) 2015, 2016 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 v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ * Dmitry Kornilov - initial implementation
+ ******************************************************************************/
+package org.eclipse.persistence.testing.osgi.beanvalidation;
+
+import org.eclipse.persistence.exceptions.BeanValidationException;
+import org.eclipse.persistence.jaxb.JAXBContextFactory;
+import org.eclipse.persistence.jaxb.MarshallerProperties;
+import org.eclipse.persistence.testing.osgi.OSGITestHelper;
+import org.hibernate.validator.HibernateValidator;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.Configuration;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.junit.PaxExam;
+import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
+import org.ops4j.pax.exam.spi.reactors.PerClass;
+
+import javax.validation.Validation;
+import javax.validation.ValidationProviderResolver;
+import javax.validation.ValidatorFactory;
+import javax.validation.spi.ValidationProvider;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Marshaller;
+import javax.xml.bind.Unmarshaller;
+
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.util.Collections;
+import java.util.List;
+
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Marshal/unmarshal + validation tests in OSGi container with installed bean validation implementation bundles.
+ * The purpose of these tests is to make sure that bean validation works in OSGi environment.
+ *
+ * @author Dmitry Kornilov
+ * @since 2.7.0
+ */
+@RunWith(PaxExam.class)
+@ExamReactorStrategy(PerClass.class)
+public class BeanValidationTest extends BaseBeanValidationTest {
+ private static JAXBContext jaxbContext;
+
+ @Configuration
+ public static Option[] config() {
+ return OSGITestHelper.getOptionsWithBeanValidation();
+ }
+
+ @BeforeClass
+ public static void setUp() throws Exception {
+ Class[] classes = new Class[1];
+ classes[0] = Customer.class;
+ jaxbContext = JAXBContextFactory.createContext(classes, null);
+ }
+
+ @Test(expected = BeanValidationException.class)
+ public void testMarshalInvalid() throws JAXBException {
+ StringWriter xml = new StringWriter();
+ Marshaller marshaller = jaxbContext.createMarshaller();
+ marshaller.setProperty(MarshallerProperties.BEAN_VALIDATION_FACTORY, getValidatorFactory());
+ marshaller.marshal(createInvalidCustomer(), xml);
+ }
+
+ @Test
+ public void testMarshalValid() throws JAXBException {
+ StringWriter xml = new StringWriter();
+ Marshaller marshaller = jaxbContext.createMarshaller();
+ marshaller.setProperty(MarshallerProperties.BEAN_VALIDATION_FACTORY, getValidatorFactory());
+ marshaller.marshal(createValidCustomer(), xml);
+ assertTrue(xml.toString().contains(CUSTOMER_VALID_XML));
+ }
+
+ @Test(expected = JAXBException.class)
+ public void testUnmarshalInvalid() throws JAXBException {
+ StringReader xml = new StringReader(CUSTOMER_INVALID_XML);
+ Unmarshaller unmarshaler = jaxbContext.createUnmarshaller();
+ unmarshaler.setProperty(MarshallerProperties.BEAN_VALIDATION_FACTORY, getValidatorFactory());
+ unmarshaler.unmarshal(xml);
+ }
+
+ @Test
+ public void testUnmarshalValid() throws JAXBException {
+ StringReader xml = new StringReader(CUSTOMER_VALID_XML);
+ Unmarshaller unmarshaler = jaxbContext.createUnmarshaller();
+ unmarshaler.setProperty(MarshallerProperties.BEAN_VALIDATION_FACTORY, getValidatorFactory());
+ Customer testCustomer = (Customer)unmarshaler.unmarshal(xml);
+ assertTrue(createValidCustomer().equals(testCustomer));
+ }
+
+ private ValidatorFactory getValidatorFactory() {
+ return Validation.byProvider(HibernateValidator.class)
+ .providerResolver(new BeanValidationTest.MyValidationProviderResolver())
+ .configure()
+ .buildValidatorFactory();
+ }
+
+ private static class MyValidationProviderResolver implements ValidationProviderResolver {
+ @Override
+ public List<ValidationProvider<?>> getValidationProviders() {
+ return Collections.<ValidationProvider<?>>singletonList(new HibernateValidator());
+ }
+ }
+}
diff --git a/moxy/eclipselink.moxy.test/src/org/eclipse/persistence/testing/osgi/beanvalidation/Customer.java b/moxy/eclipselink.moxy.test/src/org/eclipse/persistence/testing/osgi/beanvalidation/Customer.java
new file mode 100644
index 0000000..0b64086
--- /dev/null
+++ b/moxy/eclipselink.moxy.test/src/org/eclipse/persistence/testing/osgi/beanvalidation/Customer.java
@@ -0,0 +1,73 @@
+/*******************************************************************************
+ * Copyright (c) 2015, 2016 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 v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ * Dmitry Kornilov - initial implementation
+ ******************************************************************************/
+package org.eclipse.persistence.testing.osgi.beanvalidation;
+
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Size;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+/**
+ * Test class for OSGi tests with javax.validation in class path and without it.
+ *
+ * @author Dmitry Kornilov
+ * @since 2.7
+ */
+@XmlRootElement
+public class Customer {
+
+ @NotNull
+ @XmlAttribute
+ private String id;
+
+ @NotNull
+ @Size(min = 3, max = 15)
+ @XmlElement
+ private String name;
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ Customer customer = (Customer) o;
+
+ if (id != null ? !id.equals(customer.id) : customer.id != null) return false;
+ return !(name != null ? !name.equals(customer.name) : customer.name != null);
+
+ }
+
+ @Override
+ public int hashCode() {
+ int result = id != null ? id.hashCode() : 0;
+ result = 31 * result + (name != null ? name.hashCode() : 0);
+ return result;
+ }
+}
\ No newline at end of file
diff --git a/moxy/eclipselink.moxy.test/src/org/eclipse/persistence/testing/osgi/beanvalidation/NoBeanValidationTest.java b/moxy/eclipselink.moxy.test/src/org/eclipse/persistence/testing/osgi/beanvalidation/NoBeanValidationTest.java
new file mode 100644
index 0000000..e75fee7
--- /dev/null
+++ b/moxy/eclipselink.moxy.test/src/org/eclipse/persistence/testing/osgi/beanvalidation/NoBeanValidationTest.java
@@ -0,0 +1,87 @@
+/*******************************************************************************
+ * Copyright (c) 2015, 2016 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 v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ * Dmitry Kornilov - initial implementation
+ ******************************************************************************/
+package org.eclipse.persistence.testing.osgi.beanvalidation;
+
+import org.eclipse.persistence.jaxb.JAXBContextFactory;
+import org.eclipse.persistence.testing.osgi.OSGITestHelper;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.Configuration;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.junit.PaxExam;
+import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
+import org.ops4j.pax.exam.spi.reactors.PerClass;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Marshaller;
+import java.io.StringReader;
+import java.io.StringWriter;
+
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Marshal/unmarshal tests in OSGi container without installed bean validation implementation bundles.
+ * The purpose of these tests is to make sure that javax.validation import is optional.
+ *
+ * @author Dmitry Kornilov
+ * @since 2.7.0
+ */
+@RunWith(PaxExam.class)
+@ExamReactorStrategy(PerClass.class)
+public class NoBeanValidationTest extends BaseBeanValidationTest {
+ private static JAXBContext jaxbContext;
+
+ @Configuration
+ public static Option[] config() {
+ return OSGITestHelper.getDefaultOptions();
+ }
+
+ @BeforeClass
+ public static void setUp() throws Exception {
+ Class[] classes = new Class[1];
+ classes[0] = Customer.class;
+ jaxbContext = JAXBContextFactory.createContext(classes, null);
+ }
+
+ @Test
+ public void testMarshalValid() throws JAXBException {
+ StringWriter xml = new StringWriter();
+ Marshaller marshaller = jaxbContext.createMarshaller();
+ marshaller.marshal(createValidCustomer(), xml);
+ assertTrue(xml.toString().contains(CUSTOMER_VALID_XML));
+ }
+
+ @Test
+ public void testMarshalInvalid() throws JAXBException {
+ StringWriter xml = new StringWriter();
+ Marshaller marshaller = jaxbContext.createMarshaller();
+ marshaller.marshal(createInvalidCustomer(), xml);
+ assertTrue(xml.toString().contains(CUSTOMER_INVALID_XML));
+ }
+
+ @Test
+ public void testUnmarshalValid() throws JAXBException {
+ StringReader xml = new StringReader(CUSTOMER_VALID_XML);
+ Customer testCustomer = (Customer) jaxbContext.createUnmarshaller().unmarshal(xml);
+ assertTrue(createValidCustomer().equals(testCustomer));
+ }
+
+ @Test
+ public void testUnmarshalInvalid() throws JAXBException {
+ StringReader xml = new StringReader(CUSTOMER_INVALID_XML);
+ Customer testCustomer = (Customer) jaxbContext.createUnmarshaller().unmarshal(xml);
+ assertTrue(createInvalidCustomer().equals(testCustomer));
+ }
+}
diff --git a/moxy/org.eclipse.persistence.moxy/META-INF/MANIFEST.MF b/moxy/org.eclipse.persistence.moxy/META-INF/MANIFEST.MF
index 6c9f4e2..ad3e75e 100644
--- a/moxy/org.eclipse.persistence.moxy/META-INF/MANIFEST.MF
+++ b/moxy/org.eclipse.persistence.moxy/META-INF/MANIFEST.MF
@@ -38,6 +38,7 @@
javax.validation;resolution:=optional;version="1.1.0",
javax.validation.constraints;resolution:=optional;version="1.1.0",
javax.validation.groups;resolution:=optional;version="1.1.0",
+ javax.validation.metadata;resolution:=optional;version="1.1.0",
javax.ws.rs;resolution:=optional,
javax.ws.rs.core;resolution:=optional,
javax.ws.rs.ext;resolution:=optional,
@@ -47,7 +48,7 @@
javax.xml.bind.attachment,
javax.xml.bind.helpers,
javax.xml.namespace;resolution:=optional,
- javax.xml.parsers;resolution:=optional,
+ javax.xml.parsers,
javax.xml.stream;resolution:=optional,
javax.xml.transform;resolution:=optional,
javax.xml.transform.dom;resolution:=optional,
diff --git a/moxy/org.eclipse.persistence.moxy/src/org/eclipse/persistence/jaxb/ConstraintViolationWrapper.java b/moxy/org.eclipse.persistence.moxy/src/org/eclipse/persistence/jaxb/ConstraintViolationWrapper.java
new file mode 100644
index 0000000..6415fa2
--- /dev/null
+++ b/moxy/org.eclipse.persistence.moxy/src/org/eclipse/persistence/jaxb/ConstraintViolationWrapper.java
@@ -0,0 +1,112 @@
+/*******************************************************************************
+ * Copyright (c) 2015, 2016 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 v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ * Dmitry Kornilov - initial implementation
+ ******************************************************************************/
+package org.eclipse.persistence.jaxb;
+
+import javax.validation.ConstraintViolation;
+import javax.validation.Path;
+import javax.validation.metadata.ConstraintDescriptor;
+
+/**
+ * Wrapper over {@link ConstraintViolation} class. Required due to optional nature of javax.validation bundle.
+ *
+ * @author Dmitry Kornilov
+ * @since 2.7.0
+ */
+public class ConstraintViolationWrapper<T> {
+ private ConstraintViolation<T> constraintViolation;
+
+ /**
+ * Creates a new wrapper.
+ * @param constraintViolation original object
+ */
+ public ConstraintViolationWrapper(ConstraintViolation<T> constraintViolation) {
+ this.constraintViolation = constraintViolation;
+ }
+
+ /**
+ * {@see ConstraintViolation#getMessage}
+ */
+ public String getMessage() {
+ return constraintViolation.getMessage();
+ }
+
+ /**
+ * {@see ConstraintViolation#getMessageTemplate}
+ */
+ public String getMessageTemplate() {
+ return constraintViolation.getMessageTemplate();
+ }
+
+ /**
+ * {@see ConstraintViolation#getRootBean}
+ */
+ public T getRootBean() {
+ return constraintViolation.getRootBean();
+ }
+
+ /**
+ * {@see ConstraintViolation#getRootBeanClass}
+ */
+ public Class<T> getRootBeanClass() {
+ return constraintViolation.getRootBeanClass();
+ }
+
+ /**
+ * {@see ConstraintViolation#getLeafBean}
+ */
+ public Object getLeafBean() {
+ return constraintViolation.getLeafBean();
+ }
+
+ /**
+ * {@see ConstraintViolation#getExecutableParameters}
+ */
+ public Object[] getExecutableParameters() {
+ return constraintViolation.getExecutableParameters();
+ }
+
+ /**
+ * {@see ConstraintViolation#getExecutableReturnValue}
+ */
+ public Object getExecutableReturnValue() {
+ return constraintViolation.getExecutableReturnValue();
+ }
+
+ /**
+ * {@see ConstraintViolation#getPropertyPath}
+ */
+ public Path getPropertyPath() {
+ return constraintViolation.getPropertyPath();
+ }
+
+ /**
+ * {@see ConstraintViolation#getInvalidValue}
+ */
+ public Object getInvalidValue() {
+ return constraintViolation.getInvalidValue();
+ }
+
+ /**
+ * {@see ConstraintViolation#getConstraintDescriptor}
+ */
+ public ConstraintDescriptor<?> getConstraintDescriptor() {
+ return constraintViolation.getConstraintDescriptor();
+ }
+
+ /**
+ * Unwraps original object and returns it.
+ */
+ public ConstraintViolation<T> unwrap() {
+ return constraintViolation;
+ }
+}
diff --git a/moxy/org.eclipse.persistence.moxy/src/org/eclipse/persistence/jaxb/JAXBBeanValidator.java b/moxy/org.eclipse.persistence.moxy/src/org/eclipse/persistence/jaxb/JAXBBeanValidator.java
index a551f31..b7ad4f4 100644
--- a/moxy/org.eclipse.persistence.moxy/src/org/eclipse/persistence/jaxb/JAXBBeanValidator.java
+++ b/moxy/org.eclipse.persistence.moxy/src/org/eclipse/persistence/jaxb/JAXBBeanValidator.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016 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 v1.0 and Eclipse Distribution License v. 1.0
* which accompanies this distribution.
@@ -29,6 +29,7 @@
import java.security.PrivilegedAction;
import java.util.Collection;
import java.util.Collections;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Set;
@@ -185,8 +186,8 @@
* @param beanValidationMode Bean validation mode - allowed values AUTO, CALLBACK, NONE.
* @param value validated object. It is passed because validation on some objects may be skipped,
* e.g. non-constrained objects (like XmlBindings).
- * @param preferredValidatorFactory May be null. Will use this factory as the preferred provider;
- * if null, will use javax defaults.
+ * @param preferredValidatorFactory Must be {@link ValidatorFactory} or null. Will use this factory as the
+ * preferred provider; if null, will use javax defaults.
* @param noOptimisation if true, bean validation optimisations that skip non-constrained objects will not be
* performed
* @return
@@ -196,7 +197,7 @@
* @since 2.6
*/
boolean shouldValidate (Object value, BeanValidationMode beanValidationMode,
- ValidatorFactory preferredValidatorFactory,
+ Object preferredValidatorFactory,
boolean noOptimisation) throws BeanValidationException {
if (isValidationEffectivelyOff(beanValidationMode)) return false;
@@ -207,9 +208,8 @@
/* Mode or validator factory was changed externally (or it's the first time this method is called). */
if (this.beanValidationMode != beanValidationMode || this.validatorFactory != preferredValidatorFactory) {
-
this.beanValidationMode = beanValidationMode;
- this.validatorFactory = preferredValidatorFactory;
+ this.validatorFactory = (ValidatorFactory)preferredValidatorFactory;
changeInternalState();
}
@@ -262,11 +262,15 @@
* Stores the result of validation in {@link #constraintViolations}.
*
* @param value Object to be validated.
- * @param groups Target groups as per BV spec. Must not be null, may be empty.
+ * @param groups Target groups as per BV spec. If null {@link #DEFAULT_GROUP_ARRAY} is used.
* @throws BeanValidationException {@link BeanValidationException#constraintViolation}
*/
void validate(Object value, Class<?>... groups) throws BeanValidationException {
- constraintViolations = validator.validate(value, groups);
+ Class<?>[] grp = groups;
+ if (grp == null || grp.length == 0) {
+ grp = DEFAULT_GROUP_ARRAY;
+ }
+ constraintViolations = validator.validate(value, grp);
if (!constraintViolations.isEmpty())
throw buildConstraintViolationException();
}
@@ -274,8 +278,12 @@
/**
* @return constraintViolations from the last {@link #validate} call.
*/
- Set<ConstraintViolation<Object>> getConstraintViolations() {
- return constraintViolations;
+ Set<ConstraintViolationWrapper<Object>> getConstraintViolations() {
+ Set<ConstraintViolationWrapper<Object>> result = new HashSet<>(constraintViolations.size());
+ for (ConstraintViolation cv : constraintViolations) {
+ result.add(new ConstraintViolationWrapper<>(cv));
+ }
+ return result;
}
/**
diff --git a/moxy/org.eclipse.persistence.moxy/src/org/eclipse/persistence/jaxb/JAXBMarshaller.java b/moxy/org.eclipse.persistence.moxy/src/org/eclipse/persistence/jaxb/JAXBMarshaller.java
index fea8e3c..24188c3 100644
--- a/moxy/org.eclipse.persistence.moxy/src/org/eclipse/persistence/jaxb/JAXBMarshaller.java
+++ b/moxy/org.eclipse.persistence.moxy/src/org/eclipse/persistence/jaxb/JAXBMarshaller.java
@@ -1,16 +1,16 @@
-/*******************************************************************************
- * Copyright (c) 1998, 2015 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 v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- * Oracle - initial API and implementation from Oracle TopLink
- * Marcel Valovy - 2.6.0 - added case insensitive unmarshalling property,
- * added Bean Validation support.
+/*******************************************************************************
+ * Copyright (c) 1998, 2016 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 v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ * Oracle - initial API and implementation from Oracle TopLink
+ * Marcel Valovy - 2.6.0 - added case insensitive unmarshalling property,
+ * added Bean Validation support.
******************************************************************************/
package org.eclipse.persistence.jaxb;
@@ -22,24 +22,23 @@
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
-import javax.validation.ConstraintViolation;
-import javax.validation.ValidatorFactory;
-import javax.xml.bind.JAXBElement;
-import javax.xml.bind.JAXBException;
-import javax.xml.bind.MarshalException;
-import javax.xml.bind.Marshaller;
-import javax.xml.bind.PropertyException;
-import javax.xml.bind.ValidationEventHandler;
-import javax.xml.bind.annotation.adapters.XmlAdapter;
-import javax.xml.bind.attachment.AttachmentMarshaller;
-import javax.xml.namespace.QName;
-import javax.xml.stream.XMLEventWriter;
-import javax.xml.stream.XMLStreamWriter;
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.MarshalException;
+import javax.xml.bind.Marshaller;
+import javax.xml.bind.PropertyException;
+import javax.xml.bind.ValidationEventHandler;
+import javax.xml.bind.annotation.adapters.XmlAdapter;
+import javax.xml.bind.attachment.AttachmentMarshaller;
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLEventWriter;
+import javax.xml.stream.XMLStreamWriter;
import javax.xml.transform.Result;
import javax.xml.validation.Schema;
@@ -73,235 +72,245 @@
/**
* INTERNAL:
- * <p>
- * <b>Purpose:</b>To Provide an implementation of the JAXB 2.0 Marshaller
- * Interface
- * <p>
- * <b>Responsibilities:</b>
- * <ul>
- * <li>Provide a JAXB wrapper on the XMLMarshaller API</li>
- * <li>Perform Object to XML Conversions</li>
- * </ul>
- * <p>This implementation of the JAXB 2.1/2.2 Marshaller interface provides the
- * required functionality by acting as a thin wrapper on the existing
- * XMLMarshaller API.</p>
- *
- * @author mmacivor
- * @since Oracle TopLink 11.1.1.0.0
- * @see javax.xml.bind.Marshaller
- * @see org.eclipse.persistence.jaxb.MarshallerProperties
- * @see org.eclipse.persistence.oxm.XMLMarshaller
- */
-
-public class JAXBMarshaller implements javax.xml.bind.Marshaller {
-
- private final JAXBBeanValidator beanValidator;
-
- private BeanValidationMode beanValidationMode;
- private ValidatorFactory prefValidatorFactory;
- private boolean bvNoOptimisation = false;
- private Class<?>[] beanValidationGroups = JAXBBeanValidator.DEFAULT_GROUP_ARRAY;
-
- private final XMLMarshaller xmlMarshaller;
- private final JAXBContext jaxbContext;
- private ValidationEventHandler validationEventHandler;
-
- public static final String XML_JAVATYPE_ADAPTERS = "xml-javatype-adapters";
-
- private static final String SUN_NAMESPACE_PREFIX_MAPPER = "com.sun.xml.bind.namespacePrefixMapper";
- private static final String SUN_JSE_NAMESPACE_PREFIX_MAPPER = "com.sun.xml.internal.bind.namespacePrefixMapper";
-
- private static final String SUN_INDENT_STRING = "com.sun.xml.bind.indentString";
- private static final String SUN_JSE_INDENT_STRING = "com.sun.xml.internal.bind.indentString";
-
- private static final String SUN_CHARACTER_ESCAPE_HANDLER_MARSHALLER = "com.sun.xml.bind.marshaller.CharacterEscapeHandler";
- private static final String SUN_JSE_CHARACTER_ESCAPE_HANDLER_MARSHALLER = "com.sun.xml.internal.bind.marshaller.CharacterEscapeHandler";
-
- private static final String SUN_CHARACTER_ESCAPE_HANDLER= "com.sun.xml.bind.characterEscapeHandler";
- private static final String SUN_JSE_CHARACTER_ESCAPE_HANDLER = "com.sun.xml.internal.bind.characterEscapeHandler";
-
- // XML_DECLARATION is the "opposite" to JAXB_FRAGMENT. If XML_DECLARATION is set to false it means JAXB_FRAGMENT should be set to true.
- private static final String XML_DECLARATION = "com.sun.xml.bind.xmlDeclaration";
-
- private static final String XML_HEADERS = "com.sun.xml.bind.xmlHeaders";
-
- private static final String OBJECT_IDENTITY_CYCLE_DETECTION = "com.sun.xml.bind.objectIdentitityCycleDetection";
-
- /**
- * This constructor initializes various settings on the XML marshaller.
- *
- * @param newXMLMarshaller xml marshaller
- * @param jaxbContext jaxb context
- */
- public JAXBMarshaller(XMLMarshaller newXMLMarshaller, JAXBContext jaxbContext) {
- this.jaxbContext = jaxbContext;
- validationEventHandler = JAXBContext.DEFAULT_VALIDATION_EVENT_HANDLER;
- beanValidationMode = BeanValidationMode.AUTO;
- beanValidator = JAXBBeanValidator.getMarshallingBeanValidator(jaxbContext);
- xmlMarshaller = newXMLMarshaller;
- xmlMarshaller.setErrorHandler(new JAXBErrorHandler(validationEventHandler));
- xmlMarshaller.setEncoding("UTF-8");
- xmlMarshaller.setFormattedOutput(false);
- xmlMarshaller.getProperties().put(Constants.JAXB_MARSHALLER, this);
- }
-
- /**
- * Create an instance of XMLRoot populated from the contents of the provided
- * JAXBElement. XMLRoot will be used to hold the contents of the JAXBElement
- * while the marshal operation is performed by TopLink OXM. This will avoid
- * adding any runtime dependencies to TopLink.
- *
- * @param elt
- * @return
- */
- private Root createXMLRootFromJAXBElement(JAXBElement elt) {
- // create an XMLRoot to hand into the marshaller
- Root xmlroot = new Root();
- Object objectValue = elt.getValue();
- xmlroot.setObject(objectValue);
- QName qname = elt.getName();
- xmlroot.setLocalName(qname.getLocalPart());
- xmlroot.setNamespaceURI(qname.getNamespaceURI());
- xmlroot.setDeclaredType(elt.getDeclaredType());
- xmlroot.setNil(elt.isNil());
- if (elt.getDeclaredType() == CoreClassConstants.ABYTE || elt.getDeclaredType() == CoreClassConstants.APBYTE ||
- elt.getDeclaredType().getCanonicalName().equals("javax.activation.DataHandler") ||
- elt.getDeclaredType().isEnum()) {
- // need a binary data mapping so need to wrap
- Class generatedClass = getClassToGeneratedClasses().get(elt.getDeclaredType().getCanonicalName());
- if(!elt.getDeclaredType().isEnum()) {
- xmlroot.setSchemaType(Constants.BASE_64_BINARY_QNAME);
- }
- if (generatedClass != null && WrappedValue.class.isAssignableFrom(generatedClass)) {
- ClassDescriptor desc = xmlMarshaller.getXMLContext().getSession(generatedClass).getDescriptor(generatedClass);
- Object newObject = desc.getInstantiationPolicy().buildNewInstance();
- ((WrappedValue) newObject).setValue(objectValue);
- xmlroot.setObject(newObject);
- return xmlroot;
- }
- } else {
- xmlroot.setSchemaType((QName) org.eclipse.persistence.internal.oxm.XMLConversionManager.getDefaultJavaTypes().get(elt.getDeclaredType()));
- }
-
- if (elt instanceof WrappedValue) {
- xmlroot.setObject(elt);
- return xmlroot;
- }
- Map<QName, Class> qNameToGeneratedClasses = jaxbContext.getQNameToGeneratedClasses();
- if (qNameToGeneratedClasses != null) {
- Class theClass = qNameToGeneratedClasses.get(qname);
- if (theClass != null && WrappedValue.class.isAssignableFrom(theClass)) {
- ClassDescriptor desc = xmlMarshaller.getXMLContext().getSession(theClass).getDescriptor(theClass);
- Object newObject = desc.getInstantiationPolicy().buildNewInstance();
- ((WrappedValue) newObject).setValue(objectValue);
- xmlroot.setObject(newObject);
- return xmlroot;
- }
- }
-
- Class generatedClass = null;
- if (jaxbContext.getTypeMappingInfoToGeneratedType() != null) {
- if (jaxbContext.getTypeToTypeMappingInfo() != null) {
- if (elt.getDeclaredType() != null && elt.getDeclaredType().isArray()) {
- TypeMappingInfo tmi = jaxbContext.getTypeToTypeMappingInfo().get(elt.getDeclaredType());
- generatedClass = jaxbContext.getTypeMappingInfoToGeneratedType().get(tmi);
- } else if (elt instanceof JAXBTypeElement) {
- Type objectType = ((JAXBTypeElement) elt).getType();
- TypeMappingInfo tmi = jaxbContext.getTypeToTypeMappingInfo().get(objectType);
- generatedClass = jaxbContext.getTypeMappingInfoToGeneratedType().get(tmi);
- }
- }
- } else {
- if (elt.getDeclaredType() != null && elt.getDeclaredType().isArray()) {
- if (jaxbContext.getArrayClassesToGeneratedClasses() != null) {
- generatedClass = jaxbContext.getArrayClassesToGeneratedClasses().get(elt.getDeclaredType().getCanonicalName());
- }
- } else if (elt instanceof JAXBTypeElement) {
- Type objectType = ((JAXBTypeElement) elt).getType();
- generatedClass = jaxbContext.getCollectionClassesToGeneratedClasses().get(objectType);
- }
- }
-
- if (generatedClass != null) {
- ClassDescriptor desc = xmlMarshaller.getXMLContext().getSession(generatedClass).getDescriptor(generatedClass);
- Object newObject = desc.getInstantiationPolicy().buildNewInstance();
- ((ManyValue) newObject).setItem(objectValue);
- xmlroot.setObject(newObject);
- }
-
- return xmlroot;
- }
-
- public XmlAdapter getAdapter(Class javaClass) {
- HashMap result = (HashMap) xmlMarshaller.getProperty(XML_JAVATYPE_ADAPTERS);
- if (result == null) {
- return null;
- }
- return (XmlAdapter) result.get(javaClass);
- }
-
- public AttachmentMarshaller getAttachmentMarshaller() {
- if (xmlMarshaller.getAttachmentMarshaller() == null) {
- return null;
- }
- return ((AttachmentMarshallerAdapter) xmlMarshaller.getAttachmentMarshaller()).getAttachmentMarshaller();
- }
-
- public ValidationEventHandler getEventHandler() throws JAXBException {
- return validationEventHandler;
- }
-
- public Marshaller.Listener getListener() {
- XMLMarshalListener xmlMarshalListener = xmlMarshaller.getMarshalListener();
- if(null != xmlMarshalListener) {
- return ((JAXBMarshalListener) xmlMarshalListener).getListener();
- }
- return null;
- }
-
- public Node getNode(Object object) throws JAXBException {
- throw new UnsupportedOperationException();
- }
-
- /**
- * Get a property from the JAXBMarshaller. Attempting to get any unsupported
- * property will result in a javax.xml.bind.PropertyException
- * @see org.eclipse.persistence.jaxb.MarshallerProperties
- */
- public Object getProperty(String key) throws PropertyException {
- if (key == null) {
- throw new IllegalArgumentException();
- } else if (JAXB_FORMATTED_OUTPUT.equals(key)) {
- return xmlMarshaller.isFormattedOutput();
- } else if (JAXB_ENCODING.equals(key)) {
- return xmlMarshaller.getEncoding();
- } else if (JAXB_SCHEMA_LOCATION.equals(key)) {
- return xmlMarshaller.getSchemaLocation();
- } else if (JAXB_NO_NAMESPACE_SCHEMA_LOCATION.equals(key)) {
- return xmlMarshaller.getNoNamespaceSchemaLocation();
- } else if (Constants.JAXB_FRAGMENT.equals(key)) {
- return xmlMarshaller.isFragment();
- } else if (MarshallerProperties.MEDIA_TYPE.equals(key)) {
- return xmlMarshaller.getMediaType();
- } else if (MarshallerProperties.NAMESPACE_PREFIX_MAPPER.equals(key)) {
- return xmlMarshaller.getNamespacePrefixMapper();
- } else if (MarshallerProperties.INDENT_STRING.equals(key) || SUN_INDENT_STRING.equals(key) || SUN_JSE_INDENT_STRING.equals(key)) {
- return xmlMarshaller.getIndentString();
- } else if (MarshallerProperties.CHARACTER_ESCAPE_HANDLER.equals(key)) {
- return xmlMarshaller.getCharacterEscapeHandler();
- } else if (XML_DECLARATION.equals(key)) {
- return !xmlMarshaller.isFragment();
- } else if (XML_HEADERS.equals(key)) {
- return xmlMarshaller.getXmlHeader();
- } else if (OBJECT_IDENTITY_CYCLE_DETECTION.equals(key)) {
- return xmlMarshaller.isEqualUsingIdenity();
- } else if (MarshallerProperties.JSON_ATTRIBUTE_PREFIX.equals(key)) {
- return xmlMarshaller.getAttributePrefix();
- } else if (MarshallerProperties.JSON_INCLUDE_ROOT.equals(key)) {
- return xmlMarshaller.isIncludeRoot();
- } else if (MarshallerProperties.JSON_VALUE_WRAPPER.equals(key)) {
- return xmlMarshaller.getValueWrapper();
- } else if (MarshallerProperties.JSON_NAMESPACE_SEPARATOR.equals(key)) {
+ * <p>
+ * <b>Purpose:</b>To Provide an implementation of the JAXB 2.0 Marshaller
+ * Interface
+ * <p>
+ * <b>Responsibilities:</b>
+ * <ul>
+ * <li>Provide a JAXB wrapper on the XMLMarshaller API</li>
+ * <li>Perform Object to XML Conversions</li>
+ * </ul>
+ * <p>This implementation of the JAXB 2.1/2.2 Marshaller interface provides the
+ * required functionality by acting as a thin wrapper on the existing
+ * XMLMarshaller API.</p>
+ *
+ * @author mmacivor
+ * @since Oracle TopLink 11.1.1.0.0
+ * @see javax.xml.bind.Marshaller
+ * @see org.eclipse.persistence.jaxb.MarshallerProperties
+ * @see org.eclipse.persistence.oxm.XMLMarshaller
+ */
+
+public class JAXBMarshaller implements javax.xml.bind.Marshaller {
+
+ private JAXBBeanValidator beanValidator;
+
+ private BeanValidationMode beanValidationMode;
+
+ // The actual type is ValidatorFactory. It's done due to optional nature of javax.validation.
+ private Object prefValidatorFactory;
+ private boolean bvNoOptimisation = false;
+ private Class<?>[] beanValidationGroups;
+
+ private final XMLMarshaller xmlMarshaller;
+ private final JAXBContext jaxbContext;
+ private ValidationEventHandler validationEventHandler;
+
+ public static final String XML_JAVATYPE_ADAPTERS = "xml-javatype-adapters";
+
+ private static final String SUN_NAMESPACE_PREFIX_MAPPER = "com.sun.xml.bind.namespacePrefixMapper";
+ private static final String SUN_JSE_NAMESPACE_PREFIX_MAPPER = "com.sun.xml.internal.bind.namespacePrefixMapper";
+
+ private static final String SUN_INDENT_STRING = "com.sun.xml.bind.indentString";
+ private static final String SUN_JSE_INDENT_STRING = "com.sun.xml.internal.bind.indentString";
+
+ private static final String SUN_CHARACTER_ESCAPE_HANDLER_MARSHALLER = "com.sun.xml.bind.marshaller.CharacterEscapeHandler";
+ private static final String SUN_JSE_CHARACTER_ESCAPE_HANDLER_MARSHALLER = "com.sun.xml.internal.bind.marshaller.CharacterEscapeHandler";
+
+ private static final String SUN_CHARACTER_ESCAPE_HANDLER= "com.sun.xml.bind.characterEscapeHandler";
+ private static final String SUN_JSE_CHARACTER_ESCAPE_HANDLER = "com.sun.xml.internal.bind.characterEscapeHandler";
+
+ // XML_DECLARATION is the "opposite" to JAXB_FRAGMENT. If XML_DECLARATION is set to false it means JAXB_FRAGMENT should be set to true.
+ private static final String XML_DECLARATION = "com.sun.xml.bind.xmlDeclaration";
+
+ private static final String XML_HEADERS = "com.sun.xml.bind.xmlHeaders";
+
+ private static final String OBJECT_IDENTITY_CYCLE_DETECTION = "com.sun.xml.bind.objectIdentitityCycleDetection";
+
+ /**
+ * This constructor initializes various settings on the XML marshaller.
+ *
+ * @param newXMLMarshaller xml marshaller
+ * @param jaxbContext jaxb context
+ */
+ public JAXBMarshaller(XMLMarshaller newXMLMarshaller, JAXBContext jaxbContext) {
+ this.jaxbContext = jaxbContext;
+ validationEventHandler = JAXBContext.DEFAULT_VALIDATION_EVENT_HANDLER;
+ beanValidationMode = BeanValidationMode.AUTO;
+ if (BeanValidationChecker.isBeanValidationPresent()) {
+ beanValidator = JAXBBeanValidator.getMarshallingBeanValidator(jaxbContext);
+ }
+ xmlMarshaller = newXMLMarshaller;
+ xmlMarshaller.setErrorHandler(new JAXBErrorHandler(validationEventHandler));
+ xmlMarshaller.setEncoding("UTF-8");
+ xmlMarshaller.setFormattedOutput(false);
+ xmlMarshaller.getProperties().put(Constants.JAXB_MARSHALLER, this);
+ }
+
+ /**
+ * Create an instance of XMLRoot populated from the contents of the provided
+ * JAXBElement. XMLRoot will be used to hold the contents of the JAXBElement
+ * while the marshal operation is performed by TopLink OXM. This will avoid
+ * adding any runtime dependencies to TopLink.
+ *
+ * @param elt
+ * @return
+ */
+ private Root createXMLRootFromJAXBElement(JAXBElement elt) {
+ // create an XMLRoot to hand into the marshaller
+ Root xmlroot = new Root();
+ Object objectValue = elt.getValue();
+ xmlroot.setObject(objectValue);
+ QName qname = elt.getName();
+ xmlroot.setLocalName(qname.getLocalPart());
+ xmlroot.setNamespaceURI(qname.getNamespaceURI());
+ xmlroot.setDeclaredType(elt.getDeclaredType());
+ xmlroot.setNil(elt.isNil());
+ if (elt.getDeclaredType() == CoreClassConstants.ABYTE || elt.getDeclaredType() == CoreClassConstants.APBYTE ||
+ elt.getDeclaredType().getCanonicalName().equals("javax.activation.DataHandler") ||
+ elt.getDeclaredType().isEnum()) {
+ // need a binary data mapping so need to wrap
+ Class generatedClass = getClassToGeneratedClasses().get(elt.getDeclaredType().getCanonicalName());
+ if(!elt.getDeclaredType().isEnum()) {
+ xmlroot.setSchemaType(Constants.BASE_64_BINARY_QNAME);
+ }
+ if (generatedClass != null && WrappedValue.class.isAssignableFrom(generatedClass)) {
+ ClassDescriptor desc = xmlMarshaller.getXMLContext().getSession(generatedClass).getDescriptor(generatedClass);
+ Object newObject = desc.getInstantiationPolicy().buildNewInstance();
+ ((WrappedValue) newObject).setValue(objectValue);
+ xmlroot.setObject(newObject);
+ return xmlroot;
+ }
+ } else {
+ xmlroot.setSchemaType((QName) org.eclipse.persistence.internal.oxm.XMLConversionManager.getDefaultJavaTypes().get(elt.getDeclaredType()));
+ }
+
+ if (elt instanceof WrappedValue) {
+ xmlroot.setObject(elt);
+ return xmlroot;
+ }
+ Map<QName, Class> qNameToGeneratedClasses = jaxbContext.getQNameToGeneratedClasses();
+ if (qNameToGeneratedClasses != null) {
+ Class theClass = qNameToGeneratedClasses.get(qname);
+ if (theClass != null && WrappedValue.class.isAssignableFrom(theClass)) {
+ ClassDescriptor desc = xmlMarshaller.getXMLContext().getSession(theClass).getDescriptor(theClass);
+ Object newObject = desc.getInstantiationPolicy().buildNewInstance();
+ ((WrappedValue) newObject).setValue(objectValue);
+ xmlroot.setObject(newObject);
+ return xmlroot;
+ }
+ }
+
+ Class generatedClass = null;
+ if (jaxbContext.getTypeMappingInfoToGeneratedType() != null) {
+ if (jaxbContext.getTypeToTypeMappingInfo() != null) {
+ if (elt.getDeclaredType() != null && elt.getDeclaredType().isArray()) {
+ TypeMappingInfo tmi = jaxbContext.getTypeToTypeMappingInfo().get(elt.getDeclaredType());
+ generatedClass = jaxbContext.getTypeMappingInfoToGeneratedType().get(tmi);
+ } else if (elt instanceof JAXBTypeElement) {
+ Type objectType = ((JAXBTypeElement) elt).getType();
+ TypeMappingInfo tmi = jaxbContext.getTypeToTypeMappingInfo().get(objectType);
+ generatedClass = jaxbContext.getTypeMappingInfoToGeneratedType().get(tmi);
+ }
+ }
+ } else {
+ if (elt.getDeclaredType() != null && elt.getDeclaredType().isArray()) {
+ if (jaxbContext.getArrayClassesToGeneratedClasses() != null) {
+ generatedClass = jaxbContext.getArrayClassesToGeneratedClasses().get(elt.getDeclaredType().getCanonicalName());
+ }
+ } else if (elt instanceof JAXBTypeElement) {
+ Type objectType = ((JAXBTypeElement) elt).getType();
+ generatedClass = jaxbContext.getCollectionClassesToGeneratedClasses().get(objectType);
+ }
+ }
+
+ if (generatedClass != null) {
+ ClassDescriptor desc = xmlMarshaller.getXMLContext().getSession(generatedClass).getDescriptor(generatedClass);
+ Object newObject = desc.getInstantiationPolicy().buildNewInstance();
+ ((ManyValue) newObject).setItem(objectValue);
+ xmlroot.setObject(newObject);
+ }
+
+ return xmlroot;
+ }
+
+ @Override
+ public XmlAdapter getAdapter(Class javaClass) {
+ HashMap result = (HashMap) xmlMarshaller.getProperty(XML_JAVATYPE_ADAPTERS);
+ if (result == null) {
+ return null;
+ }
+ return (XmlAdapter) result.get(javaClass);
+ }
+
+ @Override
+ public AttachmentMarshaller getAttachmentMarshaller() {
+ if (xmlMarshaller.getAttachmentMarshaller() == null) {
+ return null;
+ }
+ return ((AttachmentMarshallerAdapter) xmlMarshaller.getAttachmentMarshaller()).getAttachmentMarshaller();
+ }
+
+ @Override
+ public ValidationEventHandler getEventHandler() throws JAXBException {
+ return validationEventHandler;
+ }
+
+ @Override
+ public Marshaller.Listener getListener() {
+ XMLMarshalListener xmlMarshalListener = xmlMarshaller.getMarshalListener();
+ if(null != xmlMarshalListener) {
+ return ((JAXBMarshalListener) xmlMarshalListener).getListener();
+ }
+ return null;
+ }
+
+ @Override
+ public Node getNode(Object object) throws JAXBException {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Get a property from the JAXBMarshaller. Attempting to get any unsupported
+ * property will result in a javax.xml.bind.PropertyException
+ * @see org.eclipse.persistence.jaxb.MarshallerProperties
+ */
+ @Override
+ public Object getProperty(String key) throws PropertyException {
+ if (key == null) {
+ throw new IllegalArgumentException();
+ } else if (JAXB_FORMATTED_OUTPUT.equals(key)) {
+ return xmlMarshaller.isFormattedOutput();
+ } else if (JAXB_ENCODING.equals(key)) {
+ return xmlMarshaller.getEncoding();
+ } else if (JAXB_SCHEMA_LOCATION.equals(key)) {
+ return xmlMarshaller.getSchemaLocation();
+ } else if (JAXB_NO_NAMESPACE_SCHEMA_LOCATION.equals(key)) {
+ return xmlMarshaller.getNoNamespaceSchemaLocation();
+ } else if (Constants.JAXB_FRAGMENT.equals(key)) {
+ return xmlMarshaller.isFragment();
+ } else if (MarshallerProperties.MEDIA_TYPE.equals(key)) {
+ return xmlMarshaller.getMediaType();
+ } else if (MarshallerProperties.NAMESPACE_PREFIX_MAPPER.equals(key)) {
+ return xmlMarshaller.getNamespacePrefixMapper();
+ } else if (MarshallerProperties.INDENT_STRING.equals(key) || SUN_INDENT_STRING.equals(key) || SUN_JSE_INDENT_STRING.equals(key)) {
+ return xmlMarshaller.getIndentString();
+ } else if (MarshallerProperties.CHARACTER_ESCAPE_HANDLER.equals(key)) {
+ return xmlMarshaller.getCharacterEscapeHandler();
+ } else if (XML_DECLARATION.equals(key)) {
+ return !xmlMarshaller.isFragment();
+ } else if (XML_HEADERS.equals(key)) {
+ return xmlMarshaller.getXmlHeader();
+ } else if (OBJECT_IDENTITY_CYCLE_DETECTION.equals(key)) {
+ return xmlMarshaller.isEqualUsingIdenity();
+ } else if (MarshallerProperties.JSON_ATTRIBUTE_PREFIX.equals(key)) {
+ return xmlMarshaller.getAttributePrefix();
+ } else if (MarshallerProperties.JSON_INCLUDE_ROOT.equals(key)) {
+ return xmlMarshaller.isIncludeRoot();
+ } else if (MarshallerProperties.JSON_VALUE_WRAPPER.equals(key)) {
+ return xmlMarshaller.getValueWrapper();
+ } else if (MarshallerProperties.JSON_NAMESPACE_SEPARATOR.equals(key)) {
return xmlMarshaller.getNamespaceSeparator();
} else if (MarshallerProperties.JSON_WRAPPER_AS_ARRAY_NAME.equals(key)) {
return xmlMarshaller.isWrapperAsCollectionName();
@@ -312,29 +321,29 @@
} else if (SUN_CHARACTER_ESCAPE_HANDLER.equals(key) || SUN_JSE_CHARACTER_ESCAPE_HANDLER.equals(key) ||SUN_CHARACTER_ESCAPE_HANDLER_MARSHALLER.equals(key) || SUN_JSE_CHARACTER_ESCAPE_HANDLER_MARSHALLER.equals(key)) {
if (xmlMarshaller.getCharacterEscapeHandler() instanceof CharacterEscapeHandlerWrapper) {
CharacterEscapeHandlerWrapper wrapper = (CharacterEscapeHandlerWrapper) xmlMarshaller.getCharacterEscapeHandler();
- return wrapper.getHandler();
- }
- return xmlMarshaller.getCharacterEscapeHandler();
- } else if (SUN_NAMESPACE_PREFIX_MAPPER.equals(key) || SUN_JSE_NAMESPACE_PREFIX_MAPPER.equals(key)) {
- NamespacePrefixMapperWrapper wrapper = (NamespacePrefixMapperWrapper) xmlMarshaller.getNamespacePrefixMapper();
- if(wrapper == null){
- return null;
- }
- return wrapper.getPrefixMapper();
- } else if (MarshallerProperties.OBJECT_GRAPH.equals(key)) {
- Object graph = xmlMarshaller.getMarshalAttributeGroup();
- if(graph instanceof CoreAttributeGroup) {
- return new ObjectGraphImpl((CoreAttributeGroup)graph);
- }
- return graph;
- } else if (MarshallerProperties.BEAN_VALIDATION_MODE.equals(key)) {
- return this.beanValidationMode;
- } else if (MarshallerProperties.BEAN_VALIDATION_FACTORY.equals(key)) {
- return this.prefValidatorFactory;
- } else if (MarshallerProperties.BEAN_VALIDATION_GROUPS.equals(key)) {
- return this.beanValidationGroups;
- } else if (MarshallerProperties.BEAN_VALIDATION_NO_OPTIMISATION.equals(key)) {
- return this.bvNoOptimisation;
+ return wrapper.getHandler();
+ }
+ return xmlMarshaller.getCharacterEscapeHandler();
+ } else if (SUN_NAMESPACE_PREFIX_MAPPER.equals(key) || SUN_JSE_NAMESPACE_PREFIX_MAPPER.equals(key)) {
+ NamespacePrefixMapperWrapper wrapper = (NamespacePrefixMapperWrapper) xmlMarshaller.getNamespacePrefixMapper();
+ if(wrapper == null){
+ return null;
+ }
+ return wrapper.getPrefixMapper();
+ } else if (MarshallerProperties.OBJECT_GRAPH.equals(key)) {
+ Object graph = xmlMarshaller.getMarshalAttributeGroup();
+ if(graph instanceof CoreAttributeGroup) {
+ return new ObjectGraphImpl((CoreAttributeGroup)graph);
+ }
+ return graph;
+ } else if (MarshallerProperties.BEAN_VALIDATION_MODE.equals(key)) {
+ return this.beanValidationMode;
+ } else if (MarshallerProperties.BEAN_VALIDATION_FACTORY.equals(key)) {
+ return this.prefValidatorFactory;
+ } else if (MarshallerProperties.BEAN_VALIDATION_GROUPS.equals(key)) {
+ return this.beanValidationGroups;
+ } else if (MarshallerProperties.BEAN_VALIDATION_NO_OPTIMISATION.equals(key)) {
+ return this.bvNoOptimisation;
}
throw new PropertyException(key);
}
@@ -342,537 +351,551 @@
public Schema getSchema() {
return xmlMarshaller.getSchema();
}
-
- public void marshal(Object object, ContentHandler contentHandler) throws JAXBException {
- if (object == null || contentHandler == null) {
- throw new IllegalArgumentException();
- }
-
- Listener listener = getListener();
- if(listener != null) {
- if(object instanceof JAXBElement) {
- listener.beforeMarshal(object);
- }
- }
-
- Object oxmObject = validateAndTransformIfNeeded(object); // xml bindings + object
- try {
- xmlMarshaller.marshal(oxmObject, contentHandler);
- } catch (BeanValidationException bve) {
- throw new MarshalException(bve.getMessage(), String.valueOf(bve.getErrorCode()), bve);
- } catch (Exception e) {
- throw new MarshalException(e);
- }
-
- if(listener != null) {
- if(object instanceof JAXBElement) {
- listener.afterMarshal(object);
- }
- }
- }
-
- private Object wrapEnumeration(Object object, Class enumerationClass) {
- Class generatedClass = this.getClassToGeneratedClasses().get(enumerationClass.getName());
- if (generatedClass != null && WrappedValue.class.isAssignableFrom(generatedClass)) {
- ClassDescriptor desc = xmlMarshaller.getXMLContext().getSession(generatedClass).getDescriptor(generatedClass);
- Object newObject = desc.getInstantiationPolicy().buildNewInstance();
- ((WrappedValue) newObject).setValue(object);
- object = newObject;
- }
- return object;
- }
-
- public void marshal(Object object, XMLEventWriter eventWriter) throws JAXBException {
- if (object == null || eventWriter == null) {
- throw new IllegalArgumentException();
- }
-
- Listener listener = getListener();
- if(listener != null) {
- if(object instanceof JAXBElement) {
- listener.beforeMarshal(object);
- }
- }
-
- Object oxmObject = validateAndTransformIfNeeded(object); // xml bindings + object
- try {
- XMLEventWriterRecord record = new XMLEventWriterRecord(eventWriter);
- record.setMarshaller(this.xmlMarshaller);
- this.xmlMarshaller.marshal(oxmObject, record);
- } catch (BeanValidationException bve) {
- throw new MarshalException(bve.getMessage(), String.valueOf(bve.getErrorCode()), bve);
- } catch (Exception ex) {
- throw new MarshalException(ex);
- }
-
- if(listener != null) {
- if(object instanceof JAXBElement) {
- listener.afterMarshal(object);
- }
- }
- }
-
- public void marshal(Object object, XMLEventWriter eventWriter, TypeMappingInfo type) throws JAXBException {
- if (jaxbContext.getTypeMappingInfoToGeneratedType() == null) {
- marshal(object, eventWriter);
- } else {
- JAXBElement element = null;
- Object value = object;
- if (object instanceof JAXBElement) {
- // use the JAXBElement's properties to populate an XMLRoot
- element = (JAXBElement) object;
- value = element.getValue();
- }
-
- RootLevelXmlAdapter adapter = jaxbContext.getTypeMappingInfoToJavaTypeAdapters().get(type);
- if (adapter != null) {
- try {
- value = adapter.getXmlAdapter().marshal(value);
- } catch (Exception ex) {
- throw new JAXBException(XMLMarshalException.marshalException(ex));
- }
- }
-
- value = wrapObject(value, element, type);
- marshal(value, eventWriter);
- }
- }
-
- public void marshal(Object object, Node node) throws JAXBException {
- if (object == null || node == null) {
- throw new IllegalArgumentException();
- }
-
- Listener listener = getListener();
- if(listener != null) {
- if(object instanceof JAXBElement) {
- listener.beforeMarshal(object);
- }
- }
-
- Object oxmObject = validateAndTransformIfNeeded(object); // xml bindings + object
- try {
- xmlMarshaller.marshal(oxmObject, node);
- } catch (BeanValidationException bve) {
- throw new MarshalException(bve.getMessage(), String.valueOf(bve.getErrorCode()), bve);
- } catch (Exception e) {
- throw new MarshalException(e);
- }
-
- if(listener != null) {
- if(object instanceof JAXBElement) {
- listener.afterMarshal(object);
- }
- }
- }
-
- public void marshal(Object object, OutputStream outputStream) throws JAXBException {
- if (object == null || outputStream == null) {
- throw new IllegalArgumentException();
- }
-
- Listener listener = getListener();
- if(listener != null) {
- if(object instanceof JAXBElement) {
- listener.beforeMarshal(object);
- }
- }
-
- Object oxmObject = validateAndTransformIfNeeded(object); // xml bindings + object
- try {
- xmlMarshaller.marshal(oxmObject, outputStream);
- } catch (BeanValidationException bve) {
- throw new MarshalException(bve.getMessage(), String.valueOf(bve.getErrorCode()), bve);
- } catch (Exception e) {
- throw new MarshalException(e);
- }
-
- if(listener != null) {
- if(object instanceof JAXBElement) {
- listener.afterMarshal(object);
- }
- }
- }
-
- public void marshal(Object object, File file) throws JAXBException {
- try {
- FileOutputStream outputStream = new FileOutputStream(file);
- try {
- marshal(object, outputStream); // link to the other one
- } finally {
- outputStream.close();
- }
- } catch (BeanValidationException bve) {
- throw new MarshalException(bve.getMessage(), String.valueOf(bve.getErrorCode()), bve);
- } catch (Exception ex) {
- throw new MarshalException(ex);
- }
- }
-
- public void marshal(Object object, Result result) throws JAXBException {
- if (object == null || result == null) {
- throw new IllegalArgumentException();
- }
- object = validateAndTransformIfNeeded(object); // xml bindings + json object
-
- try {
- xmlMarshaller.marshal(object, result);
- } catch (BeanValidationException bve) {
- throw new MarshalException(bve.getMessage(), String.valueOf(bve.getErrorCode()), bve);
- } catch (Exception e) {
- throw new MarshalException(e);
- }
- }
-
- public void marshal(Object object, Result result, TypeMappingInfo type) throws JAXBException {
- if (jaxbContext.getTypeMappingInfoToGeneratedType() == null) {
- marshal(object, result);
- } else {
- JAXBElement element = null;
- Object value = object;
- if (object instanceof JAXBElement) {
- // use the JAXBElement's properties to populate an XMLRoot
- element = (JAXBElement) object;
- value = element.getValue();
- }
-
- if(jaxbContext.getTypeMappingInfoToJavaTypeAdapters().size() > 0){
- RootLevelXmlAdapter adapter = jaxbContext.getTypeMappingInfoToJavaTypeAdapters().get(type);
-
- if (adapter != null) {
- try {
- value = adapter.getXmlAdapter().marshal(value);
- } catch (Exception ex) {
- throw new JAXBException(XMLMarshalException.marshalException(ex));
- }
- }
- }
- value = wrapObject(value, element, type);
- marshal(value, result);
- }
- }
-
- public void marshal(Object object, XMLStreamWriter streamWriter) throws JAXBException {
- if (object == null || streamWriter == null) {
- throw new IllegalArgumentException();
- }
-
- Listener listener = getListener();
- if(listener != null) {
- if(object instanceof JAXBElement) {
- listener.beforeMarshal(object);
- }
- }
-
- Object oxmObject = validateAndTransformIfNeeded(object); // xml bindings + object
- try {
- XMLStreamWriterRecord record = new XMLStreamWriterRecord(streamWriter);
- record.setMarshaller(this.xmlMarshaller);
- this.xmlMarshaller.marshal(oxmObject, record);
- } catch (BeanValidationException bve) {
- throw new MarshalException(bve.getMessage(), String.valueOf(bve.getErrorCode()), bve);
- } catch (Exception ex) {
- throw new MarshalException(ex);
- }
-
- if(listener != null) {
- if(object instanceof JAXBElement) {
- listener.afterMarshal(object);
- }
- }
- }
-
- private Object validateAndTransformIfNeeded(Object obj) throws BeanValidationException {
- Object result = modifyObjectIfNeeded(obj);
- if (beanValidator.shouldValidate(obj, beanValidationMode, prefValidatorFactory, bvNoOptimisation)) {
- beanValidator.validate(result, beanValidationGroups);
- }
- return result;
- }
-
- private Object modifyObjectIfNeeded(Object obj) {
- if (obj instanceof Collection) {
- Collection objectList = (Collection) obj;
- List newList = new ArrayList(objectList.size());
- for (Object o : objectList) {
- newList.add(modifySingleObjectIfNeeded(o));
- }
- return newList;
- } else if (obj.getClass().isArray()) {
- int arraySize = Array.getLength(obj);
- List newList = new ArrayList(arraySize);
- for (int x = 0; x < arraySize; x++) {
- newList.add(modifySingleObjectIfNeeded(Array.get(obj, x)));
- }
- return newList;
- } else {
- return modifySingleObjectIfNeeded(obj);
- }
- }
-
- private Object modifySingleObjectIfNeeded(Object obj){
- // let the JAXBIntrospector determine if the object is a JAXBElement
- if (obj instanceof JAXBElement) {
- // use the JAXBElement's properties to populate an XMLRoot
- return createXMLRootFromJAXBElement((JAXBElement) obj);
- } else if(obj != null && obj.getClass().isEnum()) {
- return wrapEnumeration(obj, obj.getClass());
- } else if (obj instanceof JSONWithPadding){
- Object nestedObject = ((JSONWithPadding)obj).getObject();
- if(nestedObject != null){
- Object newNestedObject = modifyObjectIfNeeded(nestedObject);
- if(nestedObject != newNestedObject){
- return new JSONWithPadding(newNestedObject,((JSONWithPadding)obj).getCallbackName());
- }
- }
- }
- return obj;
- }
-
- public void marshal(Object object, XMLStreamWriter streamWriter, TypeMappingInfo type) throws JAXBException {
- if (jaxbContext.getTypeMappingInfoToGeneratedType() == null) {
- marshal(object, streamWriter);
- } else {
- JAXBElement element = null;
- Object value = object;
- if (object instanceof JAXBElement) {
- // use the JAXBElement's properties to populate an XMLRoot
- element = (JAXBElement) object;
- value = element.getValue();
- }
- if(jaxbContext.getTypeMappingInfoToJavaTypeAdapters().size() > 0){
- RootLevelXmlAdapter adapter = jaxbContext.getTypeMappingInfoToJavaTypeAdapters().get(type);
- if (adapter != null) {
- try {
- value = adapter.getXmlAdapter().marshal(value);
- } catch (Exception ex) {
- throw new JAXBException(XMLMarshalException.marshalException(ex));
- }
- }
- }
-
- value = wrapObject(value, element, type);
- marshal(value, streamWriter);
- }
- }
-
- private Object wrapObject(Object object, JAXBElement wrapperElement, TypeMappingInfo typeMappingInfo) {
- if(jaxbContext.getTypeMappingInfoToGeneratedType().size() > 0){
- Class generatedClass = jaxbContext.getTypeMappingInfoToGeneratedType().get(typeMappingInfo);
- if(generatedClass != null && object == null && wrapperElement != null) {
- return wrapObjectInXMLRoot(wrapperElement, object, typeMappingInfo);
- }
-
- if (generatedClass != null && WrappedValue.class.isAssignableFrom(generatedClass)) {
- ClassDescriptor desc = xmlMarshaller.getXMLContext().getSession(generatedClass).getDescriptor(generatedClass);
- Object newObject = desc.getInstantiationPolicy().buildNewInstance();
- ((WrappedValue) newObject).setValue(object);
- object = newObject;
- } else if (generatedClass != null) {
- // should be a many value
- ClassDescriptor desc = xmlMarshaller.getXMLContext().getSession(generatedClass).getDescriptor(generatedClass);
- Object newObject = desc.getInstantiationPolicy().buildNewInstance();
- ((ManyValue) newObject).setItem(object);
- object = newObject;
- }
- }
-
- if (null == wrapperElement) {
- Root xmlRoot = new Root();
- QName xmlTagName = typeMappingInfo.getXmlTagName();
- if (null == xmlTagName) {
- return object;
- }
- xmlRoot.setNamespaceURI(typeMappingInfo.getXmlTagName().getNamespaceURI());
- xmlRoot.setLocalName(typeMappingInfo.getXmlTagName().getLocalPart());
- xmlRoot.setObject(object);
- return xmlRoot;
-
- }
- return wrapObjectInXMLRoot(wrapperElement, object, typeMappingInfo);
- }
-
- private Root wrapObjectInXMLRoot(JAXBElement wrapperElement, Object value, TypeMappingInfo typeMappingInfo) {
- Root xmlroot = new Root();
- Object objectValue = value;
- xmlroot.setObject(objectValue);
- QName qname = wrapperElement.getName();
- xmlroot.setLocalName(qname.getLocalPart());
- xmlroot.setNamespaceURI(qname.getNamespaceURI());
- xmlroot.setDeclaredType(wrapperElement.getDeclaredType());
- if(typeMappingInfo != null){
- xmlroot.setSchemaType(typeMappingInfo.getSchemaType());
- } else if(value != null) {
- if (value.getClass() == CoreClassConstants.ABYTE || value.getClass() == CoreClassConstants.APBYTE ||
- value.getClass().getCanonicalName().equals("javax.activation.DataHandler")) {
- xmlroot.setSchemaType(Constants.BASE_64_BINARY_QNAME);
- }
- }
- return xmlroot;
- }
-
- public void marshal(Object object, Writer writer) throws JAXBException {
- if (object == null || writer == null) {
- throw new IllegalArgumentException();
- }
-
- Listener listener = getListener();
- if(listener != null) {
- if(object instanceof JAXBElement) {
- listener.beforeMarshal(object);
- }
- }
-
- Object oxmObject = validateAndTransformIfNeeded(object); // xml bindings + object
- try {
- xmlMarshaller.marshal(oxmObject, writer);
- } catch (BeanValidationException bve) {
- throw new MarshalException(bve.getMessage(), String.valueOf(bve.getErrorCode()), bve);
- } catch (Exception e) {
- throw new MarshalException(e);
- }
-
- if(listener != null) {
- if(object instanceof JAXBElement) {
- listener.afterMarshal(object);
- }
- }
- }
-
- public void marshal(Object object, MarshalRecord record) throws JAXBException {
- if (object == null || record == null) {
- throw new IllegalArgumentException();
- }
- object = validateAndTransformIfNeeded(object); // xml bindings + object
-
- try {
- record.setMarshaller(xmlMarshaller);
- xmlMarshaller.marshal(object, record);
- } catch (BeanValidationException bve) {
- throw new MarshalException(bve.getMessage(), String.valueOf(bve.getErrorCode()), bve);
- } catch (Exception e) {
- throw new MarshalException(e);
- }
- }
-
- public void marshal(Object object, MarshalRecord record, TypeMappingInfo type) throws JAXBException {
- if (jaxbContext.getTypeMappingInfoToGeneratedType() == null) {
- marshal(object, record);
- } else {
- JAXBElement element = null;
- Object value = object;
- if (object instanceof JAXBElement) {
- // use the JAXBElement's properties to populate an XMLRoot
- element = (JAXBElement) object;
- value = element.getValue();
- }
- RootLevelXmlAdapter adapter = jaxbContext.getTypeMappingInfoToJavaTypeAdapters().get(type);
- if (adapter != null) {
- try {
- value = adapter.getXmlAdapter().marshal(value);
- } catch (Exception ex) {
- throw new JAXBException(XMLMarshalException.marshalException(ex));
- }
- }
- value = wrapObject(value, element, type);
- marshal(value, record);
- }
- }
-
- public void setAdapter(Class javaClass, XmlAdapter adapter) {
- HashMap result = (HashMap) xmlMarshaller.getProperty(XML_JAVATYPE_ADAPTERS);
- if (result == null) {
- result = new HashMap();
- xmlMarshaller.getProperties().put(XML_JAVATYPE_ADAPTERS, result);
- }
- result.put(javaClass, adapter);
- }
-
- public void setAdapter(XmlAdapter adapter) {
- setAdapter(adapter.getClass(), adapter);
- }
-
- public void setAttachmentMarshaller(AttachmentMarshaller attachmentMarshaller) {
- if (attachmentMarshaller == null) {
- xmlMarshaller.setAttachmentMarshaller(null);
- } else {
- xmlMarshaller.setAttachmentMarshaller(new AttachmentMarshallerAdapter(attachmentMarshaller));
- }
- }
-
- public void setEventHandler(ValidationEventHandler newValidationEventHandler) throws JAXBException {
- if (null == newValidationEventHandler) {
- validationEventHandler = JAXBContext.DEFAULT_VALIDATION_EVENT_HANDLER;
- } else {
- validationEventHandler = newValidationEventHandler;
- }
- xmlMarshaller.setErrorHandler(new JAXBErrorHandler(validationEventHandler));
- }
-
- public void setListener(Marshaller.Listener listener) {
- if(xmlMarshaller.getMarshalListener() == null) {
- xmlMarshaller.setMarshalListener(new JAXBMarshalListener(jaxbContext, this));
- }
- ((JAXBMarshalListener) xmlMarshaller.getMarshalListener()).setListener(listener);
- }
-
- public void setMarshalCallbacks(Map callbacks) {
- if(callbacks == null || callbacks.isEmpty()) {
- return;
- }
- if(xmlMarshaller.getMarshalListener() == null) {
- xmlMarshaller.setMarshalListener(new JAXBMarshalListener(jaxbContext, this));
- }
- ((JAXBMarshalListener) xmlMarshaller.getMarshalListener()).setClassBasedMarshalEvents(callbacks);
- }
-
- /**
- * Set a property on the JAXBMarshaller. Attempting to set any unsupported
- * property will result in a javax.xml.bind.PropertyException
- * @see org.eclipse.persistence.jaxb.MarshallerProperties
- */
- public void setProperty(String key, Object value) throws PropertyException {
- try {
- if (key == null) {
- throw new IllegalArgumentException();
- } else if (Constants.JAXB_FRAGMENT.equals(key)) {
- if(value == null){
- throw new PropertyException(key, Constants.EMPTY_STRING);
- }
- Boolean fragment = (Boolean) value;
- xmlMarshaller.setFragment(fragment.booleanValue());
- } else if (JAXB_FORMATTED_OUTPUT.equals(key)) {
- if(value == null){
- throw new PropertyException(key, Constants.EMPTY_STRING);
- }
- Boolean formattedOutput = (Boolean) value;
- xmlMarshaller.setFormattedOutput(formattedOutput.booleanValue());
- } else if (JAXB_ENCODING.equals(key)) {
- xmlMarshaller.setEncoding((String) value);
- } else if (JAXB_SCHEMA_LOCATION.equals(key)) {
- xmlMarshaller.setSchemaLocation((String) value);
- } else if (JAXB_NO_NAMESPACE_SCHEMA_LOCATION.equals(key)) {
- xmlMarshaller.setNoNamespaceSchemaLocation((String) value);
- } else if(MarshallerProperties.NAMESPACE_PREFIX_MAPPER.equals(key)) {
- if(value == null){
- xmlMarshaller.setNamespacePrefixMapper(null);
- }else if(value instanceof Map){
- NamespacePrefixMapper namespacePrefixMapper = new MapNamespacePrefixMapper((Map)value);
- xmlMarshaller.setNamespacePrefixMapper(namespacePrefixMapper);
- }else{
- xmlMarshaller.setNamespacePrefixMapper((NamespacePrefixMapper)value);
- }
- } else if(SUN_NAMESPACE_PREFIX_MAPPER.equals(key) || SUN_JSE_NAMESPACE_PREFIX_MAPPER.equals(key)) {
- if(value == null){
- xmlMarshaller.setNamespacePrefixMapper(null);
- }else{
- xmlMarshaller.setNamespacePrefixMapper(new NamespacePrefixMapperWrapper(value));
- }
- } else if (MarshallerProperties.INDENT_STRING.equals(key) || SUN_INDENT_STRING.equals(key) || SUN_JSE_INDENT_STRING.equals(key)) {
- xmlMarshaller.setIndentString((String) value);
- } else if (MarshallerProperties.JSON_MARSHAL_EMPTY_COLLECTIONS.equals(key)){
- xmlMarshaller.setMarshalEmptyCollections((Boolean) value);
- } else if (MarshallerProperties.JSON_REDUCE_ANY_ARRAYS.equals(key)){
+
+ @Override
+ public void marshal(Object object, ContentHandler contentHandler) throws JAXBException {
+ if (object == null || contentHandler == null) {
+ throw new IllegalArgumentException();
+ }
+
+ Listener listener = getListener();
+ if(listener != null) {
+ if(object instanceof JAXBElement) {
+ listener.beforeMarshal(object);
+ }
+ }
+
+ Object oxmObject = validateAndTransformIfNeeded(object); // xml bindings + object
+ try {
+ xmlMarshaller.marshal(oxmObject, contentHandler);
+ } catch (BeanValidationException bve) {
+ throw new MarshalException(bve.getMessage(), String.valueOf(bve.getErrorCode()), bve);
+ } catch (Exception e) {
+ throw new MarshalException(e);
+ }
+
+ if(listener != null) {
+ if(object instanceof JAXBElement) {
+ listener.afterMarshal(object);
+ }
+ }
+ }
+
+ private Object wrapEnumeration(Object object, Class enumerationClass) {
+ Class generatedClass = this.getClassToGeneratedClasses().get(enumerationClass.getName());
+ if (generatedClass != null && WrappedValue.class.isAssignableFrom(generatedClass)) {
+ ClassDescriptor desc = xmlMarshaller.getXMLContext().getSession(generatedClass).getDescriptor(generatedClass);
+ Object newObject = desc.getInstantiationPolicy().buildNewInstance();
+ ((WrappedValue) newObject).setValue(object);
+ object = newObject;
+ }
+ return object;
+ }
+
+ @Override
+ public void marshal(Object object, XMLEventWriter eventWriter) throws JAXBException {
+ if (object == null || eventWriter == null) {
+ throw new IllegalArgumentException();
+ }
+
+ Listener listener = getListener();
+ if(listener != null) {
+ if(object instanceof JAXBElement) {
+ listener.beforeMarshal(object);
+ }
+ }
+
+ Object oxmObject = validateAndTransformIfNeeded(object); // xml bindings + object
+ try {
+ XMLEventWriterRecord record = new XMLEventWriterRecord(eventWriter);
+ record.setMarshaller(this.xmlMarshaller);
+ this.xmlMarshaller.marshal(oxmObject, record);
+ } catch (BeanValidationException bve) {
+ throw new MarshalException(bve.getMessage(), String.valueOf(bve.getErrorCode()), bve);
+ } catch (Exception ex) {
+ throw new MarshalException(ex);
+ }
+
+ if(listener != null) {
+ if(object instanceof JAXBElement) {
+ listener.afterMarshal(object);
+ }
+ }
+ }
+
+ public void marshal(Object object, XMLEventWriter eventWriter, TypeMappingInfo type) throws JAXBException {
+ if (jaxbContext.getTypeMappingInfoToGeneratedType() == null) {
+ marshal(object, eventWriter);
+ } else {
+ JAXBElement element = null;
+ Object value = object;
+ if (object instanceof JAXBElement) {
+ // use the JAXBElement's properties to populate an XMLRoot
+ element = (JAXBElement) object;
+ value = element.getValue();
+ }
+
+ RootLevelXmlAdapter adapter = jaxbContext.getTypeMappingInfoToJavaTypeAdapters().get(type);
+ if (adapter != null) {
+ try {
+ value = adapter.getXmlAdapter().marshal(value);
+ } catch (Exception ex) {
+ throw new JAXBException(XMLMarshalException.marshalException(ex));
+ }
+ }
+
+ value = wrapObject(value, element, type);
+ marshal(value, eventWriter);
+ }
+ }
+
+ @Override
+ public void marshal(Object object, Node node) throws JAXBException {
+ if (object == null || node == null) {
+ throw new IllegalArgumentException();
+ }
+
+ Listener listener = getListener();
+ if(listener != null) {
+ if(object instanceof JAXBElement) {
+ listener.beforeMarshal(object);
+ }
+ }
+
+ Object oxmObject = validateAndTransformIfNeeded(object); // xml bindings + object
+ try {
+ xmlMarshaller.marshal(oxmObject, node);
+ } catch (BeanValidationException bve) {
+ throw new MarshalException(bve.getMessage(), String.valueOf(bve.getErrorCode()), bve);
+ } catch (Exception e) {
+ throw new MarshalException(e);
+ }
+
+ if(listener != null) {
+ if(object instanceof JAXBElement) {
+ listener.afterMarshal(object);
+ }
+ }
+ }
+
+ @Override
+ public void marshal(Object object, OutputStream outputStream) throws JAXBException {
+ if (object == null || outputStream == null) {
+ throw new IllegalArgumentException();
+ }
+
+ Listener listener = getListener();
+ if(listener != null) {
+ if(object instanceof JAXBElement) {
+ listener.beforeMarshal(object);
+ }
+ }
+
+ Object oxmObject = validateAndTransformIfNeeded(object); // xml bindings + object
+ try {
+ xmlMarshaller.marshal(oxmObject, outputStream);
+ } catch (BeanValidationException bve) {
+ throw new MarshalException(bve.getMessage(), String.valueOf(bve.getErrorCode()), bve);
+ } catch (Exception e) {
+ throw new MarshalException(e);
+ }
+
+ if(listener != null) {
+ if(object instanceof JAXBElement) {
+ listener.afterMarshal(object);
+ }
+ }
+ }
+
+ @Override
+ public void marshal(Object object, File file) throws JAXBException {
+ try {
+ FileOutputStream outputStream = new FileOutputStream(file);
+ try {
+ marshal(object, outputStream); // link to the other one
+ } finally {
+ outputStream.close();
+ }
+ } catch (BeanValidationException bve) {
+ throw new MarshalException(bve.getMessage(), String.valueOf(bve.getErrorCode()), bve);
+ } catch (Exception ex) {
+ throw new MarshalException(ex);
+ }
+ }
+
+ @Override
+ public void marshal(Object object, Result result) throws JAXBException {
+ if (object == null || result == null) {
+ throw new IllegalArgumentException();
+ }
+ object = validateAndTransformIfNeeded(object); // xml bindings + json object
+
+ try {
+ xmlMarshaller.marshal(object, result);
+ } catch (BeanValidationException bve) {
+ throw new MarshalException(bve.getMessage(), String.valueOf(bve.getErrorCode()), bve);
+ } catch (Exception e) {
+ throw new MarshalException(e);
+ }
+ }
+
+ public void marshal(Object object, Result result, TypeMappingInfo type) throws JAXBException {
+ if (jaxbContext.getTypeMappingInfoToGeneratedType() == null) {
+ marshal(object, result);
+ } else {
+ JAXBElement element = null;
+ Object value = object;
+ if (object instanceof JAXBElement) {
+ // use the JAXBElement's properties to populate an XMLRoot
+ element = (JAXBElement) object;
+ value = element.getValue();
+ }
+
+ if(jaxbContext.getTypeMappingInfoToJavaTypeAdapters().size() > 0){
+ RootLevelXmlAdapter adapter = jaxbContext.getTypeMappingInfoToJavaTypeAdapters().get(type);
+
+ if (adapter != null) {
+ try {
+ value = adapter.getXmlAdapter().marshal(value);
+ } catch (Exception ex) {
+ throw new JAXBException(XMLMarshalException.marshalException(ex));
+ }
+ }
+ }
+ value = wrapObject(value, element, type);
+ marshal(value, result);
+ }
+ }
+
+ @Override
+ public void marshal(Object object, XMLStreamWriter streamWriter) throws JAXBException {
+ if (object == null || streamWriter == null) {
+ throw new IllegalArgumentException();
+ }
+
+ Listener listener = getListener();
+ if(listener != null) {
+ if(object instanceof JAXBElement) {
+ listener.beforeMarshal(object);
+ }
+ }
+
+ Object oxmObject = validateAndTransformIfNeeded(object); // xml bindings + object
+ try {
+ XMLStreamWriterRecord record = new XMLStreamWriterRecord(streamWriter);
+ record.setMarshaller(this.xmlMarshaller);
+ this.xmlMarshaller.marshal(oxmObject, record);
+ } catch (BeanValidationException bve) {
+ throw new MarshalException(bve.getMessage(), String.valueOf(bve.getErrorCode()), bve);
+ } catch (Exception ex) {
+ throw new MarshalException(ex);
+ }
+
+ if(listener != null) {
+ if(object instanceof JAXBElement) {
+ listener.afterMarshal(object);
+ }
+ }
+ }
+
+ private Object validateAndTransformIfNeeded(Object obj) throws BeanValidationException {
+ Object result = modifyObjectIfNeeded(obj);
+ if (beanValidator != null && beanValidator.shouldValidate(obj, beanValidationMode, prefValidatorFactory, bvNoOptimisation)) {
+ beanValidator.validate(result, beanValidationGroups);
+ }
+ return result;
+ }
+
+ private Object modifyObjectIfNeeded(Object obj) {
+ if (obj instanceof Collection) {
+ Collection objectList = (Collection) obj;
+ List newList = new ArrayList(objectList.size());
+ for (Object o : objectList) {
+ newList.add(modifySingleObjectIfNeeded(o));
+ }
+ return newList;
+ } else if (obj.getClass().isArray()) {
+ int arraySize = Array.getLength(obj);
+ List newList = new ArrayList(arraySize);
+ for (int x = 0; x < arraySize; x++) {
+ newList.add(modifySingleObjectIfNeeded(Array.get(obj, x)));
+ }
+ return newList;
+ } else {
+ return modifySingleObjectIfNeeded(obj);
+ }
+ }
+
+ private Object modifySingleObjectIfNeeded(Object obj){
+ // let the JAXBIntrospector determine if the object is a JAXBElement
+ if (obj instanceof JAXBElement) {
+ // use the JAXBElement's properties to populate an XMLRoot
+ return createXMLRootFromJAXBElement((JAXBElement) obj);
+ } else if(obj != null && obj.getClass().isEnum()) {
+ return wrapEnumeration(obj, obj.getClass());
+ } else if (obj instanceof JSONWithPadding){
+ Object nestedObject = ((JSONWithPadding)obj).getObject();
+ if(nestedObject != null){
+ Object newNestedObject = modifyObjectIfNeeded(nestedObject);
+ if(nestedObject != newNestedObject){
+ return new JSONWithPadding(newNestedObject,((JSONWithPadding)obj).getCallbackName());
+ }
+ }
+ }
+ return obj;
+ }
+
+ public void marshal(Object object, XMLStreamWriter streamWriter, TypeMappingInfo type) throws JAXBException {
+ if (jaxbContext.getTypeMappingInfoToGeneratedType() == null) {
+ marshal(object, streamWriter);
+ } else {
+ JAXBElement element = null;
+ Object value = object;
+ if (object instanceof JAXBElement) {
+ // use the JAXBElement's properties to populate an XMLRoot
+ element = (JAXBElement) object;
+ value = element.getValue();
+ }
+ if(jaxbContext.getTypeMappingInfoToJavaTypeAdapters().size() > 0){
+ RootLevelXmlAdapter adapter = jaxbContext.getTypeMappingInfoToJavaTypeAdapters().get(type);
+ if (adapter != null) {
+ try {
+ value = adapter.getXmlAdapter().marshal(value);
+ } catch (Exception ex) {
+ throw new JAXBException(XMLMarshalException.marshalException(ex));
+ }
+ }
+ }
+
+ value = wrapObject(value, element, type);
+ marshal(value, streamWriter);
+ }
+ }
+
+ private Object wrapObject(Object object, JAXBElement wrapperElement, TypeMappingInfo typeMappingInfo) {
+ if(jaxbContext.getTypeMappingInfoToGeneratedType().size() > 0){
+ Class generatedClass = jaxbContext.getTypeMappingInfoToGeneratedType().get(typeMappingInfo);
+ if(generatedClass != null && object == null && wrapperElement != null) {
+ return wrapObjectInXMLRoot(wrapperElement, null, typeMappingInfo);
+ }
+
+ if (generatedClass != null && WrappedValue.class.isAssignableFrom(generatedClass)) {
+ ClassDescriptor desc = xmlMarshaller.getXMLContext().getSession(generatedClass).getDescriptor(generatedClass);
+ Object newObject = desc.getInstantiationPolicy().buildNewInstance();
+ ((WrappedValue) newObject).setValue(object);
+ object = newObject;
+ } else if (generatedClass != null) {
+ // should be a many value
+ ClassDescriptor desc = xmlMarshaller.getXMLContext().getSession(generatedClass).getDescriptor(generatedClass);
+ Object newObject = desc.getInstantiationPolicy().buildNewInstance();
+ ((ManyValue) newObject).setItem(object);
+ object = newObject;
+ }
+ }
+
+ if (null == wrapperElement) {
+ Root xmlRoot = new Root();
+ QName xmlTagName = typeMappingInfo.getXmlTagName();
+ if (null == xmlTagName) {
+ return object;
+ }
+ xmlRoot.setNamespaceURI(typeMappingInfo.getXmlTagName().getNamespaceURI());
+ xmlRoot.setLocalName(typeMappingInfo.getXmlTagName().getLocalPart());
+ xmlRoot.setObject(object);
+ return xmlRoot;
+
+ }
+ return wrapObjectInXMLRoot(wrapperElement, object, typeMappingInfo);
+ }
+
+ private Root wrapObjectInXMLRoot(JAXBElement wrapperElement, Object value, TypeMappingInfo typeMappingInfo) {
+ Root xmlroot = new Root();
+ Object objectValue = value;
+ xmlroot.setObject(objectValue);
+ QName qname = wrapperElement.getName();
+ xmlroot.setLocalName(qname.getLocalPart());
+ xmlroot.setNamespaceURI(qname.getNamespaceURI());
+ xmlroot.setDeclaredType(wrapperElement.getDeclaredType());
+ if(typeMappingInfo != null){
+ xmlroot.setSchemaType(typeMappingInfo.getSchemaType());
+ } else if(value != null) {
+ if (value.getClass() == CoreClassConstants.ABYTE || value.getClass() == CoreClassConstants.APBYTE ||
+ value.getClass().getCanonicalName().equals("javax.activation.DataHandler")) {
+ xmlroot.setSchemaType(Constants.BASE_64_BINARY_QNAME);
+ }
+ }
+ return xmlroot;
+ }
+
+ @Override
+ public void marshal(Object object, Writer writer) throws JAXBException {
+ if (object == null || writer == null) {
+ throw new IllegalArgumentException();
+ }
+
+ Listener listener = getListener();
+ if(listener != null) {
+ if(object instanceof JAXBElement) {
+ listener.beforeMarshal(object);
+ }
+ }
+
+ Object oxmObject = validateAndTransformIfNeeded(object); // xml bindings + object
+ try {
+ xmlMarshaller.marshal(oxmObject, writer);
+ } catch (BeanValidationException bve) {
+ throw new MarshalException(bve.getMessage(), String.valueOf(bve.getErrorCode()), bve);
+ } catch (Exception e) {
+ throw new MarshalException(e);
+ }
+
+ if(listener != null) {
+ if(object instanceof JAXBElement) {
+ listener.afterMarshal(object);
+ }
+ }
+ }
+
+ public void marshal(Object object, MarshalRecord record) throws JAXBException {
+ if (object == null || record == null) {
+ throw new IllegalArgumentException();
+ }
+ object = validateAndTransformIfNeeded(object); // xml bindings + object
+
+ try {
+ record.setMarshaller(xmlMarshaller);
+ xmlMarshaller.marshal(object, record);
+ } catch (BeanValidationException bve) {
+ throw new MarshalException(bve.getMessage(), String.valueOf(bve.getErrorCode()), bve);
+ } catch (Exception e) {
+ throw new MarshalException(e);
+ }
+ }
+
+ public void marshal(Object object, MarshalRecord record, TypeMappingInfo type) throws JAXBException {
+ if (jaxbContext.getTypeMappingInfoToGeneratedType() == null) {
+ marshal(object, record);
+ } else {
+ JAXBElement element = null;
+ Object value = object;
+ if (object instanceof JAXBElement) {
+ // use the JAXBElement's properties to populate an XMLRoot
+ element = (JAXBElement) object;
+ value = element.getValue();
+ }
+ RootLevelXmlAdapter adapter = jaxbContext.getTypeMappingInfoToJavaTypeAdapters().get(type);
+ if (adapter != null) {
+ try {
+ value = adapter.getXmlAdapter().marshal(value);
+ } catch (Exception ex) {
+ throw new JAXBException(XMLMarshalException.marshalException(ex));
+ }
+ }
+ value = wrapObject(value, element, type);
+ marshal(value, record);
+ }
+ }
+
+ @Override
+ public void setAdapter(Class javaClass, XmlAdapter adapter) {
+ HashMap result = (HashMap) xmlMarshaller.getProperty(XML_JAVATYPE_ADAPTERS);
+ if (result == null) {
+ result = new HashMap();
+ xmlMarshaller.getProperties().put(XML_JAVATYPE_ADAPTERS, result);
+ }
+ result.put(javaClass, adapter);
+ }
+
+ @Override
+ public void setAdapter(XmlAdapter adapter) {
+ setAdapter(adapter.getClass(), adapter);
+ }
+
+ @Override
+ public void setAttachmentMarshaller(AttachmentMarshaller attachmentMarshaller) {
+ if (attachmentMarshaller == null) {
+ xmlMarshaller.setAttachmentMarshaller(null);
+ } else {
+ xmlMarshaller.setAttachmentMarshaller(new AttachmentMarshallerAdapter(attachmentMarshaller));
+ }
+ }
+
+ @Override
+ public void setEventHandler(ValidationEventHandler newValidationEventHandler) throws JAXBException {
+ if (null == newValidationEventHandler) {
+ validationEventHandler = JAXBContext.DEFAULT_VALIDATION_EVENT_HANDLER;
+ } else {
+ validationEventHandler = newValidationEventHandler;
+ }
+ xmlMarshaller.setErrorHandler(new JAXBErrorHandler(validationEventHandler));
+ }
+
+ @Override
+ public void setListener(Marshaller.Listener listener) {
+ if(xmlMarshaller.getMarshalListener() == null) {
+ xmlMarshaller.setMarshalListener(new JAXBMarshalListener(jaxbContext, this));
+ }
+ ((JAXBMarshalListener) xmlMarshaller.getMarshalListener()).setListener(listener);
+ }
+
+ public void setMarshalCallbacks(Map callbacks) {
+ if(callbacks == null || callbacks.isEmpty()) {
+ return;
+ }
+ if(xmlMarshaller.getMarshalListener() == null) {
+ xmlMarshaller.setMarshalListener(new JAXBMarshalListener(jaxbContext, this));
+ }
+ ((JAXBMarshalListener) xmlMarshaller.getMarshalListener()).setClassBasedMarshalEvents(callbacks);
+ }
+
+ /**
+ * Set a property on the JAXBMarshaller. Attempting to set any unsupported
+ * property will result in a javax.xml.bind.PropertyException
+ * @see org.eclipse.persistence.jaxb.MarshallerProperties
+ */
+ @Override
+ public void setProperty(String key, Object value) throws PropertyException {
+ try {
+ if (key == null) {
+ throw new IllegalArgumentException();
+ } else if (Constants.JAXB_FRAGMENT.equals(key)) {
+ if(value == null){
+ throw new PropertyException(key, Constants.EMPTY_STRING);
+ }
+ Boolean fragment = (Boolean) value;
+ xmlMarshaller.setFragment(fragment.booleanValue());
+ } else if (JAXB_FORMATTED_OUTPUT.equals(key)) {
+ if(value == null){
+ throw new PropertyException(key, Constants.EMPTY_STRING);
+ }
+ Boolean formattedOutput = (Boolean) value;
+ xmlMarshaller.setFormattedOutput(formattedOutput.booleanValue());
+ } else if (JAXB_ENCODING.equals(key)) {
+ xmlMarshaller.setEncoding((String) value);
+ } else if (JAXB_SCHEMA_LOCATION.equals(key)) {
+ xmlMarshaller.setSchemaLocation((String) value);
+ } else if (JAXB_NO_NAMESPACE_SCHEMA_LOCATION.equals(key)) {
+ xmlMarshaller.setNoNamespaceSchemaLocation((String) value);
+ } else if(MarshallerProperties.NAMESPACE_PREFIX_MAPPER.equals(key)) {
+ if(value == null){
+ xmlMarshaller.setNamespacePrefixMapper(null);
+ }else if(value instanceof Map){
+ NamespacePrefixMapper namespacePrefixMapper = new MapNamespacePrefixMapper((Map)value);
+ xmlMarshaller.setNamespacePrefixMapper(namespacePrefixMapper);
+ }else{
+ xmlMarshaller.setNamespacePrefixMapper((NamespacePrefixMapper)value);
+ }
+ } else if(SUN_NAMESPACE_PREFIX_MAPPER.equals(key) || SUN_JSE_NAMESPACE_PREFIX_MAPPER.equals(key)) {
+ if(value == null){
+ xmlMarshaller.setNamespacePrefixMapper(null);
+ }else{
+ xmlMarshaller.setNamespacePrefixMapper(new NamespacePrefixMapperWrapper(value));
+ }
+ } else if (MarshallerProperties.INDENT_STRING.equals(key) || SUN_INDENT_STRING.equals(key) || SUN_JSE_INDENT_STRING.equals(key)) {
+ xmlMarshaller.setIndentString((String) value);
+ } else if (MarshallerProperties.JSON_MARSHAL_EMPTY_COLLECTIONS.equals(key)){
+ xmlMarshaller.setMarshalEmptyCollections((Boolean) value);
+ } else if (MarshallerProperties.JSON_REDUCE_ANY_ARRAYS.equals(key)){
xmlMarshaller.setReduceAnyArrays((Boolean) value);
} else if (MarshallerProperties.JSON_WRAPPER_AS_ARRAY_NAME.equals(key)) {
xmlMarshaller.setWrapperAsCollectionName((Boolean) value);
@@ -883,122 +906,126 @@
} else if (MarshallerProperties.CHARACTER_ESCAPE_HANDLER.equals(key)) {
xmlMarshaller.setCharacterEscapeHandler((CharacterEscapeHandler) value);
} else if (SUN_CHARACTER_ESCAPE_HANDLER.equals(key) || SUN_JSE_CHARACTER_ESCAPE_HANDLER.equals(key) ||SUN_CHARACTER_ESCAPE_HANDLER_MARSHALLER.equals(key) || SUN_JSE_CHARACTER_ESCAPE_HANDLER_MARSHALLER.equals(key)) {
- if (value == null) {
- xmlMarshaller.setCharacterEscapeHandler(null);
- } else {
- xmlMarshaller.setCharacterEscapeHandler(new CharacterEscapeHandlerWrapper(value));
- }
- } else if (XML_DECLARATION.equals(key)) {
- if(value == null){
- throw new PropertyException(key, Constants.EMPTY_STRING);
- }
- Boolean fragment = !(Boolean) value;
- xmlMarshaller.setFragment(fragment.booleanValue());
- } else if (XML_HEADERS.equals(key)) {
- xmlMarshaller.setXmlHeader((String) value);
- } else if (OBJECT_IDENTITY_CYCLE_DETECTION.equals(key)) {
- if(value == null){
- throw new PropertyException(key, Constants.EMPTY_STRING);
- }
- xmlMarshaller.setEqualUsingIdenity(((Boolean) value).booleanValue());
- } else if (MarshallerProperties.MEDIA_TYPE.equals(key)) {
- MediaType mType = null;
- if(value instanceof MediaType) {
- mType = (MediaType) value;
- } else if(value instanceof String) {
- mType = MediaType.getMediaType((String)value);
- }
- if(mType == null){
- throw new PropertyException(key, Constants.EMPTY_STRING);
- }
- xmlMarshaller.setMediaType(mType);
- } else if (MarshallerProperties.JSON_ATTRIBUTE_PREFIX.equals(key)) {
- xmlMarshaller.setAttributePrefix((String)value);
- } else if (MarshallerProperties.JSON_INCLUDE_ROOT.equals(key)) {
- if(value == null){
- throw new PropertyException(key, Constants.EMPTY_STRING);
- }
- xmlMarshaller.setIncludeRoot((Boolean)value);
- } else if(MarshallerProperties.JSON_VALUE_WRAPPER.equals(key)){
- if(value == null || (((String)value).length() == 0)){
- throw new PropertyException(key, Constants.EMPTY_STRING);
- }
- xmlMarshaller.setValueWrapper((String)value);
- } else if(MarshallerProperties.JSON_NAMESPACE_SEPARATOR.equals(key)){
- if(value == null){
- throw new PropertyException(key, Constants.EMPTY_STRING);
- }
- xmlMarshaller.setNamespaceSeparator((Character)value);
- } else if(MarshallerProperties.OBJECT_GRAPH.equals(key)) {
- if(value == null) {
- xmlMarshaller.setMarshalAttributeGroup(null);
- } else if(value instanceof ObjectGraphImpl) {
- xmlMarshaller.setMarshalAttributeGroup(((ObjectGraphImpl)value).getAttributeGroup());
- } else if(value.getClass() == ClassConstants.STRING){
- xmlMarshaller.setMarshalAttributeGroup(value);
- } else {
- throw org.eclipse.persistence.exceptions.JAXBException.invalidValueForObjectGraph(value);
- }
- } else if (MarshallerProperties.BEAN_VALIDATION_MODE.equals(key)) {
- if(value == null){
- throw new PropertyException(key, Constants.EMPTY_STRING);
- }
- this.beanValidationMode = ((BeanValidationMode) value);
- } else if (MarshallerProperties.BEAN_VALIDATION_FACTORY.equals(key)) {
- //noinspection StatementWithEmptyBody
+ if (value == null) {
+ xmlMarshaller.setCharacterEscapeHandler(null);
+ } else {
+ xmlMarshaller.setCharacterEscapeHandler(new CharacterEscapeHandlerWrapper(value));
+ }
+ } else if (XML_DECLARATION.equals(key)) {
+ if(value == null){
+ throw new PropertyException(key, Constants.EMPTY_STRING);
+ }
+ Boolean fragment = !(Boolean) value;
+ xmlMarshaller.setFragment(fragment.booleanValue());
+ } else if (XML_HEADERS.equals(key)) {
+ xmlMarshaller.setXmlHeader((String) value);
+ } else if (OBJECT_IDENTITY_CYCLE_DETECTION.equals(key)) {
+ if(value == null){
+ throw new PropertyException(key, Constants.EMPTY_STRING);
+ }
+ xmlMarshaller.setEqualUsingIdenity(((Boolean) value).booleanValue());
+ } else if (MarshallerProperties.MEDIA_TYPE.equals(key)) {
+ MediaType mType = null;
+ if(value instanceof MediaType) {
+ mType = (MediaType) value;
+ } else if(value instanceof String) {
+ mType = MediaType.getMediaType((String)value);
+ }
+ if(mType == null){
+ throw new PropertyException(key, Constants.EMPTY_STRING);
+ }
+ xmlMarshaller.setMediaType(mType);
+ } else if (MarshallerProperties.JSON_ATTRIBUTE_PREFIX.equals(key)) {
+ xmlMarshaller.setAttributePrefix((String)value);
+ } else if (MarshallerProperties.JSON_INCLUDE_ROOT.equals(key)) {
+ if(value == null){
+ throw new PropertyException(key, Constants.EMPTY_STRING);
+ }
+ xmlMarshaller.setIncludeRoot((Boolean)value);
+ } else if(MarshallerProperties.JSON_VALUE_WRAPPER.equals(key)){
+ if(value == null || (((String)value).length() == 0)){
+ throw new PropertyException(key, Constants.EMPTY_STRING);
+ }
+ xmlMarshaller.setValueWrapper((String)value);
+ } else if(MarshallerProperties.JSON_NAMESPACE_SEPARATOR.equals(key)){
+ if(value == null){
+ throw new PropertyException(key, Constants.EMPTY_STRING);
+ }
+ xmlMarshaller.setNamespaceSeparator((Character)value);
+ } else if(MarshallerProperties.OBJECT_GRAPH.equals(key)) {
if(value == null) {
- // Allow null value for preferred validation factory.
- }
- this.prefValidatorFactory = ((ValidatorFactory)value);
- } else if (MarshallerProperties.BEAN_VALIDATION_GROUPS.equals(key)) {
- if(value == null){
- throw new PropertyException(key, Constants.EMPTY_STRING);
- }
- this.beanValidationGroups = ((Class<?>[]) value);
- } else if (MarshallerProperties.BEAN_VALIDATION_NO_OPTIMISATION.equals(key)) {
- if(value == null){
- throw new PropertyException(key, Constants.EMPTY_STRING);
- }
- this.bvNoOptimisation = ((boolean) value);
- } else {
- throw new PropertyException(key, value);
- }
- } catch (ClassCastException exception) {
- throw new PropertyException(key, exception);
- }
- }
-
- public void setSchema(Schema schema) {
- this.xmlMarshaller.setSchema(schema);
- }
-
- private Map<String, Class> getClassToGeneratedClasses() {
- return jaxbContext.getClassToGeneratedClasses();
- }
-
- public JAXBContext getJaxbContext() {
- return jaxbContext;
- }
-
- public XMLMarshaller getXMLMarshaller() {
- return this.xmlMarshaller;
- }
-
- /**
- * Returns constraint violations stored in the underlying
- * {@link org.eclipse.persistence.jaxb.JAXBBeanValidator} instance.
- *
- * @return set of constraint violations from last unmarshal
- */
- public Set<ConstraintViolation<Object>> getConstraintViolations() {
- return beanValidator.getConstraintViolations();
- }
-
- private static class CharacterEscapeHandlerWrapper extends org.eclipse.persistence.internal.oxm.record.CharacterEscapeHandlerWrapper implements CharacterEscapeHandler {
-
- public CharacterEscapeHandlerWrapper(Object sunHandler) {
- super(sunHandler);
- }
-
- }
-}
+ xmlMarshaller.setMarshalAttributeGroup(null);
+ } else if(value instanceof ObjectGraphImpl) {
+ xmlMarshaller.setMarshalAttributeGroup(((ObjectGraphImpl)value).getAttributeGroup());
+ } else if(value.getClass() == ClassConstants.STRING){
+ xmlMarshaller.setMarshalAttributeGroup(value);
+ } else {
+ throw org.eclipse.persistence.exceptions.JAXBException.invalidValueForObjectGraph(value);
+ }
+ } else if (MarshallerProperties.BEAN_VALIDATION_MODE.equals(key)) {
+ if(value == null){
+ throw new PropertyException(key, Constants.EMPTY_STRING);
+ }
+ this.beanValidationMode = ((BeanValidationMode) value);
+ } else if (MarshallerProperties.BEAN_VALIDATION_FACTORY.equals(key)) {
+ //noinspection StatementWithEmptyBody
+ if(value == null) {
+ // Allow null value for preferred validation factory.
+ }
+ this.prefValidatorFactory = value;
+ } else if (MarshallerProperties.BEAN_VALIDATION_GROUPS.equals(key)) {
+ if(value == null){
+ throw new PropertyException(key, Constants.EMPTY_STRING);
+ }
+ this.beanValidationGroups = ((Class<?>[]) value);
+ } else if (MarshallerProperties.BEAN_VALIDATION_NO_OPTIMISATION.equals(key)) {
+ if(value == null){
+ throw new PropertyException(key, Constants.EMPTY_STRING);
+ }
+ this.bvNoOptimisation = ((boolean) value);
+ } else {
+ throw new PropertyException(key, value);
+ }
+ } catch (ClassCastException exception) {
+ throw new PropertyException(key, exception);
+ }
+ }
+
+ @Override
+ public void setSchema(Schema schema) {
+ this.xmlMarshaller.setSchema(schema);
+ }
+
+ private Map<String, Class> getClassToGeneratedClasses() {
+ return jaxbContext.getClassToGeneratedClasses();
+ }
+
+ public JAXBContext getJaxbContext() {
+ return jaxbContext;
+ }
+
+ public XMLMarshaller getXMLMarshaller() {
+ return this.xmlMarshaller;
+ }
+
+ /**
+ * Returns constraint violations stored in the underlying
+ * {@link org.eclipse.persistence.jaxb.JAXBBeanValidator} instance.
+ *
+ * @return set of constraint violations from last unmarshal
+ */
+ public Set<ConstraintViolationWrapper<Object>> getConstraintViolations() {
+ if (beanValidator != null) {
+ return beanValidator.getConstraintViolations();
+ }
+ return Collections.emptySet();
+ }
+
+ private static class CharacterEscapeHandlerWrapper extends org.eclipse.persistence.internal.oxm.record.CharacterEscapeHandlerWrapper implements CharacterEscapeHandler {
+
+ public CharacterEscapeHandlerWrapper(Object sunHandler) {
+ super(sunHandler);
+ }
+
+ }
+}
diff --git a/moxy/org.eclipse.persistence.moxy/src/org/eclipse/persistence/jaxb/JAXBUnmarshaller.java b/moxy/org.eclipse.persistence.moxy/src/org/eclipse/persistence/jaxb/JAXBUnmarshaller.java
index 9ab0a24..35ab727 100644
--- a/moxy/org.eclipse.persistence.moxy/src/org/eclipse/persistence/jaxb/JAXBUnmarshaller.java
+++ b/moxy/org.eclipse.persistence.moxy/src/org/eclipse/persistence/jaxb/JAXBUnmarshaller.java
@@ -21,6 +21,7 @@
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.net.URL;
+import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
@@ -28,8 +29,6 @@
import java.util.Set;
import java.util.StringTokenizer;
-import javax.validation.ConstraintViolation;
-import javax.validation.ValidatorFactory;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.PropertyException;
@@ -97,12 +96,14 @@
*/
public class JAXBUnmarshaller implements Unmarshaller {
- private final JAXBBeanValidator beanValidator;
+ private JAXBBeanValidator beanValidator;
private BeanValidationMode beanValidationMode;
- private ValidatorFactory prefValidatorFactory;
+
+ // The actual type is ValidatorFactory. It's done due to optional nature of javax.validation.
+ private Object prefValidatorFactory;
private boolean bvNoOptimisation = false;
- private Class<?>[] beanValidationGroups = JAXBBeanValidator.DEFAULT_GROUP_ARRAY;
+ private Class<?>[] beanValidationGroups;
private final XMLUnmarshaller xmlUnmarshaller;
private final JAXBContext jaxbContext;
@@ -118,7 +119,9 @@
this.jaxbContext = jaxbContext;
validationEventHandler = JAXBContext.DEFAULT_VALIDATION_EVENT_HANDLER;
beanValidationMode = BeanValidationMode.AUTO;
- beanValidator = JAXBBeanValidator.getUnmarshallingBeanValidator(this.jaxbContext);
+ if (BeanValidationChecker.isBeanValidationPresent()) {
+ beanValidator = JAXBBeanValidator.getUnmarshallingBeanValidator(this.jaxbContext);
+ }
xmlUnmarshaller = newXMLUnmarshaller;
xmlUnmarshaller.setValidationMode(XMLUnmarshaller.NONVALIDATING);
xmlUnmarshaller.setUnmarshalListener(new JAXBUnmarshalListener(this));
@@ -236,7 +239,7 @@
}
private JAXBElement validateAndBuildJAXBElement(Object obj, Class declaredClass) throws BeanValidationException {
- if (beanValidator.shouldValidate(obj, beanValidationMode, prefValidatorFactory, bvNoOptimisation)) {
+ if (beanValidator != null && beanValidator.shouldValidate(obj, beanValidationMode, prefValidatorFactory, bvNoOptimisation)) {
beanValidator.validate(obj, beanValidationGroups);
}
return buildJAXBElementFromObject(obj, declaredClass);
@@ -884,10 +887,8 @@
}
this.beanValidationMode = ((BeanValidationMode) value);
} else if (UnmarshallerProperties.BEAN_VALIDATION_FACTORY.equals(key)) {
- if(value == null){
- // Allow null value for preferred validation factory.
- }
- this.prefValidatorFactory = ((ValidatorFactory)value);
+ // Null value is allowed
+ this.prefValidatorFactory = value;
} else if (UnmarshallerProperties.BEAN_VALIDATION_GROUPS.equals(key)) {
if (value == null) {
throw new PropertyException(key, Constants.EMPTY_STRING);
@@ -1054,7 +1055,7 @@
}
private Object validateAndTransformIfRequired(Object obj) throws BeanValidationException {
- if (beanValidator.shouldValidate(obj, beanValidationMode, prefValidatorFactory, bvNoOptimisation)) {
+ if (beanValidator != null && beanValidator.shouldValidate(obj, beanValidationMode, prefValidatorFactory, bvNoOptimisation)) {
beanValidator.validate(obj, beanValidationGroups);
}
return createJAXBElementOrUnwrapIfRequired(obj);
@@ -1138,8 +1139,11 @@
*
* @return set of constraint violations from last unmarshal
*/
- public Set<? extends ConstraintViolation<?>> getConstraintViolations() {
- return beanValidator.getConstraintViolations();
+ public Set<ConstraintViolationWrapper<Object>> getConstraintViolations() {
+ if (beanValidator != null) {
+ return beanValidator.getConstraintViolations();
+ }
+ return Collections.emptySet();
}
private static class PrimitiveContentHandler<T> extends DefaultHandler {
diff --git a/plugins/javax.validation_1.1.0.v201304101302.jar b/plugins/javax.validation_1.1.0.v201304101302.jar
index 8414119..aca36fa 100644
--- a/plugins/javax.validation_1.1.0.v201304101302.jar
+++ b/plugins/javax.validation_1.1.0.v201304101302.jar
Binary files differ