1 package org.tigris.scarab.util.build.l10nchecker; 2 3 48 49 import java.io.BufferedReader ; 50 import java.io.File ; 51 import java.io.FileReader ; 52 import java.io.IOException ; 53 import java.text.MessageFormat ; 54 import java.util.ArrayList ; 55 import java.util.Hashtable ; 56 import java.util.Iterator ; 57 import java.util.List ; 58 59 import org.apache.oro.text.regex.MalformedPatternException; 60 import org.apache.oro.text.regex.MatchResult; 61 import org.apache.oro.text.regex.Pattern; 62 import org.apache.oro.text.regex.Perl5Compiler; 63 import org.apache.oro.text.regex.Perl5Matcher; 64 65 import org.tigris.scarab.util.Log; 66 import org.tigris.scarab.util.build.l10nchecker.issues.CantParseLineIssue; 67 import org.tigris.scarab.util.build.l10nchecker.issues.DefinedTwiceIssue; 68 import org.tigris.scarab.util.build.l10nchecker.issues.DifferentAttributeCountIssue; 69 import org.tigris.scarab.util.build.l10nchecker.issues.IllegalPatternIssue; 70 import org.tigris.scarab.util.build.l10nchecker.issues.NoTransAllowedIssue; 71 import org.tigris.scarab.util.build.l10nchecker.issues.NotInReferenceIssue; 72 import org.tigris.scarab.util.build.l10nchecker.issues.NotTranslatedIssue; 73 import org.tigris.scarab.util.build.l10nchecker.issues.TranslatedTwiceDiffIssue; 74 import org.tigris.scarab.util.build.l10nchecker.issues.TranslatedTwiceIssue; 75 import org.tigris.scarab.util.build.l10nchecker.issues.TranslationMissingIssue; 76 import org.tigris.scarab.util.build.l10nchecker.issues.TranslationRequiredIssue; 77 78 96 public class L10nInspector 97 { 98 99 100 private static String COMMENT_TRANS = "^\\s*#(\\+|-)TRANS.*$"; 101 102 private static String COMMENT_REGEX = "^\\s*(#.*)?$"; 103 104 private static String COMMAND_REGEX = "^\\s*([^=\\s]+)\\s*=\\s*(.*)$"; 105 106 private static Perl5Compiler compiler = new Perl5Compiler(); 107 108 private static Perl5Matcher matcher = new Perl5Matcher(); 109 110 private static Pattern commentPattern = null; 111 112 private static Pattern commandPattern = null; 113 114 private static Pattern transPattern = null; 115 116 117 private Hashtable refProperties; 118 119 120 private String refFileName; 121 122 123 private String checkFileName; 124 125 126 private int linesRead = 0; 127 128 129 private List messages = null; 130 131 134 public L10nInspector() throws MalformedPatternException 135 { 136 try 137 { 138 L10nIssueTemplates.reset(); 139 commentPattern = compiler.compile(COMMENT_REGEX); 140 commandPattern = compiler.compile(COMMAND_REGEX); 141 transPattern = compiler.compile (COMMENT_TRANS); 142 } catch (MalformedPatternException exMP) 143 { 144 Log.get().fatal(exMP); 145 throw exMP; } 147 messages = new ArrayList (); 148 } 149 150 160 public int setReference(String aRefFile) throws IOException 161 { 162 refFileName = aRefFile; 163 164 refProperties = new Hashtable (); 165 File inFile = new File (refFileName); 166 if (!inFile.canRead()) 167 { 168 throw new IOException ("Cannot read reference file " + aRefFile); 169 } 170 loadReferenceFile(inFile); 171 return refProperties.size(); 172 } 173 174 179 public List getErrors() 180 { 181 List errs = new ArrayList (messages.size()); 182 Iterator it = messages.iterator(); 183 184 while (it.hasNext()) 185 { 186 L10nMessage msg = (L10nMessage) it.next(); 187 if (msg.getIssue().isError()) 188 { 189 errs.add(msg); 190 } 191 } 192 return errs; 193 } 194 195 200 public List getWarnings() 201 { 202 List warnings = new ArrayList (messages.size()); 203 Iterator it = messages.iterator(); 204 205 while (it.hasNext()) 206 { 207 L10nMessage msg = (L10nMessage) it.next(); 208 if (msg.getIssue().isWarning()) 209 { 210 warnings.add(msg); 211 } 212 } 213 return warnings; 214 } 215 216 221 public List getInfos() 222 { 223 List infos = new ArrayList (messages.size()); 224 Iterator it = messages.iterator(); 225 226 while (it.hasNext()) 227 { 228 L10nMessage msg = (L10nMessage) it.next(); 229 if (msg.getIssue().isInfo()) 230 { 231 infos.add(msg); 232 } 233 } 234 return infos; 235 } 236 237 242 public List getMessages() 243 { 244 return messages; 245 } 246 247 252 public boolean hasErrors() 253 { 254 return getErrors().size() > 0; 255 } 256 257 265 public int checkFile(String filename) throws IOException 266 { 267 BufferedReader inStream = null; 268 String inLine; 269 Hashtable seen = new Hashtable (); 270 int lineNo = 0; 271 boolean doNotTrans = false; 272 273 messages.clear(); 274 checkFileName = filename; 275 try 276 { 277 inStream = new BufferedReader (new FileReader (filename)); 278 while ((inLine = inStream.readLine()) != null) 279 { 280 lineNo++; 281 if (matcher.matches(inLine, transPattern)) 282 { 283 MatchResult result = matcher.getMatch(); 284 if (result.group(1).equals("-")) 285 { 286 doNotTrans = true; 287 } 288 } 289 else if (matcher.matches(inLine, commentPattern)) 290 { 291 continue; 293 } 294 else if (matcher.contains(inLine, commandPattern)) 295 { 296 MatchResult result = matcher.getMatch(); 299 String key = result.group(1); 300 String value = result.group(2); 301 L10nKey l10nKey = new L10nKey(key, value, lineNo); 302 if (value.indexOf('{') >= 0) { 303 try 305 { 306 MessageFormat fmt = new MessageFormat (value); 307 int attributeCount = fmt.getFormats().length; 308 l10nKey.setAttributeCount(attributeCount); 309 } 310 catch (IllegalArgumentException exIAE) 311 { 312 addMessage (lineNo, new IllegalPatternIssue(key), null); 313 continue; 314 } 315 } 316 l10nKey.setNoTrans(doNotTrans); 317 doNotTrans = false; 318 319 if (seen.contains(l10nKey)) 321 { 322 L10nKey orig = (L10nKey) seen.get(l10nKey); 324 if (orig.getValue().equals(l10nKey.getValue())) 325 { 326 addMessage (lineNo, new TranslatedTwiceIssue(key, orig.getLineNo()), 328 l10nKey); 329 } 330 else 331 { 332 addMessage (lineNo, new TranslatedTwiceDiffIssue(key, orig.getLineNo()), 334 l10nKey); 335 } 336 seen.remove(orig); seen.put(l10nKey, l10nKey); 338 continue; } 340 seen.put(l10nKey, l10nKey); 341 L10nKey ref = (L10nKey) refProperties.get(key); 342 if (ref == null) 343 { 344 addMessage (lineNo, new NotInReferenceIssue (key), l10nKey); 346 } 347 else 348 { 349 if (ref.isNoTrans()) 350 { 351 addMessage (lineNo, new NoTransAllowedIssue(key), l10nKey); 353 } 354 else if (ref.getValue().equals(value)) 355 { 356 if (ref.isNeedTrans()) 357 { 358 addMessage (lineNo, new TranslationRequiredIssue(key), ref); 360 } 361 else 362 { 363 if (!l10nKey.isNoTrans()) 367 addMessage (lineNo, new NotTranslatedIssue (key), l10nKey); 368 } 369 } 370 else if (ref.getAttributeCount() != l10nKey.getAttributeCount()) 371 { 372 addMessage (lineNo, 374 new DifferentAttributeCountIssue(key, 375 l10nKey.getAttributeCount(), 376 ref.getAttributeCount()), 377 l10nKey); 378 } 379 } 380 } else 381 { 382 addMessage(lineNo, new CantParseLineIssue(inLine), null); 383 } 384 } 385 } catch (IOException exIO) 386 { 387 Log.get().error(exIO); 388 exIO.printStackTrace(); 389 refProperties.clear(); 391 messages.clear(); 392 throw exIO; } catch (Exception e) 394 { 395 Log.get().error(e); 396 e.printStackTrace(); 397 refProperties.clear(); 399 messages.clear(); 400 throw new IOException (e.getMessage()); 401 } 402 403 Iterator it = refProperties.keySet().iterator(); 405 while (it.hasNext()) 406 { 407 String key = (String ) it.next(); 408 L10nKey refKey = (L10nKey)refProperties.get(key); 409 if (!seen.contains(refKey)) 410 { 411 if (refKey.isNeedTrans()) 412 { 413 addMessage (-1, new TranslationRequiredIssue(key), refKey); 415 } 416 else 417 { 418 addMessage (-1, new TranslationMissingIssue (key), refKey); 420 } 421 } 422 } 423 this.linesRead = lineNo; 424 return seen.size(); 425 } 426 427 428 429 435 private void loadReferenceFile(File inFile) throws IOException 436 { 437 BufferedReader inStream = null; 438 String inLine; 439 int lineNo = 0; 440 boolean transNeeded = false; 441 boolean doNotTrans = false; 442 443 try 444 { 445 inStream = new BufferedReader (new FileReader (inFile)); 446 while ((inLine = inStream.readLine()) != null) 447 { 448 lineNo++; 449 if (matcher.matches(inLine, transPattern)) 450 { 451 MatchResult result = matcher.getMatch(); 452 if (result.group(1).equals("+")) 453 { 454 transNeeded = true; 455 } 456 else 457 { 458 doNotTrans = true; 459 } 460 } 461 else if (matcher.matches(inLine, commentPattern)) 462 { 463 continue; 465 } 466 else if (matcher.contains(inLine, commandPattern)) 467 { 468 MatchResult result = matcher.getMatch(); 471 String key = result.group(1); 472 String value = result.group(2); 473 L10nKey l10nKey = new L10nKey(key, value, lineNo); 474 if (value.indexOf('{') >= 0) 475 { 476 try 478 { 479 MessageFormat fmt = new MessageFormat (value); 480 int attributeCount = fmt.getFormats().length; 481 l10nKey.setAttributeCount(attributeCount); 482 } 483 catch (IllegalArgumentException exIAE) 484 { 485 addMessage (lineNo, new IllegalPatternIssue(key), null); 486 continue; 487 } 488 } 489 l10nKey.setNeedTrans(transNeeded); 490 l10nKey.setNoTrans(doNotTrans); 491 transNeeded = false; 493 doNotTrans = false; 494 if (refProperties.get(key) != null) 495 { 496 L10nKey orig = (L10nKey) refProperties.get(key); 498 if (orig.getValue().equals(l10nKey.getValue())) 499 { 500 addMessage(lineNo, new DefinedTwiceIssue(key, orig.getLineNo()), 501 l10nKey); 502 } else { 503 addMessage(lineNo, new DefinedTwiceIssue (key, orig.getLineNo()), 505 l10nKey); 506 } 507 continue; 508 } 509 refProperties.put(key, l10nKey); 511 } else 512 { 513 addMessage(lineNo, new CantParseLineIssue (inLine), null); 514 } 515 } 516 } catch (IOException exIO) 517 { 518 exIO.printStackTrace(); 519 Log.get().error(exIO); 520 refProperties.clear(); 522 messages.clear(); 523 throw exIO; } catch (Exception e) 525 { 526 Log.get().error(e); 527 e.printStackTrace(); 529 refProperties.clear(); 530 messages.clear(); 531 throw new IOException (e.getMessage()); 532 } 533 this.linesRead = lineNo; 534 } 535 536 537 private void addMessage(int lineNo, L10nIssue issue, L10nKey l10nKey) 538 { 539 L10nMessage err = new L10nMessage(lineNo, issue); 540 if (l10nKey != null) 541 { 542 err.setL10nObject(l10nKey); 543 } 544 messages.add(err); 545 } 546 547 554 public static void main(String [] args) 555 { 556 L10nInspector ins = null; 557 System.err.println ("This is only used for internal tests"); 558 try 559 { 560 ins = new L10nInspector(); 561 } catch (MalformedPatternException exMP) 562 { 563 System.exit(1); } 565 try 566 { 567 File f = new File ("."); 568 System.err.println("We are here:" + f.getAbsolutePath()); 569 ins.setReference("src/conf/classes/ScarabBundle_en.properties"); 570 } catch (IOException exIO) 571 { 572 exIO.printStackTrace(); 573 System.exit(1); 574 } 575 if (ins.getErrors().size() > 0) 576 { 577 Iterator it = ins.getErrors().iterator(); 578 while (it.hasNext()) 579 { 580 L10nMessage data = (L10nMessage) it.next(); 581 System.err.println("E " + data.getLineNumber() + ": " 582 + data.getMessageText()); 583 } 584 } 585 if (ins.getWarnings().size() > 0) 586 { 587 Iterator it = ins.getWarnings().iterator(); 588 while (it.hasNext()) 589 { 590 L10nMessage data = (L10nMessage) it.next(); 591 System.err.println("W " + data.getLineNumber() + ": " 592 + data.getMessageText()); 593 } 594 } 595 if (ins.hasErrors()) 596 { 597 } 599 System.out.println("--- checking de"); 600 try 601 { 602 int lines = ins 603 .checkFile("src/conf/classes/ScarabBundle_es.properties"); 604 } catch (Exception e) 605 { 606 e.printStackTrace(); 607 System.exit(1); 608 } 609 List msgs = ins.getMessages(); 610 Iterator it = msgs.iterator(); 611 while (it.hasNext()) 612 { 613 L10nMessage msg = (L10nMessage) it.next(); 614 if (msg.getIssue().isError()) 615 { 616 System.out.print('E'); 617 } else if (msg.getIssue().isWarning()) 618 { 619 System.out.print('W'); 620 } else if (msg.getIssue().isInfo()) 621 { 622 System.out.print('I'); 623 } 624 if (msg.getLineNumber() > 0) 625 { 626 System.out.print(" " + msg.getLineNumber()); 627 } 628 System.out.println(": " + msg.getMessageText()); 629 } 630 } 631 } 632 | Popular Tags |