eu.esdihumboldt.hale.io.geoserver.AbstractResource.java Source code

Java tutorial

Introduction

Here is the source code for eu.esdihumboldt.hale.io.geoserver.AbstractResource.java

Source

/*
 * Copyright (c) 2015 Data Harmonisation Panel
 * 
 * All rights reserved. This program and the accompanying materials are made
 * available under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation, either version 3 of the License,
 * or (at your option) any later version.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with this distribution. If not, see <http://www.gnu.org/licenses/>.
 * 
 * Contributors:
 *     Data Harmonisation Panel <http://www.dhpanel.eu>
 */

package eu.esdihumboldt.hale.io.geoserver;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.apache.http.entity.ContentType;

import eu.esdihumboldt.hale.io.geoserver.template.Templates;

/**
 * Base class for classes representing GeoServer resources.
 * 
 * <p>
 * The basic idea is that a resource has a name, a set of attributes (the actual
 * set of attributes depends on the resource type) and a content, which is
 * either read from a template file, or directly from an input stream.
 * </p>
 * 
 * @author Stefano Costa, GeoSolutions
 */
public abstract class AbstractResource implements Resource {

    /**
     * Default resource content type.
     */
    public static final ContentType DEF_CONTENT_TYPE = ContentType.APPLICATION_XML.withCharset("UTF-8");
    /**
     * Zipped archive content type.
     */
    public static final ContentType ZIP_CONTENT_TYPE = ContentType.create("application/zip");

    /**
     * Resource attributes.
     */
    protected Map<String, Object> attributes;
    /**
     * The set of allowed attribute names for this particular resource type.
     */
    protected Set<String> allowedAttributes;

    /**
     * Default constructor.
     * 
     * <p>
     * Should be invoked by subclasses.
     * </p>
     */
    public AbstractResource() {
        this.attributes = new HashMap<String, Object>();
        this.allowedAttributes = new HashSet<String>();
        this.allowedAttributes.addAll(allowedAttributes());
    }

    /**
     * @see eu.esdihumboldt.hale.io.geoserver.Resource#contentType()
     */
    @Override
    public ContentType contentType() {
        return DEF_CONTENT_TYPE;
    }

    /**
     * @see eu.esdihumboldt.hale.io.geoserver.Resource#getAttribute(java.lang.String)
     */
    @Override
    public Object getAttribute(String name) {
        if (name == null || name.isEmpty()) {
            throw new IllegalArgumentException("name must be set");
        }

        return this.attributes.get(name);
    }

    /**
     * @see eu.esdihumboldt.hale.io.geoserver.Resource#setAttribute(java.lang.String,
     *      java.lang.Object)
     */
    @Override
    public void setAttribute(String name, Object value) {
        if (name == null || name.isEmpty()) {
            throw new IllegalArgumentException("name must be set");
        }
        if (!this.allowedAttributes.contains(name)) {
            throw new IllegalArgumentException(String.format("Variable \"%s\" not allowed in this resource", name));
        }

        this.attributes.put(name, value);
    }

    /**
     * @see eu.esdihumboldt.hale.io.geoserver.Resource#write(java.io.OutputStream)
     */
    @Override
    public void write(OutputStream out) throws IOException {

        // unset unspecified variables by setting their value to null
        for (String var : this.allowedAttributes) {
            if (!this.attributes.containsKey(var)) {
                this.attributes.put(var, null);
            }
        }

        InputStream resourceStream = locateResource();
        if (resourceStream != null) {
            BufferedInputStream input = new BufferedInputStream(resourceStream);
            BufferedOutputStream output = new BufferedOutputStream(out);
            try {

                for (int b = input.read(); b >= 0; b = input.read()) {
                    output.write(b);
                }
            } finally {
                try {
                    input.close();
                } catch (IOException e) {
                    // ignore exception on close
                }
                try {
                    output.close();
                } catch (IOException e) {
                    // ignore exception on close
                }
            }
        }

    }

    /**
     * Grabs an input stream from which resource content can be read.
     * 
     * <p>
     * If a non-null template location is returned by the
     * {@link #templateLocation()} method, the returned input stream points to
     * the result of the merging of the template with the resource; otherwise,
     * the result of {@link #resourceStream()} is returned.
     * </p>
     * 
     * @return the input stream from which resource content is read
     * @throws IOException if an I/O error occurs
     */
    protected InputStream locateResource() throws IOException {

        if (templateLocation() != null && !templateLocation().isEmpty()) {
            // resource is loaded from a template and attributes map is used to
            // interpolate variables in it
            return Templates.getInstance().loadTemplate(templateLocation(), this.attributes);
        } else {
            // load resource straight from the classpath
            return resourceStream();
        }

    }

    /**
     * @see eu.esdihumboldt.hale.io.geoserver.Resource#asStream()
     */
    @Override
    public InputStream asStream() throws IOException {
        ByteArrayInputStream bis = new ByteArrayInputStream(asByteArray());

        return bis;
    }

    /**
     * @see eu.esdihumboldt.hale.io.geoserver.Resource#asByteArray()
     */
    @Override
    public byte[] asByteArray() throws IOException {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        try {
            write(bos);

            return bos.toByteArray();
        } finally {
            try {
                bos.close();
            } catch (IOException e) {
                // ignore exception on close
            }
        }
    }

    /**
     * Should be overridden by sublcasses loading resource content from
     * template.
     * 
     * @return the template location (relative to classpath)
     */
    protected String templateLocation() {
        return null;
    }

    /**
     * Should be overridden by subclasses loading resource content from an
     * {@link InputStream}, e.g. file resources.
     * 
     * @return the {@link InputStream} from which resource content should be
     *         read
     */
    protected InputStream resourceStream() {
        return null;
    }

    /**
     * Return the set of allowed attributes.
     * 
     * <p>
     * The method must be implemented by subclasses and is invoked by the
     * default constructor to populate the {@link #allowedAttributes} set.
     * </p>
     * 
     * @return the set of allowed attributes
     */
    protected abstract Set<String> allowedAttributes();
}