is-collector/src/org/gcube/informationsystem/collector/impl/utils/MsgParser.java

284 lines
7.8 KiB
Java
Executable File

package org.gcube.informationsystem.collector.impl.utils;
import org.apache.axis.encoding.AnyContentType;
import org.gcube.common.core.utils.logging.GCUBELog;
import org.gcube.informationsystem.collector.impl.utils.MsgParser;
import org.globus.wsrf.utils.AnyHelper;
import org.w3c.dom.*;
import org.xml.sax.InputSource;
import org.xml.sax.SAXParseException;
import javax.xml.parsers.*;
import javax.xml.xpath.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import java.io.StringWriter;
import java.io.StringReader;
import java.lang.Exception;
/**
*
* @author manuele simi
*
* @version 1.0 June 2006
*
* @link http://www.diligentproject.org
*
*/
public class MsgParser {
private Document internalDOM;
private String originalMsgString;
private String type; // the entry type (profile or generic resource
// properties)
private XPath path = XPathFactory.newInstance().newXPath(); // object to
// evaluate
// Xpath
// expressions
private final String rootElement = "Data";
private final String typeElement = "Type";
private static GCUBELog logger = new GCUBELog(MsgParser.class);
public MsgParser(AnyContentType deliveredMsg) throws Exception {
try {
this.originalMsgString = AnyHelper.toSingleString(deliveredMsg);
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
StringReader reader = new StringReader("<" + rootElement + ">"
+ this.originalMsgString + "</" + rootElement + ">");
InputSource source = new InputSource(reader);
this.internalDOM = builder.parse(source);
// check if the message has been sent in push or pull mode
this.checkMsgType();
// gets the entry type
this.type = path.evaluate("//" + rootElement
+ "/child::*[local-name() = '" + typeElement + "']", internalDOM);
} catch (ParserConfigurationException pce) {
logger.error("", pce);
throw new Exception("Parser configuration error");
} catch (SAXParseException spe) {
logger.error("", spe);
throw new Exception(" SAX parser error");
} catch (XPathExpressionException xpee) {
logger.error("", xpee);
throw new Exception("XPath evaluation error");
}
}
/**
* Returns the entry type. It can be "Properties" or "Profile"
*
* @return the entry type
*/
public String getEntryType() {
return this.type;
}
/**
* Returns the entry type if the entry is a profile
*
* @throws Exception
*
* @return the entry type
*/
public String getResourceType() throws Exception {
if (this.type.equalsIgnoreCase("Profile")) {
logger.warn("The entry does not have a ResourceType");
throw new Exception("Invalid resource (type = Properties)");
}
return this.getDILIGENTProperty("DILIGENTResourceType");
}
/**
* Returns the VO Name included in the entry
*
* @throws Exception
*
* @return the VO name
*/
public String getVOName() throws Exception {
return this.getDILIGENTProperty("VO");
}
/**
* Returns the Service Name included in the entry
*
* @throws Exception
*
* @return the service name
*/
public String getServiceName() throws Exception {
return this.getDILIGENTProperty("ServiceName");
}
/**
* Returns the Service Class included in the entry
*
* @throws Exception
*
* @return the service class
*/
public String getServiceClass() throws Exception {
return this.getDILIGENTProperty("ServiceClass");
}
/**
* Returns the Running Instance ID included in the entry
*
* @throws Exception
*
* @return the ID
*/
public String getRunningInstanceID() throws Exception {
return this.getDILIGENTProperty("RunningInstanceID");
}
/**
* Returns the Service ID included in the entry
*
* @throws Exception
*
* @return the service ID
*/
public String getServiceID() throws Exception {
return this.getDILIGENTProperty("ServiceID");
}
/**
* Returns the DHN ID included in the entry
*
* @throws Exception
*
* @return the DHN ID
*/
public String getDHNID() throws Exception {
return this.getDILIGENTProperty("GHN");
}
/**
* Extracts a given DILIGENT Property
*
* @throws Exception
*
* @return the property value
*/
private String getDILIGENTProperty(String propName) throws Exception {
String value = null;
try {
value = path.evaluate("//" + rootElement
+ "/child::*[local-name() = '" + propName + "']",
internalDOM);
} catch (XPathExpressionException xpee) {
logger.error("", xpee);
throw new Exception("XPath evaluation error");
}
return value;
}
/**
* Returns a XML representation of the Entry
*
* @return the XML string
*/
public String getEntryAsString() {
return "<" + rootElement + ">\n" + this.originalMsgString + "</"
+ rootElement + ">\n";
// return XMLUtils.DocumentToString(this.internalDOM);
}
/**
* Releases the allocated resources
*
*/
public void dispose() {
// remove the allocated DOM
internalDOM = null;
}
/**
* Checks if the message has been sent by a WS-Notification In that case,
* the NewValue is extracted by the msg
*
*/
private void checkMsgType() throws Exception {
Boolean isPush = false;
String notificationXpath = "/child::*[local-name() = 'value']";
notificationXpath += "/child::*[local-name() = 'ResourcePropertyValueChangeNotification']";
notificationXpath += "/child::*[local-name() = 'NewValue']";
try {
isPush = (Boolean) path.evaluate("//" + rootElement + notificationXpath, this.internalDOM,
XPathConstants.BOOLEAN);
} catch (NullPointerException n) {
logger.trace("The delivered message has been sent using the pull mode");
return;
} catch (XPathExpressionException xpee) {
logger.error("", xpee);
}
if (isPush) {
// replace the originalMsgString and the internalDOM with the
// newValue section of the delivered message
logger.trace("The delivered message has been sent using the push mode");
// String nodeString = (String) path.evaluate(notificationXpath,
// this.internalDOM, XPathConstants.STRING);
Node node = (Node) path.evaluate("//" + rootElement
+ notificationXpath, this.internalDOM, XPathConstants.NODE);
Transformer serializer = TransformerFactory.newInstance().newTransformer();
StringWriter sw = new StringWriter();
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder domBuilder = factory.newDocumentBuilder();
// create the nre data string
NodeList children = node.getChildNodes();
this.originalMsgString = "";
if (children != null) {
for (int i = 0; i < children.getLength(); i++) {
serializer.transform(new DOMSource(children.item(i)),
new StreamResult(sw));
this.originalMsgString += sw.toString();
}
}
logger.trace("Data string " + this.originalMsgString);
// trim the directive <?xml... ?>
this.originalMsgString = this.originalMsgString.substring(this.originalMsgString.indexOf("?>", 1) + 1);
logger.trace("Trimmed data string " + this.originalMsgString);
// create the new internalDOM
StringReader reader = new StringReader("<" + rootElement + ">"
+ this.originalMsgString + "</" + rootElement + ">");
InputSource source = new InputSource(reader);
this.internalDOM = domBuilder.parse(source);
} else {
logger.info("The delivered message has been sent using the pull mode");
}
}
}