Package org.geoserver.wfs.xslt.rest

Source Code of org.geoserver.wfs.xslt.rest.TransformResource$FeatureTypeLinkConverter

/* (c) 2014 Open Source Geospatial Foundation - all rights reserved
* (c) 2001 - 2013 OpenPlans
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
*/
package org.geoserver.wfs.xslt.rest;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.List;

import org.apache.commons.io.IOUtils;
import org.geoserver.catalog.Catalog;
import org.geoserver.catalog.FeatureTypeInfo;
import org.geoserver.catalog.StoreInfo;
import org.geoserver.catalog.WorkspaceInfo;
import org.geoserver.catalog.impl.FeatureTypeInfoImpl;
import org.geoserver.catalog.impl.ModificationProxy;
import org.geoserver.catalog.rest.CatalogResourceBase;
import org.geoserver.rest.RestletException;
import org.geoserver.rest.format.DataFormat;
import org.geoserver.rest.format.MediaTypes;
import org.geoserver.rest.util.RESTUtils;
import org.geoserver.wfs.xslt.config.TransformInfo;
import org.geoserver.wfs.xslt.config.TransformRepository;
import org.restlet.Context;
import org.restlet.data.MediaType;
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.converters.reflection.ReflectionConverter;
import com.thoughtworks.xstream.converters.reflection.ReflectionProvider;
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import com.thoughtworks.xstream.mapper.Mapper;

/**
* The resource representing the transformation itself
*
* @author Andrea Aime - GeoSolutions
*/
public class TransformResource extends CatalogResourceBase {

    /**
     * media type for XSLT
     */
    public static final MediaType MEDIATYPE_XSLT = new MediaType("application/xslt+xml");
    static {
        MediaTypes.registerExtension("xslt", MEDIATYPE_XSLT);
    }

    private TransformRepository repository;

    public TransformResource(Context context, Request request, Response response,
            TransformRepository repository, Catalog catalog) {
        super(context, request, response, TransformInfo.class, catalog);
        this.repository = repository;
    }

    @Override
    protected List<DataFormat> createSupportedFormats(Request request, Response response) {
        List<DataFormat> formats = super.createSupportedFormats(request, response);
        formats.add(new XSLTDataFormat(MEDIATYPE_XSLT));
        return formats;
    }
   
    @Override
    protected DataFormat createHTMLFormat(Request request, Response response) {
        return new TransformHTMLDataFormat(clazz, request, response, this);
    }

    @Override
    protected Object handleObjectGet() throws Exception {
        String transform = RESTUtils.getAttribute(getRequest(), "transform");
        if (transform == null) {
            throw new RestletException("Failed to locate transformation " + transform,
                    Status.CLIENT_ERROR_NOT_FOUND);
        }

        TransformInfo info = repository.getTransformInfo(transform);
        DataFormat format = getFormatGet();
        if (format instanceof XSLTDataFormat) {
            return repository.getTransformSheet(info);
        } else {
            return info;
        }
    }

    @Override
    public boolean allowDelete() {
        return true;
    }

    @Override
    protected void handleObjectDelete() throws Exception {
        String transform = RESTUtils.getAttribute(getRequest(), "transform");
        TransformInfo info = repository.getTransformInfo(transform);
        repository.removeTransformInfo(info);
    }

    @Override
    public boolean allowPut() {
        return true;
    }

    @Override
    protected void handleObjectPut(Object object) throws Exception {
        String transform = RESTUtils.getAttribute(getRequest(), "transform");
        if (object instanceof TransformInfo) {
            TransformInfo info = (TransformInfo) object;
            // force the right name
            info.setName(transform);
            repository.putTransformInfo(info);
        } else {
            TransformInfo info = repository.getTransformInfo(transform);
            repository.putTransformSheet(info, IOUtils.toInputStream((String) object));
        }
    }

    @Override
    public boolean allowPost() {
        return RESTUtils.getAttribute(getRequest(), "transform") == null;
    }

    @Override
    protected String handleObjectPost(Object object) throws Exception {
        String transform = getQueryStringValue("name");
        String sourceFormat = getQueryStringValue("sourceFormat");
        String outputFormat = getQueryStringValue("outputFormat");
        String outputMimeType = getQueryStringValue("outputMimeType");
        String fileExtension = getQueryStringValue("fileExtension");

        TransformInfo info;
        if (object instanceof TransformInfo) {
            info = (TransformInfo) object;
            if(transform != null) {
                info.setName(transform);
            }
            validate(info);
            repository.putTransformInfo(info);
            return info.getName();
        } else {
            // the format has turned the user provided stream into a string for validation purposes
            String xslt = (String) object;
            info = repository.getTransformInfo(transform);
            if (info == null) {
                info = new TransformInfo();
                info.setName(transform);
                info.setSourceFormat(sourceFormat);
                info.setOutputFormat(outputFormat);
                info.setOutputMimeType(outputMimeType);
                info.setFileExtension(fileExtension);
                info.setXslt(transform + ".xslt");
                validate(info);
                repository.putTransformInfo(info);
            }

            repository.putTransformSheet(info, new ByteArrayInputStream(xslt.getBytes()));
        }

        return info.getName();
    }

    private void validate(TransformInfo info) {
        if (info.getSourceFormat() == null) {
            throw new RestletException("The transformation must have a source format",
                    Status.CLIENT_ERROR_BAD_REQUEST);
        }
        if (info.getOutputFormat() == null) {
            throw new RestletException("The transformation must have an output format",
                    Status.CLIENT_ERROR_BAD_REQUEST);
        }
    }

    @Override
    protected void configureXStream(XStream xs) {
        super.configureXStream(xs);
        xs.alias("transform", TransformInfo.class);
        xs.registerConverter(new TransformConverter(xs.getMapper(), xs.getReflectionProvider()));
        xs.registerLocalConverter(TransformInfo.class, "featureType",
                new FeatureTypeLinkConverter());
        xs.addDefaultImplementation(FeatureTypeInfoImpl.class, FeatureTypeInfo.class);
    }

    private class TransformConverter extends ReflectionConverter {

        public TransformConverter(Mapper mapper, ReflectionProvider reflectionProvider) {
            super(mapper, reflectionProvider);
        }

        @Override
        public boolean canConvert(Class type) {
            return TransformInfo.class.isAssignableFrom(type);
        }

        @Override
        public void marshal(Object source, HierarchicalStreamWriter writer,
                MarshallingContext context) {
            TransformInfo original = (TransformInfo) source;
            TransformInfo resolved = new TransformInfo(original);
            FeatureTypeInfo ft = resolved.getFeatureType();
            if (ft != null) {
                resolved.setFeatureType((FeatureTypeInfo) ModificationProxy.unwrap(ft));
            }
            super.marshal(resolved, writer, context);
        }

    }

    private class FeatureTypeLinkConverter implements Converter {

        @Override
        public boolean canConvert(Class type) {
            return true;
        }

        @Override
        public void marshal(Object source, HierarchicalStreamWriter writer,
                MarshallingContext context) {
            FeatureTypeInfo ft = (FeatureTypeInfo) source;
            writer.startNode("name");
            writer.setValue(ft.prefixedName());
            writer.endNode();
            StoreInfo store = ft.getStore();
            WorkspaceInfo ws = store.getWorkspace();
            encodeLink(
                    "/workspaces/" + encode(ws.getName()) + "/datastores/"
                            + encode(store.getName()) + "/featuretypes/" + encode(ft.getName()),
                    writer, getFormatGet());
        }

        @Override
        public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
            String ref = null;
            if (reader.hasMoreChildren()) {
                while (reader.hasMoreChildren()) {
                    reader.moveDown();
                    ref = reader.getValue();
                    reader.moveUp();
                }
            } else {
                ref = reader.getValue();
            }

            FeatureTypeInfo result = catalog.getFeatureType(ref);
            if (result == null) {
                result = catalog.getFeatureTypeByName(ref);
            }

            return result;
        }

    }

}
TOP

Related Classes of org.geoserver.wfs.xslt.rest.TransformResource$FeatureTypeLinkConverter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.