is-collector/src/org/gcube/informationsystem/collector/impl/persistence/AggregatorPersistentResourc...

483 lines
12 KiB
Java
Executable File

package org.gcube.informationsystem.collector.impl.persistence;
import org.gcube.common.core.utils.logging.GCUBELog;
import org.gcube.informationsystem.collector.impl.persistence.AggregatorPersistentResource;
import org.gcube.informationsystem.collector.impl.xmlstorage.exist.State;
import org.xmldb.api.modules.XMLResource;
import org.xmldb.api.base.XMLDBException;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.StringReader;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.TimeZone;
import java.lang.Exception;
import org.w3c.dom.*;
import org.xml.sax.InputSource;
import javax.xml.parsers.*;
import javax.xml.xpath.*;
/**
* AggregatorPersistentResource represents a resource in the XML Storage
* repository
*
* @author Manuele Simi (ISTI-CNR)
*
*/
public class AggregatorPersistentResource extends PersistentResource {
private String resourceID = null;
private String resource_string = null;
// the resource type states if the resource contains a profile or generic
// WS-ResourceProperties
private RESOURCETYPE type = null;
// the profile type states which kind of profiles the resource contains
// (RunningInstance, Service, etc.)
private String profile_type = null;
// the various parts of the resource
private String data, /* service_class, service_id, ri_id, ghn_id, scope, */
entryKey, groupKey, source, sourceKey = "", completeSourceKey = "";
private Calendar terminationTime = null, lastUpdateTime = null;
private static GCUBELog logger = new GCUBELog(
AggregatorPersistentResource.class);
// the source XMLResource (if any)
private XMLResource originalSource = null;
// the XML DOM loaded from the resource string
private Document internalDOM = null;
// xpath factory to evaluate Xpath expressions
private XPath path = XPathFactory.newInstance().newXPath();
/**
* Builds a new empty DISPersinstentresource
*
*/
public AggregatorPersistentResource() {
// defatult termination time is now
Calendar cal = new GregorianCalendar();
cal.setTimeZone(TimeZone.getTimeZone("GMT"));
this.setTerminationTime(cal);
lastUpdateTime = new GregorianCalendar();
lastUpdateTime.setTimeZone(TimeZone.getTimeZone("GMT"));
}
/**
* Builds a DISPersinstentresource starting from an eXist resource
*
* @param resource
* the input eXist resource
* @throws Exception
* if the resource is invalid
*/
public AggregatorPersistentResource(XMLResource resource) throws Exception {
try {
this.resourceID = resource.getId();
this.originalSource = resource;
this.resource_string = resource.getContent().toString();
this.parseResource();
} catch (XMLDBException dbe) {
throw new Exception("invalid resource");
}
}
/**
* Sets the content of the resource
*
* @param data
* the new content
*
*/
public void setData(String data) {
this.data = data;
}
/**
* Sets the content of the resource using the content of a file
*
* @param f
* the file to use as content source
*
* @throws IOException
* if the access to the given file fails
*
*/
public void setData(File f) throws IOException {
try {
FileInputStream fin = new FileInputStream(f);
this.data = fin.toString();
} catch (IOException ioe) {
System.out.print(State.logPrefix
+ "unable to set content from file " + f.getAbsolutePath());
throw ioe;
}
}
/**
* Accesses the resource content
*
* @return the content
*/
public String getData() {
return this.data;
}
/**
*
* @return the original XMLResource from which the resource has been
* generated (if any)
*/
public XMLResource getOriginalXMLResource() {
return this.originalSource;
}
/**
* Accesses the resource ID
*
* @return the ID
*/
public String getID() {
// create a unique ID unless the resource contains a profile
if (this.resourceID == null)
this.resourceID = this.getGroupKey() + this.getEntryKey();
return this.resourceID;
}
/**
* Accesses the source GroupKey
*
* @return the ID
*/
public String getGroupKey() {
return this.groupKey;
}
/**
* Sets the source GroupKey
*
* @param groupKey
* the new group key
*
*/
public void setGroupKey(String groupKey) {
this.groupKey = groupKey;
}
/**
* Accesses the source EntryKey
*
* @return the ID
*/
public String getEntryKey() {
return this.entryKey;
}
/**
* Sets the source EntryKey
*
* @param entryKey
* the new entry key
*/
public void setEntryKey(String entryKey) {
this.entryKey = entryKey;
}
/**
* Sets the source address of the RI that publishes resource as reported in
* the servicegroup entry
*
* @param source
* the new source address
*/
public void setSource(String source) {
this.source = source;
}
/**
* Accesses the source address of the service that published the data
*
* @return the source
*/
public String getSource() {
return this.source;
}
/**
* Sets the key of the WS-Resource that published the data
*
* @param key
* the new source key
*/
public void setSourceKey(String key) {
this.sourceKey = key;
}
/**
* Gets the key of the WS-Resource that published the data
*
* @return the key
*/
public String getSourceKey() {
return this.sourceKey;
}
/**
* Sets the complete source key
*
* @param completeKey
* the new complete key
*/
public void setCompleteSourceKey(String completeKey) {
this.completeSourceKey = completeKey;
}
/**
* Gets the complete source key
*
* @return the complete source key
*/
public String getCompleteSourceKey() {
return this.completeSourceKey;
}
/**
* Sets the resource type. The actual implementation supports "Profile" and
* "Properties" as type
*
* @param type
* "Profile" or "Properties"
*/
public void setType(RESOURCETYPE type) {
this.type = type;
}
/**
* Accesses the resource type. The actual implementation supports "Profile"
* and "Properties" as type
*
* @return the type
*/
public RESOURCETYPE getType() {
return this.type;
}
/**
* Updates the resource body
*
* @param data
* the new body
*
*/
public void updateData(String data) {
this.data = data;
}
/**
* Builds a XML representation of the resource
*
* @return a String in the form of <Document>... <Data> resource
* content </Data> </Document>
*/
private String toXML() {
String rep = "<Document>\n";
rep += "<ID>" + this.getID() + "</ID>\n";
rep += "<Source>" + this.getSource() + "</Source>\n";
rep += "<SourceKey>" + this.getSourceKey() + "</SourceKey>\n";
rep += "<CompleteSourceKey>" + this.getCompleteSourceKey()
+ "</CompleteSourceKey>\n";
rep += "<EntryKey>" + this.getEntryKey() + "</EntryKey>\n";
rep += "<GroupKey>" + this.getGroupKey() + "</GroupKey>\n";
rep += "<TerminationTime>"
+ this.getTerminationTime().getTimeInMillis()
+ "</TerminationTime>\n";
rep += "<TerminationTimeHuman>"
+ this.getTerminationTime().getTime().toString()
+ "</TerminationTimeHuman>\n";
rep += "<LastUpdateMs>" + this.lastUpdateTime.getTimeInMillis()
+ "</LastUpdateMs>\n";
rep += "<LastUpdateHuman>" + this.lastUpdateTime.getTime().toString()
+ "</LastUpdateHuman>\n";
rep += this.getData() + "\n";
rep += "</Document>\n";
return rep;
}
/**
*
* @return a String representation of the resource
*/
public String toString() {
if (this.resource_string == null)
return this.toXML();
else
return this.resource_string;
}
/**
* Accesses the type of resource to which the profile is related to (if any)
*
* @return null if the resource does not contain a profile
*/
public String getProfileType() {
if (this.profile_type != null) {
// the profile type has been already extracted
return this.profile_type;
}
if ((this.type != null) && (type == RESOURCETYPE.Profile)) {
try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
StringReader reader = new StringReader(this.toXML());
InputSource source = new InputSource(reader);
Document internalDOM = builder.parse(source);
// gets the type
XPath path = XPathFactory.newInstance().newXPath();
this.profile_type = path
.evaluate(
"/Document/Data/child::*[local-name()='Profile']/Resource/Type",
internalDOM);
// uses the DILIGENT ID as resource ID
this.resourceID = path
.evaluate(
"/Document/Data/child::*[local-name()='Profile']/Resource/ID",
internalDOM);
} catch (Exception e) {
logger
.error(State.logPrefix
+ "Unable to extract the profile type from the resource "
+ e.getMessage());
}
}
return this.profile_type;
}
/**
* @return the terminationTime of this resource
*/
public Calendar getTerminationTime() {
return terminationTime;
}
/**
* @param terminationTime
* the terminationTime to set
*/
public void setTerminationTime(Calendar terminationTime) {
this.terminationTime = (Calendar) terminationTime.clone();
this.terminationTime.setTimeZone(TimeZone.getTimeZone("GMT"));
}
/**
* Compares two resources
*
* @param o
* the resource to compare
* @return true if the resources have the same ID
*/
public boolean equals(Object o) {
// check the class this object is instance of
if (!(o instanceof AggregatorPersistentResource))
return false;
// compare the two objects
AggregatorPersistentResource key = (AggregatorPersistentResource) o;
if (key.getID() == this.getID())
return true;
else
return false;
}
/**
* @return the lastUpdateTime in milliseconds
* @throws Exception if an error occurs when accessing the LastUpdateMs field
*/
public long getLastUpdateTimeinMills() throws Exception {
if (lastUpdateTime != null)
return lastUpdateTime.getTimeInMillis();
if ((lastUpdateTime == null) && (this.internalDOM != null)) {
String value = "";
try {
value = path.evaluate("Document/LastUpdateMs", this.internalDOM);
} catch (XPathExpressionException xpee) {
logger.error(State.logPrefix + "" + xpee.getMessage());
logger.error(State.logPrefix + "" + xpee.getStackTrace());
throw new Exception("XPath evaluation error");
}
try {
return Long.parseLong(value);
} catch (NumberFormatException nfe) {
logger.error("Invalid last update time format found in resource " + this.getID());
logger.error("Parsed string was " + value);
throw new Exception("Unable to retrieve last update time for resource " + this.getID());
}
} else
throw new Exception("unable to retrieve last update time for resource " + this.getID());
}
/**
* Loads the XML DOM from the resource string
*
*/
private void parseResource() throws Exception {
logger.debug("Parsing resource: " + this.resource_string);
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
StringReader reader = new StringReader(this.resource_string);
InputSource source = new InputSource(reader);
this.internalDOM = builder.parse(source);
}
/*
* (non-Javadoc)
*
* @see
* org.gcube.informationsystem.collector.impl.persistence.PersistentResource
* #getPublisher()
*/
@Override
public String getPublisher() {
return null;
}
/*
* (non-Javadoc)
*
* @see
* org.gcube.informationsystem.collector.impl.persistence.PersistentResource
* #setPublisher(java.lang.String)
*/
@Override
public void setPublisher(String publisher) {
}
}