/* Copyright (c) 2001 - 2007 TOPP - www.openplans.org. All rights reserved.
* This code is licensed under the GPL 2.0 license, availible at the root
* application directory.
*/
package org.geoserver.wfs;
import net.opengis.wfs.DescribeFeatureTypeType;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import javax.xml.namespace.QName;
import org.geoserver.catalog.Catalog;
import org.geoserver.catalog.FeatureTypeInfo;
import org.geoserver.catalog.NamespaceInfo;
import org.geoserver.config.GeoServer;
/**
* Web Feature Service DescribeFeatureType operation.
* <p>
* This operation returns an array of {@link org.geoserver.data.feature.FeatureTypeInfo} metadata
* objects corresponding to the feature type names specified in the request.
* </p>
*
* @author Rob Hranac, TOPP
* @author Chris Holmes, TOPP
* @author Justin Deoliveira, The Open Planning Project, jdeolive@openplans.org
*
* @version $Id$
*/
public class DescribeFeatureType {
/**
* Catalog reference
*/
private Catalog catalog;
/**
* WFS service
*/
private WFSInfo wfs;
/**
* Creates a new wfs DescribeFeatureType operation.
*
* @param wfs The wfs configuration
* @param catalog The geoserver catalog.
*/
public DescribeFeatureType(WFSInfo wfs, Catalog catalog) {
this.catalog = catalog;
this.wfs = wfs;
}
public WFSInfo getWFS() {
return wfs;
}
public void setWFS(WFSInfo wfs) {
this.wfs = wfs;
}
public Catalog getCatalog() {
return catalog;
}
public void setCatalog(Catalog catalog) {
this.catalog = catalog;
}
public FeatureTypeInfo[] run(DescribeFeatureTypeType request)
throws WFSException {
List names = new ArrayList(request.getTypeName());
final boolean citeConformance = getWFS().isCiteCompliant();
if (!citeConformance) {
// HACK: as per GEOS-1816, if strict cite compliance is not set, and
// the user specified a typeName with no namespace prefix, we want
// it to be interpreted as being in the GeoServer's "default
// namespace". Yet, the xml parser did its job and since TypeName is
// of QName type, not having a ns prefix means it got parsed as a
// QName in the default namespace. That is, in the wfs namespace.
List hackedNames = new ArrayList(names.size());
final NamespaceInfo defaultNameSpace = catalog.getDefaultNamespace();
if (defaultNameSpace == null) {
throw new IllegalStateException("No default namespace configured in GeoServer");
}
final String defaultNsUri = defaultNameSpace.getURI();
for (Iterator it = names.iterator(); it.hasNext();) {
QName name = (QName) it.next();
String nsUri = name.getNamespaceURI();
if (org.geoserver.wfs.xml.v1_1_0.WFS.NAMESPACE.equals(nsUri)) {
// for this one we need to assign the default geoserver
// namespace
name = new QName(defaultNsUri, name.getLocalPart());
}
hackedNames.add(name);
}
names = hackedNames;
}
//list of catalog handles
Collection infos = catalog.getFeatureTypes();
ArrayList requested = new ArrayList();
if (!names.isEmpty()) {
O:
for (Iterator t = names.iterator(); t.hasNext();) {
QName name = (QName) t.next();
for (Iterator h = infos.iterator(); h.hasNext();) {
FeatureTypeInfo meta = (FeatureTypeInfo) h.next();
if(!meta.enabled())
continue;
String namespace = meta.getNamespace().getURI();
String local = meta.getName();
if (namespace.equals(name.getNamespaceURI())
&& local.equals(name.getLocalPart())) {
//found, continue on and keep this handle in list
requested.add(meta);
continue O;
}
}
//not found
String msg = "Could not find type: " + name;
if (citeConformance) {
msg += ". \nStrict WFS protocol conformance is being applied.\n"
+ "Make sure the type name is correctly qualified";
}
throw new WFSException(msg);
}
} else {
//if there are no specific requested types then get all the ones that
//are enabled
for (Iterator it = infos.iterator(); it.hasNext();) {
FeatureTypeInfo ftInfo = (FeatureTypeInfo) it.next();
if(ftInfo.enabled())
requested.add(ftInfo);
}
}
return (FeatureTypeInfo[]) requested.toArray(new FeatureTypeInfo[requested.size()]);
}
}