4250: Geonetwork Resolver upgrade: it must return only "private" Metadata Ids for CKAN harversting

Task-Url: https://support.d4science.org/issues/4250

Added code to filter a list of (public) IDs from CSW GetRecordsResponse

git-svn-id: http://svn.research-infrastructures.eu/public/d4science/gcube/trunk/data-transfer/uri-resolver@129136 82a268e6-3cf1-43bd-a215-b396298e98cf
This commit is contained in:
Francesco Mangiacrapa 2016-06-16 13:03:03 +00:00
parent df5bcfa2e7
commit 1c0504a3da
11 changed files with 929 additions and 22 deletions

View File

@ -1,5 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<classpath> <classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry including="**/*.java" kind="src" output="target/classes" path="src/main/java"> <classpathentry including="**/*.java" kind="src" output="target/classes" path="src/main/java">
<attributes> <attributes>
<attribute name="optional" value="true"/> <attribute name="optional" value="true"/>
@ -28,10 +33,5 @@
<attribute name="org.eclipse.jst.component.dependency" value="/WEB-INF/lib"/> <attribute name="org.eclipse.jst.component.dependency" value="/WEB-INF/lib"/>
</attributes> </attributes>
</classpathentry> </classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="target/classes"/> <classpathentry kind="output" path="target/classes"/>
</classpath> </classpath>

230
GetResponseRecords.xml Normal file
View File

@ -0,0 +1,230 @@
<?xml version="1.0" encoding="UTF-8"?>
<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-discovery.xsd">
<csw:SearchStatus timestamp="2016-06-16T10:46:04" />
<csw:SearchResults numberOfRecordsMatched="1359" numberOfRecordsReturned="10" elementSet="summary" nextRecord="11">
<csw:SummaryRecord xmlns:dct="http://purl.org/dc/terms/" xmlns:geonet="http://www.fao.org/geonetwork" xmlns:dc="http://purl.org/dc/elements/1.1/">
<dc:identifier>fao-species-map-heg</dc:identifier>
<dc:title>FAO aquatic species distribution map of Heterodontus galeatus</dc:title>
<dc:type>dataset</dc:type>
<dc:subject>FAO</dc:subject>
<dc:subject>FIGIS</dc:subject>
<dc:subject>fishery</dc:subject>
<dc:subject>fisheries</dc:subject>
<dc:subject>aquatic species distribution</dc:subject>
<dc:subject>Species distribution</dc:subject>
<dc:subject>276695</dc:subject>
<dc:subject>Heterodontus galeatus</dc:subject>
<dc:subject>HEG</dc:subject>
<dc:subject>Crested bullhead shark</dc:subject>
<dc:subject>Heterodontus galeatus</dc:subject>
<dc:subject>Heterodontidae</dc:subject>
<dc:subject>HETERODONTIFORMES</dc:subject>
<dc:subject>12656</dc:subject>
<dc:subject>fao-species-map-heg</dc:subject>
<dc:subject>http://www.fao.org/figis/lod/flod/entities/codedentity/eb7d98c4c597b05ce18ce35345af2eedbbc50ef2</dc:subject>
<dc:subject>biota</dc:subject>
<dc:subject>boundaries</dc:subject>
<dct:modified>2015-10-07</dct:modified>
<dct:abstract>The main sources of information for the species distribution are the habitat description and geographic range contained in the published FAO Catalogues of Species (more details at http://www.fao.org/fishery/fishfinder ). Terms used in the descriptive context of the FAO Catalogues were converted in standard depth, geographic and ecological regions and inserted into a Geographic Information System.</dct:abstract>
</csw:SummaryRecord>
<csw:SummaryRecord xmlns:dct="http://purl.org/dc/terms/" xmlns:geonet="http://www.fao.org/geonetwork" xmlns:dc="http://purl.org/dc/elements/1.1/">
<dc:identifier>fao-species-map-hef</dc:identifier>
<dc:title>FAO aquatic species distribution map of Heterodontus francisci</dc:title>
<dc:type>dataset</dc:type>
<dc:subject>FAO</dc:subject>
<dc:subject>FIGIS</dc:subject>
<dc:subject>fishery</dc:subject>
<dc:subject>fisheries</dc:subject>
<dc:subject>aquatic species distribution</dc:subject>
<dc:subject>Species distribution</dc:subject>
<dc:subject>276694</dc:subject>
<dc:subject>Heterodontus francisci</dc:subject>
<dc:subject>HEF</dc:subject>
<dc:subject>Horn shark</dc:subject>
<dc:subject>Heterodontus francisci</dc:subject>
<dc:subject>Heterodontidae</dc:subject>
<dc:subject>HETERODONTIFORMES</dc:subject>
<dc:subject>12655</dc:subject>
<dc:subject>fao-species-map-hef</dc:subject>
<dc:subject>http://www.fao.org/figis/lod/flod/entities/codedentity/a2a9b6439ce74eaf2a28afc6bef57eec6ec950b0</dc:subject>
<dc:subject>biota</dc:subject>
<dc:subject>boundaries</dc:subject>
<dct:modified>2015-10-07</dct:modified>
<dct:abstract>The main sources of information for the species distribution are the habitat description and geographic range contained in the published FAO Catalogues of Species (more details at http://www.fao.org/fishery/fishfinder ). Terms used in the descriptive context of the FAO Catalogues were converted in standard depth, geographic and ecological regions and inserted into a Geographic Information System.</dct:abstract>
</csw:SummaryRecord>
<csw:SummaryRecord xmlns:dct="http://purl.org/dc/terms/" xmlns:geonet="http://www.fao.org/geonetwork" xmlns:dc="http://purl.org/dc/elements/1.1/">
<dc:identifier>fao-fsa-map-41.1.3</dc:identifier>
<dc:title>Salvador (Division 41.1.3 of FAO Major Area 41)</dc:title>
<dc:type>dataset</dc:type>
<dc:subject>FAO</dc:subject>
<dc:subject>FIGIS</dc:subject>
<dc:subject>fishery</dc:subject>
<dc:subject>fisheries</dc:subject>
<dc:subject>fishery statistical areas</dc:subject>
<dc:subject>Area management/restriction/regulation zones and reporting units</dc:subject>
<dc:subject>http://www.fao.org/figis/lod/flod/entities/codedentity/415720c1e1813e22dd87f453e20b1fbd4c560207</dc:subject>
<dc:subject>fao-fsa-map-41.1.3</dc:subject>
<dc:subject>41.1.3</dc:subject>
<dc:subject>Salvador (Division 41.1.3 of FAO Major Area 41)</dc:subject>
<dc:subject>DIVISION</dc:subject>
<dc:subject>boundaries</dc:subject>
<dc:relation>fao-fsa-map-41.1</dc:relation>
<dct:modified>2015-10-13</dct:modified>
<dct:abstract>The FAO major fishing areas for statistical purpose are defined by the CWP handbook of fishery statistical standards available at http://www.fao.org/fishery/cwp/handbook/h/en</dct:abstract>
</csw:SummaryRecord>
<csw:SummaryRecord xmlns:dct="http://purl.org/dc/terms/" xmlns:geonet="http://www.fao.org/geonetwork" xmlns:dc="http://purl.org/dc/elements/1.1/">
<dc:identifier>fao-species-map-cre</dc:identifier>
<dc:title>FAO aquatic species distribution map of Cancer pagurus</dc:title>
<dc:type>dataset</dc:type>
<dc:subject>FAO</dc:subject>
<dc:subject>FIGIS</dc:subject>
<dc:subject>fishery</dc:subject>
<dc:subject>fisheries</dc:subject>
<dc:subject>aquatic species distribution</dc:subject>
<dc:subject>Species distribution</dc:subject>
<dc:subject>2627</dc:subject>
<dc:subject>http://www.fao.org/figis/lod/flod/entities/codedentity/c3518fda2e3c6765711757a92d24e57408eea429</dc:subject>
<dc:subject>CRE</dc:subject>
<dc:subject>Edible crab</dc:subject>
<dc:subject>Cancer pagurus</dc:subject>
<dc:subject>Cancridae</dc:subject>
<dc:subject>BRACHYURA</dc:subject>
<dc:subject>fao-species-map-cre</dc:subject>
<dc:subject>biota</dc:subject>
<dc:subject>boundaries</dc:subject>
<dct:modified>2015-10-07</dct:modified>
<dct:abstract>The main sources of information for the species distribution are the habitat description and geographic range contained in the published FAO Catalogues of Species (more details at http://www.fao.org/fishery/fishfinder ). Terms used in the descriptive context of the FAO Catalogues were converted in standard depth, geographic and ecological regions and inserted into a Geographic Information System.</dct:abstract>
</csw:SummaryRecord>
<csw:SummaryRecord xmlns:dct="http://purl.org/dc/terms/" xmlns:geonet="http://www.fao.org/geonetwork" xmlns:dc="http://purl.org/dc/elements/1.1/">
<dc:identifier>fao-fsa-map-41.1.4</dc:identifier>
<dc:title>Nothern Oceanic (Division 41.1.4 of FAO Major Area 41)</dc:title>
<dc:type>dataset</dc:type>
<dc:subject>FAO</dc:subject>
<dc:subject>FIGIS</dc:subject>
<dc:subject>fishery</dc:subject>
<dc:subject>fisheries</dc:subject>
<dc:subject>fishery statistical areas</dc:subject>
<dc:subject>Area management/restriction/regulation zones and reporting units</dc:subject>
<dc:subject>http://www.fao.org/figis/lod/flod/entities/codedentity/b1d33b4be19ed2dc28e9b53b7087b77ac9821662</dc:subject>
<dc:subject>fao-fsa-map-41.1.4</dc:subject>
<dc:subject>41.1.4</dc:subject>
<dc:subject>Nothern Oceanic (Division 41.1.4 of FAO Major Area 41)</dc:subject>
<dc:subject>DIVISION</dc:subject>
<dc:subject>boundaries</dc:subject>
<dc:relation>fao-fsa-map-41.1</dc:relation>
<dct:modified>2015-10-13</dct:modified>
<dct:abstract>The FAO major fishing areas for statistical purpose are defined by the CWP handbook of fishery statistical standards available at http://www.fao.org/fishery/cwp/handbook/h/en</dct:abstract>
</csw:SummaryRecord>
<csw:SummaryRecord xmlns:dct="http://purl.org/dc/terms/" xmlns:geonet="http://www.fao.org/geonetwork" xmlns:dc="http://purl.org/dc/elements/1.1/">
<dc:identifier>fao-species-map-hea</dc:identifier>
<dc:title>FAO aquatic species distribution map of Heterodontus ramalheira</dc:title>
<dc:type>dataset</dc:type>
<dc:subject>FAO</dc:subject>
<dc:subject>FIGIS</dc:subject>
<dc:subject>fishery</dc:subject>
<dc:subject>fisheries</dc:subject>
<dc:subject>aquatic species distribution</dc:subject>
<dc:subject>Species distribution</dc:subject>
<dc:subject>217626</dc:subject>
<dc:subject>Heterodontus ramalheira</dc:subject>
<dc:subject>HEA</dc:subject>
<dc:subject>Whitespotted bullhead shark</dc:subject>
<dc:subject>Heterodontus ramalheira</dc:subject>
<dc:subject>Heterodontidae</dc:subject>
<dc:subject>HETERODONTIFORMES</dc:subject>
<dc:subject>12661</dc:subject>
<dc:subject>fao-species-map-hea</dc:subject>
<dc:subject>http://www.fao.org/figis/lod/flod/entities/codedentity/be06aeb63705419c7b4c0912078337d03dbe708d</dc:subject>
<dc:subject>biota</dc:subject>
<dc:subject>boundaries</dc:subject>
<dct:modified>2015-10-07</dct:modified>
<dct:abstract>The main sources of information for the species distribution are the habitat description and geographic range contained in the published FAO Catalogues of Species (more details at http://www.fao.org/fishery/fishfinder ). Terms used in the descriptive context of the FAO Catalogues were converted in standard depth, geographic and ecological regions and inserted into a Geographic Information System.</dct:abstract>
</csw:SummaryRecord>
<csw:SummaryRecord xmlns:dct="http://purl.org/dc/terms/" xmlns:geonet="http://www.fao.org/geonetwork" xmlns:dc="http://purl.org/dc/elements/1.1/">
<dc:identifier>fao-species-map-crb</dc:identifier>
<dc:title>FAO aquatic species distribution map of Callinectes sapidus</dc:title>
<dc:type>dataset</dc:type>
<dc:subject>FAO</dc:subject>
<dc:subject>FIGIS</dc:subject>
<dc:subject>fishery</dc:subject>
<dc:subject>fisheries</dc:subject>
<dc:subject>aquatic species distribution</dc:subject>
<dc:subject>Species distribution</dc:subject>
<dc:subject>2632</dc:subject>
<dc:subject>http://www.fao.org/figis/lod/flod/entities/codedentity/3fe12b2c0394298dd5338da522bebadadf422326</dc:subject>
<dc:subject>CRB</dc:subject>
<dc:subject>Blue crab</dc:subject>
<dc:subject>Callinectes sapidus</dc:subject>
<dc:subject>Portunidae</dc:subject>
<dc:subject>BRACHYURA</dc:subject>
<dc:subject>fao-species-map-crb</dc:subject>
<dc:subject>biota</dc:subject>
<dc:subject>boundaries</dc:subject>
<dct:modified>2015-10-07</dct:modified>
<dct:abstract>The main sources of information for the species distribution are the habitat description and geographic range contained in the published FAO Catalogues of Species (more details at http://www.fao.org/fishery/fishfinder ). Terms used in the descriptive context of the FAO Catalogues were converted in standard depth, geographic and ecological regions and inserted into a Geographic Information System.</dct:abstract>
</csw:SummaryRecord>
<csw:SummaryRecord xmlns:dct="http://purl.org/dc/terms/" xmlns:geonet="http://www.fao.org/geonetwork" xmlns:dc="http://purl.org/dc/elements/1.1/">
<dc:identifier>fao-species-map-zbl</dc:identifier>
<dc:title>FAO aquatic species distribution map of Bathothauma lyromma</dc:title>
<dc:type>dataset</dc:type>
<dc:subject>FAO</dc:subject>
<dc:subject>FIGIS</dc:subject>
<dc:subject>fishery</dc:subject>
<dc:subject>fisheries</dc:subject>
<dc:subject>aquatic species distribution</dc:subject>
<dc:subject>Species distribution</dc:subject>
<dc:subject>20437</dc:subject>
<dc:subject>http://www.fao.org/figis/lod/flod/entities/codedentity/b9e91f69580e800b8d1f7d7ee232e7f0bdbd4b47</dc:subject>
<dc:subject>ZBL</dc:subject>
<dc:subject>Lyre cranch squid</dc:subject>
<dc:subject>Bathothauma lyromma</dc:subject>
<dc:subject>Cranchiidae</dc:subject>
<dc:subject>CEPHALOPODA</dc:subject>
<dc:subject>fao-species-map-zbl</dc:subject>
<dc:subject>biota</dc:subject>
<dc:subject>boundaries</dc:subject>
<dct:modified>2015-10-27</dct:modified>
<dct:abstract>The main sources of information for the species distribution are the habitat description and geographic range contained in the published FAO Catalogues of Species (more details at http://www.fao.org/fishery/fishfinder ). Terms used in the descriptive context of the FAO Catalogues were converted in standard depth, geographic and ecological regions and inserted into a Geographic Information System.</dct:abstract>
</csw:SummaryRecord>
<csw:SummaryRecord xmlns:dct="http://purl.org/dc/terms/" xmlns:geonet="http://www.fao.org/geonetwork" xmlns:dc="http://purl.org/dc/elements/1.1/">
<dc:identifier>fao-fsa-map-41.1.1</dc:identifier>
<dc:title>Amazon (Division 41.1.1 of FAO Major Area 41)</dc:title>
<dc:type>dataset</dc:type>
<dc:subject>FAO</dc:subject>
<dc:subject>FIGIS</dc:subject>
<dc:subject>fishery</dc:subject>
<dc:subject>fisheries</dc:subject>
<dc:subject>fishery statistical areas</dc:subject>
<dc:subject>Area management/restriction/regulation zones and reporting units</dc:subject>
<dc:subject>http://www.fao.org/figis/lod/flod/entities/codedentity/323ea512949786623dccbcd8320f24a59686a485</dc:subject>
<dc:subject>fao-fsa-map-41.1.1</dc:subject>
<dc:subject>41.1.1</dc:subject>
<dc:subject>Amazon (Division 41.1.1 of FAO Major Area 41)</dc:subject>
<dc:subject>DIVISION</dc:subject>
<dc:subject>boundaries</dc:subject>
<dc:relation>fao-fsa-map-41.1</dc:relation>
<dct:modified>2015-10-13</dct:modified>
<dct:abstract>The FAO major fishing areas for statistical purpose are defined by the CWP handbook of fishery statistical standards available at http://www.fao.org/fishery/cwp/handbook/h/en</dct:abstract>
</csw:SummaryRecord>
<csw:SummaryRecord xmlns:dct="http://purl.org/dc/terms/" xmlns:geonet="http://www.fao.org/geonetwork" xmlns:dc="http://purl.org/dc/elements/1.1/">
<dc:identifier>fao-fsa-map-41.1.2</dc:identifier>
<dc:title>Natal (Division 41.1.2 of FAO Major Area 41)</dc:title>
<dc:type>dataset</dc:type>
<dc:subject>FAO</dc:subject>
<dc:subject>FIGIS</dc:subject>
<dc:subject>fishery</dc:subject>
<dc:subject>fisheries</dc:subject>
<dc:subject>fishery statistical areas</dc:subject>
<dc:subject>Area management/restriction/regulation zones and reporting units</dc:subject>
<dc:subject>http://www.fao.org/figis/lod/flod/entities/codedentity/ec79700361176dbf80815a9235d71bde3fbc0542</dc:subject>
<dc:subject>fao-fsa-map-41.1.2</dc:subject>
<dc:subject>41.1.2</dc:subject>
<dc:subject>Natal (Division 41.1.2 of FAO Major Area 41)</dc:subject>
<dc:subject>DIVISION</dc:subject>
<dc:subject>boundaries</dc:subject>
<dc:relation>fao-fsa-map-41.1</dc:relation>
<dct:modified>2015-10-13</dct:modified>
<dct:abstract>The FAO major fishing areas for statistical purpose are defined by the CWP handbook of fishery statistical standards available at http://www.fao.org/fishery/cwp/handbook/h/en</dct:abstract>
</csw:SummaryRecord>
</csw:SearchResults>
</csw:GetRecordsResponse>

View File

@ -44,7 +44,9 @@
</Changeset> </Changeset>
<Changeset component="org.gcube.data-transfer.uri-resolver.1-7-0" <Changeset component="org.gcube.data-transfer.uri-resolver.1-7-0"
date="2016-06-09"> date="2016-06-09">
<Change>[Feature #4207] ri Resolver upgrade: it must support new Geonetwork Manager <Change>[Feature #4207] Uri Resolver upgrade: it must support new Geonetwork Manager
</Change>
<Change>[Task #4250] Geonetwork Resolver upgrade: it must return only "private" Metadata Ids for CKAN harversting
</Change> </Change>
</Changeset> </Changeset>
</ReleaseNotes> </ReleaseNotes>

View File

@ -0,0 +1,78 @@
/**
*
*/
package org.gcube.datatransfer.resolver;
/**
*
* @author Francesco Mangiacrapa francesco.mangiacrapa@isti.cnr.it
* Jun 15, 2016
*/
public class GeonetworkRequestCriteria {
private String scope;
private final String FILTER_PUBLIC_IDS = "FILTER_PUBLIC_IDS";
private boolean valueOfFilterPublicIds;
GeonetworkRequestCriteria(String scope, boolean valueOfFilterPublicIds){
this.scope = scope;
this.valueOfFilterPublicIds = valueOfFilterPublicIds;
}
/**
* @return the scope
*/
public String getScope() {
return scope;
}
/**
* @return the valueOfFilterPublicIds
*/
public boolean isValueOfFilterPublicIds() {
return valueOfFilterPublicIds;
}
/**
* @param scope the scope to set
*/
public void setScope(String scope) {
this.scope = scope;
}
/**
* @param valueOfFilterPublicIds the valueOfFilterPublicIds to set
*/
public void setValueOfFilterPublicIds(boolean valueOfFilterPublicIds) {
this.valueOfFilterPublicIds = valueOfFilterPublicIds;
}
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("GeonetworkQueryCriteria [scope=");
builder.append(scope);
builder.append(", FILTER_PUBLIC_IDS=");
builder.append(FILTER_PUBLIC_IDS);
builder.append(", valueOfFilterPublicIds=");
builder.append(valueOfFilterPublicIds);
builder.append("]");
return builder.toString();
}
}

View File

@ -0,0 +1,100 @@
/**
*
*/
package org.gcube.datatransfer.resolver;
import javax.servlet.ServletException;
import org.apache.commons.lang.StringUtils;
import org.gcube.datatransfer.resolver.gis.geonetwork.GeonetworkResolver;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* The Class GeonetworkScopeDecoder.
*
* @author Francesco Mangiacrapa francesco.mangiacrapa@isti.cnr.it
* Gets the new uri to forward the request to {@link GeonetworkResolver}
* Jun 15, 2016
*/
public class GeonetworkRequestDecoder {
public static final Logger logger = LoggerFactory.getLogger(GeonetworkRequestDecoder.class);
private String newURI;
/**
* Instantiates a new geonetwork request decoder.
*
* @param theServletPath the the servlet path
* @param queryString the query string
* @throws ServletException the servlet exception
*/
public GeonetworkRequestDecoder(String theServletPath, String queryString) throws ServletException{
logger.debug("is geonetwork request");
String path = theServletPath;
String pathWithoutGN = path.substring(UriResolverRewriteFilter.SERVLET_GEONETWORK.length()+1, path.length());
logger.debug("servlet path without "+UriResolverRewriteFilter.SERVLET_GEONETWORK + " is: " +pathWithoutGN);
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_vo_vre");
}
GeonetworkRequestCriteria rc = getGeonetworkRequestCriteria(params[0]);
logger.debug("scope value is: "+rc.getScope());
newURI = UriResolverRewriteFilter.SERVLET_GEONETWORK + "?" + GeonetworkResolver.SCOPE + "=" + rc.getScope() +"&"+ GeonetworkResolver.PARAMETER_FILTER_PUBLIC_IDS +"="+rc.isValueOfFilterPublicIds();
logger.debug(GeonetworkResolver.PARAMETER_FILTER_PUBLIC_IDS +" is: "+rc.isValueOfFilterPublicIds());
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;
}
/**
* Gets the geonetwork request criteria.
* Parses a request like root_vo_vre#filterPublicIds or root_vo_vre
*
* @param request the request
* @return the geonetwork request criteria
*/
private static GeonetworkRequestCriteria getGeonetworkRequestCriteria(String request){
logger.debug("Read request: "+request);
int index = request.indexOf(UriResolverRewriteFilter.REQUEST_PARAMETER_SEPARATOR);
String scope = "";
boolean filterPublicIds = false;
if(index!=-1){
scope = request.substring(0,index);
filterPublicIds = StringUtils.containsIgnoreCase(UriResolverRewriteFilter.PARAMETER_FILTER_PUBLIC_IDS, request);
}else
scope = request;
return new GeonetworkRequestCriteria("/"+scope.replaceAll("_", "/"), filterPublicIds);
}
/**
* Gets the new uri.
*
* @return the newURI
*/
public String getNewURI() {
return newURI;
}
}

View File

@ -13,7 +13,6 @@ import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse; import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import org.gcube.datatransfer.resolver.gis.geonetwork.GeonetworkResolver;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -27,6 +26,8 @@ import org.slf4j.LoggerFactory;
public class UriResolverRewriteFilter implements Filter{ public class UriResolverRewriteFilter implements Filter{
public static final String SERVLET_GEONETWORK = "/geonetwork"; public static final String SERVLET_GEONETWORK = "/geonetwork";
public static final String PARAMETER_FILTER_PUBLIC_IDS = "filterpublicids";
public static final String REQUEST_PARAMETER_SEPARATOR = "#";
protected static final String SMP_ID = "smp-id"; protected static final String SMP_ID = "smp-id";
protected static final String SERVLET_RESOLVER_BY_ID = "id"; protected static final String SERVLET_RESOLVER_BY_ID = "id";
protected static final Logger logger = LoggerFactory.getLogger(UriResolverRewriteFilter.class); protected static final Logger logger = LoggerFactory.getLogger(UriResolverRewriteFilter.class);
@ -63,8 +64,7 @@ public class UriResolverRewriteFilter implements Filter{
//IS A REQUEST FOR GEONETWORK AUTHENTICATION? (CKAN HARVESTING?) //IS A REQUEST FOR GEONETWORK AUTHENTICATION? (CKAN HARVESTING?)
if(isGeonetworkRequest(multiReadRequest.getServletPath())){ if(isGeonetworkRequest(multiReadRequest.getServletPath())){
logger.debug("is geonetwork"); /*String path = multiReadRequest.getServletPath();
String path = multiReadRequest.getServletPath();
String pathWithoutGN = path.substring(SERVLET_GEONETWORK.length()+1, path.length()); String pathWithoutGN = path.substring(SERVLET_GEONETWORK.length()+1, path.length());
logger.debug("servlet path without "+SERVLET_GEONETWORK + " is: " +pathWithoutGN); logger.debug("servlet path without "+SERVLET_GEONETWORK + " is: " +pathWithoutGN);
String[] params = pathWithoutGN.split("/"); String[] params = pathWithoutGN.split("/");
@ -93,11 +93,14 @@ public class UriResolverRewriteFilter implements Filter{
logger.debug("forward "+newURI); logger.debug("forward "+newURI);
//BODY DEBUG //BODY DEBUG
/* // String readBody = IOUtils.toString(multiReadRequest.getReader());
String readBody = IOUtils.toString(multiReadRequest.getReader()); // logger.debug("Read body request: "+readBody);
logger.debug("Read body request: "+readBody); multiReadRequest.getRequestDispatcher(newURI).forward(multiReadRequest, response);*/
*/ logger.debug("is geonetwork request");
multiReadRequest.getRequestDispatcher(newURI).forward(multiReadRequest, response); GeonetworkRequestDecoder grd = new GeonetworkRequestDecoder(multiReadRequest.getServletPath(), queryString);
logger.debug("forward to: "+grd.getNewURI());
multiReadRequest.getRequestDispatcher(grd.getNewURI()).forward(multiReadRequest, response);
}else{ }else{
//IS WORKSPACE REQUEST? //IS WORKSPACE REQUEST?
if (queryString == null) { // IS A /XXXXX if (queryString == null) { // IS A /XXXXX

View File

@ -0,0 +1,78 @@
/**
*
*/
package org.gcube.datatransfer.resolver.gis.geonetwork;
import it.geosolutions.geonetwork.util.GNSearchRequest;
import it.geosolutions.geonetwork.util.GNSearchResponse;
import it.geosolutions.geonetwork.util.GNSearchResponse.GNMetadata;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.gcube.spatial.data.geonetwork.GeoNetwork;
import org.gcube.spatial.data.geonetwork.GeoNetworkReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* The Class FilterGetRecords.
*
* @author Francesco Mangiacrapa francesco.mangiacrapa@isti.cnr.it
* Jun 15, 2016
*/
public class FilterGetRecords {
/**
*
*/
private static final String CSW_GET_RECORDS = "csw:GetRecords";
private static final Logger logger = LoggerFactory.getLogger(FilterGetRecords.class);
private List<String> foundPublicIds = null;
/**
* Instantiates a new filter get records.
*
* @param readBody the read body
*/
public FilterGetRecords(String readBody) {
if(readBody!=null && !readBody.isEmpty() && readBody.contains(CSW_GET_RECORDS)){
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);
}
}
}
/**
* Gets the found public ids.
*
* @return the foundPublicIds
*/
public List<String> getFoundPublicIds() {
return foundPublicIds==null || foundPublicIds.isEmpty()? null: foundPublicIds;
}
}

View File

@ -27,6 +27,7 @@ import javax.servlet.http.HttpServletResponse;
import org.apache.commons.io.IOUtils; 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.UriResolverRewriteFilter;
import org.gcube.datatransfer.resolver.gis.GeoRuntimeReader; import org.gcube.datatransfer.resolver.gis.GeoRuntimeReader;
import org.gcube.datatransfer.resolver.gis.GeoRuntimeReader.GEO_SERVICE; import org.gcube.datatransfer.resolver.gis.GeoRuntimeReader.GEO_SERVICE;
import org.gcube.datatransfer.resolver.gis.GeonetworkAccessParameter; import org.gcube.datatransfer.resolver.gis.GeonetworkAccessParameter;
@ -34,6 +35,7 @@ import org.gcube.datatransfer.resolver.gis.GeonetworkInstance;
import org.gcube.datatransfer.resolver.gis.GeonetworkServiceInterface; import org.gcube.datatransfer.resolver.gis.GeonetworkServiceInterface;
import org.gcube.datatransfer.resolver.gis.entity.ServerParameters; import org.gcube.datatransfer.resolver.gis.entity.ServerParameters;
import org.gcube.datatransfer.resolver.gis.exception.IllegalArgumentException; import org.gcube.datatransfer.resolver.gis.exception.IllegalArgumentException;
import org.gcube.datatransfer.resolver.gis.util.GetResponseRecordFilter;
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;
@ -74,6 +76,7 @@ public class GeonetworkResolver extends HttpServlet{
public static final String RESET_CACHE = "resetcache"; public static final String RESET_CACHE = "resetcache";
public static final String RESET_CACHED_SCOPE = "resetcachedscope"; public static final String RESET_CACHED_SCOPE = "resetcachedscope";
public static final String CSW_SERVER = "srv/en/csw"; public static final String CSW_SERVER = "srv/en/csw";
public static final String PARAMETER_FILTER_PUBLIC_IDS = UriResolverRewriteFilter.PARAMETER_FILTER_PUBLIC_IDS;
/** The logger. */ /** The logger. */
private static final Logger logger = LoggerFactory.getLogger(GeonetworkResolver.class); private static final Logger logger = LoggerFactory.getLogger(GeonetworkResolver.class);
@ -240,6 +243,8 @@ public class GeonetworkResolver extends HttpServlet{
logger.info("doPost running..."); logger.info("doPost running...");
String scope = req.getParameter(SCOPE); String scope = req.getParameter(SCOPE);
String remainValue = req.getParameter(REMAIN_PATH); String remainValue = req.getParameter(REMAIN_PATH);
String filterPublicIDs = req.getParameter(PARAMETER_FILTER_PUBLIC_IDS);
boolean filterPublicMetadataIDs = false;
if (scope == null || scope.equals("")) { if (scope == null || scope.equals("")) {
logger.debug("Scope not found"); logger.debug("Scope not found");
@ -247,7 +252,12 @@ public class GeonetworkResolver extends HttpServlet{
return; return;
} }
if(filterPublicIDs!=null && Boolean.parseBoolean(filterPublicIDs)){
filterPublicMetadataIDs = true;
}
logger.info("SCOPE is: " + scope); logger.info("SCOPE is: " + scope);
logger.info(PARAMETER_FILTER_PUBLIC_IDS +" is "+filterPublicMetadataIDs);
try { try {
@ -275,12 +285,6 @@ public class GeonetworkResolver extends HttpServlet{
// logger.debug("doPost read body request: "+readBody); // logger.debug("doPost read body request: "+readBody);
ByteArrayOutputStream byteArray = new ByteArrayOutputStream(); ByteArrayOutputStream byteArray = new ByteArrayOutputStream();
if(account.getUser()!=null){
boolean authorized = GNAuthentication.login(httpUtils, geonetworkParams.getUrl(), account.getUser(), account. getPassword());
logger.trace("Authorized on "+geonetworkParams +" ? "+authorized);
}else
logger.info("Skipping authentication ckan user is null");
// SPECIFIC HANDLER FOR GEONETWORK REQUEST: /srv/en/mef.export // SPECIFIC HANDLER FOR GEONETWORK REQUEST: /srv/en/mef.export
String gnCSWlURL; String gnCSWlURL;
if(remainValue!=null && remainValue.compareTo(SRV_EN_MEF_EXPORT)==0){ if(remainValue!=null && remainValue.compareTo(SRV_EN_MEF_EXPORT)==0){
@ -293,7 +297,7 @@ public class GeonetworkResolver extends HttpServlet{
data = UUID+"="+uuid; data = UUID+"="+uuid;
} }
if(data!=null){ if(data!=null){
logger.debug("Writing "+data +" to byte array"); logger.debug("Writing "+data +" into byte array");
byteArray.write(data.getBytes()); byteArray.write(data.getBytes());
}else }else
IOUtils.copy(req.getReader(), byteArray); IOUtils.copy(req.getReader(), byteArray);
@ -304,10 +308,22 @@ public class GeonetworkResolver extends HttpServlet{
IOUtils.copy(req.getReader(), byteArray); IOUtils.copy(req.getReader(), byteArray);
} }
FilterGetRecords filterGetRecords = null;
if(filterPublicMetadataIDs){
filterGetRecords = new FilterGetRecords(byteArray.toString());
}
if(account.getUser()!=null){
boolean authorized = GNAuthentication.login(httpUtils, geonetworkParams.getUrl(), account.getUser(), account. getPassword());
logger.trace("Authorized on "+geonetworkParams +" ? "+authorized);
}else
logger.info("Skipping authentication ckan user is null");
logger.info("Sending CSW POST request to URL: "+gnCSWlURL); logger.info("Sending CSW POST request to URL: "+gnCSWlURL);
logger.info("Content-Type: "+req.getContentType()); logger.info("Content-Type: "+req.getContentType());
//DEBUG //DEBUG
logger.debug("POST - BODY : "+byteArray.toString()); logger.trace("POST - BODY : "+byteArray.toString());
InputStream in = httpUtils.post(gnCSWlURL, new ByteArrayInputStream(byteArray.toByteArray()), req.getContentType(), req.getParameterMap()); InputStream in = httpUtils.post(gnCSWlURL, new ByteArrayInputStream(byteArray.toByteArray()), req.getContentType(), req.getParameterMap());
//END DEBUG //END DEBUG
logger.info("Response return Content-Type: "+httpUtils.getLastContentType()); logger.info("Response return Content-Type: "+httpUtils.getLastContentType());
@ -320,6 +336,12 @@ public class GeonetworkResolver extends HttpServlet{
return; return;
} }
try{ try{
if(filterGetRecords!=null){
logger.info("I'm removing list of public IDs, Is it right? "+filterGetRecords);
in = GetResponseRecordFilter.removeSummaryIdsByListIds(new ByteArrayInputStream(byteArray.toByteArray()), filterGetRecords.getFoundPublicIds());
}
int bytes = IOUtils.copy(in, out); int bytes = IOUtils.copy(in, out);
if(bytes==0) if(bytes==0)
logger.warn("ResponseBody is empty, returning empty resp"); logger.warn("ResponseBody is empty, returning empty resp");

View File

@ -0,0 +1,110 @@
/**
*
*/
package org.gcube.datatransfer.resolver.gis.util;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
/**
* The Class GetResponseRecordFilter.
*
* @author Francesco Mangiacrapa francesco.mangiacrapa@isti.cnr.it Jun 16, 2016
*/
public class GetResponseRecordFilter {
public static Logger logger = LoggerFactory.getLogger(GetResponseRecordFilter.class);
/**
* Delete summary record.
*
* @param doc
* the doc
* @param identifier
* the identifier
*/
private static void deleteSummaryRecord(Document doc, String identifier) {
// <csw:SummaryRecord> list
NodeList nodes = doc.getElementsByTagName("csw:SummaryRecord");
logger.trace("SummaryRecord are: " + nodes.getLength());
for (int i = 0; i < nodes.getLength(); i++) {
Element summaryRecord = (Element) nodes.item(i);
// <dc:identifier>
Element id = (Element) summaryRecord.getElementsByTagName("dc:identifier").item(0);
String idValue = id.getTextContent();
logger.trace("Summary dc:identifier is: " + idValue);
if (idValue.equals(identifier)) {
summaryRecord.getParentNode().removeChild(summaryRecord);
logger.trace("Removed child " + idValue);
}
}
}
/**
* Removes the summary ids by list ids.
*
* @param getRecordsResponse the get records response
* @param idsToRemove the ids to remove
* @return the input stream
* @throws IOException Signals that an I/O exception has occurred.
*/
public static InputStream removeSummaryIdsByListIds(InputStream getRecordsResponse, List<String> idsToRemove) throws IOException {
try {
// logger.trace("getRecordsResponse is: "+IOUtils.toString(getRecordsResponse));
BufferedInputStream bis = new BufferedInputStream(getRecordsResponse);
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setValidating(false);
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(bis);
for (String identifier : idsToRemove) {
deleteSummaryRecord(doc, identifier);
}
return documentToInputStream(doc);
}
catch (Exception e) {
logger.error("An error occurred during removing IDS by List: ", e);
return getRecordsResponse;
}
}
/**
* Document to input stream.
*
* @param xml the xml
* @return the input stream
* @throws Exception the exception
*/
private static final InputStream documentToInputStream(Document xml) throws Exception {
Transformer tf = TransformerFactory.newInstance().newTransformer();
tf.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
tf.setOutputProperty(OutputKeys.INDENT, "yes");
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
StreamResult outputTarget = new StreamResult(outputStream);
tf.transform(new DOMSource(xml), outputTarget);
return new ByteArrayInputStream(outputStream.toByteArray());
// return out.toString();
}
}

View File

@ -0,0 +1,90 @@
/**
*
*/
package org.gcube.datatransfer.resolver.gis.util;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import javax.xml.XMLConstants;
import javax.xml.namespace.NamespaceContext;
/**
* The Class NamespaceCsw.
*
* @author Francesco Mangiacrapa francesco.mangiacrapa@isti.cnr.it
* Jun 16, 2016
*/
public class NamespaceCsw extends NamespaceISO19139 implements NamespaceContext {
private Map<String, String> mapPrefix;
/**
* Instantiates a new namespace csw.
*/
public NamespaceCsw() {
mapPrefix = new HashMap<String, String>();
mapPrefix.put(getPrefixGMD(), getNamespaceGMD());
mapPrefix.put(getPrefixCSW(), getNamespaceCSW());
mapPrefix.put(getPrefixOWS(), getNamespaceOWS());
mapPrefix.put(getPrefixDC(), getNamespaceDC());
mapPrefix.put(getPrefixGCO(), getNamespaceGCO());
mapPrefix.put(getPrefixXLINK(), getNamespaceXLINK());
mapPrefix.put(getPrefixSRV(), getNamespaceSRV());
mapPrefix.put(getPrefixXSI(), getNamespaceXSI());
mapPrefix.put(getPrefixGML(), getNamespaceGML());
mapPrefix.put(getPrefixGTS(), getNamespaceGTS());
mapPrefix.put(getPrefixGEONET(), getNamespaceGEONET());
mapPrefix.put(getPrefixDCT(), getNamespaceDCT());
};
/**
* Returns an iterator to every prefix in this namespace.
*
* @return the prefix iterator
*/
public Iterator<String> getPrefixIterator() {
return mapPrefix.keySet().iterator();
}
/* (non-Javadoc)
* @see javax.xml.namespace.NamespaceContext#getNamespaceURI(java.lang.String)
*/
public String getNamespaceURI(String prefix) {
if (prefix == null)
throw new IllegalArgumentException("No prefix provided!");
if (mapPrefix.containsKey(prefix))
return mapPrefix.get(prefix);
else
return XMLConstants.NULL_NS_URI;
}
/* (non-Javadoc)
* @see javax.xml.namespace.NamespaceContext#getPrefix(java.lang.String)
*/
@Override
public String getPrefix(String namespaceURI) {
for (String prefix : mapPrefix.keySet()) {
String nu = mapPrefix.get(prefix);
if(nu.compareTo(namespaceURI)==0)
return prefix;
}
return null;
}
/* (non-Javadoc)
* @see javax.xml.namespace.NamespaceContext#getPrefixes(java.lang.String)
*/
@Override
public Iterator<String> getPrefixes(String namespaceURI) {
return mapPrefix.keySet().iterator();
}
}

View File

@ -0,0 +1,194 @@
/**
*
*/
package org.gcube.datatransfer.resolver.gis.util;
public abstract class NamespaceISO19139 {
//Namespaces
private final String namespaceCSW = "http://www.opengis.net/cat/csw/2.0.2";
private final String namespaceDC = "http://purl.org/dc/elements/1.1/";
private final String namespaceOWS = "http://www.opengis.net/ows";
private final String namespaceGMD = "http://www.isotc211.org/2005/gmd";
private final String namespaceGCO = "http://www.isotc211.org/2005/gco";
private final String namespaceXLINK = "http://www.w3.org/1999/xlink";
private final String namespaceSRV = "http://www.isotc211.org/2005/srv";
private final String namespaceXSI = "http://www.w3.org/2001/XMLSchema-instance";
private final String namespaceGML = "http://www.opengis.net/gml";
private final String namespaceGTS = "http://www.isotc211.org/2005/gts";
private final String namespaceGEONET = "http://www.fao.org/geonetwork";
private final String namespaceGMX = "http://www.isotc211.org/2005/gmx";
private final String namespaceWMS = "http://www.opengis.net/wms";
private final String namespaceDCT = "http://purl.org/dc/terms/";
//Prefixs
private final String prefixCSW = "csw";
private final String prefixGMD = "gmd";
private final String prefixOWS = "ows";
private final String prefixDC = "dc";
private final String prefixDCT = "dct";
private final String prefixGCO = "gco";
private final String prefixXLINK= "xlink";
private final String prefixSRV = "srv";
private final String prefixXSI = "xsi";
private final String prefixGML = "gml";
private final String prefixGTS = "gts";
private final String prefixGEONET = "geonet";
private final String prefixGMX = "gmx";
private final String prefixWMS = "wms";
public String getNamespaceCSW() {
return namespaceCSW;
}
public String getNamespaceDC() {
return namespaceDC;
}
public String getNamespaceOWS() {
return namespaceOWS;
}
public String getNamespaceGMD() {
return namespaceGMD;
}
public String getNamespaceGCO() {
return namespaceGCO;
}
public String getNamespaceXLINK() {
return namespaceXLINK;
}
public String getNamespaceSRV() {
return namespaceSRV;
}
public String getNamespaceXSI() {
return namespaceXSI;
}
public String getNamespaceGML() {
return namespaceGML;
}
public String getNamespaceGTS() {
return namespaceGTS;
}
public String getNamespaceGEONET() {
return namespaceGEONET;
}
public String getPrefixCSW() {
return prefixCSW;
}
public String getPrefixGMD() {
return prefixGMD;
}
public String getPrefixOWS() {
return prefixOWS;
}
public String getPrefixDC() {
return prefixDC;
}
public String getPrefixGCO() {
return prefixGCO;
}
public String getPrefixXLINK() {
return prefixXLINK;
}
public String getPrefixSRV() {
return prefixSRV;
}
public String getPrefixGML() {
return prefixGML;
}
public String getPrefixGTS() {
return prefixGTS;
}
public String getPrefixGEONET() {
return prefixGEONET;
}
public String getPrefixXSI() {
return prefixXSI;
}
public String getPrefixGMX() {
return prefixGMX;
}
public String getNamespaceGMX() {
return namespaceGMX;
}
public String getPrefixWMS() {
return prefixWMS;
}
public String getNamespaceWMS() {
return namespaceWMS;
}
public String getNamespaceDCT() {
return namespaceDCT;
}
public String getPrefixDCT() {
return prefixDCT;
}
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("NamespaceISO19139 [namespaceCSW=");
builder.append(namespaceCSW);
builder.append(", namespaceDC=");
builder.append(namespaceDC);
builder.append(", namespaceOWS=");
builder.append(namespaceOWS);
builder.append(", namespaceGMD=");
builder.append(namespaceGMD);
builder.append(", namespaceGCO=");
builder.append(namespaceGCO);
builder.append(", namespaceXLINK=");
builder.append(namespaceXLINK);
builder.append(", namespaceSRV=");
builder.append(namespaceSRV);
builder.append(", namespaceXSI=");
builder.append(namespaceXSI);
builder.append(", namespaceGML=");
builder.append(namespaceGML);
builder.append(", namespaceGTS=");
builder.append(namespaceGTS);
builder.append(", namespaceGEONET=");
builder.append(namespaceGEONET);
builder.append(", namespaceGMX=");
builder.append(namespaceGMX);
builder.append(", namespaceWMS=");
builder.append(namespaceWMS);
builder.append(", namespaceDCT=");
builder.append(namespaceDCT);
builder.append(", prefixCSW=");
builder.append(prefixCSW);
builder.append(", prefixGMD=");
builder.append(prefixGMD);
builder.append(", prefixOWS=");
builder.append(prefixOWS);
builder.append(", prefixDC=");
builder.append(prefixDC);
builder.append(", prefixDCT=");
builder.append(prefixDCT);
builder.append(", prefixGCO=");
builder.append(prefixGCO);
builder.append(", prefixXLINK=");
builder.append(prefixXLINK);
builder.append(", prefixSRV=");
builder.append(prefixSRV);
builder.append(", prefixXSI=");
builder.append(prefixXSI);
builder.append(", prefixGML=");
builder.append(prefixGML);
builder.append(", prefixGTS=");
builder.append(prefixGTS);
builder.append(", prefixGEONET=");
builder.append(prefixGEONET);
builder.append(", prefixGMX=");
builder.append(prefixGMX);
builder.append(", prefixWMS=");
builder.append(prefixWMS);
builder.append("]");
return builder.toString();
}
}