You are viewing a plain text version of this content. The canonical link for it is here.
Posted to muse-commits@ws.apache.org by da...@apache.org on 2006/06/12 18:06:57 UTC

svn commit: r413693 [3/3] - in /webservices/muse/trunk/modules/muse-wsdm-muws: specs/ src/org/apache/muse/ws/dm/muws/ src/org/apache/muse/ws/dm/muws/ext/ src/org/apache/muse/ws/dm/muws/ext/faults/ src/org/apache/muse/ws/dm/muws/impl/ src/org/apache/mus...

Added: webservices/muse/trunk/modules/muse-wsdm-muws/src/org/apache/muse/ws/dm/muws/impl/SimpleMetric.java
URL: http://svn.apache.org/viewvc/webservices/muse/trunk/modules/muse-wsdm-muws/src/org/apache/muse/ws/dm/muws/impl/SimpleMetric.java?rev=413693&view=auto
==============================================================================
--- webservices/muse/trunk/modules/muse-wsdm-muws/src/org/apache/muse/ws/dm/muws/impl/SimpleMetric.java (added)
+++ webservices/muse/trunk/modules/muse-wsdm-muws/src/org/apache/muse/ws/dm/muws/impl/SimpleMetric.java Mon Jun 12 09:06:54 2006
@@ -0,0 +1,314 @@
+/*=============================================================================*
+ *  Copyright 2006 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 org.apache.muse.ws.dm.muws.impl;
+
+import java.net.URI;
+import java.util.Date;
+
+import javax.xml.namespace.QName;
+
+import org.apache.muse.util.messages.Messages;
+import org.apache.muse.util.messages.MessagesFactory;
+import org.apache.muse.util.xml.XsdUtils;
+import org.apache.muse.ws.dm.muws.Metric;
+import org.apache.muse.ws.dm.muws.MuwsConstants;
+import org.apache.muse.ws.resource.WsResource;
+import org.apache.muse.ws.resource.basefaults.BaseFault;
+import org.apache.muse.ws.resource.metadata.MetadataDescriptor;
+import org.apache.muse.ws.resource.properties.ResourcePropertyCollection;
+
+/**
+ *
+ * SimpleMetric is a collection of metadata that is associated with resource 
+ * properties that are also metrics. This information should be provided 
+ * by a property's RMD definition, and can be used by a resource implementation 
+ * to set up the collection and retrieval of a metric. The only way that this 
+ * class can be used to modify a metric property is through the reset(Object) 
+ * method - all other methods manipulate the metric's metadata, but not its 
+ * actual value.
+ *
+ * @author Dan Jemiolo (danj)
+ *
+ */
+
+public class SimpleMetric implements Metric
+{
+    private static Messages _MESSAGES = MessagesFactory.get(SimpleMetric.class);
+    
+    //
+    // The metric attribute values
+    //
+    
+    private int _changeType;
+    
+    private int _gatheringTime;
+    
+    private URI _group = null;
+    
+    //
+    // True if the metric property has not been modified since it's last reset.
+    //
+    private boolean _hasBeenReset = false;
+    
+    //
+    // The calculation interval is optional - if not used, it's value is -1.
+    //
+    private long _interval = -1;
+    
+    private String _intervalString = null;
+    
+    private Date _lastUpdated = null;
+    
+    private QName _name = null;
+    
+    //
+    // The WS-resource that exposes the metric
+    //
+    private WsResource _resource = null;
+    
+    private Date _resetAt = null;
+    
+    private int _timeScope;
+    
+    /**
+     * 
+     * @param name
+     *        The name of the metric property.
+     * 
+     * @param resource
+     *        The WS-resource that defines this metric.
+     *
+     */
+    public SimpleMetric(QName name, WsResource resource)
+    {
+        if (name == null)
+            throw new NullPointerException(_MESSAGES.get("NullMetricName"));
+
+        if (resource == null)
+            throw new NullPointerException(_MESSAGES.get("NullResource"));
+        
+        _name = name;
+        _resource = resource;
+        
+        //
+        // get the metadata for the metric
+        //
+        ResourcePropertyCollection props = _resource.getPropertyCollection();
+        MetadataDescriptor metadata = props.getMetadata();
+
+        if (!metadata.isReadOnlyExternal(name))
+        {
+            Object[] filler = { name };
+            throw new RuntimeException(_MESSAGES.get("NotReadOnly", filler));
+        }
+        
+        String change = metadata.getExtendedMetadata(name, MuwsConstants.CHANGE_TYPE_QNAME);
+        String gathering = metadata.getExtendedMetadata(name, MuwsConstants.GATHERING_QNAME);
+        String time = metadata.getExtendedMetadata(name, MuwsConstants.TIME_SCOPE_QNAME);
+        
+        //
+        // required values (will throw if values are invalid)
+        //
+        _changeType = getChangeType(change);
+        _gatheringTime = getGatheringTime(gathering);
+        _timeScope = getTimeScope(time);
+
+        //
+        // optional values
+        //
+        
+        _intervalString = metadata.getExtendedMetadata(name, MuwsConstants.CALC_INTERVAL_QNAME);
+
+        if (_intervalString != null)
+            _interval = XsdUtils.getDuration(_intervalString);
+        
+        String groupString = metadata.getExtendedMetadata(name, MuwsConstants.METRIC_GROUP_QNAME);
+        
+        if (groupString != null)
+            _group = URI.create(groupString);
+        
+        //
+        // sanity check: if it's an Interval, it needs... an interval!
+        //
+        if (isInterval() != (getIntervalString() != null))
+        {
+            Object[] filler = { name };
+            throw new RuntimeException(_MESSAGES.get("InvalidIntervalDef", filler));
+        }
+    }
+    
+    public WsResource getWsResource()
+    {
+        return _resource;
+    }
+    
+    private int getChangeType(String value)
+    {
+        if (value.equals(MuwsConstants.COUNTER))
+            return COUNTER;
+        
+        else if (value.equals(MuwsConstants.GAUGE))
+            return GAUGE;
+        
+        else if (value.equals(MuwsConstants.UNKNOWN))
+            return UNKNOWN;
+        
+        Object[] filler = { value };
+        throw new RuntimeException(_MESSAGES.get("InvalidChangeType", filler));
+    }
+    
+    public String getDuration()
+    {
+        return _intervalString;
+    }
+    
+    private int getGatheringTime(String value)
+    {
+        if (value.equals(MuwsConstants.ON_CHANGE))
+            return ON_CHANGE;
+        
+        else if (value.equals(MuwsConstants.ON_DEMAND))
+            return ON_DEMAND;
+        
+        else if (value.equals(MuwsConstants.PERIODIC))
+            return PERIODIC;
+        
+        else if (value.equals(MuwsConstants.UNKNOWN))
+            return UNKNOWN;
+        
+        Object[] filler = { value };
+        throw new RuntimeException(_MESSAGES.get("InvalidGatheringTime", filler));
+    }
+    
+    public URI getGroup()
+    {
+        return _group;
+    }
+    
+    public long getInterval()
+    {
+        return _interval;
+    }
+    
+    public String getIntervalString()
+    {
+        return _intervalString;
+    }
+    
+    public Date getLastUpdated()
+    {
+        return _lastUpdated;
+    }
+    
+    public QName getName()
+    {
+        return _name;
+    }
+    
+    public Date getResetAt()
+    {
+        return _resetAt;
+    }
+    
+    private int getTimeScope(String value)
+    {
+        if (value.equals(MuwsConstants.INTERVAL))
+            return INTERVAL;
+        
+        else if (value.equals(MuwsConstants.POINT_IN_TIME))
+            return POINT_IN_TIME;
+        
+        else if (value.equals(MuwsConstants.SINCE_RESET))
+            return SINCE_RESET;
+
+        Object[] filler = { value };
+        throw new RuntimeException(_MESSAGES.get("InvalidTimeScope", filler));
+    }
+    
+    public boolean hasBeenReset()
+    {
+        return _hasBeenReset;
+    }
+    
+    public boolean isCounter()
+    {
+        return _changeType == COUNTER;
+    }
+    
+    public boolean isGauge()
+    {
+        return _changeType == GAUGE;
+    }
+    
+    public boolean isInterval()
+    {
+        return _timeScope == INTERVAL;
+    }
+    
+    public boolean isOnChange()
+    {
+        return _gatheringTime == ON_CHANGE;
+    }
+    
+    public boolean isOnDemand()
+    {
+        return _gatheringTime == ON_DEMAND;
+    }
+    
+    public boolean isPeriodic()
+    {
+        return _gatheringTime == PERIODIC;
+    }
+    
+    public boolean isPointInTime()
+    {
+        return _timeScope == POINT_IN_TIME;
+    }
+    
+    public boolean isSinceReset()
+    {
+        return _timeScope == SINCE_RESET;
+    }
+    
+    public void reset(Object value)
+        throws BaseFault
+    {
+        if (isPointInTime())
+        {
+            Object[] filler = { getName() };
+            throw new IllegalStateException(_MESSAGES.get("ResetNotAllowed", filler));
+        }
+        
+        //
+        // this call will eventually result in a listener calling the 
+        // SimpleMetric.update() below - we will then overwrite the values 
+        // of the date attributes
+        //
+        ResourcePropertyCollection props = getWsResource().getPropertyCollection();
+        props.updateResourceProperty(getName(), new Object[]{ value });
+        
+        _resetAt = new Date();
+        _lastUpdated = null;
+        _hasBeenReset = true;
+    }
+    
+    public void update()
+    {
+        _lastUpdated = new Date();
+        _hasBeenReset = false;
+    }
+}

Added: webservices/muse/trunk/modules/muse-wsdm-muws/src/org/apache/muse/ws/dm/muws/impl/SimpleMetrics.java
URL: http://svn.apache.org/viewvc/webservices/muse/trunk/modules/muse-wsdm-muws/src/org/apache/muse/ws/dm/muws/impl/SimpleMetrics.java?rev=413693&view=auto
==============================================================================
--- webservices/muse/trunk/modules/muse-wsdm-muws/src/org/apache/muse/ws/dm/muws/impl/SimpleMetrics.java (added)
+++ webservices/muse/trunk/modules/muse-wsdm-muws/src/org/apache/muse/ws/dm/muws/impl/SimpleMetrics.java Mon Jun 12 09:06:54 2006
@@ -0,0 +1,234 @@
+/*=============================================================================*
+ *  Copyright 2006 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 org.apache.muse.ws.dm.muws.impl;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import javax.xml.namespace.QName;
+
+import org.w3c.dom.Element;
+
+import org.apache.muse.util.xml.XmlUtils;
+import org.apache.muse.ws.addressing.soap.SoapFault;
+import org.apache.muse.ws.dm.muws.Metric;
+import org.apache.muse.ws.dm.muws.Metrics;
+import org.apache.muse.ws.dm.muws.MuwsConstants;
+import org.apache.muse.ws.resource.WsResource;
+import org.apache.muse.ws.resource.metadata.MetadataDescriptor;
+import org.apache.muse.ws.resource.properties.ResourcePropertyCollection;
+
+/**
+ *
+ * SimpleMetrics is Muse's default implementation of the WSDM Metrics 
+ * capability. It uses the WS-RP and WS-RMD features of Muse to collect 
+ * metric metadata and expose it to WS-RP clients without requiring users to 
+ * treat metric and non-metric properties differently in their code. Metrics 
+ * that are defined in a resource's RMD have various property change listeners 
+ * and approvers set up for them so that all metadata is kept up-to-date.
+ *
+ * @author Dan Jemiolo (danj)
+ *
+ */
+
+public class SimpleMetrics 
+    extends AbstractManageabilityCapability implements Metrics
+{    
+    //
+    // Collection of threads for counter metrics that run on an interval
+    //
+    private Map _countersByQName = new HashMap();
+    
+    //
+    // All metrics defined for the resource
+    //
+    private Map _metricsByQName = new HashMap();
+
+    public QName[] getPropertyNames()
+    {
+        return PROPERTIES;
+    }
+    
+    public void initialize()
+        throws SoapFault
+    {
+        super.initialize();
+        
+        WsResource resource = getWsResource();
+        ResourcePropertyCollection props = resource.getPropertyCollection();
+        MetadataDescriptor metadata = props.getMetadata();
+        
+        //
+        // load all of the metric data from the RMD
+        //
+        Iterator i = metadata.getPropertyNames().iterator();
+        
+        while (i.hasNext())
+        {
+            QName qname = (QName)i.next();
+            String capability = metadata.getExtendedMetadata(qname, MuwsConstants.CAPABILITY_QNAME);
+            
+            //
+            // a property is a metric IF it defines a Capability element in 
+            // its RMD definition with the Metrics capability URI
+            //
+            if (capability != null && capability.equals(MuwsConstants.METRICS_URI))
+            {
+                Metric metric = new SimpleMetric(qname, resource);
+                _metricsByQName.put(qname, metric);
+                
+                //
+                // on demand? update metadata before reads
+                //
+                if (metric.isOnDemand())
+                    props.addReadListener(new MetricOnDemandListener(metric));
+                
+                //
+                // add metric attributes for all reads
+                //
+                props.addReadListener(new MetricDecorationProvider(metric));
+                
+                //
+                // update metadata whenever changes occur
+                //
+                props.addChangeListener(new MetricUpdateListener(metric));
+                
+                //
+                // special case: counters that run on an interval can be 
+                // automated by starting a thread that increments the value 
+                // every N seconds
+                //
+                if (metric.isCounter() && metric.isInterval())
+                {
+                    Thread counter = new CounterThread(props, metric);
+                    _countersByQName.put(qname, counter);
+                    counter.start();
+                }
+            }
+        }
+    }
+    
+    public void shutdown() 
+        throws SoapFault
+    {
+        //
+        // make sure we kill off any counters
+        //
+        Iterator i = _countersByQName.values().iterator();
+        
+        while (i.hasNext())
+        {
+            Thread next = (Thread)i.next();
+            next.destroy();
+        }
+        
+        super.shutdown();
+    }
+
+    public Date getCurrentTime()
+    {
+        return new Date();
+    }
+    
+    public Metric getMetric(QName propertyQName)
+    {
+        return (Metric)_metricsByQName.get(propertyQName);
+    }
+    
+    /**
+     * 
+     * CounterThread simply updates an integer property value every N seconds, 
+     * as specified in a metric's RMD definition. It checks to see if a metric 
+     * has been reset before each update so it doesn't overwrite any resets.
+     *
+     * @author Dan Jemiolo (danj)
+     *
+     */
+    class CounterThread extends Thread
+    {
+        private Metric _metric = null;
+        
+        private ResourcePropertyCollection _properties = null;
+        
+        public CounterThread(ResourcePropertyCollection properties, Metric metric)
+        {
+            _properties = properties;
+            _metric = metric;
+        }
+        
+        private int getCurrentValue()
+        {
+            QName name = _metric.getName();
+            Element[] values = null;
+            
+            try
+            {
+                values = _properties.getResourceProperty(name);
+            }
+            
+            catch (SoapFault fault)
+            {
+                throw new RuntimeException(fault.getMessage(), fault);
+            }
+            
+            return XmlUtils.getInteger(values[0]).intValue();
+        }
+                
+        public void run()
+        {
+            QName name = _metric.getName();
+            long interval = _metric.getInterval();
+            
+            int currentValue = getCurrentValue();
+            
+            while (true)
+            {
+                try
+                {
+                    Thread.currentThread().sleep(interval);
+                }
+                
+                catch (InterruptedException error)
+                {
+                    //
+                    // just continue on - nothing we can do about inaccuracy
+                    //
+                    error.printStackTrace();
+                }
+                
+                if (_metric.hasBeenReset())
+                    currentValue = getCurrentValue();
+                
+                try
+                {
+                    Integer asObject = new Integer(++currentValue);
+                    _properties.updateResourceProperty(name, new Object[]{ asObject });
+                }
+                
+                catch (SoapFault fault)
+                {
+                    //
+                    // just continue on - what can we do?
+                    //
+                    fault.printStackTrace();
+                }
+            }
+        }
+    }
+}

Added: webservices/muse/trunk/modules/muse-wsdm-muws/src/org/apache/muse/ws/dm/muws/impl/SimpleOperationalStatus.java
URL: http://svn.apache.org/viewvc/webservices/muse/trunk/modules/muse-wsdm-muws/src/org/apache/muse/ws/dm/muws/impl/SimpleOperationalStatus.java?rev=413693&view=auto
==============================================================================
--- webservices/muse/trunk/modules/muse-wsdm-muws/src/org/apache/muse/ws/dm/muws/impl/SimpleOperationalStatus.java (added)
+++ webservices/muse/trunk/modules/muse-wsdm-muws/src/org/apache/muse/ws/dm/muws/impl/SimpleOperationalStatus.java Mon Jun 12 09:06:54 2006
@@ -0,0 +1,59 @@
+/*=============================================================================*
+ *  Copyright 2006 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 org.apache.muse.ws.dm.muws.impl;
+
+import javax.xml.namespace.QName;
+
+import org.apache.muse.ws.addressing.soap.SoapFault;
+import org.apache.muse.ws.dm.muws.OperationalStatus;
+
+/**
+ *
+ * SimpleOperationalStatus is Muse's default implementation of the WSDM 
+ * OperationalStatus capability.
+ *
+ * @author Dan Jemiolo (danj)
+ *
+ */
+
+public class SimpleOperationalStatus 
+    extends AbstractManageabilityCapability implements OperationalStatus
+{    
+    private String _status = null;
+
+    public QName[] getPropertyNames()
+    {
+        return PROPERTIES;
+    }
+    
+    public void initialize()
+        throws SoapFault
+    {
+        super.initialize();
+        setOperationalStatus(UNKNOWN);
+    }
+    
+    public String getOperationalStatus()
+    {
+        return _status;
+    }
+
+    public void setOperationalStatus(String status)
+    {
+        _status = status;
+    }
+}

Added: webservices/muse/trunk/modules/muse-wsdm-muws/src/org/apache/muse/ws/dm/muws/impl/SimpleParticipant.java
URL: http://svn.apache.org/viewvc/webservices/muse/trunk/modules/muse-wsdm-muws/src/org/apache/muse/ws/dm/muws/impl/SimpleParticipant.java?rev=413693&view=auto
==============================================================================
--- webservices/muse/trunk/modules/muse-wsdm-muws/src/org/apache/muse/ws/dm/muws/impl/SimpleParticipant.java (added)
+++ webservices/muse/trunk/modules/muse-wsdm-muws/src/org/apache/muse/ws/dm/muws/impl/SimpleParticipant.java Mon Jun 12 09:06:54 2006
@@ -0,0 +1,309 @@
+/*=============================================================================*
+ *  Copyright 2006 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 org.apache.muse.ws.dm.muws.impl;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import org.apache.muse.util.messages.Messages;
+import org.apache.muse.util.messages.MessagesFactory;
+import org.apache.muse.util.xml.XmlUtils;
+import org.apache.muse.ws.addressing.EndpointReference;
+import org.apache.muse.ws.addressing.soap.SoapFault;
+import org.apache.muse.ws.dm.muws.Identity;
+import org.apache.muse.ws.dm.muws.MuwsConstants;
+import org.apache.muse.ws.dm.muws.Participant;
+import org.apache.muse.ws.dm.muws.Relationships;
+import org.apache.muse.ws.resource.WsResource;
+import org.apache.muse.ws.resource.basefaults.BaseFault;
+import org.apache.muse.ws.resource.basefaults.WsbfUtils;
+import org.apache.muse.ws.resource.ext.faults.InvalidMessageFormatFault;
+import org.apache.muse.ws.resource.remote.WsResourceClient;
+
+/**
+ *
+ * SimpleParticipant represents resources that are participating in a relationship 
+ * through the {@linkplain Relationships Relationships} capability. It has 
+ * the information needed to locate the participants in a relationship and 
+ * determine their roles.
+ *
+ * @author Dan Jemiolo (danj)
+ *
+ */
+
+public class SimpleParticipant implements Participant
+{
+    //
+    // Used to look up all exception messages
+    //
+    private static Messages _MESSAGES = MessagesFactory.get(SimpleParticipant.class);
+    
+    private EndpointReference _resourceEPR = null;
+    
+    private URI _resourceID = null;
+    
+    public URI _role = null;
+    
+    /**
+     * 
+     * @param xml
+     *        The DOM Element representing the relationship participant.
+     * 
+     * @throws BaseFault
+     *         <ul>
+     *         <li>If the participant XML is not formatted properly.</li>
+     *         </ul>
+     *
+     */
+    public SimpleParticipant(Element xml)
+        throws BaseFault
+    {
+        if (xml == null)
+            throw new NullPointerException(_MESSAGES.get("NullParticipantElement"));
+        
+        Element eprXML = XmlUtils.getElement(xml, MuwsConstants.MANAGEABILITY_EPR_QNAME);
+        
+        if (eprXML == null)
+            throw new InvalidMessageFormatFault(_MESSAGES.get("NoParticipantEPR"));
+        
+        try
+        {
+            _resourceEPR = new EndpointReference(eprXML);
+        }
+        
+        catch (SoapFault error)
+        {
+            throw new InvalidMessageFormatFault(error);
+        }
+        
+        String idString = XmlUtils.getElementText(xml, MuwsConstants.RESOURCE_ID_QNAME);
+        
+        if (idString == null)
+            throw new InvalidMessageFormatFault(_MESSAGES.get("NoParticipantID"));
+        
+        String roleString = XmlUtils.getElementText(xml, MuwsConstants.ROLE_QNAME);
+        
+        if (roleString == null)
+            throw new InvalidMessageFormatFault(_MESSAGES.get("NoParticipantRole"));
+        
+        try
+        {
+            _resourceID = new URI(idString);
+            _role = new URI(roleString);
+        }
+        
+        catch (URISyntaxException error)
+        {
+            Object[] filler = { error.getMessage() };
+            throw new InvalidMessageFormatFault(_MESSAGES.get("InvalidParticipantURI", filler));
+        }
+    }
+    
+    /**
+     * 
+     * @param resourceEPR
+     *        The participant's EPR.
+     * 
+     * @param resourceID
+     *        The participant's MUWS ResourceId.
+     * 
+     * @param role
+     *        The URI that identifies the participant's role in the 
+     *        relationship.
+     *
+     */
+    public SimpleParticipant(EndpointReference resourceEPR, URI resourceID, URI role)
+    {
+        if (resourceEPR == null)
+            throw new NullPointerException(_MESSAGES.get("NullParticipantEPR"));
+
+        if (resourceID == null)
+            throw new NullPointerException(_MESSAGES.get("NullParticipantID"));
+
+        if (role == null)
+            throw new NullPointerException(_MESSAGES.get("NullParticipantRole"));
+        
+        _resourceEPR = resourceEPR;
+        _resourceID = resourceID;
+        _role = role;
+    }
+    
+    /**
+     * 
+     * @param resource
+     *        The participant resource. This will be used to gather its EPR 
+     *        and MUWS ResourceId.
+     * 
+     * @param role
+     *        The URI that identifies the participant's role in the 
+     *        relationship.
+     * 
+     * @throws BaseFault
+     *         <ul>
+     *         <li>If the participant resource is unavailable.</li>
+     *         </ul>
+     *
+     */
+    public SimpleParticipant(WsResource resource, URI role)
+        throws BaseFault
+    {
+        if (resource == null)
+            throw new NullPointerException(_MESSAGES.get("NullParticipantResource"));
+
+        if (role == null)
+            throw new NullPointerException(_MESSAGES.get("NullParticipantRole"));
+        
+        _resourceEPR = resource.getEndpointReference();
+        _resourceID = getResourceId(resource);
+        _role = role;
+    }
+    
+    /**
+     * 
+     * @param remote
+     *        A proxy that points to the participant resource. This will be 
+     *        used to gather its EPR and MUWS ResourceId.
+     * 
+     * @param role
+     *        The URI that identifies the participant's role in the 
+     *        relationship.
+     * 
+     * @throws BaseFault
+     *         <ul>
+     *         <li>If the participant resource is unavailable.</li>
+     *         </ul>
+     *
+     */
+    public SimpleParticipant(WsResourceClient remote, URI role)
+        throws BaseFault
+    {
+        if (remote == null)
+            throw new NullPointerException(_MESSAGES.get("NullParticipantResource"));
+
+        if (role == null)
+            throw new NullPointerException(_MESSAGES.get("NullParticipantRole"));
+        
+        _resourceEPR = remote.getEndpointReference();
+        _resourceID = getResourceId(remote);
+        _role = role;
+    }
+    
+    private static URI getResourceId(WsResource resource)
+        throws BaseFault
+    {
+        Identity id = (Identity)resource.getCapability(MuwsConstants.IDENTITY_URI);
+        return id == null ? null : id.getResourceId();
+    }
+    
+    private static URI getResourceId(WsResourceClient resource)
+        throws BaseFault
+    {
+        try
+        {
+            URI[] results = (URI[])resource.getPropertyAsObject(MuwsConstants.RESOURCE_ID_QNAME, URI.class);
+            
+            if (results.length == 0)
+                return null;
+            
+            return results[0];
+        }
+        
+        catch (SoapFault error)
+        {
+            throw WsbfUtils.convertToFault(error);
+        }
+    }
+    
+    /**
+     * 
+     * @return The participant's EPR.
+     *
+     */
+    public EndpointReference getManageabilityReference()
+    {
+        return _resourceEPR;
+    }
+    
+    /**
+     * 
+     * @return The participant's MUWS ResourceId.
+     * 
+     * @see org.apache.muse.ws.dm.muws.Identity#getResourceId()
+     *
+     */
+    public URI getResourceId()
+    {
+        return _resourceID;
+    }
+    
+    /**
+     * 
+     * @return The URI identifying the role of the participant in its 
+     *         relationship.
+     *
+     */
+    public URI getRole()
+    {
+        return _role;
+    }
+    
+    /**
+     * 
+     * This method calls toXML(Document) with XmlUtils.EMPTY_DOC, the system's 
+     * DOM factory scratchpad.
+     * 
+     * @see #toXML(Document)
+     *
+     */
+    public Element toXML()
+    {
+        return toXML(XmlUtils.EMPTY_DOC);
+    }
+    
+    /**
+     * 
+     * @param doc
+     *        The XML Document to use when creating new elements for the 
+     *        participant XML. The elements that are created will <b>not</b> 
+     *        be appended to this Document.
+     * 
+     * @return A valid XML representation of this participant.
+     * 
+     */
+    public Element toXML(Document doc)
+    {
+        if (doc == null)
+            throw new NullPointerException(_MESSAGES.get("NullDocument"));
+        
+        Element root = XmlUtils.createElement(doc, MuwsConstants.PARTICIPANT_QNAME);
+        
+        Element eprXML = getManageabilityReference().toXML();
+        XmlUtils.setElement(root, MuwsConstants.MANAGEABILITY_EPR_QNAME, eprXML);
+        
+        URI resourceID = getResourceId();
+        
+        if (resourceID != null)
+            XmlUtils.setElement(root, MuwsConstants.RESOURCE_ID_QNAME, resourceID);
+        
+        XmlUtils.setElement(root, MuwsConstants.ROLE_QNAME, getRole());
+        
+        return root;
+    }
+}

Added: webservices/muse/trunk/modules/muse-wsdm-muws/src/org/apache/muse/ws/dm/muws/impl/SimpleRelationshipResource.java
URL: http://svn.apache.org/viewvc/webservices/muse/trunk/modules/muse-wsdm-muws/src/org/apache/muse/ws/dm/muws/impl/SimpleRelationshipResource.java?rev=413693&view=auto
==============================================================================
--- webservices/muse/trunk/modules/muse-wsdm-muws/src/org/apache/muse/ws/dm/muws/impl/SimpleRelationshipResource.java (added)
+++ webservices/muse/trunk/modules/muse-wsdm-muws/src/org/apache/muse/ws/dm/muws/impl/SimpleRelationshipResource.java Mon Jun 12 09:06:54 2006
@@ -0,0 +1,127 @@
+/*=============================================================================*
+ *  Copyright 2006 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 org.apache.muse.ws.dm.muws.impl;
+
+import javax.xml.namespace.QName;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import org.apache.muse.util.messages.Messages;
+import org.apache.muse.util.messages.MessagesFactory;
+import org.apache.muse.util.xml.XmlUtils;
+import org.apache.muse.ws.dm.muws.MuwsConstants;
+import org.apache.muse.ws.dm.muws.Participant;
+import org.apache.muse.ws.dm.muws.RelationshipResource;
+import org.apache.muse.ws.dm.muws.RelationshipType;
+
+/**
+ *
+ * SimpleRelationship is Muse's default implementation of the MUWS Part 2 
+ * RelationshipResource resource type. This class is exposed as a first-class resource 
+ * to web service clients. 
+ *
+ * @author Dan Jemiolo (danj)
+ *
+ */
+
+public class SimpleRelationshipResource 
+    extends AbstractManageabilityCapability implements RelationshipResource
+{
+    //
+    // Used to look up all exception messages
+    //
+    private static Messages _MESSAGES = MessagesFactory.get(SimpleRelationshipResource.class);
+    
+    private String _name = null;
+    
+    private Participant[] _participants = null;
+    
+    private RelationshipType _type = null;
+
+    public QName[] getPropertyNames()
+    {
+        return PROPERTIES;
+    }
+    
+    public String getName()
+    {
+        return _name;
+    }
+
+    public Participant[] getParticipant()
+    {
+        return _participants;
+    }
+
+    public RelationshipType getType()
+    {
+        return _type;
+    }
+
+    public void setName(String name)
+    {
+        _name = name;
+    }
+
+    public void setParticipant(Participant[] participants)
+    {
+        if (participants == null)
+            throw new NullPointerException(_MESSAGES.get("NullParticipants"));
+        
+        _participants = participants;
+    }
+
+    public void setType(RelationshipType type)
+    {
+        if (type == null)
+            throw new NullPointerException(_MESSAGES.get("NullRelationshipType"));
+        
+        _type = type;
+    }
+    
+    public Element toXML()
+    {
+        return toXML(XmlUtils.EMPTY_DOC);
+    }
+    
+    public Element toXML(Document doc)
+    {
+        if (doc == null)
+            throw new NullPointerException(_MESSAGES.get("NullDocument"));
+        
+        Element root = XmlUtils.createElement(doc, MuwsConstants.RELATIONSHIP_QNAME);
+        
+        String name = getName();
+        
+        if (name != null)
+            XmlUtils.setElement(root, MuwsConstants.NAME_QNAME, name);
+        
+        Element typeXML = getType().toXML(doc);
+        XmlUtils.setElement(root, MuwsConstants.TYPE_QNAME, typeXML);
+        
+        Participant[] participants = getParticipant();
+        
+        for (int n = 0; n < participants.length; ++n)
+        {
+            Element participantXML = participants[n].toXML(doc);
+            root.appendChild(participantXML);
+        }
+        
+        return root;
+    }
+}

Added: webservices/muse/trunk/modules/muse-wsdm-muws/src/org/apache/muse/ws/dm/muws/impl/SimpleRelationshipType.java
URL: http://svn.apache.org/viewvc/webservices/muse/trunk/modules/muse-wsdm-muws/src/org/apache/muse/ws/dm/muws/impl/SimpleRelationshipType.java?rev=413693&view=auto
==============================================================================
--- webservices/muse/trunk/modules/muse-wsdm-muws/src/org/apache/muse/ws/dm/muws/impl/SimpleRelationshipType.java (added)
+++ webservices/muse/trunk/modules/muse-wsdm-muws/src/org/apache/muse/ws/dm/muws/impl/SimpleRelationshipType.java Mon Jun 12 09:06:54 2006
@@ -0,0 +1,112 @@
+/*=============================================================================*
+ *  Copyright 2006 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 org.apache.muse.ws.dm.muws.impl;
+
+import java.util.ArrayList;
+
+import javax.xml.namespace.QName;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import org.apache.muse.util.messages.Messages;
+import org.apache.muse.util.messages.MessagesFactory;
+import org.apache.muse.util.xml.XmlUtils;
+import org.apache.muse.ws.dm.muws.MuwsConstants;
+import org.apache.muse.ws.dm.muws.RelationshipType;
+import org.apache.muse.ws.dm.muws.Relationships;
+
+/**
+ *
+ * SimpleRelationshipType represents simple and complex relationship types for the 
+ * {@linkplain Relationships Relationships} capability. It is commonly used to 
+ * create static fields representing an enumeration of well-defined relationships.
+ *
+ * @author Dan Jemiolo (danj)
+ *
+ */
+
+public class SimpleRelationshipType implements RelationshipType
+{
+
+    //
+    // Used to lookup all exception messages
+    //
+    private static Messages _MESSAGES = MessagesFactory.get(SimpleRelationshipType.class);
+    
+    //
+    // The user-defined type names - this will be the element names 
+    // in the XML representation
+    //
+    private QName[] _values = null;
+    
+    public SimpleRelationshipType(Element xml)
+    {
+        ArrayList valuesList = new ArrayList();
+        Element next = XmlUtils.getFirstElement(xml);
+        
+        while (next != null)
+        {
+            valuesList.add(next);
+            next = XmlUtils.getFirstElement(next);
+        }
+        
+        _values = new QName[valuesList.size()];
+        _values = (QName[])valuesList.toArray(_values);
+    }
+    
+    public SimpleRelationshipType(QName[] values)
+    {
+        if (values == null)
+            throw new NullPointerException(_MESSAGES.get("NullRelationshipType"));
+        
+        _values = values;
+    }
+    
+    public QName[] getValues()
+    {
+        return _values;
+    }
+    
+    public Element toXML()
+    {
+        return toXML(XmlUtils.EMPTY_DOC);
+    }
+    
+    public Element toXML(Document doc)
+    {
+        if (doc == null)
+            throw new NullPointerException(_MESSAGES.get("NullDocument"));
+        
+        //
+        // the state value is wrapped in a wsdm:Type element
+        //
+        Element root = XmlUtils.createElement(doc, MuwsConstants.TYPE_QNAME);
+        
+        Element parent = root;
+        QName[] childNames = getValues();
+        
+        for (int n = 0; n < childNames.length; ++n)
+        {
+            Element child = XmlUtils.createElement(doc, childNames[n]);
+            parent.appendChild(child);
+            parent = child;
+        }
+        
+        return root;
+    }
+}

Added: webservices/muse/trunk/modules/muse-wsdm-muws/src/org/apache/muse/ws/dm/muws/impl/SimpleRelationships.java
URL: http://svn.apache.org/viewvc/webservices/muse/trunk/modules/muse-wsdm-muws/src/org/apache/muse/ws/dm/muws/impl/SimpleRelationships.java?rev=413693&view=auto
==============================================================================
--- webservices/muse/trunk/modules/muse-wsdm-muws/src/org/apache/muse/ws/dm/muws/impl/SimpleRelationships.java (added)
+++ webservices/muse/trunk/modules/muse-wsdm-muws/src/org/apache/muse/ws/dm/muws/impl/SimpleRelationships.java Mon Jun 12 09:06:54 2006
@@ -0,0 +1,263 @@
+/*=============================================================================*
+ *  Copyright 2006 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 org.apache.muse.ws.dm.muws.impl;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.xml.namespace.QName;
+
+import org.w3c.dom.Element;
+
+import org.apache.muse.core.ResourceManager;
+import org.apache.muse.core.routing.MessageHandler;
+import org.apache.muse.util.ReflectUtils;
+import org.apache.muse.util.messages.Messages;
+import org.apache.muse.util.messages.MessagesFactory;
+import org.apache.muse.util.xml.XmlUtils;
+import org.apache.muse.ws.addressing.soap.SoapFault;
+import org.apache.muse.ws.dm.muws.MuwsConstants;
+import org.apache.muse.ws.dm.muws.Participant;
+import org.apache.muse.ws.dm.muws.RelationshipResource;
+import org.apache.muse.ws.dm.muws.RelationshipType;
+import org.apache.muse.ws.dm.muws.Relationships;
+import org.apache.muse.ws.dm.muws.ext.faults.RelationshipCreationFailedFault;
+import org.apache.muse.ws.resource.WsResource;
+import org.apache.muse.ws.resource.basefaults.BaseFault;
+
+/**
+ *
+ * SimpleRelationships is Muse's default implementation of the MUWS Part 2 
+ * Relationships capability. It ensures that the RelationshipResource endpoint is 
+ * exposed (for SOAP-level access to the relationships a resource participates 
+ * in) and provides lifecycle management for the relationship resources.
+ *
+ * @author Dan Jemiolo (danj)
+ *
+ */
+
+public class SimpleRelationships 
+    extends AbstractManageabilityCapability implements Relationships
+{
+    private static Messages _MESSAGES = MessagesFactory.get(SimpleRelationships.class);
+        
+    private String _relationshipPath = null;
+    
+    private Set _relationships = new HashSet();
+
+    public QName[] getPropertyNames()
+    {
+        return PROPERTIES;
+    }
+
+    public WsResource addRelationship(String name, 
+                                      RelationshipType type, 
+                                      Participant[] participants) 
+        throws BaseFault
+    {
+        WsResource relationship = createRelationship(name, type, participants);
+        _relationships.add(relationship);
+        return relationship;
+    }
+    
+    protected MessageHandler createQueryHandler()
+    {
+        MessageHandler handler = new QueryRelationshipsHandler();
+        
+        Method method = ReflectUtils.getFirstMethod(getClass(), "queryRelationshipsByType");
+        handler.setMethod(method);
+        
+        return handler;
+    }
+    
+    protected WsResource createRelationship(Element xml) 
+        throws BaseFault
+    {
+        ResourceManager manager = getWsResource().getResourceManager();
+        String endpoint = getRelationshipContextPath();
+        
+        WsResource resource = null;
+        
+        try
+        {
+            resource = (WsResource)manager.createResource(endpoint);
+        }
+        
+        catch (SoapFault error)
+        {
+            throw new RelationshipCreationFailedFault(error);
+        }
+
+        RelationshipResource relationship = 
+            (RelationshipResource)resource.getCapability(MuwsConstants.RELATIONSHIP_RESOURCE_URI);
+                
+        relationship.setName(XmlUtils.getElementText(xml, MuwsConstants.NAME_QNAME));
+        
+        Element typeXML = XmlUtils.getElement(xml, MuwsConstants.TYPE_QNAME);
+        relationship.setType(new SimpleRelationshipType(typeXML));
+        
+        Element[] participantsXML = XmlUtils.getElements(xml, MuwsConstants.PARTICIPANT_QNAME);
+        SimpleParticipant[] participants = new SimpleParticipant[participantsXML.length];
+        
+        for (int n = 0; n < participantsXML.length; ++n)
+            participants[n] = new SimpleParticipant(participantsXML[n]);
+        
+        relationship.setParticipant(participants);
+        
+        return resource;
+    }
+    
+    protected WsResource createRelationship(String name,
+                                            RelationshipType type, 
+                                            Participant[] participants)
+        throws BaseFault
+    {
+        ResourceManager manager = getWsResource().getResourceManager();
+        String endpoint = getRelationshipContextPath();
+        
+        WsResource resource = null;
+        
+        try
+        {
+            resource = (WsResource)manager.createResource(endpoint);
+        }
+        
+        catch (SoapFault error)
+        {
+            error.printStackTrace();
+        }
+        
+        RelationshipResource relationship = 
+            (RelationshipResource)resource.getCapability(MuwsConstants.RELATIONSHIP_RESOURCE_URI);
+        
+        relationship.setName(name);
+        relationship.setType(type);
+        relationship.setParticipant(participants);
+        
+        try
+        {
+            relationship.initialize();
+            manager.addResource(resource.getEndpointReference(), resource);
+        }
+        
+        catch (SoapFault error)
+        {
+            error.printStackTrace();
+        }
+        
+        return resource;
+    }
+    
+    protected String getRelationshipContextPath()
+    {
+        return _relationshipPath;
+    }
+    
+    public WsResource[] getRelationship()
+    {
+        WsResource[] array = new WsResource[_relationships.size()];
+        return (WsResource[])_relationships.toArray(array);
+    }
+    
+    public void initialize()
+        throws SoapFault
+    {
+        super.initialize();
+        
+        //
+        // make sure the RelationshipResource endpoint is exposed, since our 
+        // relationships are all first-class resources
+        //
+        WsResource resource = getWsResource();
+        
+        ResourceManager manager = resource.getResourceManager();
+        _relationshipPath = manager.getResourceContextPath(RelationshipResource.class);
+        
+        if (_relationshipPath == null)
+            throw new RuntimeException(_MESSAGES.get("NoRelationshipEndpoint"));
+        
+        setMessageHandler(createQueryHandler());
+    }
+    
+    public WsResource[] queryRelationshipsByType(QName[] types)
+        throws BaseFault
+    {
+        if (types == null)
+            throw new NullPointerException(_MESSAGES.get("NullQueryTypes"));
+        
+        if (types.length == 0)
+            throw new IllegalArgumentException(_MESSAGES.get("EmptyQueryTypes"));
+        
+        Set typesSet = new HashSet();
+        
+        for (int n = 0; n < types.length; ++n)
+            typesSet.add(types[n]);
+        
+        WsResource[] relationships = getRelationship();
+        Collection results = new ArrayList();
+        
+        for (int n = 0; n < relationships.length; ++n)
+        {
+            RelationshipResource capability = 
+                (RelationshipResource)relationships[n].getCapability(MuwsConstants.RELATIONSHIP_RESOURCE_URI);
+            
+            QName[] typeValues = capability.getType().getValues();
+            
+            if (typesSet.contains(typeValues[0]))
+                results.add(relationships[n]);
+        }
+        
+        WsResource[] asArray = new WsResource[results.size()];
+        return (WsResource[])results.toArray(asArray);
+    }
+
+    public void removeRelationship(WsResource relationship)
+    {
+        if (relationship == null)
+            throw new NullPointerException(_MESSAGES.get("NullRelationship"));
+        
+        if (!_relationships.remove(relationship))
+            throw new RuntimeException(_MESSAGES.get("RelationshipNotFound"));
+    }
+    
+    protected Element[] getRelationshipElements()
+    {
+        WsResource[] relationships = getRelationship();
+        Element[] relationshipXML = new Element[relationships.length];
+        
+        for (int n = 0; n < relationships.length; ++n)
+        {
+            RelationshipResource capability = 
+                (RelationshipResource)relationships[n].getCapability(MuwsConstants.RELATIONSHIP_RESOURCE_URI);
+            relationshipXML[n] = capability.toXML();
+        }
+        
+        return relationshipXML;
+    }
+
+    public Element[] getProperty(QName propertyName) 
+        throws BaseFault
+    {
+        if (propertyName.equals(MuwsConstants.RELATIONSHIP_QNAME))
+            return getRelationshipElements();
+        
+        return super.getProperty(propertyName);
+    }
+}

Added: webservices/muse/trunk/modules/muse-wsdm-muws/src/org/apache/muse/ws/dm/muws/impl/SimpleState.java
URL: http://svn.apache.org/viewvc/webservices/muse/trunk/modules/muse-wsdm-muws/src/org/apache/muse/ws/dm/muws/impl/SimpleState.java?rev=413693&view=auto
==============================================================================
--- webservices/muse/trunk/modules/muse-wsdm-muws/src/org/apache/muse/ws/dm/muws/impl/SimpleState.java (added)
+++ webservices/muse/trunk/modules/muse-wsdm-muws/src/org/apache/muse/ws/dm/muws/impl/SimpleState.java Mon Jun 12 09:06:54 2006
@@ -0,0 +1,72 @@
+/*=============================================================================*
+ *  Copyright 2006 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 org.apache.muse.ws.dm.muws.impl;
+
+import javax.xml.namespace.QName;
+
+import org.apache.muse.util.messages.Messages;
+import org.apache.muse.util.messages.MessagesFactory;
+import org.apache.muse.ws.dm.muws.StateType;
+import org.apache.muse.ws.dm.muws.StateTransition;
+import org.apache.muse.ws.dm.muws.State;
+
+/**
+ *
+ * SimpleState is Muse's default implementation of the WSDM State capability.
+ *
+ * @author Dan Jemiolo (danj)
+ *
+ */
+
+public class SimpleState 
+    extends AbstractManageabilityCapability implements State
+{
+    //
+    // Used to lookup all exception messages
+    //
+    private static Messages _MESSAGES = MessagesFactory.get(SimpleState.class);
+        
+    private StateType _state = null;
+    
+    private StateTransition _transition = null;
+
+    public QName[] getPropertyNames()
+    {
+        return PROPERTIES;
+    }
+    
+    public StateType getState()
+    {
+        return _state;
+    }
+    
+    public StateTransition getStateTransition()
+    {
+        return _transition;
+    }
+
+    public void setState(StateType state)
+    {
+        if (state == null)
+            throw new NullPointerException(_MESSAGES.get("NullState"));
+        
+        StateType previous = _state;
+        _state = state;
+        
+        _transition = new SimpleStateTransition(previous, _state);
+    }
+}

Added: webservices/muse/trunk/modules/muse-wsdm-muws/src/org/apache/muse/ws/dm/muws/impl/SimpleStateTransition.java
URL: http://svn.apache.org/viewvc/webservices/muse/trunk/modules/muse-wsdm-muws/src/org/apache/muse/ws/dm/muws/impl/SimpleStateTransition.java?rev=413693&view=auto
==============================================================================
--- webservices/muse/trunk/modules/muse-wsdm-muws/src/org/apache/muse/ws/dm/muws/impl/SimpleStateTransition.java (added)
+++ webservices/muse/trunk/modules/muse-wsdm-muws/src/org/apache/muse/ws/dm/muws/impl/SimpleStateTransition.java Mon Jun 12 09:06:54 2006
@@ -0,0 +1,215 @@
+/*=============================================================================*
+ *  Copyright 2006 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 org.apache.muse.ws.dm.muws.impl;
+
+import java.text.ParseException;
+import java.util.Date;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import org.apache.muse.util.messages.Messages;
+import org.apache.muse.util.messages.MessagesFactory;
+import org.apache.muse.util.xml.XmlUtils;
+import org.apache.muse.util.xml.XsdUtils;
+import org.apache.muse.ws.dm.muws.StateTransition;
+import org.apache.muse.ws.dm.muws.MuwsConstants;
+import org.apache.muse.ws.dm.muws.State;
+import org.apache.muse.ws.dm.muws.StateType;
+import org.apache.muse.ws.resource.basefaults.BaseFault;
+import org.apache.muse.ws.resource.ext.faults.InvalidMessageFormatFault;
+
+/**
+ *
+ * SimpleStateTransition represents changes in state for the 
+ * {@linkplain State State} capability.
+ * 
+ * @author Dan Jemiolo (danj)
+ *
+ */
+
+public class SimpleStateTransition implements StateTransition
+{
+    //
+    // Used to lookup all exception messages
+    //
+    private static Messages _MESSAGES = 
+        MessagesFactory.get(SimpleStateTransition.class);
+    
+    //
+    // The current state value - equivalent to State.getCurrentState()
+    //
+    private StateType _entered = null;
+    
+    //
+    // The last state value - this is null for a resource's first transition.
+    //
+    private StateType _previous = null;
+    
+    //
+    // The time that the transition was performed. The default is "right now".
+    //
+    private Date _transitionTime = new Date();
+    
+    /**
+     * 
+     * @param xml
+     *        The DOM Element representing the state transition.
+     *
+     */
+    public SimpleStateTransition(Element xml) 
+        throws BaseFault
+    {
+        if (xml == null)
+            throw new NullPointerException(_MESSAGES.get("NullSTElement"));
+        
+        //
+        // first get the time - we have to add a lot of exception cruft 
+        // to make sure we get a valid date
+        //
+        
+        String timeString = xml.getAttribute(MuwsConstants.TIME);
+        
+        if (timeString == null || timeString.length() == 0)
+            throw new InvalidMessageFormatFault(_MESSAGES.get("NoTransitionTime"));
+        
+        try
+        {
+            _transitionTime = XsdUtils.getLocalTime(timeString);
+        }
+        
+        catch (ParseException error)
+        {
+            throw new InvalidMessageFormatFault(error);
+        }
+        
+        //
+        // now grab the two state values - the "previous" one is optional
+        //
+        
+        Element previousXML = XmlUtils.getElement(xml, MuwsConstants.PREVIOUS_QNAME);
+        
+        if (previousXML != null)
+            _previous = new SimpleStateType(previousXML);
+        
+        Element enteredXML = XmlUtils.getElement(xml, MuwsConstants.ENTERED_QNAME);
+
+        if (enteredXML == null)
+            throw new InvalidMessageFormatFault(_MESSAGES.get("NoEnteredState"));
+        
+        _entered = new SimpleStateType(enteredXML);
+    }
+    
+    /** 
+     * 
+     * @param previous
+     *        The state the owning resource was in previously. This can be 
+     *        null for new resources that had no initial state.
+     * 
+     * @param entered
+     *        The state the owning resource just entered. This is usually 
+     *        equivalent to its current state.
+     * 
+     */
+    public SimpleStateTransition(StateType previous, StateType entered)
+    {
+        if (entered == null)
+            throw new NullPointerException(_MESSAGES.get("NullState"));
+        
+        _previous = previous;
+        _entered = entered;
+    }
+    
+    /**
+     * 
+     * @return The state the resource entered during the transition.
+     *
+     */
+    public StateType getEnteredState()
+    {
+        return _entered;
+    }
+    
+    /**
+     * 
+     * @return The state the resource left during the transition. This is 
+     *         null if there was no previous state.
+     *
+     */
+    public StateType getPreviousState()
+    {
+        return _previous;
+    }
+    
+    /**
+     * 
+     * @return The time that the transition occurred.
+     *
+     */
+    public Date getTransitionTime()
+    {
+        return _transitionTime;
+    }
+    
+    /**
+     * 
+     * This method calls toXML(Document) with XmlUtils.EMPTY_DOC, the system's 
+     * DOM factory scratchpad.
+     * 
+     * @see #toXML(Document)
+     *
+     */    
+    public Element toXML()
+    {
+        return toXML(XmlUtils.EMPTY_DOC);
+    }
+    
+    /**
+     * 
+     * @param doc
+     *        The XML Document to use when creating new elements for the 
+     *        transition XML. The elements that are created will <b>not</b> 
+     *        be appended to this Document.
+     * 
+     * @return A valid XML representation of this transition.
+     * 
+     */
+    public Element toXML(Document doc)
+    {
+        if (doc == null)
+            throw new NullPointerException(_MESSAGES.get("NullDocument"));
+        
+        Element root = XmlUtils.createElement(doc, MuwsConstants.TRANSITION_QNAME);
+        
+        Date time = getTransitionTime();
+        root.setAttribute(MuwsConstants.TIME, XsdUtils.getLocalTimeString(time));
+        
+        StateType previous = getPreviousState();
+        
+        if (previous != null)
+        {
+            Element previousXML = previous.toXML(doc);
+            XmlUtils.setElement(root, MuwsConstants.PREVIOUS_QNAME, previousXML, true);
+        }
+        
+        StateType entered = getEnteredState();
+        Element enteredXML = entered.toXML(doc);
+        XmlUtils.setElement(root, MuwsConstants.ENTERED_QNAME, enteredXML, true);
+        
+        return root;
+    }
+}

Added: webservices/muse/trunk/modules/muse-wsdm-muws/src/org/apache/muse/ws/dm/muws/impl/SimpleStateType.java
URL: http://svn.apache.org/viewvc/webservices/muse/trunk/modules/muse-wsdm-muws/src/org/apache/muse/ws/dm/muws/impl/SimpleStateType.java?rev=413693&view=auto
==============================================================================
--- webservices/muse/trunk/modules/muse-wsdm-muws/src/org/apache/muse/ws/dm/muws/impl/SimpleStateType.java (added)
+++ webservices/muse/trunk/modules/muse-wsdm-muws/src/org/apache/muse/ws/dm/muws/impl/SimpleStateType.java Mon Jun 12 09:06:54 2006
@@ -0,0 +1,111 @@
+/*=============================================================================*
+ *  Copyright 2006 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 org.apache.muse.ws.dm.muws.impl;
+
+import java.util.ArrayList;
+
+import javax.xml.namespace.QName;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import org.apache.muse.util.messages.Messages;
+import org.apache.muse.util.messages.MessagesFactory;
+import org.apache.muse.util.xml.XmlUtils;
+import org.apache.muse.ws.dm.muws.StateType;
+import org.apache.muse.ws.dm.muws.MuwsConstants;
+import org.apache.muse.ws.dm.muws.State;
+
+/**
+ *
+ * SimpleStateType represents state values for the {@linkplain State State} 
+ * capability. It is commonly used to create static fields representing 
+ * an enumeration of well-defined states.
+ *
+ * @author Dan Jemiolo (danj)
+ *
+ */
+
+public class SimpleStateType implements StateType
+{
+    //
+    // Used to lookup all exception messages
+    //
+    private static Messages _MESSAGES = MessagesFactory.get(SimpleStateType.class);
+    
+    //
+    // The user-defined state names - this will be the element names 
+    // in the XML representation
+    //
+    private QName[] _values = null;
+    
+    public SimpleStateType(Element xml)
+    {
+        ArrayList valuesList = new ArrayList();
+        Element next = XmlUtils.getFirstElement(xml);
+        
+        while (next != null)
+        {
+            valuesList.add(next);
+            next = XmlUtils.getFirstElement(next);
+        }
+        
+        _values = new QName[valuesList.size()];
+        _values = (QName[])valuesList.toArray(_values);
+    }
+    
+    public SimpleStateType(QName[] values)
+    {
+        if (values == null)
+            throw new NullPointerException(_MESSAGES.get("NullStateName"));
+        
+        _values = values;
+    }
+    
+    public QName[] getValues()
+    {
+        return _values;
+    }
+    
+    public Element toXML()
+    {
+        return toXML(XmlUtils.EMPTY_DOC);
+    }
+    
+    public Element toXML(Document doc)
+    {
+        if (doc == null)
+            throw new NullPointerException(_MESSAGES.get("NullDocument"));
+        
+        //
+        // the state value is wrapped in a wsdm:State element
+        //
+        Element root = XmlUtils.createElement(doc, MuwsConstants.STATE_QNAME);
+        
+        Element parent = root;
+        QName[] childNames = getValues();
+        
+        for (int n = 0; n < childNames.length; ++n)
+        {
+            Element child = XmlUtils.createElement(doc, childNames[n]);
+            parent.appendChild(child);
+            parent = child;
+        }
+        
+        return root;
+    }
+}

Added: webservices/muse/trunk/modules/muse-wsdm-muws/src/org/apache/muse/ws/dm/muws/impl/XPathCorrelation.java
URL: http://svn.apache.org/viewvc/webservices/muse/trunk/modules/muse-wsdm-muws/src/org/apache/muse/ws/dm/muws/impl/XPathCorrelation.java?rev=413693&view=auto
==============================================================================
--- webservices/muse/trunk/modules/muse-wsdm-muws/src/org/apache/muse/ws/dm/muws/impl/XPathCorrelation.java (added)
+++ webservices/muse/trunk/modules/muse-wsdm-muws/src/org/apache/muse/ws/dm/muws/impl/XPathCorrelation.java Mon Jun 12 09:06:54 2006
@@ -0,0 +1,248 @@
+/*=============================================================================*
+ *  Copyright 2006 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 org.apache.muse.ws.dm.muws.impl;
+
+import javax.xml.namespace.QName;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+import org.apache.muse.util.messages.Messages;
+import org.apache.muse.util.messages.MessagesFactory;
+import org.apache.muse.util.xml.XPathUtils;
+import org.apache.muse.util.xml.XmlUtils;
+import org.apache.muse.ws.addressing.EndpointReference;
+import org.apache.muse.ws.addressing.soap.SoapFault;
+import org.apache.muse.ws.dm.muws.Correlation;
+import org.apache.muse.ws.dm.muws.MuwsConstants;
+import org.apache.muse.ws.resource.WsResource;
+import org.apache.muse.ws.resource.remote.WsResourceClient;
+
+/**
+ *
+ * XPathCorrelation represents correlation expressions formatted in XPath 1.0.
+ *
+ * @author Dan Jemiolo (danj)
+ *
+ */
+
+public class XPathCorrelation implements Correlation
+{
+    //
+    // Used to lookup all exception messages
+    //
+    private static Messages _MESSAGES = 
+        MessagesFactory.get(XPathCorrelation.class);
+    
+    private boolean _hasNegativeAssertion = false;
+    
+    //
+    // The local resource that is defining this correlation
+    //
+    private WsResource _resource = null;
+    
+    //
+    // The XPath used to evaluate other resources
+    //
+    private String _xpath = null;
+
+    /**
+     * 
+     * @param resource
+     *        The resource that is defining the CorrelatableProperties 
+     *        capability and, thus, this correlation.
+     * 
+     * @param xml
+     *        The DOM Element representing an instance of CorrelatableProperties 
+     *        that uses the XPath 1.0 dialect.
+     *
+     */
+    public XPathCorrelation(WsResource resource, Element xml)
+    {
+        if (resource == null)
+            throw new NullPointerException(_MESSAGES.get("NullOwner"));
+        
+        if (xml == null)
+            throw new NullPointerException(_MESSAGES.get("NullCPElement"));
+        
+        _resource = resource;
+        
+        _xpath = XmlUtils.extractText(xml);
+
+        if (_xpath == null)
+            throw new NullPointerException(_MESSAGES.get("NullXPath"));
+        
+        //
+        // get the (optional) NegativeAssertionPossible value
+        //
+        String negative = xml.getAttribute(MuwsConstants.NEGATIVE);
+        
+        if (negative != null && negative.length() > 0)
+            _hasNegativeAssertion = Boolean.valueOf(negative).booleanValue();
+    }
+    
+    /**
+     * 
+     * This is a convenience constructor that calls this(Resource, String, boolean) 
+     * with a 'false' third parameter.
+     *
+     * @see #XPathCorrelation(WsResource, String, boolean)
+     * 
+     */
+    public XPathCorrelation(WsResource resource, String xpath)
+    {
+        this(resource, xpath, false);
+    }
+    
+    /**
+     * 
+     * @param resource
+     *        The resource that is defining the CorrelatableProperties 
+     *        capability and, thus, this correlation.
+     * 
+     * @param xpath
+     *        The XPath 1.0 expression that should be used to evaluate 
+     *        other resources.
+     * 
+     * @param negativeAssertion
+     *        True if this correlation guarantees that a false match equates 
+     *        to two resources being different.
+     *
+     */
+    public XPathCorrelation(WsResource resource, String xpath, boolean negativeAssertion)
+    {
+        if (resource == null)
+            throw new NullPointerException(_MESSAGES.get("NullOwner"));
+        
+        if (xpath == null)
+            throw new NullPointerException(_MESSAGES.get("NullXPath"));
+        
+        _resource = resource;
+        _xpath = xpath;
+        _hasNegativeAssertion = negativeAssertion;
+    }
+    
+    /**
+     * 
+     * @return The XPath 1.0 namespace URI.
+     * 
+     */
+    public String getDialect()
+    {
+        return XPathUtils.NAMESPACE_URI;
+    }
+    
+    public WsResource getWsResource()
+    {
+        return _resource;
+    }
+    
+    /**
+     * 
+     * @return The XPath expression to evaluate against other resources' 
+     *         WS-RP collections.
+     *
+     */
+    public String getXPath()
+    {
+        return _xpath;
+    }
+    
+    public boolean hasNegativeAssertion()
+    {
+        return _hasNegativeAssertion;
+    }
+
+    /**
+     * 
+     * {@inheritDoc}
+     * <br><br>
+     * This implementation performs a WS-RP QueryResourceProperties call 
+     * against the given resource using its XPath value. If the expression 
+     * results in either a) a Boolean value of 'true' or b) a non-Boolean 
+     * that is not null (or not empty), then this method returns 'true'.
+     * 
+     */
+    public boolean matches(EndpointReference epr) 
+        throws SoapFault
+    {
+        if (epr == null)
+            throw new NullPointerException(_MESSAGES.get("NullRemoteResource"));
+        
+        WsResourceClient resource = new WsResourceClient(epr);
+        
+        String dialect = XPathUtils.NAMESPACE_URI;
+        Node[] results = resource.queryResourceProperties(_xpath, dialect);
+        
+        //
+        // no results - failed!
+        //
+        if (results.length == 0)
+            return false;
+        
+        //
+        // multiple results - passed!
+        //
+        if (results.length > 1)
+            return true;
+        
+        //
+        // one result - passes if not equal to "false"
+        //
+        // NOTE: a null Node value is ok - this signifies an Element
+        //
+        String text = results[0].getNodeValue();        
+        return text == null || !text.equalsIgnoreCase("false");
+    }
+    
+    /**
+     * 
+     * @param xpath
+     *        The XPath 1.0 expression that should be used to evaluate 
+     *        other resources.
+     *
+     */
+    public void setXPath(String xpath)
+    {
+        if (xpath == null)
+            throw new NullPointerException(_MESSAGES.get("NullXPath"));
+        
+        _xpath = xpath;
+    }
+    
+    public Element toXML()
+    {
+        return toXML(XmlUtils.EMPTY_DOC);
+    }
+
+    public Element toXML(Document doc)
+    {
+        if (doc == null)
+            throw new NullPointerException(_MESSAGES.get("NullDocument"));
+        
+        QName qname = MuwsConstants.CORRELATABLE_QNAME;
+        Element root = XmlUtils.createElement(doc, qname, getXPath());
+        
+        root.setAttribute(MuwsConstants.DIALECT, getDialect());
+        
+        String negative = Boolean.toString(hasNegativeAssertion());
+        root.setAttribute(MuwsConstants.NEGATIVE, negative);
+        
+        return root;
+    }
+}

Added: webservices/muse/trunk/modules/muse-wsdm-muws/src/org/apache/muse/ws/dm/muws/remote/RelationshipsClient.java
URL: http://svn.apache.org/viewvc/webservices/muse/trunk/modules/muse-wsdm-muws/src/org/apache/muse/ws/dm/muws/remote/RelationshipsClient.java?rev=413693&view=auto
==============================================================================
--- webservices/muse/trunk/modules/muse-wsdm-muws/src/org/apache/muse/ws/dm/muws/remote/RelationshipsClient.java (added)
+++ webservices/muse/trunk/modules/muse-wsdm-muws/src/org/apache/muse/ws/dm/muws/remote/RelationshipsClient.java Mon Jun 12 09:06:54 2006
@@ -0,0 +1,78 @@
+/*=============================================================================*
+ *  Copyright 2006 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 org.apache.muse.ws.dm.muws.remote;
+
+import java.net.URI;
+
+import javax.xml.namespace.QName;
+
+import org.w3c.dom.Element;
+
+import org.apache.muse.core.Environment;
+import org.apache.muse.ws.addressing.EndpointReference;
+import org.apache.muse.ws.dm.muws.MuwsConstants;
+import org.apache.muse.ws.dm.muws.impl.QueryRelationships;
+import org.apache.muse.ws.dm.muws.impl.QueryRelationshipsResponse;
+import org.apache.muse.ws.resource.remote.WsResourceClient;
+import org.apache.muse.ws.addressing.soap.SoapClient;
+import org.apache.muse.ws.addressing.soap.SoapFault;
+
+/**
+ *
+ * @author Dan Jemiolo (danj)
+ *
+ */
+
+public class RelationshipsClient extends WsResourceClient
+{
+    public RelationshipsClient(EndpointReference destination)
+    {
+        super(destination);
+    }
+
+    public RelationshipsClient(EndpointReference destination, 
+                               EndpointReference source)
+    {
+        super(destination, source);
+    }
+
+    public RelationshipsClient(EndpointReference destination, 
+                               EndpointReference source, 
+                               Environment environment)
+    {
+        super(destination, source, environment);
+    }
+
+    public RelationshipsClient(EndpointReference destination, 
+                               EndpointReference source, 
+                               SoapClient soapClient)
+    {
+        super(destination, source, soapClient);
+    }
+
+    public WsResourceClient[] queryRelationshipsByType(QName[] types) 
+        throws SoapFault
+    {
+        URI action = URI.create(MuwsConstants.QUERY_RELATIONSHIPS_URI);
+        QueryRelationships query = new QueryRelationships(types);
+        
+        Element responseXML = invoke(action, query.toXML());
+        QueryRelationshipsResponse response = new QueryRelationshipsResponse(responseXML);
+        
+        return response.getRelationshipClients();
+    }
+}



---------------------------------------------------------------------
To unsubscribe, e-mail: muse-commits-unsubscribe@ws.apache.org
For additional commands, e-mail: muse-commits-help@ws.apache.org