/*=============================================================================*
* 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;
}
}