package fr.univNantes.geodoc.services.inner;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.namespace.QName;
import junit.framework.AssertionFailedError;
import org.geotoolkit.csw.CatalogServicesServer;
import org.geotoolkit.csw.GetRecordsRequest;
import org.geotoolkit.csw.TransactionRequest;
import org.geotoolkit.csw.xml.ElementSetType;
import org.geotoolkit.csw.xml.GetRecordsResponse;
import org.geotoolkit.csw.xml.ResultType;
import org.geotoolkit.csw.xml.v202.DeleteType;
import org.geotoolkit.csw.xml.v202.InsertType;
import org.geotoolkit.csw.xml.v202.QueryConstraintType;
import org.geotoolkit.csw.xml.v202.TransactionResponseType;
import org.geotoolkit.csw.xml.v202.UpdateType;
import org.geotoolkit.ebrim.xml.EBRIMClassesContext;
import org.geotoolkit.ogc.xml.v110.FilterType;
import org.geotoolkit.ogc.xml.v110.LiteralType;
import org.geotoolkit.ogc.xml.v110.PropertyIsEqualToType;
import org.geotoolkit.ogc.xml.v110.PropertyIsLikeType;
import org.geotoolkit.ogc.xml.v110.PropertyNameType;
import org.geotoolkit.ows.xml.v100.ExceptionReport;
import org.geotoolkit.xml.MarshallerPool;
import org.opengis.metadata.Metadata;
import fr.univNantes.geodoc.exceptions.BaseAppException;
import fr.univNantes.geodoc.exceptions.CswException;
public class CswRequester {
private Unmarshaller unmarshaller;
private CatalogServicesServer cswServer;
public CswRequester(Properties configuration) throws JAXBException, MalformedURLException {
MarshallerPool pool = new MarshallerPool(EBRIMClassesContext.getAllClasses());
unmarshaller = pool.acquireUnmarshaller();
cswServer = new CatalogServicesServer(
new URL(configuration.getProperty("csw-server-url")), "2.0.2"
);
}
public List<Metadata> getRecords(Integer maxRecords,
Integer startPosition,
double[] boundingBox)
throws BaseAppException {
GetRecordsRequest request = cswServer.createGetRecords();
if (maxRecords == null || maxRecords < 1) {
maxRecords = 10;
}
if (maxRecords == null || maxRecords < 1) {
maxRecords = 1;
}
request.setMaxRecords(maxRecords);
request.setStartPosition(startPosition);
request.setResultType(ResultType.RESULTS);
request.setOutputFormat("application/xml");
request.setOutputSchema("http://www.isotc211.org/2005/gmd");
request.setElementSetName(ElementSetType.FULL);
request.setTypeNames("csw:Record");
request.setDistributedSearch(false);
if (boundingBox != null) {
request.setConstraint(
String.format("BBOX(ows:BoundingBox, %d, %d, %d, %d)",
boundingBox[0], boundingBox[1], boundingBox[2], boundingBox[3])
);
}
List<Metadata> records = new ArrayList<Metadata>();
try {
InputStream stream = request.getResponseStream();
Object response = unmarshaller.unmarshal(stream);
if (response instanceof JAXBElement) {
response = ((JAXBElement<?>)response).getValue();
}
if (response instanceof GetRecordsResponse) {
GetRecordsResponse getRecordsResponse = (GetRecordsResponse) response;
for (Object record : getRecordsResponse.getSearchResults().getAny()) {
if (record instanceof Metadata) {
records.add((Metadata) record);
}
}
}
else if (response instanceof ExceptionReport) {
throw new CswException((ExceptionReport) response);
}
} catch (JAXBException e) {
throw new CswException();
} catch (IOException e) {
throw new CswException();
}
return records;
}
public void insertMetadata(Metadata metadata)
throws BaseAppException {
InsertType insert = new InsertType(metadata);
TransactionRequest request = cswServer.createTransaction();
request.setInsert(insert);
try {
InputStream stream = request.getResponseStream();
Object response = unmarshaller.unmarshal(stream);
if (response instanceof JAXBElement) {
response = ((JAXBElement<?>)response).getValue();
}
if (response instanceof TransactionResponseType) {
/*
===> LOG ERROR
TransactionResponseType transactionResponse = (TransactionResponseType) response;
assertEquals(1, transactionResponse.getTransactionSummary().getTotalInserted());
*/
}
else if (response instanceof ExceptionReport) {
throw new CswException((ExceptionReport) response);
}
} catch (JAXBException e) {
throw new CswException();
} catch (IOException e) {
throw new CswException();
} catch (AssertionFailedError e) {
throw new CswException();
}
}
public void updateMetadata(Metadata metadata)
throws BaseAppException {
String identifier = metadata.getFileIdentifier();
QueryConstraintType queryConstraint
= buildIdentifierEqualToConstraint(identifier);
UpdateType update = new UpdateType(metadata, queryConstraint);
TransactionRequest request = cswServer.createTransaction();
request.setUpdate(update);
try {
InputStream stream = request.getResponseStream();
Object response = unmarshaller.unmarshal(stream);
if (response instanceof JAXBElement) {
response = ((JAXBElement<?>)response).getValue();
}
if (response instanceof TransactionResponseType) {
/*
===> LOG ERROR
TransactionResponseType transactionResponse = (TransactionResponseType) response;
assertEquals(1, transactionResponse.getTransactionSummary().getTotalUpdated());
*/
}
else if (response instanceof ExceptionReport) {
throw new CswException((ExceptionReport) response);
}
} catch (JAXBException e) {
throw new CswException();
} catch (IOException e) {
throw new CswException();
}
}
public void deleteMetadata(String identifier)
throws BaseAppException {
QueryConstraintType queryConstraint
= buildIdentifierEqualToConstraint(identifier);
DeleteType delete = new DeleteType();
delete.setConstraint(queryConstraint);
TransactionRequest request = cswServer.createTransaction();
request.setDelete(delete);
try {
InputStream stream = request.getResponseStream();
Object response = unmarshaller.unmarshal(stream);
if (response instanceof JAXBElement) {
response = ((JAXBElement<?>)response).getValue();
}
if (response instanceof TransactionResponseType) {
/*
===> LOG ERROR
TransactionResponseType transactionResponse = (TransactionResponseType) response;
assertEquals(1, transactionResponse.getTransactionSummary().getTotalDeleted());
*/
}
else if (response instanceof ExceptionReport) {
throw new CswException((ExceptionReport) response);
}
} catch (JAXBException e) {
throw new CswException();
} catch (IOException e) {
throw new CswException();
} catch (AssertionFailedError e) {
throw new CswException();
}
}
public void deleteAllMetadata()
throws BaseAppException {
QueryConstraintType queryConstraint
= buildIdentifierAnyConstraint();
DeleteType delete = new DeleteType();
delete.setConstraint(queryConstraint);
TransactionRequest request = cswServer.createTransaction();
request.setDelete(delete);
try {
InputStream stream = request.getResponseStream();
Object response = unmarshaller.unmarshal(stream);
if (response instanceof JAXBElement) {
response = ((JAXBElement<?>)response).getValue();
}
if (response instanceof TransactionResponseType) {
/*
===> LOG ERROR
TransactionResponseType transactionResponse = (TransactionResponseType) response;
assertEquals(1, transactionResponse.getTransactionSummary().getTotalDeleted());
*/
}
else if (response instanceof ExceptionReport) {
throw new CswException((ExceptionReport) response);
}
} catch (JAXBException e) {
throw new CswException();
} catch (IOException e) {
throw new CswException();
} catch (AssertionFailedError e) {
throw new CswException();
}
}
private QueryConstraintType buildIdentifierEqualToConstraint(String identifier) {
PropertyIsEqualToType propertyIsEqualTo = new PropertyIsEqualToType();
propertyIsEqualTo.setLiteral(new LiteralType(identifier));
propertyIsEqualTo.setPropertyName(
// new PropertyNameType(new QName("http://www.opengis.net/cat/csw/apiso/1.0", "Identifier", "apiso"))
new PropertyNameType(new QName("apiso:Identifier"))
);
FilterType filter = new FilterType(propertyIsEqualTo);
QueryConstraintType queryConstraint = new QueryConstraintType();
queryConstraint.setVersion("1.1.0");
queryConstraint.setFilter(filter);
return queryConstraint;
}
private QueryConstraintType buildIdentifierAnyConstraint() {
PropertyIsLikeType propertyIsLike = new PropertyIsLikeType();
propertyIsLike.setEscapeChar("\\");
propertyIsLike.setSingleChar("?");
propertyIsLike.setWildCard("*");
propertyIsLike.setLiteral(propertyIsLike.getWildCard());
propertyIsLike.setPropertyName(
new PropertyNameType(new QName("apiso:Identifier"))
);
FilterType filter = new FilterType(propertyIsLike);
QueryConstraintType queryConstraint = new QueryConstraintType();
queryConstraint.setVersion("1.1.0");
queryConstraint.setFilter(filter);
return queryConstraint;
}
}