Enhancement on Task #10070

git-svn-id: http://svn.research-infrastructures.eu/public/d4science/gcube/trunk/data-transfer/uri-resolver@167175 82a268e6-3cf1-43bd-a215-b396298e98cf
This commit is contained in:
Francesco Mangiacrapa 2018-04-23 15:07:57 +00:00
parent 21d3f858d1
commit 427bf23e5c
22 changed files with 1676 additions and 2926 deletions

View File

@ -0,0 +1,7 @@
<root>
<facet id="jst.jaxrs">
<node name="libprov">
<attribute name="provider-id" value="jaxrs-no-op-library-provider"/>
</node>
</facet>
</root>

View File

@ -4,4 +4,5 @@
<installed facet="wst.jsdt.web" version="1.0"/> <installed facet="wst.jsdt.web" version="1.0"/>
<installed facet="jst.web" version="2.3"/> <installed facet="jst.web" version="2.3"/>
<installed facet="java" version="1.7"/> <installed facet="java" version="1.7"/>
<installed facet="jst.jaxrs" version="2.0"/>
</faceted-project> </faceted-project>

File diff suppressed because it is too large Load Diff

View File

@ -94,7 +94,17 @@
</Changeset> </Changeset>
<Changeset component="org.gcube.data-transfer.uri-resolver.1-14-0" <Changeset component="org.gcube.data-transfer.uri-resolver.1-14-0"
date="2017-09-06"> date="2017-09-06">
<Change>[Task #9538] Geonetwork-Uri Resolver enhancement: provide new filters and improve current ones <Change>[Task #9538] Geonetwork-Uri Resolver enhancement: provide new
filters and improve current ones
</Change>
</Changeset>
<Changeset component="org.gcube.data-transfer.uri-resolver.1-15-0"
date="2017-11-21">
<Change>[Task #10381] Geonetwork Resolver enhancement: porting to
Geonetwork connector
</Change>
<Change>[Task #10070] Catalogue Resolver enhancement: resolve
public/private items to public/private catalogue
</Change> </Change>
</Changeset> </Changeset>
</ReleaseNotes> </ReleaseNotes>

17
pom.xml
View File

@ -8,7 +8,7 @@
</parent> </parent>
<groupId>org.gcube.data.transfer</groupId> <groupId>org.gcube.data.transfer</groupId>
<artifactId>uri-resolver</artifactId> <artifactId>uri-resolver</artifactId>
<version>1.14.0-SNAPSHOT</version> <version>1.15.0-SNAPSHOT</version>
<packaging>war</packaging> <packaging>war</packaging>
<description>The URI Resolver is an HTTP URI resolver implemented as an HTTP servlet which gives access trough HTTP to different protocols URIs. </description> <description>The URI Resolver is an HTTP URI resolver implemented as an HTTP servlet which gives access trough HTTP to different protocols URIs. </description>
@ -22,7 +22,7 @@
<distroDirectory>distro</distroDirectory> <distroDirectory>distro</distroDirectory>
<maven.compiler.source>1.7</maven.compiler.source> <maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target> <maven.compiler.target>1.8</maven.compiler.target>
<!-- <additionalparam>-Xdoclint:none</additionalparam> --> <!-- <additionalparam>-Xdoclint:none</additionalparam> -->
</properties> </properties>
<dependencies> <dependencies>
@ -98,6 +98,12 @@
<version>2.6</version> <version>2.6</version>
</dependency> </dependency>
<dependency>
<groupId>org.gcube.common</groupId>
<artifactId>authorization-client</artifactId>
<version>[2.0.0-SNAPSHOT, 3.0.0-SNAPSHOT)</version>
</dependency>
<!-- DOM --> <!-- DOM -->
<dependency> <dependency>
<groupId>org.w3c</groupId> <groupId>org.w3c</groupId>
@ -106,6 +112,13 @@
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
<dependency>
<groupId>org.gcube.data-catalogue</groupId>
<artifactId>ckan-util-library</artifactId>
<version>[2.0.0-SNAPSHOT, 3.0.0-SNAPSHOT)</version>
<scope>compile</scope>
</dependency>
<!-- END GIS RESOLVER DEPENDENCIES --> <!-- END GIS RESOLVER DEPENDENCIES -->
<dependency> <dependency>

View File

@ -3,6 +3,8 @@
*/ */
package org.gcube.datatransfer.resolver; package org.gcube.datatransfer.resolver;
import java.util.Map;
import org.gcube.datatransfer.resolver.GeonetworkRequestFilterParameters.MODE; import org.gcube.datatransfer.resolver.GeonetworkRequestFilterParameters.MODE;
import org.gcube.datatransfer.resolver.GeonetworkRequestFilterParameters.VISIBILITY; import org.gcube.datatransfer.resolver.GeonetworkRequestFilterParameters.VISIBILITY;
@ -13,12 +15,17 @@ import org.gcube.datatransfer.resolver.GeonetworkRequestFilterParameters.VISIBIL
* @author Francesco Mangiacrapa francesco.mangiacrapa@isti.cnr.it * @author Francesco Mangiacrapa francesco.mangiacrapa@isti.cnr.it
* Jun 15, 2016 * Jun 15, 2016
*/ */
public class GeonetworkRequestCriteria { public class GeonetworkRequestCriteria{
private String scope; private String scope;
private String gCubeToken;
private MODE mode; private MODE mode;
private String owner; //This is optional private Map<String, String> filters; //This is optional
private VISIBILITY visibility; private VISIBILITY visibility;
public GeonetworkRequestCriteria(){
}
/** /**
* @param scope * @param scope
* @param mode * @param mode
@ -26,15 +33,37 @@ public class GeonetworkRequestCriteria {
* @param visibility * @param visibility
*/ */
public GeonetworkRequestCriteria( public GeonetworkRequestCriteria(
String scope, MODE mode, String owner, VISIBILITY visibility) { String scope, String gCubeToken, MODE mode, Map<String, String> filters, VISIBILITY visibility) {
super(); super();
this.scope = scope; this.scope = scope;
this.gCubeToken = gCubeToken;
this.mode = mode; this.mode = mode;
this.owner = owner; this.filters = filters;
this.visibility = visibility; this.visibility = visibility;
} }
/**
* Gets the gcube token.
*
* @return the gCubeToken
*/
public String getGcubeToken() {
return gCubeToken;
}
/**
* @param gCubeToken the gCubeToken to set
*/
public void setgCubeToken(String gCubeToken) {
this.gCubeToken = gCubeToken;
}
/** /**
* @return the scope * @return the scope
*/ */
@ -52,11 +81,11 @@ public class GeonetworkRequestCriteria {
} }
/** /**
* @return the owner * @return the filters
*/ */
public String getOwner() { public Map<String, String> getFilters() {
return owner; return filters;
} }
/** /**
@ -83,12 +112,13 @@ public class GeonetworkRequestCriteria {
this.mode = mode; this.mode = mode;
} }
/**
* @param owner the owner to set
*/
public void setOwner(String owner) {
this.owner = owner; /**
* @param filters the filters to set
*/
public void setFilters(Map<String, String> filters) {
this.filters = filters;
} }
/** /**
@ -98,7 +128,6 @@ public class GeonetworkRequestCriteria {
this.visibility = visibility; this.visibility = visibility;
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see java.lang.Object#toString() * @see java.lang.Object#toString()
*/ */
@ -108,10 +137,12 @@ public class GeonetworkRequestCriteria {
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();
builder.append("GeonetworkRequestCriteria [scope="); builder.append("GeonetworkRequestCriteria [scope=");
builder.append(scope); builder.append(scope);
builder.append(", gCubeToken=");
builder.append(gCubeToken);
builder.append(", mode="); builder.append(", mode=");
builder.append(mode); builder.append(mode);
builder.append(", owner="); builder.append(", filters=");
builder.append(owner); builder.append(filters);
builder.append(", visibility="); builder.append(", visibility=");
builder.append(visibility); builder.append(visibility);
builder.append("]"); builder.append("]");
@ -120,4 +151,5 @@ public class GeonetworkRequestCriteria {
} }

View File

@ -3,6 +3,11 @@
*/ */
package org.gcube.datatransfer.resolver; package org.gcube.datatransfer.resolver;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import javax.servlet.ServletException; import javax.servlet.ServletException;
import org.gcube.datatransfer.resolver.GeonetworkRequestFilterParameters.MODE; import org.gcube.datatransfer.resolver.GeonetworkRequestFilterParameters.MODE;
@ -62,13 +67,22 @@ public class GeonetworkRequestDecoder {
logger.debug("scope value is: "+geonetworkRequestCriteria.getScope()); logger.debug("scope value is: "+geonetworkRequestCriteria.getScope());
//newURI = UriResolverRewriteFilter.SERVLET_GEONETWORK + "?" + GeonetworkResolver.SCOPE + "=" + geonetworkRequestCriteria.getScope() +"&"+ GeonetworkResolver.PARAMETER_FILTER_PUBLIC_IDS +"="+geonetworkRequestCriteria.isValueOfFilterPublicIds() +"&"+GeonetworkResolver.PARAMETER_NO_AUTHENTICATION+"="+geonetworkRequestCriteria.isNoAuthOnGeonetwork(); //newURI = UriResolverRewriteFilter.SERVLET_GEONETWORK + "?" + GeonetworkResolver.SCOPE + "=" + geonetworkRequestCriteria.getScope() +"&"+ GeonetworkResolver.PARAMETER_FILTER_PUBLIC_IDS +"="+geonetworkRequestCriteria.isValueOfFilterPublicIds() +"&"+GeonetworkResolver.PARAMETER_NO_AUTHENTICATION+"="+geonetworkRequestCriteria.isNoAuthOnGeonetwork();
//+ GeonetworkResolver.GCUBETOKEN + "=" + geonetworkRequestCriteria.getGcubeToken()!=null?geonetworkRequestCriteria.getGcubeToken():"" +"&"
gnResolverUriRequest = UriResolverRewriteFilter.SERVLET_GEONETWORK + "?" gnResolverUriRequest = UriResolverRewriteFilter.SERVLET_GEONETWORK + "?"
+ GeonetworkResolver.SCOPE + "=" + geonetworkRequestCriteria.getScope() +"&" + GeonetworkResolver.SCOPE + "=" + geonetworkRequestCriteria.getScope() +"&"
+ GeonetworkResolver.GCUBETOKEN + "=" + geonetworkRequestCriteria.getGcubeToken() +"&"
+ GeonetworkRequestFilterParameters.MODE.class.getSimpleName() +"="+geonetworkRequestCriteria.getMode() +"&" + GeonetworkRequestFilterParameters.MODE.class.getSimpleName() +"="+geonetworkRequestCriteria.getMode() +"&"
+ GeonetworkRequestFilterParameters.VISIBILITY.class.getSimpleName()+"="+geonetworkRequestCriteria.getVisibility(); + GeonetworkRequestFilterParameters.VISIBILITY.class.getSimpleName()+"="+geonetworkRequestCriteria.getVisibility();
if(geonetworkRequestCriteria.getOwner()!=null){ if(geonetworkRequestCriteria.getFilters()!=null){
gnResolverUriRequest+="&"+GeonetworkRequestFilterParameters.OWNER_PARAM +"="+geonetworkRequestCriteria.getOwner(); Set<String> keyset = geonetworkRequestCriteria.getFilters().keySet();
for (String key : keyset) {
gnResolverUriRequest+="&"+GeonetworkRequestFilterParameters.FILTER_KEY +"="+key;
gnResolverUriRequest+="&"+GeonetworkRequestFilterParameters.FILTER_VALUE +"="+geonetworkRequestCriteria.getFilters().get(key);
}
} }
//BUILDING REMAINING PATH WITHOUT GeonetworkRequestFilterParameters.REQUEST_DELIMITIER //BUILDING REMAINING PATH WITHOUT GeonetworkRequestFilterParameters.REQUEST_DELIMITIER
@ -81,33 +95,6 @@ public class GeonetworkRequestDecoder {
gnResolverUriRequest+="&"+queryString; gnResolverUriRequest+="&"+queryString;
logger.info("built Geonetwork Resolver GET Request: "+gnResolverUriRequest); logger.info("built Geonetwork Resolver GET Request: "+gnResolverUriRequest);
/*
String[] params = pathWithoutGN.split("/");
if(params[0]==null || params[0].isEmpty()){
logger.error("Scope is null or empty, you must set a valid scope /geonetwork/root|vo|vre");
throw new ServletException("Scope is null or empty, you must set a valid scope /geonetwork/root"+SCOPE_SEPARATOR+"vo"+SCOPE_SEPARATOR+"vre");
}
geonetworkRequestCriteria = getGeonetworkRequestCriteria(params[0]);
logger.debug("scope value is: "+geonetworkRequestCriteria.getScope());
newURI = UriResolverRewriteFilter.SERVLET_GEONETWORK + "?" + GeonetworkResolver.SCOPE + "=" + geonetworkRequestCriteria.getScope() +"&"+ GeonetworkResolver.PARAMETER_FILTER_PUBLIC_IDS +"="+geonetworkRequestCriteria.isValueOfFilterPublicIds() +"&"+GeonetworkResolver.PARAMETER_NO_AUTHENTICATION+"="+geonetworkRequestCriteria.isNoAuthOnGeonetwork();
logger.debug(GeonetworkResolver.PARAMETER_FILTER_PUBLIC_IDS +" is: "+geonetworkRequestCriteria.isValueOfFilterPublicIds());
logger.debug(GeonetworkResolver.PARAMETER_NO_AUTHENTICATION +" is: "+geonetworkRequestCriteria.isNoAuthOnGeonetwork());
*/
// if(params.length>1){
// String remainPath = "";
//// newURI +="&remainPath=";
// for (int i = 1; i < params.length; i++) {
// String httpGetParam = params[i];
// if(httpGetParam!=null && !httpGetParam.isEmpty())
// remainPath+="/"+httpGetParam;
// }
// newURI +="&"+GeonetworkResolver.REMAIN_PATH+"="+remainPath;
// }
//
// if(queryString!=null && !queryString.isEmpty())
// newURI+="&"+queryString;
} }
@ -116,9 +103,9 @@ public class GeonetworkRequestDecoder {
* Creates a request criteria from input parameter pathWithoutGN * Creates a request criteria from input parameter pathWithoutGN
* The parameter pathWithoutGN should be an ordered string (like REST request): * The parameter pathWithoutGN should be an ordered string (like REST request):
* MODE/SCOPE/VISIBILITY/OWNER * MODE/SCOPE|GCUBETOKEN/VISIBILITY/OWNER
* MODE must be: {@link MODE} * MODE must be: {@link MODE}
* SCOPE must be: ROOT|VO|VRE * SCOPE must be: ROOT|VO|VRE or a GCUBETOKEN
* VISIBILITY must be: {@link VISIBILITY} * VISIBILITY must be: {@link VISIBILITY}
* OWNER (is optional): filter by owner * OWNER (is optional): filter by owner
* @param pathWithoutGN the path without Geonetwork base URL * @param pathWithoutGN the path without Geonetwork base URL
@ -130,21 +117,30 @@ public class GeonetworkRequestDecoder {
String[] params = pathWithoutGN.split("/"); String[] params = pathWithoutGN.split("/");
MODE mode = null; MODE mode = null;
String theScope = null; String contextScopeOrToken = null;
VISIBILITY visibility = null; VISIBILITY visibility = null;
String owner = null; Map<String, String> filters = null;
GeonetworkRequestCriteria requestCriteria = new GeonetworkRequestCriteria();
if(params.length < 3){ if(params.length < 3){
throw new BadRequestException("Bad request. Read the request "+pathWithoutGN+". You must pass a valid request like [GEONETWORK_BASE_URL]/SCOPE/MODE/VISIBILITY/OWNER"); throw new BadRequestException("Bad request. Read the request "+pathWithoutGN+". You must pass a valid request like [GEONETWORK_BASE_URL]/SCOPE/MODE/VISIBILITY/OWNER");
} }
//SCOPE //SCOPE or gcube-token
if(params[0]!=null && !params[0].isEmpty()){ if(params[0]!=null && !params[0].isEmpty()){
theScope = params[0]; contextScopeOrToken = params[0];
logger.debug("Read parameter scope: "+theScope); logger.debug("Read first parameter: "+contextScopeOrToken);
theScope = theScope.replaceAll("\\"+SCOPE_SEPARATOR, "/"); boolean isToken = isValidUUID(contextScopeOrToken);
if (!theScope.startsWith("/"))
theScope="/"+theScope; if(!isToken){
contextScopeOrToken = contextScopeOrToken.replaceAll("\\"+SCOPE_SEPARATOR, "/");
if (!contextScopeOrToken.startsWith("/"))
contextScopeOrToken="/"+contextScopeOrToken;
requestCriteria.setScope(contextScopeOrToken);
}else{
requestCriteria.setgCubeToken(contextScopeOrToken);
}
}else{ }else{
logger.error("The first parameter 'scope' is null or empty, you must set a valid scope as ROOT"+SCOPE_SEPARATOR+"VO"+SCOPE_SEPARATOR+"VRE as first parameter"); logger.error("The first parameter 'scope' is null or empty, you must set a valid scope as ROOT"+SCOPE_SEPARATOR+"VO"+SCOPE_SEPARATOR+"VRE as first parameter");
throw new ServletException("Scope is null or empty. You must pass a valid scope as ROOT"+SCOPE_SEPARATOR+"VO"+SCOPE_SEPARATOR+"VRE as first parameter"); throw new ServletException("Scope is null or empty. You must pass a valid scope as ROOT"+SCOPE_SEPARATOR+"VO"+SCOPE_SEPARATOR+"VRE as first parameter");
@ -193,11 +189,21 @@ public class GeonetworkRequestDecoder {
//OWNER //OWNER
if(params.length > 3 && params[3]!=null && params[3]!=GeonetworkRequestFilterParameters.REQUEST_DELIMITIER){ if(params.length > 3 && params[3]!=null && params[3]!=GeonetworkRequestFilterParameters.REQUEST_DELIMITIER){
owner = params[3]; filters = new HashMap<String, String>(1);
logger.debug("Read parameter owner: "+owner); filters.put(params[3], "");
logger.debug("Read filter key: "+params[3]);
if(params.length > 4 && params[4]!=null && params[4]!=GeonetworkRequestFilterParameters.REQUEST_DELIMITIER){
logger.debug("Read filter value: "+params[4]);
filters.put(params[3], params[4]);
}
} }
return new GeonetworkRequestCriteria(theScope, mode, owner, visibility); requestCriteria.setMode(mode);
requestCriteria.setFilters(filters);
requestCriteria.setVisibility(visibility);
return requestCriteria;
} }
@ -222,6 +228,31 @@ public class GeonetworkRequestDecoder {
} }
/**
* Checks if is valid uuid.
*
* @param uuid the uuid
* @return true, if is valid uuid
*/
public static boolean isValidUUID(String uuid){
if(uuid == null || uuid.isEmpty())
return false;
try{
UUID id = UUID.fromString(uuid);
if(id.toString().equals(uuid))
return true;
}catch(Exception e){
return false;
}
return true;
}
/* (non-Javadoc) /* (non-Javadoc)
* @see java.lang.Object#toString() * @see java.lang.Object#toString()
*/ */

View File

@ -15,5 +15,7 @@ public interface GeonetworkRequestFilterParameters {
public static enum VISIBILITY {PUB, PRV}; public static enum VISIBILITY {PUB, PRV};
public static String REQUEST_DELIMITIER = "/$$"; public static String REQUEST_DELIMITIER = "/$$";
public static String OWNER_PARAM = "OWNER"; public static String FILTER_KEY = "FKEY";
public static String FILTER_VALUE = "FVALUE";
} }

View File

@ -21,7 +21,8 @@ import org.gcube.datatransfer.resolver.ResourceCatalogueCodes;
import org.gcube.datatransfer.resolver.UriResolverRewriteFilter; import org.gcube.datatransfer.resolver.UriResolverRewriteFilter;
import org.gcube.datatransfer.resolver.applicationprofile.ApplicationProfileNotFoundException; import org.gcube.datatransfer.resolver.applicationprofile.ApplicationProfileNotFoundException;
import org.gcube.datatransfer.resolver.catalogue.resource.ApplicationProfileReaderForCatalogueResolver; import org.gcube.datatransfer.resolver.catalogue.resource.ApplicationProfileReaderForCatalogueResolver;
import org.gcube.datatransfer.resolver.catalogue.resource.CkanPorltetApplicationProfile; import org.gcube.datatransfer.resolver.catalogue.resource.CkanCatalogueConfigurationsReader;
import org.gcube.datatransfer.resolver.catalogue.resource.GatewayCKANCatalogueReference;
import org.gcube.datatransfer.resolver.catalogue.resource.UpdateApplicationProfileCatalogueResolver; import org.gcube.datatransfer.resolver.catalogue.resource.UpdateApplicationProfileCatalogueResolver;
import org.gcube.datatransfer.resolver.scope.ScopeUtil; import org.gcube.datatransfer.resolver.scope.ScopeUtil;
import org.json.JSONArray; import org.json.JSONArray;
@ -30,6 +31,8 @@ import org.json.JSONObject;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import eu.trentorise.opendata.jackan.model.CkanDataset;
/** /**
* The Class GisResolver. * The Class GisResolver.
@ -200,14 +203,35 @@ public class CatalogueResolver extends HttpServlet{
try{ try{
logger.info("Setting scope "+scope+ " to search Ckan Portlet URL from IS"); logger.info("Setting scope "+scope+ " to search Ckan Portlet URL from IS");
ScopeProvider.instance.set(scope); ScopeProvider.instance.set(scope);
ckanPorltetUrl = CkanPorltetApplicationProfile.getPortletUrlFromInfrastrucure(); GatewayCKANCatalogueReference ckanCatalogueReference = CkanCatalogueConfigurationsReader.loadCatalogueEndPoints();
//IS THE PRODUCT PLUBLIC OR PRIVATE?
//USING ACCESS TO PUBLIC PORTLET IF THE ITEM IS PUBLIC, OTHERWISE ACCESS TO PRIVATE PORTLET
ckanPorltetUrl = ckanCatalogueReference.getPrivatePortletURL();
String datasetName = cer.getValueOfParameter(CatalogueRequestParameter.ENTITY_NAME.getKey());
if(ckanCatalogueReference.getCkanURL()!=null){
try{
CkanDataset dataset = CkanCatalogueConfigurationsReader.getDataset(datasetName, ckanCatalogueReference.getCkanURL());
if(dataset!=null){
ckanPorltetUrl = ckanCatalogueReference.getPublicPortletURL();
logger.info("The dataset "+datasetName+" is a public item using public access to CKAN portlet: "+ckanPorltetUrl);
}
}catch(Exception e){
logger.warn("Error on checking if dataset: "+datasetName+" is private or not");
ckanPorltetUrl = ckanCatalogueReference.getPublicPortletURL();
}
}
if(ckanPorltetUrl == null || ckanPorltetUrl.isEmpty()){ if(ckanPorltetUrl == null || ckanPorltetUrl.isEmpty()){
sendError(resp, HttpStatus.SC_INTERNAL_SERVER_ERROR, "An error occurred during discovery Data Catalogue URL, try again later"); sendError(resp, HttpStatus.SC_INTERNAL_SERVER_ERROR, "An error occurred during discovery the resource: "+CkanCatalogueConfigurationsReader.APPLICATION_PROFILE_NAME+" in the scope: "+scope+", try again later");
return; return;
} }
}catch(Exception e){ }catch(Exception e){
logger.error("An error occurred during discovery Data Catalogue URL: ",e); logger.error("Error during discovery the resource: "+CkanCatalogueConfigurationsReader.APPLICATION_PROFILE_NAME+" in the scope: "+scope, e);
sendError(resp, HttpStatus.SC_INTERNAL_SERVER_ERROR, "An error occurred during discovery Data Catalogue URL, try again later"); sendError(resp, HttpStatus.SC_INTERNAL_SERVER_ERROR, "An error occurred during discovery the resource: "+CkanCatalogueConfigurationsReader.APPLICATION_PROFILE_NAME+" in the scope: "+scope+", try again later");
return; return;
}finally{ }finally{
@ -227,6 +251,7 @@ public class CatalogueResolver extends HttpServlet{
buildPath+= PATH_SEPARATOR+cer.getValueOfParameter(CatalogueRequestParameter.ENTITY_CONTEXT.getKey()) + PATH_SEPARATOR; buildPath+= PATH_SEPARATOR+cer.getValueOfParameter(CatalogueRequestParameter.ENTITY_CONTEXT.getKey()) + PATH_SEPARATOR;
buildPath+=cer.getValueOfParameter(CatalogueRequestParameter.ENTITY_NAME.getKey()); buildPath+=cer.getValueOfParameter(CatalogueRequestParameter.ENTITY_NAME.getKey());
String finalUrl = ckanPorltetUrl+"?"+buildPath; String finalUrl = ckanPorltetUrl+"?"+buildPath;
logger.info("Builded final URL: "+finalUrl); logger.info("Builded final URL: "+finalUrl);
resp.sendRedirect(resp.encodeRedirectURL(finalUrl)); resp.sendRedirect(resp.encodeRedirectURL(finalUrl));
@ -511,7 +536,7 @@ public class CatalogueResolver extends HttpServlet{
public static void main(String[] args) { public static void main(String[] args) {
try{ try{
String scope = "d4science.research"; String scope = "/d4science.research-infrastructures.eu";
ApplicationProfileReaderForCatalogueResolver appPrCatResolver = new ApplicationProfileReaderForCatalogueResolver(scope, true); ApplicationProfileReaderForCatalogueResolver appPrCatResolver = new ApplicationProfileReaderForCatalogueResolver(scope, true);
logger.info("Reosurce for Catalogue Resolver: "+appPrCatResolver); logger.info("Reosurce for Catalogue Resolver: "+appPrCatResolver);
}catch(Exception e){ }catch(Exception e){

View File

@ -0,0 +1,139 @@
/**
*
*/
package org.gcube.datatransfer.resolver.catalogue.endpoint;
import static org.gcube.resources.discovery.icclient.ICFactory.clientFor;
import static org.gcube.resources.discovery.icclient.ICFactory.queryFor;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.gcube.common.resources.gcore.ServiceEndpoint;
import org.gcube.common.scope.api.ScopeProvider;
import org.gcube.datacatalogue.ckanutillibrary.server.DataCatalogueImpl;
import org.gcube.resources.discovery.client.api.DiscoveryClient;
import org.gcube.resources.discovery.client.queries.api.SimpleQuery;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* The Class CatalogueServiceEndpointReader.
*
* @author Francesco Mangiacrapa francesco.mangiacrapa@isti.cnr.it
* Apr 20, 2018
*/
public class CatalogueServiceEndpointReader {
// data catalogue info
private final static String RUNTIME_CATALOGUE_RESOURCE_NAME = "CKanDataCatalogue";
private final static String PLATFORM_CATALOGUE_NAME = "Tomcat";
private final static String CKAN_IS_ROOT_MASTER = "IS_ROOT_MASTER";
private static final Logger logger = LoggerFactory.getLogger(CatalogueServiceEndpointReader.class);
/** A map to cache couple SCOPE - THE CKAN PORTLET URL OPERATING IN THE SCOPE*/
private static Map<String, String> cacheCkanDataCatalogue = new HashMap<String, String>();
/**
* Instantiates a new catalogue service endpoint reader.
*/
public CatalogueServiceEndpointReader(){
}
/**
* Retrieve endpoints information from IS for DataCatalogue URL.
*
* @return list of endpoints for ckan data catalogue
* @throws Exception the exception
*/
public static List<ServiceEndpoint> getConfigurationFromISFORCatalogueUrl() throws Exception{
logger.info("Searching SE "+RUNTIME_CATALOGUE_RESOURCE_NAME+" configurations in the scope: "+ScopeProvider.instance.get());
SimpleQuery query = queryFor(ServiceEndpoint.class);
query.addCondition("$resource/Profile/Name/text() eq '"+ RUNTIME_CATALOGUE_RESOURCE_NAME +"'");
query.addCondition("$resource/Profile/Platform/Name/text() eq '"+ PLATFORM_CATALOGUE_NAME +"'");
query.addVariable("$prop", "$resource/Profile/AccessPoint/Properties/Property")
.addCondition("$prop/Name/text() eq '"+CKAN_IS_ROOT_MASTER+"'")
.addCondition("$prop/Value/text() eq 'true'");
logger.info("Performing query 1 with property '"+CKAN_IS_ROOT_MASTER+"': "+query);
DiscoveryClient<ServiceEndpoint> client = clientFor(ServiceEndpoint.class);
List<ServiceEndpoint> toReturn = client.submit(query);
logger.info("The query 1 returned "+toReturn.size()+ " ServiceEndpoint/s");
if(toReturn.size()==0){
logger.info("NO "+RUNTIME_CATALOGUE_RESOURCE_NAME+" having "+CKAN_IS_ROOT_MASTER+" property");
query = queryFor(ServiceEndpoint.class);
query.addCondition("$resource/Profile/Name/text() eq '"+ RUNTIME_CATALOGUE_RESOURCE_NAME +"'");
query.addCondition("$resource/Profile/Platform/Name/text() eq '"+ PLATFORM_CATALOGUE_NAME +"'");
logger.info("Performing query 2: "+query);
client = clientFor(ServiceEndpoint.class);
toReturn = client.submit(query);
logger.info("The query 2 returned "+toReturn.size()+ " ServiceEndpoint/s");
}
return toReturn;
}
/**
* Gets the catalogue url.
*
* @return the catalogue url
*/
public static String getCatalogueUrl() {
String scope = ScopeProvider.instance.get();
logger.debug("Getting Catalogue URL for scope: "+scope +" read from ScopeProvider");
String catalogueURLForScope = cacheCkanDataCatalogue.get(scope);
if(catalogueURLForScope==null){
logger.debug("Catalogue URL not found in cache, loading from IS");
try{
logger.debug("Instancing again the scope provider with scope value: "+scope);
ScopeProvider.instance.set(scope);
DataCatalogueImpl utilCKAN = new DataCatalogueImpl(scope);
catalogueURLForScope = utilCKAN.getCatalogueUrl();
if(catalogueURLForScope==null)
throw new Exception("No cataluge url found in the scope: "+scope);
cacheCkanDataCatalogue.put(scope, catalogueURLForScope);
}catch(Exception e){
logger.error("Error on getting the catalogue url in the scope: "+scope, e);
}
}
logger.info("Returning Catalogue URL: "+catalogueURLForScope +" for the scope: "+scope);
return catalogueURLForScope;
}
// /**
// * The main method.
// *
// * @param args the arguments
// */
// public static void main(String[] args) {
//
// String scope = "/d4science.research-infrastructures.eu/gCubeApps/BiodiversityLab";
// ScopeProvider.instance.set(scope);
// try {
// String catalogueURL = CatalogueServiceEndpointReader.getCatalogueUrl(scope);
// System.out.println(catalogueURL);
// }
// catch (Exception e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
// }
}

View File

@ -0,0 +1,193 @@
/**
*
*/
package org.gcube.datatransfer.resolver.catalogue.resource;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.gcube.resources.discovery.icclient.ICFactory.client;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.net.URI;
import java.util.List;
import java.util.Properties;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.gcube.common.resources.gcore.utils.XPathHelper;
import org.gcube.common.scope.api.ScopeProvider;
import org.gcube.datatransfer.resolver.applicationprofile.ApplicationProfileNotFoundException;
import org.gcube.datatransfer.resolver.catalogue.endpoint.CatalogueServiceEndpointReader;
import org.gcube.resources.discovery.client.api.DiscoveryClient;
import org.gcube.resources.discovery.client.queries.api.Query;
import org.gcube.resources.discovery.client.queries.impl.QueryBox;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Node;
import org.xml.sax.InputSource;
import eu.trentorise.opendata.jackan.CkanClient;
import eu.trentorise.opendata.jackan.model.CkanDataset;
/**
* The Class CkanCatalogueConfigurationsReader.
*
* @author Francesco Mangiacrapa francesco.mangiacrapa@isti.cnr.it
* Apr 20, 2018
*/
public class CkanCatalogueConfigurationsReader {
private static final Logger logger = LoggerFactory.getLogger(CkanCatalogueConfigurationsReader.class);
public final static String APPLICATION_PROFILE_NAME = "CkanPortlet";
private static final String DATACATALOGUECONFIGURATION_PROPERTIES = "datacatalogueconfiguration.properties";
/**
* Load catalogue end points.
*
* @return the gateway ckan catalogue reference
* @throws Exception the exception
*/
public static GatewayCKANCatalogueReference loadCatalogueEndPoints() throws Exception{
GatewayCKANCatalogueReference links = new GatewayCKANCatalogueReference();
links.setScope(ScopeProvider.instance.get());
String privatePortletURL = getPortletUrlForScopeFromIS();
links.setPrivatePortletURL(privatePortletURL);
//Building public URL from private portlet URL
try{
URI toURL = new URI(privatePortletURL);
String publicURL = privatePortletURL.startsWith("https://")?"https://"+toURL.getHost():"http://"+toURL.getHost();
String realiveURLToPublicCtlg = getRelativeURLToCatalogue();
links.setPublicPortletURL(publicURL+"/"+realiveURLToPublicCtlg);
}catch(Exception e){
logger.warn("Erron on generating public catalogue URL from private URL: "+privatePortletURL, e);
}
//Getting the CKAN Portet URL for current scope
try{
String ckanPortletURL = CatalogueServiceEndpointReader.getCatalogueUrl();
links.setCkanURL(ckanPortletURL);
}catch(Exception e){
logger.warn("Erron on getting CKAN Porlet URL for scope: "+ScopeProvider.instance.get(), e);
}
return links;
}
/**
* Retrieve a ckan dataset given its id. The CkanClient is used, without api key. The result is null also when the dataset is private.
* @param datasetIdorName
* @param catalogueURL
* @return
* @throws Exception
*/
public static CkanDataset getDataset(String datasetIdorName, String catalogueURL) throws Exception{
logger.info("Request ckan dataset with id " + datasetIdorName);
// checks
checkNotNull(datasetIdorName);
checkArgument(!datasetIdorName.isEmpty());
CkanClient client = new CkanClient(catalogueURL);
return client.getDataset(datasetIdorName);
}
/**
* Gets the portlet url for scope from is.
*
* @return the portlet url for scope from is
* @throws Exception the exception
*/
private static String getPortletUrlForScopeFromIS() throws Exception {
String scope = ScopeProvider.instance.get();
logger.debug("Trying to fetch applicationProfile profile from the infrastructure for " +
APPLICATION_PROFILE_NAME + " scope: " + scope);
try {
Query q =
new QueryBox(
"for $profile in collection('/db/Profiles/GenericResource')//Resource " +
"where $profile/Profile/SecondaryType/string() eq 'ApplicationProfile' and $profile/Profile/Name/string() " +
" eq '" +
APPLICATION_PROFILE_NAME +
"'" +
"return $profile");
DiscoveryClient<String> client = client();
List<String> appProfile = client.submit(q);
if (appProfile == null || appProfile.size() == 0)
throw new ApplicationProfileNotFoundException(
"Your applicationProfile is not registered in the infrastructure");
else {
String elem = appProfile.get(0);
DocumentBuilder docBuilder =
DocumentBuilderFactory.newInstance().newDocumentBuilder();
Node node = docBuilder.parse(new InputSource(new StringReader(elem))).getDocumentElement();
XPathHelper helper = new XPathHelper(node);
List<String> currValue = null;
currValue =
helper.evaluate("/Resource/Profile/Body/url/text()");
if (currValue != null && currValue.size() > 0) {
logger.debug("CKAN Portlet url found is " + currValue.get(0));
return currValue.get(0);
}
}
}
catch (Exception e) {
throw new Exception("Error while trying to fetch applicationProfile profile for name "+APPLICATION_PROFILE_NAME+"from the infrastructure, using scope: "+scope);
}
return null;
}
/**
* Gets the relative url to catalogue.
*
* @return the relative url to catalogue
*/
private static String getRelativeURLToCatalogue(){
Properties prop = new Properties();
String relativeURLToCatalogue = null;
try {
InputStream in = CkanCatalogueConfigurationsReader.class.getResourceAsStream(DATACATALOGUECONFIGURATION_PROPERTIES);
// load a properties file
prop.load(in);
// get the property value
relativeURLToCatalogue = prop.getProperty("PORTAL_RELATIVE_URL_TO_CATALOGUE");
if(relativeURLToCatalogue==null || relativeURLToCatalogue.isEmpty())
return "catalogue";
} catch (IOException e) {
logger.error("An error occurred on read property file: "+DATACATALOGUECONFIGURATION_PROPERTIES, e);
}
return relativeURLToCatalogue;
}
// /**
// * The main method.
// *
// * @param args the arguments
// */
// public static void main(String[] args) {
//
// ScopeProvider.instance.set("/gcube/devsec/devVRE");
// try {
// GatewayCKANCatalogueReference links = CkanCatalogueConfigurationsReader.loadCatalogueEndPoints();
// System.out.println(links);
// }
// catch (Exception e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
// }
}

View File

@ -1,84 +0,0 @@
/**
*
*/
package org.gcube.datatransfer.resolver.catalogue.resource;
import static org.gcube.resources.discovery.icclient.ICFactory.client;
import java.io.StringReader;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.gcube.common.resources.gcore.utils.XPathHelper;
import org.gcube.common.scope.api.ScopeProvider;
import org.gcube.datatransfer.resolver.applicationprofile.ApplicationProfileNotFoundException;
import org.gcube.resources.discovery.client.api.DiscoveryClient;
import org.gcube.resources.discovery.client.queries.api.Query;
import org.gcube.resources.discovery.client.queries.impl.QueryBox;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Node;
import org.xml.sax.InputSource;
/**
* The Class CkanPorltetApplicationProfile.
*
* @author Francesco Mangiacrapa francesco.mangiacrapa@isti.cnr.it
* May 16, 2017
*/
public class CkanPorltetApplicationProfile {
private static final Logger logger = LoggerFactory.getLogger(CkanPorltetApplicationProfile.class);
private final static String APPLICATION_PROFILE_NAME = "CkanPortlet";
/**
* Gets the portlet url from infrastrucure.
*
* @return the portlet url from infrastrucure
* @throws Exception the exception
*/
public static String getPortletUrlFromInfrastrucure() throws Exception {
String scope = ScopeProvider.instance.get();
logger.debug("Trying to fetch applicationProfile profile from the infrastructure for " +
APPLICATION_PROFILE_NAME + " scope: " + scope);
try {
Query q =
new QueryBox(
"for $profile in collection('/db/Profiles/GenericResource')//Resource " +
"where $profile/Profile/SecondaryType/string() eq 'ApplicationProfile' and $profile/Profile/Name/string() " +
" eq '" +
APPLICATION_PROFILE_NAME +
"'" +
"return $profile");
DiscoveryClient<String> client = client();
List<String> appProfile = client.submit(q);
if (appProfile == null || appProfile.size() == 0)
throw new ApplicationProfileNotFoundException(
"Your applicationProfile is not registered in the infrastructure");
else {
String elem = appProfile.get(0);
DocumentBuilder docBuilder =
DocumentBuilderFactory.newInstance().newDocumentBuilder();
Node node = docBuilder.parse(new InputSource(new StringReader(elem))).getDocumentElement();
XPathHelper helper = new XPathHelper(node);
List<String> currValue = null;
currValue =
helper.evaluate("/Resource/Profile/Body/url/text()");
if (currValue != null && currValue.size() > 0) {
logger.debug("CKAN Portlet url found is " + currValue.get(0));
return currValue.get(0);
}
}
}
catch (Exception e) {
throw new Exception("Error while trying to fetch applicationProfile profile for name "+APPLICATION_PROFILE_NAME+"from the infrastructure, using scope: "+scope);
}
return null;
}
}

View File

@ -0,0 +1,140 @@
/**
*
*/
package org.gcube.datatransfer.resolver.catalogue.resource;
import java.io.Serializable;
/**
*
* @author Francesco Mangiacrapa francesco.mangiacrapa@isti.cnr.it
* Nov 23, 2017
*/
public class GatewayCKANCatalogueReference implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
private String privatePortletURL;
private String publicPortletURL;
private String scope;
private String ckanURL;
/**
*
*/
public GatewayCKANCatalogueReference() {
}
/**
* @param privatePortletURL
* @param publicPortletURL
* @param ckanURL
* @param scope
*/
public GatewayCKANCatalogueReference(String scope,
String privatePortletURL, String publicPortletURL, String ckanURL) {
this.scope = scope;
this.privatePortletURL = privatePortletURL;
this.publicPortletURL = publicPortletURL;
this.ckanURL = ckanURL;
}
/**
* @return the ckanURL
*/
public String getCkanURL() {
return ckanURL;
}
/**
* @param ckanURL the ckanURL to set
*/
public void setCkanURL(String ckanURL) {
this.ckanURL = ckanURL;
}
/**
* @return the privatePortletURL
*/
public String getPrivatePortletURL() {
return privatePortletURL;
}
/**
* @return the publicPortletURL
*/
public String getPublicPortletURL() {
return publicPortletURL;
}
/**
* @return the scope
*/
public String getScope() {
return scope;
}
/**
* @param privatePortletURL the privatePortletURL to set
*/
public void setPrivatePortletURL(String privatePortletURL) {
this.privatePortletURL = privatePortletURL;
}
/**
* @param publicPortletURL the publicPortletURL to set
*/
public void setPublicPortletURL(String publicPortletURL) {
this.publicPortletURL = publicPortletURL;
}
/**
* @param scope the scope to set
*/
public void setScope(String scope) {
this.scope = scope;
}
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("GatewayCatalogueReference [privatePortletURL=");
builder.append(privatePortletURL);
builder.append(", publicPortletURL=");
builder.append(publicPortletURL);
builder.append(", scope=");
builder.append(scope);
builder.append(", ckanURL=");
builder.append(ckanURL);
builder.append("]");
return builder.toString();
}
}

View File

@ -0,0 +1,7 @@
# Property files
#
# author Francesco Mangiacrapa francesco.mangiacrapa@isti.cnr.it
# created 11/2017
#
PORTAL_RELATIVE_URL_TO_CATALOGUE = catalogue

View File

@ -34,44 +34,101 @@ public class FilterGetRecords {
private List<String> foundPublicIds = null; private List<String> foundPublicIds = null;
private static FilterGetRecords instance = null;
private Object lock1 = new Object();
private long delay = 60000; //1 min
/** /**
* Instantiates a new filter get records. * Instantiates a new filter get records.
*
* @param readBody the read body
*/ */
public FilterGetRecords(String readBody) { private FilterGetRecords() {
if(readBody!=null && !readBody.isEmpty() && readBody.contains(CSW_GET_RECORDS)){ new java.util.Timer().scheduleAtFixedRate(new java.util.TimerTask() {
logger.info("Is "+CSW_GET_RECORDS+" request, getting public ids");
GeoNetworkReader reader;
try {
reader = GeoNetwork.get();
final GNSearchRequest req=new GNSearchRequest();
req.addParam(GNSearchRequest.Param.any,"");
GNSearchResponse resp=reader.query(req);
foundPublicIds = new ArrayList<String>(); @Override
Iterator<GNMetadata> iterator=resp.iterator(); public void run() {
while(iterator.hasNext()){
foundPublicIds.add(iterator.next().getUUID()); resetCache();
}
logger.info("Public Metadata ids are: "+foundPublicIds.size());
}catch (Exception e) {
logger.error("Error during sending GNSearchRequest: ",e);
} }
}else }, delay, delay);
logger.trace("Is not a"+CSW_GET_RECORDS+" request, skipping");
} }
/**
* Gets the single instance of FilterGetRecords.
*
* @return single instance of FilterGetRecords
*/
public static FilterGetRecords getInstance() {
if(instance == null)
instance = new FilterGetRecords();
return instance;
}
public void resetCache(){
synchronized(lock1) {
foundPublicIds = null;
logger.info("Reset publid ids performed");
}
}
/** /**
* Gets the public file identifiers. * Gets the public file identifiers.
* *
* @param bodyRequest the body request
* @param useCache the use cache
* @return the public file identifiers * @return the public file identifiers
*/ */
public List<String> getPublicFileIdentifiers(){ public List<String> getPublicFileIdentifiers(String bodyRequest, boolean useCache){
//System.out.println("the readBody: "+readBody);
synchronized (lock1) {
if(bodyRequest!=null && !bodyRequest.isEmpty() && bodyRequest.contains(CSW_GET_RECORDS)){
if(useCache && foundPublicIds!=null)
return foundPublicIds;
logger.info("Is "+CSW_GET_RECORDS+" request, getting public ids");
GeoNetworkReader reader;
try {
reader = GeoNetwork.get();
final GNSearchRequest req=new GNSearchRequest();
req.addParam(GNSearchRequest.Param.any,"");
GNSearchResponse resp=reader.query(req);
foundPublicIds = new ArrayList<String>();
Iterator<GNMetadata> iterator=resp.iterator();
while(iterator.hasNext()){
foundPublicIds.add(iterator.next().getUUID());
}
logger.info("Public Metadata ids are: "+foundPublicIds.size());
}catch (Exception e) {
logger.error("Error during sending GNSearchRequest: ",e);
}
}else
logger.trace("Is not a: "+CSW_GET_RECORDS+" request, skipping");
return foundPublicIds;
}
}
/**
* Csw request get public identifier.
*
* @return the list
*/
public List<String> cswRequestGetPublicIdentifier(){
logger.info("Performing query to retrieve the public file identifiers"); logger.info("Performing query to retrieve the public file identifiers");
GeoNetworkReader reader; GeoNetworkReader reader;

View File

@ -3,6 +3,8 @@
*/ */
package org.gcube.datatransfer.resolver.gis.geonetwork; package org.gcube.datatransfer.resolver.gis.geonetwork;
import static org.gcube.common.authorization.client.Constants.authorizationService;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
@ -24,6 +26,7 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.gcube.common.authorization.library.AuthorizationEntry;
import org.gcube.common.scope.api.ScopeProvider; import org.gcube.common.scope.api.ScopeProvider;
import org.gcube.datatransfer.resolver.GeonetworkRequestFilterParameters; import org.gcube.datatransfer.resolver.GeonetworkRequestFilterParameters;
import org.gcube.datatransfer.resolver.GeonetworkRequestFilterParameters.MODE; import org.gcube.datatransfer.resolver.GeonetworkRequestFilterParameters.MODE;
@ -54,6 +57,15 @@ import org.w3c.dom.Document;
*/ */
public class GeonetworkResolver extends HttpServlet{ public class GeonetworkResolver extends HttpServlet{
/**
*
*/
public static final String REPLACED_UUID_BY_FILTER_PLEASE_IGNORE =
"Replaced UUID by GeonetworkResolver filter, please ignore";
/**
*
*/
public static final String REPLACED_A_PUBLIC_UUID_PLEASE_IGNORE = "Replaced a public UUID, please ignore";
/** /**
* *
*/ */
@ -71,6 +83,7 @@ public class GeonetworkResolver extends HttpServlet{
*/ */
private static final long serialVersionUID = -61097584153314181L; private static final long serialVersionUID = -61097584153314181L;
public static final String SCOPE = "scope"; public static final String SCOPE = "scope";
public static final String GCUBETOKEN = "gcube-token";
public static final String REMAIN_PATH_PARAM = "remainPath"; public static final String REMAIN_PATH_PARAM = "remainPath";
public static final String RESET_CACHE_PARAM = "resetcache"; public static final String RESET_CACHE_PARAM = "resetcache";
public static final String RESET_CACHED_SCOPE_PARAM = "resetcachedscope"; public static final String RESET_CACHED_SCOPE_PARAM = "resetcachedscope";
@ -92,6 +105,7 @@ public class GeonetworkResolver extends HttpServlet{
//TEN SECONDS //TEN SECONDS
public static final long CACHE_RESET_DELAY = 10*1000; public static final long CACHE_RESET_DELAY = 10*1000;
/* (non-Javadoc) /* (non-Javadoc)
* @see javax.servlet.GenericServlet#init() * @see javax.servlet.GenericServlet#init()
*/ */
@ -116,18 +130,20 @@ public class GeonetworkResolver extends HttpServlet{
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
logger.info("doGET running... query string: "+req.getQueryString()); logger.info("doGET running... query string: "+req.getQueryString());
String scopeValue = req.getParameter(SCOPE); String scopeValue = req.getParameter(SCOPE);
String gCubeToken = req.getParameter(GCUBETOKEN);
String remainValue = req.getParameter(REMAIN_PATH_PARAM); String remainValue = req.getParameter(REMAIN_PATH_PARAM);
String mode = req.getParameter(GeonetworkRequestFilterParameters.MODE.class.getSimpleName()); String mode = req.getParameter(GeonetworkRequestFilterParameters.MODE.class.getSimpleName());
String visibility = req.getParameter(GeonetworkRequestFilterParameters.VISIBILITY.class.getSimpleName()); String visibility = req.getParameter(GeonetworkRequestFilterParameters.VISIBILITY.class.getSimpleName());
String owner = req.getParameter(GeonetworkRequestFilterParameters.OWNER_PARAM); String filterKeyParam = req.getParameter(GeonetworkRequestFilterParameters.FILTER_KEY);
String filterValueParam = req.getParameter(GeonetworkRequestFilterParameters.FILTER_VALUE);
String resetCache = req.getParameter(RESET_CACHE_PARAM); String resetCache = req.getParameter(RESET_CACHE_PARAM);
String resetScope = req.getParameter(RESET_CACHED_SCOPE_PARAM); String resetScope = req.getParameter(RESET_CACHED_SCOPE_PARAM);
String originalScope = ScopeProvider.instance.get(); String originalScope = ScopeProvider.instance.get();
if (scopeValue == null || scopeValue.equals("")) { if ((scopeValue == null || scopeValue.isEmpty()) && (gCubeToken==null || gCubeToken.isEmpty())) {
logger.debug("Scope not found"); logger.debug("Scope not found");
sendError(resp, HttpServletResponse.SC_BAD_REQUEST, SCOPE+" not found or empty"); sendError(resp, HttpServletResponse.SC_BAD_REQUEST, SCOPE+" and "+GCUBETOKEN+" not found or empty");
return; return;
} }
@ -146,19 +162,24 @@ public class GeonetworkResolver extends HttpServlet{
} }
logger.info("SCOPE: " + scopeValue); logger.info("SCOPE: " + scopeValue);
logger.info("GCUBETOKEN: " + gCubeToken);
logger.info("MODE is: "+theMode); logger.info("MODE is: "+theMode);
logger.info("VISIBILITY is: "+theVisibility); logger.info("VISIBILITY is: "+theVisibility);
logger.info(GeonetworkRequestFilterParameters.OWNER_PARAM +" is: "+owner); logger.info(GeonetworkRequestFilterParameters.FILTER_KEY +" is: "+filterKeyParam);
logger.info(GeonetworkRequestFilterParameters.FILTER_VALUE +" is: "+filterValueParam);
try { try {
GeonetworkInstance gnInstance = getGeonetworkInstanceForScope(scopeValue); if(isValidToken(gCubeToken)){
AuthorizationEntry entry = authorizationService().get(gCubeToken);
//retrieve the info of the token owner
//entry.getClientInfo();
//retrieve the context of the token owner
scopeValue = entry.getContext();
logger.info("Got scope "+scopeValue+" from token: "+gCubeToken+" via authorization service");
}
// if(gnInstance==null){ GeonetworkInstance gnInstance = getGeonetworkInstanceForScope(scopeValue);
// logger.info("GeonetworkInstance not istanciable via geonetwork library.. using ");
// ServerParameters serverParams = getGeonetworkCachedServerParameters(scopeValue);
// gnInstance = gntwAccess.getGeonetworkInstance();
// }
ScopeProvider.instance.set(scopeValue); ScopeProvider.instance.set(scopeValue);
@ -221,6 +242,272 @@ public class GeonetworkResolver extends HttpServlet{
} }
} }
/* (non-Javadoc)
* @see javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
* This call is authenticated
*/
@SuppressWarnings("resource")
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {
/*MultiReadHttpServletRequest req2;
if(req instanceof MultiReadHttpServletRequest)
req2 = (MultiReadHttpServletRequest) req;*/
String originalScope = ScopeProvider.instance.get();
logger.info("doPost running...");
String scope = req.getParameter(SCOPE);
String gCubeToken = req.getParameter(GCUBETOKEN);
String remainValue = req.getParameter(REMAIN_PATH_PARAM);
String mode = req.getParameter(GeonetworkRequestFilterParameters.MODE.class.getSimpleName());
String visibility = req.getParameter(GeonetworkRequestFilterParameters.VISIBILITY.class.getSimpleName());
//HOW TO PASS MORE THAN ONE?
String filterKeyParam = req.getParameter(GeonetworkRequestFilterParameters.FILTER_KEY);
String filterValueParam = req.getParameter(GeonetworkRequestFilterParameters.FILTER_VALUE);
Map<String,String> filters = new HashMap<String, String>();
//boolean filterPublicMetadata = false;
boolean noAuthenticationB = false;
MODE theMode;
VISIBILITY theVisibility;
if ((scope == null || scope.isEmpty()) && (gCubeToken==null || gCubeToken.isEmpty())) {
logger.debug("Scope not found");
sendError(resp, HttpServletResponse.SC_BAD_REQUEST, SCOPE+" and "+GCUBETOKEN+" not found or empty");
return;
}
theMode = GeonetworkRequestFilterParameters.MODE.valueOf(mode);
theVisibility = GeonetworkRequestFilterParameters.VISIBILITY.valueOf(visibility);
logger.info(SCOPE +" is: " + scope);
logger.info(GeonetworkRequestFilterParameters.MODE.class.getSimpleName() +" is: "+theMode);
logger.info(GeonetworkRequestFilterParameters.VISIBILITY.class.getSimpleName() +" is: "+theVisibility);
logger.info(GeonetworkRequestFilterParameters.FILTER_KEY +" are: "+filterKeyParam);
logger.info(GeonetworkRequestFilterParameters.FILTER_VALUE +" are: "+filterValueParam);
if(filterKeyParam!=null && filterValueParam!=null){
filters.put(filterKeyParam, filterValueParam);
logger.debug("Added filter parmas to map filters: "+filters);
}
try {
if(isValidToken(gCubeToken)){
AuthorizationEntry entry = authorizationService().get(gCubeToken);
//retrieve the info of the token owner
//entry.getClientInfo();
//retrieve the context of the token owner
scope = entry.getContext();
logger.info("Got scope "+scope+" from token: "+gCubeToken+" via authorization service");
}
GeonetworkServiceInterface gntwAccess = new GeonetworkAccessParameter(scope);
GeonetworkInstance gnInstance = gntwAccess.getGeonetworkInstance();
ScopeProvider.instance.set(scope);
logger.info("set scope provider "+scope);
Configuration config = gnInstance.getGeonetworkPublisher().getConfiguration();
Account account = config.getScopeConfiguration().getAccounts().get(Type.CKAN);
logger.info("CKAN user owner is: "+account.getUser());
logger.info("Parameters..");
for (Enumeration<String> e = req.getParameterNames(); e.hasMoreElements();){
String p = e.nextElement();
logger.debug("param "+p + " value "+Arrays.toString(req.getParameterValues(p)));
}
//DEBUG BODY
// String readBody = IOUtils.toString(req.getReader());
// logger.debug("doPost read body request: "+readBody);
ByteArrayOutputStream byteArray = new ByteArrayOutputStream();
String geonetworkUrl = config.getGeoNetworkEndpoint();
// SPECIFIC HANDLER FOR GEONETWORK REQUEST: /srv/en/mef.export
String gnCSWlURL;
if(remainValue!=null && remainValue.compareTo(SRV_EN_MEF_EXPORT)==0){
logger.info("In case of mef.export, perfoming a custom handler");
gnCSWlURL = geonetworkUrl + SRV_EN_MEF_EXPORT;
String[] uuidValues = req.getParameterValues(UUID);
if(uuidValues!=null){
String data = null;
for (String uuid : uuidValues) {
data = UUID+"="+uuid;
}
if(data!=null){
logger.debug("Writing "+data +" into byte array");
byteArray.write(data.getBytes());
}else
IOUtils.copy(req.getReader(), byteArray);
}else
IOUtils.copy(req.getReader(), byteArray);
}else{
gnCSWlURL = remainValue==null ||remainValue.isEmpty()?geonetworkUrl+"/"+CSW_SERVER:geonetworkUrl+"/"+CSW_SERVER+remainValue;
IOUtils.copy(req.getReader(), byteArray);
}
//filterPublicMetadata = theVisibility.equals(VISIBILITY.PRV)?true:false;
HTTPCallsUtils httpUtils = new HTTPCallsUtils();
//String theOwner = null;
//PRIVATE LAYERS
if(theVisibility.equals(VISIBILITY.PRV)){
logger.debug("Visibility: "+VISIBILITY.PRV+" getting private layers..");
//VRE LAYERS
if(theMode.equals(MODE.VRE)){
logger.debug("Getting "+MODE.VRE+" layers..");
//HARVESTED LAYERS
}else{
// logger.debug("Getting "+MODE.HARVEST+" layers, I'm using filters [key: '"+filter_keys +"' and value: '"+filter_values +"'] passed as parameter to filter layer/s returned..");
// if(filter_keys==null || filter_keys.isEmpty() || filter_values==null || filter_values.isEmpty()){
// String error = "Harvest owner is missing. It is not possible to filter layers for the request "+MODE.HARVEST + " in the scope: "+scope+", without a valid filter as input";
// logger.error(error);
// sendError(resp, HttpServletResponse.SC_BAD_REQUEST, error);
// return;
// }
filters.put("isHarvested", "y");
logger.debug("Getting "+MODE.HARVEST+" layers, I'm using filters ["+filters+"]");
}
if(account.getUser()!=null){
boolean authorized = GNAuthentication.login(httpUtils, geonetworkUrl, account.getUser(), account.getPassword());
logger.trace("Authorized on "+geonetworkUrl +" ? "+authorized);
}else
logger.info("Skipping authentication, ckan user (the owner) is null");
//PUBLIC LAYERS
}else{
logger.debug("Visibility: "+VISIBILITY.PUB+" getting public layers..");
//VRE LAYERS
if(theMode.equals(MODE.VRE)){
logger.debug("Getting "+MODE.VRE+" layers, the VRE account: "+account.getUser() +" will be used as owner user for filtering... Is it right?");
filters.put("ownername", account.getUser());
//HARVESTED LAYERS
}else{
// logger.debug("Getting "+MODE.HARVEST+" layers, I'm using filters [key: '"+filter_keys +"' and value: '"+filter_values +"'] passed as parameter to filter layer/s returned..");
// if(filter_keys==null || filter_keys.isEmpty() || filter_values==null || filter_values.isEmpty()){
// String error = "Harvest owner is missing. It is not possible to filter layers for the request "+MODE.HARVEST + " in the scope: "+scope+", without a valid filter as input";
// logger.error(error);
// sendError(resp, HttpServletResponse.SC_BAD_REQUEST, error);
// return;
// }
filters.put("isHarvested", "y");
logger.debug("Getting "+MODE.HARVEST+" layers, I'm using filters ["+filters+"] as default");
}
}
logger.info("Sending CSW POST request to URL: "+gnCSWlURL);
logger.debug("Content-Type: "+req.getContentType());
//DEBUG
//logger.debug("POST - BODY: "+byteArray.toString());
String body = byteArray.toString();
InputStream in = httpUtils.post(gnCSWlURL, new ByteArrayInputStream(byteArray.toByteArray()), req.getContentType(), req.getParameterMap());
//END DEBUG
logger.debug("Response return Content-Type: "+httpUtils.getLastContentType());
resp.setContentType(httpUtils.getLastContentType());
OutputStream out = resp.getOutputStream();
if(in==null){
logger.warn("Input stream returned is null, sending "+HttpServletResponse.SC_NOT_FOUND);
resp.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
}
try{
ReusableInputStream reus = new ReusableInputStream(in);
if(theVisibility.equals(VISIBILITY.PRV)){
logger.info("Private VISIBILITY getting public file identifiers to remove them...");
FilterGetRecords filterGetRecords = FilterGetRecords.getInstance();
List<String> publicIds = filterGetRecords.getPublicFileIdentifiers(body, true);
if(publicIds!=null && publicIds.size()>0){
logger.info("I'm removing list of public IDs with "+publicIds.size() +" item/s. Is it right?");
//System.out.println("The response is: "+IOUtils.toString(reus));
Document doc = GetResponseRecordFilter.inputStreamToW3CDocument(reus);
doc = GetResponseRecordFilter.overrideResponseIdsByListIds(doc, filterGetRecords.getFoundPublicIds(), REPLACED_A_PUBLIC_UUID_PLEASE_IGNORE);
in = GetResponseRecordFilter.w3CDocumentToInputStream(doc);
//in = GetResponseRecordFilter.overrideResponseIdsByListIds(reus, publicIds, REPLACED_A_PUBLIC_UUID_PLEASE_IGNORE);
}
}
if(filters.size()>0){
logger.info("Applying filtering on geonet:info...");
Document doc = GetResponseRecordFilter.inputStreamToW3CDocument(reus);
List<String> fileIdentifiers = GetResponseRecordFilter.getTextContentStringsForTagName(doc, "gmd:fileIdentifier");
List<String> noMatchingFilter = new ArrayList<String>();
for (String fileId : fileIdentifiers) {
//CKECKING THE FILTERS
for (String fkey : filters.keySet()) {
String value = GetResponseRecordFilter.getMetadataValueByFileIdentifier(fileId, config.getGeoNetworkEndpoint(),config.getAdminAccount().getUser(), config.getAdminAccount().getPassword(), fkey);
//String own = GetResponseRecordFilter.getMetaOwnerNameByFileIdentifier(fileId, config.getGeoNetworkEndpoint(),config.getAdminAccount().getUser(), config.getAdminAccount().getPassword());
String fValue = filters.get(fkey);
if(value!=null && value.compareTo(fValue)!=0){
logger.debug(fkey +" of file Identifier "+fileId+" not matching the filter: "+fkey+" with value: "+fValue+", adding it to list to remove file identifier and exit from loop..");
noMatchingFilter.add(fileId);
//WHEN I ADD THE FILE IDENTIFIER TO FILTERED ID, I CAN EXIT FROM CKECKING FILTERS LOOP
break;
}
}
}
if(noMatchingFilter.size()>0){
logger.info("Removing "+noMatchingFilter.size()+" layer/s not macthing the filters: "+filters);
//Document doc2 = GetResponseRecordFilter.inputStreamToW3CDocument(reus);
doc = GetResponseRecordFilter.overrideResponseIdsByListIds(doc, noMatchingFilter, REPLACED_UUID_BY_FILTER_PLEASE_IGNORE);
in = GetResponseRecordFilter.w3CDocumentToInputStream(doc);
}else{
logger.info("No replace on UUIDs was applied from filters: "+filters);
in = reus;
}
}
ReusableInputStream reusIs = new ReusableInputStream(in);
int bytes = IOUtils.copy(reusIs, out);
//logger.trace("POST - RETURN : "+IOUtils.toString(reusIs));
if(bytes==0)
logger.warn("ResponseBody is empty, returning empty resp");
}catch(Exception e){
logger.error("Error on copy response:", e);
}finally{
IOUtils.closeQuietly(in);
}
} catch (IllegalArgumentException e){
logger.error("IllegalArgumentException:", e);
sendError(resp, HttpServletResponse.SC_BAD_REQUEST, "Illegal argument to carry out the request!");
return;
} catch (Exception e) {
logger.error("Exception:", e);
String error = "Sorry, an error occurred on resolving geonetwork request with scope "+scope+". Please, contact support!";
sendError(resp, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, error);
return;
}finally{
if(originalScope!=null){
ScopeProvider.instance.set(originalScope);
logger.info("scope provider set to orginal scope: "+originalScope);
}else{
ScopeProvider.instance.reset();
logger.info("scope provider reset");
}
}
}
/** /**
* Purge remain from query string. * Purge remain from query string.
* *
@ -274,222 +561,6 @@ public class GeonetworkResolver extends HttpServlet{
return queryString; return queryString;
} }
/* (non-Javadoc)
* @see javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
* This call is authenticated
*/
@SuppressWarnings("resource")
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {
/*MultiReadHttpServletRequest req2;
if(req instanceof MultiReadHttpServletRequest)
req2 = (MultiReadHttpServletRequest) req;*/
String originalScope = ScopeProvider.instance.get();
logger.info("doPost running...");
String scope = req.getParameter(SCOPE);
String remainValue = req.getParameter(REMAIN_PATH_PARAM);
String mode = req.getParameter(GeonetworkRequestFilterParameters.MODE.class.getSimpleName());
String visibility = req.getParameter(GeonetworkRequestFilterParameters.VISIBILITY.class.getSimpleName());
String theOwner = req.getParameter(GeonetworkRequestFilterParameters.OWNER_PARAM);
//boolean filterPublicMetadata = false;
boolean noAuthenticationB = false;
MODE theMode;
VISIBILITY theVisibility;
if (scope == null || scope.equals("")) {
logger.debug("Scope not found");
sendError(resp, HttpServletResponse.SC_BAD_REQUEST, SCOPE+" not found or empty");
return;
}
theMode = GeonetworkRequestFilterParameters.MODE.valueOf(mode);
theVisibility = GeonetworkRequestFilterParameters.VISIBILITY.valueOf(visibility);
logger.info(SCOPE +" is: " + scope);
logger.info(GeonetworkRequestFilterParameters.MODE.class.getSimpleName() +" is: "+theMode);
logger.info(GeonetworkRequestFilterParameters.VISIBILITY.class.getSimpleName() +" is: "+theVisibility);
logger.info(GeonetworkRequestFilterParameters.OWNER_PARAM +" is: "+theOwner);
try {
GeonetworkServiceInterface gntwAccess = new GeonetworkAccessParameter(scope);
GeonetworkInstance gnInstance = gntwAccess.getGeonetworkInstance();
ScopeProvider.instance.set(scope);
logger.info("set scope provider "+scope);
Configuration config = gnInstance.getGeonetworkPublisher().getConfiguration();
Account account = config.getScopeConfiguration().getAccounts().get(Type.CKAN);
logger.info("CKAN user owner is: "+account.getUser());
logger.info("Parameters..");
for (Enumeration<String> e = req.getParameterNames(); e.hasMoreElements();){
String p = e.nextElement();
logger.debug("param "+p + " value "+Arrays.toString(req.getParameterValues(p)));
}
//DEBUG BODY
// String readBody = IOUtils.toString(req.getReader());
// logger.debug("doPost read body request: "+readBody);
ByteArrayOutputStream byteArray = new ByteArrayOutputStream();
String geonetworkUrl = config.getGeoNetworkEndpoint();
// SPECIFIC HANDLER FOR GEONETWORK REQUEST: /srv/en/mef.export
String gnCSWlURL;
if(remainValue!=null && remainValue.compareTo(SRV_EN_MEF_EXPORT)==0){
logger.info("In case of mef.export, perfoming a custom handler");
gnCSWlURL = geonetworkUrl + SRV_EN_MEF_EXPORT;
String[] uuidValues = req.getParameterValues(UUID);
if(uuidValues!=null){
String data = null;
for (String uuid : uuidValues) {
data = UUID+"="+uuid;
}
if(data!=null){
logger.debug("Writing "+data +" into byte array");
byteArray.write(data.getBytes());
}else
IOUtils.copy(req.getReader(), byteArray);
}else
IOUtils.copy(req.getReader(), byteArray);
}else{
gnCSWlURL = remainValue==null ||remainValue.isEmpty()?geonetworkUrl+"/"+CSW_SERVER:geonetworkUrl+"/"+CSW_SERVER+remainValue;
IOUtils.copy(req.getReader(), byteArray);
}
//filterPublicMetadata = theVisibility.equals(VISIBILITY.PRV)?true:false;
HTTPCallsUtils httpUtils = new HTTPCallsUtils();
//PRIVATE LAYERS
if(theVisibility.equals(VISIBILITY.PRV)){
logger.debug("Visibility: "+VISIBILITY.PRV+" getting private layers..");
//VRE LAYERS
if(theMode.equals(MODE.VRE)){
logger.debug("Getting "+MODE.VRE+" layers..");
//HARVESTED LAYERS
}else{
logger.debug("Getting "+MODE.HARVEST+" layers, I'm using the owner: '"+theOwner +"' passed as parameter to filter layer/s returned..");
if(theOwner==null || theOwner.isEmpty()){
String error = "Harvest owner is missing. It is not possible to filter layers for the request "+MODE.HARVEST + " in the scope: "+scope+", without a valid owner as input";
logger.error(error);
sendError(resp, HttpServletResponse.SC_BAD_REQUEST, error);
return;
}
}
if(account.getUser()!=null){
boolean authorized = GNAuthentication.login(httpUtils, geonetworkUrl, account.getUser(), account. getPassword());
logger.trace("Authorized on "+geonetworkUrl +" ? "+authorized);
}else
logger.info("Skipping authentication, ckan user (the owner) is null");
//PUBLIC LAYERS
}else{
logger.debug("Visibility: "+VISIBILITY.PUB+" getting public layers..");
//VRE LAYERS
if(theMode.equals(MODE.VRE)){
logger.debug("Getting "+MODE.VRE+" layers, the VRE account: "+account.getUser() +" will be used as owner user for filtering... Is it right?");
theOwner = account.getUser();
//HARVESTED LAYERS
}else{
logger.debug("Getting "+MODE.HARVEST+" layers, I'm using the owner: '"+theOwner +"' passed as parameter to filter layer/s returned..");
if(theOwner==null || theOwner.isEmpty()){
String error = "Harvest owner is missing. It is not possible to filter layers for the request "+MODE.HARVEST + " in the scope: "+scope+", without a valid owner as input";
logger.error(error);
sendError(resp, HttpServletResponse.SC_BAD_REQUEST, error);
return;
}
}
}
logger.info("Sending CSW POST request to URL: "+gnCSWlURL);
logger.debug("Content-Type: "+req.getContentType());
//DEBUG
//logger.debug("POST - BODY : "+byteArray.toString());
InputStream in = httpUtils.post(gnCSWlURL, new ByteArrayInputStream(byteArray.toByteArray()), req.getContentType(), req.getParameterMap());
//END DEBUG
logger.debug("Response return Content-Type: "+httpUtils.getLastContentType());
resp.setContentType(httpUtils.getLastContentType());
OutputStream out = resp.getOutputStream();
if(in==null){
logger.warn("Input stream returned is null, sending "+HttpServletResponse.SC_NOT_FOUND);
resp.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
}
try{
ReusableInputStream reus = new ReusableInputStream(in);
if(theVisibility.equals(VISIBILITY.PRV)){
logger.info("Private VISIBILITY performing so getting public file identifiers to apply filtering..");
FilterGetRecords filterGetRecords = new FilterGetRecords(byteArray.toString());
if(filterGetRecords.getFoundPublicIds()!=null && filterGetRecords.getFoundPublicIds().size()>0){
logger.info("I'm removing list of public IDs with "+filterGetRecords.getFoundPublicIds().size() +" item/s. Is it right?");
in = GetResponseRecordFilter.overrideResponseIdsByListIds(reus, filterGetRecords.getFoundPublicIds(), "Replaced a public UUID, please ignore");
}
}else {
logger.info("Public VISIBILITY perfoming check on ownership...");
Document doc = GetResponseRecordFilter.inputStreamToW3CDocument(reus);
List<String> fileIdentifiers = GetResponseRecordFilter.getTextContentStringsForTagName(doc, "gmd:fileIdentifier");
List<String> noMatchingOwner = new ArrayList<String>();
for (String fileId : fileIdentifiers) {
String own = GetResponseRecordFilter.getMetaCategoryByFileIdentifier(fileId, config.getGeoNetworkEndpoint(),config.getAdminAccount().getUser(), config.getAdminAccount().getPassword());
//String own = GetResponseRecordFilter.getMetaOwnerNameByFileIdentifier(fileId, config.getGeoNetworkEndpoint(),config.getAdminAccount().getUser(), config.getAdminAccount().getPassword());
if(own.compareTo(theOwner)!=0){
logger.debug("Owner of file Identifier "+fileId+" not matching the owner passed: "+theOwner+", removing it..");
noMatchingOwner.add(fileId);
}
}
if(noMatchingOwner.size()>0){
logger.info("Removing "+noMatchingOwner.size()+" layer/s not macthing the owner: "+theOwner);
in = GetResponseRecordFilter.overrideResponseIdsByListIds(reus, noMatchingOwner, "Replaced UUID owned by another user, please ignore");
}else{
logger.info("No replace on UUIDs was applied for the owner: "+theOwner);
in = reus;
}
}
ReusableInputStream reusIs = new ReusableInputStream(in);
int bytes = IOUtils.copy(reusIs, out);
//logger.trace("POST - RETURN : "+IOUtils.toString(reusIs));
if(bytes==0)
logger.warn("ResponseBody is empty, returning empty resp");
}catch(Exception e){
logger.error("Error on copy response:", e);
}finally{
IOUtils.closeQuietly(in);
}
} catch (IllegalArgumentException e){
logger.error("IllegalArgumentException:", e);
sendError(resp, HttpServletResponse.SC_BAD_REQUEST, "Illegal argument to carry out the request!");
return;
} catch (Exception e) {
logger.error("Exception:", e);
String error = "Sorry, an error occurred on resolving geonetwork request with scope "+scope+". Please, contact support!";
sendError(resp, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, error);
return;
}finally{
if(originalScope!=null){
ScopeProvider.instance.set(originalScope);
logger.info("scope provider set to orginal scope: "+originalScope);
}else{
ScopeProvider.instance.reset();
logger.info("scope provider reset");
}
}
}
/** /**
@ -595,4 +666,14 @@ public class GeonetworkResolver extends HttpServlet{
response.sendRedirect(response.encodeRedirectURL(redirectTo)); response.sendRedirect(response.encodeRedirectURL(redirectTo));
return; return;
} }
/**
* Checks if is valid token.
*
* @param gCubeToken the g cube token
* @return true, if is valid token
*/
public static boolean isValidToken(String gCubeToken){
return gCubeToken!=null && !gCubeToken.isEmpty() && !(gCubeToken.compareTo("null")==0);
}
} }

View File

@ -15,6 +15,7 @@ import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URLEncoder; import java.net.URLEncoder;
@ -22,13 +23,19 @@ import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import javax.xml.namespace.NamespaceContext;
import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys; import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer; import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory; import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource; import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamResult;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathFactory;
import org.apache.commons.httpclient.HttpStatus; import org.apache.commons.httpclient.HttpStatus;
import org.gcube.datatransfer.resolver.gis.GeonetworkInstance; import org.gcube.datatransfer.resolver.gis.GeonetworkInstance;
@ -45,6 +52,7 @@ import org.w3c.dom.Document;
import org.w3c.dom.Element; import org.w3c.dom.Element;
import org.w3c.dom.Node; import org.w3c.dom.Node;
import org.w3c.dom.NodeList; import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
/** /**
@ -55,6 +63,14 @@ import org.w3c.dom.NodeList;
*/ */
public class GetResponseRecordFilter { public class GetResponseRecordFilter {
/**
*
*/
private static final String FILE_IDENTIFIER = "fileIdentifier";
/**
*
*/
private static final String GMD_FILE_IDENTIFIER = "gmd:fileIdentifier";
/** /**
* *
*/ */
@ -67,8 +83,16 @@ public class GetResponseRecordFilter {
* *
*/ */
private static final String MESSAGE_TO_REPLACED_ID = "Replaced ID please ignore"; private static final String MESSAGE_TO_REPLACED_ID = "Replaced ID please ignore";
public static Logger logger = LoggerFactory.getLogger(GetResponseRecordFilter.class); public static Logger logger = LoggerFactory.getLogger(GetResponseRecordFilter.class);
public static NamespaceCsw cswNamesapces = new NamespaceCsw();
public static NamespaceContextMap namespaces = new NamespaceContextMap(cswNamesapces.getMapPrefix());
/** /**
* Delete summary record. * Delete summary record.
* *
@ -84,7 +108,7 @@ public class GetResponseRecordFilter {
for (int i = 0; i < nodes.getLength(); i++) { for (int i = 0; i < nodes.getLength(); i++) {
Element mdMetadata = (Element) nodes.item(i); Element mdMetadata = (Element) nodes.item(i);
// <dc:identifier> // <dc:identifier>
Element id = (Element) mdMetadata.getElementsByTagName("gmd:fileIdentifier").item(0); Element id = (Element) mdMetadata.getElementsByTagName(GMD_FILE_IDENTIFIER).item(0);
Element gco = (Element) id.getElementsByTagName("gco:CharacterString").item(0); Element gco = (Element) id.getElementsByTagName("gco:CharacterString").item(0);
String idValue = gco.getTextContent(); String idValue = gco.getTextContent();
logger.trace("Summary gmd:fileIdentifier is: " + idValue); logger.trace("Summary gmd:fileIdentifier is: " + idValue);
@ -119,41 +143,69 @@ public class GetResponseRecordFilter {
return fileIds; return fileIds;
} }
/** /**
* Override summary record. * Override summary record.
* *
* @param doc the doc * @param getRecordsResponse the get records response
* @param identifier the identifier * @param identifier the identifier
* @param messageToReplace the message to replace * @param messageToReplace the message to replace
* @return true, if successful * @return true, if successful
* @throws Exception the exception
*/ */
private static boolean overrideSummaryRecord(Document doc, String identifier, String messageToReplace) { public static boolean overrideSummaryRecord(Document getRecordsResponse, String identifier, String messageToReplace) throws Exception {
// <csw:SummaryRecord> list // USING XPATH
NodeList nodes = doc.getElementsByTagName("gmd:MD_Metadata"); //String xpathExpression ="//gmd:MD_Metadata/gmd:fileIdentifier[gco:CharacterString='"+identifier+"']/gco:CharacterString";
String xpathExpression ="//MD_Metadata/fileIdentifier/CharacterString[text()='"+identifier+"']";
logger.trace("Searching identifier: " + identifier +" xpath: "+xpathExpression);
NodeList nodes = getNodesFromXPathExpression(namespaces, getRecordsResponse, xpathExpression);
//Document doc = inputStreamToW3CDocument(getRecordsResponse);
if(nodes!=null && nodes.getLength()>0){
logger.trace("Found gmd:fileIdentifier for: " + identifier);
for (int i = 0; i < nodes.getLength(); i++) {
Node mdId = nodes.item(i);
String idValue = mdId.getTextContent();
logger.trace("ovveriding gmd:fileIdentifier value: " + idValue+ " as public: "+messageToReplace);
String msg = messageToReplace==null?MESSAGE_TO_REPLACED_ID:messageToReplace;
mdId.setTextContent(msg);
}
return true;
}
return false;
/*NodeList nodes = getRecordsResponse.getElementsByTagName("gmd:MD_Metadata");
logger.trace("gmd:MD_Metadata are: " + nodes.getLength()); logger.trace("gmd:MD_Metadata are: " + nodes.getLength());
for (int i = 0; i < nodes.getLength(); i++) { for (int i = 0; i < nodes.getLength(); i++) {
Element mdMetadata = (Element) nodes.item(i); Element mdMetadata = (Element) nodes.item(i);
// <dc:identifier> //printElement(mdMetadata);
NodeList fileIdentifierLst = mdMetadata.getElementsByTagName("gmd:fileIdentifier");
// nodelist with element <gmd:fileIdentifier> or <fileIdentifier>
NodeList fileIdentifierLst = mdMetadata.getElementsByTagName(GMD_FILE_IDENTIFIER);
if(fileIdentifierLst==null || fileIdentifierLst.getLength()==0 || fileIdentifierLst.item(0)==null){ if(fileIdentifierLst==null || fileIdentifierLst.getLength()==0 || fileIdentifierLst.item(0)==null){
logger.info("skipping identifier: " + identifier +" it has not fileidentifier"); logger.info("NodeList of "+GMD_FILE_IDENTIFIER+" is empty, trying search 'fileIdentifier'");
return false; fileIdentifierLst = mdMetadata.getElementsByTagName(FILE_IDENTIFIER);
if(fileIdentifierLst==null || fileIdentifierLst.getLength()==0 || fileIdentifierLst.item(0)==null){
logger.info("Also "+FILE_IDENTIFIER+" is missing, returning no override'");
return false;
}
} }
Element id = (Element) fileIdentifierLst.item(0); Element id = (Element) fileIdentifierLst.item(0);
NodeList gcoLst = id.getElementsByTagName("gco:CharacterString"); NodeList gcoLst = id.getElementsByTagName("gco:CharacterString");
if(gcoLst==null || gcoLst.getLength()==0 || gcoLst.item(0)==null){ if(gcoLst==null || gcoLst.getLength()==0 || gcoLst.item(0)==null){
logger.info("skipping identifier: " + identifier +" it has not gco:CharacterString"); logger.info("gco:CharacterString is missing, returning no override");
return false; return false;
} }
Element gco = (Element) gcoLst.item(0); Element gco = (Element) gcoLst.item(0);
String idValue = gco.getTextContent(); String idValue = gco.getTextContent();
logger.trace("Summary gmd:fileIdentifier is: " + idValue); logger.trace("gmd:fileIdentifier/fileIdentifier value is: " + idValue);
if (idValue!=null && idValue.equals(identifier)) { if (idValue!=null && idValue.equals(identifier)) {
String msg = messageToReplace==null?MESSAGE_TO_REPLACED_ID:messageToReplace; String msg = messageToReplace==null?MESSAGE_TO_REPLACED_ID:messageToReplace;
gco.setTextContent(msg); gco.setTextContent(msg);
@ -161,11 +213,202 @@ public class GetResponseRecordFilter {
return true; return true;
} }
} }
return false; return false;*/
} }
/**
* Gets the nodes from x path expression.
*
* @param context the context
* @param getRecordsResponse the get records response
* @param xpathExpression the xpath expression
* @return the nodes from x path expression
*/
private static NodeList getNodesFromXPathExpression(NamespaceContextMap context, Document getRecordsResponse, String xpathExpression) {
try {
XPath xpath = XPathFactory.newInstance().newXPath();
xpath.setNamespaceContext(context);
XPathExpression xPathExpression = xpath.compile(xpathExpression);
return (NodeList) xPathExpression.evaluate(getRecordsResponse, XPathConstants.NODESET);
} catch (Exception e) {
logger.warn("Error on searching xpath expression: "+xpathExpression+", returning null", e);
return null;
}
}
/**
* Override summary record.
*
* @param getRecordsResponse the get records response
* @param identifier the identifier
* @param messageToReplace the message to replace
* @return true, if successful
* @throws Exception the exception
*/
private static InputStream overrideSummaryRecord(InputStream getRecordsResponse, String identifier, String messageToReplace) throws Exception {
//String xpathExpression ="//gmd:MD_Metadata/gmd:fileIdentifier[gco:CharacterString='"+identifier+"']/gco:CharacterString";
String xpathExpression ="//gmd:MD_Metadata/gmd:fileIdentifier/gco:CharacterString[text()='"+identifier+"']";
logger.trace("Searching identifier: " + identifier +" xpath: "+xpathExpression);
NodeList nodes = getNodesFromXPathExpression(namespaces, getRecordsResponse, xpathExpression);
//Document doc = inputStreamToW3CDocument(getRecordsResponse);
if(nodes!=null && nodes.getLength()>0){
logger.trace("Found gmd:fileIdentifier for: " + identifier);
for (int i = 0; i < nodes.getLength(); i++) {
Node mdId = nodes.item(i);
String idValue = mdId.getTextContent();
logger.trace("ovveriding gmd:fileIdentifier value: " + idValue+ " as public: "+messageToReplace);
String msg = messageToReplace==null?MESSAGE_TO_REPLACED_ID:messageToReplace;
mdId.setTextContent(msg);
}
return getRecordsResponse;
}
xpathExpression ="//gmd:MD_Metadata/fileIdentifier/gco:CharacterString[text()='"+identifier+"']";
nodes = getNodesFromXPathExpression(namespaces, getRecordsResponse, xpathExpression);
if(nodes!=null && nodes.getLength()>0){
logger.trace("Found fileIdentifier for: " + identifier);
for (int i = 0; i < nodes.getLength(); i++) {
Node mdId = nodes.item(i);
String idValue = mdId.getTextContent();
logger.trace("ovveriding fileIdentifier value: " + idValue+ " as public: "+messageToReplace);
String msg = messageToReplace==null?MESSAGE_TO_REPLACED_ID:messageToReplace;
mdId.setTextContent(msg);
}
return getRecordsResponse;
}
return getRecordsResponse;
/*NodeList nodes = doc.getElementsByTagName("gmd:MD_Metadata");
logger.trace("gmd:MD_Metadata are: " + nodes.getLength());
for (int i = 0; i < nodes.getLength(); i++) {
Element mdMetadata = (Element) nodes.item(i);
//printElement(mdMetadata);
// nodelist with element <gmd:fileIdentifier> or <fileIdentifier>
NodeList fileIdentifierLst = mdMetadata.getElementsByTagName(GMD_FILE_IDENTIFIER);
if(fileIdentifierLst==null || fileIdentifierLst.getLength()==0 || fileIdentifierLst.item(0)==null){
logger.info("NodeList of "+GMD_FILE_IDENTIFIER+" is empty, trying search 'fileIdentifier'");
fileIdentifierLst = mdMetadata.getElementsByTagName(FILE_IDENTIFIER);
if(fileIdentifierLst==null || fileIdentifierLst.getLength()==0 || fileIdentifierLst.item(0)==null){
logger.info("Also "+FILE_IDENTIFIER+" is missing, returning no override'");
return false;
}
}
Element id = (Element) fileIdentifierLst.item(0);
NodeList gcoLst = id.getElementsByTagName("gco:CharacterString");
if(gcoLst==null || gcoLst.getLength()==0 || gcoLst.item(0)==null){
logger.info("gco:CharacterString is missing, returning no override");
return false;
}
Element gco = (Element) gcoLst.item(0);
String idValue = gco.getTextContent();
logger.trace("gmd:fileIdentifier/fileIdentifier value is: " + idValue);
if (idValue!=null && idValue.equals(identifier)) {
String msg = messageToReplace==null?MESSAGE_TO_REPLACED_ID:messageToReplace;
gco.setTextContent(msg);
logger.debug("Overrided child " + idValue);
return true;
}
}
return false;*/
}
/**
* Gets the text from x path expression.
*
* @param context the context
* @param source the source
* @param xpathExpression the xpath expression
* @return the text from x path expression
*/
public static List<String> getTextFromXPathExpression(NamespaceContextMap context, InputStream source, String xpathExpression){
List<String> list = new ArrayList<String>();
try {
XPath xpath = XPathFactory.newInstance().newXPath();
xpath.setNamespaceContext(context);
XPathExpression xPathExpression = xpath.compile(xpathExpression);
InputSource inputSource = new InputSource(source);
// System.out.println(xml);
// System.out.println(xpathExpression);
// System.out.println(inputSource.toString());
NodeList nodes = (NodeList) xPathExpression.evaluate(inputSource, XPathConstants.NODESET);
for (int i = 0; i<nodes.getLength(); i++) {
Node node = nodes.item(i);
list.add(node.getTextContent());
}
} catch (Exception e) {
e.printStackTrace();
}
return list;
}
/**
* Gets the nodes from x path expression.
*
* @param context the context
* @param doc the doc
* @param xpathExpression the xpath expression
* @return the nodes from x path expression
*/
public static NodeList getNodesFromXPathExpression(NamespaceContext context, InputStream doc, String xpathExpression){
try {
XPath xpath = XPathFactory.newInstance().newXPath();
xpath.setNamespaceContext(context);
XPathExpression xPathExpression = xpath.compile(xpathExpression);
//InputSource inputSource = new InputSource(IOUtils.toInputStream(source));
InputSource inputSource = new InputSource(doc);
return (NodeList) xPathExpression.evaluate(inputSource, XPathConstants.NODESET);
// XPath xpath = XPathFactory.newInstance().newXPath();
// xpath.setNamespaceContext(context);
// XPathExpression xPathExpression = xpath.compile(xpathExpression);
// InputSource inputSource = new InputSource(source);
//
//// System.out.println(xml);
//// System.out.println(xpathExpression);
//// System.out.println(inputSource.toString());
//
// NodeList nodes = (NodeList) xPathExpression.evaluate(inputSource, XPathConstants.NODESET);
} catch (Exception e) {
logger.warn("Error on searching xpath expression: "+xpathExpression+", returning null", e);
return null;
}
}
/** /**
* Input stream to w3 c document. * Input stream to w3 c document.
* *
@ -188,59 +431,64 @@ public class GetResponseRecordFilter {
} }
} }
/** /**
* Override response ids by list ids. * Override response ids by list ids.
* *
* @param getRecordsResponse the get records response * @param doc the doc
* @param idsToRemove the ids to remove * @param idsToRemove the ids to remove
* @param messageToWrite the message to replace the right ID in the response. * @param messageToWrite the message to replace the right ID in the response.
* @return the input stream * @return the input stream
* @throws IOException Signals that an I/O exception has occurred. * @throws IOException Signals that an I/O exception has occurred.
*/ */
public static InputStream overrideResponseIdsByListIds(InputStream getRecordsResponse, List<String> idsToRemove, String messageToWrite) throws IOException { public static Document overrideResponseIdsByListIds(Document doc, List<String> idsToRemove, String messageToWrite) throws IOException {
try { try {
Document doc = inputStreamToW3CDocument(getRecordsResponse); //Document doc = inputStreamToW3CDocument(getRecordsResponse);
int override = 0; int override = 0;
for (String identifier : idsToRemove) { for (String identifier : idsToRemove) {
if(overrideSummaryRecord(doc, identifier, messageToWrite)) if(overrideSummaryRecord(doc, identifier, messageToWrite))
override++; override++;
} }
logger.info("Overrided "+override +" node/s"); logger.info("Overrided "+override +" node/s");
return doc;
//TODO IS IT POSSIBLE TO REMOVE?
/*NodeList nodeList = doc.getElementsByTagName("csw:SearchResults");
if(nodeList!=null && nodeList.item(0)!=null){
Node nd = nodeList.item(0);
// update staff attribute
NamedNodeMap attr = nd.getAttributes();
Node numberOfRecordsMatched = attr.getNamedItem("numberOfRecordsMatched");
Node numberOfRecordsReturned = attr.getNamedItem("numberOfRecordsReturned");
logger.trace("Old numberOfRecordsMatched: "+numberOfRecordsMatched.getTextContent());
logger.trace("Old numberOfRecordsReturned: "+numberOfRecordsReturned.getTextContent());
try{
int oldValueM = Integer.parseInt(numberOfRecordsMatched.getTextContent());
int oldValueR = Integer.parseInt(numberOfRecordsReturned.getTextContent());
int newValueM = oldValueM-removed;
int newValueR = oldValueR-removed;
logger.trace("Updating numberOfRecordsMatched at: "+newValueM);
logger.trace("Updating numberOfRecordsReturned at: "+newValueR);
numberOfRecordsMatched.setTextContent(newValueM+"");
numberOfRecordsReturned.setTextContent(newValueR+"");
}catch (Exception e) {
logger.warn("An error occurred during attribe numberOfRecordsMatched updating, skipping operation");
}
}*/
return w3CDocumentToInputStream(doc);
} }
catch (Exception e) { catch (Exception e) {
logger.error("An error occurred during removing IDS by List: ", e); logger.error("An error occurred during removing IDS by List: ", e);
return getRecordsResponse; return doc;
} }
} }
// /**
// * Override response ids by list ids.
// *
// * @param getRecordsResponse the get records response
// * @param idsToRemove the ids to remove
// * @param messageToWrite the message to replace the right ID in the response.
// * @return the input stream
// * @throws IOException Signals that an I/O exception has occurred.
// */
// public static InputStream overrideResponseIdsByListIds(InputStream getRecordsResponse, List<String> idsToRemove, String messageToWrite) throws IOException {
//
// try {
// Document doc = inputStreamToW3CDocument(getRecordsResponse);
// int override = 0;
// for (String identifier : idsToRemove) {
// getRecordsResponse = overrideSummaryRecord(getRecordsResponse, identifier, messageToWrite);
//
// }
// //logger.info("Overrided "+override +" node/s");
// return getRecordsResponse;
// }
// catch (Exception e) {
// logger.error("An error occurred during removing IDS by List: ", e);
// return getRecordsResponse;
// }
// }
/** /**
* W3 c document to input stream. * W3 c document to input stream.
* *
@ -393,7 +641,7 @@ public class GetResponseRecordFilter {
* @param metadataName the metadata name * @param metadataName the metadata name
* @return the metadata value by file identifier * @return the metadata value by file identifier
*/ */
private static String getMetadataValueByFileIdentifier(String fileIdentifier, String geonetworkURL, String user, String pwd, String metadataName){ public static String getMetadataValueByFileIdentifier(String fileIdentifier, String geonetworkURL, String user, String pwd, String metadataName){
String response = requestXmlMetadataGet(fileIdentifier, geonetworkURL, user, pwd); String response = requestXmlMetadataGet(fileIdentifier, geonetworkURL, user, pwd);
@ -421,6 +669,33 @@ public class GetResponseRecordFilter {
} }
} }
/**
* Prints the element.
*
* @param node the node
*/
public static void printElement(Element node){
TransformerFactory transFactory = TransformerFactory.newInstance();
Transformer transformer;
try {
transformer = transFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
//transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
//transformer.transform(new DOMSource(node), new StreamResult(buffer));
StreamResult result = new StreamResult(new StringWriter());
DOMSource source = new DOMSource(node);
transformer.transform(source, result);
String xmlString = result.getWriter().toString();
System.out.println("Element:" +xmlString);
// String str = buffer.toString();
// System.out.println("Element: "+str);
}catch (TransformerException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// /** // /**
// * The main method. // * The main method.
// * // *

View File

@ -0,0 +1,195 @@
/**
*
*/
package org.gcube.datatransfer.resolver.gis.util;
/**
* @author Francesco Mangiacrapa francesco.mangiacrapa@isti.cnr.it
* @May 7, 2013
*
*/
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import javax.xml.XMLConstants;
import javax.xml.namespace.NamespaceContext;
/**
* The Class NamespaceContextMap.
*
* @author Francesco Mangiacrapa francesco.mangiacrapa@isti.cnr.it
* Jan 22, 2016
*/
public final class NamespaceContextMap implements NamespaceContext {
private final Map<String, String> prefixMap;
private final Map<String, Set<String>> nsMap;
/**
* Constructor that takes a map of XML prefix-namespaceURI values. A
* defensive copy is made of the map. An IllegalArgumentException will be
* thrown if the map attempts to remap the standard prefixes defined in the
* NamespaceContext contract.
*
* @param prefixMappings
* a map of prefix:namespaceURI values
*/
public NamespaceContextMap(Map<String, String> prefixMappings) {
prefixMap = createPrefixMap(prefixMappings);
nsMap = createNamespaceMap(prefixMap);
}
/**
* Convenience constructor.
*
* @param mappingPairs
* pairs of prefix-namespaceURI values
*/
public NamespaceContextMap(String... mappingPairs) {
this(toMap(mappingPairs));
}
/**
* To map.
*
* @param mappingPairs the mapping pairs
* @return the map
*/
private static Map<String, String> toMap(String... mappingPairs) {
Map<String, String> prefixMappings = new HashMap<String, String>(
mappingPairs.length / 2);
for (int i = 0; i < mappingPairs.length; i++) {
prefixMappings.put(mappingPairs[i], mappingPairs[++i]);
}
return prefixMappings;
}
/**
* Creates the prefix map.
*
* @param prefixMappings the prefix mappings
* @return the map
*/
private Map<String, String> createPrefixMap(
Map<String, String> prefixMappings) {
Map<String, String> prefixMap = new HashMap<String, String>(
prefixMappings);
addConstant(prefixMap, XMLConstants.XML_NS_PREFIX,
XMLConstants.XML_NS_URI);
addConstant(prefixMap, XMLConstants.XMLNS_ATTRIBUTE,
XMLConstants.XMLNS_ATTRIBUTE_NS_URI);
return Collections.unmodifiableMap(prefixMap);
}
/**
* Adds the constant.
*
* @param prefixMap the prefix map
* @param prefix the prefix
* @param nsURI the ns uri
*/
private void addConstant(Map<String, String> prefixMap, String prefix,
String nsURI) {
String previous = prefixMap.put(prefix, nsURI);
if (previous != null && !previous.equals(nsURI)) {
throw new IllegalArgumentException(prefix + " -> " + previous
+ "; see NamespaceContext contract");
}
}
/**
* Creates the namespace map.
*
* @param prefixMap the prefix map
* @return the map
*/
private Map<String, Set<String>> createNamespaceMap(
Map<String, String> prefixMap) {
Map<String, Set<String>> nsMap = new HashMap<String, Set<String>>();
for (Map.Entry<String, String> entry : prefixMap.entrySet()) {
String nsURI = entry.getValue();
Set<String> prefixes = nsMap.get(nsURI);
if (prefixes == null) {
prefixes = new HashSet<String>();
nsMap.put(nsURI, prefixes);
}
prefixes.add(entry.getKey());
}
for (Map.Entry<String, Set<String>> entry : nsMap.entrySet()) {
Set<String> readOnly = Collections
.unmodifiableSet(entry.getValue());
entry.setValue(readOnly);
}
return nsMap;
}
/* (non-Javadoc)
* @see javax.xml.namespace.NamespaceContext#getNamespaceURI(java.lang.String)
*/
@Override
public String getNamespaceURI(String prefix) {
checkNotNull(prefix);
String nsURI = prefixMap.get(prefix);
return nsURI == null ? XMLConstants.NULL_NS_URI : nsURI;
}
/* (non-Javadoc)
* @see javax.xml.namespace.NamespaceContext#getPrefix(java.lang.String)
*/
@Override
public String getPrefix(String namespaceURI) {
checkNotNull(namespaceURI);
Set<String> set = nsMap.get(namespaceURI);
return set == null ? null : set.iterator().next();
}
/* (non-Javadoc)
* @see javax.xml.namespace.NamespaceContext#getPrefixes(java.lang.String)
*/
@Override
public Iterator<String> getPrefixes(String namespaceURI) {
checkNotNull(namespaceURI);
Set<String> set = nsMap.get(namespaceURI);
return set.iterator();
}
/**
* Check not null.
*
* @param value the value
*/
private void checkNotNull(String value) {
if (value == null) {
throw new IllegalArgumentException("null");
}
}
/**
* Gets the map.
*
* @return an unmodifiable map of the mappings in the form
* prefix-namespaceURI
*/
public Map<String, String> getMap() {
return prefixMap;
}
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("NamespaceContextMap [prefixMap=");
builder.append(prefixMap);
builder.append(", nsMap=");
builder.append(nsMap);
builder.append("]");
return builder.toString();
}
}

View File

@ -51,6 +51,15 @@ public class NamespaceCsw extends NamespaceISO19139 implements NamespaceContext
} }
/**
* @return the mapPrefix
*/
public Map<String, String> getMapPrefix() {
return mapPrefix;
}
/* (non-Javadoc) /* (non-Javadoc)
* @see javax.xml.namespace.NamespaceContext#getNamespaceURI(java.lang.String) * @see javax.xml.namespace.NamespaceContext#getNamespaceURI(java.lang.String)
*/ */

View File

@ -24,28 +24,32 @@ public class GeonetworkQueryTest {
private static final String UUID = "8a878105-ef06-4b1f-843f-120fc525b22b"; private static final String UUID = "8a878105-ef06-4b1f-843f-120fc525b22b";
//private String[] scopes = {"/gcube/devNext/NextNext"}; private static String[] scopesProd = {"/gcube/devsec/devVRE"};
//private String[] scopesProd = {"/d4science.research-infrastructures.eu/gCubeApps/SIASPA"}; //private static String[] scopesProd = {"/d4science.research-infrastructures.eu/gCubeApps/SIASPA"};
//private String[] scopesProd = {"/d4science.research-infrastructures.eu/gCubeApps/fisheriesandecosystematmii"}; //private String[] scopesProd = {"/d4science.research-infrastructures.eu/gCubeApps/fisheriesandecosystematmii"};
//private String[] scopesProd = {"/d4science.research-infrastructures.eu/D4Research"}; //private String[] scopesProd = {"/d4science.research-infrastructures.eu/D4Research"};
private String[] scopesProd = {"/d4science.research-infrastructures.eu"}; //private String[] scopesProd = {"/d4science.research-infrastructures.eu"};
//private String[] scopesProd = {"/d4science.research-infrastructures.eu/gCubeApps/FAO_TunaAtlas"}; //private String[] scopesProd = {"/d4science.research-infrastructures.eu/gCubeApps/FAO_TunaAtlas"};
//private String[] scopesProd = {"/d4science.research-infrastructures.eu/D4Research/Blue-Datathon"}; //private String[] scopesProd = {"/d4science.research-infrastructures.eu/D4Research/Blue-Datathon"};
private LoginLevel loginLevel = LoginLevel.CKAN; private static LoginLevel loginLevel = LoginLevel.CKAN;
private Type accountType = Type.SCOPE; //private static String[] scopesProd = {"/d4science.research-infrastructures.eu/gCubeApps/ICCAT_BFT-E"};
private String textToSearch = "geo_fea";
@Test private static Type accountType = Type.SCOPE;
public void getCount() throws Exception{
private static String textToSearch = "geo_fea";
//@Test
public static void getCount() throws Exception{
try{ try{
for(String scope:scopesProd){ for(String scope:scopesProd){
ScopeProvider.instance.set(scope); ScopeProvider.instance.set(scope);
@ -91,7 +95,7 @@ public class GeonetworkQueryTest {
} }
} }
//@Test @Test
public void getLayerByUUID() throws Exception{ public void getLayerByUUID() throws Exception{
try{ try{
for(String scope:scopesProd){ for(String scope:scopesProd){
@ -228,4 +232,15 @@ public class GeonetworkQueryTest {
e.printStackTrace(); e.printStackTrace();
} }
} }
public static void main(String[] args) {
try {
getCount();
}
catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} }

View File

@ -1,17 +1,23 @@
import java.io.ByteArrayInputStream; import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import org.apache.commons.io.IOUtils;
import org.gcube.common.scope.api.ScopeProvider; import org.gcube.common.scope.api.ScopeProvider;
import org.gcube.datatransfer.resolver.gis.geonetwork.FilterGetRecords;
import org.gcube.datatransfer.resolver.gis.geonetwork.GeonetworkResolver; import org.gcube.datatransfer.resolver.gis.geonetwork.GeonetworkResolver;
import org.gcube.datatransfer.resolver.gis.geonetwork.HTTPCallsUtils; import org.gcube.datatransfer.resolver.gis.geonetwork.HTTPCallsUtils;
import org.gcube.datatransfer.resolver.gis.geonetwork.ReusableInputStream;
import org.gcube.datatransfer.resolver.gis.util.GetResponseRecordFilter; import org.gcube.datatransfer.resolver.gis.util.GetResponseRecordFilter;
import org.gcube.spatial.data.geonetwork.GeoNetwork; import org.gcube.spatial.data.geonetwork.GeoNetwork;
import org.gcube.spatial.data.geonetwork.GeoNetworkPublisher; import org.gcube.spatial.data.geonetwork.GeoNetworkPublisher;
@ -19,29 +25,62 @@ import org.gcube.spatial.data.geonetwork.LoginLevel;
import org.gcube.spatial.data.geonetwork.configuration.Configuration; import org.gcube.spatial.data.geonetwork.configuration.Configuration;
import org.gcube.spatial.data.geonetwork.model.Account; import org.gcube.spatial.data.geonetwork.model.Account;
import org.gcube.spatial.data.geonetwork.model.Account.Type; import org.gcube.spatial.data.geonetwork.model.Account.Type;
import org.w3c.dom.Document;
/** /**
* *
*/ */
/** /**
* * @author Francesco Mangiacrapa francesco.mangiacrapa@isti.cnr.it Sep 8, 2016
* @author Francesco Mangiacrapa francesco.mangiacrapa@isti.cnr.it
* Sep 8, 2016
*/ */
public class GeonetworkResolverTest { public class GeonetworkResolverTest {
private static String scope = "/d4science.research-infrastructures.eu"; private static String scope = "/d4science.research-infrastructures.eu";
private static LoginLevel loginLevel = LoginLevel.SCOPE; private static LoginLevel loginLevel = LoginLevel.SCOPE;
private static Type accountType = Type.CKAN; private static Type accountType = Type.CKAN;
public static String readFile(String cswQueyrFileName) throws FileNotFoundException{
String fileName = cswQueyrFileName;
// //read file into stream, try-with-resources
// try (Stream<String> stream = Files.lines(Paths.get(fileName))) {
//
// stream.forEach(System.out::println);
//
// } catch (IOException e) {
// e.printStackTrace();
// }
FileReader reportReader = new FileReader(fileName);
//Stream<String> stream = reportBW.lines();
StringWriter reader = new StringWriter();
List<String> list;
try (BufferedReader reportBW = new BufferedReader(reportReader)){
String line;
while ((line = reportBW.readLine()) != null) {
reader.append(line);
}
}catch (Exception e) {
e.printStackTrace();
}
return reader.toString();
}
/** /**
* The main method. * The main method.
* *
* @param args the arguments * @param args
* @throws UnsupportedEncodingException the unsupported encoding exception * the arguments
* @throws UnsupportedEncodingException
* the unsupported encoding exception
*/ */
public static void main(String[] args) throws UnsupportedEncodingException { public static void main(String[] args) throws UnsupportedEncodingException {
@ -63,7 +102,7 @@ public class GeonetworkResolverTest {
try{ try{
HTTPCallsUtils httpUtils = new HTTPCallsUtils(); HTTPCallsUtils httpUtils = new HTTPCallsUtils();
String data =""; //String data ="";
ScopeProvider.instance.set(scope); ScopeProvider.instance.set(scope);
GeoNetworkPublisher reader=GeoNetwork.get(); GeoNetworkPublisher reader=GeoNetwork.get();
@ -88,25 +127,45 @@ public class GeonetworkResolverTest {
map.put(GeonetworkResolver.UUID, value); map.put(GeonetworkResolver.UUID, value);
// data = "<request><uuid>"+uuid+"</uuid></request>"; // data = "<request><uuid>"+uuid+"</uuid></request>";
data = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + /*data = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<csw:GetRecordById xmlns:csw=\"http://www.opengis.net/cat/csw/2.0.2\" service=\"CSW\" version=\"2.0.2\" " + "<csw:GetRecordById xmlns:csw=\"http://www.opengis.net/cat/csw/2.0.2\" service=\"CSW\" version=\"2.0.2\" " +
"outputSchema=\"csw:IsoRecord\" xsi:schemaLocation=\"http://www.opengis.net/cat/csw/2.0.2/CSW-discovery.xsd\" xmlns=\"http://www.opengis.net/cat/csw/2.0.2\" " + "outputSchema=\"csw:IsoRecord\" xsi:schemaLocation=\"http://www.opengis.net/cat/csw/2.0.2/CSW-discovery.xsd\" xmlns=\"http://www.opengis.net/cat/csw/2.0.2\" " +
"xmlns:ogc=\"http://www.opengis.net/ogc\" xmlns:dc=\"http://purl.org/dc/elements/1.1/\" xmlns:dct=\"http://purl.org/dc/terms/\" xmlns:gml=\"http://www.opengis.net/gml\" " + "xmlns:ogc=\"http://www.opengis.net/ogc\" xmlns:dc=\"http://purl.org/dc/elements/1.1/\" xmlns:dct=\"http://purl.org/dc/terms/\" xmlns:gml=\"http://www.opengis.net/gml\" " +
"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">"+ "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">"+
"<csw:Id>"+uuid+"</csw:Id>" + "<csw:Id>"+uuid+"</csw:Id>" +
"<ElementSetName typeNames=\"csw:Record\">full</ElementSetName>" + "<ElementSetName typeNames=\"csw:Record\">full</ElementSetName>" +
"</csw:GetRecordById>"; "</csw:GetRecordById>";*/
byte[] byteArray = data.getBytes(); String cswQueryString = readFile("query_csw.xml");
InputStream response = httpUtils.post(gnCSWlURL, new ByteArrayInputStream(byteArray), contentType, map);
System.out.println(cswQueryString);
byte[] byteArray = cswQueryString.getBytes();
//InputStream response = httpUtils.post(gnCSWlURL, new ByteArrayInputStream(byteArray), contentType, map);
String resp = readFile("csw_response.xml");
InputStream response = IOUtils.toInputStream(resp);
// String respToString = IOUtils.toString(response); // String respToString = IOUtils.toString(response);
// System.out.println("Response returned by request: \n"+respToString); // System.out.println("Response returned by request: \n"+respToString);
// InputStream responseToIs = IOUtils.toInputStream(respToString); // InputStream responseToIs = IOUtils.toInputStream(respToString);
if(response!=null){
ReusableInputStream resResponse = new ReusableInputStream(response);
System.out.println("Get Records Response: "+IOUtils.toString(resResponse));
if(resResponse!=null){
try { try {
InputStream re = GetResponseRecordFilter.overrideResponseIdsByListIds(response, new ArrayList<String>(), "Replaced UUID"); // List<String> publicIDS = new ArrayList<String>();
FilterGetRecords filterGetRecords = FilterGetRecords.getInstance();
// publicIDS.add("000b8da6-eae6-4d91-808d-abbffdd12922");
// publicIDS.add("0652120c0f5562c8805c03c12cc971fbf14b3d05");
// publicIDS.add("fao-species-map-ojg");
// publicIDS.add("fao-species-map-sip");
Document doc = GetResponseRecordFilter.inputStreamToW3CDocument(resResponse);
doc = GetResponseRecordFilter.overrideResponseIdsByListIds(doc, filterGetRecords.getFoundPublicIds(), "Replaced UUID");
InputStream re = GetResponseRecordFilter.w3CDocumentToInputStream(doc);
// String theString = IOUtils.toString(re); // String theString = IOUtils.toString(re);
// System.out.println("Response returned after overriding: \n"+theString); // System.out.println("Response returned after overriding: \n"+theString);
@ -123,6 +182,5 @@ public class GeonetworkResolverTest {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e1.printStackTrace(); e1.printStackTrace();
} }
} }
} }

514
test.xml
View File

@ -1,514 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<csw:GetRecordByIdResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2">
<gmd:MD_Metadata xmlns:fra="http://www.cnig.gouv.fr/2005/fra" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:geonet="http://www.fao.org/geonetwork" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gmi="http://www.isotc211.org/2005/gmi" xmlns:gml="http://www.opengis.net/gml" xmlns:gmx="http://www.isotc211.org/2005/gmx" xmlns:xlink="http://www.w3.org/1999/xlink">
<gmd:fileIdentifier>
<gco:CharacterString>c15ae8e5-71c0-4b8b-aa29-304cc4e97238</gco:CharacterString>
</gmd:fileIdentifier>
<gmd:language>
<gmd:LanguageCode codeList="http://schemas.opengis.net/iso/19139/20070417/resources/Codelist/ML_gmxCodelists.xml#LanguageCode" codeListValue="eng">English</gmd:LanguageCode>
</gmd:language>
<gmd:characterSet>
<gmd:MD_CharacterSetCode codeList="http://schemas.opengis.net/iso/19139/20070417/resources/Codelist/gmxCodelists.xml#MD_CharacterSetCode" codeListValue="utf8">UTF-8</gmd:MD_CharacterSetCode>
</gmd:characterSet>
<gmd:hierarchyLevel>
<gmd:MD_ScopeCode codeList="http://schemas.opengis.net/iso/19139/20070417/resources/Codelist/gmxCodelists.xml#MD_ScopeCode" codeListValue="dataset" codeSpace="eng">Dataset</gmd:MD_ScopeCode>
</gmd:hierarchyLevel>
<gmd:contact>
<gmd:CI_ResponsibleParty>
<gmd:individualName>
<gco:CharacterString>fabio.sinibaldi</gco:CharacterString>
</gmd:individualName>
<gmd:organisationName>
<gco:CharacterString>iMarine Consortium</gco:CharacterString>
</gmd:organisationName>
<gmd:role>
<gmd:CI_RoleCode codeList="http://schemas.opengis.net/iso/19139/20070417/resources/Codelist/gmxCodelists.xml#CI_RoleCode" codeListValue="author">Author</gmd:CI_RoleCode>
</gmd:role>
</gmd:CI_ResponsibleParty>
</gmd:contact>
<gmd:contact>
<gmd:CI_ResponsibleParty>
<gmd:individualName>
<gco:CharacterString>iMarine Consortium</gco:CharacterString>
</gmd:individualName>
<gmd:organisationName>
<gco:CharacterString>iMarine.eu</gco:CharacterString>
</gmd:organisationName>
<gmd:contactInfo>
<gmd:CI_Contact>
<gmd:address>
<gmd:CI_Address>
<gmd:electronicMailAddress>
<gco:CharacterString>info@i-marine.eu</gco:CharacterString>
</gmd:electronicMailAddress>
</gmd:CI_Address>
</gmd:address>
<gmd:onlineResource>
<gmd:CI_OnlineResource>
<gmd:linkage>
<gmd:URL>http://www.i-marine.eu</gmd:URL>
</gmd:linkage>
<gmd:protocol>
<gco:CharacterString>WWW:LINK-1.0-http--link</gco:CharacterString>
</gmd:protocol>
</gmd:CI_OnlineResource>
</gmd:onlineResource>
</gmd:CI_Contact>
</gmd:contactInfo>
<gmd:role>
<gmd:CI_RoleCode codeList="http://schemas.opengis.net/iso/19139/20070417/resources/Codelist/gmxCodelists.xml#CI_RoleCode" codeListValue="distributor">Distributor</gmd:CI_RoleCode>
</gmd:role>
</gmd:CI_ResponsibleParty>
</gmd:contact>
<gmd:contact>
<gmd:CI_ResponsibleParty>
<gmd:individualName>
<gco:CharacterString>iMarine Consortium Technical Support</gco:CharacterString>
</gmd:individualName>
<gmd:organisationName>
<gco:CharacterString>iMarine.eu</gco:CharacterString>
</gmd:organisationName>
<gmd:contactInfo>
<gmd:CI_Contact>
<gmd:address>
<gmd:CI_Address>
<gmd:electronicMailAddress>
<gco:CharacterString>support@i-marine.eu</gco:CharacterString>
</gmd:electronicMailAddress>
</gmd:CI_Address>
</gmd:address>
<gmd:onlineResource>
<gmd:CI_OnlineResource>
<gmd:linkage>
<gmd:URL>http://www.i-marine.eu</gmd:URL>
</gmd:linkage>
<gmd:protocol>
<gco:CharacterString>WWW:LINK-1.0-http--link</gco:CharacterString>
</gmd:protocol>
</gmd:CI_OnlineResource>
</gmd:onlineResource>
</gmd:CI_Contact>
</gmd:contactInfo>
<gmd:role>
<gmd:CI_RoleCode codeList="http://schemas.opengis.net/iso/19139/20070417/resources/Codelist/gmxCodelists.xml#CI_RoleCode" codeListValue="resourceProvider">Resource provider</gmd:CI_RoleCode>
</gmd:role>
</gmd:CI_ResponsibleParty>
</gmd:contact>
<gmd:dateStamp>
<gco:DateTime>2013-06-19T06:28:12.340+02:00</gco:DateTime>
</gmd:dateStamp>
<gmd:spatialRepresentationInfo>
<gmd:MD_VectorSpatialRepresentation>
<gmd:topologyLevel>
<gmd:MD_TopologyLevelCode codeList="http://schemas.opengis.net/iso/19139/20070417/resources/Codelist/gmxCodelists.xml#MD_TopologyLevelCode" codeListValue="geometryOnly">Geometry only</gmd:MD_TopologyLevelCode>
</gmd:topologyLevel>
<gmd:geometricObjects>
<gmd:MD_GeometricObjects>
<gmd:geometricObjectType>
<gmd:MD_GeometricObjectTypeCode codeList="http://schemas.opengis.net/iso/19139/20070417/resources/Codelist/gmxCodelists.xml#MD_GeometricObjectTypeCode" codeListValue="surface">Surface</gmd:MD_GeometricObjectTypeCode>
</gmd:geometricObjectType>
<gmd:geometricObjectCount>
<gco:Integer>130</gco:Integer>
</gmd:geometricObjectCount>
</gmd:MD_GeometricObjects>
</gmd:geometricObjects>
</gmd:MD_VectorSpatialRepresentation>
</gmd:spatialRepresentationInfo>
<gmd:identificationInfo>
<gmd:MD_DataIdentification>
<gmd:citation>
<gmd:CI_Citation>
<gmd:title>
<gco:CharacterString>Farfantepenaeus paulensis</gco:CharacterString>
</gmd:title>
<gmd:date>
<gmd:CI_Date>
<gmd:date>
<gco:DateTime>2012-12-21T19:30:57.139+01:00</gco:DateTime>
</gmd:date>
<gmd:dateType>
<gmd:CI_DateTypeCode codeList="http://schemas.opengis.net/iso/19139/20070417/resources/Codelist/gmxCodelists.xml#CI_DateTypeCode" codeListValue="creation" codeSpace="eng">Creation</gmd:CI_DateTypeCode>
</gmd:dateType>
</gmd:CI_Date>
</gmd:date>
<gmd:presentationForm>
<gmd:CI_PresentationFormCode codeList="http://schemas.opengis.net/iso/19139/20070417/resources/Codelist/gmxCodelists.xml#CI_PresentationFormCode" codeListValue="mapDigital">Map digital</gmd:CI_PresentationFormCode>
</gmd:presentationForm>
</gmd:CI_Citation>
</gmd:citation>
<gmd:abstract>
<gco:CharacterString>This Farfantepenaeus paulensis Species Distribution Map has been generated with the AquaMaps methodology by exploiting the technology and the computational resources provided by iMarine. In particular, this map has been produced using the HSPEC 2050 Native Range dataset, generated using AquaMaps NativeRange2050 algorithm.</gco:CharacterString>
</gmd:abstract>
<gmd:purpose>
<gco:CharacterString>The aim of this Species Distribution map is to provide its users with a model-based map displaying prediction of species distributions based on occurrence records.</gco:CharacterString>
</gmd:purpose>
<gmd:credit>
<gco:CharacterString>This layer has been produced by iMarine (www.i-marine.eu). iMarine (283644) is funded by the European Commission under Framework Programme 7</gco:CharacterString>
</gmd:credit>
<gmd:credit>
<gco:CharacterString>Kaschner, K., J. S. Ready, E. Agbayani, J. Rius, K. Kesner-Reyes, P. D. Eastwood, A. B. South, S. O. Kullander, T. Rees, C. H. Close, R. Watson, D. Pauly, and R. Froese. 2008 AquaMaps: Predicted range maps for aquatic species. World wide web electronic publication, www.aquamaps.org, Version 10/2008.</gco:CharacterString>
</gmd:credit>
<gmd:resourceMaintenance>
<gmd:MD_MaintenanceInformation>
<gmd:maintenanceAndUpdateFrequency>
<gmd:MD_MaintenanceFrequencyCode codeList="http://schemas.opengis.net/iso/19139/20070417/resources/Codelist/gmxCodelists.xml#MD_MaintenanceFrequencyCode" codeListValue="asNeeded">As needed</gmd:MD_MaintenanceFrequencyCode>
</gmd:maintenanceAndUpdateFrequency>
</gmd:MD_MaintenanceInformation>
</gmd:resourceMaintenance>
<gmd:graphicOverview>
<gmd:MD_BrowseGraphic>
<gmd:fileName>
<gco:CharacterString>http://node49.p.d4science.research-infrastructures.eu:9003/83/Animalia/Arthropoda/Malacostraca/Decapoda/Penaeidae/ITS-551576/Earth.jpg</gco:CharacterString>
</gmd:fileName>
</gmd:MD_BrowseGraphic>
</gmd:graphicOverview>
<gmd:descriptiveKeywords>
<gmd:MD_Keywords>
<gmd:keyword>
<gco:CharacterString>São Paulo shrimp</gco:CharacterString>
</gmd:keyword>
<gmd:type>
<gmd:MD_KeywordTypeCode codeList="http://schemas.opengis.net/iso/19139/20070417/resources/Codelist/gmxCodelists.xml#MD_KeywordTypeCode" codeListValue="theme">Theme</gmd:MD_KeywordTypeCode>
</gmd:type>
<gmd:thesaurusName>
<gmd:CI_Citation>
<gmd:title>
<gco:CharacterString>FISHBASE</gco:CharacterString>
</gmd:title>
<gmd:date>
<gmd:CI_Date>
<gmd:date>
<gco:DateTime>2013-06-18T18:06:55.662+02:00</gco:DateTime>
</gmd:date>
<gmd:dateType>
<gmd:CI_DateTypeCode codeList="http://schemas.opengis.net/iso/19139/20070417/resources/Codelist/gmxCodelists.xml#CI_DateTypeCode" codeListValue="creation" codeSpace="eng">Creation</gmd:CI_DateTypeCode>
</gmd:dateType>
</gmd:CI_Date>
</gmd:date>
<gmd:citedResponsibleParty>
<gmd:CI_ResponsibleParty>
<gmd:individualName>
<gco:CharacterString>FISHBASE</gco:CharacterString>
</gmd:individualName>
<gmd:organisationName>
<gco:CharacterString>IFM-GEOMAR</gco:CharacterString>
</gmd:organisationName>
<gmd:contactInfo>
<gmd:CI_Contact>
<gmd:onlineResource>
<gmd:CI_OnlineResource>
<gmd:linkage>
<gmd:URL>http://www.fishbase.org/search.php</gmd:URL>
</gmd:linkage>
</gmd:CI_OnlineResource>
</gmd:onlineResource>
</gmd:CI_Contact>
</gmd:contactInfo>
<gmd:role>
<gmd:CI_RoleCode codeList="http://schemas.opengis.net/iso/19139/20070417/resources/Codelist/gmxCodelists.xml#CI_RoleCode" codeListValue="pointOfContact">Point of contact</gmd:CI_RoleCode>
</gmd:role>
</gmd:CI_ResponsibleParty>
</gmd:citedResponsibleParty>
<gmd:otherCitationDetails>
<gco:CharacterString>FishBase is a global species database of fish species (specifically finfish).</gco:CharacterString>
</gmd:otherCitationDetails>
</gmd:CI_Citation>
</gmd:thesaurusName>
</gmd:MD_Keywords>
</gmd:descriptiveKeywords>
<gmd:descriptiveKeywords>
<gmd:MD_Keywords>
<gmd:keyword>
<gco:CharacterString>Farfantepenaeus paulensis</gco:CharacterString>
</gmd:keyword>
<gmd:type>
<gmd:MD_KeywordTypeCode codeList="http://schemas.opengis.net/iso/19139/20070417/resources/Codelist/gmxCodelists.xml#MD_KeywordTypeCode" codeListValue="theme">Theme</gmd:MD_KeywordTypeCode>
</gmd:type>
<gmd:thesaurusName>
<gmd:CI_Citation>
<gmd:title>
<gco:CharacterString>OBIS</gco:CharacterString>
</gmd:title>
<gmd:date>
<gmd:CI_Date>
<gmd:date>
<gco:DateTime>2013-06-18T18:06:55.662+02:00</gco:DateTime>
</gmd:date>
<gmd:dateType>
<gmd:CI_DateTypeCode codeList="http://schemas.opengis.net/iso/19139/20070417/resources/Codelist/gmxCodelists.xml#CI_DateTypeCode" codeListValue="creation" codeSpace="eng">Creation</gmd:CI_DateTypeCode>
</gmd:dateType>
</gmd:CI_Date>
</gmd:date>
<gmd:citedResponsibleParty>
<gmd:CI_ResponsibleParty>
<gmd:individualName>
<gco:CharacterString>OBIS</gco:CharacterString>
</gmd:individualName>
<gmd:organisationName>
<gco:CharacterString>UNESCO</gco:CharacterString>
</gmd:organisationName>
<gmd:contactInfo>
<gmd:CI_Contact>
<gmd:onlineResource>
<gmd:CI_OnlineResource>
<gmd:linkage>
<gmd:URL>http://www.iobis.org</gmd:URL>
</gmd:linkage>
</gmd:CI_OnlineResource>
</gmd:onlineResource>
</gmd:CI_Contact>
</gmd:contactInfo>
<gmd:role>
<gmd:CI_RoleCode codeList="http://schemas.opengis.net/iso/19139/20070417/resources/Codelist/gmxCodelists.xml#CI_RoleCode" codeListValue="pointOfContact">Point of contact</gmd:CI_RoleCode>
</gmd:role>
</gmd:CI_ResponsibleParty>
</gmd:citedResponsibleParty>
<gmd:otherCitationDetails>
<gco:CharacterString>Intergovernmental Oceanographic Commission (IOC) of UNESCO. The Ocean Biogeographic Information System. Web. http://www.iobis.org. (Consulted on DATE)</gco:CharacterString>
</gmd:otherCitationDetails>
</gmd:CI_Citation>
</gmd:thesaurusName>
</gmd:MD_Keywords>
</gmd:descriptiveKeywords>
<gmd:descriptiveKeywords>
<gmd:MD_Keywords>
<gmd:keyword>
<gco:CharacterString>Ecological niche modelling</gco:CharacterString>
</gmd:keyword>
<gmd:keyword>
<gco:CharacterString>AquaMaps</gco:CharacterString>
</gmd:keyword>
<gmd:keyword>
<gco:CharacterString>SpeciesDistribution</gco:CharacterString>
</gmd:keyword>
<gmd:keyword>
<gco:CharacterString>iMarine</gco:CharacterString>
</gmd:keyword>
<gmd:type>
<gmd:MD_KeywordTypeCode codeList="http://schemas.opengis.net/iso/19139/20070417/resources/Codelist/gmxCodelists.xml#MD_KeywordTypeCode" codeListValue="theme">Theme</gmd:MD_KeywordTypeCode>
</gmd:type>
<gmd:thesaurusName>
<gmd:CI_Citation>
<gmd:title>
<gco:CharacterString>General</gco:CharacterString>
</gmd:title>
<gmd:date>
<gmd:CI_Date>
<gmd:date>
<gco:DateTime>2013-06-19T06:28:12.340+02:00</gco:DateTime>
</gmd:date>
<gmd:dateType>
<gmd:CI_DateTypeCode codeList="http://schemas.opengis.net/iso/19139/20070417/resources/Codelist/gmxCodelists.xml#CI_DateTypeCode" codeListValue="creation" codeSpace="eng">Creation</gmd:CI_DateTypeCode>
</gmd:dateType>
</gmd:CI_Date>
</gmd:date>
</gmd:CI_Citation>
</gmd:thesaurusName>
</gmd:MD_Keywords>
</gmd:descriptiveKeywords>
<gmd:spatialResolution>
<gmd:MD_Resolution>
<gmd:distance>
<gco:Distance uom="http://schemas.opengis.net/iso/19139/20070417/resources/uom/gmxUom.xml#xpointer(//*[@gml:id='m'])">0.5</gco:Distance>
</gmd:distance>
</gmd:MD_Resolution>
</gmd:spatialResolution>
<gmd:language>
<gmd:LanguageCode codeList="http://schemas.opengis.net/iso/19139/20070417/resources/Codelist/ML_gmxCodelists.xml#LanguageCode" codeListValue="eng">English</gmd:LanguageCode>
</gmd:language>
<gmd:topicCategory>
<gmd:MD_TopicCategoryCode>biota</gmd:MD_TopicCategoryCode>
</gmd:topicCategory>
<gmd:extent>
<gmd:EX_Extent>
<gmd:geographicElement>
<gmd:EX_GeographicBoundingBox>
<gmd:extentTypeCode>
<gco:Boolean>true</gco:Boolean>
</gmd:extentTypeCode>
<gmd:westBoundLongitude>
<gco:Decimal>-180.0</gco:Decimal>
</gmd:westBoundLongitude>
<gmd:eastBoundLongitude>
<gco:Decimal>180.0</gco:Decimal>
</gmd:eastBoundLongitude>
<gmd:southBoundLatitude>
<gco:Decimal>-90.0</gco:Decimal>
</gmd:southBoundLatitude>
<gmd:northBoundLatitude>
<gco:Decimal>90.0</gco:Decimal>
</gmd:northBoundLatitude>
</gmd:EX_GeographicBoundingBox>
</gmd:geographicElement>
</gmd:EX_Extent>
</gmd:extent>
</gmd:MD_DataIdentification>
</gmd:identificationInfo>
<gmd:distributionInfo>
<gmd:MD_Distribution>
<gmd:distributionFormat>
<gmd:MD_Format>
<gmd:name>
<gco:CharacterString>WMS</gco:CharacterString>
</gmd:name>
<gmd:version>
<gco:CharacterString>1.1.0</gco:CharacterString>
</gmd:version>
</gmd:MD_Format>
</gmd:distributionFormat>
<gmd:distributionFormat>
<gmd:MD_Format>
<gmd:name>
<gco:CharacterString>WFS</gco:CharacterString>
</gmd:name>
<gmd:version>
<gco:CharacterString>1.1.0</gco:CharacterString>
</gmd:version>
</gmd:MD_Format>
</gmd:distributionFormat>
<gmd:distributionFormat>
<gmd:MD_Format>
<gmd:name>
<gco:CharacterString>WCS</gco:CharacterString>
</gmd:name>
<gmd:version>
<gco:CharacterString>1.0.0</gco:CharacterString>
</gmd:version>
</gmd:MD_Format>
</gmd:distributionFormat>
<gmd:transferOptions>
<gmd:MD_DigitalTransferOptions>
<gmd:onLine>
<gmd:CI_OnlineResource>
<gmd:linkage>
<gmd:URL>http://geoserver4.d4science.research-infrastructures.eu/geoserver/wms?service=wms&amp;version=1.1.0&amp;request=GetMap&amp;layers=lfarfantepenaeuspaulensis20121221193002924cet&amp;styles=&amp;bbox=-180,-90,180,90&amp;width=676&amp;height=330&amp;srs=EPSG:4326&amp;crs=EPSG:4326&amp;format=application/openlayers</gmd:URL>
</gmd:linkage>
<gmd:protocol>
<gco:CharacterString>OGC:WMS-1.3.0-http-get-map</gco:CharacterString>
</gmd:protocol>
<gmd:name>
<gco:CharacterString>lfarfantepenaeuspaulensis20121221193002924cet</gco:CharacterString>
</gmd:name>
</gmd:CI_OnlineResource>
</gmd:onLine>
<gmd:onLine>
<gmd:CI_OnlineResource>
<gmd:linkage>
<gmd:URL>http://geoserver4.d4science.research-infrastructures.eu/geoserver/ows?service=WFS&amp;version=1.0.0&amp;request=GetFeature&amp;typeName=lfarfantepenaeuspaulensis20121221193002924cet&amp;format=json</gmd:URL>
</gmd:linkage>
<gmd:protocol>
<gco:CharacterString>OGC:WFS-1.0.0-http-get-feature</gco:CharacterString>
</gmd:protocol>
<gmd:name>
<gco:CharacterString>lfarfantepenaeuspaulensis20121221193002924cet</gco:CharacterString>
</gmd:name>
</gmd:CI_OnlineResource>
</gmd:onLine>
<gmd:onLine>
<gmd:CI_OnlineResource>
<gmd:linkage>
<gmd:URL>http://geoserver4.d4science.research-infrastructures.eu/geoserver/wms?service=wms&amp;version=1.1.0&amp;request=GetMap&amp;layers=lfarfantepenaeuspaulensis20121221193002924cet&amp;styles=&amp;bbox=-180,-90,180,90&amp;width=676&amp;height=330&amp;srs=EPSG:4326&amp;crs=EPSG:4326&amp;format=application/openlayers</gmd:URL>
</gmd:linkage>
<gmd:protocol>
<gco:CharacterString>OGC:WMS-1.3.0-http-get-map</gco:CharacterString>
</gmd:protocol>
<gmd:name>
<gco:CharacterString>lfarfantepenaeuspaulensis20121221193002924cet</gco:CharacterString>
</gmd:name>
</gmd:CI_OnlineResource>
</gmd:onLine>
</gmd:MD_DigitalTransferOptions>
</gmd:transferOptions>
</gmd:MD_Distribution>
</gmd:distributionInfo>
<gmd:dataQualityInfo>
<gmd:DQ_DataQuality>
<gmd:scope>
<gmd:DQ_Scope>
<gmd:level>
<gmd:MD_ScopeCode codeList="http://schemas.opengis.net/iso/19139/20070417/resources/Codelist/gmxCodelists.xml#MD_ScopeCode" codeListValue="dataset" codeSpace="eng">Dataset</gmd:MD_ScopeCode>
</gmd:level>
</gmd:DQ_Scope>
</gmd:scope>
<gmd:lineage>
<gmd:LI_Lineage>
<gmd:statement>
<gco:CharacterString>Kaschner, K., J. S. Ready, E. Agbayani, J. Rius, K. Kesner-Reyes, P. D. Eastwood, A. B. South, S. O. Kullander, T. Rees, C. H. Close, R. Watson, D. Pauly, and R. Froese. 2008 AquaMaps: Predicted range maps for aquatic species. World wide web electronic publication, www.aquamaps.org, Version 10/2008.</gco:CharacterString>
</gmd:statement>
<gmd:processStep>
<gmd:LI_ProcessStep>
<gmd:description>
<gco:CharacterString>AquaMaps Ecological Niche Modelling</gco:CharacterString>
</gmd:description>
</gmd:LI_ProcessStep>
</gmd:processStep>
<gmd:source>
<gmd:LI_Source>
<gmd:sourceCitation>
<gmd:CI_Citation>
<gmd:title>
<gco:CharacterString>HSPEC 2050 Native Range</gco:CharacterString>
</gmd:title>
<gmd:date>
<gmd:CI_Date>
<gmd:date>
<gco:DateTime>2011-10-05T00:39:17.101+02:00</gco:DateTime>
</gmd:date>
<gmd:dateType>
<gmd:CI_DateTypeCode codeList="http://schemas.opengis.net/iso/19139/20070417/resources/Codelist/gmxCodelists.xml#CI_DateTypeCode" codeListValue="creation" codeSpace="eng">Creation</gmd:CI_DateTypeCode>
</gmd:dateType>
</gmd:CI_Date>
</gmd:date>
<gmd:identifier>
<gmd:MD_Identifier>
<gmd:code>
<gco:CharacterString>hspec2011_10_04_21_00_23_274</gco:CharacterString>
</gmd:code>
</gmd:MD_Identifier>
</gmd:identifier>
</gmd:CI_Citation>
</gmd:sourceCitation>
<gmd:sourceExtent>
<gmd:EX_Extent>
<gmd:geographicElement>
<gmd:EX_GeographicBoundingBox>
<gmd:extentTypeCode>
<gco:Boolean>true</gco:Boolean>
</gmd:extentTypeCode>
<gmd:westBoundLongitude>
<gco:Decimal>-180.0</gco:Decimal>
</gmd:westBoundLongitude>
<gmd:eastBoundLongitude>
<gco:Decimal>180.0</gco:Decimal>
</gmd:eastBoundLongitude>
<gmd:southBoundLatitude>
<gco:Decimal>-90.0</gco:Decimal>
</gmd:southBoundLatitude>
<gmd:northBoundLatitude>
<gco:Decimal>90.0</gco:Decimal>
</gmd:northBoundLatitude>
</gmd:EX_GeographicBoundingBox>
</gmd:geographicElement>
</gmd:EX_Extent>
</gmd:sourceExtent>
</gmd:LI_Source>
</gmd:source>
</gmd:LI_Lineage>
</gmd:lineage>
</gmd:DQ_DataQuality>
</gmd:dataQualityInfo>
<gmd:metadataConstraints>
<gmd:MD_LegalConstraints>
<gmd:useLimitation>
<gco:CharacterString>CC-BY-SA</gco:CharacterString>
</gmd:useLimitation>
<gmd:accessConstraints>
<gmd:MD_RestrictionCode codeList="http://schemas.opengis.net/iso/19139/20070417/resources/Codelist/gmxCodelists.xml#MD_RestrictionCode" codeListValue="license">License</gmd:MD_RestrictionCode>
</gmd:accessConstraints>
<gmd:useConstraints>
<gmd:MD_RestrictionCode codeList="http://schemas.opengis.net/iso/19139/20070417/resources/Codelist/gmxCodelists.xml#MD_RestrictionCode" codeListValue="license">License</gmd:MD_RestrictionCode>
</gmd:useConstraints>
</gmd:MD_LegalConstraints>
</gmd:metadataConstraints>
</gmd:MD_Metadata>
</csw:GetRecordByIdResponse>