001    //$$Header: $$
002    /*----------------------------------------------------------------------------
003     This file is part of deegree, http://deegree.org/
004     Copyright (C) 2001-2009 by:
005       Department of Geography, University of Bonn
006     and
007       lat/lon GmbH
008    
009     This library is free software; you can redistribute it and/or modify it under
010     the terms of the GNU Lesser General Public License as published by the Free
011     Software Foundation; either version 2.1 of the License, or (at your option)
012     any later version.
013     This library is distributed in the hope that it will be useful, but WITHOUT
014     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
015     FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
016     details.
017     You should have received a copy of the GNU Lesser General Public License
018     along with this library; if not, write to the Free Software Foundation, Inc.,
019     59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
020    
021     Contact information:
022    
023     lat/lon GmbH
024     Aennchenstr. 19, 53177 Bonn
025     Germany
026     http://lat-lon.de/
027    
028     Department of Geography, University of Bonn
029     Prof. Dr. Klaus Greve
030     Postfach 1147, 53001 Bonn
031     Germany
032     http://www.geographie.uni-bonn.de/deegree/
033    
034     e-mail: info@deegree.org
035    ----------------------------------------------------------------------------*/
036    
037    package org.deegree.graphics.charts;
038    
039    import java.util.Arrays;
040    import java.util.Iterator;
041    import java.util.List;
042    import java.util.regex.Matcher;
043    import java.util.regex.Pattern;
044    
045    /**
046     * A Parser and tokenizer for the three defined formats.
047     *
048     * @author <a href="mailto:elmasry@lat-lon.de">Moataz Elmasry</a>
049     * @author last edited by: $Author: elmasri$
050     *
051     * @version $Revision: $, $Date: 28 Mar 2008 16:33:58$
052     */
053    class ValueFormatsParser {
054    
055        /**
056         * &CDU=34&SPD=36&Gruene=11
057         */
058        public final static int VALUE_FORMAT_SIMPLE = 1101;
059    
060        /**
061         * &CDU=23,25,21,26&SPD=42 23 33 36
062         */
063        public final static int VALUE_FORMAT_SERIES = 1102;
064    
065        /**
066         * &CDU=1970 23;1974,44;1978,43&SPD=1970,23;1974,44;1978,43
067         */
068        public final static int VALUE_FORMAT_XYSERIES = 1103;
069    
070        /**
071         * Unknown format
072         */
073        public final static int VALUE_FORMAT_UNKNOWN = 1104;
074    
075        private String value;
076    
077        // private String regexSeries = "[\\w*,\\w*;]*[\\w*,\\w*]";
078        // private String regexSeriesSep1 = "((\\w*,)*(\\w*){1})";
079        //
080        // private String regexSeriesSep2 = "((\\w*\\s)*(\\w*){1})";
081    
082        private String regexSeriesSep1 = "((\\-){0,1}\\d+(\\.\\d+){0,1},)*((\\-){0,1}\\d+(\\.\\d+){0,1})";
083    
084        private String regexSeriesSep2 = "((\\-){0,1}\\d+(\\.\\d+){0,1}\\s)*((\\-){0,1}\\d+(\\.\\d+){0,1})";
085    
086        // ex: &CDU=1970 23;1974,44;1978,43&SPD=1970,23;1974,44;1978,43
087        // private String regexSeriesXY = "(\\d+(\\.\\d+){0,1},\\d+(\\.\\d+){0,1};)*";
088        private String regexSeriesXYSep1 = "((\\-){0,1}\\d+(\\.\\d+){0,1},(\\-){0,1}\\d+(\\.\\d+){0,1};)*((\\-){0,1}\\d+(\\.\\d+){0,1},(\\-){0,1}\\d+(\\.\\d+){0,1})";
089    
090        private String regexSeriesXYSep2 = "((\\-){0,1}\\d+(\\.\\d+){0,1}\\s\\d+((\\-){0,1}\\.\\d+){0,1};)*((\\-){0,1}\\d+(\\.\\d+){0,1}\\s\\d+((\\-){0,1}\\.\\d+){0,1})";
091    
092        // Will only be used with xySeries
093        private String separator = ";";
094    
095        private List<String> list = null;
096    
097        private Iterator<String> it = null;
098    
099        private int format = -1;
100    
101        private String separator1 = ",";
102    
103        private String separator2 = " ";
104    
105        /**
106         * @param value
107         * @throws IncorrectFormatException
108         */
109        public ValueFormatsParser( String value ) throws IncorrectFormatException {
110            this.value = value;
111    
112            if ( value.contains( separator1 ) && value.contains( separator2 ) ) {
113                throw new IncorrectFormatException( Messages.getMessage( "GRA_CHART_BAD_SEPARATOR", value, separator1,
114                                                                         separator2 ) );
115    
116            }
117            if ( !value.contains( separator ) ) {
118                String sep = value.contains( separator1 ) ? separator1 : separator2;
119                list = Arrays.asList( this.value.split( sep ) );
120                it = list.iterator();
121                format = getFormatType();
122            } else {
123                list = Arrays.asList( this.value.split( separator ) );
124                it = list.iterator();
125                format = getFormatType();
126            }
127        }
128    
129        /**
130         * @return String
131         */
132        public String getValue() {
133            return value;
134        }
135    
136        /**
137         * @return boolean
138         */
139        public boolean isFormatSimple() {
140            // If simple format
141            if ( format == VALUE_FORMAT_SIMPLE ) {
142                return true;
143            } else if ( format == -1 ) {
144                // if not yet checked
145                try {
146                    double d = Double.parseDouble( value );
147                    if ( String.valueOf( d ).length() != value.length() ) {
148                        return false;
149                    }
150                    return true;
151                } catch ( Exception e ) {
152                    return false;
153                }
154            } else {
155                // if checked and not found simple
156                return false;
157            }
158        }
159    
160        /**
161         * @return boolean
162         */
163        public boolean isFormatSeries() {
164            // if series
165            if ( format == VALUE_FORMAT_SERIES ) {
166                return true;
167            } else if ( format == -1 ) {
168                // if not checked
169                boolean match = matchPattern( regexSeriesSep1 );
170                if ( !match ) {
171                    return matchPattern( regexSeriesSep2 );
172                }
173                return match;
174            } else {
175                // if checked and found series
176                return false;
177            }
178        }
179    
180        /**
181         * @return boolean
182         */
183        public boolean isFormatSeriesXY() {
184            // of seriesXY
185            if ( format == VALUE_FORMAT_XYSERIES ) {
186                return true;
187            } else if ( format == -1 ) {
188                // if not yet checked
189                boolean match = matchPattern( regexSeriesXYSep1 );
190                if ( !match ) {
191                    return matchPattern( regexSeriesXYSep2 );
192                }
193                return match;
194            } else {
195                // if checked and not found seriesXY
196                return false;
197            }
198        }
199    
200        /**
201         * @return boolean
202         */
203        public boolean isFormatUnknown() {
204            if ( getFormatType() == VALUE_FORMAT_UNKNOWN ) {
205                return true;
206            }
207            return false;
208        }
209    
210        /**
211         * @param pattern a regex to match
212         * @return true if the pattern matches the value.
213         */
214        protected boolean matchPattern( String pattern ) {
215            Pattern pat = Pattern.compile( pattern );
216            Matcher matcher = null;
217            try {
218                matcher = pat.matcher( value );
219            } catch ( Exception e ) {
220                return false;
221            }
222            if ( matcher.matches() == false || matcher.group().length() != value.length() ) {
223                return false;
224            }
225            return true;
226        }
227    
228        /**
229         * @return A public variable indicating the format type
230         */
231        public int getFormatType() {
232            if ( isFormatSeriesXY() ) {
233                format = VALUE_FORMAT_XYSERIES;
234                return VALUE_FORMAT_XYSERIES;
235            }
236            if ( isFormatSeries() ) {
237                format = VALUE_FORMAT_SERIES;
238                return VALUE_FORMAT_SERIES;
239            } else if ( isFormatSimple() ) {
240                format = VALUE_FORMAT_SIMPLE;
241                return VALUE_FORMAT_SIMPLE;
242            } else {
243                format = VALUE_FORMAT_UNKNOWN;
244                return VALUE_FORMAT_UNKNOWN;
245            }
246        }
247    
248        /**
249         * @return Separator
250         */
251        public String getSeparator() {
252            return separator;
253        }
254    
255        /**
256         * @return Number of tupels parsed
257         */
258        public int getTupelsCount() {
259            return list.size();
260        }
261    
262        /**
263         * Resets the market to the start of the string
264         */
265        public void start() {
266            it = list.iterator();
267        }
268    
269        /**
270         * @return true if the tokenizer has more tupels, false otherwise
271         */
272        public boolean hasNext() {
273            return it.hasNext();
274        }
275    
276        /**
277         * @return next tupel
278         */
279        public String getNext() {
280            return it.next();
281        }
282    
283        /**
284         * @return nextTupel
285         */
286        public String nextTupel() {
287            return it.next();
288        }
289    }