1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 package org.openoffice.xmerge.converter.xml.sxc.minicalc; 25 26 /** 27 * This class is used by <code>MinicalcDecoder</code> to manipulate a 28 * <code>String</code> containing MiniCalc cell data. 29 * 30 * @author Paul Rank 31 */ 32 public class MinicalcDataString { 33 34 /** The String representation of the MiniCalc data. */ 35 private String data = null; 36 37 38 /** 39 * Constructor stores the MiniCalc data <code>String</code>. 40 * 41 * @param data A <code>String</code> containing MiniCalc 42 * cell data. 43 */ MinicalcDataString(String data)44 public MinicalcDataString(String data) { 45 this.data = data; 46 } 47 48 49 /** 50 * Checks if the MiniCalc data <code>String</code> is a <i>formula</i>. 51 * 52 * @return true if the MiniCalc data <code>String</code> is a 53 * <i>formula</i>, false if the MiniCalc data <code>String</code> 54 * is not a <i>formula</i>. 55 */ isFormula()56 public boolean isFormula() { 57 58 if (data.startsWith("=")) { 59 return true; 60 } 61 62 return false; 63 } 64 65 66 /** 67 * Checks if the MiniCalc data <code>String</code> is a <i>percentage</i>. 68 * 69 * @return true if the MiniCalc data <code>String</code> is a 70 * <i>percentage</i>, false if the MiniCalc data 71 * <code>String</code> is not a <i>percentage</i>. 72 */ isPercent()73 public boolean isPercent() { 74 75 if (data.endsWith("%")) { 76 return true; 77 } 78 79 return false; 80 } 81 82 83 /** 84 * Checks if the MiniCalc data <code>String</code> is a 85 * <i>boolean</i> value. 86 * 87 * @return true if the MiniCalc data <code>String</code> is 88 * a <i>boolean</i>, false if the MiniCalc data 89 * <code>String</code> is not a <i>boolean</i>. 90 */ isBoolean()91 public boolean isBoolean() { 92 93 if (data.equalsIgnoreCase("false") || 94 data.equalsIgnoreCase("true")) { 95 return true; 96 } 97 98 return false; 99 } 100 101 102 /** 103 * Checks if the MiniCalc data <code>String</code> is a <i>date</i>. 104 * 105 * @return true if the MiniCalc data <code>String</code> is 106 * a <i>date</i>, false if the MiniCalc data <code>String</code> 107 * is not a <i>date</i>. 108 */ isDate()109 public boolean isDate() { 110 111 // Starting index into the date string - month 112 int start = 0; 113 114 // Search for "/", which separates month from day 115 int end = data.indexOf("/"); 116 117 // Separator was found 118 if (end > 0) { 119 120 String monthString = data.substring(start, end); 121 122 try { 123 Float f = Float.valueOf(monthString); 124 if ((f.intValue() < 0) || (f.intValue() > 12)) { 125 return false; 126 } 127 } 128 catch (NumberFormatException e) { 129 130 // no, it is not a currency type 131 return false; 132 } 133 134 // start is now the starting index of day 135 start = end+1; 136 137 // Search for "/", which separates day from year 138 end = data.indexOf("/", start); 139 140 // Separator was found 141 if (end > 0) { 142 143 String dayString = data.substring(start, end); 144 145 try { 146 Float f = Float.valueOf(dayString); 147 if ((f.intValue() < 0) || (f.intValue() > 31)) 148 return false; 149 } 150 catch (NumberFormatException e) { 151 // no, it is not a currency type 152 return false; 153 } 154 } else { 155 return false; 156 } 157 158 // start is now at the starting index of the year 159 start = end + 1; 160 161 String yearString = data.substring(start); 162 try { 163 Float f = Float.valueOf(yearString); 164 if (f.intValue() < 0) { 165 return false; 166 } 167 } 168 catch (NumberFormatException e) { 169 // no, it is not a currency type 170 return false; 171 } 172 173 } else { 174 return false; 175 } 176 177 return true; 178 } 179 180 181 /** 182 * Checks if the MiniCalc data <code>String</code> is a <i>time</i>. 183 * 184 * @return true if the MiniCalc data <code>String</code> 185 * is a <i>time</i>, false if the MiniCalc data 186 * <code>String</code> is not a <i>time</i>. 187 */ isTime()188 public boolean isTime() { 189 190 // Starting index into the time string - hour 191 int start = 0; 192 193 // Search for ":", which separates hour from minute 194 int end = data.indexOf(":"); 195 196 197 // Separator was found 198 if (end > 0) { 199 200 String hourString = data.substring(start, end); 201 try { 202 Float f = Float.valueOf(hourString); 203 if ((f.intValue() < 0) || (f.intValue() > 24)) 204 return false; 205 } 206 catch (NumberFormatException e) { 207 // no, it is not a time type 208 return false; 209 } 210 211 // start is now the starting index of minute 212 start = end+1; 213 214 // Search for ":", which separates minute from second 215 end = data.indexOf(":", start); 216 217 // Separator was found 218 if (end > 0) { 219 220 String minuteString = data.substring(start, end); 221 222 try { 223 Float f = Float.valueOf(minuteString); 224 if ((f.intValue() < 0) || (f.intValue() > 60)) 225 return false; 226 } 227 catch (NumberFormatException e) { 228 // no, it is not a time type 229 return false; 230 } 231 232 // start is now at the starting index of the seconds 233 start = end+1; 234 235 // The seconds are in the string 236 if (data.length() > start) { 237 238 String secondString = data.substring(start); 239 240 241 try { 242 Float f = Float.valueOf(secondString); 243 if ((f.intValue() < 0) || (f.intValue() > 60)) 244 return false; 245 } 246 catch (NumberFormatException e) { 247 // no, it is not a time type 248 return false; 249 } 250 } 251 252 } 253 254 return true; 255 256 } 257 258 return false; 259 } 260 261 262 /** 263 * Checks if the MiniCalc data <code>String</code> is a <i>currency</i> 264 * value. 265 * 266 * @return true if the MiniCalc data <code>String</code> is 267 * a <i>currency</i>, false if the MiniCalc data 268 * <code>String</code> is not a <i>currency</i>. 269 */ isCurrency()270 public boolean isCurrency() { 271 272 boolean result = false; 273 274 // TODO - we currently only check for US currencies 275 276 if (data.endsWith("$")) { 277 String number = data.substring(0, data.length()-1); 278 try { 279 Float f = Float.valueOf(number); 280 result = true; 281 } 282 catch (NumberFormatException e) { 283 // no, it is not a currency type 284 result = false; 285 } 286 } 287 288 else if (data.startsWith("$")) { 289 String number = data.substring(1, data.length()); 290 try { 291 Float f = Float.valueOf(number); 292 result = true; 293 } 294 catch (NumberFormatException e) { 295 // no, it is not a currency type 296 result = false; 297 } 298 } 299 300 return result; 301 302 } 303 304 305 /** 306 * This method removes the percent sign from the MiniCalc data 307 * <code>String</code>. If the percent sign is not the last 308 * character of the MiniCalc data <code>String</code>, the 309 * MiniCalc data <code>String</code> is returned. 310 * 311 * @return The MiniCalc data <code>String</code> minus the 312 * percent sign. If the MiniCalc data <code>String</code> 313 * does not begin with a percent sign, the MiniCalc data 314 * <code>String</code> is returned. 315 */ percentRemoveSign()316 public String percentRemoveSign() { 317 318 String number = data; 319 320 if (data.endsWith("%")) { 321 // "%" is the last character, so remove 322 number = data.substring(0, data.length()-1); 323 324 try { 325 Float f = Float.valueOf(number); 326 float f1 = f.floatValue()/100f; 327 Float f2 = new Float(f1); 328 number = f2.toString(); 329 } 330 catch (NumberFormatException e) { 331 // no, it is not a float type 332 } 333 } 334 335 return number; 336 } 337 338 339 /** 340 * This method removes the currency sign from the MiniCalc data 341 * <code>String</code>. If the currency sign is not the first or 342 * last character of the MiniCalc data <code>String</code>, the 343 * MiniCalc data <code>String</code> is returned. 344 * 345 * @return The MiniCalc data <code>String</code> minus the currency 346 * sign. If the MiniCalc data <code>String</code> does not 347 * begin or end with a currency sign, the MiniCalc 348 * data <code>String</code> is returned. 349 */ currencyRemoveSign()350 public String currencyRemoveSign() { 351 352 String number = data; 353 354 // TODO - only works with US currencies 355 356 if (data.endsWith("$")) { 357 358 number = data.substring(0, data.length()-1); 359 360 } else if (data.startsWith("$")) { 361 362 number = data.substring(1, data.length()); 363 } 364 365 return number; 366 367 } 368 369 370 /** 371 * <p>This method converts a MiniCalc date from MiniCalc 372 * format to StarOffice XML format.</p> 373 * 374 * <p>MiniCalc format:</p> 375 * 376 * <p><blockquote> 377 * MM/DD/YY or MM/DD/YYYY 378 * </blockquote></p> 379 * 380 * <p>StarOffice XML format:</p> 381 * 382 * <p><blockquote> 383 * YYYY-MM-DD 384 * </blockquote></p> 385 * 386 * @return The MiniCalc date converted to StarOffice XML 387 * format. 388 */ convertToStarDate()389 public String convertToStarDate() { 390 391 // The output date string 392 String out; 393 394 String monthString = "01"; 395 String dayString = "01"; 396 String yearString = "1900"; 397 398 // Starting index into the date string - month 399 int start = 0; 400 401 // Search for "/", which separates month from day 402 int end = data.indexOf("/"); 403 404 // Separator was found 405 if (end > 0) { 406 407 monthString = data.substring(start, end); 408 409 Integer monthInt = new Integer(monthString); 410 411 // Make sure month is 2 digits 412 if (monthInt.intValue() < 10) { 413 monthString = "0" + monthString; 414 } 415 416 // start is now the starting index of day 417 start = end+1; 418 419 // Search for "/", which separates day from year 420 end = data.indexOf("/", start); 421 422 // Separator was found 423 if (end > 0) { 424 425 dayString = data.substring(start, end); 426 427 Integer dayInt = new Integer(dayString); 428 429 // Make sure day is 2 digits 430 if (dayInt.intValue() < 10) { 431 dayString = "0" + dayString; 432 } 433 434 // start is now at the starting index of the year 435 start = end + 1; 436 437 // The year is in the string 438 if (data.length() > start) { 439 440 yearString = data.substring(start); 441 442 Integer yearInt = new Integer(yearString); 443 int year = yearInt.intValue(); 444 445 if (year < 31) { 446 447 // MiniCalc years between 0 and 30 correspond to 448 // 2000 - 2030 449 year += 2000; 450 451 } else if (year < 100) { 452 453 // MiniCalc years between 31 and 99 correspond 454 // to 1931 - 1999 455 year += 1900; 456 } 457 458 yearString = Integer.toString(year); 459 } 460 } 461 } 462 463 // Set out to StarOffice XML date format 464 out = yearString + "-" + monthString + "-" + dayString; 465 466 return out; 467 } 468 469 470 /** 471 * This method converts the MiniCalc time from MiniCalc 472 * format to StarOffice XML format. 473 * 474 * <p>MiniCalc format:</p> 475 * 476 * <p><blockquote> 477 * hh:mm:ss 478 * </blockquote></p> 479 * 480 * <p>StarOffice XML format:</p> 481 * 482 * <p><blockquote> 483 * PThhHmmMssS 484 * </blockquote></p> 485 * 486 * @return The MiniCalc time converted to StarOffice XML 487 * format. 488 */ convertToStarTime()489 public String convertToStarTime() { 490 491 // The output time string 492 String out; 493 494 String hourString = "00"; 495 String minuteString = "00"; 496 String secondString = "00"; 497 498 // Starting index into the time string - hour 499 int start = 0; 500 501 // Search for ":", which separates hour from minute 502 int end = data.indexOf(":"); 503 504 // Separator was found 505 if (end > 0) { 506 507 hourString = data.substring(start, end); 508 509 // start is now the starting index of minute 510 start = end+1; 511 512 // Search for ":", which separates minute from second 513 end = data.indexOf(":", start); 514 515 // Separator was found 516 if (end > 0) { 517 518 minuteString = data.substring(start, end); 519 520 // start is now at the starting index of the seconds 521 start = end+1; 522 523 // The seconds are in the string 524 if (data.length() > start) { 525 526 secondString = data.substring(start); 527 } 528 529 } 530 } 531 532 // TODO - PT is for pacific time, where can we get the 533 // localized value from? 534 535 // Set to StarOffice XML time format 536 out = "PT"+hourString+"H"+minuteString+"M"+secondString+"S"; 537 538 return out; 539 } 540 } 541 542