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 }