/* (c) 2014 Open Source Geospatial Foundation - all rights reserved * (c) 2001 - 2014 OpenPlans * This code is licensed under the GPL 2.0 license, available at the root * application directory. */ package org.geoserver.catalog; import java.awt.Color; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.Reader; import java.io.StringReader; import java.net.URL; import java.util.Arrays; import java.util.List; import org.geoserver.platform.resource.Resource; import org.geotools.factory.CommonFactoryFinder; import org.geotools.styling.ResourceLocator; import org.geotools.styling.StyleFactory; import org.geotools.styling.StyledLayerDescriptor; import org.geotools.util.Version; import org.xml.sax.EntityResolver; /** * Extension point for handling a style of a particular language/version. * <p> * </p> * @author Justin Deoliveira, Boundless * */ public abstract class StyleHandler { protected static StyleFactory styleFactory = CommonFactoryFinder.getStyleFactory(null); String name; String format; protected StyleHandler(String name, String format) { this.name = name; this.format = format; } /** * Human readable name of the handler. */ public String getName() { return name; } /** * Format identifier for the handler. */ public String getFormat() { return format; } /** * Supported format versions. */ public List<Version> getVersions() { return Arrays.asList(new Version("1.0.0")); } /** * Returns the file extension for the format. * <p> * Defaults to {@link #getFormat()}. * </p> */ public String getFileExtension() { return getFormat(); } /** * Returns the identifier for the mode used for syntax highlighting * in the code mirror editor. * <p> * Defaults to {@link #getFormat()} * </p> */ public String getCodeMirrorEditMode() { return getFormat(); } /** * Generates a style from a template using the provided substitutions. * * @param type the template type, see {@link org.geoserver.catalog.StyleType}. * @param color java.aw.Color to use during substitution * @param colorName Human readable color name, for use generating comments * @param layerName Layer name, for use generating comments * * @return The text content of the style template after performing substitutions */ public String getStyle(StyleType type, Color color, String colorName, String layerName) { throw new UnsupportedOperationException(); } /** * Parses a style resource. * * @param input The style input, see {@link #toReader(Object)} for accepted inputs. * @param version Optional version of the format, maybe <code>null</code> * @param resourceLocator Optional locator for resources (icons, etc...) referenced by the style, may be * <code>null</code>. * @param entityResolver Optional entity resolver for XML based formats, may be <code>null</code>. * */ public abstract StyledLayerDescriptor parse(Object input, Version version, ResourceLocator resourceLocator, EntityResolver entityResolver) throws IOException; /** * Encodes a style. * <p> * Handlers that don't support encoding should throw {@link java.lang.UnsupportedOperationException}. * </p> * @param sld The style to encode. * @param version The version of the format to use to encode the style, may be <code>null</code>. * @param pretty Flag controlling whether or not the style should be encoded in pretty form. * @param output The stream to write the encoded style to. */ public abstract void encode(StyledLayerDescriptor sld, Version version, boolean pretty, OutputStream output) throws IOException; /** * Validates a style resource. * <p> * For handlers that don't support an extended form of validation (like against an XML schema) this implementation * should at a minimum attempt to parse the input and return any parsing errors. * </p> * @param input The style input, see {@link #toReader(Object)} for accepted inputs. * @param version The version of the format to use to validate the style, may be <code>null</code>. * * @return Any validation errors, or empty list if the style is valid. */ public abstract List<Exception> validate(Object input, Version version, EntityResolver entityResolver) throws IOException; /** * Returns the format mime type for the specified version. * */ public abstract String mimeType(Version version); /** * Returns the format version for the specified mime type. * <p> * This method should only be overriden by formats that support multiple versions. The default * implementation just returns 1.0.0. * </p> */ public Version versionForMimeType(String mimeType) { return new Version("1.0.0"); } /** * Determines the version of the format/language of the specified style resource. * <p> * This method should only be overriden by formats that support multiple versions. The default * implementation just returns 1.0.0. * </p> * @param input The style input, see {@link #toReader(Object)} for accepted inputs. */ public Version version(Object input) throws IOException { return new Version("1.0.0"); } /** * Turns input into a Reader. * * @param input A {@link Reader}, {@link java.io.InputStream}, {@link File}, or {@link Resource}. */ protected Reader toReader(Object input) throws IOException { if (input instanceof Reader) { return (Reader) input; } if (input instanceof InputStream) { return new InputStreamReader((InputStream)input); } if (input instanceof String) { return new StringReader((String)input); } if (input instanceof URL) { return new InputStreamReader(((URL) input).openStream()); } if (input instanceof File) { return new FileReader((File)input); } if (input instanceof Resource) { return toReader(((Resource)input).in()); } throw new IllegalArgumentException("Unable to turn " + input + " into reader"); } }