/* * GeoTools - The Open Source Java GIS Toolkit * http://geotools.org * * (C) 2016 Open Source Geospatial Foundation (OSGeo) * (C) 2014-2016 Boundless Spatial * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ package org.geotools.ysld; import org.geotools.ysld.encode.YsldEncoder; import org.geotools.ysld.parse.YsldParser; import org.geotools.ysld.parse.ZoomContextFinder; import org.geotools.ysld.transform.sld.SldTransformer; import org.geotools.factory.CommonFactoryFinder; import org.geotools.styling.ResourceLocator; import org.geotools.styling.SLDParser; import org.geotools.styling.StyledLayerDescriptor; import org.geotools.ysld.validate.YsldValidator; import org.yaml.snakeyaml.error.MarkedYAMLException; import javax.annotation.Nullable; import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamReader; import java.io.*; import java.util.Collections; import java.util.List; /** * Parses, encodes, and transforms Ysld. */ public class Ysld { public static String OPTION_PREFIX = "x-"; /** * Creates a {@link java.io.Reader} from an input object. * <p> * Handles objects of the following type. * <ul> * <li>{@link java.io.Reader}</li> * <li>{@link java.io.InputStream}</li> * <li>{@link java.io.File}</li> * <li>{@link java.lang.String}</li> * </ul> * </p> * * @param input The input object. * * @throws java.lang.IllegalArgumentException If the input object can not be converted. */ static YsldInput reader(Object input) throws IOException { if (input instanceof Reader) { return new YsldInput((Reader) input); } else if (input instanceof InputStream) { return new YsldInput(new BufferedReader(new InputStreamReader((InputStream) input))); } else if (input instanceof File) { return new YsldInput(new BufferedReader(new FileReader((File) input))); } else if (input instanceof String) { return new YsldInput(new StringReader((String) input)); } else { throw new IllegalArgumentException("Unable to turn " + input + " into reader"); } } /** * Creates a {@link java.io.Writer} from an output object. * <p> * Handles objects of the following type. * <ul> * <li>{@link java.io.Reader}</li> * <li>{@link java.io.InputStream}</li> * <li>{@link java.io.File}</li> * </ul> * </p> * * @param output The output object. * * @throws java.lang.IllegalArgumentException If the output object can not be converted. */ static Writer writer(Object output) throws IOException { if (output instanceof Writer) { return (Writer) output; } else if (output instanceof OutputStream) { return new BufferedWriter(new OutputStreamWriter((OutputStream) output)); } else if (output instanceof File) { return new BufferedWriter(new FileWriter((File) output)); } else { throw new IllegalArgumentException("Unable to turn " + output + " into writer"); } } /** * Creates an XML reader from an input object. * * @param input THe input object, see {@link #reader(Object)} for details. */ public static XMLStreamReader xmlReader(Object input) throws IOException { YsldInput in = reader(input); try { XMLInputFactory xmlFactory = XMLInputFactory.newFactory(); try { return xmlFactory.createXMLStreamReader(in.reader); } catch (XMLStreamException e) { throw new IOException(e); } } finally { in.close(); } } /** * Parses a Ysld stream into GeoTools style objects. * * @param ysld The Ysld content, anything accepted by {@link #reader(Object)}. * @param locator Resource locator for resolving relative URIs. * * @return The GeoTools SLD object. */ public static StyledLayerDescriptor parse(Object ysld, @Nullable List<ZoomContextFinder> zCtxtFinders, @Nullable ResourceLocator locator) throws IOException { return parse(ysld, zCtxtFinders, locator, new UomMapper()); } /** * Parses a Ysld stream into GeoTools style objects. * * @param ysld The Ysld content, anything accepted by {@link #reader(Object)}. * @param locator Resource locator for resolving relative URIs. * * @return The GeoTools SLD object. */ public static StyledLayerDescriptor parse(Object ysld, @Nullable List<ZoomContextFinder> zCtxtFinders, @Nullable ResourceLocator locator, @Nullable UomMapper uomMapper) throws IOException { YsldInput in = reader(ysld); try { YsldParser parser = new YsldParser(in.reader); if (zCtxtFinders != null) { parser.setZoomContextFinders(zCtxtFinders); } if (locator != null) { parser.setResourceLocator(locator); } if (uomMapper != null) { parser.setUomMapper(uomMapper); } return parser.parse(); } finally { in.close(); } } /** * Parses a Ysld stream into GeoTools style objects. * * @param ysld The Ysld content, anything accepted by {@link #reader(Object)}. * * @return The GeoTools SLD object. */ public static StyledLayerDescriptor parse(Object ysld) throws IOException { return parse(ysld, (List<ZoomContextFinder>) null, (ResourceLocator) null, new UomMapper()); } /** * Encodes a GeoTools style object as Ysld. * * @param sld The sld to encode. * @param output The output object, anything accepted by {@link #writer(Object)} */ public static void encode(StyledLayerDescriptor sld, Object output) throws IOException { encode(sld, output, new UomMapper()); } /** * Encodes a GeoTools style object as Ysld. * * @param sld The sld to encode. * @param output The output object, anything accepted by {@link #writer(Object)} */ public static void encode(StyledLayerDescriptor sld, Object output, UomMapper uomMapper) throws IOException { YsldEncoder e = new YsldEncoder(writer(output), uomMapper); e.encode(sld); } /** * Transforms an SLD stream to Ysld. * * @param sld SLD xml reader. * @param ysld Ysld writer. * */ public static void transform(XMLStreamReader sld, Writer ysld) throws IOException { throw new UnsupportedOperationException();/* * SldTransformer tx = new SldTransformer(sld, ysld); try { tx.transform(); } * catch(XMLStreamException e) { throw new IOException(e); } */ } /** * Transforms an SLD stream to Ysld. * * @param sld SLD xml reader. * @param ysld Ysld writer. * */ public static void transform(InputStream sld, Writer ysld) throws IOException { SLDParser parser = new SLDParser(CommonFactoryFinder.getStyleFactory(), sld); StyledLayerDescriptor style = parser.parseSLD(); Ysld.encode(style, ysld); } /** * Validates a Ysld stream. * * @param ysld The Ysld. * * @return List of marked exceptions corresponding to validation errors. */ public static List<MarkedYAMLException> validate(Object ysld) throws IOException { return validate(ysld, Collections.<ZoomContextFinder> emptyList(), new UomMapper()); } /** * Validates a Ysld stream. * * @param ysld The Ysld. * @param zContextFinders additional zoom context finders in order of priority. * * @return List of marked exceptions corresponding to validation errors. */ public static List<MarkedYAMLException> validate(Object ysld, List<ZoomContextFinder> zContextFinders, UomMapper uomMapper) throws IOException { YsldInput in = reader(ysld); try { YsldValidator validator = new YsldValidator(); validator.setZCtxtFinders(zContextFinders); return validator.validate(in.reader); } finally { in.close(); ; } } static class YsldInput { Reader reader; YsldInput(Reader reader) { this.reader = reader; } public void close() throws IOException { reader.close(); } } }