/**
* Copyright (c) Codice Foundation
*
* This is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser
* General Public License as published by the Free Software Foundation, either version 3 of the
* License, or any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details. A copy of the GNU Lesser General Public License
* is distributed along with this program and can be found at
* <http://www.gnu.org/licenses/lgpl.html>.
*
**/
package org.codice.ddf.spatial.ogc.csw.catalog.source;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.namespace.QName;
import javax.xml.parsers.ParserConfigurationException;
import org.geotools.filter.text.ecql.ECQL;
import org.geotools.filter.v1_1.OGCConfiguration;
import org.geotools.xml.Parser;
import org.opengis.filter.Filter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.SAXException;
import ddf.catalog.source.UnsupportedQueryException;
import net.opengis.filter.v_1_1_0.FilterType;
/**
* CswCqlTextFilter converts a {@link FilterType} to the equivalent CQL Text.
*
*/
public final class CswCqlTextFilter {
private static final Logger LOGGER = LoggerFactory.getLogger(CswCqlTextFilter.class);
private static final JAXBContext JAXB_CONTEXT = initJaxbContext();
private static final org.geotools.xml.Configuration PARSER_CONFIG = new org.geotools.filter.v1_1.OGCConfiguration();
private static CswCqlTextFilter instance;
private CswCqlTextFilter() {
}
public static CswCqlTextFilter getInstance() {
if (instance == null) {
instance = new CswCqlTextFilter();
}
return instance;
}
private static JAXBContext initJaxbContext() {
JAXBContext jaxbContext = null;
try {
jaxbContext = JAXBContext.newInstance(
"net.opengis.filter.v_1_1_0:net.opengis.gml.v_3_1_1:net.opengis.ows.v_1_0_0",
CswSource.class.getClassLoader());
} catch (JAXBException e) {
LOGGER.error("Failed to initialize JAXBContext", e);
}
return jaxbContext;
}
public String getCqlText(FilterType filterType) throws UnsupportedQueryException {
Parser parser = new Parser(new OGCConfiguration());
try {
StringReader reader = new StringReader(marshalFilterType(filterType));
Object parsedFilter = parser.parse(reader);
if (parsedFilter instanceof Filter) {
Filter filterToCql = (Filter) parsedFilter;
LOGGER.debug("Filter to Convert to CQL => {}", filterToCql);
String cql = ECQL.toCQL(filterToCql);
LOGGER.debug("Generated CQL from Filter => {}", cql);
return cql;
} else {
throw new UnsupportedQueryException("Query did not produce a valid filter.");
}
} catch (IOException e) {
throw new UnsupportedQueryException("Unable to create CQL Filter.", e);
} catch (SAXException e) {
throw new UnsupportedQueryException("Unable to create CQL Filter.", e);
} catch (ParserConfigurationException e) {
throw new UnsupportedQueryException("Unable to create CQL Filter.", e);
} catch (JAXBException e) {
throw new UnsupportedQueryException("Unable to create CQL Filter.", e);
}
}
private String marshalFilterType(FilterType filterType) throws JAXBException {
Marshaller marshaller = JAXB_CONTEXT.createMarshaller();
JAXBElement<FilterType> filterTypeJaxbElement = new JAXBElement<FilterType>(
new QName("http://www.opengis.net/ogc", "Filter"), FilterType.class, filterType);
StringWriter writer = new StringWriter();
marshaller.marshal(filterTypeJaxbElement, writer);
LOGGER.debug("Filter as XML => {}", writer.toString());
return writer.toString();
}
}