You are viewing a plain text version of this content. The canonical link for it is here.
Posted to muse-dev@ws.apache.org by wi...@apache.org on 2005/08/12 22:45:46 UTC
svn commit: r232376 [8/112] - in
/webservices/muse/trunk/src/examples/client: ./ bin/ bin/axis/
bin/axis/com/ bin/axis/com/xyz/ bin/org/ bin/org/apache/ bin/org/apache/ws/
bin/org/apache/ws/client/ bin/org/apache/ws/client/async/
bin/org/apache/ws/clie...
Added: webservices/muse/trunk/src/examples/client/src/java/org/apache/ws/client/util/Consumer.java
URL: http://svn.apache.org/viewcvs/webservices/muse/trunk/src/examples/client/src/java/org/apache/ws/client/util/Consumer.java?rev=232376&view=auto
==============================================================================
--- webservices/muse/trunk/src/examples/client/src/java/org/apache/ws/client/util/Consumer.java (added)
+++ webservices/muse/trunk/src/examples/client/src/java/org/apache/ws/client/util/Consumer.java Fri Aug 12 13:38:04 2005
@@ -0,0 +1,273 @@
+/*=============================================================================*
+ * Confidential Copyright (c) 2004 Hewlett-Packard Development Company, L.P. *
+ *=============================================================================*/
+package org.apache.ws.client.util;
+
+import org.apache.ws.client.model.WsdmClient;
+import org.apache.ws.client.model.WsdmClientFactory;
+import org.apache.ws.client.model.WsdmInstance;
+import org.apache.ws.client.model.WsdmResource;
+import com.ibm.xmlns.stdwip.webServices.wsBaseNotification.NotifyDocument;
+import com.ibm.xmlns.stdwip.webServices.wsBaseNotification.TopicExpressionType;
+import org.apache.xmlbeans.XmlException;
+import org.apache.xmlbeans.XmlObject;
+import javax.xml.namespace.QName;
+import java.net.URL;
+
+/**
+ * Object that represents a notification consumer. This object will take care of
+ * creating and destroying subscriptions as well as spawning a notification consumer
+ * endpoint that can be used to accept incoming notification messages from producers.
+ * <p/>
+ * This class is meant to be subclassed. The subclass is to use the subscriber to create
+ * subscriptions and should also override {@link #consume(NotifyDocument)} to process
+ * notifications generated from those subscriptions.
+ */
+public class Consumer
+{
+ /** the default port that will be listened to by the listener */
+ private static final int DEFAULT_LISTENER_PORT = 9090;
+
+ /** object used to manage subscriptions */
+ private Subscriber m_subscriber;
+
+ /** listens for incoming notification requests */
+ private SimpleHttpPortListener m_listener;
+
+ /** the port that will be listened to be the listener */
+ private int m_listenerPort;
+
+ /** <code>true</code> when the consumer has started its listener and is ready to consume notifications */
+ private boolean m_started;
+
+ /**
+ * Creates the consumer object but does not start it. Call {@link #start()} to begin consuming.
+ */
+ public Consumer( )
+ {
+ m_subscriber = null;
+ m_listener = null;
+ m_listenerPort = DEFAULT_LISTENER_PORT;
+ m_started = false;
+ }
+
+ /**
+ * FOR TESTING ONLY!!!!!!!!!!!!!!!
+ * We can delete this later.
+ *
+ * @param args DOCUMENT_ME
+ * @throws Exception
+ */
+ public static void main( String[] args )
+ throws Exception
+ {
+ /** just a test util class to house common test code for this main method */
+ final class Util
+ {
+ /** */
+ public WsdmInstance getMyInstance( )
+ throws Exception
+ {
+ WsdmClient wc =
+ WsdmClientFactory.create( WsdmClientFactory.AXIS_CLIENT_TYPE, "localhost:8080", "wsdm" );
+ WsdmResource wr = wc.getResource( "sensor" );
+ WsdmInstance[] wi = wr.getInstances( );
+
+ return wi[0];
+ }
+
+ /** */
+ public TopicExpressionType getMyTopicExpressionType( WsdmInstance wi )
+ throws Exception
+ {
+ QName tq =
+ new QName( "http://www.ibm.com/xmlns/stdwip/web-services/WS-BaseNotification", "Topic" );
+ XmlObject[] topics = wi.getPropertyValue( tq );
+
+ return TopicExpressionType.Factory.parse( topics[1].newInputStream( ) );
+ }
+ }
+
+ // read the comments for this MyConsumer class - it tells you how you use the Consumer class
+
+ /**
+ * Demonstrates the usage pattern for Consumer class.
+ * We extend it and subscribe to the things we want to consume.
+ * We can then override consume() to do what we want.
+ */
+ final class MyConsumer
+ extends Consumer
+ {
+ /** we can do with the notification what we want here- for testing, just delegate to superclass */
+ protected void consume( NotifyDocument notif )
+ {
+ super.consume( notif );
+ }
+
+ /** if we want to, we can have our consumer subclass do the subscribing */
+ public void start( )
+ {
+ super.start( ); // make sure you start first - this creates our subscriber
+
+ try
+ {
+ // now we can subscribe to the notification producers
+ WsdmInstance notifProducer = new Util( ).getMyInstance( );
+ TopicExpressionType tet = new Util( ).getMyTopicExpressionType( notifProducer );
+
+ getSubscriber( ).subscribe( notifProducer, tet );
+ }
+ catch ( Exception e )
+ {
+ e.printStackTrace( );
+ }
+ }
+ }
+
+ // here our main method creates our consumer class - if we want, we can subscribe to producers here
+ // note that if our consumer already subscribed, we don't have to do this
+ // but nothing is stopping us from telling the consumer to subscribe to more things here
+ // this is helpful if, during runtime, we want the consumer to subscribe to new notifications
+ Consumer c = new MyConsumer( );
+ c.start( );
+
+ WsdmInstance notifProducer = new Util( ).getMyInstance( );
+ TopicExpressionType tet = new Util( ).getMyTopicExpressionType( notifProducer );
+ c.getSubscriber( ).subscribe( notifProducer, tet );
+
+ c.stop( );
+ }
+
+ /**
+ * Returns this consumer's endpoint URL. If this consumer has not yet been {@link #start() started},
+ * this method will return <code>null</code>.
+ *
+ * @return this consumer's endpoint URL that producers send notifications to; <code>null</code> if not consuming yet
+ */
+ public URL getConsumerUrl( )
+ {
+ return ( m_started ) ? m_listener.getServerUrl( ) : null;
+ }
+
+ /**
+ * Starts the consumer. This creates a network endpoint that begins accepting incoming notifications.
+ */
+ public void start( )
+ {
+ if ( !m_started )
+ {
+ final int consumerPort = getListenerPort( );
+ final int timeout = 0; // wait for an infinite time for notifications to come in
+
+ m_listener = new SimpleHttpPortListener( consumerPort, timeout );
+ m_subscriber = new Subscriber( m_listener.getServerUrl( ) );
+
+ // start a thread that continually listens for new notifications and consumes them as they come in
+ new Thread( new Runnable( )
+ {
+ public void run( )
+ {
+ while ( !m_listener.isStopped( ) )
+ {
+ String incomingMsg = m_listener.waitForIncomingMessage( );
+
+ if ( incomingMsg != null )
+ {
+ String notifXml = m_listener.getHttpBody( incomingMsg );
+
+ if ( notifXml != null )
+ {
+ try
+ {
+ consume( NotifyDocument.Factory.parse( notifXml ) );
+ }
+ catch ( XmlException e )
+ {
+ e.printStackTrace( );
+ }
+ }
+ }
+ }
+
+ return; // notification consumer thread is exiting
+ }
+ },
+ "notification-consumer" ).start( );
+
+ m_started = true;
+ }
+
+ return;
+ }
+
+ /**
+ * Stops the consumer. This terminates the network endpoint which disallows all future incoming notifications.
+ * Any currently existing subscriptions are canceled.
+ */
+ public void stop( )
+ {
+ if ( m_started )
+ {
+ try
+ {
+ m_subscriber.unsubscribe( );
+ m_listener.stopListening( );
+ m_started = false;
+ }
+ catch ( Exception e )
+ {
+ throw new RuntimeException( e );
+ }
+ }
+
+ return;
+ }
+
+ /**
+ * Sets the port in which this consumer's listener will listen to.
+ * Subclasses are free to call this in order to set their own port.
+ * Note that calling this method while the consumer is {@link #start() started}
+ * has no effect until the consumer is {@link #stop() stopped} and restarted.
+ *
+ * @param port port that is to be listened to for notifications
+ */
+ protected void setListenerPort( int port )
+ {
+ m_listenerPort = port;
+ }
+
+ /**
+ * Returns the port in which this consumer's listener will listen to.
+ * Subclasses may {@link #setListenerPort(int) set} the port; otherwise, the default
+ * will be {@link #DEFAULT_LISTENER_PORT}.
+ *
+ * @return port that is to be listened to for notifications
+ */
+ protected int getListenerPort( )
+ {
+ return m_listenerPort;
+ }
+
+ /**
+ * Returns the <code>Subscriber</code> used by this object to manage subscriptions.
+ * Subclasses are free to use this Subscriber to subscribe/unsubcribe to any notification
+ * producer they choose.
+ *
+ * @return the subscriber that this object uses to manage subscriptions
+ */
+ protected Subscriber getSubscriber( )
+ {
+ return m_subscriber;
+ }
+
+ /**
+ * The default consumption implementation that simply outputs the notification XML to stdout.
+ * Subclasses should normally override this method to perform its own custom tasks.
+ *
+ * @param notif the notification being consumed
+ */
+ protected void consume( NotifyDocument notif )
+ {
+ System.out.println( notif.xmlText( ) );
+ }
+}
\ No newline at end of file
Added: webservices/muse/trunk/src/examples/client/src/java/org/apache/ws/client/util/EnvelopeWrapper.java
URL: http://svn.apache.org/viewcvs/webservices/muse/trunk/src/examples/client/src/java/org/apache/ws/client/util/EnvelopeWrapper.java?rev=232376&view=auto
==============================================================================
--- webservices/muse/trunk/src/examples/client/src/java/org/apache/ws/client/util/EnvelopeWrapper.java (added)
+++ webservices/muse/trunk/src/examples/client/src/java/org/apache/ws/client/util/EnvelopeWrapper.java Fri Aug 12 13:38:04 2005
@@ -0,0 +1,79 @@
+/*=============================================================================*
+ * Confidential Copyright (c) 2004 Hewlett-Packard Development Company, L.P. *
+ *=============================================================================*/
+package org.apache.ws.client.util;
+
+import org.apache.commons.io.IoUtils;
+import org.apache.xmlbeans.XmlException;
+import org.apache.xmlbeans.XmlObject;
+import org.xmlsoap.schemas.soap.envelope.Envelope;
+import org.xmlsoap.schemas.soap.envelope.EnvelopeDocument;
+
+import javax.xml.soap.SOAPException;
+import javax.xml.soap.SOAPMessage;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+/**
+ * Wraps an XmlBean Envelope (or a javax.xml.soap.SOAPMessage class) to provide
+ * utility methods for getting at the XmlBean objects.
+ *
+ * @author Ian Springer, Sal Campana
+ */
+public class EnvelopeWrapper
+{
+ private Envelope m_envelope;
+
+ /**
+ * Constructor. Takes an XmlBean Envelope type.
+ *
+ * @param envelope
+ */
+ public EnvelopeWrapper( Envelope envelope )
+ {
+ m_envelope = envelope;
+ }
+
+ /**
+ * Constructor. Takes a java.xml.soap.SOAPMessage type and converts
+ * it to an XmlObject Envelope type inside the wrapper.
+ *
+ * @param message
+ * @throws IOException
+ * @throws SOAPException
+ * @throws XmlException
+ */
+ public EnvelopeWrapper( SOAPMessage message )
+ throws IOException,
+ SOAPException,
+ XmlException
+ {
+ ByteArrayOutputStream byteout = new ByteArrayOutputStream( );
+ message.writeTo( byteout );
+ ByteArrayInputStream byteinput = IoUtils.toByteArrayInputStream( byteout );
+ m_envelope = ((EnvelopeDocument) XmlObject.Factory.parse( byteinput )).getEnvelope();
+ byteout.close( );
+ byteinput.close( );
+ }
+
+ /**
+ * Returns the BodyWrapper class for accessing the body XmlObjects
+ *
+ * @return BodyWrapper
+ */
+ public BodyWrapper getBodyWrapper( )
+ {
+ return new BodyWrapper( m_envelope.getBody( ) );
+ }
+
+ /**
+ * Returns the HeaderWrapper class for accessing the header XmlObjects
+ *
+ * @return HeaderWrapper
+ */
+ public HeaderWrapper getHeaderWrapper( )
+ {
+ return new HeaderWrapper( m_envelope.getHeader( ) );
+ }
+}
\ No newline at end of file
Added: webservices/muse/trunk/src/examples/client/src/java/org/apache/ws/client/util/HeaderWrapper.java
URL: http://svn.apache.org/viewcvs/webservices/muse/trunk/src/examples/client/src/java/org/apache/ws/client/util/HeaderWrapper.java?rev=232376&view=auto
==============================================================================
--- webservices/muse/trunk/src/examples/client/src/java/org/apache/ws/client/util/HeaderWrapper.java (added)
+++ webservices/muse/trunk/src/examples/client/src/java/org/apache/ws/client/util/HeaderWrapper.java Fri Aug 12 13:38:04 2005
@@ -0,0 +1,86 @@
+/*=============================================================================*
+ * Confidential Copyright (c) 2004 Hewlett-Packard Development Company, L.P. *
+ *=============================================================================*/
+package org.apache.ws.client.util;
+
+import org.apache.xmlbeans.XmlCursor;
+import org.apache.xmlbeans.XmlObject;
+import org.xmlsoap.schemas.soap.envelope.Header;
+import javax.xml.namespace.QName;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Wraps an XmlBean generated Header to provide
+ * utility methods for getting at the XmlBean objects.
+ *
+ * @author Ian Springer, Sal Campana
+ */
+public class HeaderWrapper
+{
+ private Header m_header;
+
+ /**
+ * Creates a new {@link HeaderWrapper} object.
+ *
+ * @param header
+ */
+ public HeaderWrapper( Header header )
+ {
+ m_header = header;
+ }
+
+ /**
+ * Returns the top-level elements from the header as an XmlBean Object[].
+ *
+ * @return XmlObject[] of header elements
+ */
+ public XmlObject[] getHeaderElements( )
+ {
+ if ( m_header == null )
+ {
+ return new XmlObject[0];
+ }
+
+ XmlCursor xmlCursor = m_header.newCursor( );
+ xmlCursor.toNextToken( );
+
+ //get the first child of the body i.e. the response message, or fault
+ XmlObject xmlBeanResponseMessage = xmlCursor.getObject( );
+ List xmlObjects = new ArrayList( );
+ xmlObjects.add( xmlBeanResponseMessage );
+
+ //add the rest of the top-level-elements to the list
+ while ( xmlCursor.toNextSibling( ) )
+ {
+ xmlObjects.add( xmlCursor.getObject( ) );
+ }
+
+ return (XmlObject[]) xmlObjects.toArray( new XmlObject[0] );
+ }
+
+ /**
+ * Returns the top-level header elements with the specified name.
+ *
+ * @return the top-level header elements with the specified name
+ */
+ public XmlObject[] getHeaderElements( QName qName )
+ {
+ if ( qName == null )
+ {
+ throw new IllegalArgumentException( "Null name is not allowed." );
+ }
+
+ XmlObject[] allHeaderElems = getHeaderElements( );
+ List headerElems = new ArrayList( );
+ for ( int i = 0; i < allHeaderElems.length; i++ )
+ {
+ if ( qName.equals( allHeaderElems[i].schemaType( ).getName( ) ) )
+ {
+ headerElems.add( allHeaderElems[i] );
+ }
+ }
+
+ return (XmlObject[]) headerElems.toArray( new XmlObject[0] );
+ }
+}
\ No newline at end of file
Added: webservices/muse/trunk/src/examples/client/src/java/org/apache/ws/client/util/SimpleHttpPortListener.java
URL: http://svn.apache.org/viewcvs/webservices/muse/trunk/src/examples/client/src/java/org/apache/ws/client/util/SimpleHttpPortListener.java?rev=232376&view=auto
==============================================================================
--- webservices/muse/trunk/src/examples/client/src/java/org/apache/ws/client/util/SimpleHttpPortListener.java (added)
+++ webservices/muse/trunk/src/examples/client/src/java/org/apache/ws/client/util/SimpleHttpPortListener.java Fri Aug 12 13:38:04 2005
@@ -0,0 +1,159 @@
+/*=============================================================================*
+ * Confidential Copyright (c) 2004 Hewlett-Packard Development Company, L.P. *
+ *=============================================================================*/
+package org.apache.ws.client.util;
+
+import org.apache.commons.httpclient.Header;
+import org.apache.commons.httpclient.HeaderGroup;
+import java.net.InetAddress;
+import java.net.URL;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+import java.util.StringTokenizer;
+import java.util.TimeZone;
+
+/**
+ * Listens for incoming HTTP messages and provides convienence methods to access
+ * HTTP headers and the HTTP body. An HTTP response will be sent back to the client in reponse
+ * to all messages received.
+ */
+public class SimpleHttpPortListener
+ extends SimplePortListener
+{
+ /** format used to build a date for the HTTP response that is returned to the client sending us a message */
+ private static DateFormat HTTP_DATE_FORMAT = new SimpleDateFormat( "EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US );
+
+ static
+ {
+ HTTP_DATE_FORMAT.setTimeZone( TimeZone.getTimeZone( "GMT" ) );
+ }
+
+ /**
+ * @see SimplePortListener#SimplePortListener(int, int)
+ */
+ public SimpleHttpPortListener( int port,
+ int timeout )
+ {
+ super( port, timeout );
+ }
+
+ /**
+ * Returns a URL of the form <code>http://hostname:port</code> where
+ * <code>hostname</code> and <code>port</code> is of this listener.
+ *
+ * @return the HTTP URL used to access this listener
+ */
+ public URL getServerUrl( )
+ {
+ try
+ {
+ return new URL( "http://" + InetAddress.getLocalHost( ).getCanonicalHostName( ) + ":"
+ + getServerSocket( ).getLocalPort( ) );
+ }
+ catch ( Exception e )
+ {
+ return null;
+ }
+ }
+
+ /**
+ * Returns the HTTP body of the <code>message</code> string.
+ * If it doesn't look like an HTTP message, <code>null</code> is returned.
+ *
+ * @param message the HTTP message (typically this is the value returned by {@link SimplePortListener#waitForIncomingMessage()})
+ *
+ * @return the HTTP body of the message (the HTTP headers will be stripped out)
+ */
+ public String getHttpBody( String message )
+ {
+ final String headersBodyDelimiter = "\r\n\r\n";
+ int endOfHeaders = message.indexOf( headersBodyDelimiter );
+ int startOfBody = endOfHeaders + headersBodyDelimiter.length( );
+
+ return ( endOfHeaders != -1 ) ? message.substring( startOfBody ) : null;
+ }
+
+ /**
+ * Returns the HTTP headers found in the given HTTP message in a map keyed on the header names.
+ * If <code>message</code> doesn't look like an HTTP message, <code>null</code> is returned.
+ *
+ * @param message the HTTP message (typically this is the value returned by {@link SimplePortListener#waitForIncomingMessage()})
+ *
+ * @return the HTTP headers found in the message (the HTTP body will be ignored)
+ */
+ public Map getHttpHeaders( String message )
+ {
+ final String headersDelimiter = "\r\n"; // each header is separated by this
+ final String nvpDelimiter = ":"; // delimits between a header's name and value
+ final String headersStartDelimiter = "\r\n"; // from the start of the message, this delimits the first header
+ final String headersBodyDelimiter = "\r\n\r\n"; // delimits between the headers and the HTTP body
+ int endOfHeaders = message.indexOf( headersBodyDelimiter );
+ int startOfHeaders = message.indexOf( headersStartDelimiter );
+
+ if ( ( endOfHeaders == -1 ) || ( startOfHeaders == -1 ) )
+ {
+ return null;
+ }
+
+ startOfHeaders += headersStartDelimiter.length( ); // skip the delimiter
+
+ String headers = message.substring( startOfHeaders, endOfHeaders );
+ StringTokenizer strtok = new StringTokenizer( headers, headersDelimiter );
+ Map headerMap = new HashMap( );
+
+ while ( strtok.hasMoreTokens( ) )
+ {
+ String nvp = strtok.nextToken( );
+ int nvpDelimiterIndex = nvp.indexOf( nvpDelimiter );
+ String name = nvp.substring( 0, nvpDelimiterIndex );
+ String value = nvp.substring( nvpDelimiterIndex + 1 );
+
+ headerMap.put( name.trim( ),
+ value.trim( ) );
+ }
+
+ return headerMap;
+ }
+
+ /**
+ * Build a one-way HTTP response message that complies to the WS-I
+ * Basic Profile 1.0, section 5.6.10 - see
+ * http://www.ws-i.org/Profiles/BasicProfile-1.0-2004-04-16.html#refinement16651160
+ *
+ * @return a WS-I-compliant Notify response message
+ */
+ protected String buildResponse( )
+ {
+ final String httpServerName = "WS-NotificationConsumer/1.0";
+ final String httpVersion = "1.0";
+ final String httpStatus = "202 Accepted";
+
+ Date timeNow = new Date( );
+ Date sameTimeTomorrow = new Date( timeNow.getTime( ) + ( 24 * 60 * 60 * 1000 ) );
+ StringBuffer responseBuf = new StringBuffer( "HTTP/" );
+
+ responseBuf.append( httpVersion );
+ responseBuf.append( " " );
+ responseBuf.append( httpStatus );
+ responseBuf.append( "\r\n" );
+ HeaderGroup headerGroup = new HeaderGroup( );
+ headerGroup.addHeader( new Header( "Date",
+ HTTP_DATE_FORMAT.format( timeNow ) ) );
+ headerGroup.addHeader( new Header( "Server", httpServerName ) );
+ headerGroup.addHeader( new Header( "Cache-Control", "max-age=86400" ) );
+ headerGroup.addHeader( new Header( "Expires",
+ HTTP_DATE_FORMAT.format( sameTimeTomorrow ) ) );
+ Header[] headers = headerGroup.getAllHeaders( );
+
+ for ( int i = 0; i < headers.length; i++ )
+ {
+ responseBuf.append( headers[i] );
+ }
+
+ return responseBuf.toString( );
+ }
+}
\ No newline at end of file
Added: webservices/muse/trunk/src/examples/client/src/java/org/apache/ws/client/util/SimplePortListener.java
URL: http://svn.apache.org/viewcvs/webservices/muse/trunk/src/examples/client/src/java/org/apache/ws/client/util/SimplePortListener.java?rev=232376&view=auto
==============================================================================
--- webservices/muse/trunk/src/examples/client/src/java/org/apache/ws/client/util/SimplePortListener.java (added)
+++ webservices/muse/trunk/src/examples/client/src/java/org/apache/ws/client/util/SimplePortListener.java Fri Aug 12 13:38:04 2005
@@ -0,0 +1,356 @@
+/*=============================================================================*
+ * Confidential Copyright (c) 2004 Hewlett-Packard Development Company, L.P. *
+ *=============================================================================*/
+package org.apache.ws.client.util;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.IOException;
+import java.io.InterruptedIOException;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.util.Vector;
+
+/**
+ * A simple port listener that accepts multiple messages on a TCP/IP socket and returns a simple response string in reply.
+ * When this object is instantiated, it will spawn a thread
+ * and listen for messages on the specified port. Call {@link #waitForIncomingMessage()}
+ * to block, waiting for a message. If multiple messages have been receieved, each call to
+ * {@link #waitForIncomingMessage()} will return the messages in the order than were received.
+ */
+public class SimplePortListener
+{
+ /** a value used to indicate that our listening thread has stopped */
+ public static final String STOP_LISTENING_MESSAGE = "ERROR: listening stopped";
+
+ /**
+ * the buffer to store the incoming message
+ */
+ private StringBuffer m_incomingMessage;
+
+ /**
+ * a list of all messages received but not yet picked up via {@link #waitForIncomingMessage()}
+ */
+ private Vector m_messages;
+
+ /** the thread that listens */
+ private Thread m_listenerThread;
+
+ /** will be true when this listener has been asked to stop */
+ private boolean m_stopped;
+
+ /** the server socket used to accept incoming messages */
+ private ServerSocket m_serverSocket;
+
+ /**
+ * Instantiates the object and immediately begins listening for a message.
+ *
+ * @param port the port to listen to
+ * @param timeout the time (in milliseconds) the socket accept() will wait for an incoming connection
+ */
+ public SimplePortListener( int port,
+ int timeout )
+ {
+ m_incomingMessage = new StringBuffer( );
+ m_messages = new Vector( );
+ m_stopped = false;
+
+ // spawn the thread (this assigns the thread to m_listenerThread and creates m_serverSocket)
+ spawnListeningThread( port, timeout );
+
+ // There is a small window of time between the listener thread getting created and the server socket getting bound.
+ // Wait for that small window of time to elapse. This ensures that when the constructor returns, the listener thread
+ // has been created and the server socket is actually listening for messages.
+ while ( !m_serverSocket.isBound( ) && !m_stopped && m_listenerThread.isAlive( ) )
+ {
+ ;
+ }
+
+ return;
+ }
+
+ /**
+ * Returns <code>true</code> if there is at least one message that has been received.
+ * Use this method to determine if the next call to {@link #waitForIncomingMessage()} will block.
+ *
+ * @return <code>true</code> if a message has been received but not yet collected or <code>false</code>
+ * if no messages are available to be collected yet.
+ *
+ * @see #waitForIncomingMessage()
+ */
+ public boolean isMessageAvailable( )
+ {
+ return !m_messages.isEmpty( );
+ }
+
+ /**
+ * Returns <code>true</code> if the listener has stopped listening for messages. A stopped listener
+ * cannot be restarted.
+ *
+ * @return <code>true</code> if this object is no longer accepting new messages.
+ */
+ public boolean isStopped( )
+ {
+ return m_stopped;
+ }
+
+ /**
+ * Tells this listener to stop listening for more messages.
+ */
+ public void stopListening( )
+ {
+ m_stopped = true;
+
+ while ( m_listenerThread.isAlive( ) )
+ {
+ try
+ {
+ m_serverSocket.close( );
+ }
+ catch ( IOException e )
+ {
+ }
+
+ m_listenerThread.interrupt( );
+ }
+
+ return;
+ }
+
+ /**
+ * Returns the next incoming message in the order it was received; waits for the incoming message if
+ * none have been received yet. Call {@link #isMessageAvailable()} to determine if this method
+ * will block.
+ * <p/>
+ * This method will block waiting for the incoming message to come in or for
+ * an error to occur or until the listening has been {@link #stopListening() stopped}.
+ *
+ * @return the incoming message as an immutable <code>String</code>
+ *
+ * @see #isMessageAvailable()
+ */
+ public String waitForIncomingMessage( )
+ {
+ String newMessage;
+
+ synchronized ( m_incomingMessage )
+ {
+ while ( ( m_messages.isEmpty( ) ) && !m_stopped )
+ {
+ try
+ {
+ m_incomingMessage.wait( 1000 );
+ }
+ catch ( InterruptedException e )
+ {
+ }
+ }
+
+ synchronized ( m_messages )
+ {
+ if ( !m_messages.isEmpty( ) )
+ {
+ newMessage = (String) m_messages.get( 0 );
+ m_messages.remove( 0 );
+ }
+ else
+ {
+ newMessage = STOP_LISTENING_MESSAGE;
+ }
+ }
+ }
+
+ return newMessage;
+ }
+
+ /**
+ * Returns the server socket used to receive incoming messages.
+ *
+ * @return the server socket that is or was used to receive incoming TCP/IP messages
+ */
+ protected ServerSocket getServerSocket( )
+ {
+ return m_serverSocket;
+ }
+
+ /**
+ * Builds a simple response string that will be sent back to the client to acknowledge the receipt of the message.
+ * Subclasses may override this method if a more sophisticated response string should be sent back (such as a set of HTTP
+ * response headers).
+ *
+ * @return simple one-line response string.
+ */
+ protected String buildResponse( )
+ {
+ return "Message Received";
+ }
+
+ /**
+ * Creates the thread that listens for incoming TCP/IP messages. When an incoming message is received, it is stored in the
+ * <code>m_incomingMessage</code> string buffer and <code>notify</code> on that string buffer will
+ * be called to let the caller know that it is ready. <code>m_messages</code> will be used to store immutable
+ * forms of all incoming messages that are received by the listening thread.
+ * <p/>
+ * The incoming message string buffer must be non-<code>null</code> and must be empty.
+ * <p/>
+ * If an error occurs, the string buffer will be filled with the string "ERROR:" followed by the exception message.
+ * Even on an error, <code>notify</code> will be called to let the caller know that something happened.
+ * <p/>
+ * Note that this method does not block - it spawns a thread to perform the listening and returns immediately.
+ * <p/>
+ * This will return a simple one-line response string back to the client.
+ * <p/>
+ * The created thread will run indefinitely, or until {@link #stopListening() stopped}.
+ *
+ * @param port the port to listen to
+ * @param timeout the time (in milliseconds) the socket accept() will wait for an incoming connection
+ *
+ * @throws IllegalArgumentException if the given buffer was <code>null</code> or not empty
+ */
+ protected void spawnListeningThread( final int port,
+ final int timeout )
+ throws IllegalArgumentException
+ {
+ // use as a monitor lock to determine when the thread has started
+ // this must be final to allow for the inner Runnable class to access it
+ final Object listenerStarted = new Object( );
+
+ m_listenerThread =
+ new Thread( new Runnable( )
+ {
+ public void run( )
+ {
+ m_serverSocket = null;
+
+ while ( !m_stopped )
+ {
+ try
+ {
+ // create our server socket if not yet created
+ if ( m_serverSocket == null )
+ {
+ m_serverSocket = new ServerSocket( port );
+ m_serverSocket.setSoTimeout( timeout );
+ }
+
+ // let the outer method know that we have started and just about to block on the accept
+ synchronized ( listenerStarted )
+ {
+ listenerStarted.notify( );
+ }
+
+ Socket sock = m_serverSocket.accept( );
+ sock.setSoTimeout( 500 );
+
+ BufferedInputStream bufIn = new BufferedInputStream( sock.getInputStream( ) );
+ BufferedOutputStream bufOut = new BufferedOutputStream( sock.getOutputStream( ) );
+ byte[] responseBytes = buildResponse( ).toString( ).getBytes( );
+
+ bufOut.write( responseBytes, 0, responseBytes.length );
+ bufOut.flush( );
+
+ try
+ {
+ byte[] incoming = new byte[1];
+
+ synchronized ( m_incomingMessage )
+ {
+ m_incomingMessage.setLength( 0 ); // clear it out
+
+ while ( bufIn.read( incoming ) != -1 )
+ {
+ m_incomingMessage.append( new String( incoming ) );
+ }
+ }
+ }
+ catch ( InterruptedIOException ignored )
+ {
+ }
+
+ bufIn.close( );
+ bufOut.close( );
+ }
+ catch ( Throwable t )
+ {
+ synchronized ( m_incomingMessage )
+ {
+ m_incomingMessage.delete( 0,
+ m_incomingMessage.length( ) );
+
+ if ( !m_stopped )
+ {
+ m_incomingMessage.append( "ERROR:" );
+ m_incomingMessage.append( t );
+ }
+ }
+ }
+ finally
+ {
+ synchronized ( m_incomingMessage )
+ {
+ // make sure something goes in the message, even if nothing was received
+ // don't bother if we were stopped, we'll add our own stopped message
+ if ( ( m_incomingMessage.length( ) == 0 ) && !m_stopped )
+ {
+ m_incomingMessage.append( "ERROR: incoming message was empty" );
+ }
+
+ // add our new incoming message to the list of messages
+ if ( m_incomingMessage.length( ) > 0 )
+ {
+ m_messages.add( m_incomingMessage.toString( ) );
+ }
+
+ // if we are stopped, add another message to let the client know we stopped
+ if ( m_stopped )
+ {
+ m_messages.add( STOP_LISTENING_MESSAGE );
+ }
+
+ // wake up the wait method
+ m_incomingMessage.notify( );
+ }
+
+ if ( m_stopped && ( m_serverSocket != null ) )
+ {
+ try
+ {
+ m_serverSocket.close( );
+ }
+ catch ( IOException ignored )
+ {
+ }
+ }
+
+ // do this as a fail safe
+ synchronized ( listenerStarted )
+ {
+ listenerStarted.notify( );
+ }
+ }
+ }
+
+ // this is the listener thread exiting
+ return;
+ }
+ } );
+
+ // start listening and then return when the thread has officially gone live
+ // and the socket is ready to be accepted
+ synchronized ( listenerStarted )
+ {
+ m_listenerThread.setDaemon( true );
+ m_listenerThread.start( );
+
+ try
+ {
+ listenerStarted.wait( );
+ }
+ catch ( InterruptedException ignored )
+ {
+ }
+ }
+
+ return;
+ }
+}
\ No newline at end of file
Added: webservices/muse/trunk/src/examples/client/src/java/org/apache/ws/client/util/Subscriber.java
URL: http://svn.apache.org/viewcvs/webservices/muse/trunk/src/examples/client/src/java/org/apache/ws/client/util/Subscriber.java?rev=232376&view=auto
==============================================================================
--- webservices/muse/trunk/src/examples/client/src/java/org/apache/ws/client/util/Subscriber.java (added)
+++ webservices/muse/trunk/src/examples/client/src/java/org/apache/ws/client/util/Subscriber.java Fri Aug 12 13:38:04 2005
@@ -0,0 +1,402 @@
+/*=============================================================================*
+ * Confidential Copyright (c) 2004 Hewlett-Packard Development Company, L.P. *
+ *=============================================================================*/
+package org.apache.ws.client.util;
+
+import org.apache.ws.client.model.WsdmClient;
+import org.apache.ws.client.model.WsdmInstance;
+import org.apache.ws.client.model.WsdmOperation;
+import com.ibm.xmlns.stdwip.webServices.wsBaseNotification.TopicExpressionType;
+import org.apache.xmlbeans.XmlObject;
+import org.xmlsoap.schemas.ws.x2003.x03.addressing.EndpointReferenceDocument;
+import org.xmlsoap.schemas.ws.x2003.x03.addressing.EndpointReferenceType;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Acts as a WS-Notification Subscriber and will subscribe a notification consumer to
+ * a set of notification producers.
+ * <p>
+ * This object groups subscriptions based on which notification producers are subscribed to with each
+ * group holding subscriptions to individual topics.
+ * <p>
+ * Subscriptions may be canceled individually (see {@link #unsubscribe(WsdmInstance, TopicExpressionType)})
+ * or en masse (see {@link #unsubscribe()} and {@link #unsubscribe(WsdmInstance)}).
+ */
+public class Subscriber
+{
+ /** the EPR of the notification consumer that is to be subscribed */
+ private final EndpointReferenceType m_notificationConsumer;
+
+ /** the set of all subscriptions, keyed on WsdmInstance objects (each value is also a Map of Subscriptions keyed on topic expression) */
+ private final Map m_subscriptions = new HashMap( );
+
+ /**
+ * Creates the subscriber given a consumer's EPR.
+ *
+ * @param consumer the EPR of the consumer who will be subscribed
+ */
+ public Subscriber( EndpointReferenceType consumer )
+ {
+ m_notificationConsumer = consumer;
+ }
+
+ /**
+ * Creates the subscriber given a consumer's <code>WsdmInstance</code> object representation.
+ *
+ * @param consumer the EPR of the consumer who will be subscribed
+ */
+ public Subscriber( WsdmInstance consumer )
+ {
+ try
+ {
+ m_notificationConsumer = consumer.getEPR( );
+ }
+ catch ( Exception e )
+ {
+ throw new IllegalArgumentException( e.toString( ) );
+ }
+ }
+
+ /**
+ * Creates the subscriber given just the consumer's endpoint URL. Since only a URL is provided,
+ * the consumer's EPR will not consist of any WS-Addressing information.
+ *
+ * @param consumer the endpoint URL of the consumer
+ */
+ public Subscriber( URL consumer )
+ {
+ m_notificationConsumer = EndpointReferenceDocument.Factory.newInstance( ).addNewEndpointReference( );
+
+ m_notificationConsumer.addNewAddress( ).setStringValue( consumer.toString( ) );
+ }
+
+ /**
+ * Returns the EPR to a subscription resource for the subscription on the given producer topic.
+ * <code>null</code> will be returned if this object is not maintaining such a subscription.
+ *
+ * @param notificationProducer the producer resource whose is subscribed to
+ * @param topic the topic that is subscribed to
+ *
+ * @return the subscription resource EPR, or <code>null</code> if there is no such subscription
+ */
+ public synchronized Subscription getSubscription( WsdmInstance notificationProducer,
+ TopicExpressionType topic )
+ {
+ Subscription retSubscription = null;
+ Map producerSubscriptions = (Map) m_subscriptions.get( notificationProducer );
+
+ if ( producerSubscriptions != null )
+ {
+ retSubscription = (Subscription) producerSubscriptions.get( topic );
+ }
+
+ return retSubscription;
+ }
+
+ /**
+ * Returns an array of EPRs refering to all subscription resources for all subscriptions on the given producer.
+ * An empty array will be returned if no subscriptions exist.
+ *
+ * @param notificationProducer the producer resource whose is subscribed to
+ *
+ * @return array of subscription resource EPRs
+ */
+ public synchronized Subscription[] getSubscriptions( WsdmInstance notificationProducer )
+ {
+ Subscription[] retSubscriptions;
+ Map producerSubscriptions = (Map) m_subscriptions.get( notificationProducer );
+
+ if ( producerSubscriptions != null )
+ {
+ Collection subscriptions = producerSubscriptions.values( );
+ retSubscriptions = (Subscription[]) subscriptions.toArray( new Subscription[subscriptions.size( )] );
+ }
+ else
+ {
+ retSubscriptions = new Subscription[0];
+ }
+
+ return retSubscriptions;
+ }
+
+ /**
+ * Returns an array of EPRs refering to all subscription resources for all subscriptions for all producers.
+ * An empty array will be returned if no subscriptions exist.
+ *
+ * @return array of subscription resource EPRs
+ */
+ public synchronized Subscription[] getSubscriptions( )
+ {
+ List retSubscriptions = new ArrayList( );
+
+ for ( Iterator iter = m_subscriptions.values( ).iterator( ); iter.hasNext( ); )
+ {
+ Map producerSubscriptions = (Map) iter.next( );
+
+ retSubscriptions.addAll( producerSubscriptions.values( ) );
+ }
+
+ return (Subscription[]) retSubscriptions.toArray( new Subscription[retSubscriptions.size( )] );
+ }
+
+ /**
+ * Subscribes the notification consumer to the given notification producer on the given topic.
+ * If the subscription already exists, this method will <b>not</b> subscribe again.
+ *
+ * @param notificationProducer the producer of the notifications to be subscribed to
+ * @param topicExpression the topic to subscribe to
+ *
+ * @throws Exception on any error that caused the request to fail
+ */
+ public synchronized void subscribe( WsdmInstance notificationProducer,
+ TopicExpressionType topicExpression )
+ throws Exception
+ {
+ EndpointReferenceType subscriptionEpr;
+ WsdmOperation subscribeOp = notificationProducer.findOperation( "Subscribe" );
+
+ if ( subscribeOp == null )
+ {
+ throw new IllegalArgumentException( "The given WsdmInstance is not a notification producer:"
+ + notificationProducer.getName( ) );
+ }
+
+ // actually perform the subscribe
+ Hashtable params = new Hashtable( );
+ params.put( "TopicExpression", topicExpression );
+ params.put( "ConsumerReference", m_notificationConsumer );
+ params.put( "UseNotify", Boolean.TRUE );
+
+ XmlObject[] results = notificationProducer.invoke( subscribeOp, params );
+
+ // TODO get the subscription resource EPR from the invoke results
+ subscriptionEpr = null;
+
+ // add the new subscription to our set of exiting subscriptions
+ addSubscription( new Subscription( notificationProducer, topicExpression, subscriptionEpr ) );
+
+ return;
+ }
+
+ /**
+ * Unsubscribes the notification consumer from the given notification producer's topic.
+ * If the subscription does not already exist, this method will do nothing.
+ *
+ * @param notificationProducer the producer of the notifications to be unsubscribed from
+ * @param topicExpression the topic to unsubscribe from
+ *
+ * @throws Exception on any error that caused the request to fail
+ */
+ public synchronized void unsubscribe( WsdmInstance notificationProducer,
+ TopicExpressionType topicExpression )
+ throws Exception
+ {
+ Subscription doomedSubscription = getSubscription( notificationProducer, topicExpression );
+
+ unsubscribe( doomedSubscription );
+
+ return;
+ }
+
+ /**
+ * Unsubscribes the notification consumer from any and all subscribed topics from the given notification producer.
+ *
+ * @param notificationProducer the producer of the notifications to be unsubscribed from
+ *
+ * @throws Exception on any error that caused the request to fail
+ */
+ public synchronized void unsubscribe( WsdmInstance notificationProducer )
+ throws Exception
+ {
+ Subscription[] doomedSubscriptions = getSubscriptions( notificationProducer );
+
+ for ( int i = 0; i < doomedSubscriptions.length; i++ )
+ {
+ unsubscribe( doomedSubscriptions[i] );
+ }
+
+ return;
+ }
+
+ /**
+ * Unsubscribes the notification consumer from any and all topics on any and all notification producers.
+ *
+ * @throws Exception on any error that caused the request to fail
+ */
+ public synchronized void unsubscribe( )
+ throws Exception
+ {
+ Subscription[] doomedSubscriptions = getSubscriptions( );
+
+ for ( int i = 0; i < doomedSubscriptions.length; i++ )
+ {
+ unsubscribe( doomedSubscriptions[i] );
+ }
+
+ return;
+ }
+
+ /**
+ * Adds the given subscription to our internal set of existing subscriptions.
+ * This does not actually perform any type of subscribing, this method merely adds
+ * the subscription to our internal map structure.
+ *
+ * @param newSubscription the new subscription to add
+ */
+ protected void addSubscription( Subscription newSubscription )
+ {
+ // get the map of all the subscriptions to the producer of the new subscription
+ Map producerSubscriptions = (Map) m_subscriptions.get( newSubscription.getNotificationProducer( ) );
+
+ // if this producer has not yet been subscribed to, create the new, empty map for it
+ if ( producerSubscriptions == null )
+ {
+ producerSubscriptions = new HashMap( );
+ m_subscriptions.put( newSubscription.getNotificationProducer( ),
+ producerSubscriptions );
+ }
+
+ // add the new subscription to the map of producer subscriptions, keyed on the topic that is subscribed to
+ producerSubscriptions.put( newSubscription.getTopic( ),
+ newSubscription );
+
+ return;
+ }
+
+ /**
+ * Removes the given subscription from our internal set of existing subscriptions.
+ * This does not actually perform any type of unsubscribing, this method merely removes
+ * the subscription from our internal map structure.
+ *
+ * @param doomedSubscription the subscription to remove
+ */
+ protected void removeSubscription( Subscription doomedSubscription )
+ {
+ // get the map of all the subscriptions to the producer of the doomed subscription
+ Map producerSubscriptions = (Map) m_subscriptions.get( doomedSubscription.getNotificationProducer( ) );
+
+ if ( producerSubscriptions != null )
+ {
+ // remove the subscription from the map of producer subscriptions (this map is keyed on topic)
+ producerSubscriptions.remove( doomedSubscription.getTopic( ) );
+
+ // if that was the last subscription for this producer, remove the entire producer subscription map, too
+ if ( producerSubscriptions.isEmpty( ) )
+ {
+ m_subscriptions.remove( doomedSubscription.getNotificationProducer( ) );
+ }
+ }
+
+ return;
+ }
+
+ /**
+ * Unsubscribes the given subscription and removes the subscription from our internal map structure.
+ *
+ * @param doomedSubscription the subscription that is to be destroyed
+ */
+ protected void unsubscribe( Subscription doomedSubscription )
+ {
+ // perform the actual WSDM unsubscribe here by destroying the subscription resource
+ WsdmInstance subscriptionWsdmInstance = doomedSubscription.getSubscriptionWsdmInstance( );
+
+ try
+ {
+ WsdmOperation destroyOp = subscriptionWsdmInstance.findOperation( "Destroy" );
+ subscriptionWsdmInstance.invoke( destroyOp, null );
+ }
+ catch ( Exception e )
+ {
+ throw new IllegalArgumentException( "The subscription WsdmInstance does not conform to WS-ResourceLifetime:"
+ + subscriptionWsdmInstance.getName( ) );
+ }
+
+ // remove the subscription from our set of exiting subscriptions
+ removeSubscription( doomedSubscription );
+
+ return;
+ }
+
+ /**
+ * Immutable inner class used to hold information on an existing subscription, including the WsdmInstance
+ * of the notification producer, the topic subscribed to and the subscription resource EPR.
+ */
+ public class Subscription
+ {
+ private final WsdmInstance m_notificationProducer;
+ private final TopicExpressionType m_topic;
+ private final EndpointReferenceType m_subscriptionEpr;
+
+ /**
+ * Creates the object.
+ *
+ * @param notificationProducer the producer who is subscribed to
+ * @param topic the topic that is subscribed to
+ * @param subscriptionEpr the EPR of the subscription resource
+ */
+ public Subscription( final WsdmInstance notificationProducer,
+ final TopicExpressionType topic,
+ final EndpointReferenceType subscriptionEpr )
+ {
+ m_notificationProducer = notificationProducer;
+ m_topic = topic;
+ m_subscriptionEpr = subscriptionEpr;
+ }
+
+ /**
+ * Returns the notification producer.
+ *
+ * @return the notification producer
+ */
+ public WsdmInstance getNotificationProducer( )
+ {
+ return m_notificationProducer;
+ }
+
+ /**
+ * Returns the subscription resource EPR.
+ *
+ * @return the subscription EPR
+ */
+ public EndpointReferenceType getSubscriptionEpr( )
+ {
+ return m_subscriptionEpr;
+ }
+
+ /**
+ * Returns a <code>WsdmInstance</code> that can be used to access the
+ * Subscription resource.
+ * The returned Subscription resource has the WS-Notification Subscription Manager interface.
+ *
+ * @return subscription resource instance
+ */
+ public WsdmInstance getSubscriptionWsdmInstance( )
+ {
+ WsdmInstance retSubcriptionInstance = null;
+ WsdmClient producerClient = m_notificationProducer.getParent( ).getParent( );
+
+ // note that we assume the subscription resource is located in the same SOAP engine
+ // (host/port/servlet context) as the notification producer
+ // TODO retSubcriptionInstance = producerClient.findInstance( m_subscriptionEpr );
+
+ return retSubcriptionInstance;
+ }
+
+ /**
+ * Returns the topic that is subscribed to.
+ *
+ * @return the subscribed topic
+ */
+ public TopicExpressionType getTopic( )
+ {
+ return m_topic;
+ }
+ }
+}
\ No newline at end of file
Added: webservices/muse/trunk/src/examples/client/src/test/axis/com/xyz/DiskWsdmServiceWSResource.java
URL: http://svn.apache.org/viewcvs/webservices/muse/trunk/src/examples/client/src/test/axis/com/xyz/DiskWsdmServiceWSResource.java?rev=232376&view=auto
==============================================================================
--- webservices/muse/trunk/src/examples/client/src/test/axis/com/xyz/DiskWsdmServiceWSResource.java (added)
+++ webservices/muse/trunk/src/examples/client/src/test/axis/com/xyz/DiskWsdmServiceWSResource.java Fri Aug 12 13:38:04 2005
@@ -0,0 +1,415 @@
+/*=============================================================================*
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed 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 axis.com.xyz;
+
+
+// [mod] imports for added code
+import org.apache.ws.resource.example.Disk;
+import org.apache.ws.resource.example.ExampleConstants;
+import org.apache.ws.resource.example.StateInfo;
+import org.apache.ws.muws.Muws05Constants;
+import org.apache.ws.muws.state.StateTransitionFailedException;
+import com.xyz.ActiveTimeDocument;
+import com.xyz.BlockSizeDocument;
+import com.xyz.FileSystemDocument;
+import com.xyz.ManufacturerDocument;
+import com.xyz.NotificationSimulator;
+import com.xyz.NumberOfBlocksDocument;
+import com.xyz.StateInfoDocument;
+import org.oasisOpen.docs.wsdm.x2004.x04.muws05.schema.DurationMetric;
+import org.oasisOpen.docs.wsdm.x2004.x04.muws05.schema.IntegerMetric;
+import org.oasisOpen.docs.wsdm.x2004.x04.muws05.schema.StateInformation;
+import javax.xml.soap.SOAPException;
+import java.util.Calendar;
+
+/**
+ * WSResource class to support the service <b>DiskWsdmService</b>.
+ * This is an auto-generated class that requires developer modification.
+ * Modified for use by our unit tests - ips, 09/11/04.
+ */
+public class DiskWsdmServiceWSResource
+ extends AbstractDiskWsdmServiceWSResource
+{
+ /** object used to log messages */
+ private static final org.apache.commons.logging.Log LOG =
+ org.apache.commons.logging.LogFactory.getLog( DiskWsdmServiceWSResource.class );
+
+ // [mod] added to simulate the true backend resource
+ private Disk m_backendDiskBean;
+
+ /**
+ * Constructor creating a new WSResource instance.
+ * [mod] changed to call added constructor that takes a Disk arg
+ *
+ * @param id the resource Id
+ *
+ * @throws Exception if failed to create the WSResource instance
+ */
+ public DiskWsdmServiceWSResource( String id )
+ throws Exception
+ {
+ this( new Disk( id ) );
+ }
+
+ /**
+ * Constructor creating a new WSResource instance.
+ * [mod] changed constructor param to Disk instead of String
+ *
+ * @param backendDisk the "backend" disk that this WSResource is fronting
+ *
+ * @throws Exception if failed to create the WSResource instance
+ */
+ public DiskWsdmServiceWSResource( Disk backendDisk )
+ throws Exception
+ {
+ // [mod] call super() specifying disk serial # as the resource Id
+ super( backendDisk.getSerialNumber( ) );
+
+ // [mod] set m_backendDiskBean to the specified Disk bean
+ m_backendDiskBean = backendDisk;
+
+ // [mod] added this to support custom notification emission
+ // Demonstrate the support for non-property change notifications
+ setupBadSectorNotifications( );
+ }
+
+ /**
+ * Adds a resource property to the backend managed resource.
+ *
+ * @param qname the name of the resource property to add
+ * @param bean an XmlBean that contains the initial value of the new resource property
+ *
+ * @return true if property was added successfully, false otherwise
+ */
+ public boolean addBackendProperty( javax.xml.namespace.QName qname,
+ org.apache.xmlbeans.XmlObject bean )
+ {
+ // [mod] added logic to if blocks
+ if ( qname.equals( PropertyQNames.STATEINFO ) )
+ {
+ final StateInfo backendStateInfo = new StateInfo( );
+ backendStateInfo.setState( ( (StateInfoDocument) bean ).getStateInfo( ).getState( ) );
+ backendStateInfo.setTimeEntered( ( (StateInfoDocument) bean ).getStateInfo( ).getTimeEntered( ) );
+ m_backendDiskBean.addStateInfo( backendStateInfo );
+ }
+ else if ( qname.equals( PropertyQNames.BLOCKSIZE ) )
+ {
+ m_backendDiskBean.setBlockSize( ( (BlockSizeDocument) bean ).getBlockSize( ) );
+
+ // changing BlockSize will change the Capacity, so call refreshProperty() so the Capacity metric's LastUpdated attrib will be updated
+ try
+ {
+ refreshProperty( PropertyQNames.CAPACITY );
+ }
+ catch ( Exception e )
+ {
+ throw new RuntimeException( e );
+ }
+ }
+ else if ( qname.equals( PropertyQNames.FILESYSTEM ) )
+ {
+ m_backendDiskBean.addFilesystem( ( (FileSystemDocument) bean ).getFileSystem( ) );
+ }
+ else if ( qname.equals( PropertyQNames.MANUFACTURER ) )
+ {
+ m_backendDiskBean.setManufacturer( ( (ManufacturerDocument) bean ).getManufacturer( ) );
+ }
+ else if ( qname.equals( PropertyQNames.NUMBEROFBLOCKS ) )
+ {
+ m_backendDiskBean.setNumberOfBlocks( ( (NumberOfBlocksDocument) bean ).getNumberOfBlocks( ) );
+
+ // changing NumberOfBlocks will change the Capacity, so call refreshProperty() so the Capacity metric's LastUpdated attrib will be updated
+ try
+ {
+ refreshProperty( PropertyQNames.CAPACITY );
+ }
+ catch ( Exception e )
+ {
+ throw new RuntimeException( e );
+ }
+ }
+ else if ( qname.equals( PropertyQNames.ACTIVETIME ) )
+ {
+ m_backendDiskBean.setActiveTime( ( (ActiveTimeDocument) bean ).getActiveTime( ).getGDurationValue( ) );
+ }
+ else
+ {
+ LOG.warn( "addBackendProperty() not implemented for property " + qname );
+ }
+
+ return true;
+ }
+
+ /**
+ * Refreshes the value of the resource property with the specified name.
+ * The method of retrieving backend properties is application-specific,
+ * so the application developer must fill in this method.
+ *
+ * @param propQName the name of the resource property to refresh
+ */
+ public void refreshProperty( javax.xml.namespace.QName propQName )
+ throws Exception
+ {
+ // [mod] added logic to if blocks
+ if ( propQName.equals( PropertyQNames.STATEINFO ) )
+ {
+ if ( m_backendDiskBean.getStateInfoList( ).length != 0 )
+ {
+ final StateInfo[] backendStateInfos = m_backendDiskBean.getStateInfoList( );
+ final StateInformation[] stateInfoXBeans = new StateInformation[backendStateInfos.length];
+
+ for ( int i = 0; i < backendStateInfos.length; i++ )
+ {
+ final StateInformation stateInfoXBean = StateInformation.Factory.newInstance( );
+ stateInfoXBean.setState( backendStateInfos[i].getState( ) );
+ stateInfoXBean.setTimeEntered( backendStateInfos[i].getTimeEntered( ) );
+ stateInfoXBeans[i] = stateInfoXBean;
+ }
+
+ getProperties( ).setStateInfoArray( stateInfoXBeans );
+ }
+ }
+ else if ( propQName.equals( PropertyQNames.BLOCKSIZE ) )
+ {
+ if ( m_backendDiskBean.getBlockSize( ) != -1 )
+ {
+ getProperties( ).setBlockSize( m_backendDiskBean.getBlockSize( ) );
+ }
+ }
+ else if ( propQName.equals( PropertyQNames.ACTIVETIME ) )
+ {
+ DurationMetric activeTime = getProperties( ).getActiveTime( );
+
+ if ( activeTime == null )
+ {
+ activeTime = DurationMetric.Factory.newInstance( );
+ activeTime.setChangeType( DurationMetric.ChangeType.COUNTER );
+ activeTime.setTimeScope( DurationMetric.TimeScope.POINT_IN_TIME );
+ }
+
+ activeTime.setGDurationValue( m_backendDiskBean.getActiveTime( ) );
+ activeTime.setLastUpdated( Calendar.getInstance( ) );
+ getProperties( ).setActiveTime( activeTime );
+ }
+ else if ( propQName.equals( PropertyQNames.CAPACITY ) )
+ {
+ IntegerMetric capacity = getProperties( ).getCapacity( );
+
+ if ( capacity == null )
+ {
+ capacity = IntegerMetric.Factory.newInstance( );
+ capacity.setChangeType( IntegerMetric.ChangeType.GAUGE );
+ capacity.setTimeScope( IntegerMetric.TimeScope.POINT_IN_TIME );
+ }
+
+ capacity.setBigIntegerValue( m_backendDiskBean.getCapacity( ) );
+ capacity.setLastUpdated( Calendar.getInstance( ) );
+ getProperties( ).setCapacity( capacity );
+ }
+ else if ( propQName.equals( PropertyQNames.FILESYSTEM ) )
+ {
+ if ( m_backendDiskBean.getFilesystems( ).length != 0 )
+ {
+ getProperties( ).setFileSystemArray( m_backendDiskBean.getFilesystems( ) );
+ }
+ }
+ else if ( propQName.equals( PropertyQNames.MANUFACTURER ) )
+ {
+ if ( m_backendDiskBean.getManufacturer( ) != null )
+ {
+ getProperties( ).setManufacturer( m_backendDiskBean.getManufacturer( ) );
+ }
+ }
+ else if ( propQName.equals( PropertyQNames.NUMBEROFBLOCKS ) )
+ {
+ if ( m_backendDiskBean.getNumberOfBlocks( ) != null )
+ {
+ getProperties( ).setNumberOfBlocks( m_backendDiskBean.getNumberOfBlocks( ) );
+ }
+ }
+ else if ( propQName.equals( PropertyQNames.RESOURCESTATE ) )
+ {
+ if ( m_backendDiskBean.isStarted( ) )
+ {
+ setResourceState( Muws05Constants.RESOURCE_STATE_URI_AVAILABLE );
+ }
+ else
+ {
+ setResourceState( Muws05Constants.RESOURCE_STATE_URI_UNAVAILABLE );
+ }
+ }
+ else if ( propQName.equals( PropertyQNames.TERMINATIONTIME ) )
+ {
+ getProperties( ).setNilTerminationTime( );
+ }
+ else if ( propQName.equals( PropertyQNames.FIXEDTOPICSET ) )
+ {
+ getProperties( ).setFixedTopicSet( true );
+ }
+ }
+
+ /**
+ * Removes all data associated with the given resource property name from the backend managed resource.
+ *
+ * @param qname the name of the resource property to remove
+ *
+ * @return true if property was removed successfully, false otherwise
+ */
+ public boolean removeAllBackendProperties( javax.xml.namespace.QName qname )
+ {
+ // [mod] added logic to if blocks
+ if ( qname.equals( PropertyQNames.STATEINFO ) )
+ {
+ m_backendDiskBean.removeAllStateInfos( );
+ }
+ else if ( qname.equals( PropertyQNames.BLOCKSIZE ) )
+ {
+ m_backendDiskBean.setBlockSize( -1 );
+ }
+ else if ( qname.equals( PropertyQNames.FILESYSTEM ) )
+ {
+ m_backendDiskBean.removeAllFilesystems( );
+ }
+ else if ( qname.equals( PropertyQNames.MANUFACTURER ) )
+ {
+ m_backendDiskBean.setManufacturer( null );
+ }
+ else if ( qname.equals( PropertyQNames.NUMBEROFBLOCKS ) )
+ {
+ m_backendDiskBean.setNumberOfBlocks( null );
+ }
+ else
+ {
+ LOG.warn( "removeAllBackendProperties() not implemented for property " + qname );
+ }
+
+ return true;
+ }
+
+ /**
+ * If the metric property with the specified QName can be reset,
+ * then reset it on the "backend" resource and return true;
+ * otherwise, return false.
+ *
+ * @param propQName the QName of a metric property
+ *
+ * @return true if the specified "backend" property was reset, or false otherwise
+ */
+ protected boolean backendResetMetric( javax.xml.namespace.QName propQName )
+ {
+ if ( propQName.equals( PropertyQNames.CAPACITY ) )
+ {
+ // [mod] capacity metric cannot be reset.
+ }
+ else if ( propQName.equals( PropertyQNames.ACTIVETIME ) )
+ {
+ // [mod] added following two lines
+ m_backendDiskBean.setActiveTime( ExampleConstants.INITIAL_PROP_VALUE__ACTIVE_TIME );
+
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * This method will be invoked by the Muse infrastructure whenever
+ * the muws:ResourceState Start operation is called by a client.
+ * The MUWS service developer is responsible for adding code to this
+ * method that will appropriately update the state of the "backend"
+ * managed resource.
+ */
+ protected void backendStart( )
+ throws StateTransitionFailedException
+ {
+ // [mod] below code added
+ try
+ {
+ m_backendDiskBean.start( );
+ }
+ catch ( Exception e )
+ {
+ throw new StateTransitionFailedException( e );
+ }
+ }
+
+ /**
+ * This method will be invoked by the Muse infrastructure whenever
+ * the muws:ResourceState Stop operation is called by a client.
+ * The MUWS service developer is responsible for adding code to this
+ * method that will appropriately update the state of the "backend"
+ * managed resource.
+ */
+ protected void backendStop( )
+ throws StateTransitionFailedException
+ {
+ // [mod] below code added
+ try
+ {
+ m_backendDiskBean.stop( );
+ }
+ catch ( Exception e )
+ {
+ throw new StateTransitionFailedException( e );
+ }
+ }
+
+ /**
+ * DOCUMENT_ME
+ */
+ protected void registerForPropertyChangeNotifications( )
+ {
+ // Make calls to register all properties that participate in property change notifications.
+ // [mod] removed register calls for resource properties that should not emit property change notifications
+ registerPropertyForChangeNotification( PropertyQNames.STATEINFO );
+ registerPropertyForChangeNotification( PropertyQNames.RESOURCESTATE );
+ registerPropertyForChangeNotification( PropertyQNames.BLOCKSIZE );
+ registerPropertyForChangeNotification( PropertyQNames.MANUFACTURER );
+ registerPropertyForChangeNotification( PropertyQNames.NUMBEROFBLOCKS );
+ }
+
+ // [mod] added setupBadSectorNotifications to support a custom notification
+
+ /**
+ * Demonstrates how to support a miscellaneous notification (i.e. not a property change notification).
+ * In this example we are demonstrating support for a BadSector topic.
+ *
+ * @throws SOAPException
+ */
+ private void setupBadSectorNotifications( )
+ throws SOAPException
+ {
+ String namespace = "http://com.xyz";
+ String localName = "BadSector";
+
+ // To indicate that a particular notification topic is supported call the base class's
+ // registerBaseNotifTopic passing the namespace and localName of the topic.
+ // The topic is returned so that it can be used in the Notification process
+ com.ibm.xmlns.stdwip.webServices.wsBaseNotification.TopicExpressionType topic =
+ registerBaseNotifTopic( namespace, localName );
+
+ // The rest of this method is about setting up the NotificationSimulator class.
+ // Create a bad sector SOAP message with sectorId 6789
+ javax.xml.soap.SOAPElement badSectorMessage =
+ javax.xml.soap.SOAPFactory.newInstance( ).createElement( localName, "ns1", namespace );
+ javax.xml.soap.SOAPElement sectorId = badSectorMessage.addTextNode( "SectorId" );
+ sectorId.setValue( "6789" );
+
+ // Start simulation of the bad sector notification issuing one every 5 seconds.
+ new NotificationSimulator( this,
+ getNotificationManager( ), topic, badSectorMessage, 5000 );
+ }
+}
\ No newline at end of file
Added: webservices/muse/trunk/src/examples/client/src/test/client-config.wsdd
URL: http://svn.apache.org/viewcvs/webservices/muse/trunk/src/examples/client/src/test/client-config.wsdd?rev=232376&view=auto
==============================================================================
--- webservices/muse/trunk/src/examples/client/src/test/client-config.wsdd (added)
+++ webservices/muse/trunk/src/examples/client/src/test/client-config.wsdd Fri Aug 12 13:38:04 2005
@@ -0,0 +1,29 @@
+<?xml version="1.0"?>
+
+<deployment xmlns="http://xml.apache.org/axis/wsdd/" xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
+ <handler name="LogHandler" type="java:org.apache.axis.handlers.LogHandler">
+ <parameter name="LogHandler.fileName" value="C:/Projects/ws-rp/src/test/client.log"/>
+ </handler>
+ <handler name="AddressingHandler" type="java:org.apache.axis.message.addressing.handler.AddressingHandler" />
+ <handler name="AxisClientSideAddressingHandler" type="java:org.apache.axis.message.addressing.handler.AxisClientSideAddressingHandler" />
+ <globalConfiguration>
+ <requestFlow>
+ <!--
+ <handler type="java:org.apache.axis.handlers.JAXRPCHandler">
+ <parameter name="className" value="org.apache.axis.message.addressing.handler.AxisClientSideAddressingHandler"/>
+ <parameter name="referencePropertyNames" value="*"/>
+ </handler>
+ -->
+ </requestFlow>
+ <responseFlow>
+ <!--
+ <handler type="java:org.apache.axis.handlers.JAXRPCHandler">
+ <parameter name="className" value="org.apache.axis.message.addressing.handler.AxisClientSideAddressingHandler"/>
+ <parameter name="referencePropertyNames" value="*"/>
+ </handler>
+ -->
+ </responseFlow>
+ </globalConfiguration>
+ <transport name="http" pivot="java:org.apache.axis.transport.http.HTTPSender"/>
+ <transport name="local" pivot="java:org.apache.axis.transport.local.LocalSender"/>
+</deployment>
Added: webservices/muse/trunk/src/examples/client/src/test/discovery-agent-registry.xml
URL: http://svn.apache.org/viewcvs/webservices/muse/trunk/src/examples/client/src/test/discovery-agent-registry.xml?rev=232376&view=auto
==============================================================================
--- webservices/muse/trunk/src/examples/client/src/test/discovery-agent-registry.xml (added)
+++ webservices/muse/trunk/src/examples/client/src/test/discovery-agent-registry.xml Fri Aug 12 13:38:04 2005
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<discovery-config xmlns='http://apache.org/ws/resource/discovery/xml' >
+ <agent-list>
+ <agent>
+ <name>Disk Resource Discovery Agent 1</name>
+ <class>org.apache.ws.resource.example.discovery.DiskDiscoveryAgent</class>
+ <properties>
+ <property id="ResourceID">1234</property>
+ <property id="ResourceID">5678</property>
+ </properties>
+ </agent>
+ <agent>
+ <name>Disk Resource Discovery Agent 2</name>
+ <class>org.apache.ws.resource.example.discovery.DiskDiscoveryAgent</class>
+ <properties>
+ <property id="ResourceID">4321</property>
+ <property id="ResourceID">8765</property>
+ </properties>
+ </agent>
+ </agent-list>
+</discovery-config>
\ No newline at end of file
Added: webservices/muse/trunk/src/examples/client/src/test/org/apache/ws/client/DynamicSchemaClassBuilderTestCase.java
URL: http://svn.apache.org/viewcvs/webservices/muse/trunk/src/examples/client/src/test/org/apache/ws/client/DynamicSchemaClassBuilderTestCase.java?rev=232376&view=auto
==============================================================================
--- webservices/muse/trunk/src/examples/client/src/test/org/apache/ws/client/DynamicSchemaClassBuilderTestCase.java (added)
+++ webservices/muse/trunk/src/examples/client/src/test/org/apache/ws/client/DynamicSchemaClassBuilderTestCase.java Fri Aug 12 13:38:04 2005
@@ -0,0 +1,230 @@
+/*=============================================================================*
+ * Confidential Copyright (c) 2004 Hewlett-Packard Development Company, L.P. *
+ *=============================================================================*/
+package org.apache.ws.client;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.URL;
+import java.util.Iterator;
+
+import javax.wsdl.WSDLException;
+import javax.xml.namespace.QName;
+import javax.xml.soap.MessageFactory;
+import javax.xml.soap.SOAPElement;
+import javax.xml.soap.SOAPException;
+import javax.xml.soap.SOAPMessage;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+
+import org.apache.xmlbeans.XmlObject;
+
+import org.apache.commons.io.IoUtils;
+
+/**
+ * Test case for the DynamicSchemaClassBuilder.
+ *
+ * @author wire
+ *
+ */
+public class DynamicSchemaClassBuilderTestCase extends TestCase {
+ File m_tempDir;
+ URL m_wsdl_url;
+
+ /*
+ * @see TestCase#setUp()
+ */
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ // Write out a test wsdl
+ String hashAsString=this.getClass().getName()+"@"+this.hashCode();
+ m_tempDir=new File(System.getProperty("java.io.tmpdir")+"/"+hashAsString);
+ m_tempDir.mkdir();
+ Assert.assertTrue(m_tempDir.exists());
+ File tempFile= new File("./src/wsdl/muse/registry.wsdl");
+ m_wsdl_url=tempFile.getAbsoluteFile().toURL();
+ m_builder = new DynamicSchemaClassBuilder("src\\wsdl\\muse",m_wsdl_url);
+ m_builder.compile();
+ }
+
+
+ /*
+ * @see TestCase#tearDown()
+ */
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ DynamicSchemaClassBuilder.dispose();
+ IoUtils.deleteDir(m_tempDir);
+ }
+
+
+ /**
+ * Objective: Excersize schema compiler to create empty instances of classes from the smaple schema.
+ * @throws WSDLException
+ * @throws IOException
+ * @throws SecurityException
+ * @throws IllegalArgumentException
+ * @throws ClassNotFoundException
+ * @throws NoSuchMethodException
+ * @throws IllegalAccessException
+ * @throws InvocationTargetException
+ */
+
+ public void testCreateInstance() throws WSDLException, IOException, SecurityException, IllegalArgumentException, ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException{
+ XmlObject xmlBean=m_builder.getEmptyInstanceOfXMLBean(new QName("http://schemas.xmlsoap.org/ws/2004/03/addressing","EndpointReference"));
+ Assert.assertNotNull(xmlBean);
+ String className=xmlBean.getClass().getName();
+ Assert.assertEquals(xmlBean.getClass().getName() , "org.xmlsoap.schemas.ws.x2004.x03.addressing.impl.EndpointReferenceDocumentImpl");
+
+ XmlObject xmlBean1=m_builder.getEmptyInstanceOfXMLBean(new QName("http://registry.generated.ws.apache.org","FindResourceRequest"));
+ Assert.assertNotNull(xmlBean1);
+ String className1=xmlBean1.getClass().getName();
+ Assert.assertEquals(xmlBean1.getClass().getName(),"org.apache.ws.generated.registry.impl.FindResourceRequestDocumentImpl");
+ }
+
+
+ public void testCreateInstanceFromXML() throws WSDLException, IOException, SecurityException, IllegalArgumentException, ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, SOAPException{
+
+ // Build a SOAP message
+ InputStream in=new ByteArrayInputStream(m_test_envelope.getBytes());
+ SOAPMessage soapResponseMsg = MessageFactory.newInstance().createMessage(null,in);
+ Iterator propElemsIter = soapResponseMsg.getSOAPPart().getEnvelope().getBody().getChildElements();
+ Assert.assertTrue(propElemsIter.hasNext());
+
+ // Iterate into it to find FindResponse element, an array of EndpointReferences
+ SOAPElement e=(SOAPElement)propElemsIter.next();
+ Iterator children = e.getChildElements();
+ Assert.assertTrue(children.hasNext());
+ SOAPElement elementFindResponse=(SOAPElement)children.next();
+
+ // Get a document bean
+ QName findResponseQName=new QName(e.getNamespaceURI(),e.getLocalName());
+ XmlObject xmlBean=m_builder.getInstanceOfXMLBean(findResponseQName,e);
+ Assert.assertNotNull(xmlBean);
+ String className=xmlBean.getClass().getName();
+ Assert.assertEquals("org.apache.ws.generated.registry.impl.FindResponseDocumentImpl",className);
+
+ // Extract an xmlBean
+ Method getFindResponseMethod=xmlBean.getClass().getMethod("getFindResponse",null);
+ Assert.assertNotNull(getFindResponseMethod);
+ XmlObject findResponse=(XmlObject)getFindResponseMethod.invoke(xmlBean,null);
+ Method getItemArrayMethod=findResponse.getClass().getMethod("getItemArray",null);
+ Object[] array=(Object[])getItemArrayMethod.invoke(findResponse,null);
+
+ // See if the returned array has for parts
+ Assert.assertEquals(4,array.length);
+ XmlObject endpointReferenceType=(XmlObject)array[0];
+ Method[] methods=endpointReferenceType.getClass().getMethods();
+
+ // Use introspection to tests some values
+// XmlObject portType=(XmlObject)DynamicSchemaClassBuilder.getProperty(endpointReferenceType,"PortType");
+// String localPart=(String)DynamicSchemaClassBuilder.getProperty(portType,"StringValue");//
+// Assert.assertEquals("ns5:DiskPortType",localPart);
+
+ // Get ResourceID
+// XmlObject refProps=(XmlObject)DynamicSchemaClassBuilder.getProperty(endpointReferenceType,"ReferenceProperties");
+ //Method[] methods = refProps.getClass().getMethods();
+ //String[] meths = DynamicSchemaClassBuilder.getProperties(refProps);
+ //XmlObject d=(XmlObject)DynamicSchemaClassBuilder.getProperty(endpointReferenceType,"refProps");
+ //Object id=DynamicSchemaClassBuilder.getProperty(refProps,"EnumValue");
+ //Method selectPathMethod = refProps.getClass().getMethod("selectPath",new Class[]{java.lang.String.class});
+ //Object ret = selectPathMethod.invoke(refProps,new Object[]{"ResourceID"});
+
+ System.out.println();
+ }
+
+ String m_test_envelope1="<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n"+
+ " <soapenv:Body>\n"+
+ " <ns1:findResourcesByServiceNameResponse xmlns:ns1=\"http://registry.generated.ws.apache.org\" >\n"+
+ " <ns1:FindResponse xmlns:ns1=\"http://registry.generated.ws.apache.org\">\n"+
+ " <ns1:item>\n"+
+ " <ns2:Address xmlns:ns2=\"http://schemas.xmlsoap.org/ws/2004/03/addressing\">http://localhost:8080/wsdm/services/disk</ns2:Address>\n"+
+ " <ns3:ReferenceProperties xmlns:ns3=\"http://schemas.xmlsoap.org/ws/2004/03/addressing\">\n"+
+ " <ns4:ResourceID xmlns:ns4=\"http://www.apache.org/props\">8765</ns4:ResourceID>\n"+
+ " </ns3:ReferenceProperties>\n"+
+ " <ns6:PortType xmlns:ns5=\"http://xyz.com/\" xmlns:ns6=\"http://schemas.xmlsoap.org/ws/2004/03/addressing\">ns5:DiskPortType</ns6:PortType>\n"+
+ " <ns8:ServiceName PortName=\"disk\" xmlns:ns7=\"http://xyz.com/\" xmlns:ns8=\"http://schemas.xmlsoap.org/ws/2004/03/addressing\">ns7:DiskWsdmService</ns8:ServiceName>\n"+
+ " </ns1:item>\n"+
+ " <ns1:item>\n"+
+ " <ns9:Address xmlns:ns9=\"http://schemas.xmlsoap.org/ws/2004/03/addressing\">http://localhost:8080/wsdm/services/disk</ns9:Address>\n"+
+ " <ns10:ReferenceProperties xmlns:ns10=\"http://schemas.xmlsoap.org/ws/2004/03/addressing\">\n"+
+ " <ns11:ResourceID xmlns:ns11=\"http://www.apache.org/props\">5678</ns11:ResourceID>\n"+
+ " </ns10:ReferenceProperties>\n"+
+ " <ns13:PortType xmlns:ns12=\"http://xyz.com/\" xmlns:ns13=\"http://schemas.xmlsoap.org/ws/2004/03/addressing\">ns12:DiskPortType</ns13:PortType>\n"+
+ " <ns15:ServiceName PortName=\"disk\" xmlns:ns14=\"http://xyz.com/\" xmlns:ns15=\"http://schemas.xmlsoap.org/ws/2004/03/addressing\">ns14:DiskWsdmService</ns15:ServiceName>\n"+
+ " </ns1:item>\n"+
+ " <ns1:item>\n"+
+ " <ns16:Address xmlns:ns16=\"http://schemas.xmlsoap.org/ws/2004/03/addressing\">http://localhost:8080/wsdm/services/disk</ns16:Address>\n"+
+ " <ns17:ReferenceProperties xmlns:ns17=\"http://schemas.xmlsoap.org/ws/2004/03/addressing\">\n"+
+ " <ns18:ResourceID xmlns:ns18=\"http://www.apache.org/props\">4321</ns18:ResourceID>\n"+
+ " </ns17:ReferenceProperties>\n"+
+ " <ns20:PortType xmlns:ns19=\"http://xyz.com/\" xmlns:ns20=\"http://schemas.xmlsoap.org/ws/2004/03/addressing\">ns19:DiskPortType</ns20:PortType>\n"+
+ " <ns22:ServiceName PortName=\"disk\" xmlns:ns21=\"http://xyz.com/\" xmlns:ns22=\"http://schemas.xmlsoap.org/ws/2004/03/addressing\">ns21:DiskWsdmService</ns22:ServiceName>\n"+
+ " </ns1:item>\n"+
+ " <ns1:item>\n"+
+ " <ns23:Address xmlns:ns23=\"http://schemas.xmlsoap.org/ws/2004/03/addressing\">http://localhost:8080/wsdm/services/disk</ns23:Address>\n"+
+ " <ns24:ReferenceProperties xmlns:ns24=\"http://schemas.xmlsoap.org/ws/2004/03/addressing\">\n"+
+ " <ns25:ResourceID xmlns:ns25=\"http://www.apache.org/props\">1234</ns25:ResourceID>\n"+
+ " </ns24:ReferenceProperties>\n"+
+ " <ns27:PortType xmlns:ns26=\"http://xyz.com/\" xmlns:ns27=\"http://schemas.xmlsoap.org/ws/2004/03/addressing\">ns26:DiskPortType</ns27:PortType>\n"+
+ " <ns29:ServiceName PortName=\"disk\" xmlns:ns28=\"http://xyz.com/\" xmlns:ns29=\"http://schemas.xmlsoap.org/ws/2004/03/addressing\">ns28:DiskWsdmService</ns29:ServiceName>\n"+
+ " </ns1:item>\n"+
+ " </ns1:FindResponse>\n"+
+ " </ns1:findResourcesByServiceNameResponse>\n"+
+ " </soapenv:Body></soapenv:Envelope>";
+
+ String m_test_envelope="<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:wsa=\"http://schemas.xmlsoap.org/ws/2004/03/addressing\">"+
+ " <soapenv:Header>"+
+ " <wsa:MessageID soapenv:mustUnderstand=\"0\">uuid:51B07250-0DDA-11D9-A169-845A89F5F967</wsa:MessageID>"+
+ " <wsa:To soapenv:mustUnderstand=\"0\">http://schemas.xmlsoap.org/ws/2004/03/addressing/role/anonymous</wsa:To>"+
+ " <wsa:Action soapenv:mustUnderstand=\"0\">http://127.0.0.1:9009/axis/services/registry/actionResponse</wsa:Action>"+
+ " <wsa:From soapenv:mustUnderstand=\"0\">"+
+ " <Address xmlns=\"http://schemas.xmlsoap.org/ws/2004/03/addressing\">http://127.0.0.1:9009/axis/services/registry</Address>"+
+ " </wsa:From>"+
+ " </soapenv:Header>"+
+ " <soapenv:Body>"+
+ " <FindResponse xmlns=\"http://apache.org/ws/generated/registry\">"+
+ " <item xsi:type=\"wsa:EndpointReferenceType\">"+
+ " <wsa:Address>http://localhost:8080/wsdm/services/disk</wsa:Address>"+
+ " <wsa:ReferenceProperties>"+
+ " <ns1:ResourceID xmlns:ns1=\"urn:proposedstandard.org/muse/addressing\">1234</ns1:ResourceID>"+
+ " </wsa:ReferenceProperties>"+
+ " <wsa:PortType xmlns:ns2=\"http://xyz.com/\">ns2:DiskPortType</wsa:PortType>"+
+ " <wsa:ServiceName PortName=\"disk\" xmlns:ns3=\"http://xyz.com/\">ns3:DiskWsdmService</wsa:ServiceName>"+
+ " </item>"+
+ " <item xsi:type=\"wsa:EndpointReferenceType\">"+
+ " <wsa:Address>http://localhost:8080/wsdm/services/disk</wsa:Address>"+
+ " <wsa:ReferenceProperties>"+
+ " <ns4:ResourceID xmlns:ns4=\"urn:proposedstandard.org/muse/addressing\">8765</ns4:ResourceID>"+
+ " </wsa:ReferenceProperties>"+
+ " <wsa:PortType xmlns:ns5=\"http://xyz.com/\">ns5:DiskPortType</wsa:PortType>"+
+ " <wsa:ServiceName PortName=\"disk\" xmlns:ns6=\"http://xyz.com/\">ns6:DiskWsdmService</wsa:ServiceName>"+
+ " </item>"+
+ " <item xsi:type=\"wsa:EndpointReferenceType\">"+
+ " <wsa:Address>http://localhost:8080/wsdm/services/disk</wsa:Address>"+
+ " <wsa:ReferenceProperties>"+
+ " <ns7:ResourceID xmlns:ns7=\"urn:proposedstandard.org/muse/addressing\">4321</ns7:ResourceID>"+
+ " </wsa:ReferenceProperties>"+
+ " <wsa:PortType xmlns:ns8=\"http://xyz.com/\">ns8:DiskPortType</wsa:PortType>"+
+ " <wsa:ServiceName PortName=\"disk\" xmlns:ns9=\"http://xyz.com/\">ns9:DiskWsdmService</wsa:ServiceName>"+
+ " </item>"+
+ " <item xsi:type=\"wsa:EndpointReferenceType\">"+
+ " <wsa:Address>http://localhost:8080/wsdm/services/disk</wsa:Address>"+
+ " <wsa:ReferenceProperties>"+
+ " <ns10:ResourceID xmlns:ns10=\"urn:proposedstandard.org/muse/addressing\">5678</ns10:ResourceID>"+
+ " </wsa:ReferenceProperties>"+
+ " <wsa:PortType xmlns:ns11=\"http://xyz.com/\">ns11:DiskPortType</wsa:PortType>"+
+ " <wsa:ServiceName PortName=\"disk\" xmlns:ns12=\"http://xyz.com/\">ns12:DiskWsdmService</wsa:ServiceName>"+
+ " </item>"+
+ " </FindResponse>"+
+ " </soapenv:Body>"+
+ "</soapenv:Envelope>";
+
+ private DynamicSchemaClassBuilder m_builder;
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: muse-dev-unsubscribe@ws.apache.org
For additional commands, e-mail: muse-dev-help@ws.apache.org