You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by da...@apache.org on 2015/07/04 09:28:43 UTC

[1/3] isis git commit: ISIS-1167: new NullPrintStream unittestsupport class

Repository: isis
Updated Branches:
  refs/heads/master c7280dc40 -> faf5c6656


ISIS-1167: new NullPrintStream unittestsupport class


Project: http://git-wip-us.apache.org/repos/asf/isis/repo
Commit: http://git-wip-us.apache.org/repos/asf/isis/commit/10462c99
Tree: http://git-wip-us.apache.org/repos/asf/isis/tree/10462c99
Diff: http://git-wip-us.apache.org/repos/asf/isis/diff/10462c99

Branch: refs/heads/master
Commit: 10462c99fedbdcdc2d89c75a6e72dc12af9c9e19
Parents: c7280dc
Author: Dan Haywood <da...@haywood-associates.co.uk>
Authored: Fri Jul 3 11:05:26 2015 +0100
Committer: Dan Haywood <da...@haywood-associates.co.uk>
Committed: Fri Jul 3 11:05:26 2015 +0100

----------------------------------------------------------------------
 .../streams/NullPrintStream.java                | 113 +++++++++++++++++++
 1 file changed, 113 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/isis/blob/10462c99/core/unittestsupport/src/main/java/org/apache/isis/core/unittestsupport/streams/NullPrintStream.java
----------------------------------------------------------------------
diff --git a/core/unittestsupport/src/main/java/org/apache/isis/core/unittestsupport/streams/NullPrintStream.java b/core/unittestsupport/src/main/java/org/apache/isis/core/unittestsupport/streams/NullPrintStream.java
new file mode 100644
index 0000000..971bfe0
--- /dev/null
+++ b/core/unittestsupport/src/main/java/org/apache/isis/core/unittestsupport/streams/NullPrintStream.java
@@ -0,0 +1,113 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.isis.core.unittestsupport.streams;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.util.concurrent.Callable;
+
+public class NullPrintStream extends PrintStream {
+    public NullPrintStream() {
+        super(new NullByteArrayOutputStream());
+    }
+
+    private static class NullByteArrayOutputStream extends ByteArrayOutputStream {
+        @Override
+        public void write(int b) {
+            // do nothing
+        }
+
+        @Override
+        public void write(byte[] b, int off, int len) {
+            // do nothing
+        }
+
+        @Override
+        public void writeTo(OutputStream out) throws IOException {
+            // do nothing
+        }
+    }
+
+    public static void suppressingStdout(Runnable r)  {
+        suppressing(r, true, false);
+    }
+
+    public static <T> T suppressingStdout(Callable<T> c) throws Exception {
+        return suppressing(c, true, false);
+    }
+
+    public static void suppressingStderr(Runnable r) {
+        suppressing(r, false, true);
+    }
+
+    public static <T> T suppressingStderr(Callable<T> c) throws Exception {
+        return suppressing(c, false, true);
+    }
+
+    public static void suppressing(Runnable r) throws Exception {
+        suppressing(r, true, true);
+    }
+
+    public static <T> T suppressing(Callable<T> c) throws Exception {
+        return suppressing(c, true, true);
+    }
+
+    private static void suppressing(Runnable r, boolean suppressStdout, boolean suppressStderr) {
+        PrintStream stdout = System.out;
+        PrintStream stderr = System.err;
+        try {
+            if (suppressStdout) {
+                System.setOut(new NullPrintStream());
+            }
+            if (suppressStderr) {
+                System.setErr(new NullPrintStream());
+            }
+            r.run();
+        } finally {
+            if (suppressStdout) {
+                System.setOut(stdout);
+            }
+            if (suppressStdout) {
+                System.setErr(stderr);
+            }
+        }
+    }
+
+    private static <T> T suppressing(Callable<T> c, boolean suppressStdout, boolean suppressStderr) throws Exception {
+        PrintStream stdout = System.out;
+        PrintStream stderr = System.err;
+        try {
+            if (suppressStdout) {
+                System.setOut(new NullPrintStream());
+            }
+            if (suppressStderr) {
+                System.setErr(new NullPrintStream());
+            }
+            return c.call();
+        } finally {
+            if (suppressStdout) {
+                System.setOut(stdout);
+            }
+            if (suppressStdout) {
+                System.setErr(stderr);
+            }
+        }
+    }
+
+}


[3/3] isis git commit: ISIS-1166: generalized SoapEndpointPublishingRule to host mulitple SOAP endpoints

Posted by da...@apache.org.
ISIS-1166: generalized SoapEndpointPublishingRule to host mulitple SOAP endpoints


Project: http://git-wip-us.apache.org/repos/asf/isis/repo
Commit: http://git-wip-us.apache.org/repos/asf/isis/commit/faf5c665
Tree: http://git-wip-us.apache.org/repos/asf/isis/tree/faf5c665
Diff: http://git-wip-us.apache.org/repos/asf/isis/diff/faf5c665

Branch: refs/heads/master
Commit: faf5c6656483d052ac1a49ee4939fc9ddf97ca46
Parents: 5e89a11
Author: Dan Haywood <da...@haywood-associates.co.uk>
Authored: Sat Jul 4 08:10:34 2015 +0100
Committer: Dan Haywood <da...@haywood-associates.co.uk>
Committed: Sat Jul 4 08:27:18 2015 +0100

----------------------------------------------------------------------
 ...est-support_soap-fake-server-junit-rule.adoc | 109 +++++++++++--------
 .../soap/SoapEndpointPublishingRule.java        | 100 ++++++++++++++---
 2 files changed, 149 insertions(+), 60 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/isis/blob/faf5c665/adocs/documentation/src/main/asciidoc/guides/_ug_testing_unit-test-support_soap-fake-server-junit-rule.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_ug_testing_unit-test-support_soap-fake-server-junit-rule.adoc b/adocs/documentation/src/main/asciidoc/guides/_ug_testing_unit-test-support_soap-fake-server-junit-rule.adoc
index 6dad06b..3d1f314 100644
--- a/adocs/documentation/src/main/asciidoc/guides/_ug_testing_unit-test-support_soap-fake-server-junit-rule.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/_ug_testing_unit-test-support_soap-fake-server-junit-rule.adoc
@@ -1,5 +1,5 @@
 [[_ug_testing_unit-test-support_soap-fake-server-junit-rule]]
-= SOAP Fake Servers
+= SOAP Fake Endpoints
 :Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR  CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
 :_basedir: ../
 :_imagesdir: images/
@@ -20,90 +20,111 @@ The (non-ASF) http://github.com/isisaddons/isis-module-publishmq[Isis addons' pu
 
 == `SoapEndpointPublishingRule`
 
-The idea behing this rule is that you write a fake server that implements the same WSDL contract as the "real" external system does, but which also exposes additional API to specify responses (or throw exceptions) from SOAP calls.  It also typically records the requests and allows these to be queried.
+The idea behind this rule is that you write a fake server endpoint that implements the same WSDL contract as the "real" external system does, but which also exposes additional API to specify responses (or throw exceptions) from SOAP calls.  It also typically records the requests and allows these to be queried.
 
-In its setup your unit test instantiates the fake server, and gets the rule to host that fake server on an SOAP endpoint.  It also instantiates the SOAP client, pointing it at the endpoint address (that is, a URL) that the fake server is runnig on.
+In its setup your unit test and gets the rule to instantiate and publish that fake server endpoint, and then obtains a reference to that server endpoint.  It also instantiates the SOAP client, pointing it at the address (that is, a URL) that the fake server endpoint is running on.  This way the unit test has control of both the SOAP client and server: the software under test and its collaborator.
 
 In the test methods your unit test sets up expectations on your fake server, and then exercises the SOAP client.  The SOAP client calls the fake server, which then responds accordingly.  The test can then assert that all expected interactions have occurred.
 
-So that tests don't take too long to run, the rule puts the server onto a thread-local.  Therefore the unit tests should clear up any state on the fake server.
+So that tests don't take too long to run, the rule puts the fake server endpoints onto a thread-local.  Therefore the unit tests should clear up any state on the fake server endpoints.
 
-The easiest way to use the rule is to subclass it for your particular fake server, eg:
+The easiest way to use the rule is to subclass it, eg:
 
 [source,java]
 ----
-public class ExternalSystemFakeServerRule
-        extends SoapEndpointPublishingRule<ExternalSystemFakeServer> {  <1>
-    public ExternalSystemFakeServerRule() {
-        this(54345);                                                    <2>
-    }
-    public ExternalSystemFakeServerRule(final int port) {
+public class FakeExternalSystemEndpointRule extends SoapEndpointPublishingRule {
+    public FakeExternalSystemEndpointRule() {
         super(
-            buildAddress(port),                                         <3>
-            () -> new ExternalSystemFakeServer());                      <4>
-    }
-    protected static String buildAddress(final int port) {
-        return String.format("http://localhost:%d/any/old/string/will/work", port);
+            FakeExternalSystemEndpoint.class,                   // <1>
+            "http://localhost:54345/any/old/string/will/work",  // <2>
+            );
     }
 }
 ----
-<1> generic type specifies the class that implements the endpoint
-<2> hardcoded port (or could choose one at random from within a range)
-<3> build an address based on the port
-<4> provide a `Supplier` that will instantiate the fake server
+<1> specify the class that implements the endpoint (must have a no-arg constructor)
+<2> provide an address to host the endpoint.  The port can be hard-coded, as shown, or (probably better) could choose one at random from within a range
 
 
 Your unit test should then look something like:
 
 [source,java]
 ----
-public class ExternalSystemFakeServerRuleTest {
+public class FakeExternalSystemEndpointRuleTest {
     @Rule
-    public ExternalSystemFakeServerRule serverRule = new ExternalSystemFakeServerRule();
-    private ExternalSystemFakeServer externalSystemFakeServer;
+    public FakeExternalSystemEndpointRule serverRule = new FakeExternalSystemEndpointRule();
+    private FakeExternalSystemEndpoint fakeServerEndpoint;
     private DemoObject externalSystemContract;                                      // <1>
     @Before
     public void setUp() throws Exception {
-        final DemoObjectService externalSystemService =                             // <2>
-                new DemoObjectService(ExternalSystemWsdl.getWsdl());                // <3>
+        fakeServerEndpoint =
+            serverRule.getEndpointImplementor(ExternalSystemFakeServer.class);      // <2>
+        final String endpointAddress =
+            serverRule.getEndpointAddress(ExternalSystemFakeServer.class);          // <3>
+        final DemoObjectService externalSystemService =                             // <4>
+                new DemoObjectService(ExternalSystemWsdl.getWsdl());                // <5>
         externalSystemContract = externalSystemService.getDemoObjectOverSOAP();
         BindingProvider provider = (BindingProvider) externalSystemContract;
         provider.getRequestContext().put(
                 BindingProvider.ENDPOINT_ADDRESS_PROPERTY,
-                serverRule.getEndpointAddress()
+                endpointAddress)
         );
-        externalSystemFakeServer = serverRule.getPublishedEndpoint();               // <4>
     }
     @Test
     public void happy_case() throws Exception {
         // given
-        final Update update = new Update();                                         // <5>
+        final Update update = new Update();                                         // <6>
         ...
-
         // expect
-        final UpdateResponse response = new UpdateResponse();                       // <6>
+        final UpdateResponse response = new UpdateResponse();                       // <7>
         ...
-        externalSystemFakeServer.control().setResponse(updateResponse);
-
+        fakeServerEndpoint.control().setResponse(updateResponse);
         // when
-        PostResponse response = externalSystemContract.post(update);                // <7>
-
+        PostResponse response = externalSystemContract.post(update);                // <8>
         // then
-        final List<Update> updates =                                                // <8>
-            externalSystemFakeServer.control().getUpdates();
+        final List<Update> updates =                                                // <9>
+            fakeServerEndpoint.control().getUpdates();
         ...
     }
-    ...
 }
 ----
 <1> the SOAP contract as defined in WSDL and generated by wsdl2java
-<2> also generated by wsdl2java
-<3> `getWsdl()` is a utility method to return a URL for the WSDL (eg from the classpath)
-<4> get hold of the fake server running at the end point
-<5> create a request (generated from the WSDL and wsdl2java)
-<6> instruct fake server how to respond
-<7> invoke the service
-<8> check service was correctly invoked etc.
+<2> get hold of the fake server-side endpoint from the rule...
+<3> ... and its endpoint address
+<4> use factory (also geneated by wsdl2java) to create client-side endpoint
+<5> `getWsdl()` is a utility method to return a URL for the WSDL (eg from the classpath)
+<6> create a request (generated from the WSDL and wsdl2java)
+<7> instruct fake server how to respond
+<8> invoke the service
+<9> check service was correctly invoked etc.
+
+For "real-world" usage, see the example app of the (non-ASF) http://github.com/isisaddons/isis-module-publishmq[Isis addons' publishmq] module.
+
+Alternatively, the rule can host multiple endpoints.  Each of these will be at a separate address.
+
+[source,java]
+----
+public class ExternalSystemFakeServerRule extends SoapEndpointPublishingRule {
+    public ExternalSystemFakeServerRule() {
+        super(
+            new SoapEndpointSpec(FakeCustomersEndpoint.class,
+                                 "http://localhost:54346/customers"),
+            new SoapEndpointSpec(FakeOrdersEndpoint.class,
+                                 "http://localhost:54347/orders"),
+            new SoapEndpointSpec(FakeProductsEndpoint.class,
+                                 "http://localhost:54348/products"))
+    }
+}
+----
+
+To lookup a particular endpoint, specify its type, eg:
+
+[source,java]
+----
+FakeProductsEndpoint fakeProductsServerEndpoint =
+            serverRule.getPublishedEndpoint(FakeProductsEndpoint.class);
+----
+
+
 
 == XML Marshalling Support
 

http://git-wip-us.apache.org/repos/asf/isis/blob/faf5c665/core/unittestsupport/src/main/java/org/apache/isis/core/unittestsupport/soap/SoapEndpointPublishingRule.java
----------------------------------------------------------------------
diff --git a/core/unittestsupport/src/main/java/org/apache/isis/core/unittestsupport/soap/SoapEndpointPublishingRule.java b/core/unittestsupport/src/main/java/org/apache/isis/core/unittestsupport/soap/SoapEndpointPublishingRule.java
index f6b4385..4eba9e5 100644
--- a/core/unittestsupport/src/main/java/org/apache/isis/core/unittestsupport/soap/SoapEndpointPublishingRule.java
+++ b/core/unittestsupport/src/main/java/org/apache/isis/core/unittestsupport/soap/SoapEndpointPublishingRule.java
@@ -16,10 +16,15 @@
  */
 package org.apache.isis.core.unittestsupport.soap;
 
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
 import java.util.function.Supplier;
 
 import javax.xml.ws.Endpoint;
 
+import com.google.common.collect.Maps;
+
 import org.junit.rules.TestRule;
 import org.junit.runner.Description;
 import org.junit.runners.model.Statement;
@@ -28,20 +33,51 @@ import org.junit.runners.model.Statement;
 /**
  * For example usage, see <a href="https://github.com/isisaddons/isis-module-publishmq">Isis addons' publishmq module</a> (non-ASF)
  */
-public class SoapEndpointPublishingRule<T> implements TestRule {
+public class SoapEndpointPublishingRule implements TestRule {
+
+    private static Map<Class<?>,SoapEndpoint> cachedSoapEndpointByType = Maps.newLinkedHashMap();
+
+    public static class SoapEndpointSpec {
+        private final Class<?> endpointClass;
+        private final String endpointAddress;
+        private final Supplier<?> endpointImplementorFactory;
+
+        public SoapEndpointSpec(final Class<?> endpointClass, final String endpointAddress) {
+            this(endpointClass, endpointAddress, new SupplierUsingDefaultConstructor(endpointClass));
+        }
+        public SoapEndpointSpec(final Class<?> endpointClass, final String endpointAddress, final Supplier<?> endpointImplementorFactory) {
+            this.endpointClass = endpointClass;
+            this.endpointAddress = endpointAddress;
+            this.endpointImplementorFactory = endpointImplementorFactory;
+        }
+
+    }
+
+    private static class SoapEndpoint {
+        private final SoapEndpointSpec spec;
+        /**
+         * lazily populated first time
+         */
+        private Object implementor;
+        public SoapEndpoint(final SoapEndpointSpec spec) {
+            this.spec = spec;
+        }
+    }
 
-    private static ThreadLocal<Object> ENDPOINT = new ThreadLocal<>();
+    private final Map<Class<?>,SoapEndpoint> soapEndpointByType = Maps.newLinkedHashMap();
 
-    private final String endpointAddress;
-    private final Supplier<T> endpointImplementorFactory;
+    public SoapEndpointPublishingRule(final Class<?> endpointClass, final String endpointAddress) {
+        this(new SoapEndpointSpec(endpointClass, endpointAddress, new SupplierUsingDefaultConstructor(endpointClass)));
+    }
 
-    public SoapEndpointPublishingRule(final String endpointAddress, final Supplier<T> endpointImplementorFactory) {
-        this.endpointAddress = endpointAddress;
-        this.endpointImplementorFactory = endpointImplementorFactory;
+    public SoapEndpointPublishingRule(SoapEndpointSpec... soapEndpointSpecs) {
+        this(Arrays.asList(soapEndpointSpecs));
     }
 
-    public String getEndpointAddress() {
-        return endpointAddress;
+    public SoapEndpointPublishingRule(final List<SoapEndpointSpec> soapEndpointSpecs) {
+        for (SoapEndpointSpec soapEndpointSpec : soapEndpointSpecs) {
+            soapEndpointByType.put(soapEndpointSpec.endpointClass, new SoapEndpoint(soapEndpointSpec));
+        }
     }
 
     @Override
@@ -51,17 +87,49 @@ public class SoapEndpointPublishingRule<T> implements TestRule {
     }
 
     private void publishEndpointIfRequired() {
-        if (ENDPOINT.get() == null) {
-            final T implementor = endpointImplementorFactory.get();
-            Endpoint.publish(endpointAddress, implementor);
-            ENDPOINT.set(implementor);
+        // merge in any new endpoints to static cache
+        for (Class<?> type : soapEndpointByType.keySet()) {
+            final SoapEndpoint soapEndpoint = soapEndpointByType.get(type);
+            final Class<?> endpointClass = soapEndpoint.spec.endpointClass;
+            final SoapEndpoint cachedSoapEndpoint = cachedSoapEndpointByType.get(endpointClass);
+            if(cachedSoapEndpoint == null) {
+                cachedSoapEndpointByType.put(endpointClass, soapEndpoint);
+            }
+        }
+        // ensure all endpoints (including any new ones) are instantiated and published
+        for (Class<?> type : cachedSoapEndpointByType.keySet()) {
+            final SoapEndpoint cachedSoapEndpoint = cachedSoapEndpointByType.get(type);
+            if(cachedSoapEndpoint.implementor == null) {
+                cachedSoapEndpoint.implementor = cachedSoapEndpoint.spec.endpointImplementorFactory.get();
+                Endpoint.publish(cachedSoapEndpoint.spec.endpointAddress, cachedSoapEndpoint.implementor);
+            }
         }
     }
-    //endregion
 
-    public T getPublishedEndpoint() {
-        return (T) ENDPOINT.get();
+    public String getEndpointAddress(Class<?> endpointClass) {
+        return cachedSoapEndpointByType.get(endpointClass).spec.endpointAddress;
     }
 
+    public <T> T getEndpointImplementor(Class<T> endpointClass) {
+        return (T)cachedSoapEndpointByType.get(endpointClass).implementor;
+    }
+
+
+    private static class SupplierUsingDefaultConstructor implements Supplier<Object> {
+        private final Class<?> endpointClass;
+
+        public SupplierUsingDefaultConstructor(final Class<?> endpointClass) {
+            this.endpointClass = endpointClass;
+        }
+
+        @Override
+        public Object get() {
+            try {
+                return endpointClass.newInstance();
+            } catch (InstantiationException | IllegalAccessException e) {
+                throw new RuntimeException(e);
+            }
+        }
+    }
 
 }


[2/3] isis git commit: ISIS-1167: moving JaxbUtil into applib/utils.

Posted by da...@apache.org.
ISIS-1167: moving JaxbUtil into applib/utils.


Project: http://git-wip-us.apache.org/repos/asf/isis/repo
Commit: http://git-wip-us.apache.org/repos/asf/isis/commit/5e89a117
Tree: http://git-wip-us.apache.org/repos/asf/isis/tree/5e89a117
Diff: http://git-wip-us.apache.org/repos/asf/isis/diff/5e89a117

Branch: refs/heads/master
Commit: 5e89a1178d712168507db5ab621ee8271ee7b315
Parents: 10462c9
Author: Dan Haywood <da...@haywood-associates.co.uk>
Authored: Fri Jul 3 12:50:22 2015 +0100
Committer: Dan Haywood <da...@haywood-associates.co.uk>
Committed: Fri Jul 3 12:50:22 2015 +0100

----------------------------------------------------------------------
 .../org/apache/isis/applib/util/JaxbUtil.java   | 93 ++++++++++++++++++++
 .../core/unittestsupport/jaxb/JaxbMatchers.java | 72 ++++++++++++++-
 .../core/unittestsupport/jaxb/JaxbUtil.java     | 93 --------------------
 3 files changed, 162 insertions(+), 96 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/isis/blob/5e89a117/core/applib/src/main/java/org/apache/isis/applib/util/JaxbUtil.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/util/JaxbUtil.java b/core/applib/src/main/java/org/apache/isis/applib/util/JaxbUtil.java
new file mode 100644
index 0000000..b2cd974
--- /dev/null
+++ b/core/applib/src/main/java/org/apache/isis/applib/util/JaxbUtil.java
@@ -0,0 +1,93 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.isis.applib.util;
+
+import java.io.CharArrayWriter;
+import java.io.IOException;
+import java.io.Reader;
+import java.io.StringReader;
+import java.io.Writer;
+import java.net.URL;
+import java.nio.charset.Charset;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Marshaller;
+import javax.xml.bind.Unmarshaller;
+
+import com.google.common.io.Resources;
+
+/**
+ * Helper methods for converting {@link javax.xml.bind.annotation.XmlRootElement}-annotated class to-and-from XML.  Intended primarily for
+ * test use only (the {@link JAXBContext} is not cached).
+ *
+ * <p>
+ * For example usage, see <a href="https://github.com/isisaddons/isis-module-publishmq">Isis addons' publishmq module</a> (non-ASF)
+ * </p>
+ */
+public class JaxbUtil {
+
+    private JaxbUtil(){}
+
+    public static <T> T fromXml(
+            final Reader reader,
+            final Class<T> dtoClass) {
+        Unmarshaller un = null;
+        try {
+            un = getJaxbContext(dtoClass).createUnmarshaller();
+            return (T) un.unmarshal(reader);
+        } catch (JAXBException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public static <T> T fromXml(
+            final Class<?> contextClass,
+            final String resourceName,
+            final Charset charset,
+            final Class<T> dtoClass) throws IOException {
+        final URL url = Resources.getResource(contextClass, resourceName);
+        final String s = Resources.toString(url, charset);
+        return fromXml(new StringReader(s), dtoClass);
+    }
+
+    public static <T> String toXml(final T dto) {
+        final CharArrayWriter caw = new CharArrayWriter();
+        toXml(dto, caw);
+        return caw.toString();
+    }
+
+    public static <T> void toXml(final T dto, final Writer writer) {
+        Marshaller m = null;
+        try {
+            final Class<?> aClass = dto.getClass();
+            m = getJaxbContext(aClass).createMarshaller();
+            m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
+            m.marshal(dto, writer);
+        } catch (JAXBException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private static JAXBContext getJaxbContext(Class<?> dtoClass) {
+        try {
+            return JAXBContext.newInstance(dtoClass);
+        } catch (JAXBException e) {
+            throw new RuntimeException(e);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/5e89a117/core/unittestsupport/src/main/java/org/apache/isis/core/unittestsupport/jaxb/JaxbMatchers.java
----------------------------------------------------------------------
diff --git a/core/unittestsupport/src/main/java/org/apache/isis/core/unittestsupport/jaxb/JaxbMatchers.java b/core/unittestsupport/src/main/java/org/apache/isis/core/unittestsupport/jaxb/JaxbMatchers.java
index 6299d3d..10e67e4 100644
--- a/core/unittestsupport/src/main/java/org/apache/isis/core/unittestsupport/jaxb/JaxbMatchers.java
+++ b/core/unittestsupport/src/main/java/org/apache/isis/core/unittestsupport/jaxb/JaxbMatchers.java
@@ -16,7 +16,21 @@
  */
 package org.apache.isis.core.unittestsupport.jaxb;
 
+import java.io.CharArrayWriter;
+import java.io.IOException;
+import java.io.Reader;
+import java.io.StringReader;
+import java.io.Writer;
+import java.net.URL;
+import java.nio.charset.Charset;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Marshaller;
+import javax.xml.bind.Unmarshaller;
+
 import com.google.common.base.Objects;
+import com.google.common.io.Resources;
 
 import org.hamcrest.Matcher;
 import org.hamcrest.TypeSafeMatcher;
@@ -36,17 +50,69 @@ public class JaxbMatchers {
         return new TypeSafeMatcher<T>() {
             @Override
             protected boolean matchesSafely(final T item) {
-                final String expectedXml = JaxbUtil.toXml(expected);
-                final String itemXml = JaxbUtil.toXml(item);
+                final String expectedXml = JaxbUtil2.toXml(expected);
+                final String itemXml = JaxbUtil2.toXml(item);
                 return Objects.equal(expectedXml, itemXml);
             }
 
             @Override
             public void describeTo(final org.hamcrest.Description description) {
-                final String expectedXml = JaxbUtil.toXml(expected);
+                final String expectedXml = JaxbUtil2.toXml(expected);
                 description.appendText("is equivalent to ").appendValue(expectedXml);
             }
         };
     }
 
 }
+class JaxbUtil2 {
+
+    private JaxbUtil2(){}
+
+    public static <T> T fromXml(
+            final Reader reader,
+            final Class<T> dtoClass) {
+        Unmarshaller un = null;
+        try {
+            un = getJaxbContext(dtoClass).createUnmarshaller();
+            return (T) un.unmarshal(reader);
+        } catch (JAXBException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public static <T> T fromXml(
+            final Class<?> contextClass,
+            final String resourceName,
+            final Charset charset,
+            final Class<T> dtoClass) throws IOException {
+        final URL url = Resources.getResource(contextClass, resourceName);
+        final String s = Resources.toString(url, charset);
+        return fromXml(new StringReader(s), dtoClass);
+    }
+
+    public static <T> String toXml(final T dto) {
+        final CharArrayWriter caw = new CharArrayWriter();
+        toXml(dto, caw);
+        return caw.toString();
+    }
+
+    public static <T> void toXml(final T dto, final Writer writer) {
+        Marshaller m = null;
+        try {
+            final Class<?> aClass = dto.getClass();
+            m = getJaxbContext(aClass).createMarshaller();
+            m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
+            m.marshal(dto, writer);
+        } catch (JAXBException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private static JAXBContext getJaxbContext(Class<?> dtoClass) {
+        try {
+            return JAXBContext.newInstance(dtoClass);
+        } catch (JAXBException e) {
+            throw new RuntimeException(e);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/5e89a117/core/unittestsupport/src/main/java/org/apache/isis/core/unittestsupport/jaxb/JaxbUtil.java
----------------------------------------------------------------------
diff --git a/core/unittestsupport/src/main/java/org/apache/isis/core/unittestsupport/jaxb/JaxbUtil.java b/core/unittestsupport/src/main/java/org/apache/isis/core/unittestsupport/jaxb/JaxbUtil.java
deleted file mode 100644
index a4ac6a6..0000000
--- a/core/unittestsupport/src/main/java/org/apache/isis/core/unittestsupport/jaxb/JaxbUtil.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/**
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-package org.apache.isis.core.unittestsupport.jaxb;
-
-import java.io.CharArrayWriter;
-import java.io.IOException;
-import java.io.Reader;
-import java.io.StringReader;
-import java.io.Writer;
-import java.net.URL;
-import java.nio.charset.Charset;
-
-import javax.xml.bind.JAXBContext;
-import javax.xml.bind.JAXBException;
-import javax.xml.bind.Marshaller;
-import javax.xml.bind.Unmarshaller;
-
-import com.google.common.io.Resources;
-
-/**
- * Helper methods for converting {@link javax.xml.bind.annotation.XmlRootElement}-annotated class to-and-from XML.  Intended for
- * test use only (the {@link JAXBContext} is not cached).
- *
- * <p>
- * For example usage, see <a href="https://github.com/isisaddons/isis-module-publishmq">Isis addons' publishmq module</a> (non-ASF)
- * </p>
- */
-public class JaxbUtil {
-
-    private JaxbUtil(){}
-
-    public static <T> T fromXml(
-            final Reader reader,
-            final Class<T> dtoClass) {
-        Unmarshaller un = null;
-        try {
-            un = getJaxbContext(dtoClass).createUnmarshaller();
-            return (T) un.unmarshal(reader);
-        } catch (JAXBException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    public static <T> T fromXml(
-            final Class<?> contextClass,
-            final String resourceName,
-            final Charset charset,
-            final Class<T> dtoClass) throws IOException {
-        final URL url = Resources.getResource(contextClass, resourceName);
-        final String s = Resources.toString(url, charset);
-        return fromXml(new StringReader(s), dtoClass);
-    }
-
-    public static <T> String toXml(final T dto) {
-        final CharArrayWriter caw = new CharArrayWriter();
-        toXml(dto, caw);
-        return caw.toString();
-    }
-
-    public static <T> void toXml(final T dto, final Writer writer) {
-        Marshaller m = null;
-        try {
-            final Class<?> aClass = dto.getClass();
-            m = getJaxbContext(aClass).createMarshaller();
-            m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
-            m.marshal(dto, writer);
-        } catch (JAXBException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    private static JAXBContext getJaxbContext(Class<?> dtoClass) {
-        try {
-            return JAXBContext.newInstance(dtoClass);
-        } catch (JAXBException e) {
-            throw new RuntimeException(e);
-        }
-    }
-}