aslcore/src/org/gcube/application/framework/core/cache/factories/CollectionCacheEntryFactory...

439 lines
17 KiB
Java

package org.gcube.application.framework.core.cache.factories;
import org.apache.axis.message.addressing.EndpointReferenceType;
import org.globus.wsrf.ResourceKey;
import org.globus.wsrf.impl.SimpleResourceKey;
import org.globus.wsrf.utils.AddressingUtils;
import javax.xml.namespace.QName;
import org.apache.axis.message.addressing.AttributedURI;
import javax.xml.parsers.*;
import org.w3c.dom.*;
import org.xml.sax.InputSource;
import java.util.HashMap;
import java.util.List;
import java.util.ArrayList;
import java.io.StringReader;
import javax.xml.parsers.DocumentBuilderFactory;
import org.apache.xpath.XPathAPI;
import org.gcube.application.framework.core.cache.CachesManager;
import org.gcube.application.framework.core.commons.model.CollectionInfo;
import org.gcube.application.framework.core.commons.model.IndexInfo;
import org.gcube.application.framework.core.util.QueryString;
import org.gcube.application.framework.core.util.SessionConstants;
import org.gcube.application.framework.core.vremanagement.model.ISGenericResource;
import org.gcube.common.core.scope.GCUBEScope;
import org.gcube.searchservice.searchlibrary.isharvester.CollectionInfo.CollectionAttrs;
import org.gcube.searchservice.searchlibrary.isharvester.CollectionInfo.TypeValues;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import net.sf.ehcache.constructs.blocking.CacheEntryFactory;
/**
* @author Valia Tsagkalidou (NKUA)
*
*/
public class CollectionCacheEntryFactory implements CacheEntryFactory {
/**
* Document factory instance
*/
public static final DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance();
/**
* whether geospatial tab should be available or not
*/
protected boolean geospatial;
//TODO: find a way to return also the geospatial tab boolean variable
/**
* @param key a String representing the DL name.
* @return List<CollectionInfo>[] an array of Lists containing CollectionInfo objects. Each List contains a Collection group. The First element of the list is the CollectionInfo containing info for the Group (name, description etc). The rest of the objects in the list are the actual collections.
*/
public Object createEntry(Object key) throws Exception {
List<CollectionInfo> collections;
String searchConfig = (String) CachesManager.getInstance().getSearchConfigCache().get(key).getValue();
if(searchConfig == null || searchConfig.equals(""))
return null;
collections = parseSearchConfig(searchConfig);
return retrieveStaticConfiguration(key.toString(), collections);
}
/**
* @param searchConfig the search configuration as it is returned from the SearchMaster
* @return a list of CollectionInfo, which represents the currently available collections
*/
protected List<CollectionInfo> parseSearchConfig(String searchConfig)
{
try {
// Interpreting the dynamic configuration
System.out.println("******************************");
System.out.println(searchConfig);
System.out.println("******************************");
InputSource colls_in = new InputSource(new StringReader(searchConfig));
Document colls_doc;
colls_doc = dfactory.newDocumentBuilder().parse(colls_in);
NodeList colls_res;
colls_res = XPathAPI.selectNodeList(colls_doc, "/SearchConfig/collections/collection["+CollectionAttrs.TYPE+"='"+TypeValues.DATA+"']");
// the initParameter "scenario" should be replaced by vdl parameter.
// However, currently only one vdl exists and supports both scenarios...
int n = colls_res.getLength(),i;
List<CollectionInfo> collections = new ArrayList<CollectionInfo>();
for (i = 0; i < n; i++)
{//Foreach content collection:
// Storing the information in local variables.
CollectionInfo colInfo = new CollectionInfo();
String val;
String id = colls_res.item(i).getAttributes().getNamedItem("id").getNodeValue();
val = id;
String colName = colls_res.item(i).getAttributes().getNamedItem("name").getNodeValue();
colInfo.setId(id);
colInfo.setName(colName);
NodeList contentRes = XPathAPI.selectNodeList(colls_doc, "/SearchConfig/collections/collection[@id='"+id+"']/"+CollectionAttrs.ASSOCIATEDWITH);
int attrNo = contentRes.getLength();
for(int j=0; j<attrNo; j++)
{//Foreach metadata collection:
try
{
String metadataID = contentRes.item(j).getFirstChild().getNodeValue();
String language = null, schema = null;
NodeList metaRes = XPathAPI.selectNodeList(colls_doc, "/SearchConfig/collections/collection[@id='"+metadataID+"']/"+"LANGUAGE");
if(metaRes == null)
continue;
language = metaRes.item(0).getFirstChild().getNodeValue();
metaRes = XPathAPI.selectNodeList(colls_doc, "/SearchConfig/collections/collection[@id='"+metadataID+"']/"+"SCHEMA");
if(metaRes != null)
schema = metaRes.item(0).getFirstChild().getNodeValue();
metaRes = XPathAPI.selectNodeList(colls_doc, "/SearchConfig/collections/collection[@id='"+metadataID+"']/"+"INDEX");
IndexInfo indexInformation = new IndexInfo();
if(metaRes != null)
{
System.out.println("schema = " + metaRes);
int k, total = metaRes.getLength();
for(k=0; k<total; k++)
{//Foreach Index:
System.out.println(" -- " + metaRes.item(k).getFirstChild().getNodeValue());
if(metaRes.item(k).getFirstChild().getNodeValue().equals("FTS"))
{
indexInformation.setFts(true);
System.out.println("id name : "+val);
}
else if(metaRes.item(k).getFirstChild().getNodeValue().equals("GEO"))
{
indexInformation.setGeospatial(true);
System.out.println("id name : "+val);
}
else if(metaRes.item(k).getFirstChild().getNodeValue().equals("FEATURE"))
{//Ayto mporei na allaxei....
indexInformation.setSimilarity(true);
System.out.println("id name : "+val);
// geoFound = true; //Prepei na allaxei?
}
}
}
colInfo.setMetadataCollection(schema, metadataID, language, indexInformation);
}
catch (Exception e) {
e.printStackTrace();
}
}//End of metadata for.
collections.add(colInfo);
}
return collections;
} catch (Exception e1) {
e1.printStackTrace();
}
return null;
}
/**
* Retrieves the static configuration for the collections from the DIS.
* @param dl the dl for which it will retrieve the static configuration (generic resource in IS)
* @param collections the collection derived from the dynamic configuration (SearchMaster configuration)
* @return an array of Lists containing CollectionInfo objects. Each List contains a Collection group. The First element of the list is the CollectionInfo containing info for the Group (name, description etc). The rest of the objects in the list are the actual collections.
* @throws Exception an Exception occurred during the procedure
*/
protected List<CollectionInfo>[] retrieveStaticConfiguration(String dl, List<CollectionInfo> collections) throws Exception
{
// Reading the static configuration file and initializing the parameters
List<CollectionInfo>[] colHierarchy;
QueryString query = new QueryString();
query.put("dl", dl);
query.put("name", SessionConstants.ScenarioSchemaInfo);
List<ISGenericResource> scenarioSchemaInfo = (List<ISGenericResource>) CachesManager.getInstance().getGenericResourceCache().get(query).getValue();
if(scenarioSchemaInfo == null || scenarioSchemaInfo.size() == 0)
{
colHierarchy = new ArrayList[0];
return colHierarchy;
}
System.out.println("*************************************");
System.out.println(scenarioSchemaInfo.get(0).getBody());
System.out.println("*************************************");
InputSource in = new InputSource(new StringReader(scenarioSchemaInfo.get(0).getBody()));
Document doc = dfactory.newDocumentBuilder().parse(in);
retrieveCollections(doc, collections);
colHierarchy = retrieveCollectionHierarchy(dl, doc, collections);
return colHierarchy;
}
/**
* Retrieves the collections.
* @param doc document which holds the collections
* @param collections the list containing the collections
*/
protected void retrieveCollections(Document doc, List<CollectionInfo> collections)
{
int i,n;
List<CollectionInfo> availableCollections = new ArrayList<CollectionInfo>();
// Reading the collections and storing them in a list only if they are currently available.
NodeList res = doc.getElementsByTagName("collection");
n = res.getLength();
for (i = 0; i < n; i++)
{
String val = res.item(i).getAttributes().getNamedItem("name").getNodeValue();
CollectionInfo colInfo = null;
colInfo = getCollectionInfo(val, collections);
if (colInfo == null)
continue;// This collection is not currently available.
val = res.item(i).getAttributes().getNamedItem("description").getNodeValue();
colInfo.setDescription(val);
val = res.item(i).getAttributes().getNamedItem("reference").getNodeValue();
colInfo.setReference(val);
val = res.item(i).getAttributes().getNamedItem("shortname").getNodeValue();
colInfo.setShortName(val);
availableCollections.add(colInfo);
}
collections.clear();
for(CollectionInfo col : availableCollections)
{
collections.add(col);
}
res = doc.getElementsByTagName("collections");
n = res.getLength();
for (i = 0; i < n; i++)
{
CollectionInfo colInfo = new CollectionInfo();
colInfo.setId("collection_id_"+i);
String val;
try{
val = res.item(i).getAttributes().getNamedItem("name").getNodeValue();
colInfo.setName(val);
}
catch(Exception e){}
try{
val = res.item(i).getAttributes().getNamedItem("description").getNodeValue();
colInfo.setDescription(val);
}
catch(Exception e){}
try{
val = res.item(i).getAttributes().getNamedItem("reference").getNodeValue();
colInfo.setReference(val);
}
catch(Exception e){}
try{
val = res.item(i).getAttributes().getNamedItem("shortname").getNodeValue();
colInfo.setShortName(val);
}
catch(Exception e){}
collections.add(colInfo);
}
System.out.println("***Number of collections:" + collections.size());
}
/**
* Retrieves the collection hierarchy. Joins the static and the dynamic search configuration and produces a hierarchical structure containing information about each collection.
* @param DLname the dl name of the active DL (VRE)
* @param doc document which holds the collections
* @param collections the available collections
* @return an array of Lists containing CollectionInfo objects. Each List contains a Collection group. The First element of the list is the CollectionInfo containing info for the Group (name, description etc). The rest of the objects in the list are the actual collections.
* @throws Exception an Exception occurred during processing
*/
protected List<CollectionInfo>[] retrieveCollectionHierarchy(String DLname, Document doc, List<CollectionInfo> collections) throws Exception {
// Retrieving the tree structure of the collection hierarchy
NodeList res = XPathAPI.selectNodeList(doc, "//DL");
Node geo = res.item(0).getAttributes().getNamedItem("geospatial");
if(geo != null && geo.getNodeValue().equals("true"))
geospatial = true;
res = XPathAPI.selectNodeList(doc, "//collections");
int n = res.getLength();
System.out.println("***** number of collection groups:" + n + "*******");
List<CollectionInfo>[] colHierachy = new List[n];
for (int i = 0; i < n; i++)
{
String val = res.item(i).getAttributes().getNamedItem("name").getNodeValue();
NodeList res2 = XPathAPI.selectNodeList(doc, "//collections[@name=\"" + val + "\"]/collection");
colHierachy[i] = new ArrayList<CollectionInfo>();
CollectionInfo colInfo = getCollectionInfo(val, collections);
if(colInfo != null)
{
colHierachy[i].add(colInfo); // Collection Group Name
for (int j = 0; j < res2.getLength(); j++)
{//for each collection belonging to that group, it stores its name...
colInfo = getCollectionInfo(res2.item(j).getAttributes().getNamedItem("name").getNodeValue(), collections);
if(colInfo != null)
{
findBrowseFields(colInfo, GCUBEScope.getScope(DLname));
colHierachy[i].add(colInfo);
}
}
}
System.out.println("***collection group " + i + " contains " + (colHierachy[i].size()-1) + " collections***");
}
return colHierachy;
}
/**
* @param resultSet the results
* @param forwardIndices a HashMap containing EPRs for each collection - field
* @throws Exception an exception occurred
*/
protected void parseEPRResult(String resultSet, HashMap<String, EndpointReferenceType> forwardIndices) throws Exception {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
DocumentBuilder builder = factory.newDocumentBuilder();
if(resultSet == null)
return;
StringReader reader = new StringReader(resultSet);
InputSource source = new InputSource(reader);
Document domDoc = builder.parse(source);
String Address = "";
String key = "";
String namespaceKey = "";
String localNameKey = "";
String fieldName = "";
Element root = domDoc.getDocumentElement();
NodeList resultSetChilds = root.getElementsByTagName("RESULT");
for (int numRes = 0; numRes < resultSetChilds.getLength(); numRes++) {
boolean keyExist = false;
NodeList EPRChild = resultSetChilds.item(numRes).getChildNodes();
for (int i = 0; i < EPRChild.getLength(); i++) {
if (EPRChild.item(i) instanceof Element) {
Element child = (Element) EPRChild.item(i);
if (child.getTagName().equals("KeyName")) {
fieldName = ((Text) child.getFirstChild()).getNodeValue();
} else if (child.getTagName().equals("Source")) {
Address = ((Text) child.getFirstChild()).getNodeValue();
} else if (child.getTagName().equals("SourceKey")) {
Text keyElement = (Text) child.getFirstChild();
if (keyElement != null) {
key = keyElement.getNodeValue();
keyExist = true;
}
} else if (child.getTagName().equals("CompleteSourceKey")
&& keyExist) {
if (child instanceof Element) {
Element completeKey = (Element) child;
NodeList listChild = completeKey.getChildNodes();
for (int x = 0; x < listChild.getLength(); x++) {
if (listChild.item(x) instanceof Element) {
Element childEl = (Element) listChild
.item(x);
if (childEl != null) {
Text keyElement = (Text) childEl
.getFirstChild();
key = (String) keyElement
.getNodeValue();
// logger.debug("key " +key);
namespaceKey = (String) childEl
.getNamespaceURI();
// logger.debug("ns "+namespaceKey);
localNameKey = (String) childEl
.getLocalName();
// logger.debug("local " +localNameKey);
}
}
}
}
}
}
}
EndpointReferenceType epr = new EndpointReferenceType();
if (keyExist) {
ResourceKey key_resource = new SimpleResourceKey(new QName(
namespaceKey, localNameKey), key);
epr = AddressingUtils.createEndpointReference(Address,
key_resource);
} else
epr.setAddress(new AttributedURI(Address));
forwardIndices.put(fieldName, epr);
}
}
/**
* Finds the Browsable fields for the given collection
* @param colInfo the CollectionInfo containing info about the current collection
* @param scope the GCUBEScope of the active VRE
*/
private void findBrowseFields(CollectionInfo colInfo, GCUBEScope scope) {
String where = "$doc//ServiceClass/string() eq 'Index' and $doc//ServiceName/string() eq 'ForwardIndexLookupService' and $doc//CollectionID/string() eq '"+ colInfo.getId() +"'";
String query = "for $doc in collection(\"/db/Properties\")//Document where " + where + " return <RESULT>{$doc//KeyName}{$doc/Source}{$doc/SourceKey}{$doc/CompleteSourceKey}</RESULT>";
try {
//TODO: change the way i call IS
String forwardResults = null;// = DISHLSClient.getGeneralQueryManager(cred, null).queryDISIC(query, cred, null);
parseEPRResult(forwardResults, colInfo.getForward());
} catch(Exception e){
e.printStackTrace();
}
}
/**
* @param collectionName the name of the collection
* @param collections a list containing all the collections
* @return the CollectionInfo of the collection with the corresponding name
*/
protected CollectionInfo getCollectionInfo(String collectionName, List<CollectionInfo> collections)
{
CollectionInfo colInfo = null;
int i, n = collections.size();
for(i=0; i< n; i++)
{
System.out.println("*******" + collections.get(i).getName() + " vs. " + collectionName);
if(collections.get(i).getName().equals(collectionName))
{
colInfo = collections.get(i);
System.out.println("***collection found****");
break;
}
}
return colInfo;
}
}