diff --git a/camel-core/src/main/java/org/apache/camel/builder/DataFormatClause.java b/camel-core/src/main/java/org/apache/camel/builder/DataFormatClause.java index f839d5897d2e4..b706602ce29c4 100644 --- a/camel-core/src/main/java/org/apache/camel/builder/DataFormatClause.java +++ b/camel-core/src/main/java/org/apache/camel/builder/DataFormatClause.java @@ -16,11 +16,10 @@ */ package org.apache.camel.builder; +import java.nio.charset.Charset; import java.util.Map; import java.util.zip.Deflater; -import org.w3c.dom.Node; - import org.apache.camel.model.DataFormatDefinition; import org.apache.camel.model.ProcessorDefinition; import org.apache.camel.model.dataformat.AvroDataFormat; @@ -52,7 +51,9 @@ import org.apache.camel.model.dataformat.XmlJsonDataFormat; import org.apache.camel.model.dataformat.ZipDataFormat; import org.apache.camel.model.dataformat.ZipFileDataFormat; +import org.apache.camel.util.CollectionStringBuffer; import org.apache.camel.util.jsse.KeyStoreParameters; +import org.w3c.dom.Node; /** * An expression for constructing the different possible {@link org.apache.camel.spi.DataFormat} @@ -531,17 +532,60 @@ public T tidyMarkup() { } /** - * Uses the XStream data format + * Uses the XStream data format. + *

+ * Favor using {@link #xstream(String)} to pass in a permission */ public T xstream() { return dataFormat(new XStreamDataFormat()); } + /** + * Uses the xstream by setting the encoding or permission + * + * @param encodingOrPermission is either an encoding or permission syntax + */ + public T xstream(String encodingOrPermission) { + // is it an encoding? if not we assume its a permission + if (Charset.isSupported(encodingOrPermission)) { + return xstream(encodingOrPermission, (String) null); + } else { + return xstream(null, encodingOrPermission); + } + } + /** * Uses the xstream by setting the encoding */ - public T xstream(String encoding) { - return dataFormat(new XStreamDataFormat(encoding)); + public T xstream(String encoding, String permission) { + XStreamDataFormat xdf = new XStreamDataFormat(); + xdf.setPermissions(permission); + xdf.setEncoding(encoding); + return dataFormat(xdf); + } + + /** + * Uses the xstream by permitting the java type + * + * @param type the pojo xstream should use as allowed permission + */ + public T xstream(Class type) { + return xstream(null, type); + } + + /** + * Uses the xstream by permitting the java type + * + * @param encoding encoding to use + * @param type the pojo class(es) xstream should use as allowed permission + */ + public T xstream(String encoding, Class... type) { + CollectionStringBuffer csb = new CollectionStringBuffer(","); + for (Class clazz : type) { + csb.append("+"); + csb.append(clazz.getName()); + } + return xstream(encoding, csb.toString()); } /** diff --git a/camel-core/src/main/java/org/apache/camel/model/dataformat/JsonDataFormat.java b/camel-core/src/main/java/org/apache/camel/model/dataformat/JsonDataFormat.java index 3aceb18fd0134..0d03b6da66455 100644 --- a/camel-core/src/main/java/org/apache/camel/model/dataformat/JsonDataFormat.java +++ b/camel-core/src/main/java/org/apache/camel/model/dataformat/JsonDataFormat.java @@ -27,6 +27,7 @@ import org.apache.camel.spi.DataFormat; import org.apache.camel.spi.Metadata; import org.apache.camel.spi.RouteContext; +import org.apache.camel.util.CollectionStringBuffer; import org.apache.camel.util.ObjectHelper; /** @@ -68,6 +69,8 @@ public class JsonDataFormat extends DataFormatDefinition { private String enableFeatures; @XmlAttribute private String disableFeatures; + @XmlAttribute + private String permissions; public JsonDataFormat() { super("json"); @@ -253,6 +256,42 @@ public void setDisableFeatures(String disableFeatures) { this.disableFeatures = disableFeatures; } + public String getPermissions() { + return permissions; + } + + /** + * Adds permissions that controls which Java packages and classes XStream is allowed to use during + * unmarshal from xml/json to Java beans. + *

+ * A permission must be configured either here or globally using a JVM system property. The permission + * can be specified in a syntax where a plus sign is allow, and minus sign is deny. + *
+ * Wildcards is supported by using .* as prefix. For example to allow com.foo and all subpackages + * then specfy +com.foo.*. Multiple permissions can be configured separated by comma, such as + * +com.foo.*,-com.foo.bar.MySecretBean. + *
+ * The following default permission is always included: "-*,java.lang.*,java.util.*" unless + * its overridden by specifying a JVM system property with they key org.apache.camel.xstream.permissions. + */ + public void setPermissions(String permissions) { + this.permissions = permissions; + } + + /** + * To add permission for the given pojo classes. + * @param type the pojo class(es) xstream should use as allowed permission + * @see #setPermissions(String) + */ + public void setPermissions(Class... type) { + CollectionStringBuffer csb = new CollectionStringBuffer(","); + for (Class clazz : type) { + csb.append("+"); + csb.append(clazz.getName()); + } + setPermissions(csb.toString()); + } + @Override public String getDataFormatName() { // json data format is special as the name can be from different bundles @@ -325,6 +364,14 @@ protected void configureDataFormat(DataFormat dataFormat, CamelContext camelCont if (disableFeatures != null) { setProperty(camelContext, dataFormat, "disableFeatures", disableFeatures); } + if (permissions != null) { + setProperty(camelContext, dataFormat, "permissions", permissions); + } + // if we have the unmarshal type, but no permission set, then use it to be allowed + if (permissions == null && unmarshalType != null) { + String allow = "+" + unmarshalType.getName(); + setProperty(camelContext, dataFormat, "permissions", allow); + } } } diff --git a/camel-core/src/main/java/org/apache/camel/model/dataformat/XStreamDataFormat.java b/camel-core/src/main/java/org/apache/camel/model/dataformat/XStreamDataFormat.java index e89bc7bfadcbd..dd9d966742963 100644 --- a/camel-core/src/main/java/org/apache/camel/model/dataformat/XStreamDataFormat.java +++ b/camel-core/src/main/java/org/apache/camel/model/dataformat/XStreamDataFormat.java @@ -38,6 +38,7 @@ import org.apache.camel.spi.Metadata; import org.apache.camel.spi.RouteContext; import org.apache.camel.util.CamelContextHelper; +import org.apache.camel.util.CollectionStringBuffer; import org.apache.camel.util.ObjectHelper; /** @@ -49,6 +50,8 @@ @XmlRootElement(name = "xstream") @XmlAccessorType(XmlAccessType.NONE) public class XStreamDataFormat extends DataFormatDefinition { + @XmlAttribute + private String permissions; @XmlAttribute private String encoding; @XmlAttribute @@ -57,9 +60,7 @@ public class XStreamDataFormat extends DataFormatDefinition { private String driverRef; @XmlAttribute private String mode; - @XmlAttribute - private String permissions; - + @XmlJavaTypeAdapter(ConvertersAdapter.class) @XmlElement(name = "converters") private List converters; @@ -187,12 +188,37 @@ public String getPermissions() { } /** - * Adds permissionsList + * Adds permissions that controls which Java packages and classes XStream is allowed to use during + * unmarshal from xml/json to Java beans. + *

+ * A permission must be configured either here or globally using a JVM system property. The permission + * can be specified in a syntax where a plus sign is allow, and minus sign is deny. + *
+ * Wildcards is supported by using .* as prefix. For example to allow com.foo and all subpackages + * then specfy +com.foo.*. Multiple permissions can be configured separated by comma, such as + * +com.foo.*,-com.foo.bar.MySecretBean. + *
+ * The following default permission is always included: "-*,java.lang.*,java.util.*" unless + * its overridden by specifying a JVM system property with they key org.apache.camel.xstream.permissions. */ public void setPermissions(String permissions) { this.permissions = permissions; } + /** + * To add permission for the given pojo classes. + * @param type the pojo class(es) xstream should use as allowed permission + * @see #setPermissions(String) + */ + public void setPermissions(Class... type) { + CollectionStringBuffer csb = new CollectionStringBuffer(","); + for (Class clazz : type) { + csb.append("+"); + csb.append(clazz.getName()); + } + setPermissions(csb.toString()); + } + @Override protected DataFormat createDataFormat(RouteContext routeContext) { if ("json".equals(this.driver)) { @@ -208,6 +234,9 @@ protected DataFormat createDataFormat(RouteContext routeContext) { @Override protected void configureDataFormat(DataFormat dataFormat, CamelContext camelContext) { + if (this.permissions != null) { + setProperty(camelContext, dataFormat, "permissions", this.permissions); + } if (encoding != null) { setProperty(camelContext, dataFormat, "encoding", encoding); } @@ -223,9 +252,6 @@ protected void configureDataFormat(DataFormat dataFormat, CamelContext camelCont if (this.implicitCollections != null) { setProperty(camelContext, dataFormat, "implicitCollections", this.implicitCollections); } - if (this.permissions != null) { - setProperty(camelContext, dataFormat, "permissions", this.permissions); - } if (this.mode != null) { setProperty(camelContext, dataFormat, "mode", mode); } diff --git a/components/camel-xstream/src/test/java/org/apache/camel/dataformat/xstream/MarshalDomainObjectJSONTest.java b/components/camel-xstream/src/test/java/org/apache/camel/dataformat/xstream/MarshalDomainObjectJSONTest.java index 3c5da940efe27..752a9f6e3500d 100644 --- a/components/camel-xstream/src/test/java/org/apache/camel/dataformat/xstream/MarshalDomainObjectJSONTest.java +++ b/components/camel-xstream/src/test/java/org/apache/camel/dataformat/xstream/MarshalDomainObjectJSONTest.java @@ -17,6 +17,7 @@ package org.apache.camel.dataformat.xstream; import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.model.dataformat.JsonLibrary; public class MarshalDomainObjectJSONTest extends MarshalDomainObjectTest { @@ -28,7 +29,10 @@ public void configure() throws Exception { // just used for helping to marhsal from("direct:marshal").marshal().json(); - from("direct:reverse").unmarshal().json().to("mock:reverse"); + from("direct:reverse").unmarshal().json(JsonLibrary.XStream, PurchaseOrder.class).to("mock:reverse"); + + from("direct:inPretty").marshal().json(true); + from("direct:backPretty").unmarshal().json(JsonLibrary.XStream, PurchaseOrder.class, true).to("mock:reverse"); } }; } diff --git a/components/camel-xstream/src/test/java/org/apache/camel/dataformat/xstream/MarshalDomainObjectTest.java b/components/camel-xstream/src/test/java/org/apache/camel/dataformat/xstream/MarshalDomainObjectTest.java index 63bc5344a531f..53bebb6cf4869 100644 --- a/components/camel-xstream/src/test/java/org/apache/camel/dataformat/xstream/MarshalDomainObjectTest.java +++ b/components/camel-xstream/src/test/java/org/apache/camel/dataformat/xstream/MarshalDomainObjectTest.java @@ -19,8 +19,6 @@ import org.apache.camel.builder.RouteBuilder; import org.apache.camel.component.mock.MockEndpoint; import org.apache.camel.test.junit4.CamelTestSupport; -import org.junit.AfterClass; -import org.junit.BeforeClass; import org.junit.Test; /** @@ -28,16 +26,6 @@ */ public class MarshalDomainObjectTest extends CamelTestSupport { - @BeforeClass - public static void setup() { - XStreamTestUtils.setPermissionSystemProperty(""); - } - - @AfterClass - public static void cleanup() { - XStreamTestUtils.revertPermissionSystemProperty(); - } - @Test public void testMarshalDomainObject() throws Exception { MockEndpoint mock = getMockEndpoint("mock:result"); @@ -96,12 +84,12 @@ public void testMarshalAndUnmarshal() throws Exception { protected RouteBuilder createRouteBuilder() throws Exception { return new RouteBuilder() { public void configure() throws Exception { - from("direct:in").marshal().xstream().to("mock:result"); + from("direct:in").marshal().xstream(PurchaseOrder.class).to("mock:result"); // just used for helping to marshal - from("direct:marshal").marshal().xstream("UTF-8"); + from("direct:marshal").marshal().xstream("UTF-8", PurchaseOrder.class); - from("direct:reverse").unmarshal().xstream("UTF-8").to("mock:reverse"); + from("direct:reverse").unmarshal().xstream("UTF-8", PurchaseOrder.class).to("mock:reverse"); } }; } diff --git a/components/camel-xstream/src/test/java/org/apache/camel/dataformat/xstream/UnmarshalThenMarshalJSONTest.java b/components/camel-xstream/src/test/java/org/apache/camel/dataformat/xstream/UnmarshalThenMarshalJSONTest.java index 53ad1e6d78839..1dd9d129499f9 100644 --- a/components/camel-xstream/src/test/java/org/apache/camel/dataformat/xstream/UnmarshalThenMarshalJSONTest.java +++ b/components/camel-xstream/src/test/java/org/apache/camel/dataformat/xstream/UnmarshalThenMarshalJSONTest.java @@ -19,19 +19,20 @@ import org.apache.camel.Exchange; import org.apache.camel.Processor; import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.model.dataformat.JsonLibrary; public class UnmarshalThenMarshalJSONTest extends UnmarshalThenMarshalTest { protected RouteBuilder createRouteBuilder() { return new RouteBuilder() { public void configure() { from("direct:start"). - marshal().json(). + marshal().json(JsonLibrary.XStream, PurchaseOrder.class). process(new Processor() { public void process(Exchange exchange) throws Exception { log.debug("marshalled: " + exchange.getIn().getBody(String.class)); } }). - unmarshal().json(). + unmarshal().json(JsonLibrary.XStream, PurchaseOrder.class). to("mock:result"); } }; diff --git a/components/camel-xstream/src/test/java/org/apache/camel/dataformat/xstream/UnmarshalThenMarshalTest.java b/components/camel-xstream/src/test/java/org/apache/camel/dataformat/xstream/UnmarshalThenMarshalTest.java index 6e936a50f7645..a5e26bb1e7ce4 100644 --- a/components/camel-xstream/src/test/java/org/apache/camel/dataformat/xstream/UnmarshalThenMarshalTest.java +++ b/components/camel-xstream/src/test/java/org/apache/camel/dataformat/xstream/UnmarshalThenMarshalTest.java @@ -23,8 +23,6 @@ import org.apache.camel.builder.RouteBuilder; import org.apache.camel.component.mock.MockEndpoint; import org.apache.camel.test.junit4.CamelTestSupport; -import org.junit.AfterClass; -import org.junit.BeforeClass; import org.junit.Test; /** @@ -32,16 +30,6 @@ */ public class UnmarshalThenMarshalTest extends CamelTestSupport { - @BeforeClass - public static void setup() { - XStreamTestUtils.setPermissionSystemProperty(""); - } - - @AfterClass - public static void cleanup() { - XStreamTestUtils.revertPermissionSystemProperty(); - } - @Test public void testSendXmlAndUnmarshal() throws Exception { @@ -69,13 +57,13 @@ protected RouteBuilder createRouteBuilder() { return new RouteBuilder() { public void configure() { from("direct:start"). - marshal().xstream(). + marshal().xstream(PurchaseOrder.class). process(new Processor() { public void process(Exchange exchange) throws Exception { log.debug("marshalled: " + exchange.getIn().getBody(String.class)); } }). - unmarshal().xstream(). + unmarshal().xstream(PurchaseOrder.class). to("mock:result"); } }; diff --git a/components/camel-xstream/src/test/java/org/apache/camel/dataformat/xstream/XStreamConcurrencyTest.java b/components/camel-xstream/src/test/java/org/apache/camel/dataformat/xstream/XStreamConcurrencyTest.java index b0e6aa229c636..1f086266c66b3 100644 --- a/components/camel-xstream/src/test/java/org/apache/camel/dataformat/xstream/XStreamConcurrencyTest.java +++ b/components/camel-xstream/src/test/java/org/apache/camel/dataformat/xstream/XStreamConcurrencyTest.java @@ -22,8 +22,6 @@ import org.apache.camel.builder.RouteBuilder; import org.apache.camel.test.junit4.CamelTestSupport; -import org.junit.AfterClass; -import org.junit.BeforeClass; import org.junit.Test; /** @@ -31,16 +29,6 @@ */ public class XStreamConcurrencyTest extends CamelTestSupport { - @BeforeClass - public static void setup() { - XStreamTestUtils.setPermissionSystemProperty(""); - } - - @AfterClass - public static void cleanup() { - XStreamTestUtils.revertPermissionSystemProperty(); - } - @Test public void testNoConcurrentProducers() throws Exception { doSendMessages(1, 1); @@ -79,11 +67,11 @@ protected RouteBuilder createRouteBuilder() { return new RouteBuilder() { public void configure() { from("direct:start"). - marshal().xstream(). + marshal().xstream(PurchaseOrder.class). to("direct:marshalled"); from("direct:marshalled"). - unmarshal().xstream(). + unmarshal().xstream(PurchaseOrder.class). to("mock:result"); } }; diff --git a/components/camel-xstream/src/test/java/org/apache/camel/dataformat/xstream/XStreamConfigurationTest.java b/components/camel-xstream/src/test/java/org/apache/camel/dataformat/xstream/XStreamConfigurationTest.java index b411abeeeae5b..5fc8858135431 100644 --- a/components/camel-xstream/src/test/java/org/apache/camel/dataformat/xstream/XStreamConfigurationTest.java +++ b/components/camel-xstream/src/test/java/org/apache/camel/dataformat/xstream/XStreamConfigurationTest.java @@ -28,13 +28,10 @@ import com.thoughtworks.xstream.io.HierarchicalStreamReader; import com.thoughtworks.xstream.io.HierarchicalStreamWriter; import com.thoughtworks.xstream.io.json.JsonHierarchicalStreamDriver; - import org.apache.camel.builder.RouteBuilder; import org.apache.camel.component.mock.MockEndpoint; import org.apache.camel.model.dataformat.XStreamDataFormat; import org.apache.camel.test.junit4.CamelTestSupport; -import org.junit.AfterClass; -import org.junit.BeforeClass; import org.junit.Test; /** @@ -45,16 +42,6 @@ public class XStreamConfigurationTest extends CamelTestSupport { private static volatile boolean constructorInjected; private static volatile boolean methodInjected; - @BeforeClass - public static void setup() { - XStreamTestUtils.setPermissionSystemProperty(""); - } - - @AfterClass - public static void cleanup() { - XStreamTestUtils.revertPermissionSystemProperty(); - } - @Override public void setUp() throws Exception { super.setUp(); @@ -152,6 +139,7 @@ public void configure() throws Exception { Map aliases = new HashMap(); aliases.put("purchase-order", PurchaseOrder.class.getName()); xstreamDefinition.setAliases(aliases); + xstreamDefinition.setPermissions(PurchaseOrder.class, PurchaseHistory.class); List converters = new ArrayList(); converters.add(PurchaseOrderConverter.class.getName()); @@ -172,6 +160,7 @@ public void configure() throws Exception { aliases = new HashMap(); aliases.put("purchase-order", PurchaseOrder.class.getName()); xstreamDefinition.setAliases(aliases); + xstreamDefinition.setPermissions(PurchaseOrder.class, PurchaseHistory.class); converters = new ArrayList(); converters.add(PurchaseOrderConverter.class.getName()); @@ -182,6 +171,8 @@ public void configure() throws Exception { org.apache.camel.dataformat.xstream.XStreamDataFormat xStreamDataFormat = new org.apache.camel.dataformat.xstream.XStreamDataFormat(); xStreamDataFormat.setXstreamDriver(new JsonHierarchicalStreamDriver()); + xStreamDataFormat.setPermissions("+6org.apache.camel.dataformat.xstream.*"); + from("direct:myDriver").marshal(xStreamDataFormat).to("mock:result"); } }; diff --git a/components/camel-xstream/src/test/java/org/apache/camel/dataformat/xstream/XStreamTestUtils.java b/components/camel-xstream/src/test/java/org/apache/camel/dataformat/xstream/XStreamTestUtils.java index ff6cf35e57052..7601f43c4f25b 100644 --- a/components/camel-xstream/src/test/java/org/apache/camel/dataformat/xstream/XStreamTestUtils.java +++ b/components/camel-xstream/src/test/java/org/apache/camel/dataformat/xstream/XStreamTestUtils.java @@ -14,7 +14,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.apache.camel.dataformat.xstream; /** diff --git a/components/camel-xstream/src/test/resources/log4j.properties b/components/camel-xstream/src/test/resources/log4j.properties index 034f615180e8c..af8bba9396e96 100644 --- a/components/camel-xstream/src/test/resources/log4j.properties +++ b/components/camel-xstream/src/test/resources/log4j.properties @@ -20,7 +20,7 @@ # log4j.rootLogger=INFO, out -log4j.logger.org.apache.activemq.spring=WARN +#log4j.logger.org.apache.camel=DEBUG # CONSOLE appender not used by default log4j.appender.stdout=org.apache.log4j.ConsoleAppender @@ -34,4 +34,3 @@ log4j.appender.out.layout.ConversionPattern=%d [%-15.15t] %-5p %-30.30c{1} - %m% log4j.appender.out.file=target/camel-xstream-test.log log4j.appender.out.append=true -log4j.logger.org.apache.camel=DEBUG diff --git a/components/camel-xstream/src/test/resources/org/apache/camel/dataformat/xstream/SpringMarshalDomainObjectJSONTest.xml b/components/camel-xstream/src/test/resources/org/apache/camel/dataformat/xstream/SpringMarshalDomainObjectJSONTest.xml index 0e9f7e43b1a47..4a4765ced7c0c 100644 --- a/components/camel-xstream/src/test/resources/org/apache/camel/dataformat/xstream/SpringMarshalDomainObjectJSONTest.xml +++ b/components/camel-xstream/src/test/resources/org/apache/camel/dataformat/xstream/SpringMarshalDomainObjectJSONTest.xml @@ -27,7 +27,8 @@ - + + diff --git a/components/camel-xstream/src/test/resources/org/apache/camel/dataformat/xstream/SpringMarshalListTest.xml b/components/camel-xstream/src/test/resources/org/apache/camel/dataformat/xstream/SpringMarshalListTest.xml index 412f0e0d43a14..d04a881baea49 100644 --- a/components/camel-xstream/src/test/resources/org/apache/camel/dataformat/xstream/SpringMarshalListTest.xml +++ b/components/camel-xstream/src/test/resources/org/apache/camel/dataformat/xstream/SpringMarshalListTest.xml @@ -27,8 +27,8 @@ - - + + diff --git a/components/camel-xstream/src/test/resources/org/apache/camel/dataformat/xstream/SpringMarshalOmitFieldsTest.xml b/components/camel-xstream/src/test/resources/org/apache/camel/dataformat/xstream/SpringMarshalOmitFieldsTest.xml index f0a18809a0e47..a085de01813e0 100644 --- a/components/camel-xstream/src/test/resources/org/apache/camel/dataformat/xstream/SpringMarshalOmitFieldsTest.xml +++ b/components/camel-xstream/src/test/resources/org/apache/camel/dataformat/xstream/SpringMarshalOmitFieldsTest.xml @@ -26,7 +26,7 @@ - + diff --git a/components/camel-xstream/src/test/resources/org/apache/camel/dataformat/xstream/SpringXStreamConfigurationTest.xml b/components/camel-xstream/src/test/resources/org/apache/camel/dataformat/xstream/SpringXStreamConfigurationTest.xml index 97a5e80f9cff9..3b9deb8c99d37 100644 --- a/components/camel-xstream/src/test/resources/org/apache/camel/dataformat/xstream/SpringXStreamConfigurationTest.xml +++ b/components/camel-xstream/src/test/resources/org/apache/camel/dataformat/xstream/SpringXStreamConfigurationTest.xml @@ -44,7 +44,7 @@ - + @@ -58,7 +58,7 @@ - +