/* (c) 2014 - 2015 Open Source Geospatial Foundation - all rights reserved
* Copyright (C) 2007-2008-2009 GeoSolutions S.A.S.
* http://www.geo-solutions.it
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
*/
package org.geoserver.sldservice.rest.resource;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.geoserver.catalog.Catalog;
import org.geoserver.catalog.FeatureTypeInfo;
import org.geoserver.catalog.LayerInfo;
import org.geoserver.catalog.ResourceInfo;
import org.geoserver.catalog.rest.AbstractCatalogResource;
import org.geoserver.config.util.SecureXStream;
import org.geoserver.rest.RestletException;
import org.geoserver.rest.format.DataFormat;
import org.geoserver.rest.format.ReflectiveHTMLFormat;
import org.geoserver.rest.format.ReflectiveJSONFormat;
import org.geoserver.rest.format.ReflectiveXMLFormat;
import org.opengis.feature.type.PropertyDescriptor;
import org.restlet.Context;
import org.restlet.data.Request;
import org.restlet.data.Response;
import org.restlet.data.Status;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.converters.Converter;
import com.thoughtworks.xstream.converters.MarshallingContext;
import com.thoughtworks.xstream.converters.UnmarshallingContext;
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import com.thoughtworks.xstream.io.json.JettisonMappedXmlDriver;
import freemarker.ext.beans.MapModel;
import freemarker.template.Configuration;
import freemarker.template.SimpleHash;
/**
* @author kappu
*
* Should get all Attributes related to a featureType we have internal
* Style abd external sld
*
*/
public class ListAttributesResource extends AbstractCatalogResource {
public ListAttributesResource(Context context, Request request,
Response response, Catalog catalog) {
super(context, request, response, ListAttributesResource.class, catalog);
}
@Override
protected Object handleObjectGet() {
String layer = getAttribute("layer");
if (layer == null) {
// return all layers
return new ArrayList();
}
LayerInfo layerInfo = catalog.getLayerByName(layer);
if (layerInfo != null) {
ResourceInfo obj = layerInfo.getResource();
Collection<PropertyDescriptor> attributes = null;
/* Check if it's feature type or coverage */
if (obj instanceof FeatureTypeInfo) {
FeatureTypeInfo fTpInfo;
fTpInfo = (FeatureTypeInfo) obj;
LayerAttributesList out = new LayerAttributesList(layer);
try {
attributes = fTpInfo.getFeatureType().getDescriptors();
for (PropertyDescriptor attr : attributes) {
out.addAttribute(attr.getName().getLocalPart(), attr.getType().getBinding().getSimpleName());
}
} catch (IOException e) {
throw new RestletException("Error generating Attributes List!", Status.CLIENT_ERROR_BAD_REQUEST);
}
return out;
}
}
return new ArrayList();
}
/**
*
*/
@Override
protected ReflectiveXMLFormat createXMLFormat(Request request,
Response response) {
return new ReflectiveXMLFormat() {
@Override
protected void write(Object data, OutputStream output)
throws IOException {
XStream xstream = new SecureXStream();
xstream.setMode(XStream.NO_REFERENCES);
// Aliases
xstream.alias("Attributes", LayerAttributesList.class);
// Converters
xstream.registerConverter(new LayerAttributesListConverter());
xstream.allowTypes(new Class[] { LayerAttributesList.class,
LayerAttributesListConverter.class });
// Marshalling
xstream.toXML(data, output);
}
};
}
/**
* @see
* org.geoserver.catalog.rest.AbstractCatalogResource#createJSONFormat(org
* .restlet.data.Request, org.restlet.data.Response)
*/
@Override
protected ReflectiveJSONFormat createJSONFormat(Request request,
Response response) {
return new ReflectiveJSONFormat() {
/**
* @see
* org.geoserver.rest.format.ReflectiveJSONFormat#write(java.lang
* .Object, java.io.OutputStream)
*/
@Override
protected void write(Object data, OutputStream output)
throws IOException {
XStream xstream = new SecureXStream(new JettisonMappedXmlDriver());
xstream.setMode(XStream.NO_REFERENCES);
// Aliases
xstream.alias("Attributes", LayerAttributesList.class);
// Converters
xstream.registerConverter(new LayerAttributesListConverter());
xstream.allowTypes(new Class[] { LayerAttributesList.class,
LayerAttributesListConverter.class });
// Marshalling
xstream.toXML(data, new OutputStreamWriter(output, "UTF-8"));
}
};
}
/*
* (non-Javadoc)
*
* @see
* org.geoserver.catalog.rest.CatalogResourceBase#createHTMLFormat(org.restlet
* .data.Request, org.restlet.data.Response)
*/
@Override
protected DataFormat createHTMLFormat(Request request, Response response) {
return new ReflectiveHTMLFormat(LayerAttributesList.class, request, response, this) {
@Override
protected Configuration createConfiguration(Object data, Class clazz) {
final Configuration cfg = super.createConfiguration(data, clazz);
cfg.setClassForTemplateLoading(getClass(), "templates");
cfg.setObjectWrapper(new ObjectToMapWrapper<LayerAttributesList>(LayerAttributesList.class) {
@Override
protected void wrapInternal(Map properties, SimpleHash model, LayerAttributesList object) {
properties.put( "attributes", new MapModel( object.attributes, new ObjectToMapWrapper(LayerAttributesList.class) ) );
}
});
return cfg;
}
};
}
@Override
public boolean allowPost() {
return false;
}
@Override
protected String handleObjectPost(Object object) {
return null;
}
@Override
protected void handleObjectPut(Object object) {
// do nothing, we do not allow post
}
/**
*
* @author Fabiani
*
*/
public class LayerAttributesList {
private String layerName;
private Map<String, String> attributes = new HashMap<String, String>();
public LayerAttributesList(final String layer) {
layerName = layer;
}
public void addAttribute(final String name, final String type) {
attributes.put(name, type);
}
public List<String> getAttributesNames() {
List<String> out = new ArrayList<String>();
for (String key : attributes.keySet()) {
out.add(key);
}
return out;
}
public int getAttributesCount() {
return attributes.size();
}
public String getAttributeName(final int index) {
if (index >= getAttributesCount())
return null;
int cnt = 0;
for (String key : attributes.keySet()) {
if (index == cnt)
return key;
cnt++;
}
return null;
}
public String getAttributeType(final String name) {
return attributes.get(name);
}
/**
* @return the layerName
*/
public String getLayerName() {
return layerName;
}
}
/**
*
* @author Fabiani
*
*/
public class LayerAttributesListConverter implements Converter {
/**
*
* @see
* com.thoughtworks.xstream.converters.ConverterMatcher#canConvert(java
* .lang.Class)
*/
public boolean canConvert(Class clazz) {
return LayerAttributesList.class.isAssignableFrom(clazz);
}
/**
*
* @see
* com.thoughtworks.xstream.converters.Converter#marshal(java.lang.Object
* , com.thoughtworks.xstream.io.HierarchicalStreamWriter,
* com.thoughtworks.xstream.converters.MarshallingContext)
*/
public void marshal(Object value, HierarchicalStreamWriter writer, MarshallingContext context) {
final LayerAttributesList obj = (LayerAttributesList) value;
writer.addAttribute("layer", obj.getLayerName());
for (int k = 0; k < obj.getAttributesCount(); k++) {
writer.startNode("Attribute");
final String name = obj.getAttributeName(k);
final String type = obj.getAttributeType(name);
writer.startNode("name");
writer.setValue(name);
writer.endNode();
writer.startNode("type");
writer.setValue(type);
writer.endNode();
writer.endNode();
}
}
/**
* @see
* com.thoughtworks.xstream.converters.Converter#unmarshal(com.thoughtworks
* .xstream.io.HierarchicalStreamReader,
* com.thoughtworks.xstream.converters.UnmarshallingContext)
*/
public Object unmarshal(HierarchicalStreamReader arg0,
UnmarshallingContext arg1) {
// TODO Auto-generated method stub
return null;
}
}
}