Connecting to HornetQ via remote JNDI provider
Today I have been trying to make my SwitchYard application connected to remote HornetQ, succeeded with following.
Add JNDI properties to the InitialContext
This piece is mentioned by Justin on this thread:
Accessing HornetQ using remote lookup via JNDI | Community
final Properties env = new Properties(); env.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory"); env.put(Context.PROVIDER_URL, "remote://localhost:4447"); InitialContext ic = new InitialContext(env);
Add jboss-deployment-structure.xml into application.jar!/META-INF
This was the piece I've been looking for. org.jboss.naming.remote.client.InitialContextFactory is in the org.jboss.remote-naming module.
- application.jar!/META-INF/jboss-deployment-structure.xml
<?xml version="1.0" encoding="UTF-8"?> <jboss-deployment-structure> <deployment> <dependencies> <module name="org.jboss.remote-naming" /> <module name="org.hornetq" /> </dependencies> </deployment> </jboss-deployment-structure>
Once [SWITCHYARD-1712] JCA outbound cannot communicate with remote destinations/brokers - JBoss Issue Tracker is fixed, then SwitchYard JCA outbound should be able to connect to the HornetQ server via remote JNDI.
Message Ordering on HornetQ
An important tips - enable Message Group or limit "max-pool-size" to 1 to guarantee the order. Notice that the max-pool-size is only available on JBossAS7.2 or later.
How to order messages that are sent from the message queue? | SwitchYard | JBoss Community
Moving to Japan - Thanks to everybody I met in US
Finally, I need to accept the end of living in US. It has been the most amazing time in my life. I miss lots of beautiful historic structure in Boston city, and full of greenery once I just go 30 minutes away from the city.
In winter, not only I love to do snowboarding, but also I love the snowscape itself here. Snow plowing was also a kind of fun to me.
Summer, I regret that it was just only once to go to the Tanglewood Music Festival, and I couldn't go to Boston Symphony Hall at last.
People. I love people I met here in US. I remember somebody said to me that the service and staff in US is terrible, But I clearly disagree. I know the staff like waiter or operator is always polite in Japan, but they are just reading a manual, right? I love to be served by person, and I could in US. Yeah, there were a few impolite person, but I could just talk to other good person.
And Red Hat. I'm honored to have worked with them. They are highly motivated, professional and fun to talk - my poor English doesn't produce any joke, so I just have been listening though. I'll never dispose the "I miss you" mail from them so that I can see it when I'm captured into death march ;)
Bye for now, everybody and everything in US. Thank you so much so far. I'll see you again.
そしてUSで出会った日本人の皆さま、今までお世話になりました。同じ日本人とのほっこり一息というのは、異なる文化圏の人々と触れ合うのとはまた違う、これも欠かせないものだったと思います。またどこかでお会いできることを願っております。
JBoss AS7 remote debug
Standard installation
enable following option in $AS7/bin/standalone.conf
JAVA_OPTS="$JAVA_OPTS -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=y"
JUnit testcase kicked by Maven
mvn -Dmaven.surefire.debug test
or
mvn -Dmaven.surefire.debug="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000" test
Arquillian testcase
Add javaVmArguments property into arquillian.xml
...(snip)... <container qualifier="jboss7" default="true"> <configuration> + <property name="javaVmArguments">-Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=y</property> </configuration> ...(snip)...
Playing around with SwitchYard on OpenShift Express
Prerequisite
- Fedora16 environment http://fedoraproject.org/en/get-fedora
- SwitchYard http://www.jboss.org/switchyard/downloads
- OpenShift account https://openshift.redhat.com/
Install OpenShift Express Client Tools
yum install rubygem-rhc
Create an application with jbossas-7 cartridge
Used HelloSwitchYard as the application name.
rhc app create -l <openshift-account> -a HelloSwitchYard -t jbossas-7
Add SwitchYard Subsystem to the JBoss AS7
switchyard-openshift repository provides a way of that. Let's swipe it :)
cd HelloSwitchYard git remote add switchyard-template git://github.com/jboss-switchyard/switchyard-openshift.git git fetch switchyard-template git checkout switchyard-template/master -- pom.xml git checkout switchyard-template/master -- standalone.diff git apply standalone.diff git rm -f standalone.diff
Edit pom.xml
Fix the artifact name as you like and profile id in the OpenShift manner
diff --git a/pom.xml b/pom.xml index 845c81c..44e8b12 100644 --- a/pom.xml +++ b/pom.xml @@ -1,11 +1,11 @@ <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> - <groupId>org.switchyard.sample</groupId> - <artifactId>swydapp</artifactId> + <groupId>mynamespace.helloswitchyard</groupId> + <artifactId>HelloSwitchYard</artifactId> <version>1.0</version> - <name>swydapp</name> + <name>HelloSwitchYard</name> <properties> <switchyard.version>0.4.0.OS1</switchyard.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> @@ -43,9 +43,9 @@ <build /> <profiles> <profile> - <id>switchyard</id> + <id>openshift</id> <build> - <finalName>swydapp</finalName> + <finalName>HelloSwitchYard</finalName> <plugins> <plugin> <artifactId>maven-jar-plugin</artifactId>
Commit those changes
git add . git commit -m "Added SwitchYard Subsystem"
Import the bean-service quickstart
Import the bean-service quickstart from SwitchYard distribution. bean-service is simple enough to use as template application
cp -r ${quickstarts}/bean-service/src/main/java/org src/main/java cp -r ${quickstarts}/bean-service/src/main/resources/wsdl src/main/resources/ cp -r ${quickstarts}/bean-service/src/main/resources/META-INF src/main/resources/ cp -r ${quickstarts}/bean-service/src/test src/
Edit pom.xml
Edit pom.xml to add dependency on switchyard-component-bean, switchyard-component-soap, switchyard-test
diff --git a/pom.xml b/pom.xml index 44e8b12..210a101 100644 --- a/pom.xml +++ b/pom.xml @@ -21,6 +21,18 @@ <artifactId>switchyard-plugin</artifactId> <version>${switchyard.version}</version> </dependency> + <dependency> + <groupId>org.switchyard.components</groupId> + <artifactId>switchyard-component-bean</artifactId> + <version>${switchyard.version}</version> + </dependency> + <dependency> + <groupId>org.switchyard.components</groupId> + <artifactId>switchyard-component-soap</artifactId> + <version>${switchyard.version}</version> + </dependency> + <dependency> + <groupId>org.switchyard</groupId> + <artifactId>switchyard-test</artifactId> + <version>${switchyard.version}</version> + </dependency> </dependencies> <repositories> <repository>
Edit src/main/resources/META-INF/switchyard.xml
comment out the socketAddr & contextPath elements in the binding.soap element
diff --git a/src/main/resources/META-INF/switchyard.xml b/src/main/resources/META-INF/switchyard.xml index 3d24bed..cb193bc 100644 --- a/src/main/resources/META-INF/switchyard.xml +++ b/src/main/resources/META-INF/switchyard.xml @@ -5,8 +5,8 @@ <interface.wsdl interface="wsdl/OrderService.wsdl#wsdl.porttype(OrderService)"/> <binding.soap xmlns="urn:switchyard-component-soap:config:1.0"> <wsdl>wsdl/OrderService.wsdl</wsdl> - <socketAddr>:18001</socketAddr> - <contextPath>quickstart-bean</contextPath> + <!-- <socketAddr>:18001</socketAddr> --> + <!-- <contextPath>quickstart-bean</contextPath> --> </binding.soap> </service> </composite>
Edit src/test/java/org/switchyard/quickstarts/bean/service/WebServiceTest.java
Change the web service address in the testcase
diff --git a/src/test/java/org/switchyard/quickstarts/bean/service/WebServiceTest.java b/src/test/java/org/switchyard/quickstarts/bean/service/WebServiceTest.ja index 4c6ac9e..ccdc7d0 100644 --- a/src/test/java/org/switchyard/quickstarts/bean/service/WebServiceTest.java +++ b/src/test/java/org/switchyard/quickstarts/bean/service/WebServiceTest.java @@ -41,7 +41,7 @@ public class WebServiceTest { public void invokeOrderWebService() throws Exception { // Use the HttpMixIn to invoke the SOAP binding endpoint with a SOAP input (from the test classpath) // and compare the SOAP response to a SOAP response resource (from the test classpath)... - httpMixIn.postResourceAndTestXML("http://localhost:18001/quickstart-bean/OrderService", "/xml/soap-request.xml", "/xml/soap-response.xml"); + httpMixIn.postResourceAndTestXML("http://localhost:8080/OrderService", "/xml/soap-request.xml", "/xml/soap-response.xml"); } }
Build and deploy
mvn -Popenshift clean package git add . git commit -m "Added bean-service" git push
Check the status of application
rhc app status -l <openshift-account> -a HelloSwitchYard
Logs looks like this. Don't mind about some Japanese characters in my log, and an error as well. The important thing here is that HelloSwitchYard.jar has been Deployed successfully.
2012/03/14 14:55:38,258 INFO [org.jboss.weld.deployer] (MSC service thread 1-2) JBAS016008: Starting weld service for deployment HelloSwitchYard.jar 2012/03/14 14:55:38,993 INFO [org.switchyard] (MSC service thread 1-3) Starting SwitchYard service 2012/03/14 14:55:39,099 INFO [org.apache.camel.impl.converter.AnnotationTypeConverterLoader] (MSC service thread 1-3) Found 3 packages with 14 @Converter classes to load 2012/03/14 14:55:39,109 INFO [org.apache.camel.impl.converter.DefaultTypeConverter] (MSC service thread 1-3) Loaded 153 core type converters (total 153 type converters) 2012/03/14 14:55:39,111 INFO [org.apache.camel.impl.converter.DefaultTypeConverter] (MSC service thread 1-3) Loaded additional 0 type converters (total 153 type converters) in 0.001 seconds 2012/03/14 14:55:40,197 INFO [org.switchyard.component.soap.InboundHandler] (MSC service thread 1-3) Publishing WebService at http://127.13.2.129:18001/swydws/OrderService 2012/03/14 14:55:40,630 情報 [org.apache.cxf.service.factory.ReflectionServiceFactoryBean] (MSC service thread 1-3) Creating Service {urn:switchyard-quickstart:bean-service:1.0}OrderService from WSDL: vfs:/content/HelloSwitchYard.jar/wsdl/OrderService.wsdl 2012/03/14 14:55:41,376 情報 [org.apache.cxf.endpoint.ServerImpl] (MSC service thread 1-3) Setting the server's publish address to be http://127.13.2.129:18001/swydws/OrderService 2012/03/14 14:55:41,504 ERROR [org.jboss.as] (MSC service thread 1-3) JBAS015875: JBoss AS 7.1.0.Final "Thunder" started (with errors) in 7971ms - Started 143 of 178 services (1 services failed or missing dependencies, 31 services are passive or on-demand) 2012/03/14 14:55:41,549 INFO [org.jboss.as.server] (DeploymentScanner-threads - 2) JBAS018559: Deployed "HelloSwitchYard.jar"
Submit a WebService request using SoapUI
Assuming the namespace is "namespace", Import WSDL from http://helloswitchyard-namespace.rhcloud.com/swydws/OrderService?wsdl into SoapUI and invoke.
Request
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:switchyard-quickstart:bean-service:1.0"> <soapenv:Header/> <soapenv:Body> <urn:submitOrder> <order> <orderId>XYZ</orderId> <itemId>BUTTER</itemId> <quantity>200</quantity> </order> </urn:submitOrder> </soapenv:Body> </soapenv:Envelope>
Response
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"> <SOAP-ENV:Header/> <SOAP-ENV:Body> <orders:submitOrderResponse xmlns:orders="urn:switchyard-quickstart:bean-service:1.0"> <orderAck> <orderId>XYZ</orderId> <accepted>true</accepted> <status>Order Accepted</status> </orderAck> </orders:submitOrderResponse> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
Then you are all set to develop the SwitchYard application on OpenShift Express!
You may want to use the forge tool instead of editing switchyard.xml by hand. Let's see this:
Enjoy!
Debugging around JBossWS & apache-cxf without JBoss instance on Eclipse
Just a note for debugging SWITCHYARD-600.
Don't forget to mkdir ${project}/resources and add it to the build path.
Download&import following projects into Eclipse workspace
Add system property when run/debug
-Djavax.xml.ws.spi.Provider=org.jboss.wsf.stack.cxf.client.ProviderImpl
resources/META-INF/cxf/bus-extensions.txt
org.apache.cxf.wsdl11.WSDLManagerImpl:org.apache.cxf.wsdl.WSDLManager:true org.apache.cxf.phase.PhaseManagerImpl:org.apache.cxf.phase.PhaseManager:true org.apache.cxf.workqueue.WorkQueueManagerImpl:org.apache.cxf.workqueue.WorkQueueManager:true org.apache.cxf.buslifecycle.CXFBusLifeCycleManager:org.apache.cxf.buslifecycle.BusLifeCycleManager:true org.apache.cxf.endpoint.ServerRegistryImpl:org.apache.cxf.endpoint.ServerRegistry:true org.apache.cxf.transport.http.QueryHandlerRegistryImpl:org.apache.cxf.transports.http.QueryHandlerRegistry:true org.apache.cxf.endpoint.EndpointResolverRegistryImpl:org.apache.cxf.endpoint.EndpointResolverRegistry:true org.apache.cxf.headers.HeaderManagerImpl:org.apache.cxf.headers.HeaderManager:true org.apache.cxf.catalog.OASISCatalogManager:org.apache.cxf.catalog.OASISCatalogManager:true org.apache.cxf.service.factory.FactoryBeanListenerManager::true org.apache.cxf.endpoint.ServerLifeCycleManagerImpl:org.apache.cxf.endpoint.ServerLifeCycleManager:true org.apache.cxf.endpoint.ClientLifeCycleManagerImpl:org.apache.cxf.endpoint.ClientLifeCycleManager:true org.apache.cxf.bus.resource.ResourceManagerImpl:org.apache.cxf.resource.ResourceManager:true org.apache.cxf.binding.soap.SoapBindingFactory::true org.apache.cxf.binding.soap.SoapTransportFactory::true org.apache.cxf.transport.http.HTTPTransportFactory::true org.apache.cxf.transport.http.HTTPWSDLExtensionLoader::true org.apache.cxf.transport.http.policy.HTTPClientAssertionBuilder::true org.apache.cxf.transport.http.policy.HTTPServerAssertionBuilder::true org.apache.cxf.transport.http.policy.NoOpPolicyInterceptorProvider::true org.jboss.wsf.stack.cxf.addons.transports.httpserver.HttpServerDestinationFactory::true
resources/wsdl.wsdl
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <definitions targetNamespace="urn:test" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="urn:test" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"> <types> <xsd:schema targetNamespace="urn:test" xmlns:tns="urn:test" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:element name="input" type="xs:string"/> </xsd:schema> </types> <message name="message"> <part name="input" element="tns:input"/> </message> <portType name="service"> <operation name="message"> <input message="tns:message"/> </operation> </portType> <binding name="serviceBinding" type="tns:service"> <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/> <operation name="message"> <soap:operation soapAction="urn:test"/> <input> <soap:body use="literal"/> </input> </operation> </binding> <service name="service"> <port name="port" binding="tns:serviceBinding"> <soap:address location="http://localhost:18080/test"/> </port> </service> </definitions>
src/PublishWebService.java
Test code for javax.xml.ws.{Provider,Endpoint}. Using TCP socket to invoke the service.
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.Socket; import java.net.URL; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.xml.namespace.QName; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.soap.SOAPMessage; import javax.xml.transform.Source; import javax.xml.transform.stream.StreamSource; import javax.xml.ws.Endpoint; import javax.xml.ws.Provider; import javax.xml.ws.ServiceMode; import javax.xml.ws.Service.Mode; import javax.xml.ws.WebServiceProvider; import javax.wsdl.Definition; import javax.wsdl.Port; import javax.wsdl.Service; import javax.wsdl.factory.WSDLFactory; import javax.wsdl.xml.WSDLReader; import org.w3c.dom.Document; import org.xml.sax.InputSource; @WebServiceProvider @ServiceMode(Mode.MESSAGE) public class PublishWebService implements Provider<SOAPMessage> { private static final String PUBLISH_URL = "http://127.0.0.1:18080/context/test"; private static final String WSDL = "wsdl.wsdl"; private static final String REQUEST_BODY = "<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">\r\n" + " <soap:Body>\r\n" + " <test:input xmlns:test=\"urn:test\">foobar</test:input>\r\n" + " </soap:Body>\r\n" + "</soap:Envelope>"; @Override public SOAPMessage invoke(SOAPMessage request) { return null; } public void perform() throws Exception { Endpoint _endpoint = createEndpoint(WSDL); _endpoint.publish(PUBLISH_URL); Socket sock = new Socket("127.0.0.1", 18080); BufferedReader reader = new BufferedReader(new InputStreamReader(sock.getInputStream())); Thread t = new MyReader(reader); t.start(); OutputStream out = sock.getOutputStream(); String method = "POST /context/test HTTP/1.1\r\n"; out.write(method.getBytes(), 0, method.getBytes().length); String contentLength = "Content-Length: " + REQUEST_BODY.length() + "\r\n"; out.write(contentLength.getBytes(), 0, contentLength.getBytes().length); String contentType = "Content-Type: text/xml; charset=\"utf-8\"\r\n\r\n"; out.write(contentType.getBytes(), 0, contentType.getBytes().length); out.write(REQUEST_BODY.getBytes(), 0, REQUEST_BODY.getBytes().length); String eof = "\r\n\r\n"; out.write(eof.getBytes(), 0, eof.getBytes().length); out.flush(); Thread.sleep(1000); sock.close(); _endpoint.stop(); System.out.println(">>>>> end."); System.exit(0); } private Endpoint createEndpoint(String wsdl) throws Exception { URL wsdlUrl = this.getClass().getResource(wsdl); javax.wsdl.Service wsdlService = getService(wsdlUrl); Port _wsdlPort = (Port) wsdlService.getPorts().values().iterator().next(); List<Source> metadata = new ArrayList<Source>(); StreamSource source = new StreamSource(this.getClass().getResourceAsStream(wsdl)); source.setSystemId(wsdlUrl.toExternalForm()); metadata.add(source); Map<String, Object> properties = new HashMap<String, Object>(); properties.put(Endpoint.WSDL_SERVICE, wsdlService.getQName()); properties.put(Endpoint.WSDL_PORT, new QName(wsdlService.getQName().getNamespaceURI(), _wsdlPort.getName())); properties.put("javax.xml.ws.wsdl.description", wsdlUrl.toExternalForm()); Endpoint _endpoint = Endpoint.create(this); _endpoint.setMetadata(metadata); _endpoint.setProperties(properties); return _endpoint; } private Service getService(URL wsdlUrl) throws Exception { DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance(); docBuilderFactory.setNamespaceAware(true); DocumentBuilder builder = docBuilderFactory.newDocumentBuilder(); InputStream inputStream = wsdlUrl.openStream(); InputSource source = new InputSource(inputStream); source.setSystemId(wsdlUrl.toString()); Document wsdlDoc = builder.parse(source); WSDLFactory wsdlFactory = WSDLFactory.newInstance(); WSDLReader reader = wsdlFactory.newWSDLReader(); reader.setFeature("javax.wsdl.verbose", false); Definition definition = reader.readWSDL(wsdlUrl.toString(), wsdlDoc); Service service = null; service = (Service) definition.getServices().values().iterator().next(); return service; } public static void main(String[] args) throws Exception { new PublishWebService().perform(); } } class MyReader extends Thread { private BufferedReader reader; String line; public MyReader(BufferedReader reader) { this.reader = reader; } public void run() { while(true) { try { if ((line = reader.readLine()) != null) { System.out.println(">>>>> received [" + line + "]"); } } catch (IOException ignore) {break;} } } }
resources/log4j.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"> <log4j:configuration xmlns:log4j='http://jakarta.apache.org/log4j/'> <appender name="STDOUT" class="org.apache.log4j.ConsoleAppender"> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%d{HH:mm:ss,SSS} %-5p [%c] %m%n"/> </layout> </appender> <root> <level value="FINE"/> <appender-ref ref="STDOUT"/> </root> </log4j:configuration>
XSLT transformation using DOMSource & DOMResult
Just reminder. really hit a wall.
The points are following two. It's no problem if the source is always String, but sometimes not somehow.
- need to do DocumentBuilderFactory#setNamespaceAware(true) when creating DOMSource from String, or XSLT transformation fails afterward. And what is worse, it doesn't return a error but empty result.
- DOMResult#getNode() actually returns Document, so need to do like this - ((Document)domresult.getNode()).getDocumentElement() - I don't like this. use getDocument() as method name if it returns the Document.
XsltTransformTest.java - Testcase using StreamSource, StreamResult as well
import java.io.StringReader; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.transform.Result; import javax.xml.transform.Source; import javax.xml.transform.Templates; import javax.xml.transform.dom.DOMResult; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource; import org.w3c.dom.Document; import org.xml.sax.InputSource; public class XsltTransformTest { private static final String XML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<orders:order xmlns:orders=\"urn:switchyard-quickstart:transform-xslt:1.0\">\n" + " <orderId>PO-19838-XYZ</orderId>\n" + " <itemId>BUTTER</itemId>\n" + " <quantity>200</quantity>\n" + "</orders:order>"; private static final String XSLT = "<?xml version=\"1.0\"?>\n" + "<xsl:stylesheet xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" version=\"1.0\">\n" + " <xsl:template match=\"/\">\n" + " <orders:orderAck xmlns:orders=\"urn:switchyard-quickstart:transform-xslt:1.0\">\n" + " <xsl:for-each select=\"orders:order\">\n" + " <orderId>\n" + " <xsl:value-of select=\"orderId\" />\n" + " </orderId>\n" + " <accepted>\n" + " <xsl:choose>\n" + " <xsl:when test=\"(itemId = 'BUTTER') and (quantity <= 200)\">\n" + " true\n" + " </xsl:when>\n" + " <xsl:otherwise>\n" + " false\n" + " </xsl:otherwise>\n" + " </xsl:choose>\n" + " </accepted>\n" + " <status>\n" + " <xsl:choose>\n" + " <xsl:when test=\"(itemId = 'BUTTER') and (quantity <= 200)\">\n" + " Order Accepted\n" + " </xsl:when>\n" + " <xsl:when test=\"itemId != 'BUTTER'\">\n" + " No Such Item:\n" + " <xsl:value-of select=\"itemId\" />\n" + " </xsl:when>\n" + " <xsl:when test=\"quantity > 200\">\n" + " Not Enough Stock\n" + " </xsl:when>\n" + " <xsl:otherwise>\n" + " UNKNOWN\n" + " </xsl:otherwise>\n" + " </xsl:choose>\n" + " </status>\n" + " </xsl:for-each>\n" + " </orders:orderAck>\n" + " </xsl:template>\n" + "</xsl:stylesheet>"; public static void main(String[] args) throws Exception { new XsltTransformTest().perform(); } public void perform() throws Exception { System.out.println("* * * StreamSource => StreamResult * * *"); transform(XSLT, createStreamSource(XML), new StreamResult(System.out)); System.out.println("\n* * * DOMSource => StreamResult * * *"); transform(XSLT, createDOMSource(XML), new StreamResult(System.out)); DOMResult result = new DOMResult(); System.out.println("\n* * * StreamSource => DOMResult * * *"); printDOMResult(transform(XSLT, createStreamSource(XML), result)); result = new DOMResult(); System.out.println("\n* * * DOMSource => DOMResult * * *"); printDOMResult(transform(XSLT, createDOMSource(XML), result)); } private void printDOMResult(DOMResult dom) throws Exception { System.out.println("getNode().getLocalName()=" + dom.getNode().getLocalName() + ", ((Document)getNode()).getDocumentElement().getLocalName()=" + ((Document)dom.getNode()).getDocumentElement().getLocalName()); } private <T extends Result> T transform(String xslt, Source source, T result) throws Exception { javax.xml.transform.TransformerFactory tFactory = javax.xml.transform.TransformerFactory.newInstance(); Templates templates = tFactory.newTemplates(new StreamSource(new StringReader(xslt))); javax.xml.transform.Transformer transformer = templates.newTransformer(); transformer.transform(source, result); return result; } private DOMSource createDOMSource(String str) throws Exception { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setNamespaceAware(true); InputSource input = new InputSource(new StringReader(str)); Document document = factory.newDocumentBuilder().parse(input); return new DOMSource(document.getDocumentElement()); } private StreamSource createStreamSource(String str) throws Exception { return new StreamSource(new StringReader(str)); } }
output
* * * StreamSource => StreamResult * * * <?xml version="1.0" encoding="UTF-8"?><orders:orderAck xmlns:orders="urn:switchyard-quickstart:transform-xslt:1.0"><orderId>PO-19838-XYZ</orderId><accepted> true </accepted><status> Order Accepted </status></orders:orderAck> * * * DOMSource => StreamResult * * * <?xml version="1.0" encoding="UTF-8"?><orders:orderAck xmlns:orders="urn:switchyard-quickstart:transform-xslt:1.0"><orderId>PO-19838-XYZ</orderId><accepted> true </accepted><status> Order Accepted </status></orders:orderAck> * * * StreamSource => DOMResult * * * getNode().getLocalName()=null, ((Document)getNode()).getDocumentElement().getLocalName()=orderAck * * * DOMSource => DOMResult * * * getNode().getLocalName()=null, ((Document)getNode()).getDocumentElement().getLocalName()=orderAck