483 lines
12 KiB
Java
Executable File
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) {
|
|
|
|
}
|
|
}
|