importing common modules from dnet45

This commit is contained in:
Claudio Atzori 2019-05-30 18:23:22 +02:00
parent 54e4e2c4e3
commit 11c100f627
337 changed files with 27052 additions and 26 deletions

View File

@ -16,10 +16,22 @@
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
</dependency>
<dependency>
<groupId>com.mycila</groupId>
<artifactId>xmltool</artifactId>
</dependency>
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
@ -48,27 +60,136 @@
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<exclusions>
<exclusion>
<groupId>com.sun.jmx</groupId>
<artifactId>jmxri</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.jdmk</groupId>
<artifactId>jmxtools</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>runcc</groupId>
<artifactId>runcc</artifactId>
</dependency>
<dependency>
<groupId>org.antlr</groupId>
<artifactId>stringtemplate</artifactId>
</dependency>
<dependency>
<groupId>jparsec</groupId>
<artifactId>jparsec</artifactId>
</dependency>
<dependency>
<groupId>apache</groupId>
<artifactId>oro</artifactId>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
</dependency>
<dependency>
<groupId>org.apache.solr</groupId>
<artifactId>solr-solrj</artifactId>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-queryparser</artifactId>
</dependency>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongo-java-driver</artifactId>
</dependency>
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
</dependency>
<dependency>
<groupId>org.z3950.zing</groupId>
<artifactId>cql-java</artifactId>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
</dependency>
<!-- Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<optional>false</optional>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<scope>test</scope>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
</dependency>
<!-- CXF -->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-core</artifactId>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-bindings-soap</artifactId>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
</dependency>
<!-- Tomcat7 -->
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-catalina</artifactId>
</dependency>
</dependencies>

View File

@ -0,0 +1,10 @@
package eu.dnetlib.common.rmi;
public class APIDeprecatedException extends RuntimeException {
/**
*
*/
private static final long serialVersionUID = -5606373588445519515L;
}

View File

@ -0,0 +1,34 @@
package eu.dnetlib.common.rmi;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
@WebService(targetNamespace = "http://services.dnetlib.eu/")
public interface BaseService {
/**
* All DRIVER services must implement method notify() in order to communicate with the IS_SN
*
* @param subsrciptionId
* @param topic
* @param isId
* @param message
*/
@WebMethod(operationName = "notify")
public void notify(@WebParam(name = "subscrId") String subscriptionId,
@WebParam(name = "topic") String topic,
@WebParam(name = "is_id") String isId,
@WebParam(name = "message") String message);
/**
* Identifies the service's version. Version syntax: ${NAME}-${MAJOR}.${MINOR}.${MICRO}[-${LABEL}]
*
* @return the service's version
*/
@WebMethod(operationName = "identify")
public String identify();
public void start();
}

View File

@ -0,0 +1,16 @@
package eu.dnetlib.common.rmi;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Created by claudio on 30/11/2016.
* to be used in REST controllers, and autodiscovered to build and publish their documentation
*/
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface DNetRestDocumentation {
}

View File

@ -0,0 +1,28 @@
package eu.dnetlib.common.rmi;
/**
*
* All RMI exception thrown from the service remote method invocation interfaces inherit this class
*
* @author marko
*
*/
abstract public class RMIException extends Exception { // NOPMD
/**
*
*/
private static final long serialVersionUID = 428841258652765265L;
public RMIException(final Throwable exception) {
super(exception);
}
public RMIException(final String string) {
super(string);
}
public RMIException(final String string, final Throwable exception) {
super(string, exception);
}
}

View File

@ -0,0 +1,10 @@
package eu.dnetlib.common.rmi;
public class UnimplementedException extends RuntimeException {
/**
*
*/
private static final long serialVersionUID = 6040968020696349497L;
}

View File

@ -0,0 +1,60 @@
package eu.dnetlib.conf;
import javax.servlet.ServletContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.web.context.ServletContextAware;
/**
* This spring bean detects the webapp context path, from the ServletContext. It requires servlet-api 2.5 (tomcat6 and
* jetty 6.x).
*
* <p>
* Concrete subclasses will know what to do with this information
* </p>
*
* @author marko
*
*/
public abstract class AbstractWebappContextProperty implements ServletContextAware {
/**
* logger.
*/
private static final Log log = LogFactory.getLog(AbstractWebappContextProperty.class); // NOPMD by marko on 11/24/08 5:02 PM
/**
* web application context.
*/
protected String context;
/**
* saved servlet context.
*/
protected ServletContext servletContext;
@Override
public void setServletContext(final ServletContext servletContext) {
this.servletContext = servletContext;
try {
context = servletContext.getContextPath().substring(1);
} catch (final NoSuchMethodError e) {
log.warn("cannot detect servlet context path. servlet-api 2.5 is required, falling back to property based configuration", e);
}
}
public String getContext() {
return context;
}
public void setContext(final String context) {
this.context = context;
}
public ServletContext getServletContext() {
return servletContext;
}
}

View File

@ -0,0 +1,87 @@
package eu.dnetlib.conf;
import java.util.Map.Entry;
import java.util.Properties;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.PropertyResourceConfigurer;
/**
* PropertyFletcher
*
* @author marko
*
*/
public class PropertyFetcher extends PropertyResourceConfigurer implements InitializingBean {
private static final Log log = LogFactory.getLog(PropertyFetcher.class); // NOPMD by marko on 11/24/08 5:02 PM
boolean unchangedHostname = false;
boolean unchangedPort = true;
private Properties props;
@Override
public void afterPropertiesSet() throws Exception {
this.props = mergeProperties();
// Convert the merged properties, if necessary.
convertProperties(props);
log.debug("FOUND A container.hostname property " + props.getProperty("container.hostname"));
if ("localhost".equals(props.getProperty("container.hostname"))) {
unchangedHostname = true;
}
if (props.getProperty("container.port") != null) {
log.debug("FOUND A container.port property " + props.getProperty("container.port"));
unchangedPort = false;
}
if (log.isDebugEnabled()) {
log.debug("HOST unchanged? " + unchangedHostname);
log.debug("PORT unchanged? " + unchangedPort);
for (Entry<?, ?> e : props.entrySet()) {
log.debug("system property: " + e.getKey() + " --> " + e.getValue());
}
}
}
@Override
protected void processProperties(final ConfigurableListableBeanFactory arg0, final Properties props) throws BeansException {
}
public boolean isUnchangedHostname() {
return unchangedHostname;
}
public void setUnchangedHostname(final boolean unchangedHostname) {
this.unchangedHostname = unchangedHostname;
}
public boolean isUnchangedPort() {
return unchangedPort;
}
public void setUnchangedPort(final boolean unchangedPort) {
this.unchangedPort = unchangedPort;
}
public String getProperty(final String key) {
return props.getProperty(key);
}
public Properties getProps() {
return props;
}
public void setProps(final Properties props) {
this.props = props;
}
}

View File

@ -0,0 +1,66 @@
package eu.dnetlib.conf;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.FactoryBean;
/**
* This class wraps a list of property file paths and expands the @{webapp} placeholder with the name of the webapp taken from servlet-api
* 2.5.
*
* @author marko
*
*/
public class WebappContextPropertyLocationFactory extends AbstractWebappContextProperty implements FactoryBean<List<String>> {
/**
* logger.
*/
private static final Log log = LogFactory.getLog(WebappContextPropertyLocationFactory.class); // NOPMD by marko on 11/24/08 5:02 PM
private List<String> locations;
@Override
public List<String> getObject() throws Exception {
List<String> expanded = new ArrayList<String>();
for (String loc : locations) {
expanded.add(expand(loc).trim());
}
if (log.isInfoEnabled()) {
for (String location : expanded) {
log.info("Searching property file: " + location);
}
}
return expanded;
}
private String expand(final String loc) {
if (getContext() == null) return loc;
return loc.replace("@{webapp}", getContext());
}
@Override
public Class<?> getObjectType() {
return locations.getClass();
}
@Override
public boolean isSingleton() {
return true;
}
public List<String> getLocations() {
return locations;
}
public void setLocations(final List<String> locations) {
this.locations = locations;
}
}

View File

@ -0,0 +1,146 @@
package eu.dnetlib.conf;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Properties;
import javax.servlet.ServletContext;
import org.apache.catalina.Container;
import org.apache.catalina.connector.Connector;
import org.apache.catalina.core.StandardContext;
import org.apache.catalina.core.StandardEngine;
import org.apache.commons.lang.reflect.FieldUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.annotation.Required;
/**
* This factory generates default properties based on the amount of information available from the servlet container.
*
* @author marko
*
*/
public class WebappContextProperyFactory extends AbstractWebappContextProperty implements FactoryBean<Properties> {
/**
* logger.
*/
private static final Log log = LogFactory.getLog(WebappContextProperyFactory.class); // NOPMD by marko on
// 11/24/08 5:02 PM
/**
* If false, the ip address will be returned, otherwise a best effort attemp will be made to retrieve a meaningful host name. There is a
* risk that the hostname is obtained without domain and thus completely useless.
*/
private boolean resolveHostname = false;
private PropertyFetcher propertyFetcher;
@Override
public Properties getObject() throws Exception {
Properties props = new Properties();
if (getContext() == null) return props;
props.setProperty("container.context", getContext());
log.debug("trying to autodetect port and hostame");
// if the user didn't customize, then autodetect, otherwise honour the
// user!
if (propertyFetcher.isUnchangedPort()) {
log.debug("PORT IS NOT OVERRIDDEN, autodetecting");
int port = getPort(getServletContext());
if (port > 0) {
props.setProperty("container.port", Integer.toString(port));
}
} else {
log.debug("PORT IS OVERRIDDEN, NOT autodetecting");
}
if (propertyFetcher.isUnchangedHostname()) {
log.debug("HOST IS NOT OVERRIDDEN, autodetecting");
String hostname = getHost(getServletContext());
if (hostname != null) {
props.setProperty("container.hostname", hostname);
}
} else {
log.debug("HOST IS OVERRIDDEN, NOT autodetecting");
}
return props;
}
@Override
public Class<?> getObjectType() {
return Properties.class;
}
@Override
public boolean isSingleton() {
return true;
}
private int getPort(final ServletContext servletContext) {
try {
return getContainerPort(servletContext);
} catch (Throwable e) {
log.warn("cannot obtain port from container...strange: I thought it would work both on jetty and tomcat7...)", e);
return 0;
}
}
private int getContainerPort(final ServletContext servletContext) {
try {
Object o = FieldUtils.readField(servletContext, "context", true);
StandardContext sCtx = (StandardContext) FieldUtils.readField(o, "context", true);
Container container = sCtx;
Container c = container.getParent();
while ((c != null) && !(c instanceof StandardEngine)) {
c = c.getParent();
}
if (c != null) {
StandardEngine engine = (StandardEngine) c;
for (Connector connector : engine.getService().findConnectors()) {
if (connector.getPort() > 0) return connector.getPort();
}
}
} catch (Exception e) {
e.printStackTrace();
}
return 0;
}
private String getHost(final ServletContext servletContext) {
try {
if (resolveHostname) return InetAddress.getLocalHost().getCanonicalHostName();
else return InetAddress.getLocalHost().toString().split("/")[1];
} catch (UnknownHostException e) {
log.warn("cannot obtain hostname from JVM", e);
}
return null;
}
public boolean isResolveHostname() {
return resolveHostname;
}
public void setResolveHostname(final boolean resolveHostname) {
this.resolveHostname = resolveHostname;
}
public PropertyFetcher getPropertyFetcher() {
return propertyFetcher;
}
@Required
public void setPropertyFetcher(final PropertyFetcher propertyFetcher) {
this.propertyFetcher = propertyFetcher;
}
}

View File

@ -0,0 +1,28 @@
package eu.dnetlib.data.information.collectionservice.rmi;
import java.util.List;
import javax.jws.WebParam;
import javax.jws.WebService;
import eu.dnetlib.common.rmi.BaseService;
/**
* The Collection Service is used to ...
*
*
*/
@WebService(targetNamespace = "http://services.dnetlib.eu/")
public interface CollectionService extends BaseService {
public String getCollection(@WebParam(name = "collId") final String collId) throws CollectionServiceException;
public List<String> getCollections(@WebParam(name = "collIds") final List<String> collIds) throws CollectionServiceException;
public void updateCollection(@WebParam(name = "coll") final String coll) throws CollectionServiceException;
public void deleteCollection(@WebParam(name = "collId") final String collId) throws CollectionServiceException;
public String createCollection(@WebParam(name = "coll") final String coll) throws CollectionServiceException;
}

View File

@ -0,0 +1,28 @@
package eu.dnetlib.data.information.collectionservice.rmi;
import javax.xml.ws.WebFault;
import eu.dnetlib.common.rmi.RMIException;
@WebFault
public class CollectionServiceException extends RMIException {
/**
*
*/
private static final long serialVersionUID = 8094008463553904905L;
public CollectionServiceException(Throwable e) {
super(e);
}
public CollectionServiceException(String message, Throwable e) {
super(message, e);
}
public CollectionServiceException(String message) {
super(message);
}
}

View File

@ -0,0 +1,50 @@
package eu.dnetlib.data.information.publisher.rmi;
import java.util.List;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
import javax.xml.ws.wsaddressing.W3CEndpointReference;
import eu.dnetlib.common.rmi.BaseService;
/**
* Publisher service. Provides access to metadata records and objects.
*
* @author marko
*
*/
@WebService(targetNamespace = "http://services.dnetlib.eu/")
public interface PublisherService extends BaseService {
/**
* Get a (metadata) resource by ID.
*
* @param id
* @param format
* @param layout
* @param interpretation
* @return
*/
@WebMethod
String getResourceById(@WebParam(name = "id") final String id,
@WebParam(name = "format") final String format,
@WebParam(name = "layout") final String layout,
@WebParam(name = "interpretation") final String interpretation);
/**
* Get (metadata) resources by IDs.
*
* @param ids
* @param format
* @param layout
* @param interpretation
* @return
*/
@WebMethod
W3CEndpointReference getResourcesByIds(@WebParam(name = "ids") final List<String> ids,
@WebParam(name = "format") final String format,
@WebParam(name = "layout") final String layout,
@WebParam(name = "interpretation") final String interpretation);
}

View File

@ -0,0 +1,29 @@
package eu.dnetlib.data.mdstore;
/**
* Signals that a metadata record cannot be found in a given MDStore.
*/
public class DocumentNotFoundException extends MDStoreServiceException {
/**
*
*/
private static final long serialVersionUID = 5188036989114250548L;
public DocumentNotFoundException(final String s, final Throwable e) {
super(s, e);
}
public DocumentNotFoundException(final String s) {
super(s);
}
public DocumentNotFoundException(final Throwable e) {
super(e);
}
public DocumentNotFoundException() {
super();
}
}

View File

@ -0,0 +1,105 @@
package eu.dnetlib.data.mdstore;
import java.util.List;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
import javax.xml.ws.wsaddressing.W3CEndpointReference;
import eu.dnetlib.common.rmi.BaseService;
@WebService(targetNamespace = "http://services.dnetlib.eu/")
public interface MDStoreService extends BaseService {
/**
* Identifies service and version.
*
* @return
*/
@Override
public String identify();
/**
* Returns ResultSet EPR for delivered mdstore records.
*
* @param mdId
* @param from
* @param until
* @param recordFilter
* REGEX on the metadata record
* @return ResultSet EPR
* @throws MDStoreServiceException
*/
public W3CEndpointReference deliverMDRecords(@WebParam(name = "mdId") final String mdId,
@WebParam(name = "from") final String from,
@WebParam(name = "until") final String until,
@WebParam(name = "recordsFilter") final String recordFilter) throws MDStoreServiceException;
/**
* Deliver single record from selected mdstore.
*
* @param mdId
* @param recordId
* @return record
* @throws MDStoreServiceException
*/
public String deliverRecord(@WebParam(name = "mdId") final String mdId, @WebParam(name = "recordId") final String recordId) throws MDStoreServiceException,
DocumentNotFoundException;
/**
* Returns list of all stored indices.
*
* @return list of all stored indices
*/
public List<String> getListOfMDStores() throws MDStoreServiceException;
public List<String> listMDStores(@WebParam(name = "format") final String format,
@WebParam(name = "layout") final String layout,
@WebParam(name = "interpretation") final String interpretation) throws MDStoreServiceException;
public W3CEndpointReference bulkDeliverMDRecords(@WebParam(name = "format") final String format,
@WebParam(name = "layout") final String layout,
@WebParam(name = "interpretation") final String interpretation) throws MDStoreServiceException;
/**
* Store md records from a result set
*
* @param mdId
* @param rsId
* @param storingType
* @return returns true immediately.
* @throws MDStoreServiceException
*/
@Deprecated
public boolean storeMDRecordsFromRS(@WebParam(name = "mdId") final String mdId,
@WebParam(name = "rsId") final String rsId,
@WebParam(name = "storingType") final String storingType) throws MDStoreServiceException;
/**
* Gets the size of the mdstore with the given identifier.
*
* @param mdId
* identifier of an mdstore
* @return the number of records in the store
*/
@WebMethod(operationName = "size")
public int size(@WebParam(name = "mdId") final String mdId) throws MDStoreServiceException;
/**
* Gets the sum of records stored in all mdstore with the given format, layout , interpretation
*
* @param format
* format
* @param layout
* layout
* @param interpretation
* interpretation
* @return the total number of records in the mdstores of the given type
*/
@WebMethod(operationName = "sizeByFormat")
public int size(@WebParam(name = "format") final String format,
@WebParam(name = "layout") final String layout,
@WebParam(name = "interpretation") final String interpretation) throws MDStoreServiceException;
}

View File

@ -0,0 +1,32 @@
package eu.dnetlib.data.mdstore;
/**
* General mdstore service exception.
* @author claudio atzori
* @version 1.0.0
*
*/
public class MDStoreServiceException extends Exception {
/**
*
*/
private static final long serialVersionUID = -6772977735282310658L;
public MDStoreServiceException(String s, Throwable e) {
super(s, e);
}
public MDStoreServiceException(String s) {
super(s);
}
public MDStoreServiceException(Throwable e) {
super(e);
}
public MDStoreServiceException() {
super();
}
}

View File

@ -0,0 +1,65 @@
package eu.dnetlib.data.provision.index.rmi;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
/**
*
* serialization of the browsing result.
*
* <row> <groupresult field="facetFieldName1"> <value>facetFieldValue</value> <count>1</count> </groupresult>
*
* <groupresult field="facetFieldName2"> <value>facetFieldValue</value> <count>1</count> </groupresult>
*
* </row>
*
* @author claudio
*
*/
@XmlRootElement(namespace = "", name = "row")
@XmlAccessorType(XmlAccessType.FIELD)
public class BrowsingRow {
@XmlElement(name = "groupresult", required = true)
private List<GroupResult> groupresult;
public BrowsingRow() {}
public BrowsingRow(final List<GroupResult> groupresult) {
this.groupresult = groupresult;
}
/**
* adds a GroupResult.
*
* @param fieldName
* @param fieldValue
* @param count
*/
public void addBrowsingRow(final String fieldName, final String fieldValue, final int count) {
groupresult.add(new GroupResult(fieldName, fieldValue, count));
}
@Override
public boolean equals(final Object obj) {
if (!(obj instanceof BrowsingRow)) return false;
final BrowsingRow brws = (BrowsingRow) obj;
return groupresult.equals(brws.getGroupResult());
}
public List<GroupResult> getGroupResult() {
return groupresult;
}
public void setGroupResult(final List<GroupResult> groupresult) {
this.groupresult = groupresult;
}
}

View File

@ -0,0 +1,76 @@
package eu.dnetlib.data.provision.index.rmi;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;
/**
* <pre>
* {@code
* <groupresult field="facetFieldName">
* <value>facetFieldValue</value>
* <count>1</count>
* </groupresult>
* }
* </pre>
*
* @author claudio
*
*/
@XmlRootElement(namespace = "", name = "groupresult")
public class GroupResult {
private String name;
private String value;
private int count;
public GroupResult() {}
/**
* Builds a groupResult.
*
* @param fieldName
* @param fieldValue
* @param count
*/
public GroupResult(final String name, final String value, final int count) {
this.name = name;
this.value = value;
this.count = count;
}
@Override
public boolean equals(final Object obj) {
if (!(obj instanceof GroupResult)) return false;
final GroupResult g = (GroupResult) obj;
if ((this.getCount() == g.getCount()) && this.getName().equals(g.getName()) && this.getValue().equals(g.getValue())) return true;
return false;
}
@XmlAttribute(name = "field", required = true)
public String getName() {
return name;
}
public String getValue() {
return value;
}
public int getCount() {
return count;
}
public void setName(final String name) {
this.name = name;
}
public void setValue(final String value) {
this.value = value;
}
public void setCount(final int count) {
this.count = count;
}
}

View File

@ -0,0 +1,27 @@
package eu.dnetlib.data.provision.index.rmi;
import java.util.List;
import javax.jws.WebMethod;
import javax.jws.WebService;
import eu.dnetlib.common.rmi.BaseService;
/**
* Interface for the IndexService.
*
* @author alessia
*
*/
@WebService(targetNamespace = "http://services.dnetlib.eu/")
public interface IndexService extends BaseService {
/**
* Returns list of all stored indices.
*
* @return list of all stored indices
* @throws IndexServiceException
*/
@WebMethod(operationName = "getListOfIndices", action = "getListOfIndices")
public List<String> getListOfIndices() throws IndexServiceException;
}

View File

@ -0,0 +1,23 @@
package eu.dnetlib.data.provision.index.rmi;
public class IndexServiceException extends Exception {
private static final long serialVersionUID = 8330264706967294512L;
public IndexServiceException() {
super();
}
public IndexServiceException(String message, Throwable cause) {
super(message, cause);
}
public IndexServiceException(String message) {
super(message);
}
public IndexServiceException(Throwable cause) {
super(cause);
}
}

View File

@ -0,0 +1,5 @@
package eu.dnetlib.data.provision.index.rmi.protocols;
public enum IndexProtocols {
SOLR, SOLR_CLOUD
}

View File

@ -0,0 +1,28 @@
package eu.dnetlib.data.utility.objectpackaging.rmi;
import javax.xml.ws.WebFault;
import eu.dnetlib.common.rmi.RMIException;
@WebFault
public class ObjectPackagingException extends RMIException {
private static final long serialVersionUID = 3468254939586031822L;
/**
*
*/
public ObjectPackagingException(Throwable e) {
super(e);
}
public ObjectPackagingException(String message, Throwable e) {
super(message, e);
}
public ObjectPackagingException(String message) {
super(message);
}
}

View File

@ -0,0 +1,35 @@
package eu.dnetlib.data.utility.objectpackaging.rmi;
import java.util.List;
import javax.jws.WebParam;
import javax.jws.WebService;
import javax.xml.ws.wsaddressing.W3CEndpointReference;
import eu.dnetlib.common.rmi.BaseService;
/** The Object Packaging Service is used to combine the records spread
* into one information package, namely an Object Record.
*/
@WebService(targetNamespace = "http://services.dnetlib.eu/")
public interface ObjectPackagingService extends BaseService {
/** Return the EPR of the resultSet containing the generated packages
*
* @param eprs A list of EPRs used to access the input resultSets. ResultSets MUST be ordered using an order key identified by xpath_ID
* @param xpath_ID A valid xpath, used to access the ordered ID of the elements of the input resultSets.
* @return EPR of the generated resultset
*/
W3CEndpointReference generatePackages(@WebParam(name="eprs") List<W3CEndpointReference> eprs,
@WebParam(name="xpath_ID") String xpath_ID) throws ObjectPackagingException;
/** Return the EPR of the resultSet containing the unpackaged element
*
* @param epr The epr used to access the resultset that contains input packages, packages are xml record in this format: <objectRecord><elem>REC1</elem><elem>REC2</elem><elem>REC3</elem></objectRecord>
* @return EPR of the generated resultset
*/
W3CEndpointReference splitPackages(@WebParam(name="epr") W3CEndpointReference epr) throws ObjectPackagingException;
}

View File

@ -0,0 +1,7 @@
package eu.dnetlib.enabling.common;
public interface Stoppable {
void stop();
void resume();
StoppableDetails getStopDetails();
}

View File

@ -0,0 +1,45 @@
package eu.dnetlib.enabling.common;
public class StoppableDetails {
public enum StopStatus {
RUNNING, STOPPED, STOPPING
}
private String name;
private String message;
private StopStatus status;
public StoppableDetails() {}
public StoppableDetails(String name, String message, StopStatus status) {
this.name = name;
this.message = message;
this.status = status;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public StopStatus getStatus() {
return status;
}
public void setStatus(StopStatus status) {
this.status = status;
}
}

View File

@ -0,0 +1,18 @@
package eu.dnetlib.enabling.dlm.rmi;
import javax.jws.WebService;
import eu.dnetlib.common.rmi.BaseService;
/**
* Distributed lock manager. Currently is used mostly to start the underlying lock manager (e.g. zookeeper) and let
* client interface directly with it.
*
* <p>The DLM service profile contains the entry point of the underlying locking service.</p>
*
* @author marko
*
*/
@WebService(targetNamespace = "http://services.dnetlib.eu/")
public interface DlmService extends BaseService {
}

View File

@ -0,0 +1,20 @@
package eu.dnetlib.enabling.hcm.rmi;
import javax.jws.WebService;
import eu.dnetlib.common.rmi.BaseService;
/**
* Like a HostingNodeManager, but any webapp (web context) can have its own.
* <p>
* useful for dispatching notifications shared by all the services local to a single context.
* </p>
*
* @author marko
* @author antonis
*
*/
@WebService(targetNamespace = "http://services.dnetlib.eu/")
public interface HostingContextManagerService extends BaseService {
}

View File

@ -0,0 +1,17 @@
package eu.dnetlib.enabling.hnm.rmi;
import javax.jws.WebParam;
import javax.jws.WebService;
import eu.dnetlib.common.rmi.BaseService;
/**
* The HostingNodeManager Service is used to ...
*
*
*/
@WebService(targetNamespace = "http://services.dnetlib.eu/")
public interface HostingNodeManagerService extends BaseService {
public String echo(@WebParam(name = "s") String s);
}

View File

@ -0,0 +1,47 @@
package eu.dnetlib.enabling.is.lookup.rmi;
import javax.xml.ws.WebFault;
/**
* Thrown when a given document is not found.
*
* @author marko
*
*/
@WebFault
public class ISLookUpDocumentNotFoundException extends ISLookUpException {
/**
* exception chain + message.
*
* @param message message
* @param e
*/
public ISLookUpDocumentNotFoundException(String message, Throwable e) {
super(message, e);
}
/**
* exception chain constructor.
* @param e
*/
public ISLookUpDocumentNotFoundException(Throwable e) {
super(e);
}
/**
* exception message.
*
* @param message
*/
public ISLookUpDocumentNotFoundException(String message) {
super(message);
}
/**
*
*/
private static final long serialVersionUID = 2295995755165801937L;
}

View File

@ -0,0 +1,27 @@
package eu.dnetlib.enabling.is.lookup.rmi;
import javax.xml.ws.WebFault;
import eu.dnetlib.common.rmi.RMIException;
@WebFault
public class ISLookUpException extends RMIException {
/**
*
*/
private static final long serialVersionUID = -5626136963653382533L;
public ISLookUpException(Throwable e) {
super(e);
}
public ISLookUpException(String message, Throwable e) {
super(message, e);
}
public ISLookUpException(String message) {
super(message);
}
}

View File

@ -0,0 +1,53 @@
package eu.dnetlib.enabling.is.lookup.rmi;
import java.util.List;
import javax.jws.WebParam;
import javax.jws.WebService;
import eu.dnetlib.common.rmi.BaseService;
@WebService(targetNamespace = "http://services.dnetlib.eu/")
public interface ISLookUpService extends BaseService {
Boolean flushCachedResultSets();
@Deprecated
String getCollection(@WebParam(name = "profId") String profId, @WebParam(name = "format") String format) throws ISLookUpException;
String retrieveCollection(@WebParam(name = "profId") String profId) throws ISLookUpException;
String getResourceProfile(@WebParam(name = "profId") String profId) throws ISLookUpException, ISLookUpDocumentNotFoundException;
String getResourceProfileByQuery(@WebParam(name = "XQuery") String XQuery) throws ISLookUpException, ISLookUpDocumentNotFoundException;
String getResourceQoSParams(@WebParam(name = "id") String id) throws ISLookUpException;
String getResourceTypeSchema(@WebParam(name = "resourceType") String resourceType) throws ISLookUpException, ISLookUpDocumentNotFoundException;
List<String> listCollections(
@WebParam(name = "format") String format,
@WebParam(name = "idfather") String idfather,
@WebParam(name = "owner") String owner) throws ISLookUpException;
@Deprecated
List<String> listDHNIDs() throws ISLookUpException;
List<String> listResourceTypes() throws ISLookUpException;
@Deprecated
List<String> listServiceIDs(@WebParam(name = "serviceType") String serviceType) throws ISLookUpException;
@Deprecated
List<String> listServiceTypes() throws ISLookUpException;
/**
* Like searchProfile(), but bypassing the resultset. Useful for short xquery results.
*
* @param xquery xquery to be executed
* @return list of strings (never null)
* @throws ISLookUpException could happen
*/
List<String> quickSearchProfile(@WebParam(name = "XQuery") String xquery) throws ISLookUpException;
}

View File

@ -0,0 +1,27 @@
package eu.dnetlib.enabling.is.registry;
import eu.dnetlib.enabling.is.registry.rmi.ISRegistryException;
public class ISRegistryDocumentNotFoundException extends ISRegistryException {
/**
*
*/
private static final long serialVersionUID = -1304948213334188538L;
public ISRegistryDocumentNotFoundException(String string, Throwable e) {
super(string, e);
// TODO Auto-generated constructor stub
}
public ISRegistryDocumentNotFoundException(String string) {
super(string);
// TODO Auto-generated constructor stub
}
public ISRegistryDocumentNotFoundException(Throwable e) {
super(e);
// TODO Auto-generated constructor stub
}
}

View File

@ -0,0 +1,24 @@
package eu.dnetlib.enabling.is.registry.rmi;
import eu.dnetlib.common.rmi.RMIException;
public class ISRegistryException extends RMIException {
/**
*
*/
private static final long serialVersionUID = -3347405941287624771L;
public ISRegistryException(Throwable e) {
super(e);
}
public ISRegistryException(String string) {
super(string);
}
public ISRegistryException(String string, Throwable e) {
super(string, e);
}
}

View File

@ -0,0 +1,75 @@
package eu.dnetlib.enabling.is.registry.rmi;
import java.util.List;
import javax.jws.WebService;
import eu.dnetlib.common.rmi.BaseService;
import eu.dnetlib.enabling.is.registry.ISRegistryDocumentNotFoundException;
@WebService(targetNamespace = "http://services.dnetlib.eu/")
public interface ISRegistryService extends BaseService {
boolean addOrUpdateResourceType(String resourceType, String resourceSchema) throws ISRegistryException;
boolean addResourceType(String resourceType, String resourceSchema) throws ISRegistryException;
boolean deleteProfile(String profId) throws ISRegistryException, ISRegistryDocumentNotFoundException;
@Deprecated
boolean deleteProfiles(List<String> arrayprofId) throws ISRegistryException;
/**
* @param resourceType
* @param hierarchical
* remove subscription topics
* @return
* @throws ISRegistryException
*/
boolean deleteResourceType(String resourceType, Boolean hierarchical) throws ISRegistryException;
boolean executeXUpdate(String XQuery) throws ISRegistryException;
String insertProfileForValidation(String resourceType, String resourceProfile) throws ISRegistryException;
String invalidateProfile(String profId) throws ISRegistryException;
boolean refreshProfile(String profId, String resourceType) throws ISRegistryException;
/**
* register a XML Profile.
*
* @param resourceProfile
* xml profile
* @return profile id
* @throws ISRegistryException
*/
String registerProfile(String resourceProfile) throws ISRegistryException;
String registerSecureProfile(String resourceProfId, String secureProfId) throws ISRegistryException;
boolean updateProfile(String profId, String resourceProfile, String resourceType) throws ISRegistryException;
@Deprecated
String updateProfileDHN(String resourceProfile) throws ISRegistryException;
boolean addProfileNode(String profId, String xpath, String node) throws ISRegistryException;
boolean updateProfileNode(String profId, String xpath, String node) throws ISRegistryException;
boolean removeProfileNode(String profId, String nodeId) throws ISRegistryException;
@Deprecated
boolean updateRegionDescription(String profId, String resourceProfile) throws ISRegistryException;
String validateProfile(String profId) throws ISRegistryException;
@Deprecated
List<String> validateProfiles(List<String> profIds) throws ISRegistryException;
void addBlackBoardMessage(String profId, String messageId, String message) throws ISRegistryException;
void replyBlackBoardMessage(String profId, String message) throws ISRegistryException;
void deleteBlackBoardMessage(String profId, String messageId) throws ISRegistryException;
}

View File

@ -0,0 +1,19 @@
package eu.dnetlib.enabling.is.registry.schema;
import eu.dnetlib.enabling.tools.OpaqueResource;
/**
* validates the conformity of a resource to a give resource type.
*
* @author marko
*
*/
public interface OpaqueResourceValidator {
/**
* check if the given resource is valid according to it's schema.
*
* @param resource opaque resource
* @throws ValidationException thrown if the validation fails, along with a description of the cause.
*/
void validate(OpaqueResource resource) throws ValidationException;
}

View File

@ -0,0 +1,35 @@
package eu.dnetlib.enabling.is.registry.schema;
/**
* encapsulates a schema validation exception.
*
* @author marko
*
*/
public class ValidationException extends Exception {
/**
* version.
*/
private static final long serialVersionUID = -6886927707534508655L;
/**
* construct a validation exception based upon an encapsulated cause.
* @param cause cause
*/
public ValidationException(final Throwable cause) {
super(cause);
}
/**
* construct a validation exception with a message.
*
* @param message message
*/
public ValidationException(final String message) {
super(message);
}
}

View File

@ -0,0 +1,24 @@
package eu.dnetlib.enabling.is.sn.rmi;
import eu.dnetlib.common.rmi.RMIException;
public class ISSNException extends RMIException {
/**
*
*/
private static final long serialVersionUID = -7384073901457430004L;
public ISSNException(final Throwable e) {
super(e);
}
public ISSNException(final String message) {
super(message);
}
public ISSNException(final String message, final Throwable e) {
super(message, e);
}
}

View File

@ -0,0 +1,129 @@
package eu.dnetlib.enabling.is.sn.rmi;
import java.util.List;
import javax.jws.WebParam;
import javax.jws.WebService;
import javax.xml.ws.wsaddressing.W3CEndpointReference;
import eu.dnetlib.common.rmi.BaseService;
@WebService(targetNamespace = "http://services.dnetlib.eu/")
public interface ISSNService extends BaseService {
/**
* fossil.
*
* @param topic
* @return
* @throws ISSNException
*/
String getCurrentMessage(@WebParam(name = "topic") String topic) throws ISSNException;
/**
* puts a subcription in a paused state. paused subscription are not notified even when triggered.
*
* @param subscrId
* subscription identifier
* @return returns false if the subscription is already paused.
* @throws ISSNException
* may happen
*/
boolean pauseSubscription(@WebParam(name = "subscrId") String subscrId) throws ISSNException;
/**
* Used to renew the subscription before it expires.
*
* <p>
* In practice it resets the ttl to another value, so it can be used to reset a infinte ttl subscription to a finite
* value.
* </p>
*
* @param subscrId
* subscription id
* @param terminationTime
* new ttl (from now), or 0 (infinite)
* @return true if successful
* @throws ISSNException
* may happen
*/
boolean renew(@WebParam(name = "subscrId") String subscrId, @WebParam(name = "terminationTime") int terminationTime) throws ISSNException;
/**
* resumes a paused subscription.
*
* @param subscrId
* subscription id
* @return true if resumed. false if it was not paused.
* @throws ISSNException
* may happen
*/
boolean resumeSubscription(@WebParam(name = "subscrId") String subscrId) throws ISSNException;
/**
* @param consumerReference
* epr to be called when the notification is triggered
* @param topicExpression
* topic expression to register
* @param initialTerminationTime
* ttl in seconds (0 = infinite)
* @return subscription id
* @throws ISSNException
* may happen
*/
String subscribe(
@WebParam(name = "consumerReference") W3CEndpointReference consumerReference,
@WebParam(name = "topicExpression") String topicExpression,
@WebParam(name = "initialTerminationTime") int initialTerminationTime) throws ISSNException, SubscriptionRequestRejectedException;
boolean unsubscribe(@WebParam(name = "subscrId") String subscrId) throws ISSNException;
/**
* fossil.
*
* @param resourceType
* @param profileId
* @param profile
* @return
* @throws ISSNException
*/
boolean actionCreatePerformed(
@WebParam(name = "resourceType") String resourceType,
@WebParam(name = "profileId") String profileId,
@WebParam(name = "profile") String profile) throws ISSNException;
/**
* fossil.
*
* @param resourceType
* @param profileId
* @param profileBefore
* @param profileAfter
* @return
* @throws ISSNException
*/
boolean actionUpdatePerformed(
@WebParam(name = "resourceType") String resourceType,
@WebParam(name = "profileId") String profileId,
@WebParam(name = "profileBefore") String profileBefore,
@WebParam(name = "profileAfter") String profileAfter) throws ISSNException;
/**
* fossil.
*
* @param resourceType
* @param profileId
* @return
* @throws ISSNException
*/
boolean actionDeletePerformed(@WebParam(name = "resourceType") String resourceType, @WebParam(name = "profileId") String profileId)
throws ISSNException;
/**
* list all subscriptions. Mostly for debug reasons.
*
* @return list of subscription ids.
*/
List<String> listSubscriptions();
}

View File

@ -0,0 +1,21 @@
package eu.dnetlib.enabling.is.sn.rmi;
/**
* Thrown when a subscription request is rejected.
*
* @author claudio
*
*/
public class SubscriptionRequestRejectedException extends ISSNException {
/**
*
*/
private static final long serialVersionUID = 263095606953662098L;
public SubscriptionRequestRejectedException(String message) {
super(message);
// TODO Auto-generated constructor stub
}
}

View File

@ -0,0 +1,135 @@
package eu.dnetlib.enabling.is.store;
import java.io.IOException;
import java.io.StringWriter;
import java.net.URL;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPathExpressionException;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Required;
import org.xml.sax.SAXException;
import eu.dnetlib.enabling.is.registry.rmi.ISRegistryException;
import eu.dnetlib.enabling.is.registry.rmi.ISRegistryService;
import eu.dnetlib.enabling.locators.UniqueServiceLocator;
import eu.dnetlib.enabling.tools.StreamOpaqueResource;
/**
* Abstract resource loading code.
*
* @author marko, michele
*
*/
public class AbstractContentInitializer {
/**
* logger.
*/
private static final Log log = LogFactory.getLog(AbstractContentInitializer.class); // NOPMD by marko on 11/24/08 5:02 PM
/**
* service locator.
*/
private UniqueServiceLocator serviceLocator;
/**
* helper class used to bypass the registry and import resources as-is from a backup dump.
*/
private BulkResourceImporter bulkImporter;
private int timeToSleep;
/**
* register a schema from a local resource.
*
* @param url
* url
* @throws IOException
* happens
* @throws ISRegistryException
* could happen
*/
protected void registerSchema(final URL url) throws IOException, ISRegistryException {
final String resourceType = FilenameUtils.getBaseName(url.getPath());
log.debug("registering schema: " + resourceType);
final StringWriter writer = new StringWriter();
IOUtils.copy(url.openStream(), writer);
ISRegistryService service = null;
while (service == null) {
try {
service = serviceLocator.getService(ISRegistryService.class, true);
service.addResourceType(resourceType, writer.getBuffer().toString());
log.info("The is registry service is ready ");
} catch (Exception e) {
log.fatal("The is registry service is not ready ", e);
try {
Thread.sleep(timeToSleep);
} catch (InterruptedException e1) {
log.error(e1);
}
}
}
}
/**
* register a profile from a local resource.
*
* @param url
* url
* @throws IOException
* could happen
* @throws ISRegistryException
* could happen
* @throws ParserConfigurationException
* could happen
* @throws SAXException
* could happen
* @throws XPathExpressionException
* could happen
*/
protected void registerProfile(final URL url) throws IOException, ISRegistryException, XPathExpressionException, SAXException, ParserConfigurationException {
log.debug("registering profile: " + url);
bulkImporter.importResource(new StreamOpaqueResource(url.openStream()));
}
@Required
public void setBulkImporter(final BulkResourceImporter bulkImporter) {
this.bulkImporter = bulkImporter;
}
public BulkResourceImporter getBulkImporter() {
return bulkImporter;
}
/**
* @return the timeToSleep
*/
public int getTimeToSleep() {
return timeToSleep;
}
/**
* @param timeToSleep
* the timeToSleep to set
*/
@Required
public void setTimeToSleep(final int timeToSleep) {
this.timeToSleep = timeToSleep;
}
public UniqueServiceLocator getServiceLocator() {
return serviceLocator;
}
@Required
public void setServiceLocator(final UniqueServiceLocator serviceLocator) {
this.serviceLocator = serviceLocator;
}
}

View File

@ -0,0 +1,115 @@
package eu.dnetlib.enabling.is.store;
import org.springframework.beans.factory.annotation.Required;
import eu.dnetlib.enabling.is.registry.rmi.ISRegistryException;
import eu.dnetlib.enabling.is.registry.schema.OpaqueResourceValidator;
import eu.dnetlib.enabling.is.registry.schema.ValidationException;
import eu.dnetlib.enabling.is.store.rmi.ISStoreException;
import eu.dnetlib.enabling.is.store.rmi.ISStoreService;
import eu.dnetlib.enabling.locators.UniqueServiceLocator;
import eu.dnetlib.enabling.tools.OpaqueResource;
import eu.dnetlib.enabling.tools.XQueryUtils;
/**
* This class implements a bulk resource import, i.e. importing stuff straight into the store, bypassing checks and policies imposed by the
* registry service.
*
* TODO: move from registry based to store based.
*
* @author marko
*
*/
public class BulkResourceImporter {
/**
* xquery utils, needed to map resources with the xmldb collection names.
*/
private XQueryUtils xqueryUtils;
/**
* service locator.
*/
private UniqueServiceLocator serviceLocator;
/**
* resource validator.
*/
private OpaqueResourceValidator resourceValidator;
/**
* set to false to skip validation.
*/
private boolean validating = true;
/**
* bulk loading enabled.
*/
private boolean enabled = true;
/**
* register a resource bypassing the checks.
*
* @param resource
* a resource
* @throws ISRegistryException
* could happen
*/
public void importResource(final OpaqueResource resource) throws ISRegistryException {
try {
if (validating) {
resourceValidator.validate(resource);
}
serviceLocator.getService(ISStoreService.class, true).insertXML(xqueryUtils.getFileName(resource), xqueryUtils.getCollectionAbsPath(resource),
resource.asString());
} catch (final ISStoreException e) {
throw new ISRegistryException(e);
} catch (final ValidationException e) {
throw new ISRegistryException(e);
}
}
public XQueryUtils getXqueryUtils() {
return xqueryUtils;
}
@Required
public void setXqueryUtils(final XQueryUtils xqueryUtils) {
this.xqueryUtils = xqueryUtils;
}
@Required
public void setResourceValidator(final OpaqueResourceValidator resourceValidator) {
this.resourceValidator = resourceValidator;
}
public OpaqueResourceValidator getResourceValidator() {
return resourceValidator;
}
public void setValidating(final boolean validating) {
this.validating = validating;
}
public boolean isValidating() {
return validating;
}
public boolean isEnabled() {
return enabled;
}
public void setEnabled(final boolean enabled) {
this.enabled = enabled;
}
public UniqueServiceLocator getServiceLocator() {
return serviceLocator;
}
@Required
public void setServiceLocator(final UniqueServiceLocator serviceLocator) {
this.serviceLocator = serviceLocator;
}
}

View File

@ -0,0 +1,24 @@
package eu.dnetlib.enabling.is.store.rmi;
import eu.dnetlib.common.rmi.RMIException;
public class ISStoreException extends RMIException {
/**
*
*/
private static final long serialVersionUID = 8683126829156096420L;
public ISStoreException(Throwable e) {
super(e);
}
public ISStoreException(String message, Throwable e) {
super(message, e);
}
public ISStoreException(String message) {
super(message);
}
}

View File

@ -0,0 +1,44 @@
package eu.dnetlib.enabling.is.store.rmi;
import java.util.List;
import javax.jws.WebParam;
import javax.jws.WebService;
import javax.xml.ws.wsaddressing.W3CEndpointReference;
import eu.dnetlib.common.rmi.BaseService;
@WebService(targetNamespace = "http://services.dnetlib.eu/")
public interface ISStoreService extends BaseService {
boolean createFileColl(@WebParam(name = "fileColl") String fileColl) throws ISStoreException;
boolean deleteFileColl(@WebParam(name = "fileColl") String fileColl) throws ISStoreException;
boolean deleteXML(@WebParam(name = "fileName") String fileName, @WebParam(name = "fileColl") String fileColl) throws ISStoreException;
boolean executeXUpdate(@WebParam(name = "query") String query) throws ISStoreException;
List<String> getFileColls() throws ISStoreException;
List<String> getFileNames(@WebParam(name = "fileColl") String fileColl) throws ISStoreException;
String getXML(@WebParam(name = "fileName") String fileName, @WebParam(name = "fileColl") String fileColl) throws ISStoreException;
String getXMLbyQuery(@WebParam(name = "query") String query) throws ISStoreException;
boolean insertXML(@WebParam(name = "fileName") String fileName, @WebParam(name = "fileColl") String fileColl, @WebParam(name = "file") String file)
throws ISStoreException;
boolean reindex();
List<String> quickSearchXML(@WebParam(name = "query") String query) throws ISStoreException;
boolean sync();
boolean updateXML(@WebParam(name = "fileName") String fileName, @WebParam(name = "fileColl") String fileColl, @WebParam(name = "file") String file)
throws ISStoreException;
String backup() throws ISStoreException;
}

View File

@ -0,0 +1,264 @@
package eu.dnetlib.enabling.locators;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.*;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import eu.dnetlib.common.rmi.BaseService;
import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpException;
import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService;
import eu.dnetlib.enabling.tools.registration.ServiceNameResolver;
import eu.dnetlib.enabling.tools.registration.ValidatingServiceRegistrationManagerImpl;
import eu.dnetlib.miscutils.collections.EnsureCollection;
import eu.dnetlib.soap.cxf.StandaloneCxfEndpointReferenceBuilder;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Required;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
public class DefaultUniqueServiceLocator implements UniqueServiceLocator, ApplicationContextAware {
private ApplicationContext appContext;
private Comparator<ServiceRunningInstance> defaultComparator; // = new
// PreferLocalRunningInstanceComparator();
/**
* An instance of isLookupService (local or stub)
*/
@Autowired
private ISLookUpService isLookupService;
@Autowired
private ServiceNameResolver serviceNameResolver;
/**
* XML Parser
*/
private SAXReader reader = new SAXReader();
/**
* build epr.
*/
@Autowired
private StandaloneCxfEndpointReferenceBuilder eprBuilder;
/**
* logger.
*/
private static final Log log = LogFactory.getLog(DefaultUniqueServiceLocator.class);
@Override
public <T extends BaseService> T getService(final Class<T> clazz) {
return getService(clazz, true);
}
@Override
public <T extends BaseService> T getService(final Class<T> clazz, final Comparator<ServiceRunningInstance> comparator) {
final String serviceName = serviceNameResolver.getName(clazz);
return findRunningInstances(serviceName, comparator).get(0).obtainClient(clazz, eprBuilder);
}
@Override
public <T extends BaseService> T getService(final Class<T> clazz, final String profileId) {
final String profile = obtainServiceProfile(profileId);
try {
return obtainRunningInstance(profile, obtainLocalServices()).obtainClient(clazz, eprBuilder);
} catch (Exception e) {
log.error("cannot instantiate service from id: " + profileId, e);
throw new IllegalStateException("cannot instantiate service from id: " + profileId, e);
}
}
@Override
public <T extends BaseService> T getService(final Class<T> clazz, final boolean local) {
if (clazz.isInstance(isLookupService)) return clazz.cast(isLookupService);
if (local) {
try {
final Map<String, T> beans = appContext.getBeansOfType(clazz);
if ((beans != null) && !beans.isEmpty()) return beans.values().iterator().next();
} catch (Throwable e) {
log.warn("No beans found in context, class " + clazz);
}
}
return getService(clazz, defaultComparator);
}
@Override
public <T extends BaseService> String getServiceId(final Class<T> clazz) {
return getServiceId(clazz, defaultComparator);
}
@Override
public <T extends BaseService> String getServiceId(final Class<T> clazz, final Comparator<ServiceRunningInstance> comparator) {
return findRunningInstances(serviceNameResolver.getName(clazz), comparator).get(0).getServiceId();
}
@Override
public <T extends BaseService> String getServiceId(final Class<T> clazz, final String profileId) {
final String profile = obtainServiceProfile(profileId);
final ServiceRunningInstance instance = obtainRunningInstance(profile, obtainLocalServices());
return instance.getServiceId();
}
@Override
public <T extends BaseService> Set<T> getAllServices(final Class<T> clazz) {
final Set<T> res = Sets.newHashSet();
for (ServiceRunningInstance instance : findRunningInstances(serviceNameResolver.getName(clazz), null)) {
res.add(instance.obtainClient(clazz, eprBuilder));
}
return res;
}
@Override
public <T extends BaseService> Set<String> getAllServiceIds(final Class<T> clazz) {
final Set<String> res = Sets.newHashSet();
for (ServiceRunningInstance instance : findRunningInstances(serviceNameResolver.getName(clazz), null)) {
res.add(instance.getServiceId());
}
return res;
}
private synchronized <T extends BaseService> ServiceRunningInstance obtainRunningInstance(final String profile, final Map<String, BaseService> locals) {
try {
final Document doc = reader.read(new StringReader(profile));
final String url = doc.valueOf("//PROTOCOL[@name = 'SOAP']/@address");
final String id = doc.valueOf("//RESOURCE_IDENTIFIER/@value");
final Map<String, String> props = Maps.newHashMap();
final BaseService local = locals.containsKey(id) ? locals.get(id) : null;
final int usedDiskpace = NumberUtils.toInt(doc.valueOf("//USED_DISKSPACE"), 0);
final int handledDatastructures = NumberUtils.toInt(doc.valueOf("//HANDLED_DATASTRUCTURE"), 0);;
for (Object o : doc.selectNodes("//SERVICE_PROPERTIES/PROPERTY")) {
final Element p = (Element) o;
props.put(p.valueOf("@key"), p.valueOf("@value"));
}
return new ServiceRunningInstance(id, url, local, usedDiskpace, handledDatastructures, props);
} catch (DocumentException e) {
log.error("Error parsing profile: " + profile, e);
throw new RuntimeException("Error parsing profile: " + profile, e);
}
}
private List<ServiceRunningInstance> findRunningInstances(final String serviceName, final Comparator<ServiceRunningInstance> comparator) {
final List<ServiceRunningInstance> list = findRegisteredServices(serviceName);
if (list.isEmpty()) {
log.error("Service not found, name: " + serviceName);
throw new RuntimeException("Service not found, name: " + serviceName);
}
if (comparator != null) {
Collections.sort(list, comparator);
}
return list;
}
private List<ServiceRunningInstance> findRegisteredServices(final String serviceName) {
log.debug("searching for service: " + serviceName);
final String xquery = "for $x in collection('/db/DRIVER/ServiceResources/" + serviceName + "ResourceType') return $x";
log.debug(xquery);
try {
final List<String> services = isLookupService.quickSearchProfile(xquery);
final List<ServiceRunningInstance> instances = Lists.newArrayList();
final Map<String, BaseService> locals = obtainLocalServices();
for (final String source : EnsureCollection.list(services)) {
final ServiceRunningInstance instance = obtainRunningInstance(source, locals);
instances.add(instance);
}
return instances;
} catch (final Exception e) {
throw new IllegalStateException("cannot locate service " + serviceName, e);
}
}
private Map<String, BaseService> obtainLocalServices() {
final Map<String, BaseService> locals = Maps.newHashMap();
for (ValidatingServiceRegistrationManagerImpl r : appContext.getBeansOfType(ValidatingServiceRegistrationManagerImpl.class).values()) {
if (r.getService() instanceof BaseService) {
if (!StringUtils.isBlank(r.getProfileId())) {
final BaseService baseService = (BaseService) r.getService();
if (baseService != null) {
locals.put(r.getProfileId(), baseService);
log.debug(" -> Service: " + r.getService().getClass().getName() + " has id " + r.getServiceProfile().getResourceId());
}
}
}
}
return locals;
}
private String obtainServiceProfile(final String profileId) {
final StringWriter sw = new StringWriter();
sw.append("let $uri:=/RESOURCE_PROFILE/HEADER[./RESOURCE_IDENTIFIER/@value='");
sw.append(profileId);
sw.append("']/RESOURCE_URI/@value/string()");
sw.append("\n\n");
sw.append("for $x in collection('/db/DRIVER/ServiceResources')");
sw.append("\n");
sw.append("where $x/RESOURCE_PROFILE/HEADER/RESOURCE_URI/@value = $uri");
sw.append("\n");
sw.append("return $x");
final String xq = sw.toString();
try {
return isLookupService.getResourceProfileByQuery(xq);
} catch (ISLookUpException e) {
log.error("cannot locate service using query: " + xq, e);
throw new IllegalStateException("cannot locate service using query: " + xq, e);
}
}
@Override
public void setApplicationContext(final ApplicationContext appContext) throws BeansException {
this.appContext = appContext;
}
public Comparator<ServiceRunningInstance> getDefaultComparator() {
return defaultComparator;
}
@Required
public void setDefaultComparator(final Comparator<ServiceRunningInstance> defaultComparator) {
this.defaultComparator = defaultComparator;
}
public ISLookUpService getIsLookupService() {
return isLookupService;
}
public void setIsLookupService(final ISLookUpService isLookupService) {
this.isLookupService = isLookupService;
}
public ServiceNameResolver getServiceNameResolver() {
return serviceNameResolver;
}
public void setServiceNameResolver(final ServiceNameResolver serviceNameResolver) {
this.serviceNameResolver = serviceNameResolver;
}
}

View File

@ -0,0 +1,102 @@
package eu.dnetlib.enabling.locators;
import java.util.HashMap;
import java.util.Map;
import javax.xml.ws.WebServiceFeature;
import javax.xml.ws.wsaddressing.W3CEndpointReference;
import eu.dnetlib.common.rmi.BaseService;
import eu.dnetlib.soap.cxf.StandaloneCxfEndpointReferenceBuilder;
/**
* This bean packages the minimum information for describing a service running instance.
*/
public class ServiceRunningInstance {
private String serviceId;
private String url;
private BaseService localService;
private int usedDiskSpace = 0;
private int handledDatastructures = 0;
private Map<String, String> serviceProperties = new HashMap<String, String>();
public ServiceRunningInstance() {}
public ServiceRunningInstance(final String serviceId, final String url) {
this.serviceId = serviceId;
this.url = url;
}
public ServiceRunningInstance(final String serviceId, final String url, final BaseService localService, final int usedDiskSpace,
final int handledDatastructures, final Map<String, String> serviceProperties) {
this.serviceId = serviceId;
this.url = url;
this.localService = localService;
this.usedDiskSpace = usedDiskSpace;
this.handledDatastructures = handledDatastructures;
this.serviceProperties = serviceProperties;
}
public boolean isLocal() {
return localService != null;
}
synchronized public <T extends BaseService> T obtainClient(final Class<T> clazz, final StandaloneCxfEndpointReferenceBuilder eprBuilder) {
if (isLocal() && clazz.isInstance(localService)) {
return clazz.cast(localService);
} else {
final W3CEndpointReference epr = eprBuilder.getEndpointReference(url, null, null, url + "?wsdl", null, null);
return epr.getPort(clazz, new WebServiceFeature[] {});
}
}
public String getServiceId() {
return serviceId;
}
public void setServiceId(final String serviceId) {
this.serviceId = serviceId;
}
public String getUrl() {
return url;
}
public void setUrl(final String url) {
this.url = url;
}
public BaseService getLocalService() {
return localService;
}
public void setLocalService(final BaseService localService) {
this.localService = localService;
}
public Map<String, String> getServiceProperties() {
return serviceProperties;
}
public void setServiceProperties(final Map<String, String> serviceProperties) {
this.serviceProperties = serviceProperties;
}
public int getUsedDiskSpace() {
return usedDiskSpace;
}
public void setUsedDiskSpace(final int usedDiskSpace) {
this.usedDiskSpace = usedDiskSpace;
}
public int getHandledDatastructures() {
return handledDatastructures;
}
public void setHandledDatastructures(final int handledDatastructures) {
this.handledDatastructures = handledDatastructures;
}
}

View File

@ -0,0 +1,20 @@
package eu.dnetlib.enabling.locators;
import java.util.Comparator;
import java.util.Set;
import eu.dnetlib.common.rmi.BaseService;
public interface UniqueServiceLocator {
<T extends BaseService> T getService(Class<T> clazz);
<T extends BaseService> T getService(Class<T> clazz, Comparator<ServiceRunningInstance> comparator);
<T extends BaseService> T getService(Class<T> clazz, String profileId);
<T extends BaseService> T getService(Class<T> clazz, boolean local);
<T extends BaseService> String getServiceId(Class<T> clazz);
<T extends BaseService> String getServiceId(Class<T> clazz, Comparator<ServiceRunningInstance> comparator);
<T extends BaseService> String getServiceId(Class<T> clazz, String profileId);
<T extends BaseService> Set<T> getAllServices(Class<T> clazz);
<T extends BaseService> Set<String> getAllServiceIds(Class<T> clazz);
}

View File

@ -0,0 +1,14 @@
package eu.dnetlib.enabling.locators.comparators;
import java.util.Comparator;
import eu.dnetlib.enabling.locators.ServiceRunningInstance;
public class DiskSpaceComparator implements Comparator<ServiceRunningInstance> {
@Override
public int compare(final ServiceRunningInstance s0, ServiceRunningInstance s1) {
return Integer.compare(s0.getUsedDiskSpace(), s1.getUsedDiskSpace());
}
}

View File

@ -0,0 +1,14 @@
package eu.dnetlib.enabling.locators.comparators;
import java.util.Comparator;
import eu.dnetlib.enabling.locators.ServiceRunningInstance;
public class HandledDatastructuresComparator implements Comparator<ServiceRunningInstance> {
@Override
public int compare(final ServiceRunningInstance s1, final ServiceRunningInstance s2) {
return Integer.compare(s1.getHandledDatastructures(), s2.getHandledDatastructures());
}
}

View File

@ -0,0 +1,20 @@
package eu.dnetlib.enabling.locators.comparators;
import java.util.Comparator;
import eu.dnetlib.enabling.locators.ServiceRunningInstance;
public class PreferLocalRunningInstanceComparator implements Comparator<ServiceRunningInstance> {
@Override
public int compare(final ServiceRunningInstance s1, final ServiceRunningInstance s2) {
if (s1.isLocal()) {
return -1;
} else if (s2.isLocal()) {
return 1;
} else {
return 0;
}
}
}

View File

@ -0,0 +1,21 @@
package eu.dnetlib.enabling.resultset.rmi;
import eu.dnetlib.common.rmi.RMIException;
public class ResultSetException extends RMIException {
/**
*
*/
private static final long serialVersionUID = -7130554407601059627L;
public ResultSetException(Throwable e) {
super(e);
// TODO Auto-generated constructor stub
}
public ResultSetException(String string) {
super(string);
}
}

View File

@ -0,0 +1,142 @@
package eu.dnetlib.enabling.resultset.rmi;
import java.util.List;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
import javax.xml.ws.wsaddressing.W3CEndpointReference;
import eu.dnetlib.common.rmi.BaseService;
/**
* ResultSet service interface.
*
* TODO: implement other compatibility methods as needed.
*
* @author marko
*
*/
@WebService(targetNamespace = "http://services.dnetlib.eu/")
public interface ResultSetService extends BaseService {
/**
* create a new pull rs.
*
* @param bdId
* bulk data identifier
* @param initialPageSize
* page size for the polling on the server side.
* @param expiryTime
* RS expiry time
* @return
*/
W3CEndpointReference createPullRSEPR(
@WebParam(name = "dataProviderServiceAddress") W3CEndpointReference dataProviderEPR,
@WebParam(name = "bdId") String bdId,
@WebParam(name = "initialPageSize") int initialPageSize,
@WebParam(name = "expiryTime") int expiryTime,
@WebParam(name = "styleSheet") String styleSheet,
@WebParam(name = "keepAliveTime") Integer keepAliveTime,
@WebParam(name = "total") Integer total);
/**
* create a new pull rs.
*
* compatibility version
*
* @param bdId
* bulk data identifier
* @param initialPageSize
* page size for the polling on the server side.
* @param expiryTime
* RS expiry time
* @return
*/
W3CEndpointReference createPullRS(
@WebParam(name = "dataProviderServiceAddress") String dataProviderServiceAddress,
@WebParam(name = "bdId") String bdId,
@WebParam(name = "initialPageSize") int initialPageSize,
@WebParam(name = "expiryTime") int expiryTime,
@WebParam(name = "styleSheet") String styleSheet,
@WebParam(name = "keepAliveTime") Integer keepAliveTime,
@WebParam(name = "total") Integer total);
/**
* close a result set. A closed resultset is guaranteed not to grow.
*
* @param rsId
*/
void closeRS(@WebParam(name = "rsId") String rsId);
/**
* get one 'page' of results.
*
* TODO: define how results are returned when the range is not present in the result set.
*
* @param fromPosition
* counting from 1
* @param toPosition
* included
* @param requestMode
* @return a page of data
*/
List<String> getResult(
@WebParam(name = "rsId") String rsId,
@WebParam(name = "fromPosition") int fromPosition,
@WebParam(name = "toPosition") int toPosition,
@WebParam(name = "requestMode") String requestMode) throws ResultSetException;
/**
* get the number of result elements present in the resultset.
*
* @param rsId
* result set identifier
* @return number of results available in the resultset
* @throws ResultSetException
*/
int getNumberOfElements(@WebParam(name = "rsId") String rsId) throws ResultSetException;
/**
* create a new push resultset.
*
* @param expiryTime RS expiry time
* @param keepAliveTime keep alive time
* @return epr of new resultset
* @throws ResultSetException
*/
W3CEndpointReference createPushRS(@WebParam(name = "expiryTime") int expiryTime, @WebParam(name = "keepAliveTime") int keepAliveTime)
throws ResultSetException;
/**
* add new data to a push resultset.
*
* @param rsId resultset id
* @param elements list of elements to be addded
* @return dummy value
* @throws ResultSetException
*/
String populateRS(@WebParam(name = "rsId") String rsId, @WebParam(name = "elements") List<String> elements) throws ResultSetException;
/**
* return current status of a resultset.
*
* @param rsId resultset id
* @return status
* @throws ResultSetException
*/
String getRSStatus(@WebParam(name = "rsId") String rsId) throws ResultSetException;
/**
* read a resultset property.
*
* @param rsId resultset id
* @param name property value
* @return property value
* @throws ResultSetException
*/
String getProperty(@WebParam(name = "rsId") String rsId, @WebParam(name = "name") String name) throws ResultSetException;
@WebMethod(operationName = "identify")
public String identify();
}

View File

@ -0,0 +1,46 @@
package eu.dnetlib.soap;
import java.util.Map;
import javax.xml.namespace.QName;
import javax.xml.ws.wsaddressing.W3CEndpointReference;
/**
*
* default implementation short methods.
*
* @author marko
*
* @param <T>
*/
public abstract class AbstractEndpointReferenceBuilder<T> implements EndpointReferenceBuilder<T> {
/**
* {@inheritDoc}
*
* @see eu.dnetlib.soap.EndpointReferenceBuilder#getEndpointReference(java.lang.Object)
*/
@Override
public W3CEndpointReference getEndpointReference(final T endpoint) {
return getEndpointReference(endpoint, (Map<QName, Object>)null);
}
/**
* {@inheritDoc}
* @see eu.dnetlib.soap.EndpointReferenceBuilder#getEndpointReference(java.lang.Object, java.lang.String)
*/
@Override
public W3CEndpointReference getEndpointReference(final T endpoint, final String referenceParam) {
return getEndpointReference(endpoint, referenceParam, null);
}
/**
* {@inheritDoc}
* @see eu.dnetlib.soap.EndpointReferenceBuilder#getEndpointReference(java.lang.Object, java.util.Map)
*/
@Override
public W3CEndpointReference getEndpointReference(final T endpoint, final Map<QName, Object> attrs) {
return getEndpointReference(endpoint, null, attrs);
}
}

View File

@ -0,0 +1,88 @@
package eu.dnetlib.enabling.soap;
import java.util.Map;
import javax.xml.namespace.QName;
import javax.xml.ws.wsaddressing.W3CEndpointReference;
import org.springframework.beans.factory.annotation.Required;
import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService;
import eu.dnetlib.enabling.locators.UniqueServiceLocator;
import eu.dnetlib.enabling.tools.OpaqueResource;
import eu.dnetlib.enabling.tools.StringOpaqueResource;
import eu.dnetlib.soap.AbstractEndpointReferenceBuilder;
import eu.dnetlib.soap.EndpointReferenceBuilder;
/**
* Builds an epr given an ID to a datastructure.
*
* @author marko
*
*/
public class DataStructureLookupEndpointReferenceBuilder extends AbstractEndpointReferenceBuilder<String> implements EndpointReferenceBuilder<String> {
/**
* service locator.
*/
private UniqueServiceLocator serviceLocator;
/**
* underlying ds epr builder.
*/
private DataStructureProfileEndpointReferenceBuilder dsEprBuilder;
/**
* {@inheritDoc}
*
* @see eu.dnetlib.soap.EndpointReferenceBuilder#getAddress(java.lang.Object)
*/
@Override
public String getAddress(final String pid) {
return dsEprBuilder.getAddress(getProfile(pid));
}
/**
* {@inheritDoc}
*
* @see eu.dnetlib.soap.EndpointReferenceBuilder#getEndpointReference(java.lang.Object, java.lang.String, java.util.Map)
*/
@Override
public W3CEndpointReference getEndpointReference(final String pid, final String referenceParam, final Map<QName, Object> attrs) {
return dsEprBuilder.getEndpointReference(getProfile(pid), attrs);
}
/**
* obtain the ds profile
*
* @param pid
* datastructure profile
* @return resource
*/
private OpaqueResource getProfile(final String pid) {
try {
return new StringOpaqueResource(serviceLocator.getService(ISLookUpService.class).getResourceProfile(pid));
} catch (Exception e) { // TODO: remove this hack (conversion to unchecked exception)
throw new IllegalStateException(e);
}
}
public DataStructureProfileEndpointReferenceBuilder getDsEprBuilder() {
return dsEprBuilder;
}
@Required
public void setDsEprBuilder(final DataStructureProfileEndpointReferenceBuilder dsEprBuilder) {
this.dsEprBuilder = dsEprBuilder;
}
public UniqueServiceLocator getServiceLocator() {
return serviceLocator;
}
@Required
public void setServiceLocator(final UniqueServiceLocator serviceLocator) {
this.serviceLocator = serviceLocator;
}
}

View File

@ -0,0 +1,76 @@
package eu.dnetlib.enabling.soap;
import java.util.HashMap;
import java.util.Map;
import javax.xml.namespace.QName;
import javax.xml.ws.wsaddressing.W3CEndpointReference;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import eu.dnetlib.enabling.tools.OpaqueResource;
import eu.dnetlib.soap.AbstractEndpointReferenceBuilder;
import eu.dnetlib.soap.EndpointReferenceBuilder;
import eu.dnetlib.soap.cxf.CxfEndpointReferenceBuilder;
/**
* Build an epr from a data structure.
*
* @author marko
*
*/
public class DataStructureProfileEndpointReferenceBuilder extends AbstractEndpointReferenceBuilder<OpaqueResource> implements
EndpointReferenceBuilder<OpaqueResource> {
private static final Log log = LogFactory.getLog(DataStructureProfileEndpointReferenceBuilder.class); // NOPMD by marko on 11/24/08 5:02 PM
/**
* low level epr builder used to create the actual epr.
*
* TODO: factor out the address based epr building out of CXF specific code.
*
*/
private transient CxfEndpointReferenceBuilder lowEprBuilder = new CxfEndpointReferenceBuilder();
/**
* {@inheritDoc}
* @see eu.dnetlib.soap.EndpointReferenceBuilder#getAddress(java.lang.Object)
*/
@Override
public String getAddress(OpaqueResource profile) {
return profile.getResourceUri().replace("?wsdl", "");
}
/**
* {@inheritDoc}
* @see eu.dnetlib.soap.AbstractEndpointReferenceBuilder#getEndpointReference(java.lang.Object, java.util.Map)
*/
@Override
public W3CEndpointReference getEndpointReference(OpaqueResource profile, Map<QName, Object> attrs) {
return getEndpointReference(profile, profile.getResourceId(), attrs);
}
/**
* {@inheritDoc}
* @see eu.dnetlib.soap.AbstractEndpointReferenceBuilder#getEndpointReference(java.lang.Object)
*/
@Override
public W3CEndpointReference getEndpointReference(OpaqueResource profile) {
log.info("GETTING EPR short");
return getEndpointReference(profile, profile.getResourceId());
}
/**
* {@inheritDoc}
* @see eu.dnetlib.soap.EndpointReferenceBuilder#getEndpointReference(java.lang.Object, java.lang.String, java.util.Map)
*/
@Override
public W3CEndpointReference getEndpointReference(OpaqueResource profile, String referenceParam, Map<QName, Object> attrs) {
return lowEprBuilder.getEndpointReference(getAddress(profile), null, null, getAddress(profile) + "?wsdl", referenceParam,
new HashMap<QName, Object>());
}
}

View File

@ -0,0 +1,96 @@
package eu.dnetlib.soap;
import java.util.Map;
import javax.xml.namespace.QName;
import javax.xml.ws.wsaddressing.W3CEndpointReference;
/**
* This is a generalization of org.apache.cxf.jaxws.EndpointReferenceBuilder and org.apache.cxf.jaxws.EndpointImpl
*
* <p>
* javax.xml.ws.WebServiceContext org.apache.cxf.jaxws.EndpointReferenceBuilder doesn't expose the API for adding
* additional metadata while org.apache.cxf.jaxws.EndpointImpl doesn't take the correct endpoint address from the
* EndpointInfo object. org.apache.cxf.endpoint.Endpoint return a CXF proprietary endpoint reference and not the
* javax/w3c standard definition.
* </p>
*
* <p>
* This interface is intended to provide an abstract way to construct an endpoint reference for a given service,
* depending on the type of endpoint interface you have at hand (CXF abstract endpoint or jaxws endpoint)
* </p>
*
* <p>
* Normally the type parameter T will be bound to your endpoint type.
* </p>
*
* <p>
* In CXF jaxws applications you can easly get a WebServiceContext instance which returns an EndpointReference, however
* the API is cumbersome because it requires instantiating w3c DOM Element instances for each reference parameter, and
* it doesn't allow setting custom metadata elements.
* </p>
*
* <p>
* Implementors of this API will extract as many useful informations from the runtime besides the plain soap endpoint
* address.
* </p>
*
* @author marko
* @param <T>
* all endpoint builders are parameterized to specific endpoint type which on the used framework (not on the
* service)
*
*/
public interface EndpointReferenceBuilder<T> {
/**
* get an endpoint reference with default metadata attached.
*
* @param endpoint
* the endpoint
* @return an endpoint reference
*/
W3CEndpointReference getEndpointReference(T endpoint);
/**
* get an endpoint reference with custom metadata attached.
*
* @param endpoint
* the endpoint
* @param attrs
* metadata attribute map
* @return an endpoint reference
*/
W3CEndpointReference getEndpointReference(T endpoint, Map<QName, Object> attrs);
/**
* get an endpoint reference with a WSA reference parameter.
*
* @param endpoint
* the endpoint
* @param referenceParam
* reference parameters
* @return an endpoint reference
*/
W3CEndpointReference getEndpointReference(T endpoint, String referenceParam);
/**
* get an endpoint reference with custom metadata attached and WSA reference parameter.
*
* @param endpoint
* endpoint
* @param referenceParam
* reference parameters
* @param attrs
* metadata attribute map
* @return an endpoint reference
*/
W3CEndpointReference getEndpointReference(T endpoint, String referenceParam, Map<QName, Object> attrs);
/**
* Sometimes we need only the address.
*
* @param endpoint endpoint
* @return address
*/
String getAddress(T endpoint);
}

View File

@ -0,0 +1,60 @@
package eu.dnetlib.soap;
import java.util.Map;
import javax.xml.namespace.QName;
import javax.xml.ws.wsaddressing.W3CEndpointReference;
import javax.xml.ws.wsaddressing.W3CEndpointReferenceBuilder;
/**
* This endpoint reference builder builds always the same epr, with a fixed address, for any incoming endpoint (even
* null endpoints). Useful when registering service profiles for external services like the old perl Aggregator.
*
* @author marko
*
* @param <T>
* endpoint type
*/
public class StaticEndpointReferenceBuilder<T> implements EndpointReferenceBuilder<T> {
/**
* service address.
*/
private String address;
@Override
public String getAddress(final T endpoint) {
return address;
}
@Override
public W3CEndpointReference getEndpointReference(final T endpoint) {
final W3CEndpointReferenceBuilder builder = new W3CEndpointReferenceBuilder();
builder.address(address);
return builder.build();
}
@Override
public W3CEndpointReference getEndpointReference(final T endpoint, final Map<QName, Object> attrs) {
return getEndpointReference(endpoint);
}
@Override
public W3CEndpointReference getEndpointReference(final T endpoint, final String referenceParam) {
return getEndpointReference(endpoint);
}
@Override
public W3CEndpointReference getEndpointReference(final T endpoint, final String referenceParam, final Map<QName, Object> attrs) {
return getEndpointReference(endpoint);
}
public String getAddress() {
return address;
}
public void setAddress(final String address) {
this.address = address;
}
}

View File

@ -0,0 +1,206 @@
package eu.dnetlib.soap.cxf;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.ws.wsaddressing.W3CEndpointReference;
import javax.xml.ws.wsaddressing.W3CEndpointReferenceBuilder;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.cxf.endpoint.Endpoint;
import org.apache.oro.text.perl.Perl5Util;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import eu.dnetlib.soap.AbstractEndpointReferenceBuilder;
/**
* The cxf endpoint is an internal cross-toolkit implementation of the messaging endpoint.
*
* <p>
* End users will normally access jaxws endpoints, since jaxws is the mostly used cxf frontend. However, generic code,
* like interceptors, will handle cxf endpoints, so sometimes you may need to construct endpoint references from them.
* </p>
*
* <pre>
* &lt;ns3:Address&gt;http://localhost:8090/app/services/isStore&lt;/ns3:Address&gt;
* &lt;ns3:ReferenceParameters/&gt;
* &lt;ns3:Metadata&gt;
* &lt;wsaw:InterfaceName&gt;ns1:ISStoreService&lt;/wsaw:InterfaceName&gt;
* &lt;wsaw:ServiceName EndpointName=&quot;ISStoreServicePort&quot;&gt;ns2:ISStoreServiceService&lt;/wsaw:ServiceName&gt;
* &lt;infrastructure:infrastructure&gt;development&lt;/infrastructure:infrastructure&gt;
* &lt;/ns3:Metadata&gt;
* </pre>
*
* Users can easily define default system or service wide custom metadata to endpoint references by setting a
* defaultMetadata property:
*
* <pre>
* &lt;bean name=&quot;cxfEndpointReferenceBuilder&quot; class=&quot;eu.dnetlib.soap.cxf.CxfEndpointReferenceBuilder&quot;&gt;
* &lt;property name=&quot;defaultMetadata&quot;&gt;
* &lt;map&gt;
* &lt;entry key=&quot;{http://dnetlib.eu/endpointReference}infrastructure&quot; value=&quot;${infrastructure.name}&quot; /&gt;
* &lt;/map&gt;
* &lt;/property&gt;
* &lt;/bean&gt;
* </pre>
*
*
* @author marko
*
*/
public class CxfEndpointReferenceBuilder extends AbstractEndpointReferenceBuilder<Endpoint> {
/**
* logger.
*/
private static final Log log = LogFactory.getLog(CxfEndpointReferenceBuilder.class); // NOPMD by marko on 11/24/08 4:55
/**
* users can put some default metadata elements into all EPRs.
*/
private Map<String, Object> defaultMetadata;
/**
* regexp utility.
*/
private final transient Perl5Util matcher = new Perl5Util();
/**
* namespace of the ResourceIdentifier reference parameter.
*/
private String riNamespace = "http://www.driver.org";
/**
* element name of the ResourceIdentifier reference parameter.
*/
private String riElementName = "ResourceIdentifier";
/**
* {@inheritDoc}
*
* TODO: refactor.
*
* @see eu.dnetlib.soap.EndpointReferenceBuilder#getEndpointReference(java.lang.Object, java.util.Map)
*/
@Override
public W3CEndpointReference getEndpointReference(final Endpoint endpoint, final String referenceParam, final Map<QName, Object> attributes) {
final String address = getAddress(endpoint);
return getEndpointReference(address, endpoint.getService().getName(), endpoint.getEndpointInfo().getName(), null, referenceParam,
attributes);
}
/**
* low level method which allows the construction of a endpoint reference knowing all basic data as the address, service name etc.
*
* @param address
* @param serviceName
* @param endpointName
* @param wsdl
* @param referenceParam
* @param attributes
* @return
*/
public W3CEndpointReference getEndpointReference(
final String address,
final QName serviceName,
final QName endpointName,
final String wsdl,
final String referenceParam,
final Map<QName, Object> attributes) {
Map<QName, Object> attrs = attributes;
final W3CEndpointReferenceBuilder builder = new W3CEndpointReferenceBuilder();
builder.address(address);
if(serviceName != null)
builder.serviceName(serviceName);
if(endpointName != null)
builder.endpointName(endpointName);
builder.wsdlDocumentLocation(wsdl);
if (defaultMetadata != null) {
if (attrs == null)
attrs = new HashMap<QName, Object>();
for (Entry<String, Object> entry : defaultMetadata.entrySet())
attrs.put(splitQNameString(entry.getKey()), entry.getValue());
}
try {
final Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); // NOPMD
if (referenceParam != null) {
final Element referenceElement = doc.createElementNS(getRiNamespace(), getRiElementName());
referenceElement.setTextContent(referenceParam);
builder.referenceParameter(referenceElement);
}
if (attrs != null && !attrs.isEmpty()) {
for (Entry<QName, Object> entry : attrs.entrySet()) {
final QName qname = entry.getKey();
final Element element = doc.createElementNS(qname.getNamespaceURI(), qname.getLocalPart());
element.setTextContent((String) entry.getValue());
builder.metadata(element);
}
}
} catch (ParserConfigurationException e) {
log.fatal("cannot extend EPR", e);
throw new IllegalStateException("cannot extend EPR", e);
}
return builder.build();
}
/**
* compute an endpoint address.
*
* @param endpoint
* endpoint
* @return url as string
*/
@Override
public String getAddress(final Endpoint endpoint) {
return endpoint.getEndpointInfo().getAddress();
}
/**
* helper method for converting "{namespace}elementName" strings to QNames.
*
* @param key
* "{namespace}elementName" string
* @return qname
*/
private QName splitQNameString(final String key) {
matcher.match("m/{(.*)}(.*)/", key);
return new QName(matcher.group(1), matcher.group(2));
}
public Map<String, Object> getDefaultMetadata() {
return defaultMetadata;
}
public void setDefaultMetadata(final Map<String, Object> defaultMetadata) {
this.defaultMetadata = defaultMetadata;
}
public String getRiNamespace() {
return riNamespace;
}
public void setRiNamespace(final String riNamespace) {
this.riNamespace = riNamespace;
}
public String getRiElementName() {
return riElementName;
}
public void setRiElementName(final String riElementName) {
this.riElementName = riElementName;
}
}

View File

@ -0,0 +1,64 @@
package eu.dnetlib.soap.cxf;
import java.util.Map;
import javax.xml.namespace.QName;
import javax.xml.ws.Endpoint;
import javax.xml.ws.wsaddressing.W3CEndpointReference;
import org.apache.cxf.jaxws.EndpointImpl;
import org.springframework.beans.factory.annotation.Required;
import eu.dnetlib.soap.AbstractEndpointReferenceBuilder;
/**
* This EndpointReferenceBuilder implementation takes a jaxws endpoint and extracts the cxf endpoint from it.
*
* jaxws endpoints are the most readily available endpoint objects since they constructed from jaxws:endpoint spring
* beans, as shown in the CXF documentation.
*
* Since this implementation forwards the job to CxfEndpointReferenceBuilder, the 'builder' property has to be set:
*
* <pre>
* &lt;bean name=&quot;jaxwsEndpointReferenceBuilder&quot; class=&quot;eu.dnetlib.soap.cxf.JaxwsEndpointReferenceBuilder&quot;
* p:builder-ref=&quot;cxfEndpointReferenceBuilder&quot; /&gt;
* </pre>
*
* @author marko
* @see CxfEndpointReferenceBuilder
*
*/
public class JaxwsEndpointReferenceBuilder extends AbstractEndpointReferenceBuilder<Endpoint> {
/**
* required reference to the cxf endpoint builder.
*/
private CxfEndpointReferenceBuilder builder = null;
/**
* simply unpacks the cxf endpoint from the jaxws endpoint and forwards it to CxfEndpointReferenceBuilder.
*
* {@inheritDoc}
*
* @see eu.dnetlib.soap.EndpointReferenceBuilder#getEndpointReference(java.lang.Object, java.util.Map)
*/
@Override
public W3CEndpointReference getEndpointReference(final Endpoint endpoint, final String referenceParam, final Map<QName, Object> attrs) {
return builder.getEndpointReference(((EndpointImpl) endpoint).getServer().getEndpoint(), referenceParam, attrs);
}
public CxfEndpointReferenceBuilder getBuilder() {
return builder;
}
@Required
public void setBuilder(final CxfEndpointReferenceBuilder builder) {
this.builder = builder;
}
@Override
public String getAddress(Endpoint endpoint) {
return builder.getAddress(((EndpointImpl) endpoint).getServer().getEndpoint());
}
}

View File

@ -0,0 +1,97 @@
package eu.dnetlib.soap.cxf;
import java.net.URI;
import java.net.URISyntaxException;
import javax.annotation.PostConstruct;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.cxf.endpoint.Endpoint;
import org.springframework.beans.factory.annotation.Required;
/**
* CxfEndpointReferenceBuilder is not able to create correct endpoint addresses outside a http request context. This means that service
* initialization code cannot obtain the service address and thus cannot register himself.
*
* This subclass allows putting a local address (ip/dns + port) to be used when the runtime servlet context is not available.
*
* TODO: automated tomcat port detection, trough org.apache.catalina.ServerFactory.getServer().getServices() TODO: automated jetty port
* detection
*
*
* @author marko
*
*/
public class StandaloneCxfEndpointReferenceBuilder extends CxfEndpointReferenceBuilder {
private static final Log log = LogFactory.getLog(StandaloneCxfEndpointReferenceBuilder.class); // NOPMD by marko on 11/24/08 5:02 PM
/**
* base url where all services are exported.
*/
private String baseAddress;
private String absoluteBase;
private boolean forceLocalAddress = false;
public String getBaseAddress() {
return baseAddress;
}
public void setBaseAddress(final String baseAddress) {
this.baseAddress = baseAddress;
}
@PostConstruct
public void init() throws URISyntaxException {
URI base = new URI(baseAddress);
log.info("base address: " + baseAddress);
this.absoluteBase = (new URI(base.getScheme(), base.getUserInfo(), base.getHost(), base.getPort(), null, null, null)).toString().trim();
log.info("absolute base address: " + absoluteBase);
}
/**
* {@inheritDoc}
*
* @see eu.dnetlib.soap.cxf.CxfEndpointReferenceBuilder#getAddress(org.apache.cxf.endpoint.Endpoint)
*/
@Override
public String getAddress(final Endpoint endpoint) {
final String address = super.getAddress(endpoint);
if (forceLocalAddress) {
try {
URI uri = new URI(address);
if (!address.startsWith("http://")) {
String res = baseAddress + uri.getPath();
if (log.isDebugEnabled()) {
log.debug("fixing address to: " + res);
}
return res;
}
String res = absoluteBase + uri.getPath();
if (log.isDebugEnabled()) {
log.debug("forcing address to: " + res);
}
return res;
} catch (URISyntaxException e) {
throw new IllegalArgumentException(e);
}
}
if (!address.startsWith("http://") && (baseAddress != null)) { return baseAddress + address; }
return address;
}
public boolean isForceLocalAddress() {
return forceLocalAddress;
}
@Required
public void setForceLocalAddress(final boolean forceLocalAddress) {
this.forceLocalAddress = forceLocalAddress;
}
}

View File

@ -0,0 +1,85 @@
package eu.dnetlib.enabling.tools;
import javax.jws.WebService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.Lifecycle;
import eu.dnetlib.common.rmi.BaseService;
/**
* This class contains default definition for BaseService contract and basic service lifecycle.
*
* TODO: split BaseService contract implementation from lifecycle and other helper method
*
* @author marko
*
*/
@WebService(targetNamespace = "http://services.dnetlib.eu/")
public abstract class AbstractBaseService implements BaseService, Lifecycle {
/**
* logger.
*/
private static final Log log = LogFactory // NOPMD by marko on 11/24/08 5:02 PM
.getLog(AbstractBaseService.class);
private boolean started = false;
/**
* {@inheritDoc}
*
* @see eu.dnetlib.common.rmi.BaseService#identify()
*/
@Override
public String identify() {
return getClass().getName();
}
/**
* {@inheritDoc}
*
* @see eu.dnetlib.common.rmi.BaseService#notify(java.lang.String, java.lang.String, java.lang.String, java.lang.String)
*/
@Override
public void notify(final String subscriptionId, final String topic, final String isId, final String message) {
log.debug("got notification: " + topic + ", profile: " + isId + ", body: " + message);
}
/**
* {@inheritDoc}
*
* @see eu.dnetlib.common.rmi.BaseService#start()
*/
@Override
public void start() {
log.info("Starting service " + identify());
if (started) {
log.warn("Service " + this + "already started, check bean initializations!");
}
started = true;
}
/**
* {@inheritDoc}
*
* @see org.springframework.context.Lifecycle#isRunning()
*/
@Override
public boolean isRunning() {
log.debug("called isRunning " + this);
return false;
}
/**
* {@inheritDoc}
*
* @see org.springframework.context.Lifecycle#stop()
*/
@Override
public void stop() {
log.info("Stopping service " + this);
}
}

View File

@ -0,0 +1,119 @@
package eu.dnetlib.enabling.tools;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.Map;
import javax.annotation.Resource;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.ws.wsaddressing.W3CEndpointReference;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import com.google.common.collect.Maps;
import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpException;
import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService;
import eu.dnetlib.soap.cxf.StandaloneCxfEndpointReferenceBuilder;
@Deprecated
public abstract class AbstractServiceLocator<T> implements ServiceLocator<T> {
/**
* lookup locator.
*/
@Resource(name="lookupLocator")
private ServiceLocator<ISLookUpService> lookUpLocator;
/**
* build epr.
*/
@Resource
private StandaloneCxfEndpointReferenceBuilder eprBuilder;
/**
* service resolver. used to create proxies for discovered services.
*/
@Resource(name="serviceResolver")
private ServiceResolver serviceResolver;
/**
* logger.
*/
private static final Log log = LogFactory.getLog(AbstractServiceLocator.class); // NOPMD by marko on 11/24/08 5:02 PM
@Override
public T getService(final String profileId, final Class<T> clazz) {
final String profile = executeQuery(profileId, null);
try {
final XPathFactory factory = XPathFactory.newInstance();
final XPath xpath = factory.newXPath();
final DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
final DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
final Document doc = docBuilder.parse(new InputSource(new StringReader(profile)));
final String url = xpath.evaluate("//url", doc);
final String serviceId = xpath.evaluate("//id", doc);
final NodeList propElements = (NodeList) xpath.evaluate("//PROPERTY", doc, XPathConstants.NODESET);
final Map<String, String> props = Maps.newHashMap();
for (int i = 0; i < propElements.getLength(); i++) {
Element propElement = (Element) propElements.item(i);
props.put(propElement.getAttribute("key"), propElement.getAttribute("value"));
}
final W3CEndpointReference epr = eprBuilder.getEndpointReference(url, null, null, url + "?wsdl", null, null);
final ServiceRunningInstance<T> instance = new ServiceRunningInstance<T>(epr, serviceId, url, props);
return serviceResolver.getService(clazz, instance.getEpr());
} catch(Exception e) {
log.error("cannot instantiate service from id: " + profileId, e);
throw new IllegalStateException("cannot instantiate service from id: " + profileId, e);
}
}
@Override
public String getServiceId(final String profileId) {
return executeQuery(profileId, "/RESOURCE_PROFILE/HEADER/RESOURCE_IDENTIFIER/@value/string()");
}
private String executeQuery(final String profileId, final String xpath) {
final StringWriter sw = new StringWriter();
sw.append("let $uri:=/RESOURCE_PROFILE/HEADER[./RESOURCE_IDENTIFIER/@value='");
sw.append(profileId);
sw.append("']/RESOURCE_URI/@value/string()");
sw.append("\n\n");
sw.append("for $x in collection('/db/DRIVER/ServiceResources')/RESOURCE_PROFILE/HEADER");
sw.append("\n");
sw.append("where $x/RESOURCE_PROFILE/HEADER/RESOURCE_URI/@value = $uri");
sw.append("\n");
sw.append("return $x");
if (xpath != null) {
sw.append(xpath);
}
final String xq = sw.toString();
try {
return lookUpLocator.getService().getResourceProfileByQuery(xq);
} catch (ISLookUpException e) {
log.error("cannot locate service using query: " + xq, e);
throw new IllegalStateException("cannot locate service using query: " + xq, e);
}
}
}

View File

@ -0,0 +1,32 @@
package eu.dnetlib.enabling.tools;
import javax.xml.transform.dom.DOMResult;
import javax.xml.ws.wsaddressing.W3CEndpointReference;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
/**
* implement common functionality of ServiceResolvers.
*
* @author marko
*
*/
public abstract class AbstractServiceResolverImpl implements ServiceResolver {
/**
* {@inheritDoc}
* @see eu.dnetlib.enabling.tools.ServiceResolver#getResourceIdentifier(javax.xml.ws.wsaddressing.W3CEndpointReference)
*/
@Override
public String getResourceIdentifier(final W3CEndpointReference epr) {
final DOMResult dom = new DOMResult();
epr.writeTo(dom);
try {
return XPathFactory.newInstance().newXPath().evaluate("//*[local-name() = 'ResourceIdentifier']", dom.getNode());
} catch (XPathExpressionException e) {
throw new IllegalStateException("cannot construct xpath expression", e);
}
}
}

View File

@ -0,0 +1,264 @@
package eu.dnetlib.enabling.tools;
import java.io.StringWriter;
import java.util.Date;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import eu.dnetlib.miscutils.datetime.DateUtils;
/**
* OpaqueResource holding a plain old DOM document.
*
* @author marko
*
*/
public class DOMOpaqueResource implements OpaqueResource {
/**
* xpath expression error message.
*/
private static final String XPATH_ERROR = "cannot compile xpath expression";
/**
* value attribute.
*/
private static final String VALUE_ATTR = "value";
/**
* logger.
*/
private static final Log log = LogFactory.getLog(DOMOpaqueResource.class); // NOPMD by marko on 11/24/08 5:02 PM
/**
* resource identifier.
*/
private String resourceId;
/**
* resource type.
*/
private String resourceType;
/**
* resource kind.
*/
private String resourceKind;
/**
* resource uri.
*/
private String resourceUri;
/**
* modification time stamp.
*/
private Date modificationDate;
/**
* original document DOM.
*/
private Document dom;
/**
* xslt transformer instance.
*/
private Transformer transformer;
/**
* construct a DOMOpaqueInstance from a W3C DOM document.
*
* @param dom
* DOM document
* @throws XPathExpressionException
* happens
*/
public DOMOpaqueResource(final Document dom) throws XPathExpressionException {
this.dom = dom;
try {
transformer = TransformerFactory.newInstance().newTransformer();
} catch (TransformerConfigurationException e) {
throw new IllegalStateException("transformer configuration", e);
} catch (TransformerFactoryConfigurationError e) {
throw new IllegalStateException("transformer configuration", e);
}
final XPath xpath = XPathFactory.newInstance().newXPath();
this.resourceId = xpath.evaluate("/RESOURCE_PROFILE/HEADER/RESOURCE_IDENTIFIER/@value", dom);
this.resourceType = xpath.evaluate("/RESOURCE_PROFILE/HEADER/RESOURCE_TYPE/@value", dom);
this.resourceKind = xpath.evaluate("/RESOURCE_PROFILE/HEADER/RESOURCE_KIND/@value", dom);
this.resourceUri = xpath.evaluate("/RESOURCE_PROFILE/HEADER/RESOURCE_URI/@value", dom);
String modificationDateSource = xpath.evaluate("/RESOURCE_PROFILE/HEADER/DATE_OF_CREATION/@value", dom);
try {
this.modificationDate = new DateUtils().parse(modificationDateSource);
} catch (IllegalStateException e) {
log.debug("invalid date '" + modificationDateSource + "'", e);
}
}
/**
* {@inheritDoc}
*
* @see eu.dnetlib.enabling.tools.OpaqueResource#asDom()
*/
@Override
public Document asDom() {
return getDom();
}
/**
* {@inheritDoc}
*
* @see eu.dnetlib.enabling.tools.OpaqueResource#asString()
*/
@Override
public String asString() {
final StringWriter writer = new StringWriter();
try {
transformer.transform(new DOMSource(getDom()), new StreamResult(writer));
} catch (TransformerException e) {
log.fatal("cannot serialize document", e);
return null;
}
return writer.toString();
}
public Document getDom() {
return dom;
}
public void setDom(final Document dom) {
this.dom = dom;
}
@Override
public String getResourceId() {
return resourceId;
}
@Override
public String getResourceType() {
return resourceType;
}
public void setResourceType(final String resourceType) {
this.resourceType = resourceType;
}
@Override
public String getResourceKind() {
return resourceKind;
}
/**
* {@inheritDoc}
*
* @see eu.dnetlib.enabling.tools.OpaqueResource#setResourceKind(java.lang.String)
*/
@Override
public void setResourceKind(final String resourceKind) {
try {
final XPath xpath = XPathFactory.newInstance().newXPath();
final Element kindEl = (Element) xpath.evaluate("/RESOURCE_PROFILE/HEADER/RESOURCE_KIND", asDom(), XPathConstants.NODE);
kindEl.setAttribute(VALUE_ATTR, resourceKind);
this.resourceKind = resourceKind;
} catch (XPathExpressionException e) {
throw new IllegalStateException(XPATH_ERROR, e);
}
}
/**
* {@inheritDoc}
*
* @see eu.dnetlib.enabling.tools.OpaqueResource#setResourceId(java.lang.String)
*/
@Override
public void setResourceId(final String identifier) {
try {
final XPath xpath = XPathFactory.newInstance().newXPath();
final Element idEl = (Element) xpath.evaluate("/RESOURCE_PROFILE/HEADER/RESOURCE_IDENTIFIER", asDom(), XPathConstants.NODE);
idEl.setAttribute(VALUE_ATTR, identifier);
resourceId = identifier;
} catch (XPathExpressionException e) {
throw new IllegalStateException(XPATH_ERROR, e);
}
}
@Override
public Date getModificationDate() {
return modificationDate;
}
/**
* {@inheritDoc}
*
* @see eu.dnetlib.enabling.tools.OpaqueResource#setModificationDate(java.util.Date)
*/
@Override
public void setModificationDate(final Date modificationDate) {
try {
final XPath xpath = XPathFactory.newInstance().newXPath();
final Element idEl = (Element) xpath.evaluate("/RESOURCE_PROFILE/HEADER/DATE_OF_CREATION", asDom(), XPathConstants.NODE);
if (idEl == null) {
log.warn("resource with type " + getResourceType() + " has no date of creation element");
return;
}
idEl.setAttribute(VALUE_ATTR, new DateUtils(modificationDate).getDateAsISO8601String());
this.modificationDate = modificationDate;
} catch (XPathExpressionException e) {
throw new IllegalStateException(XPATH_ERROR, e);
}
}
@Override
public String getResourceUri() {
return resourceUri;
}
/**
* {@inheritDoc}
*
* @see eu.dnetlib.enabling.tools.OpaqueResource#setResourceUri(java.lang.String)
*/
@Override
public void setResourceUri(final String resourceUri) {
try {
final XPath xpath = XPathFactory.newInstance().newXPath();
final Element uriEl = (Element) xpath.evaluate("/RESOURCE_PROFILE/HEADER/RESOURCE_URI", asDom(), XPathConstants.NODE);
uriEl.setAttribute(VALUE_ATTR, resourceUri);
this.resourceUri = resourceUri;
} catch (XPathExpressionException e) {
throw new IllegalStateException(XPATH_ERROR, e);
}
}
public Transformer getTransformer() {
return transformer;
}
public void setTransformer(final Transformer transformer) {
this.transformer = transformer;
}
}

View File

@ -0,0 +1,107 @@
package eu.dnetlib.enabling.tools;
import java.net.MalformedURLException;
import java.net.URL;
import javax.annotation.Resource;
import eu.dnetlib.soap.cxf.StandaloneCxfEndpointReferenceBuilder;
/**
* Assign better scores for near services. Can be configured.
*
* @author marko
*
*/
@Deprecated
public class DefaultServiceLocatorLocationScorer implements DynamicServiceLocatorLocationScorer {
/**
* default score assigned when the other service has the same host.
*/
private static final int LOCAL_HOST_SCORE = 5;
/**
* default score assigned when the other service has the same host and port (same container).
*/
private static final int LOCAL_PORT_SCORE = 10;
/**
* default score assigned when the other service has the same host and port (same container and context).
*/
private static final int LOCAL_SRV_SCORE = 15;
/**
* score assigned when the other service has the same host.
*/
private int localHostScore = LOCAL_HOST_SCORE;
/**
* score assigned when the other service has the same host and port (same container).
*/
private int localPortScore = LOCAL_PORT_SCORE;
/**
* score assigned when the other service has the same host and port (same container and context).
*/
private int localSrvScore = LOCAL_SRV_SCORE;
/**
* build epr.
*/
@Resource
private StandaloneCxfEndpointReferenceBuilder eprBuilder;
/**
* {@inheritDoc}
* @throws MalformedURLException
* @see eu.dnetlib.enabling.tools.DynamicServiceLocatorLocationScorer#score(java.net.URL)
*/
@Override
public int score(final URL url) throws MalformedURLException {
final URL localBase = new URL(eprBuilder.getBaseAddress());
if (url.toString().startsWith(localBase.toString()))
return localSrvScore;
if (localBase.getHost().equals(url.getHost())) {
if (localBase.getPort() == url.getPort())
return localPortScore;
return localHostScore;
}
return 0;
}
public StandaloneCxfEndpointReferenceBuilder getEprBuilder() {
return eprBuilder;
}
public void setEprBuilder(final StandaloneCxfEndpointReferenceBuilder eprBuilder) {
this.eprBuilder = eprBuilder;
}
public int getLocalHostScore() {
return localHostScore;
}
public void setLocalHostScore(final int localHostScore) {
this.localHostScore = localHostScore;
}
public int getLocalPortScore() {
return localPortScore;
}
public void setLocalPortScore(final int localPortScore) {
this.localPortScore = localPortScore;
}
public int getLocalSrvScore() {
return localSrvScore;
}
public void setLocalSrvScore(final int localSrvScore) {
this.localSrvScore = localSrvScore;
}
}

View File

@ -0,0 +1,62 @@
package eu.dnetlib.enabling.tools;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Required;
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.locators.UniqueServiceLocator;
/**
* Locates a registered HNM running on a given url.
*
* @author marko
*
*/
@Deprecated
public class DynamicHNMLocator implements HNMLocator {
/**
* logger.
*/
private static final Log log = LogFactory.getLog(DynamicHNMLocator.class); // NOPMD by marko on 11/24/08 5:02 PM
/**
* service locator.
*/
UniqueServiceLocator serviceLocator;
/**
* {@inheritDoc}
*
* @see eu.dnetlib.enabling.tools.HNMLocator#getHNMForUrl(java.lang.String)
*/
@Override
public String getHNMForUrl(final String url) {
final String prefix = url.substring(0, url.indexOf('/', "http://".length()));
final String query = "collection('')//RESOURCE_PROFILE[.//RESOURCE_TYPE/@value = 'HostingNodeManagerServiceResourceType' and starts-with(.//RESOURCE_URI/@value, '"
+ prefix + "')]//RESOURCE_IDENTIFIER/@value/string()";
try {
return serviceLocator.getService(ISLookUpService.class).getResourceProfileByQuery(query);
} catch (final ISLookUpDocumentNotFoundException e) {
log.debug("doument not found for query: " + query);
return null;
} catch (final ISLookUpException e) {
throw new IllegalStateException("cannot search hnm", e);
}
}
public UniqueServiceLocator getServiceLocator() {
return serviceLocator;
}
@Required
public void setServiceLocator(UniqueServiceLocator serviceLocator) {
this.serviceLocator = serviceLocator;
}
}

View File

@ -0,0 +1,182 @@
package eu.dnetlib.enabling.tools;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.Resource;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.ws.wsaddressing.W3CEndpointReference;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Required;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpException;
import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService;
import eu.dnetlib.enabling.tools.registration.ServiceNameResolver;
import eu.dnetlib.miscutils.collections.EnsureCollection;
import eu.dnetlib.soap.cxf.StandaloneCxfEndpointReferenceBuilder;
/**
* Enumerates all services of a given type.
*
* @author marko
*
* @param <T>
* service class
*/
@Deprecated
public class DynamicServiceEnumerator<T> implements ServiceEnumerator<T> {
/**
* logger.
*/
private static final Log log = LogFactory.getLog(DynamicServiceEnumerator.class); // NOPMD by marko on 11/24/08 5:02 PM
/**
* service class
*/
private Class<T> clazz;
/**
* lookup locator.
*/
private ServiceLocator<ISLookUpService> lookUpLocator;
/**
* service name resolver.
*/
@Resource
private ServiceNameResolver serviceNameResolver; // NOPMD
/**
* build epr.
*/
@Resource
private StandaloneCxfEndpointReferenceBuilder eprBuilder;
/**
* default constructor, useful for spring based instantiation.
*/
public DynamicServiceEnumerator() {
// default
}
/**
* Build a dynamic service enumerator for a given class
*
* @param clazz
* class
*/
public DynamicServiceEnumerator(final Class<T> clazz) {
super();
this.clazz = clazz;
}
/**
* {@inheritDoc}
*
* @see eu.dnetlib.enabling.tools.ServiceEnumerator#getServices()
*/
@Override
public List<ServiceRunningInstance<T>> getServices() {
final String serviceName = serviceNameResolver.getName(clazz);
log.debug("searching for service: " + serviceName);
final String xquery = "for $x in collection('/db/DRIVER/ServiceResources')//RESOURCE_PROFILE[.//RESOURCE_TYPE/@value/string() = '"
+ serviceName
+ "ResourceType'] return <service><id>{$x//RESOURCE_IDENTIFIER/@value/string()}</id><url>{$x//PROTOCOL[@name = 'SOAP']/@address/string()}</url><properties>{$x//SERVICE_PROPERTIES/PROPERTY}</properties></service>";
log.debug(xquery);
final XPathFactory factory = XPathFactory.newInstance();
final XPath xpath = factory.newXPath();
final DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
try {
final DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
final List<String> services = lookUpLocator.getService().quickSearchProfile(xquery);
final List<ServiceRunningInstance<T>> instances = new ArrayList<ServiceRunningInstance<T>>();
for (final String source : EnsureCollection.list(services)) {
final Document doc = docBuilder.parse(new InputSource(new StringReader(source)));
final String url = xpath.evaluate("//url", doc);
final String serviceId = xpath.evaluate("//id", doc);
final NodeList propElements = (NodeList) xpath.evaluate("//PROPERTY", doc, XPathConstants.NODESET);
Map<String, String> props = new HashMap<String, String>();
for (int i = 0; i < propElements.getLength(); i++) {
Element propElement = (Element) propElements.item(i);
props.put(propElement.getAttribute("key"), propElement.getAttribute("value"));
}
final W3CEndpointReference epr = eprBuilder.getEndpointReference(url, null, null, url + "?wsdl", null, null);
instances.add(new ServiceRunningInstance<T>(epr, serviceId, url, props));
}
return instances;
} catch (final ISLookUpException e) {
throw new IllegalStateException("cannot locate service " + serviceName, e);
} catch (final XPathExpressionException e) {
throw new IllegalStateException("cannot locate service " + serviceName, e);
} catch (final SAXException e) {
throw new IllegalStateException("cannot locate service " + serviceName, e);
} catch (final IOException e) {
throw new IllegalStateException("cannot locate service " + serviceName, e);
} catch (final ParserConfigurationException e) {
throw new IllegalStateException("cannot locate service " + serviceName, e);
}
}
public Class<T> getClazz() {
return clazz;
}
@Required
public void setClazz(final Class<T> clazz) {
this.clazz = clazz;
}
public ServiceLocator<ISLookUpService> getLookUpLocator() {
return lookUpLocator;
}
public void setLookUpLocator(final ServiceLocator<ISLookUpService> lookUpLocator) {
this.lookUpLocator = lookUpLocator;
}
public ServiceNameResolver getServiceNameResolver() {
return serviceNameResolver;
}
public void setServiceNameResolver(final ServiceNameResolver serviceNameResolver) {
this.serviceNameResolver = serviceNameResolver;
}
public StandaloneCxfEndpointReferenceBuilder getEprBuilder() {
return eprBuilder;
}
public void setEprBuilder(StandaloneCxfEndpointReferenceBuilder eprBuilder) {
this.eprBuilder = eprBuilder;
}
}

View File

@ -0,0 +1,205 @@
package eu.dnetlib.enabling.tools;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Required;
import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService;
import eu.dnetlib.enabling.tools.registration.ServiceNameResolver;
import eu.dnetlib.soap.cxf.StandaloneCxfEndpointReferenceBuilder;
/**
* Locates a service through dynamic service discovery.
*
* @author marko
*
* @param <T>
*/
@Deprecated
public class DynamicServiceLocator<T> extends AbstractServiceLocator<T> {
/**
* logger.
*/
private static final Log log = LogFactory.getLog(DynamicServiceLocator.class); // NOPMD by marko on 11/24/08 5:02 PM
/**
* service interface.
*/
private Class<T> clazz;
/**
* lookup locator.
*/
private ServiceLocator<ISLookUpService> lookUpLocator;
/**
* service name resolver.
*/
@Resource
private ServiceNameResolver serviceNameResolver; // NOPMD
/**
* build epr.
* TODO: obsolete, replace by full enumerator injection
*/
@Resource
private StandaloneCxfEndpointReferenceBuilder eprBuilder;
/**
* service resolver. used to create proxies for discovered services.
*/
private ServiceResolver serviceResolver;
/**
* delegate the score computation to this component. By default use a DefaultServiceLocatorLocationScorer.
*/
private DynamicServiceLocatorLocationScorer scorer;
/**
* service enumerator.
*/
private ServiceEnumerator<T> enumerator;
/**
* By default use a DefaultServiceLocatorLocationScorer if no scorer is defined.
*/
@PostConstruct
protected void init() {
if (scorer == null) {
final DefaultServiceLocatorLocationScorer tmp = new DefaultServiceLocatorLocationScorer();
tmp.setEprBuilder(eprBuilder);
scorer = tmp;
}
if (enumerator == null) {
final DynamicServiceEnumerator<T> tmp = new DynamicServiceEnumerator<T>(clazz);
tmp.setLookUpLocator(lookUpLocator);
tmp.setServiceNameResolver(serviceNameResolver);
tmp.setEprBuilder(eprBuilder);
enumerator = tmp;
}
}
/**
* {@inheritDoc}
*
* @see eu.dnetlib.enabling.tools.ServiceLocator#getService()
*/
@Override
public T getService() {
return serviceResolver.getService(clazz, findFirstCandidate().getEpr());
}
@Override
public String getServiceId() {
return findFirstCandidate().getServiceId();
}
private ServiceRunningInstance<T> findFirstCandidate() {
final String serviceName = serviceNameResolver.getName(clazz);
log.debug("searching for service: " + serviceName);
// TODO: backward compat hack
if(enumerator == null) {
log.warn("Enumerator is null in " + this + ". Postconstruct not called by spring, please check. Now called manually to workaround this problem");
init();
}
final List<ServiceRunningInstance<T>> candidates = enumerator.getServices();
if (candidates == null || candidates.isEmpty())
throw new IllegalStateException("cannot locate service " + serviceName + ", no matching service profile found");
Collections.sort(candidates, new Comparator<ServiceRunningInstance<T>>() {
@Override
public int compare(final ServiceRunningInstance<T> o1, final ServiceRunningInstance<T> o2) {
try {
final Integer u1Score = computeScore(new URL(o1.getUrl()));
final Integer u2Score = computeScore(new URL(o2.getUrl()));
return -u1Score.compareTo(u2Score);
} catch (MalformedURLException e) {
log.warn("ignoring service with malformed url", e);
return 0;
}
}
});
log.debug(candidates);
return candidates.get(0);
}
/**
* compute the score for a given service url.
*
* @param url
* url to be scored
* @return score
* @throws MalformedURLException
* happens
*/
protected int computeScore(final URL url) throws MalformedURLException {
return scorer.score(url);
}
public Class<T> getClazz() {
return clazz;
}
@Required
public void setClazz(final Class<T> clazz) {
this.clazz = clazz;
}
public ServiceLocator<ISLookUpService> getLookUpLocator() {
return lookUpLocator;
}
@Required
public void setLookUpLocator(final ServiceLocator<ISLookUpService> lookUpLocator) {
this.lookUpLocator = lookUpLocator;
}
public ServiceNameResolver getServiceNameResolver() {
return serviceNameResolver;
}
public void setServiceNameResolver(final ServiceNameResolver serviceNameResolver) { // NOPMD
this.serviceNameResolver = serviceNameResolver;
}
public StandaloneCxfEndpointReferenceBuilder getEprBuilder() {
return eprBuilder;
}
public void setEprBuilder(final StandaloneCxfEndpointReferenceBuilder eprBuilder) {
this.eprBuilder = eprBuilder;
}
@Required
public ServiceResolver getServiceResolver() {
return serviceResolver;
}
public void setServiceResolver(final ServiceResolver serviceResolver) {
this.serviceResolver = serviceResolver;
}
public DynamicServiceLocatorLocationScorer getScorer() {
return scorer;
}
public void setScorer(final DynamicServiceLocatorLocationScorer scorer) {
this.scorer = scorer;
}
}

View File

@ -0,0 +1,21 @@
package eu.dnetlib.enabling.tools;
import java.net.MalformedURLException;
import java.net.URL;
/**
* Implementors of this interface provide custom methods to assign scores to services based solely on their location.
* @author marko
*
*/
@Deprecated
public interface DynamicServiceLocatorLocationScorer {
/**
* Compute the score assigned to a given service location (url).
*
* @param url service url
* @return score (the higher the better)
* @throws MalformedURLException could happen
*/
int score(URL url) throws MalformedURLException;
}

View File

@ -0,0 +1,19 @@
package eu.dnetlib.enabling.tools;
/**
* finds an HNM profile for a giver service url.
*
* @author marko
*
*/
public interface HNMLocator {
/**
* finds an HNM profile for a giver service url.
*
* @param url
* service address
* @return hnm id
*/
String getHNMForUrl(String url);
}

View File

@ -0,0 +1,25 @@
package eu.dnetlib.enabling.tools;
import javax.xml.ws.WebServiceFeature;
import javax.xml.ws.wsaddressing.W3CEndpointReference;
/**
* This service resolver asks jaxws to obtain a proxy to a remote service.
*
* @author marko
*
*/
public class JaxwsServiceResolverImpl extends AbstractServiceResolverImpl implements ServiceResolver {
/**
* {@inheritDoc}
* @see eu.dnetlib.enabling.tools.ServiceResolver#getService(java.lang.Class, javax.xml.ws.wsaddressing.W3CEndpointReference)
*/
@Override
public <T> T getService(final Class<T> clazz, final W3CEndpointReference epr) {
synchronized(this) {
return epr.getPort(clazz, new WebServiceFeature[] {});
}
}
}

View File

@ -0,0 +1,91 @@
package eu.dnetlib.enabling.tools;
import java.io.StringReader;
import java.util.Map;
import javax.xml.ws.wsaddressing.W3CEndpointReference;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.xml.sax.InputSource;
/**
* This service resolver parses the EPR and returns a local reference to a service instance if the EPR refers to the
* local node.
*
* @author marko
*
*/
public class LocalServiceResolverImpl extends AbstractServiceResolverImpl implements ServiceResolver, ApplicationContextAware {
private static final Log log = LogFactory.getLog(LocalServiceResolverImpl.class); // NOPMD by marko on 11/24/08 5:02 PM
private String baseAddress;
private ApplicationContext applicationContext;
/**
* {@inheritDoc}
*
* @see eu.dnetlib.enabling.tools.ServiceResolver#getService(java.lang.Class,
* javax.xml.ws.wsaddressing.W3CEndpointReference)
*/
@Override
public <T> T getService(final Class<T> clazz, final W3CEndpointReference epr) {
// backward compat
if (baseAddress == null) {
log.warn("please set baseAddress in " + this);
return null;
}
try {
// TODO: measure performance impact of this. I wrote it this way just to be sure of thread safety
String address = XPathFactory.newInstance().newXPath().evaluate("/*[local-name() ='EndpointReference']/*[local-name() = 'Address']",
new InputSource(new StringReader(epr.toString())));
if (log.isDebugEnabled())
log.debug("epr address " + address);
if (address.startsWith(baseAddress))
return resolveLocalService(clazz, epr);
} catch (XPathExpressionException e) {
log.warn("cannot parse epr", e);
}
return null;
}
private <T> T resolveLocalService(final Class<T> clazz, W3CEndpointReference epr) {
log.debug("resolving local service " + clazz);
Map<String, T> services = (Map<String, T>) applicationContext.getBeansOfType(clazz, false, false);
log.debug("found services: " + services);
if(services.size() > 0)
for(T service : services.values())
return service;
return null;
}
public String getBaseAddress() {
return baseAddress;
}
public void setBaseAddress(String baseAddress) {
this.baseAddress = baseAddress;
}
public ApplicationContext getApplicationContext() {
return applicationContext;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
}

View File

@ -0,0 +1,21 @@
package eu.dnetlib.enabling.tools;
/**
* simplest HNM locator: doesn't find any.
*
* @author marko
*
*/
public class NullHNMLocator implements HNMLocator {
/**
* {@inheritDoc}
*
* @see eu.dnetlib.enabling.tools.HNMLocator#getHNMForUrl(java.lang.String)
*/
@Override
public String getHNMForUrl(final String url) {
return "";
}
}

View File

@ -0,0 +1,98 @@
package eu.dnetlib.enabling.tools;
import java.util.Date;
import org.w3c.dom.Document;
/**
* Some services, in particular the enabling layer, needs to manipulate all types of resources without knowing the exact
* structure of their content, but only some well defined properties defined here.
*
* <p>
* Different wrappers can be provided for different kind of resources. For example resources returned from the xmldb
* layer can be cheaply mapped to an OpaqueResource, without going to full xml->bean conversion.
* </p>
*
* @author marko
*
*/
public interface OpaqueResource {
/**
* Resource type.
*
* @return resource type string
*/
String getResourceType();
/**
* Resource kind.
*
* @return resource kind string
*/
String getResourceKind();
/**
* Resource identifier.
*
* @return resource identifier string
*/
String getResourceId();
/**
* Resource URI.
*
* @return resource uri string
*/
String getResourceUri();
/**
* get modification time stamp.
*
* @return time stamp
*/
Date getModificationDate();
/**
* Implementors may need to serialize the resource to a xml string representation.
*
* @return xml serialization
*/
String asString();
/**
* Implementors may store the DOM in the first place. Otherwise they should
* return a parsed w3c DOM instance.
*
* @return DOM document
*/
Document asDom();
/**
* change the resource identifier.
*
* @param identifier new identifier
*/
void setResourceId(String identifier);
/**
* change the resource kind.
*
* @param kind new kind
*/
void setResourceKind(String kind);
/**
* change the resource uri.
*
* @param uri new uri
*/
void setResourceUri(String uri);
/**
* set modification timestamp.
*
* @param timeStamp modification time stamp
*/
void setModificationDate(Date timeStamp);
}

View File

@ -0,0 +1,30 @@
package eu.dnetlib.enabling.tools;
/**
* Resource identifiers may carry, implicitly or explicity, some informations about the location of the resource in the
* hierarchical xmldb namespace.
*
* Implementors of this interface may take different approachs to the problem.
*
* @author marko
*
*/
public interface ResourceIdentifierResolver {
/**
* get the xmldb filename associated to this resource identifier, usually extracted from the identifier itself.
*
* @param resId resource identifier
* @return xmldb file name
*/
String getFileName(String resId);
/**
* get the xmldb collection name associated to this resource identifier.
* Implementors may decide to encode it in the identifier itself or use a secondary associative memory.
* to quickly transform identifiers.
*
* @param resId resource identifier
* @return xmldb collection name
*/
String getCollectionName(String resId);
}

View File

@ -0,0 +1,44 @@
package eu.dnetlib.enabling.tools;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternUtils;
/**
* Some beans aren't directly instantiated (like quartz jobs for instance), so they cannot receive the resource loader
* by implementing the ResourceLoaderAware interface.
*
* This class is a temporary solution to this problem until we find a way to obtain a bean reference to the
* application context (the actual resource loader) itself and inject it directly. It could be done by turning this
* class into a bean factory and expose the resource loader through it.
*
* @author marko
*
*/
public class ResourceLoaderHelper implements ResourceLoaderAware {
/**
* injected resource loader.
*/
private ResourceLoader resourceLoader;
/**
* obtain a resource pattern resolver for a given resource loader.
*
* @return pattern resolver
*/
public ResourcePatternResolver getResourcePatternResolver() {
return ResourcePatternUtils.getResourcePatternResolver(getResourceLoader());
}
public ResourceLoader getResourceLoader() {
return resourceLoader;
}
@Override
public void setResourceLoader(final ResourceLoader resourceLoader) {
this.resourceLoader = resourceLoader;
}
}

View File

@ -0,0 +1,19 @@
package eu.dnetlib.enabling.tools;
import java.util.List;
/**
* A service enumerator returns a bunch of service descriptions. The logic depends on the service enumerator.
*
* @author marko
*
*/
@Deprecated
public interface ServiceEnumerator<T> {
/**
* Obtain a list of services.
*
* @return a list of service running instance descriptions
*/
List<ServiceRunningInstance<T>> getServices();
}

View File

@ -0,0 +1,47 @@
package eu.dnetlib.enabling.tools;
/**
* A service locator provides a reference to a, possibly remote, service.
*
* @author marko
*
* @param <T>
* the type of the service to return
* @deprecated As of release 2.0.0, use instead {@link eu.dnetlib.enabling.locators.DefaultUniqueServiceLocator}
*/
@Deprecated
public interface ServiceLocator<T> {
/**
* locate and return a service of this type.
*
* @return a service client instance
*/
T getService();
/**
* Locate using a profileID (service or datastructure) the service of this type.
*
* @param profileId
* @param clazz
* @return a service client instance
*/
T getService(final String profileId, final Class<T> clazz);
/**
* locate and return a service ID.
*
* @return a service ID
*/
String getServiceId();
/**
* locate and return a service ID.
*
* @param profileId
* (the id of the service or the id of one of its datastructures)
* @return a service ID.
*/
String getServiceId(final String profileId);
}

View File

@ -0,0 +1,69 @@
package eu.dnetlib.enabling.tools;
import java.util.Collection;
/**
* This class allows chaining several service locators and return the first one matching. Usually this is usefully when
* we want a StaticLocator as a fallback if the DynamicLocator cannot find anything.
*
* @author marko
*
* @param <T>
* service type
*/
@Deprecated
public class ServiceLocatorChain<T> extends AbstractServiceLocator<T> {
/**
* service locators, iterated in order.
*/
private Collection<ServiceLocator<T>> locators;
/**
* {@inheritDoc}
*
* @see eu.dnetlib.enabling.tools.ServiceLocator#getService()
*/
@Override
public T getService() {
IllegalStateException lastException = null; // NOPMD
for (ServiceLocator<T> locator : locators) {
try {
return locator.getService();
} catch (IllegalStateException e) {
lastException = e;
}
}
if (lastException != null) {
throw new IllegalStateException("cannot find any matching service. Last locator in the chain reported as cause", lastException);
}
throw new IllegalStateException("cannot find any matching service: the service locator chain is empty");
}
@Override
public String getServiceId() {
IllegalStateException lastException = null; // NOPMD
for (ServiceLocator<T> locator : locators) {
try {
return locator.getServiceId();
} catch (IllegalStateException e) {
lastException = e;
}
}
if (lastException != null) {
throw new IllegalStateException("cannot find any matching service. Last locator in the chain reported as cause", lastException);
}
throw new IllegalStateException("cannot find any matching service: the service locator chain is empty");
}
public Collection<ServiceLocator<T>> getLocators() {
return locators;
}
public void setLocators(final Collection<ServiceLocator<T>> locators) {
this.locators = locators;
}
}

View File

@ -0,0 +1,32 @@
package eu.dnetlib.enabling.tools;
import javax.xml.ws.wsaddressing.W3CEndpointReference;
/**
* Instances of this type resolve EPR references to service endpoints.
*
* @author marko
*
*/
public interface ServiceResolver {
/**
* return a service client given an EPR instance.
*
* @param <T>
* the service type
* @param clazz
* needed for type inference of type parameter <T>
* @param epr
* EPR
* @return a service client reference
*/
<T> T getService(Class<T> clazz, W3CEndpointReference epr);
/**
* Extract the resource identifier embedded in the EPR.
*
* @param epr end point reference
* @return resource identifier
*/
String getResourceIdentifier(W3CEndpointReference epr);
}

View File

@ -0,0 +1,61 @@
package eu.dnetlib.enabling.tools;
import java.util.ArrayList;
import java.util.List;
import javax.xml.ws.wsaddressing.W3CEndpointReference;
/**
* This resolver chains a list of resolvers.
*
* @author marko
*
*/
public class ServiceResolverChain implements ServiceResolver {
/**
* service resolvers in decreasing order or priority.
*/
private List<ServiceResolver> resolvers = new ArrayList<ServiceResolver>();
/**
* {@inheritDoc}
*
* @see eu.dnetlib.enabling.tools.ServiceResolver#getService(java.lang.Class,
* javax.xml.ws.wsaddressing.W3CEndpointReference)
*/
@Override
public <T> T getService(final Class<T> clazz, final W3CEndpointReference epr) {
for (ServiceResolver resolver : getResolvers()) {
final T service = resolver.getService(clazz, epr);
if (service != null)
return service;
}
return null;
}
/**
* {@inheritDoc}
* @see eu.dnetlib.enabling.tools.ServiceResolver#getResourceIdentifier(javax.xml.ws.wsaddressing.W3CEndpointReference)
*/
@Override
public String getResourceIdentifier(final W3CEndpointReference epr) {
for (ServiceResolver resolver : getResolvers()) {
final String rsId = resolver.getResourceIdentifier(epr);
if (rsId != null)
return rsId;
}
return null;
}
public List<ServiceResolver> getResolvers() {
return resolvers;
}
public void setResolvers(final List<ServiceResolver> resolvers) {
this.resolvers = resolvers;
}
}

View File

@ -0,0 +1,95 @@
package eu.dnetlib.enabling.tools;
import java.util.HashMap;
import java.util.Map;
import javax.xml.ws.wsaddressing.W3CEndpointReference;
/**
* This bean packages the minimum information for describing a service running instance.
*
* @author marko
*
*/
@Deprecated
public class ServiceRunningInstance<T> {
/**
* service endpoint.
*/
private W3CEndpointReference epr;
/**
* service resource id.
*/
private String serviceId;
/**
* service endpoint url.
*/
private String url;
/**
* arbitrary service properties stored in the profile.
*/
private Map<String, String> serviceProperties;
/**
* Create a service running instance.
*
* @param epr service epr
* @param serviceId service profile resource id
* @param url service endpoint url
*/
public ServiceRunningInstance(final W3CEndpointReference epr, final String serviceId, final String url) {
this(epr, serviceId, url, new HashMap<String, String>());
}
/**
* Create a service running instance.
*
* @param epr service epr
* @param serviceId service profile resource id
* @param url service endpoint url
* @param serviceProperties service property map
*/
public ServiceRunningInstance(final W3CEndpointReference epr, final String serviceId, final String url, final Map<String, String> serviceProperties) {
super();
this.epr = epr;
this.serviceId = serviceId;
this.url = url;
this.serviceProperties = serviceProperties;
}
public W3CEndpointReference getEpr() {
return epr;
}
public void setEpr(final W3CEndpointReference epr) {
this.epr = epr;
}
public String getServiceId() {
return serviceId;
}
public void setServiceId(final String serviceId) {
this.serviceId = serviceId;
}
public Map<String, String> getServiceProperties() {
return serviceProperties;
}
public void setServiceProperties(final Map<String, String> serviceProperties) {
this.serviceProperties = serviceProperties;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
}

View File

@ -0,0 +1,171 @@
package eu.dnetlib.enabling.tools;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Required;
import com.google.common.collect.Lists;
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.locators.UniqueServiceLocator;
import eu.dnetlib.miscutils.collections.PositionalStringMapGenerator;
/**
* Utility class which interacts with a lookup, performs a query and fills a java domain object splitting the result into constructor
* arguments.
*
* @author marko
*
*/
public class SplittedQueryExecutor {
/**
* service locator.
*/
private UniqueServiceLocator serviceLocator;
/**
* default constructor. lookupLocator has to be injected.
*/
public SplittedQueryExecutor() {
// empty
}
/**
* Commodity constructor for constructor injection.
*
* @param lookupLocator
* lookup locator
*/
public SplittedQueryExecutor(final UniqueServiceLocator serviceLocator) {
super();
this.serviceLocator = serviceLocator;
}
/**
* Performs the query, splits the result at ":-:".
*
* @param <X>
* domain class type
* @param clazz
* domain class
* @param query
* xquery
* @return iterable of domain class instances
*/
public <X> Iterable<X> query(final Class<X> clazz, final String query) {
return query(clazz, query, ":-:");
}
/**
* Performs the query, splits the result at separator
*
* @param <X>
* domain class type
* @param clazz
* domain class
* @param query
* xquery
* @param separator
* split separator
* @return iterable of domain class instances
*/
public <X> Iterable<X> query(final Class<X> clazz, final String query, final String separator) {
return new PositionalStringMapGenerator<String>().split(clazz, performQuery(query), separator);
}
/**
* Return a list of maps of splitted query results
*
* @param query
* xquery
* @param keys
* list of keys
* @return collection of key/value pairs
*/
public Iterable<Map<String, String>> query(final String query, final String... keys) {
return new PositionalStringMapGenerator<String>(keys).split(performQuery(query), ":-:");
}
/**
* Like query(String, String..) but returns a container that whose values can be modified.
*
* @param query
* xquery
* @param keys
* list of keys
* @return mutable collection of key/value pairs
*/
public Iterable<Map<String, String>> mutableQuery(final String query, final String... keys) {
return Lists.newArrayList(query(query, keys));
}
/**
* Like query(Class, String), but returns a container which can be modified.
*
* @param <X>
* some domain class
* @param clazz
* domain class
* @param query
* xquery
* @return mutable collection of X
*/
public <X> Iterable<X> mutableQuery(final Class<X> clazz, final String query) {
return Lists.newArrayList(query(clazz, query));
}
/**
* Like query(Class, String, String), but returns a container which can be modified.
*
* @param <X>
* some domain class
* @param clazz
* domain class
* @param query
* xquery
* @param separator
* separator
* @return mutable collection of X
*/
public <X> Iterable<X> mutableQuery(final Class<X> clazz, final String query, final String separator) {
return Lists.newArrayList(query(clazz, query, separator));
}
public List<String> performQuery(final String query) {
try {
return serviceLocator.getService(ISLookUpService.class).quickSearchProfile(query);
} catch (final ISLookUpException e) {
throw new IllegalStateException(e);
}
}
/**
* Fetch only one string result.
*
* @param query
* @return null if no such result
*/
public String queryFirst(final String query) {
try {
return serviceLocator.getService(ISLookUpService.class).getResourceProfileByQuery(query);
} catch (ISLookUpDocumentNotFoundException e) {
return null;
} catch (final ISLookUpException e) {
throw new IllegalStateException(e);
}
}
public UniqueServiceLocator getServiceLocator() {
return serviceLocator;
}
@Required
public void setServiceLocator(final UniqueServiceLocator serviceLocator) {
this.serviceLocator = serviceLocator;
}
}

View File

@ -0,0 +1,91 @@
package eu.dnetlib.enabling.tools;
import java.util.Map;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Required;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import eu.dnetlib.enabling.tools.registration.ServiceRegistrationManager;
/**
* This service locator returns always one service instance.
*
* Usually declared as a spring bean an injected in service when a static configuration is needed.
*
* @author marko
*
* @param <T>
* the type of the service
*/
@Deprecated
public class StaticServiceLocator<T> extends AbstractServiceLocator<T> implements ApplicationContextAware {
/**
* static service reference.
*/
private T service;
private ApplicationContext applicationContext;
/**
* default constructor. initialize with setter.
*/
public StaticServiceLocator() {
// no operation
}
/**
* construct a static service locator pointing at a given service.
*
* @param service
* service
*/
public StaticServiceLocator(final T service) {
this.service = service;
}
/**
* The usual usage pattern of service locators is to call chain a direct call
* on the result of this method. In order to avoid nullpointer exception, this method throws an exception
* with a better explanation, in case the service is null.
*
* TODO: consider using checked exceptions.
*
* {@inheritDoc}
* @see eu.dnetlib.enabling.tools.ServiceLocator#getService()
*/
@Override
public T getService() {
if (service == null) {
throw new IllegalStateException("cannot find service, check configuration");
}
return service;
}
@Override
public String getServiceId() {
final Map<String, ServiceRegistrationManager> beans = applicationContext.getBeansOfType(ServiceRegistrationManager.class);
if (beans != null) {
for (ServiceRegistrationManager r : beans.values()) {
if (r.getService() == getService()) {
return r.getServiceProfile().getResourceId();
}
}
}
throw new IllegalStateException("cannot find service, check configuration");
}
@Required
public void setService(final T service) {
this.service = service;
}
@Override
public void setApplicationContext(final ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}

View File

@ -0,0 +1,54 @@
package eu.dnetlib.enabling.tools; // NOPMD
import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPathExpressionException;
import org.apache.commons.io.IOUtils;
import org.xml.sax.SAXException;
/**
* implements a possibly optimized OpaqueResource constructed from a stream containing the xml source.
*
* <p>the optimization consists of postponing the parsing as possibly and parse the profile passing the stream
* directly to the xml parser.<p>
*
* <p>
* TODO: implement the optimization, currenly converts to string and reuses StringOpaqueResource
* </p>
*
* @author marko
*
*/
public class StreamOpaqueResource extends StringOpaqueResource {
/**
* construct with an input stream.
*
* @param source source stream of xml text
* @throws XPathExpressionException shouldn't happen
* @throws SAXException could happen
* @throws IOException could happen
* @throws ParserConfigurationException shouldn't happen
*/
public StreamOpaqueResource(final InputStream source) throws XPathExpressionException, SAXException, IOException, ParserConfigurationException {
super(stringify(source));
}
/**
* helper method: reads a stream to a string.
*
* @param source input stream
* @return string containing the whole stream content.
* @throws IOException could happen.
*/
private static String stringify(final InputStream source) throws IOException {
final StringWriter writer = new StringWriter();
IOUtils.copy(source, writer);
return writer.getBuffer().toString();
}
}

View File

@ -0,0 +1,48 @@
package eu.dnetlib.enabling.tools; // NOPMD
import java.io.IOException;
import java.io.StringReader;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPathExpressionException;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
/**
* Opaque resource initialized from a string.
*
* Currently it extends a DOMOpaqueResource, but in future it should postpone xml parsing as late as possible.
*
* @author marko
*
*/
public class StringOpaqueResource extends DOMOpaqueResource {
/**
* construct an opaque resource from a xml source string.
*
* @param source xml source
* @throws XPathExpressionException happens
* @throws SAXException happens
* @throws IOException happens
* @throws ParserConfigurationException happens
*/
public StringOpaqueResource(final String source) throws XPathExpressionException, SAXException, IOException, ParserConfigurationException {
super(getBuilderFactory().newDocumentBuilder().parse(new InputSource(new StringReader(source))));
}
/**
* get a namespace aware document builder factory.
*
* @return document builder factory.
*/
private static DocumentBuilderFactory getBuilderFactory() {
final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
return factory;
}
}

View File

@ -0,0 +1,25 @@
package eu.dnetlib.enabling.tools;
/**
* genrate unique identifiers.
*
* @author marko
*
*/
public interface UniqueIdentifierGenerator {
/**
* generate a new unique identifier.
*
* @return string identifier
*/
String generateIdentifier();
/**
* helps identify valid identifiers.
*
* @return string regex
*/
String getRegEx();
}

View File

@ -0,0 +1,74 @@
package eu.dnetlib.enabling.tools;
import java.util.UUID;
/**
* generates unique UUID identifiers.
*
* @author marko
*
*/
public class UniqueIdentifierGeneratorImpl implements UniqueIdentifierGenerator {
/**
* helps identify valid identifiers.
*/
public static final String UUID_REGEX = "[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}";
/**
* prefixes all identifiers with this string.
*/
private String prefix = "";
/**
* create a new instance with an empty prefix.
*/
public UniqueIdentifierGeneratorImpl() {
//
}
/**
* construct a new instance with a given prefix.
*
* @param prefix prefix
*/
public UniqueIdentifierGeneratorImpl(final String prefix) {
this.prefix = prefix;
}
public String getPrefix() {
return prefix;
}
public void setPrefix(final String prefix) {
this.prefix = prefix;
}
/**
* {@inheritDoc}
*
* @see eu.dnetlib.enabling.tools.UniqueIdentifierGenerator#generateIdentifier()
*/
@Override
public String generateIdentifier() {
return prefix + createUUID();
}
/**
* the real job of creating the uuid is here.
*
* @return new uuid
*/
private String createUUID() {
return UUID.randomUUID().toString();
}
/**
* {@inheritDoc}
* @see eu.dnetlib.enabling.tools.UniqueIdentifierGenerator#getRegEx()
*/
@Override
public String getRegEx() {
return UUID_REGEX;
}
}

View File

@ -0,0 +1,39 @@
package eu.dnetlib.enabling.tools;
/**
* Implementations of this interface will provide functionalities useful to create xqueries or parts of thereof, like
* xmldb collection names for a given profile.
*
* @author marko
*
*/
public interface XQueryUtils {
/**
* obtain the name of the xmldb collection for a given resource.
* @param resource resource
* @return path of the collection relative to the xmldb dnet root.
*/
String getCollectionPath(OpaqueResource resource);
/**
* obtain the absolute xmldb collection path for a given resource.
* @param resource resource
* @return collection absolute path
*/
String getCollectionAbsPath(OpaqueResource resource);
/**
* get the absolute xmldb collection path.
*
* @return root xmldb root collection path
*/
String getRootCollection();
/**
* Return the xmldb filename for a given resource.
*
* @param resource resource
* @return xmldb filename
*/
String getFileName(OpaqueResource resource);
}

View File

@ -0,0 +1,40 @@
package eu.dnetlib.enabling.tools.registration;
import javax.xml.ws.Endpoint;
import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService;
import eu.dnetlib.enabling.is.sn.rmi.ISSNService;
import eu.dnetlib.enabling.tools.OpaqueResource;
import eu.dnetlib.enabling.tools.StringOpaqueResource;
/**
* This service registrator also subscribes the service to it's own blackboard.
*
* XXX: this class is a hack. It only works with the ValidatingServiceRegistrationManager
*
* @author marko
*
*/
public class BlackboardServiceRegistrator extends ServiceRegistrator {
/**
* {@inheritDoc}
*
* @see eu.dnetlib.enabling.tools.registration.ServiceRegistrator#validateProfile(java.lang.String)
*/
@Override
public String validateProfile(final String profId, final Endpoint endpoint) {
final String profileId = super.validateProfile(profId, endpoint);
try {
final OpaqueResource serviceProfile = new StringOpaqueResource(getServiceLocator().getService(ISLookUpService.class).getResourceProfile(profileId));
getServiceLocator().getService(ISSNService.class, true).subscribe(getEprBuilder().getEndpointReference(endpoint),
"UPDATE/" + serviceProfile.getResourceType() + "/" + profileId + "/RESOURCE_PROFILE/BODY/BLACKBOARD/LAST_REQUEST", 0);
} catch (Exception e) {
throw new IllegalStateException("cannot validate service profile", e);
}
return profileId;
}
}

View File

@ -0,0 +1,74 @@
package eu.dnetlib.enabling.tools.registration;
import java.lang.annotation.Annotation;
import javax.jws.WebService;
/**
* This service name resolver tries to find the real service name through various heuristics based on the existence of the WebService
* annotation on some interface the service implements.
*
* <p>
* NOTE: The search for the interface is depth first on interfaces and then on subclasses.
* </p>
*
* @author marko
*
*/
public class InterfaceServiceNameResolver implements ServiceNameResolver {
/**
* {@inheritDoc}
*
* @see eu.dnetlib.enabling.tools.registration.ServiceNameResolver#getName(java.lang.Object)
*/
@Override
public String getName(final Object service) {
Class<?> res = findInterface(WebService.class, service.getClass());
if (res == null) {
res = service.getClass();
}
return getName(res);
}
/**
* {@inheritDoc}
*
* @see eu.dnetlib.enabling.tools.registration.ServiceNameResolver#getName(java.lang.Class)
*/
@Override
public String getName(final Class<?> iface) {
return iface.getSimpleName();
}
/**
* recursively searches a given annotation and returns the class/interface which contains it.
*
* @param <T>
* annotation type
* @param annotation
* annotation to search
* @param clazz
* root of the class hierarchy.
* @return class which contains annotation 'annotation'
*/
private <T extends Annotation> Class<?> findInterface(final Class<T> annotation, final Class<?> clazz) {
if (clazz == null) return null;
final T ann = clazz.getAnnotation(annotation);
if ((ann != null) && clazz.isInterface()) return clazz;
for (Class<?> iface : clazz.getInterfaces()) {
final Class<?> ires = findInterface(annotation, iface);
if (ires != null) return ires;
}
final Class<?> sres = findInterface(annotation, clazz.getSuperclass());
if (sres != null) return sres;
return null;
}
}

View File

@ -0,0 +1,45 @@
package eu.dnetlib.enabling.tools.registration;
import java.util.HashMap;
import java.util.Map;
/**
* Allow manual (external) override of service types, through an appropriate mapping (e.g. injected with spring).
*
* @author marko
*
*/
public class InterfaceServiceNameResolverCompatibility extends InterfaceServiceNameResolver {
/**
* Service names resolved with InterfaceServiceNameResolver will be used as keys in this map. If there is a match,
* the mapping is used instead of the inferred name.
*/
private Map<String, String> mapping = new HashMap<String, String>();
public Map<String, String> getMapping() {
return mapping;
}
public void setMapping(final Map<String, String> mapping) {
this.mapping = mapping;
}
/**
* {@inheritDoc}
* @see eu.dnetlib.enabling.tools.registration.InterfaceServiceNameResolver#getName(java.lang.Object)
*/
@Override
public String getName(final Class<?> iface) {
final String name = super.getName(iface);
final String override = getMapping().get(name);
if (override != null)
return override;
if(name.charAt(0) == 'I' && Character.isUpperCase(name.charAt(1)) && !Character.isUpperCase(name.charAt(2)))
return name.substring(1);
return name;
}
}

View File

@ -0,0 +1,26 @@
package eu.dnetlib.enabling.tools.registration;
/**
* Infers the actual name of the service from a service instance.
*
* @author marko
*
*/
public interface ServiceNameResolver {
/**
* returns the service name for a given service.
*
* @param service service instance
* @return service name
*/
String getName(Object service);
/**
* Get the service name for a given service interface.
*
* @param serviceInterface service interface
* @return service name.
*/
String getName(Class<?> serviceInterface);
}

View File

@ -0,0 +1,55 @@
package eu.dnetlib.enabling.tools.registration;
import javax.xml.ws.Endpoint;
import org.springframework.beans.factory.annotation.Required;
import eu.dnetlib.enabling.tools.OpaqueResource;
/**
* A service registration manager manages the registration of the service profile for a given service.
*
* @author marko
*
*/
public interface ServiceRegistrationManager {
/**
* service to register.
*
* @param service service instance
*/
@Required
void setService(Object service);
/**
* service endpoint.
*
* @param endpoint service endpoint
*/
@Required
void setEndpoint(Endpoint endpoint);
/**
* set to true if we want to disable service registration.
*
* @param disabled
*/
@Required
void setDisabled(boolean disabled);
/**
* returns the service profile associated with the service.
*
* @return service profile
*/
OpaqueResource getServiceProfile();
/**
* returns the registered service
*
* @return the service
*/
Object getService();
}

View File

@ -0,0 +1,366 @@
package eu.dnetlib.enabling.tools.registration;
import static eu.dnetlib.enabling.tools.registration.ServiceRegistrationManagerImpl.State.PENDING;
import static eu.dnetlib.enabling.tools.registration.ServiceRegistrationManagerImpl.State.REGISTERED;
import static eu.dnetlib.enabling.tools.registration.ServiceRegistrationManagerImpl.State.UNKNOWN;
import static eu.dnetlib.enabling.tools.registration.ServiceRegistrationManagerImpl.State.UNREGISTERED;
import java.io.IOException;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.ws.Endpoint;
import javax.xml.xpath.XPathExpressionException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Required;
import org.xml.sax.SAXException;
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.locators.UniqueServiceLocator;
import eu.dnetlib.enabling.tools.OpaqueResource;
import eu.dnetlib.enabling.tools.StringOpaqueResource;
/**
* Simple service registration manager implementation.
*
* <p>
* The simplest way to use of the service registration manager is to declare the following in your bean definition file:
* </p>
*
* <pre>
* &lt;template:instance name=&quot;serviceRegistrationManager&quot;
* t:name=&quot;myServiceRegistrationManager&quot; t:service=&quot;myService&quot; t:endpoint=&quot;myServiceEndpoint&quot;
* t:jobScheduler=&quot;jobScheduler&quot;/&gt;
* </pre>
*
* <p>
* The ServiceRegistrationManager requires periodic ticks from a quartz job scheduler (the 'jobScheduler' bean in the above example)
* </p>
*
* <p>
* See the ValidatingServiceRegistrationManagerImpl class for a special implementation which performs automatic service profile validation.
* </p>
*
* @see ValidatingServiceRegistrationManagerImpl
* @author marko
*
*/
public class ServiceRegistrationManagerImpl implements ServiceRegistrationManager {
/**
* error message: the profile is not found. This actually happens a lot, because of the way the old ISLookUpService API was concieved.
*/
private static final String PROFILE_NOT_FOUND = "profile not found";
/**
* error message: some error during searches for service profile state.
*/
private static final String ERROR_CHECK = "error checking profile";
/**
* logger.
*/
private static final Log log = LogFactory.getLog(ServiceRegistrationManagerImpl.class); // NOPMD by marko on 11/24/08 5:02 PM
/**
* registration manager states.
*
* @author marko
*
*/
public enum State {
/**
* service profile is either registered or registered and we have to check out if the profile already exists.
*/
UNKNOWN,
/**
* service profile is not yet registered or the registration disappeared.
*/
UNREGISTERED, /**
* the service profile is registered for validation. A validation operation is awaited.
*/
PENDING, /**
* the service profile is fully registered.
*/
REGISTERED
}
/**
* service profile identifier.
*/
private String profileId;
/**
* service to be registered.
*/
private Object service;
/**
* service endpoint.
*/
private Endpoint endpoint;
/**
* service locator.
*/
private UniqueServiceLocator serviceLocator;
/**
* service registrator.
*/
private ServiceRegistrator registrator;
/**
* service profile resource local cache.
*/
private OpaqueResource serviceProfile;
/**
* if true the service profile schema will be always updated at boot.
*/
private boolean schemaUpdate = true;
/**
* disable the service registration.
*/
private boolean disabled = false;
/**
* registration state of the service profile.
*/
private State state = State.UNKNOWN;
/**
* check if we have already a registered service profile for this service.
*/
void checkExisting() {
final String uri = registrator.getEprBuilder().getAddress(endpoint) + "?wsdl";
final String query = "for $x in //RESOURCE_PROFILE[.//RESOURCE_URI/@value='" + uri + "']"
+ " where contains($x//RESOURCE_TYPE/@value/string(), 'Service') return $x";
try {
final OpaqueResource resource = new StringOpaqueResource(serviceLocator.getService(ISLookUpService.class, true).getResourceProfileByQuery(query));
if ("PendingServiceResources".equals(resource.getResourceKind())) {
state = State.PENDING;
} else {
setProfileId(resource.getResourceId());
setServiceProfile(resource);
state = State.REGISTERED;
}
} catch (final ISLookUpDocumentNotFoundException e) {
log.debug("there is no service registered for uri: " + uri);
state = State.UNREGISTERED;
} catch (final ISLookUpException e) {
log.warn(ERROR_CHECK, e);
} catch (final XPathExpressionException e) {
log.warn(ERROR_CHECK, e);
} catch (final SAXException e) {
log.warn(ERROR_CHECK, e);
} catch (final IOException e) {
log.warn(ERROR_CHECK, e);
} catch (final ParserConfigurationException e) {
log.warn(ERROR_CHECK, e);
}
}
/**
* check that a pending service profile has been validated.
*
* if it has been validated change the state to REGISTERED.
*/
void checkPending() {
log.debug("checking pending status: " + getService());
final String uri = serviceProfile.getResourceUri();
final String query = "collection('')//RESOURCE_PROFILE[.//RESOURCE_URI/@value='" + uri + "']";
try {
final OpaqueResource resource = new StringOpaqueResource(serviceLocator.getService(ISLookUpService.class, true).getResourceProfileByQuery(query));
if (!"PendingServiceResources".equals(resource.getResourceKind())) {
setProfileId(resource.getResourceId());
setServiceProfile(resource);
state = State.REGISTERED;
}
} catch (final ISLookUpDocumentNotFoundException e) {
log.debug(PROFILE_NOT_FOUND, e);
} catch (final ISLookUpException e) {
log.warn(ERROR_CHECK, e);
} catch (final XPathExpressionException e) {
log.warn(ERROR_CHECK, e);
} catch (final SAXException e) {
log.warn(ERROR_CHECK, e);
} catch (final IOException e) {
log.warn(ERROR_CHECK, e);
} catch (final ParserConfigurationException e) {
log.warn(ERROR_CHECK, e);
}
}
/**
* ensure the service is registered.
*/
public void registerService() {
log.debug("registering service profile: " + getService());
setProfileId(getRegistrator().registerService(getService(), getEndpoint()));
if (getProfileId() == null) {
log.debug("cannot register profile, no hnm");
return;
}
log.debug("Service profile registered: " + getProfileId());
retrieveServiceProfile();
state = State.PENDING;
if (getProfileId() == null) throw new IllegalStateException("cannot be true, I'm dreaming");
}
/**
* register service schema.
*/
public void registerSchema() {
getRegistrator().registerServiceSchema(getService());
}
/**
* maintain the cached service profile.
*/
private void retrieveServiceProfile() {
log.debug("Retrieving service profile: " + getProfileId());
try {
setServiceProfile(new StringOpaqueResource(serviceLocator.getService(ISLookUpService.class, true).getResourceProfile(getProfileId())));
} catch (final ISLookUpDocumentNotFoundException e) {
log.debug(PROFILE_NOT_FOUND, e);
} catch (final ISLookUpException e) {
log.warn(ERROR_CHECK, e);
} catch (final XPathExpressionException e) {
log.warn(ERROR_CHECK, e);
} catch (final SAXException e) {
log.warn(ERROR_CHECK, e);
} catch (final IOException e) {
log.warn(ERROR_CHECK, e);
} catch (final ParserConfigurationException e) {
log.warn(ERROR_CHECK, e);
}
}
/**
* {@inheritDoc}
*
* @see eu.dnetlib.enabling.tools.registration.ServiceRegistrationManager#getServiceProfile()
*/
@Override
public OpaqueResource getServiceProfile() {
retrieveServiceProfile();
return serviceProfile;
}
/**
* called periodically to advance the state machine.
*/
public void tick() {
if (disabled) return;
synchronized (registrator) {
if (state != REGISTERED) {
log.debug("checking service profile registration: " + getService() + " (" + state + ")");
}
if (state == UNKNOWN) {
if (schemaUpdate) {
registerSchema();
}
checkExisting();
} else if (state == UNREGISTERED) {
registerService();
} else if (state == PENDING) {
checkPending();
}
if (state != REGISTERED) {
log.debug("tick finished");
}
}
}
public void setProfileId(final String profileId) {
this.profileId = profileId;
}
public String getProfileId() {
return profileId;
}
@Override
public Object getService() {
return service;
}
@Override
public void setService(final Object service) {
this.service = service;
}
public Endpoint getEndpoint() {
return endpoint;
}
@Override
public void setEndpoint(final Endpoint endpoint) {
this.endpoint = endpoint;
}
public ServiceRegistrator getRegistrator() {
return registrator;
}
@Required
public void setRegistrator(final ServiceRegistrator registrator) {
this.registrator = registrator;
}
public void setServiceProfile(final OpaqueResource serviceProfile) {
this.serviceProfile = serviceProfile;
}
public State getState() {
return state;
}
public void setState(final State state) {
this.state = state;
}
public boolean isSchemaUpdate() {
return schemaUpdate;
}
public void setSchemaUpdate(final boolean schemaUpdate) {
this.schemaUpdate = schemaUpdate;
}
public boolean isDisabled() {
return disabled;
}
@Override
public void setDisabled(final boolean disabled) {
this.disabled = disabled;
}
public UniqueServiceLocator getServiceLocator() {
return serviceLocator;
}
@Required
public void setServiceLocator(UniqueServiceLocator serviceLocator) {
this.serviceLocator = serviceLocator;
}
}

View File

@ -0,0 +1,331 @@
package eu.dnetlib.enabling.tools.registration;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Map;
import javax.xml.transform.dom.DOMResult;
import javax.xml.ws.Endpoint;
import javax.xml.ws.wsaddressing.W3CEndpointReference;
import org.antlr.stringtemplate.StringTemplate;
import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Required;
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.registry.rmi.ISRegistryException;
import eu.dnetlib.enabling.is.registry.rmi.ISRegistryService;
import eu.dnetlib.enabling.locators.UniqueServiceLocator;
import eu.dnetlib.enabling.tools.HNMLocator;
import eu.dnetlib.enabling.tools.NullHNMLocator;
import eu.dnetlib.soap.EndpointReferenceBuilder;
/**
* This class takes care of registering a service.
*
* TODO: merge the implementation
*
* @author marko
*
*/
public class ServiceRegistrator {
/**
* second.
*/
private static final int SECOND = 0;
/**
* logger.
*/
private static final Log log = LogFactory.getLog(ServiceRegistrator.class); // NOPMD
// by
// marko
// on
// 11/24/08
// 5:02
// PM
/**
* locator.
*/
private UniqueServiceLocator serviceLocator;
/**
* epr builder.
*/
private EndpointReferenceBuilder<Endpoint> eprBuilder;
/**
* component which finds an hnm profile.
*/
private HNMLocator hnmLocator = new NullHNMLocator();
/**
* Key-value pairs with service specific parameters which will appear in service profile.
*/
private Map<String, String> serviceProperties = new HashMap<String, String>();
/**
* Key-value pairs [name - endpoint] of extra protocols available in service profiles.
*/
private Map<String, String> extraProtocols = new HashMap<String, String>();
/**
* this bean helps us resolve service names from service instances.
*/
private ServiceNameResolver serviceNameResolver = new InterfaceServiceNameResolver(); // NOPMD
/**
* Register a service schema for a given service.
*
* @param service
* service
*/
public void registerServiceSchema(final Object service) {
registerServiceSchema(serviceNameResolver.getName(service));
}
/**
* Register a service schema for a particular service.
*
* @param serviceName
* service name
*/
public void registerServiceSchema(final String serviceName) {
try {
final InputStream schemaStream = getClass().getResourceAsStream("ServiceProfileSchemaTemplate.st");
if (schemaStream == null) { throw new IllegalStateException("cannot find service profile schema template"); }
final StringWriter schemaBuffer = new StringWriter();
IOUtils.copy(schemaStream, schemaBuffer);
final StringTemplate schema = new StringTemplate(schemaBuffer.toString());
final String resourceType = serviceName + "ResourceType";
schema.setAttribute("resourceType", resourceType);
if (serviceLocator == null) {
log.error("************* SERVICE LOCATOR IS NULL:" + serviceName);
return;
}
final ISRegistryService registry = serviceLocator.getService(ISRegistryService.class, true);
if (registry == null) {
log.error("************* REGISTRY SERVICE IS NULL");
return;
}
registry.addResourceType(resourceType, schema.toString());
} catch (final ISRegistryException e) {
throw new IllegalStateException("cannot register service profile schema", e);
} catch (final IOException e) {
throw new IllegalStateException("cannot read service profile schema template", e);
}
}
/**
* register a given service.
*
* @param service
* infers the service name from the class or annotations
* @param endpoint
* jaxws endpoint
* @return service profile id
*/
public String registerService(final Object service, final Endpoint endpoint) {
return registerService(serviceNameResolver.getName(service), endpoint);
}
/**
* register a service with a given service name. Return null if the service cannot be registered, for example because it's blocked if
* the HNM is missing.
*
* @param serviceName
* service name
* @param endpoint
* jaxws endpoint
* @return service profile id, or null if the service cannot be registered because blocked
*/
public String registerService(final String serviceName, final Endpoint endpoint) {
return registerService(serviceName, eprBuilder.getEndpointReference(endpoint));
}
/**
* register a service with a given service name.
*
* @param serviceName
* service name
* @param epr
* w3c endpoint reference
* @return service profile id
*/
public String registerService(final String serviceName, final W3CEndpointReference epr) {
ensureSchemaExists(serviceName);
final DOMResult result = new DOMResult();
epr.writeTo(result);
try {
final InputStream templateStream = getClass().getResourceAsStream("ServiceProfileTemplate.st");
if (templateStream == null) { throw new IllegalStateException("cannot find service profile template"); }
final StringWriter buffer = new StringWriter();
IOUtils.copy(templateStream, buffer);
final StringTemplate templ = new StringTemplate(buffer.toString());
final String resourceType = serviceName + "ResourceType";
final String address = result.getNode().getChildNodes().item(0).getChildNodes().item(0).getTextContent();
final String hnmId = hnmLocator.getHNMForUrl(address);
// skip registration if there is no HNM yet.
if (hnmId == null) {
log.warn(String.format("skipping %s service registration, can't find NHM service'", serviceName));
return null;
}
templ.setAttribute("resourceType", resourceType);
templ.setAttribute("serviceName", serviceName);
templ.setAttribute("address", address);
templ.setAttribute("protocols", getExtraProtocols());
templ.setAttribute("parentId", hnmId);
templ.setAttribute("properties", serviceProperties);
log.debug("template: " + templ.toString());
final String res = serviceLocator.getService(ISRegistryService.class, true).insertProfileForValidation(resourceType, templ.toString());
Thread.sleep(SECOND);
return res;
} catch (final IOException e) {
throw new IllegalStateException("cannot load service profile template", e);
} catch (final ISRegistryException e) {
throw new IllegalStateException("cannot register service profile", e);
} catch (final InterruptedException e) {
throw new IllegalStateException("cannot wait for register service profile", e);
}
}
/**
* Check that the service schema for this service already exists, and create it if it doesn't.
*
* @param serviceName
* service name
*/
protected void ensureSchemaExists(final String serviceName) {
try {
serviceLocator.getService(ISLookUpService.class).getResourceTypeSchema(serviceName);
//serviceLocator.getService(ISLookUpService.class).getResourceProfileByQuery(
// "//*[local-name() = 'complexType' and @name = 'RESOURCE_TYPEType']//*[local-name() = 'enumeration' and @value = '" + serviceName
// + "ResourceType']");
log.warn("schema for " + serviceName + " appears to exist");
} catch (final ISLookUpDocumentNotFoundException e) {
log.warn("registering schema for " + serviceName);
registerServiceSchema(serviceName);
} catch (final ISLookUpException e) {
throw new IllegalStateException(e);
}
}
/**
* validate the registered profile.
*
* TODO: XXX: huge hack. used right now to automatically register the blackboard. It won't work anymore once the services are validated
* from the GUI
*
* @param profId
* profile id
* @param endpoint
* service endpoint (hook for possible IS_SN automated registrations)
* @return new id.
*/
public String validateProfile(final String profId, final Endpoint endpoint) {
try {
Thread.sleep(SECOND);
} catch (final InterruptedException e) {
throw new IllegalStateException("interrupted", e);
}
try {
return serviceLocator.getService(ISRegistryService.class, true).validateProfile(profId);
} catch (final ISRegistryException e) {
throw new IllegalStateException("cannot validate service profile", e);
}
}
/**
* validate the registered profile.
*
* @param profId
* old profile identifier
* @return new profile identifier
*/
public String validateProfile(final String profId) {
return validateProfile(profId, null);
}
public EndpointReferenceBuilder<Endpoint> getEprBuilder() {
return eprBuilder;
}
@Required
public void setEprBuilder(final EndpointReferenceBuilder<Endpoint> eprBuilder) {
this.eprBuilder = eprBuilder;
}
public HNMLocator getHnmLocator() {
return hnmLocator;
}
public void setHnmLocator(final HNMLocator hnmLocator) {
this.hnmLocator = hnmLocator;
}
public ServiceNameResolver getServiceNameGen() {
return serviceNameResolver;
}
public void setServiceNameGen(final ServiceNameResolver serviceNameGen) {
this.serviceNameResolver = serviceNameGen;
}
public ServiceNameResolver getServiceNameResolver() {
return serviceNameResolver;
}
public void setServiceNameResolver(final ServiceNameResolver serviceNameRes) {
this.serviceNameResolver = serviceNameRes;
}
public Map<String, String> getServiceProperties() {
return serviceProperties;
}
public void setServiceProperties(final Map<String, String> serviceProperties) {
this.serviceProperties = serviceProperties;
}
public Map<String, String> getExtraProtocols() {
return extraProtocols;
}
public void setExtraProtocols(final Map<String, String> extraProtocols) {
this.extraProtocols = extraProtocols;
}
public UniqueServiceLocator getServiceLocator() {
return serviceLocator;
}
@Required
public void setServiceLocator(final UniqueServiceLocator serviceLocator) {
this.serviceLocator = serviceLocator;
}
}

View File

@ -0,0 +1,32 @@
package eu.dnetlib.enabling.tools.registration;
/**
* Dummy service name generator implementation. Simply returns the class name. This will never work in practice because
* people have freedom calling their implementations of the service interface as they want.
*
* @author marko
*
*/
@Deprecated
public class SimpleServiceNameResolver implements ServiceNameResolver {
/**
* {@inheritDoc}
*
* @see eu.dnetlib.enabling.tools.registration.ServiceNameResolver#getName(java.lang.Object)
*/
@Override
public String getName(final Object service) {
return getName(service.getClass());
}
/**
* {@inheritDoc}
* @see eu.dnetlib.enabling.tools.registration.ServiceNameResolver#getName(java.lang.Class)
*/
@Override
public String getName(final Class<?> iface) {
return iface.getSimpleName();
}
}

View File

@ -0,0 +1,43 @@
package eu.dnetlib.enabling.tools.registration;
/**
* Useful if you want to register a service external to this framework.
*
* @author marko
*
*/
@Deprecated
public class StaticServiceNameResolver implements ServiceNameResolver {
/**
* service name.
*/
private String name;
/**
* {@inheritDoc}
* @see eu.dnetlib.enabling.tools.registration.ServiceNameResolver#getName(java.lang.Object)
*/
@Override
public String getName(final Object service) {
return name;
}
/**
* {@inheritDoc}
* @see eu.dnetlib.enabling.tools.registration.ServiceNameResolver#getName(java.lang.Class)
*/
@Override
public String getName(final Class<?> serviceInterface) {
return name;
}
public String getName() {
return name;
}
public void setName(final String name) {
this.name = name;
}
}

View File

@ -0,0 +1,62 @@
package eu.dnetlib.enabling.tools.registration;
import static eu.dnetlib.enabling.tools.registration.ServiceRegistrationManagerImpl.State.PENDING;
import static eu.dnetlib.enabling.tools.registration.ServiceRegistrationManagerImpl.State.REGISTERED;
/**
* This service registration manager implementation performs automatic service profile validation.
* <p>
* This is useful during automated testing. You can use it simply by overriding the default class in the service
* registration manager bean template:
* </p>
*
* <pre>
* &lt;template:instance name=&quot;serviceRegistrationManager&quot;
* t:serviceRegistrationManagerClass=&quot;eu.dnetlib.enabling.tools.registration.ValidatingServiceRegistrationManagerImpl&quot;
* t:name=&quot;myServiceRegistrationManager&quot; t:service=&quot;myService&quot; t:endpoint=&quot;myServiceEndpoint&quot;
* t:jobScheduler=&quot;jobScheduler&quot;/&gt;
* </pre>
*
* <p>
* If your service needs to receive blackboard messages, the notification can be automatically subscribed to your
* service profile simply by using a different service registrator component (blackboardServiceRegistrator):
* </p>
*
* <pre>
* &lt;template:instance name=&quot;serviceRegistrationManager&quot;
* t:serviceRegistrationManagerClass=&quot;eu.dnetlib.enabling.tools.registration.ValidatingServiceRegistrationManagerImpl&quot;
* t:name=&quot;myServiceRegistrationManager&quot; t:service=&quot;myService&quot; t:endpoint=&quot;myServiceEndpoint&quot;
* t:jobScheduler=&quot;jobScheduler&quot; t:serviceRegistrator=&quot;blackboardServiceRegistrator&quot;/&gt;
* </pre>
*
* <p>
* This option is very useful for example to the MDStoreService or the IndexService.
* </p>
*
* @author marko
*
*/
public class ValidatingServiceRegistrationManagerImpl extends ServiceRegistrationManagerImpl {
/**
* {@inheritDoc}
*
* @see eu.dnetlib.enabling.tools.registration.ServiceRegistrationManagerImpl#tick()
*/
@Override
public void tick() {
synchronized (getRegistrator()) {
if (getState() == PENDING) {
if(getProfileId() == null) {
throw new IllegalStateException("State is PENDING but profile id isn't initialized");
}
final String newId = getRegistrator().validateProfile(getProfileId(), getEndpoint());
setProfileId(newId);
setState(REGISTERED);
return;
}
}
super.tick();
}
}

View File

@ -0,0 +1,61 @@
package eu.dnetlib.functionality.cql;
import java.util.Set;
import org.apache.commons.lang3.StringUtils;
import org.z3950.zing.cql.CQLBooleanNode;
import org.z3950.zing.cql.CQLNode;
import org.z3950.zing.cql.CQLOrNode;
import org.z3950.zing.cql.CQLParser;
import org.z3950.zing.cql.CQLTermNode;
import org.z3950.zing.cql.ModifierSet;
public class CQLExpander {
private static final String OP = "or";
private static final String _OP_ = " " + OP + " ";
public CQLNode expand(CQLNode node, Set<String> fields) {
return doExpand(node, fields);
}
private static CQLNode doExpand(CQLNode node, Set<String> fields) {
if (node instanceof CQLBooleanNode) {
return doExpand((CQLBooleanNode) node, fields);
}
if (node instanceof CQLTermNode) {
return doExpand((CQLTermNode) node, fields);
}
// if (node == null)
// return terms;
throw new RuntimeException("error choice");
}
private static CQLNode doExpand(CQLBooleanNode node, Set<String> fields) {
CQLNode left = doExpand(node.left, fields);
CQLNode right = doExpand(node.right, fields);
return new CQLOrNode(left, right, new ModifierSet("or"));
}
private static CQLNode doExpand(CQLTermNode node, Set<String> fields) {
String expand = "";
for (String field : fields) {
expand += field + "=" + node.getTerm() + _OP_;
}
expand = StringUtils.removeEnd(expand, _OP_);
try {
return new CQLParser().parse(expand);
} catch (Exception e) {
throw new RuntimeException("unable to parse: " + expand);
}
}
}

View File

@ -0,0 +1,49 @@
package eu.dnetlib.functionality.cql;
import java.util.HashSet;
import java.util.Set;
import org.z3950.zing.cql.CQLBooleanNode;
import org.z3950.zing.cql.CQLNode;
import org.z3950.zing.cql.CQLTermNode;
public class CQLFieldLister {
public Set<String> listFields(final CQLNode node) {
return doFilter(node, new HashSet<String>());
}
private Set<String> doFilter(CQLNode node, Set<String> fields) {
if (node instanceof CQLBooleanNode) {
return doFilter((CQLBooleanNode) node, fields);
}
if (node instanceof CQLTermNode) {
return doFilter((CQLTermNode) node, fields);
}
if (node == null) {
return fields;
}
throw new RuntimeException("error choice");
}
private Set<String> doFilter(CQLBooleanNode node, Set<String> fields) {
Set<String> left = doFilter(node.left, fields);
Set<String> right = doFilter(node.right, fields);
left.addAll(right);
return left;
}
private static Set<String> doFilter(CQLTermNode node, Set<String> terms) {
terms.add(node.getIndex());
return terms;
}
}

Some files were not shown because too many files have changed in this diff Show More