[Yanel-commits] rev 29599 - in public/yanel/contributions/resources/soap: src/java/org/wyona/yanel/impl/resources/soap yanel-htdocs/doc

michi at wyona.com michi at wyona.com
Thu Dec 6 14:46:34 CET 2007


Author: michi
Date: 2007-12-06 14:46:33 +0100 (Thu, 06 Dec 2007)
New Revision: 29599

Added:
   public/yanel/contributions/resources/soap/src/java/org/wyona/yanel/impl/resources/soap/AbstractOperation.java
   public/yanel/contributions/resources/soap/src/java/org/wyona/yanel/impl/resources/soap/IOperation.java
   public/yanel/contributions/resources/soap/src/java/org/wyona/yanel/impl/resources/soap/NamespaceContextSupport.java
   public/yanel/contributions/resources/soap/yanel-htdocs/doc/soap-resource.xhtml
Modified:
   public/yanel/contributions/resources/soap/src/java/org/wyona/yanel/impl/resources/soap/AbstractWebService.java
   public/yanel/contributions/resources/soap/src/java/org/wyona/yanel/impl/resources/soap/MessageContext.java
   public/yanel/contributions/resources/soap/src/java/org/wyona/yanel/impl/resources/soap/SOAPResource.java
Log:
thanks to Evaldas the soap interface has become more generic

Added: public/yanel/contributions/resources/soap/src/java/org/wyona/yanel/impl/resources/soap/AbstractOperation.java
===================================================================
--- public/yanel/contributions/resources/soap/src/java/org/wyona/yanel/impl/resources/soap/AbstractOperation.java	                        (rev 0)
+++ public/yanel/contributions/resources/soap/src/java/org/wyona/yanel/impl/resources/soap/AbstractOperation.java	2007-12-06 13:46:33 UTC (rev 29599)
@@ -0,0 +1,15 @@
+package org.wyona.yanel.impl.resources.soap;
+
+import org.apache.log4j.Logger;
+
+public abstract class AbstractOperation implements IOperation {
+    protected static final Logger log = Logger.getLogger(AbstractOperation.class);
+    
+    protected MessageContext context = null;
+    protected AbstractOperation() {
+    }
+    
+    public AbstractOperation(MessageContext context){
+        this.context = context;
+    }
+}

Modified: public/yanel/contributions/resources/soap/src/java/org/wyona/yanel/impl/resources/soap/AbstractWebService.java
===================================================================
--- public/yanel/contributions/resources/soap/src/java/org/wyona/yanel/impl/resources/soap/AbstractWebService.java	2007-12-06 11:24:07 UTC (rev 29598)
+++ public/yanel/contributions/resources/soap/src/java/org/wyona/yanel/impl/resources/soap/AbstractWebService.java	2007-12-06 13:46:33 UTC (rev 29599)
@@ -1,62 +1,28 @@
 package org.wyona.yanel.impl.resources.soap;
 
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
 
-import javax.xml.namespace.NamespaceContext;
 import javax.xml.xpath.XPath;
 import javax.xml.xpath.XPathConstants;
 import javax.xml.xpath.XPathFactory;
 
+import org.apache.log4j.Logger;
 import org.w3c.dom.Element;
 
 public abstract class AbstractWebService implements IWebService{
-    protected final class NamespaceContextSupport implements NamespaceContext{
-        public static final String SOAP_ENV_PREFIX = "soapenv";
-        
-        private final Map namespaces = new HashMap();
-
-        public NamespaceContextSupport() {
-            namespaces.put(SOAP_ENV_PREFIX, "http://schemas.xmlsoap.org/soap/envelope/");
-        }
-        
-        public String getPrefix(String namespaceURI) {
-            Set s = namespaces.entrySet();
-            for (Iterator i = s.iterator(); i.hasNext();) {
-                Map.Entry e = (Map.Entry)i.next();
-                if(namespaceURI.equals(e.getValue())){
-                    return (String)e.getKey();
-                }
-            }
-            return null;
-        }
-        
-        public Iterator getPrefixes(String namespaceURI) {
-            return new HashSet(namespaces.keySet()).iterator();
-        }
-        
-        public String getNamespaceURI(String prefix) {
-            return (String)namespaces.get(prefix);
-        }
-        
-        public void registerNamespace(String prefix, String nsURI){
-            namespaces.put(prefix, nsURI);
-        }
-    }
+    protected static final Logger log = Logger.getLogger(AbstractWebService.class);
     
-	protected final NamespaceContextSupport NAMESPACE_CONTEXT = new NamespaceContextSupport();
-	
+    protected AbstractWebService(){}
+    
 	protected final Element extractPayload(Element soapEnvelope) throws Exception{
 	    
 	    XPath xpath = XPathFactory.newInstance().newXPath();
-        xpath.setNamespaceContext(NAMESPACE_CONTEXT);
+        xpath.setNamespaceContext(new NamespaceContextSupport());
         Element payload = (Element)xpath.evaluate(
                         "/"+NamespaceContextSupport.SOAP_ENV_PREFIX+":Envelope/"+
                           NamespaceContextSupport.SOAP_ENV_PREFIX+":Body/*", soapEnvelope, XPathConstants.NODE);
         
         return payload;
 	}
+	
+	protected abstract IOperation detectOperation(MessageContext incomingMessageContext);
 }

Added: public/yanel/contributions/resources/soap/src/java/org/wyona/yanel/impl/resources/soap/IOperation.java
===================================================================
--- public/yanel/contributions/resources/soap/src/java/org/wyona/yanel/impl/resources/soap/IOperation.java	                        (rev 0)
+++ public/yanel/contributions/resources/soap/src/java/org/wyona/yanel/impl/resources/soap/IOperation.java	2007-12-06 13:46:33 UTC (rev 29599)
@@ -0,0 +1,7 @@
+package org.wyona.yanel.impl.resources.soap;
+
+import org.w3c.dom.Element;
+
+public interface IOperation {
+    public void performOperation(Element payload) throws Exception;
+}

Modified: public/yanel/contributions/resources/soap/src/java/org/wyona/yanel/impl/resources/soap/MessageContext.java
===================================================================
--- public/yanel/contributions/resources/soap/src/java/org/wyona/yanel/impl/resources/soap/MessageContext.java	2007-12-06 11:24:07 UTC (rev 29598)
+++ public/yanel/contributions/resources/soap/src/java/org/wyona/yanel/impl/resources/soap/MessageContext.java	2007-12-06 13:46:33 UTC (rev 29599)
@@ -4,21 +4,35 @@
 import org.wyona.yanel.core.Resource;
 
 public class MessageContext {
-    private Element soapMessage = null;
+    private Element requestSOAPMessage = null;
+    private Element responseSOAPMessage = null;
+    
     private Resource resource = null;
-    
-    public Element getSoapMessage() {
-        return soapMessage;
+
+    public Element getRequestSOAPMessage() {
+        return requestSOAPMessage;
     }
-    public void setSoapMessage(Element soapMessage) {
-        this.soapMessage = soapMessage;
+
+    public void setRequestSOAPMessage(Element requestSOAPMessage) {
+        this.requestSOAPMessage = requestSOAPMessage;
     }
+
+    public Element getResponseSOAPMessage() {
+        return responseSOAPMessage;
+    }
+
+    public void setResponseSOAPMessage(Element responseSOAPMessage) {
+        this.responseSOAPMessage = responseSOAPMessage;
+    }
+
     public Resource getResource() {
         return resource;
     }
+
     public void setResource(Resource resource) {
         this.resource = resource;
     }
     
     
+    
 }

Added: public/yanel/contributions/resources/soap/src/java/org/wyona/yanel/impl/resources/soap/NamespaceContextSupport.java
===================================================================
--- public/yanel/contributions/resources/soap/src/java/org/wyona/yanel/impl/resources/soap/NamespaceContextSupport.java	                        (rev 0)
+++ public/yanel/contributions/resources/soap/src/java/org/wyona/yanel/impl/resources/soap/NamespaceContextSupport.java	2007-12-06 13:46:33 UTC (rev 29599)
@@ -0,0 +1,45 @@
+package org.wyona.yanel.impl.resources.soap;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import javax.xml.namespace.NamespaceContext;
+
+/**
+ * Keeps the namespaces that are in use
+ * */
+public final class NamespaceContextSupport implements NamespaceContext{
+    public static final String SOAP_ENV_PREFIX = "soapenv";
+    
+    private final Map namespaces = new HashMap();
+
+    public NamespaceContextSupport() {
+        namespaces.put(SOAP_ENV_PREFIX, "http://schemas.xmlsoap.org/soap/envelope/");
+    }
+    
+    public String getPrefix(String namespaceURI) {
+        Set s = namespaces.entrySet();
+        for (Iterator i = s.iterator(); i.hasNext();) {
+            Map.Entry e = (Map.Entry)i.next();
+            if(namespaceURI.equals(e.getValue())){
+                return (String)e.getKey();
+            }
+        }
+        return null;
+    }
+    
+    public Iterator getPrefixes(String namespaceURI) {
+        return new HashSet(namespaces.keySet()).iterator();
+    }
+    
+    public String getNamespaceURI(String prefix) {
+        return (String)namespaces.get(prefix);
+    }
+    
+    public void registerNamespace(String prefix, String nsURI){
+        namespaces.put(prefix, nsURI);
+    }
+}
\ No newline at end of file

Modified: public/yanel/contributions/resources/soap/src/java/org/wyona/yanel/impl/resources/soap/SOAPResource.java
===================================================================
--- public/yanel/contributions/resources/soap/src/java/org/wyona/yanel/impl/resources/soap/SOAPResource.java	2007-12-06 11:24:07 UTC (rev 29598)
+++ public/yanel/contributions/resources/soap/src/java/org/wyona/yanel/impl/resources/soap/SOAPResource.java	2007-12-06 13:46:33 UTC (rev 29599)
@@ -28,7 +28,7 @@
 	}
 
     /**
-     *
+     * The returned view is actually a SOAP response message
      */
     public View getView(String viewId) throws Exception {
         View v = new View();
@@ -39,7 +39,7 @@
         Document soapMessage = dbf.newDocumentBuilder().parse(getEnvironment().getRequest().getInputStream());
 		
         MessageContext ctx = new MessageContext();
-        ctx.setSoapMessage(soapMessage.getDocumentElement());
+        ctx.setRequestSOAPMessage(soapMessage.getDocumentElement());
         ctx.setResource(this);
         
         Element response = ((IWebService)Class.forName(getResourceConfigProperty("ws-impl")).newInstance()).handle(ctx);
@@ -55,11 +55,7 @@
         return v;
     }
 
-    /**
-     *
-     */
     public ViewDescriptor[] getViewDescriptors() {
-        // TODO Auto-generated method stub
         return null;
     }
 }

Added: public/yanel/contributions/resources/soap/yanel-htdocs/doc/soap-resource.xhtml
===================================================================
--- public/yanel/contributions/resources/soap/yanel-htdocs/doc/soap-resource.xhtml	                        (rev 0)
+++ public/yanel/contributions/resources/soap/yanel-htdocs/doc/soap-resource.xhtml	2007-12-06 13:46:33 UTC (rev 29599)
@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+<title>SOAP resource</title>
+<style type="text/css">
+.code {
+	font-family: monospace;
+	font-style: italic;
+	font-weight: bold;
+}
+pre.java {
+border: 1px solid black;
+}
+</style>
+</head>
+<body>
+<h2>Description</h2>
+<div>
+<p>The SOAP resource (yanel/contributions/resources/soap) can be used to implement Web services in Yanel.
+The dynamic architecture can be summarized as follows:</p>
+<ol>
+	<li>The resource configuration (e.g. hello.xml.yanel-rc) expects a SOAP message as an
+	incoming request</li>
+	<li>It parses the incoming SOAP message and performs the actions
+	requested in the message</li>
+	<li>Then it responds with a SOAP message</li>
+</ol>
+<p>The resource configuration has one property <span class="code">ws-impl</span>
+where you have to set the implementation of the Web service.</p>
+<p>Worth noticing that a better and a more elaborated solution for Web services in Yanel would be to wrap the whole <a href="ws.apache.org/axis2">Axis2</a> 
+engine into a resource. This would require to put all the logic from <span class="code">AxisServlet</span> into a <span class="code">Viewable2</span> 
+implementation as well as dealing with the Axis2 repository configuration on a resource level.</p>
+</div>
+<h2>"Hello World" example</h2>
+<div>
+<p>Let's create a Web service that when asked to <span class="code">SayHello</span>
+would respond with the message "Hello World".</p>
+<p>
+First we need to implement the Web service (the generic interfaces and classes are available in <span class="code">org.wyona.yanel.impl.resources.soap</span>):
+</p>
+<pre class="java">
+public class HelloWorldWebServiceImpl extends AbstractWebService{
+  
+  public class SayHelloOperation extends AbstractOperation{
+    /* &lt;soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns="http//my/ns">
+    *   &lt;soapenv:Header/>
+    *   &lt;soapenv:Body>
+    *     <b>&lt;ns:SayHelloResponse>Hello World&lt;ns:/SayHelloResponse></b>
+    *   &lt;/soapenv:Body>
+    * &lt;/soapenv:Envelope>
+    */ 
+    private static final Element HELLO_WORLD_SOAP_MESSAGE = ... initialize the response ...
+    
+    public SayHelloOperation(MessageContext context) {
+      super(context);
+    }
+	    
+    public void performOperation(Element payload) throws Exception{
+      // Assume that the request is correct
+      context.setResponseSoapMessage(HELLO_WORLD_SOAP_MESSAGE);
+    }
+  }
+  
+  protected IOperation detectOperation(MessageContext incomingMessageContext) {
+    return new SayHelloOperation();
+  }
+  
+  <b>public Element handle(MessageContext ctx)</b>{
+    IOperation op = detectOperation(ctx);
+    try {
+      op.performOperation(extractPayload(ctx.getRequestSOAPMessage()));
+    } catch (Exception e) {
+      // nothing
+    }
+    
+    return ctx.getResponseSOAPMessage();
+  }
+}
+</pre>
+<p>So this Web service gets some input and returns a SOAP message which says "Hello World". Now create a resource configuration 
+file for this Web service. It will call the <span class="code">handle</span> method of the provided implementation class.</p>
+<pre class="java">
+&lt;yanel:resource-config xmlns:yanel="http://www.wyona.org/yanel/rti/1.0">
+  &lt;yanel:rti name="soap" namespace="http://www.wyona.org/yanel/resource/1.0"/>
+  &lt;yanel:property name="ws-impl" value="my.package.HelloWorldWebServiceImpl"/>
+&lt;/yanel:resource-config>
+</pre>
+
+<p>Assuming that all the necessary libraries are configured properly the Yanel should be built and started. Then using some SOAP client, 
+e.g. <a href="http://www.soapui.org">soapui</a>, you can call that Web service by passing the following SOAP message to the configured resource:</p>
+<pre class="java">
+&lt;soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns="http//my/ns">
+  &lt;soapenv:Header/>
+  &lt;soapenv:Body>
+    <b>&lt;ns:SayHello/></b>
+  &lt;/soapenv:Body>
+&lt;/soapenv:Envelope>
+</pre>
+
+<p>Of course a more sophisticated solution would provide a WSDL and an XSD describing the Web service. 
+Still the above "Hello World" example is simple and it works.</p>
+</div>
+</body>
+</html>
\ No newline at end of file



More information about the Yanel-commits mailing list