001    //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/branches/2.2_testing/src/org/deegree/graphics/sld/StyleUtils.java $
002    /*----------------    FILE HEADER  ------------------------------------------
003    
004     This file is part of deegree.
005     Copyright (C) 2001-2008 by:
006     EXSE, Department of Geography, University of Bonn
007     http://www.giub.uni-bonn.de/deegree/
008     lat/lon GmbH
009     http://www.lat-lon.de
010    
011     This library is free software; you can redistribute it and/or
012     modify it under the terms of the GNU Lesser General Public
013     License as published by the Free Software Foundation; either
014     version 2.1 of the License, or (at your option) any later version.
015    
016     This library is distributed in the hope that it will be useful,
017     but WITHOUT ANY WARRANTY; without even the implied warranty of
018     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
019     Lesser General Public License for more details.
020    
021     You should have received a copy of the GNU Lesser General Public
022     License along with this library; if not, write to the Free Software
023     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
024    
025     Contact:
026    
027     Andreas Poth
028     lat/lon GmbH
029     Aennchenstr. 19
030     53177 Bonn
031     Germany
032     E-Mail: poth@lat-lon.de
033    
034     Prof. Dr. Klaus Greve
035     Department of Geography
036     University of Bonn
037     Meckenheimer Allee 166
038     53115 Bonn
039     Germany
040     E-Mail: greve@giub.uni-bonn.de
041    
042     ---------------------------------------------------------------------------*/
043    package org.deegree.graphics.sld;
044    
045    import java.util.ArrayList;
046    import java.util.Iterator;
047    import java.util.List;
048    import java.util.Map;
049    
050    import org.deegree.io.datastore.PropertyPathResolvingException;
051    import org.deegree.model.filterencoding.Expression;
052    import org.deegree.model.filterencoding.Filter;
053    import org.deegree.model.filterencoding.FilterTools;
054    import org.deegree.ogcbase.PropertyPath;
055    
056    /**
057     * Collects all property names used by a list of styles. E.g. this can be used to optimze GetFeature
058     * requests from a WMS against a WFS.
059     * 
060     * @version $Revision: 9340 $
061     * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a>
062     * @author last edited by: $Author: apoth $
063     * 
064     * @version 1.0. $Revision: 9340 $, $Date: 2007-12-27 13:32:12 +0100 (Do, 27 Dez 2007) $
065     * 
066     * @since 2.0
067     */
068    public class StyleUtils {
069    
070        /**
071         * returns a list of all
072         * 
073         * @see PropertyPath's required by the passed UserStyles
074         * 
075         * @param styles
076         * @param scaleDen
077         * @return
078         * @throws PropertyPathResolvingException
079         */
080        public static List<PropertyPath> extractRequiredProperties( List<UserStyle> styles, double scaleDen )
081                                throws PropertyPathResolvingException {
082            List<PropertyPath> pp = new ArrayList<PropertyPath>();
083    
084            for ( int i = 0; i < styles.size(); i++ ) {
085                FeatureTypeStyle[] fts = styles.get( i ).getFeatureTypeStyles();
086                for ( int j = 0; j < fts.length; j++ ) {
087                    Rule[] rules = fts[j].getRules();
088                    for ( int k = 0; k < rules.length; k++ ) {
089                        double minScale = rules[k].getMinScaleDenominator();
090                        double maxScale = rules[k].getMaxScaleDenominator();
091                        if ( minScale <= scaleDen && maxScale > scaleDen ) {
092                            Filter filter = rules[k].getFilter();
093                            List<PropertyPath> list = FilterTools.extractPropertyPaths( filter );
094                            pp.addAll( list );
095                            Symbolizer[] sym = rules[k].getSymbolizers();
096                            for ( int d = 0; d < sym.length; d++ ) {
097                                if ( sym[d] instanceof PointSymbolizer ) {
098                                    pp = extractPPFromPointSymbolizer( (PointSymbolizer) sym[d], pp );
099                                } else if ( sym[d] instanceof LineSymbolizer ) {
100                                    pp = extractPPFromLineSymbolizer( (LineSymbolizer) sym[d], pp );
101                                } else if ( sym[d] instanceof PolygonSymbolizer ) {
102                                    pp = extractPPFromPolygonSymbolizer( (PolygonSymbolizer) sym[d], pp );
103                                } else if ( sym[d] instanceof TextSymbolizer ) {
104                                    pp = extractPPFromTextSymbolizer( (TextSymbolizer) sym[d], pp );
105                                }
106                            }
107                        }
108                    }
109                }
110            }
111    
112            List<PropertyPath> tmp = new ArrayList<PropertyPath>( pp.size() );
113            for ( int i = 0; i < pp.size(); i++ ) {
114                if ( !tmp.contains( pp.get( i ) ) ) {
115                    tmp.add( pp.get( i ) );
116                }
117            }
118    
119            return tmp;
120        }
121    
122        /**
123         * 
124         * @param symbolizer
125         * @param pp
126         * @return
127         * @throws PropertyPathResolvingException
128         */
129        private static List<PropertyPath> extractPPFromTextSymbolizer( TextSymbolizer symbolizer, List<PropertyPath> pp )
130                                throws PropertyPathResolvingException {
131            Map css = null;
132            if ( symbolizer.getFill() != null ) {
133                css = symbolizer.getFill().getCssParameters();
134                pp = extractPPFromCssParameter( css, pp );
135            }
136            if ( symbolizer.getFont() != null ) {
137                css = symbolizer.getFont().getCssParameters();
138                pp = extractPPFromCssParameter( css, pp );
139            }
140            if ( symbolizer.getGeometry() != null ) {
141                pp.add( symbolizer.getGeometry().getPropertyPath() );
142            }
143            Halo halo = symbolizer.getHalo();
144            ParameterValueType pvt = null;
145            if ( halo != null ) {
146                pvt = halo.getRadius();
147                pp = extractPPFromParamValueType( pvt, pp );
148    
149                if ( halo.getFill() != null ) {
150                    css = halo.getFill().getCssParameters();
151                    pp = extractPPFromCssParameter( css, pp );
152                }
153                if ( halo.getStroke() != null ) {
154                    css = halo.getStroke().getCssParameters();
155                    pp = extractPPFromCssParameter( css, pp );
156                }
157            }
158            pvt = symbolizer.getLabel();
159            pp = extractPPFromParamValueType( pvt, pp );
160    
161            // collect property names from line placement
162            LinePlacement lp = symbolizer.getLabelPlacement().getLinePlacement();
163            if ( lp != null ) {
164                pvt = lp.getGap();
165                pp = extractPPFromParamValueType( pvt, pp );
166                pvt = lp.getLineWidth();
167                pp = extractPPFromParamValueType( pvt, pp );
168                pvt = lp.getPerpendicularOffset();
169                pp = extractPPFromParamValueType( pvt, pp );
170            }
171    
172            // collect property names from line placement
173            PointPlacement ppl = symbolizer.getLabelPlacement().getPointPlacement();
174            if ( ppl != null ) {
175                pvt = ppl.getRotation();
176                pp = extractPPFromParamValueType( pvt, pp );
177                ParameterValueType[] pvta = ppl.getAnchorPoint();
178                if ( pvta != null ) {
179                    for ( int i = 0; i < pvta.length; i++ ) {
180                        pp = extractPPFromParamValueType( pvta[i], pp );
181                    }
182                }
183                pvta = ppl.getDisplacement();
184                if ( pvta != null ) {
185                    for ( int i = 0; i < pvta.length; i++ ) {
186                        pp = extractPPFromParamValueType( pvta[i], pp );
187                    }
188                }
189            }
190    
191            return pp;
192        }
193    
194        /**
195         * 
196         * @param symbolizer
197         * @param pp
198         * @return
199         * @throws PropertyPathResolvingException
200         */
201        private static List<PropertyPath> extractPPFromPolygonSymbolizer( PolygonSymbolizer symbolizer,
202                                                                          List<PropertyPath> pp )
203                                throws PropertyPathResolvingException {
204    
205            Map css = null;
206            if ( symbolizer != null ) {
207                if ( symbolizer.getFill() != null ) {
208                    css = symbolizer.getFill().getCssParameters();
209                    pp = extractPPFromCssParameter( css, pp );
210                }
211    
212                if ( symbolizer.getGeometry() != null ) {
213                    pp.add( symbolizer.getGeometry().getPropertyPath() );
214                }
215    
216                if ( symbolizer.getStroke() != null ) {
217                    css = symbolizer.getStroke().getCssParameters();
218                    pp = extractPPFromCssParameter( css, pp );
219                }
220            }
221    
222            return pp;
223        }
224    
225        /**
226         * 
227         * @param symbolizer
228         * @param pp
229         * @return
230         * @throws PropertyPathResolvingException
231         */
232        private static List<PropertyPath> extractPPFromLineSymbolizer( LineSymbolizer symbolizer, List<PropertyPath> pp )
233                                throws PropertyPathResolvingException {
234    
235            if ( symbolizer.getGeometry() != null ) {
236                pp.add( symbolizer.getGeometry().getPropertyPath() );
237            }
238    
239            Map css = symbolizer.getStroke().getCssParameters();
240            pp = extractPPFromCssParameter( css, pp );
241    
242            return pp;
243        }
244    
245        /**
246         * 
247         * @param symbolizer
248         * @param pp
249         * @return
250         * @throws PropertyPathResolvingException
251         */
252        private static List<PropertyPath> extractPPFromPointSymbolizer( PointSymbolizer symbolizer, List<PropertyPath> pp )
253                                throws PropertyPathResolvingException {
254    
255            Graphic graphic = symbolizer.getGraphic();
256            if ( graphic != null ) {
257                if ( graphic.getOpacity() != null ) {
258                    pp = extractPPFromParamValueType( graphic.getOpacity(), pp );
259                }
260    
261                if ( graphic.getRotation() != null ) {
262                    pp = extractPPFromParamValueType( graphic.getRotation(), pp );
263                }
264    
265                if ( graphic.getSize() != null ) {
266                    pp = extractPPFromParamValueType( graphic.getSize(), pp );
267                }
268    
269                if ( symbolizer.getGeometry() != null ) {
270                    pp.add( symbolizer.getGeometry().getPropertyPath() );
271                }
272            }
273    
274            return pp;
275        }
276    
277        private static List<PropertyPath> extractPPFromCssParameter( Map css, List<PropertyPath> pp )
278                                throws PropertyPathResolvingException {
279            if ( css != null ) {
280                Iterator iter = css.values().iterator();
281                while ( iter.hasNext() ) {
282                    ParameterValueType pvt = ( (CssParameter) iter.next() ).getValue();
283                    pp = extractPPFromParamValueType( pvt, pp );
284                }
285            }
286            return pp;
287        }
288    
289        private static List<PropertyPath> extractPPFromParamValueType( ParameterValueType pvt, List<PropertyPath> pp )
290                                throws PropertyPathResolvingException {
291            if ( pvt != null ) {
292                Object[] components = pvt.getComponents();
293                for ( int i = 0; i < components.length; i++ ) {
294                    if ( components[i] instanceof Expression ) {
295                        pp = FilterTools.extractPropertyPaths( (Expression) components[i], pp );
296                    }
297                }
298            }
299            return pp;
300        }
301    
302    }