All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.geotools.styling.visitor.DuplicatingStyleVisitor Maven / Gradle / Ivy

Go to download

The main module contains the GeoTools public interfaces that are used by other GeoTools modules (and GeoTools applications). Where possible we make use industry standard terms as provided by OGC and ISO standards. The formal GeoTools public api consists of gt-metadata, jts and the gt-main module. The main module contains the default implementations that are available provided to other GeoTools modules using our factory system. Factories are obtained from an appropriate FactoryFinder, giving applications a chance configure the factory used using the Factory Hints facilities. FilterFactory ff = CommonFactoryFinder.getFilterFactory(); Expression expr = ff.add( expression1, expression2 ); If you find yourself using implementation specific classes chances are you doing it wrong: Expression expr = new AddImpl( expression1, expressiom2 );

The newest version!
/*
 *    GeoTools - The Open Source Java GIS Toolkit
 *    http://geotools.org
 *
 *    (C) 2006 - 2015, Open Source Geospatial Foundation (OSGeo)
 *
 *    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.styling.visitor;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Stack;
import java.util.stream.Collectors;
import javax.swing.*;
import org.geotools.factory.CommonFactoryFinder;
import org.geotools.filter.visitor.DuplicatingFilterVisitor;
import org.geotools.styling.AnchorPoint;
import org.geotools.styling.ChannelSelection;
import org.geotools.styling.ColorMap;
import org.geotools.styling.ColorMapEntry;
import org.geotools.styling.ContrastEnhancement;
import org.geotools.styling.DescriptionImpl;
import org.geotools.styling.Displacement;
import org.geotools.styling.Extent;
import org.geotools.styling.ExternalGraphic;
import org.geotools.styling.FeatureTypeConstraint;
import org.geotools.styling.FeatureTypeStyle;
import org.geotools.styling.FeatureTypeStyleImpl;
import org.geotools.styling.Fill;
import org.geotools.styling.Font;
import org.geotools.styling.Graphic;
import org.geotools.styling.Halo;
import org.geotools.styling.ImageOutline;
import org.geotools.styling.LabelPlacement;
import org.geotools.styling.LinePlacement;
import org.geotools.styling.LineSymbolizer;
import org.geotools.styling.Mark;
import org.geotools.styling.NamedLayer;
import org.geotools.styling.OtherText;
import org.geotools.styling.OtherTextImpl;
import org.geotools.styling.OverlapBehavior;
import org.geotools.styling.PointPlacement;
import org.geotools.styling.PointSymbolizer;
import org.geotools.styling.PolygonSymbolizer;
import org.geotools.styling.RasterSymbolizer;
import org.geotools.styling.Rule;
import org.geotools.styling.SelectedChannelType;
import org.geotools.styling.ShadedRelief;
import org.geotools.styling.Stroke;
import org.geotools.styling.Style;
import org.geotools.styling.StyleFactory;
import org.geotools.styling.StyleVisitor;
import org.geotools.styling.StyledLayer;
import org.geotools.styling.StyledLayerDescriptor;
import org.geotools.styling.Symbol;
import org.geotools.styling.Symbolizer;
import org.geotools.styling.TextSymbolizer;
import org.geotools.styling.TextSymbolizer2;
import org.geotools.styling.UserLayer;
import org.opengis.filter.Filter;
import org.opengis.filter.FilterFactory2;
import org.opengis.filter.expression.Expression;
import org.opengis.style.Description;
import org.opengis.style.ExternalMark;
import org.opengis.style.GraphicalSymbol;

/**
 * Creates a deep copy of a Style, this class is *NOT THREAD SAFE*.
 *
 * 

This class makes use of an internal stack to story the copied result, retrieve with a call to * getCopy() after visiting: * *


 * DuplicatingStyleVisitor copyStyle = new DuplicatingStyleVisitor();
 * rule.accepts( copyStyle );
 * Rule rule = (Rule) copyStyle.getCopy();
 * 
* *

This class is often used as a base for an anoymous subclass where a style transformation is * needed (such as removing PointSymbolizers or changing the scale - see RescaleStyleVisitor for an * example). * * @author Jesse Eichar */ public class DuplicatingStyleVisitor implements StyleVisitor { protected final StyleFactory sf; protected final FilterFactory2 ff; protected boolean STRICT; /** We are using aggregation here to contain our DuplicatingFilterVisitor. */ protected final DuplicatingFilterVisitor copyFilter; /** This is our internal stack; used to maintain state as we copy sub elements. */ protected Stack pages = new Stack(); public DuplicatingStyleVisitor() { this(CommonFactoryFinder.getStyleFactory(null)); } public DuplicatingStyleVisitor(StyleFactory styleFactory) { this(styleFactory, CommonFactoryFinder.getFilterFactory2(null)); } public DuplicatingStyleVisitor(StyleFactory styleFactory, FilterFactory2 filterFactory) { this(styleFactory, filterFactory, new DuplicatingFilterVisitor(filterFactory)); } /** * Builds a new duplicating style visitor using a custom {@link DuplicatingStyleVisitor} * * @param styleFactory Creates new style objects during style duplication * @param filterFactory Creates new filters and expressions during style duplication * @param filterCloner Copies filters during style duplication */ public DuplicatingStyleVisitor( StyleFactory styleFactory, FilterFactory2 filterFactory, DuplicatingFilterVisitor filterCloner) { this.copyFilter = filterCloner; this.sf = styleFactory; this.ff = filterFactory; this.STRICT = false; } /** True if we should enforce equality after a copy. */ public void setStrict(boolean strict) { STRICT = strict; } public Object getCopy() { return pages.peek(); } public void visit(StyledLayerDescriptor sld) { StyledLayerDescriptor copy = null; StyledLayer[] layers = sld.getStyledLayers(); StyledLayer[] layersCopy = new StyledLayer[layers.length]; final int length = layers.length; for (int i = 0; i < length; i++) { if (layers[i] instanceof UserLayer) { ((UserLayer) layers[i]).accept(this); layersCopy[i] = (UserLayer) pages.pop(); } else if (layers[i] instanceof NamedLayer) { ((NamedLayer) layers[i]).accept(this); layersCopy[i] = (NamedLayer) pages.pop(); } } copy = sf.createStyledLayerDescriptor(); copy.setAbstract(sld.getAbstract()); copy.setName(sld.getName()); copy.setTitle(sld.getTitle()); copy.setStyledLayers(layersCopy); if (STRICT && !copy.equals(sld)) { throw new IllegalStateException("Was unable to duplicate provided SLD:" + sld); } pages.push(copy); } public void visit(NamedLayer layer) { NamedLayer copy = null; Style[] style = layer.getStyles(); Style[] styleCopy = new Style[style.length]; int length = style.length; for (int i = 0; i < length; i++) { if (style[i] != null) { style[i].accept(this); styleCopy[i] = (Style) pages.pop(); } } FeatureTypeConstraint[] lfc = layer.getLayerFeatureConstraints(); FeatureTypeConstraint[] lfcCopy = new FeatureTypeConstraint[lfc.length]; length = lfc.length; for (int i = 0; i < length; i++) { if (lfc[i] != null) { lfc[i].accept(this); lfcCopy[i] = (FeatureTypeConstraint) pages.pop(); } } copy = sf.createNamedLayer(); copy.setName(layer.getName()); length = styleCopy.length; for (int i = 0; i < length; i++) { copy.addStyle(styleCopy[i]); } copy.setLayerFeatureConstraints(lfcCopy); pages.push(copy); } public void visit(UserLayer layer) { UserLayer copy = null; Style[] style = layer.getUserStyles(); int length = style.length; Style[] styleCopy = new Style[length]; for (int i = 0; i < length; i++) { if (style[i] != null) { style[i].accept(this); styleCopy[i] = (Style) pages.pop(); } } FeatureTypeConstraint[] lfc = layer.getLayerFeatureConstraints(); FeatureTypeConstraint[] lfcCopy = new FeatureTypeConstraint[lfc.length]; length = lfc.length; for (int i = 0; i < length; i++) { if (lfc[i] != null) { lfc[i].accept(this); lfcCopy[i] = (FeatureTypeConstraint) pages.pop(); } } copy = sf.createUserLayer(); copy.setName(layer.getName()); copy.setUserStyles(styleCopy); copy.setLayerFeatureConstraints(lfcCopy); if (STRICT && !copy.equals(layer)) { throw new IllegalStateException("Was unable to duplicate provided UserLayer:" + layer); } pages.push(copy); } public void visit(Style style) { Style copy = null; List ftsCopy = new ArrayList<>(); for (FeatureTypeStyle fts : style.featureTypeStyles()) { if (fts != null) { fts.accept(this); ftsCopy.add((FeatureTypeStyle) pages.pop()); } } copy = sf.createStyle(); copy.getDescription().setAbstract(style.getDescription().getAbstract()); copy.setName(style.getName()); copy.getDescription().setTitle(style.getDescription().getTitle()); copy.featureTypeStyles().addAll(ftsCopy); copy.setBackground(copy(style.getBackground())); if (STRICT && !copy.equals(style)) { throw new IllegalStateException("Was unable to duplicate provided Style:" + style); } pages.push(copy); } public void visit(Rule rule) { Rule copy = null; Filter filterCopy = null; if (rule.getFilter() != null) { Filter filter = rule.getFilter(); filterCopy = copy(filter); } List symsCopy = rule.symbolizers().stream().map(s -> copy(s)).collect(Collectors.toList()); Graphic legendCopy = copy((Graphic) rule.getLegend()); Description descCopy = rule.getDescription(); descCopy = copy(descCopy); copy = sf.createRule(); copy.symbolizers().addAll(symsCopy); copy.setDescription(descCopy); copy.setLegend(legendCopy); copy.setName(rule.getName()); copy.setFilter(filterCopy); copy.setElseFilter(rule.isElseFilter()); copy.setMaxScaleDenominator(rule.getMaxScaleDenominator()); copy.setMinScaleDenominator(rule.getMinScaleDenominator()); if (STRICT && !copy.equals(rule)) { throw new IllegalStateException("Was unable to duplicate provided Rule:" + rule); } pages.push(copy); } public void visit(FeatureTypeStyle fts) { FeatureTypeStyle copy = new FeatureTypeStyleImpl(fts); // copy = new StyleFactoryImpl().createFeatureTypeStyle( // fts.getRules(), // fts.getSemanticTypeIdentifiers(), // fts.featureInstanceIDs(), // fts.getFeatureTypeName(), // fts.getDescription(), // fts.getName()); List rulesCopy = fts.rules() .stream() .filter(r -> r != null) .map( r -> { r.accept(this); return (Rule) pages.pop(); }) .collect(Collectors.toList()); // // copy = sf.createFeatureTypeStyle(); // copy.setName(fts.getName()); // copy.setTitle(fts.getTitle()); // copy.setAbstract(fts.getAbstract()); // copy.setFeatureTypeName(fts.getFeatureTypeName()); copy.rules().clear(); copy.rules().addAll(rulesCopy); // copy.setSemanticTypeIdentifiers((String[]) // fts.getSemanticTypeIdentifiers().clone()); if (fts.getTransformation() != null) { copy.setTransformation(copy(fts.getTransformation())); } if (fts.getOnlineResource() != null) { copy.setOnlineResource(fts.getOnlineResource()); } copy.getOptions().clear(); copy.getOptions().putAll(fts.getOptions()); if (STRICT && !copy.equals(fts)) { throw new IllegalStateException( "Was unable to duplicate provided FeatureTypeStyle:" + fts); } pages.push(copy); } /** * Copy list of expressions. * * @return copy of expressions or null if list was null */ protected List copyExpressions(List expressions) { if (expressions == null) return null; List copy = new ArrayList(expressions.size()); for (Expression expression : expressions) { copy.add(copy(expression)); } return copy; } /** * Null safe expression copy. * *

This method will perform a null check, and save you some lines of code: * *


     * copy.setBackgroundColor( copyExpr( fill.getColor()) );
     * 
* * @return copy of expression or null if expression was null */ protected Expression copy(Expression expression) { if (expression == null) return null; return (Expression) expression.accept(copyFilter, ff); } /** Null safe copy of filter. */ protected Filter copy(Filter filter) { if (filter == null) return null; return (Filter) filter.accept(copyFilter, ff); } /** * Null safe graphic copy * * @return copy of graphic or null if not provided */ protected Graphic copy(Graphic graphic) { if (graphic == null) return null; graphic.accept(this); return (Graphic) pages.pop(); } /** * Null safe fill copy * * @return copy of graphic or null if not provided */ protected Fill copy(Fill fill) { if (fill == null) return null; fill.accept(this); return (Fill) pages.pop(); } /** * Null safe copy of float array. * * @return copy of array or null if not provided */ protected float[] copy(float[] array) { if (array == null) return null; float copy[] = new float[array.length]; System.arraycopy(array, 0, copy, 0, array.length); return copy; } /** * Null safe map copy, used for external graphic custom properties. * * @return copy of map */ @SuppressWarnings("unchecked") protected Map copy(Map customProperties) { if (customProperties == null) return null; return new HashMap(customProperties); } /** * Null safe copy of stroke. * * @return copy of stroke if provided */ protected Stroke copy(Stroke stroke) { if (stroke == null) return null; stroke.accept(this); return (Stroke) pages.pop(); } /** * Null safe copy of shaded relief. * * @return copy of shaded or null if not provided */ protected ShadedRelief copy(ShadedRelief shaded) { if (shaded == null) return null; Expression reliefFactor = copy(shaded.getReliefFactor()); ShadedRelief copy = sf.createShadedRelief(reliefFactor); copy.setBrightnessOnly(shaded.isBrightnessOnly()); return copy; } /** * Null safe copy of description * * @return copy of shaded or null if not provided */ protected Description copy(Description desc) { if (desc == null) return null; DescriptionImpl copy = new DescriptionImpl(desc.getTitle(), desc.getAbstract()); return copy; } protected ExternalGraphic copy(ExternalGraphic externalGraphic) { if (externalGraphic == null) return null; externalGraphic.accept(this); return (ExternalGraphic) pages.pop(); } protected Mark copy(Mark mark) { if (mark == null) return null; mark.accept(this); return (Mark) pages.pop(); } private ExternalMark copy(org.geotools.styling.ExternalMark other) { if (other == null) { return null; } else if (other.getInlineContent() != null) { return sf.externalMark(other.getInlineContent()); } else { return sf.externalMark( other.getOnlineResource(), other.getFormat(), other.getMarkIndex()); } } protected ColorMapEntry copy(ColorMapEntry entry) { if (entry == null) return null; entry.accept(this); return (ColorMapEntry) pages.pop(); } protected Symbolizer copy(Symbolizer symbolizer) { if (symbolizer == null) return null; symbolizer.accept(this); return (Symbolizer) pages.pop(); } protected OverlapBehavior copy(OverlapBehavior ob) { if (ob == null) return null; ob.accept(this); return (OverlapBehavior) pages.pop(); } protected ContrastEnhancement copy(ContrastEnhancement contrast) { if (contrast == null) return null; ContrastEnhancement copy = sf.createContrastEnhancement(); copy.setGammaValue(copy(contrast.getGammaValue())); copy.setMethod(contrast.getMethod()); copy.setOptions(contrast.getOptions()); return copy; } protected ColorMap copy(ColorMap colorMap) { if (colorMap == null) return null; colorMap.accept(this); return (ColorMap) pages.pop(); } protected SelectedChannelType[] copy(SelectedChannelType[] channels) { if (channels == null) return null; SelectedChannelType[] copy = new SelectedChannelType[channels.length]; for (int i = 0; i < channels.length; i++) { copy[i] = copy(channels[i]); } return copy; } protected SelectedChannelType copy(SelectedChannelType selectedChannelType) { if (selectedChannelType == null) return null; ContrastEnhancement enhancement = copy(selectedChannelType.getContrastEnhancement()); Expression name = (Expression) selectedChannelType.getChannelName().accept(copyFilter, null); SelectedChannelType copy = sf.createSelectedChannelType(name, enhancement); return copy; } protected ChannelSelection copy(ChannelSelection channelSelection) { if (channelSelection == null) return null; if (channelSelection.getGrayChannel() != null) { return sf.createChannelSelection( new SelectedChannelType[] {copy(channelSelection.getGrayChannel())}); } else { return sf.createChannelSelection(copy(channelSelection.getRGBChannels())); } } /** * Null safe copy of font list. * *

Right now style visitor does not let us visit fonts! * * @return copy of provided fonts */ protected List copyFonts(List fonts) { if (fonts == null) { return null; } List copy = new ArrayList(fonts.size()); for (Font font : fonts) { copy.add(copy(font)); } return copy; } /** Null safe copy of a single font */ protected Font copy(Font font) { if (font == null) return font; List fontFamily = copyExpressions(font.getFamily()); Expression fontStyle = copy(font.getStyle()); Expression fontWeight = copy(font.getWeight()); Expression fontSize = copy(font.getSize()); Font copy = sf.font(fontFamily, fontStyle, fontWeight, fontSize); return copy; } /** * Null safe copy of halo. * * @return copy of halo if provided */ protected Halo copy(Halo halo) { if (halo == null) return null; halo.accept(this); return (Halo) pages.pop(); } /** * Null safe copy of displacement. * * @return copy of displacement if provided */ protected Displacement copy(Displacement displacement) { if (displacement == null) return null; displacement.accept(this); return (Displacement) pages.pop(); } protected LabelPlacement copy(LabelPlacement placement) { if (placement == null) return null; placement.accept(this); return (LabelPlacement) pages.pop(); } protected Symbol copy(Symbol symbol) { if (symbol == null) return null; symbol.accept(this); return (Symbol) pages.pop(); } /** * Null safe copy of anchor point. * * @return copy of anchor point if provided */ protected AnchorPoint copy(AnchorPoint anchorPoint) { if (anchorPoint == null) return null; anchorPoint.accept(this); return (AnchorPoint) pages.pop(); } public void visit(Fill fill) { Fill copy = sf.getDefaultFill(); copy.setColor(copy(fill.getColor())); copy.setGraphicFill(copy(fill.getGraphicFill())); copy.setOpacity(copy(fill.getOpacity())); if (STRICT && !copy.equals(fill)) { throw new IllegalStateException("Was unable to duplicate provided Fill:" + fill); } pages.push(copy); } public void visit(Stroke stroke) { Stroke copy = sf.getDefaultStroke(); copy.setColor(copy(stroke.getColor())); copy.setDashArray(copyExpressions(stroke.dashArray())); copy.setDashOffset(copy(stroke.getDashOffset())); copy.setGraphicFill(copy(stroke.getGraphicFill())); copy.setGraphicStroke(copy(stroke.getGraphicStroke())); copy.setLineCap(copy(stroke.getLineCap())); copy.setLineJoin(copy(stroke.getLineJoin())); copy.setOpacity(copy(stroke.getOpacity())); copy.setWidth(copy(stroke.getWidth())); if (STRICT && !copy.equals(stroke)) { throw new IllegalStateException("Was unable to duplicate provided Stroke:" + stroke); } pages.push(copy); } public void visit(Symbolizer sym) { if (sym instanceof RasterSymbolizer) { visit((RasterSymbolizer) sym); } else if (sym instanceof LineSymbolizer) { visit((LineSymbolizer) sym); } else if (sym instanceof PolygonSymbolizer) { visit((PolygonSymbolizer) sym); } else if (sym instanceof PointSymbolizer) { visit((PointSymbolizer) sym); } else if (sym instanceof TextSymbolizer) { visit((TextSymbolizer) sym); } else { throw new RuntimeException("visit(Symbolizer) unsupported"); } } public void visit(PointSymbolizer ps) { PointSymbolizer copy = sf.getDefaultPointSymbolizer(); copy.setGeometry(copy(ps.getGeometry())); copy.setUnitOfMeasure(ps.getUnitOfMeasure()); copy.setGraphic(copy(ps.getGraphic())); copy.getOptions().putAll(ps.getOptions()); if (STRICT) { if (!copy.equals(ps)) { throw new IllegalStateException("Was unable to duplicate provided Graphic:" + ps); } } pages.push(copy); } public void visit(LineSymbolizer line) { LineSymbolizer copy = sf.getDefaultLineSymbolizer(); copy.setGeometry(copy(line.getGeometry())); copy.setUnitOfMeasure(line.getUnitOfMeasure()); copy.setStroke(copy(line.getStroke())); copy.getOptions().putAll(line.getOptions()); copy.setPerpendicularOffset(line.getPerpendicularOffset()); if (STRICT && !copy.equals(line)) { throw new IllegalStateException( "Was unable to duplicate provided LineSymbolizer:" + line); } pages.push(copy); } public void visit(PolygonSymbolizer poly) { PolygonSymbolizer copy = sf.createPolygonSymbolizer(); copy.setFill(copy(poly.getFill())); copy.setGeometry(copy(poly.getGeometry())); copy.setUnitOfMeasure(poly.getUnitOfMeasure()); copy.setStroke(copy(poly.getStroke())); copy.getOptions().putAll(poly.getOptions()); if (STRICT && !copy.equals(poly)) { throw new IllegalStateException( "Was unable to duplicate provided PolygonSymbolizer:" + poly); } pages.push(copy); } public void visit(TextSymbolizer text) { TextSymbolizer copy = sf.createTextSymbolizer(); copy.setFill(copy(text.getFill())); copy.fonts().clear(); copy.fonts().addAll(copyFonts(text.fonts())); copy.setGeometry(copy(text.getGeometry())); copy.setUnitOfMeasure(text.getUnitOfMeasure()); copy.setHalo(copy(text.getHalo())); copy.setLabel(copy(text.getLabel())); copy.setLabelPlacement(copy(text.getLabelPlacement())); copy.setPriority(copy(text.getPriority())); copy.getOptions().putAll(text.getOptions()); if (text instanceof TextSymbolizer2) { TextSymbolizer2 text2 = (TextSymbolizer2) text; TextSymbolizer2 copy2 = (TextSymbolizer2) copy; copy2.setGraphic(copy(text2.getGraphic())); copy2.setSnippet(copy(text2.getSnippet())); copy2.setFeatureDescription(copy(text2.getFeatureDescription())); copy2.setOtherText(copy(text2.getOtherText())); } if (STRICT && !copy.equals(text)) { throw new IllegalStateException( "Was unable to duplicate provided TextSymbolizer:" + text); } pages.push(copy); } public void visit(RasterSymbolizer raster) { RasterSymbolizer copy = sf.createRasterSymbolizer(); copy.setChannelSelection(copy(raster.getChannelSelection())); copy.setColorMap(copy(raster.getColorMap())); copy.setContrastEnhancement(copy(raster.getContrastEnhancement())); copy.setGeometry(copy(raster.getGeometry())); copy.setUnitOfMeasure(raster.getUnitOfMeasure()); copy.setImageOutline(copy(raster.getImageOutline())); copy.setOpacity(copy(raster.getOpacity())); copy.setOverlapBehavior(raster.getOverlapBehavior()); copy.setShadedRelief(copy(raster.getShadedRelief())); if (STRICT && !copy.equals(raster)) { throw new IllegalStateException("Was unable to duplicate provided raster:" + raster); } pages.push(copy); } public void visit(Graphic gr) { Graphic copy = null; Displacement displacementCopy = copy(gr.getDisplacement()); List symbolsCopy = copy(gr.graphicalSymbols()); Expression opacityCopy = copy(gr.getOpacity()); Expression rotationCopy = copy(gr.getRotation()); Expression sizeCopy = copy(gr.getSize()); AnchorPoint anchorCopy = copy(gr.getAnchorPoint()); copy = sf.createDefaultGraphic(); copy.setDisplacement(displacementCopy); copy.graphicalSymbols().clear(); copy.graphicalSymbols().addAll(symbolsCopy); copy.setOpacity(opacityCopy); copy.setRotation(rotationCopy); copy.setSize(sizeCopy); copy.setAnchorPoint(anchorCopy); if (STRICT) { if (!copy.equals(gr)) { throw new IllegalStateException("Was unable to duplicate provided Graphic:" + gr); } } pages.push(copy); } private List copy(List symbols) { List copy = new ArrayList<>(symbols.size()); for (GraphicalSymbol symbol : symbols) { if (symbol instanceof Symbol) { copy.add(copy((Symbol) symbol)); } else { throw new RuntimeException("Don't know how to copy " + symbol); } } return copy; } public void visit(Mark mark) { Mark copy = null; copy = sf.createMark(); copy.setFill(copy(mark.getFill())); copy.setStroke(copy(mark.getStroke())); copy.setWellKnownName(copy(mark.getWellKnownName())); copy.setExternalMark(copy(mark.getExternalMark())); if (STRICT && !copy.equals(mark)) { throw new IllegalStateException("Was unable to duplicate provided Mark:" + mark); } pages.push(copy); } public void visit(ExternalGraphic exgr) { URL uri = null; try { uri = exgr.getLocation(); } catch (MalformedURLException huh) { } String format = exgr.getFormat(); Icon inlineContent = exgr.getInlineContent(); ExternalGraphic copy; if (inlineContent != null) { copy = sf.createExternalGraphic(inlineContent, format); } else { copy = sf.createExternalGraphic(uri, format); } copy.setCustomProperties(copy(exgr.getCustomProperties())); if (STRICT && !copy.equals(exgr)) { throw new IllegalStateException( "Was unable to duplicate provided ExternalGraphic:" + exgr); } pages.push(copy); } public void visit(PointPlacement pp) { PointPlacement copy = sf.getDefaultPointPlacement(); copy.setAnchorPoint(copy(pp.getAnchorPoint())); copy.setDisplacement(copy(pp.getDisplacement())); copy.setRotation(copy(pp.getRotation())); if (STRICT && !copy.equals(pp)) { throw new IllegalStateException( "Was unable to duplicate provided PointPlacement:" + pp); } pages.push(copy); } public void visit(AnchorPoint ap) { Expression x = copy(ap.getAnchorPointX()); Expression y = copy(ap.getAnchorPointY()); AnchorPoint copy = sf.createAnchorPoint(x, y); if (STRICT && !copy.equals(ap)) { throw new IllegalStateException("Was unable to duplicate provided AnchorPoint:" + ap); } pages.push(copy); } public void visit(Displacement dis) { Expression x = copy(dis.getDisplacementX()); Expression y = copy(dis.getDisplacementY()); Displacement copy = sf.createDisplacement(x, y); if (STRICT && !copy.equals(dis)) { throw new IllegalStateException("Was unable to duplicate provided Displacement:" + dis); } pages.push(copy); } public void visit(LinePlacement lp) { Expression offset = copy(lp.getPerpendicularOffset()); LinePlacement copy = sf.createLinePlacement(offset); copy.setAligned(lp.isAligned()); copy.setGap(copy(lp.getGap())); copy.setGeneralized(lp.isGeneralizeLine()); copy.setInitialGap(copy(lp.getInitialGap())); copy.setRepeated(lp.isRepeated()); if (STRICT && !copy.equals(lp)) { throw new IllegalStateException("Was unable to duplicate provided LinePlacement:" + lp); } pages.push(copy); } public void visit(Halo halo) { Fill fill = copy(halo.getFill()); Expression radius = copy(halo.getRadius()); Halo copy = sf.createHalo(fill, radius); if (STRICT && !copy.equals(halo)) { throw new IllegalStateException("Was unable to duplicate provided raster:" + halo); } pages.push(copy); } public void visit(FeatureTypeConstraint ftc) { String typeName = ftc.getFeatureTypeName(); Filter filter = copy(ftc.getFilter()); Extent[] extents = copy(ftc.getExtents()); FeatureTypeConstraint copy = sf.createFeatureTypeConstraint(typeName, filter, extents); if (STRICT && !copy.equals(ftc)) { throw new IllegalStateException( "Was unable to duplicate provided FeatureTypeConstraint:" + ftc); } pages.push(copy); } protected Extent[] copy(Extent[] extents) { if (extents == null) { return null; } Extent[] copy = new Extent[extents.length]; for (int i = 0; i < extents.length; i++) { copy[i] = copy(extents[i]); } return copy; } protected Extent copy(Extent extent) { String name = extent.getName(); String value = extent.getValue(); Extent copy = sf.createExtent(name, value); return copy; } private OtherText copy(OtherText otherText) { if (otherText == null) return null; // TODO: add methods to the factory to create OtherText instances // sf.createOtherText(); OtherTextImpl copy = new OtherTextImpl(); copy.setTarget(otherText.getTarget()); copy.setText(copy(otherText.getText())); return copy; } public void visit(ColorMap colorMap) { ColorMap copy = sf.createColorMap(); copy.setType(colorMap.getType()); copy.setExtendedColors(colorMap.getExtendedColors()); ColorMapEntry[] entries = colorMap.getColorMapEntries(); if (entries != null) { for (int i = 0; i < entries.length; i++) { ColorMapEntry entry = entries[i]; copy.addColorMapEntry(copy(entry)); } } if (STRICT && !copy.equals(colorMap)) { throw new IllegalStateException( "Was unable to duplicate provided ColorMap:" + colorMap); } pages.push(copy); } public void visit(ColorMapEntry colorMapEntry) { ColorMapEntry copy = sf.createColorMapEntry(); copy.setColor(copy(colorMapEntry.getColor())); copy.setLabel(colorMapEntry.getLabel()); copy.setOpacity(copy(colorMapEntry.getOpacity())); copy.setQuantity(copy(colorMapEntry.getQuantity())); if (STRICT && !copy.equals(colorMapEntry)) { throw new IllegalStateException( "Was unable to duplicate provided ColorMapEntry:" + colorMapEntry); } pages.push(copy); } public void visit(ContrastEnhancement contrastEnhancement) { final ContrastEnhancement copy = sf.createContrastEnhancement(); copy.setMethod(contrastEnhancement.getMethod()); copy.setOptions(contrastEnhancement.getOptions()); copy.setGammaValue(contrastEnhancement.getGammaValue()); if (STRICT && !copy.equals(contrastEnhancement)) { throw new IllegalStateException( "Was unable to duplicate provided contrastEnhancement:" + contrastEnhancement); } pages.push(copy); } public void visit(ImageOutline outline) { // copy the symbolizer final Symbolizer symb = outline.getSymbolizer(); final Symbolizer copySymb = copy(symb); final ImageOutline copy = sf.createImageOutline(copySymb); copy.setSymbolizer(copySymb); if (STRICT && !copy.equals(outline)) { throw new IllegalStateException( "Was unable to duplicate provided ImageOutline:" + outline); } pages.push(copy); } public void visit(ChannelSelection cs) { ChannelSelection copy = copy(cs); pages.push(copy); } public void visit(OverlapBehavior ob) { final String behavior = (String) ob.getValue(); if (behavior.equalsIgnoreCase(OverlapBehavior.AVERAGE_RESCTRICTION)) { pages.push(OverlapBehavior.AVERAGE_RESCTRICTION); } else if (behavior.equalsIgnoreCase(OverlapBehavior.EARLIEST_ON_TOP_RESCTRICTION)) { pages.push(OverlapBehavior.EARLIEST_ON_TOP_RESCTRICTION); } else if (behavior.equalsIgnoreCase(OverlapBehavior.LATEST_ON_TOP_RESCTRICTION)) { pages.push(OverlapBehavior.LATEST_ON_TOP_RESCTRICTION); } else if (behavior.equalsIgnoreCase(OverlapBehavior.RANDOM_RESCTRICTION)) { pages.push(OverlapBehavior.RANDOM_RESCTRICTION); } else { throw new IllegalStateException( "Was unable to duplicate provided OverlapBehavior:" + ob); } } public void visit(SelectedChannelType sct) { final SelectedChannelType copy = sf.createSelectedChannelType( sct.getChannelName(), copy(sct.getContrastEnhancement())); if (STRICT && !copy.equals(sct)) { throw new IllegalStateException( "Was unable to duplicate provided SelectedChannelType:" + sct); } pages.push(copy); } public void visit(ShadedRelief sr) { final ShadedRelief copy = sf.createShadedRelief(copy(sr.getReliefFactor())); copy.setBrightnessOnly(sr.isBrightnessOnly()); if (STRICT && !copy.equals(sr)) { throw new IllegalStateException("Was unable to duplicate provided ShadedRelief:" + sr); } pages.push(copy); } }