dnet-core/dnet-information-service/src/main/java/eu/dnetlib/enabling/is/lookup/ISLookUpServiceImpl.java

395 lines
12 KiB
Java

package eu.dnetlib.enabling.is.lookup;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.jws.WebService;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPathExpressionException;
import com.sun.xml.messaging.saaj.util.Base64;
import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpDocumentNotFoundException;
import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpException;
import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService;
import eu.dnetlib.enabling.is.store.rmi.ISStoreException;
import eu.dnetlib.enabling.is.store.rmi.ISStoreService;
import eu.dnetlib.enabling.tools.*;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.springframework.beans.factory.annotation.Required;
import org.xml.sax.SAXException;
/**
* ISLookUpService implementation.
*
* @author marko
* @author michele
*
*/
@WebService(targetNamespace = "http://services.dnetlib.eu/")
public class ISLookUpServiceImpl extends AbstractBaseService implements ISLookUpService { // NOPMD
/**
* error message when the given collection cannot be fetched.
*/
private static final String COLLECTION_ERROR = "cannot get collection";
/**
* base xmldb directory.
*/
private static final String DB_BASE_DIR = "/db/DRIVER";
/**
* error message when the profile is not present in the db.
*/
private static final String PROFILE_NOT_FOUND = "Profile not found";
private ISStoreService isStore;
// NOPMD by marko on 11/24/08
// 5:02 PM
/**
* logger.
*/
public static final Log log = LogFactory.getLog(ISLookUpServiceImpl.class); // NOPMD by marko on 11/24/08 5:02 PM
/**
* resource identifier resolver. Resolves identifiers to xmldb file and collection names.
*/
private ResourceIdentifierResolver resIdManager = new CompatResourceIdentifierResolverImpl();
/**
* xquery utils. Used to obtain the xmldb collection mapping for resources.
*/
private XQueryUtils xqueryUtils;
/**
* {@inheritDoc}
*
* @see eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService#flushCachedResultSets()
*/
@Override
public Boolean flushCachedResultSets() {
// TODO Auto-generated method stub
return false;
}
/**
* {@inheritDoc}
*
* @see eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService#retrieveCollection(java.lang.String)
*/
@Override
public String retrieveCollection(final String profId) throws ISLookUpException {
try {
String profile = this.getResourceProfile(profId);
final List<String> list = quickSearchProfile("for $x in collection('/db/DRIVER/CollectionDSResources') where $x//FATHER/@id = '" + profId
+ "' return $x//RESOURCE_IDENTIFIER/@value/string()");
if (!list.isEmpty()) {
final SAXReader reader = new SAXReader();
final Document doc = reader.read(new StringReader(profile));
final Element childrenNode = (Element) doc.selectSingleNode("//CHILDREN"); // NOPMD
for (final String idC : list) {
childrenNode.addElement("CHILD").addAttribute("id", idC);
}
profile = doc.asXML();
}
return profile;
} catch (final Exception e) {
throw new ISLookUpException(e);
}
}
/**
* {@inheritDoc}
*
* @see eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService#getCollection(java.lang.String, java.lang.String)
*/
@Override
public String getCollection(final String profId, final String format) throws ISLookUpException {
OpaqueResource prof;
try {
prof = new StringOpaqueResource(profId);
final StringBuilder query = new StringBuilder();
if (format != null && format.equals("ui")) {
query.append("doc('");
query.append(xqueryUtils.getCollectionAbsPath(prof));
query.append('/');
query.append(prof.getResourceId().split("_")[0]);
query.append("')");
} else {
query.append("let $x := doc('");
query.append(xqueryUtils.getCollectionAbsPath(prof));
query.append('/');
query.append(prof.getResourceId().split("_")[0]);
query.append("') return <COLLECTION name='{$x//NAME}' id='{$x//RESOURCE_IDENTIFIER/@value/string()}'>");
query.append("<STATUS private='{$x//PRIVATE}' visible='{$x//VISIBLE}' container='{$x//CONTAINER}'");
query.append("count_docs='{$x//COUNT_DOCS/@number/string()}' last_update='{$x//COUNT_DOCS/@last_update/string()}' />");
query.append("{$x//IMAGE_URL}{$x//DESCRIPTION}{$x//OWNER}{$x//FATHER}{$x//SUBJECT}{$x//CHILDREN}{$x//MEMBERSHIP_CONDITION}{$x//RETRIEVAL_CONDITION}</COLLECTION>");
}
return isStore.getXMLbyQuery(query.toString());
} catch (final ISStoreException e) {
throw new ISLookUpException(e);
} catch (final XPathExpressionException e) {
throw new ISLookUpException(COLLECTION_ERROR, e);
} catch (final SAXException e) {
throw new ISLookUpException(COLLECTION_ERROR, e);
} catch (final IOException e) {
throw new ISLookUpException(COLLECTION_ERROR, e);
} catch (final ParserConfigurationException e) {
throw new ISLookUpException(COLLECTION_ERROR, e);
}
}
/**
* {@inheritDoc}
*
* @see eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService#getResourceProfile(java.lang.String)
*/
@Override
public String getResourceProfile(final String profId) throws ISLookUpException {
if (profId == null || profId.isEmpty()) { throw new ISLookUpException("Invalid null profile ID: " + profId); }
try {
final String res = isStore.getXML(getFileNameForId(profId),
xqueryUtils.getRootCollection() + getFileCollForId(profId));
if (res == null) { throw new ISLookUpDocumentNotFoundException("document " + profId + " not found"); }
return res;
} catch (final ISStoreException e) {
throw new ISLookUpException(e);
}
}
/**
* obtain the xmldb file name from the profile identifier.
*
* @param profId
* profile id
* @return xml db file name
*/
String getFileNameForId(final String profId) {
return resIdManager.getFileName(profId);
}
/**
* obtain the xmldb collection name from the profile identifier.
*
* @param profId
* profile id
* @return plaintext xmldb collection name
*/
String getFileCollForId(final String profId) {
return resIdManager.getCollectionName(profId);
}
/**
* {@inheritDoc}
*
* @see eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService#getResourceProfileByQuery(java.lang.String)
*/
@Override
public String getResourceProfileByQuery(final String xquery) throws ISLookUpException {
String resource;
//TODO remove following hack as soon as https://issue.openaire.research-infrastructures.eu/issues/2774 is closed.
if (StringUtils.isNotBlank(xquery) && xquery.trim().startsWith("//*[local-name() = 'complexType'")) {
final Pattern p = Pattern.compile(".*value = '([a-zA-z]+)']");
final Matcher m = p.matcher(xquery);
if (m.matches()) {
final String serviceName = m.group(1);
log.debug(String.format("found service '%s', hacking response for xquery: %s", serviceName, xquery));
return getResourceTypeSchema(serviceName);
}
}
try {
resource = isStore.getXMLbyQuery(xquery);
if (resource == null || resource.isEmpty()) { throw new ISLookUpDocumentNotFoundException(PROFILE_NOT_FOUND); }
return resource;
} catch (final ISStoreException e) {
throw new ISLookUpException(e);
}
}
/**
* {@inheritDoc}
*
* @see eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService#getResourceQoSParams(java.lang.String)
*/
@Override
public String getResourceQoSParams(final String profId) throws ISLookUpException {
final String query = "for $x in collection('/db/DRIVER/ServiceResources') where $x//RESOURCE_IDENTIFIER/@value = '" + profId + "' return $x//QOS";
return getResourceProfileByQuery(query);
}
/**
* {@inheritDoc}
*
* @see eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService#getResourceTypeSchema(java.lang.String)
*/
@Override
public String getResourceTypeSchema(final String resourceType) throws ISLookUpException, ISLookUpDocumentNotFoundException {
if (resourceType == null || resourceType.isEmpty()) { throw new ISLookUpException("Invalid resourceType"); }
try {
final String resource = isStore.getXML(resourceType, xqueryUtils.getRootCollection() + ResourceType.RESOURCE_TYPES);
if (resource == null || resource.isEmpty()) { throw new ISLookUpDocumentNotFoundException(PROFILE_NOT_FOUND); }
return resource;
} catch (final ISStoreException e) {
throw new ISLookUpException(e);
}
}
/**
* {@inheritDoc}
*
* @see eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService#listCollections(java.lang.String, java.lang.String, java.lang.String)
*/
@Override
public List<String> listCollections(final String format, final String idfatherParam, final String owner) throws ISLookUpException {
String idfather = idfatherParam; // PMD
if (idfather == null || idfather.length() == 0) {
idfather = "InfoSpace";
}
final String fileColl = xqueryUtils.getRootCollection() + "CollectionDSResources/CollectionDSResourceType";
final StringBuilder query = new StringBuilder();
query.append("for $x in collection('" + fileColl + "') where $x//FATHER[@id='" + idfather + "'] "); // NOPMD
if (owner != null && owner.length() > 0) {
query.append("and $x//OWNER[@id='" + owner + "'] ");
}
if (format != null && format.equals("short")) {
query.append("return $x//RESOURCE_IDENTIFIER/@value/string()");
} else {
query.append("return $x");
}
return quickSearchProfile(query.toString());
}
/**
* {@inheritDoc}
*
* @see eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService#listDHNIDs()
*/
@Override
public List<String> listDHNIDs() throws ISLookUpException {
final String fileColl = DB_BASE_DIR + "/InfrastructureResources/DRIVERHostingNodeDSResourceType";
final ArrayList<String> ret = new ArrayList<String>();
try {
for (final String i : isStore.getFileNames(fileColl)) {
ret.add(i + ":" + fileColl);
}
return ret;
} catch (final ISStoreException e) {
throw new ISLookUpException(e);
}
}
/**
* {@inheritDoc}
*
* @see eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService#listResourceTypes()
*/
@Override
public List<String> listResourceTypes() throws ISLookUpException {
try {
return isStore.getFileNames(DB_BASE_DIR + "/" + ResourceType.RESOURCE_TYPES);
} catch (final ISStoreException e) {
throw new ISLookUpException(e);
}
}
/**
* {@inheritDoc}
*
* @see eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService#listServiceIDs(java.lang.String)
*/
@Override
public List<String> listServiceIDs(final String serviceType) throws ISLookUpException {
final String fileColl = "ServiceResources/" + serviceType;
final String encodedColl = "_" + new String(Base64.encode(fileColl.getBytes())); // NOPMD
final List<String> ret = new ArrayList<String>();
try {
for (final String i : isStore.getFileNames(DB_BASE_DIR + "/" + fileColl)) {
ret.add(i + encodedColl);
}
return ret;
} catch (final ISStoreException e) {
throw new ISLookUpException(e);
}
}
/**
* {@inheritDoc}
*
* @see eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService#listServiceTypes()
*/
@Override
public List<String> listServiceTypes() throws ISLookUpException {
final List<String> ret = new ArrayList<String>();
try {
for (final String i : isStore.getFileColls()) {
if (i.startsWith("ServiceResources/")) {
ret.add(i.substring("ServiceResources/".length()));
}
}
return ret;
} catch (final ISStoreException e) {
throw new ISLookUpException(e);
}
}
/**
* {@inheritDoc}
*
* @see eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService#quickSearchProfile(java.lang.String)
*/
@Override
public List<String> quickSearchProfile(final String xquery) throws ISLookUpException {
try {
return isStore.quickSearchXML(xquery);
} catch (final ISStoreException e) {
throw new ISLookUpException(e);
}
}
public ResourceIdentifierResolver getResIdManager() {
return resIdManager;
}
public void setResIdManager(final ResourceIdentifierResolver resIdManager) {
this.resIdManager = resIdManager;
}
@Required
public void setXqueryUtils(final XQueryUtils xqueryUtils) {
this.xqueryUtils = xqueryUtils;
}
public XQueryUtils getXqueryUtils() {
return xqueryUtils;
}
public ISStoreService getIsStore() {
return isStore;
}
@Required
public void setIsStore(final ISStoreService isStore) {
this.isStore = isStore;
}
}