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 }