1 56 package org.opencrx.application.customizing; 57 import java.io.File ; 58 import java.io.FileNotFoundException ; 59 import java.io.FileOutputStream ; 60 import java.io.IOException ; 61 import java.io.OutputStreamWriter ; 62 import java.io.UnsupportedEncodingException ; 63 import java.io.Writer ; 64 import java.util.ArrayList ; 65 import java.util.HashMap ; 66 import java.util.HashSet ; 67 import java.util.Iterator ; 68 import java.util.List ; 69 import java.util.Map ; 70 import java.util.Set ; 71 import java.util.TreeMap ; 72 import java.util.Map.Entry; 73 74 import javax.xml.parsers.DocumentBuilderFactory ; 75 import javax.xml.parsers.ParserConfigurationException ; 76 77 import org.opencrx.base.text.conversion.XMLWriter; 78 import org.openmdx.base.application.control.Application; 79 import org.openmdx.base.application.control.ApplicationController; 80 import org.openmdx.base.application.control.CmdLineOption; 81 import org.openmdx.base.exception.ServiceException; 82 import org.openmdx.compatibility.base.dataprovider.cci.DataproviderObject; 83 import org.openmdx.compatibility.base.dataprovider.cci.DataproviderObject_1_0; 84 import org.openmdx.compatibility.base.dataprovider.cci.SystemAttributes; 85 import org.openmdx.compatibility.base.dataprovider.importer.xml.XmlImporter; 86 import org.openmdx.compatibility.base.naming.Path; 87 import org.openmdx.uses.java.beans.ExceptionListener; 88 import org.openmdx.uses.org.apache.commons.collections.map.ListOrderedMap; 89 import org.w3c.dom.Document ; 90 import org.w3c.dom.NodeList ; 91 import org.xml.sax.SAXException ; 92 93 103 public class CodeUtility 104 extends Application 105 implements ExceptionListener { 106 107 public CodeUtility( 109 ) { 110 super( 111 APP_NAME, 112 VERSION, 113 HELP_TEXT, 114 createCmdLineOptions() 115 ); 116 } 117 118 public void exceptionThrown( 120 Exception exception 121 ){ 122 exception.printStackTrace(); 123 } 124 125 protected void init( 127 ) throws Exception { 128 this.locale = new ArrayList (); 130 if(getCmdLineArgs().hasArg("locale")) { 131 this.locale.addAll(getCmdLineArgs().getValues("locale")); 132 } 133 if((this.locale.size() == 0) || !"en_US".equals(this.locale.get(0))) { 134 this.locale.add(0, "en_US"); 135 } 136 this.sourceDir = null; 138 if(getCmdLineArgs().hasArg("sourceDir")) { 139 this.sourceDir = new File (getCmdLineArgs().getFirstValue("sourceDir")); 140 } 141 else { 142 this.sourceDir = new File ("."); 143 } 144 this.targetDir = null; 146 if(getCmdLineArgs().hasArg("targetDir")) { 147 this.targetDir = new File (getCmdLineArgs().getFirstValue("targetDir")); 148 } 149 else { 150 this.targetDir = new File ("."); 151 } 152 } 153 154 private Map lookupCode( 156 Document document, 157 String lookupContainerName, 158 String lookupCode 159 ) { 160 Map codeEntry = new HashMap (); 161 NodeList containerNodes = document.getElementsByTagName("CodeValueContainer"); 162 for(int i = 0; i < containerNodes.getLength(); i++) { 163 org.w3c.dom.Node containerNode = containerNodes.item(i); 164 org.w3c.dom.NamedNodeMap containerNodeAttributes = containerNode.getAttributes(); 165 org.w3c.dom.Attr containerNodeName = (org.w3c.dom.Attr )containerNodeAttributes.getNamedItem("name"); 166 if( 167 (containerNodeName != null) && 168 lookupContainerName.equals(containerNodeName.getValue()) 169 ) { 170 org.w3c.dom.NodeList codeValueEntryNodes = containerNode.getChildNodes(); 171 for(int j = 0; j < codeValueEntryNodes.getLength(); j++) { 172 org.w3c.dom.Node codeValueEntryNode = codeValueEntryNodes.item(j); 173 if(codeValueEntryNode.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE) { 174 if("CodeValueEntry".equals(codeValueEntryNode.getNodeName())) { 175 org.w3c.dom.NamedNodeMap codeValueEntryNodeAttributes = codeValueEntryNode.getAttributes(); 176 org.w3c.dom.Attr codeValueEntryNodeName = (org.w3c.dom.Attr )codeValueEntryNodeAttributes.getNamedItem("code"); 177 if( 178 (codeValueEntryNodeName != null) && 179 (lookupCode.equals(codeValueEntryNodeName.getValue())) 180 ) { 181 org.w3c.dom.NodeList attributeNodes = codeValueEntryNode.getChildNodes(); 182 for(int k = 0; k < attributeNodes.getLength(); k++) { 183 org.w3c.dom.Node attributeNode = attributeNodes.item(k); 184 if(attributeNode.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE) { 185 if(attributeNode.hasChildNodes()) { 186 codeEntry.put( 187 attributeNode.getNodeName(), 188 attributeNode.getFirstChild().getNodeValue() 189 ); 190 } 191 } 192 } 193 } 194 } 195 else { 196 System.out.println("WARNING: skipping node " + codeValueEntryNode.getNodeName()); 197 } 198 } 199 } 200 } 201 } 202 return codeEntry; 203 } 204 205 protected void split( 207 List locale, 208 File sourceDir, 209 File targetDir 210 ) throws ServiceException { 211 String en_US_Dir = targetDir.getAbsolutePath() + File.separatorChar + "en_US"; 212 System.out.println("sourceDir=" + sourceDir.getAbsolutePath()); 213 File [] en_US_files = new File (en_US_Dir).listFiles(); 214 if(en_US_files == null) { 215 System.out.println("ERROR: directory not found: " + en_US_Dir); 216 return; 217 } 218 219 for(int u = 0; u < en_US_files.length; u++) { 221 Map codes = ListOrderedMap.decorate(new HashMap ()); 223 XmlImporter importer = new XmlImporter( 224 codes, 225 false 226 ); 227 System.out.println("loading " + en_US_files[u]); 228 try { 229 importer.process( 230 new String []{en_US_files[u].getAbsolutePath()} 231 ); 232 } 233 catch(ServiceException e) { 234 e.log(); 235 System.out.println("STATUS: " + e.getMessage()); 236 } 237 catch(Exception e) { 238 new ServiceException(e).log(); 239 System.out.println("STATUS: " + e.getMessage()); 240 } 241 File file = new File (sourceDir.getAbsolutePath() + File.separatorChar + en_US_files[u].getName()); 242 try { 243 System.out.println("loading " + file.getAbsolutePath()); 244 org.w3c.dom.Document mergedCodes = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(file); 245 for(Iterator i = codes.values().iterator(); i.hasNext(); ) { 246 DataproviderObject code = (DataproviderObject)i.next(); 247 Map mergedCode = 248 this.lookupCode( 249 mergedCodes, 250 code.path().getParent().getParent().getBase(), 251 code.path().getBase() 252 ); 253 for(int j = 1; j < locale.size(); j++) { String shortText = (String )mergedCode.get(locale.get(j) + "_short"); 255 String longText = (String )mergedCode.get(locale.get(j) + "_long"); 256 code.values("shortText").add(shortText == null ? "" : shortText); 257 code.values("longText").add(longText == null ? "" : longText); 258 } 259 } 260 } 261 catch(ParserConfigurationException e) { 262 System.err.println("ParserConfigurationException: can not load file " + file.getAbsolutePath()); 263 } 264 catch(SAXException e) { 265 System.err.println("SAXException: can not load file " + file.getAbsolutePath()); 266 } 267 catch(IOException e) { 268 System.err.println("IOException: can not load file " + file.getAbsolutePath()); 269 } 270 271 for(int j = 1; j < locale.size(); j++) { String outFileName = targetDir.getAbsolutePath() + File.separatorChar + locale.get(j) + File.separatorChar + en_US_files[u].getName(); 274 try { 275 File outFile = new File (outFileName); 276 if(outFile.exists()) { 277 File renamed = new File (outFile.getParent() + File.separatorChar + ".#" + outFile.getName()); 278 if(!outFile.renameTo(renamed)) { 279 System.out.println("WARNING: can not move file " + outFile.getAbsolutePath() + " to " + renamed.getAbsolutePath() + ". Skipping"); 280 continue; 281 } 282 } 283 else if(!outFile.getParentFile().exists()) { 284 if(!outFile.getParentFile().mkdir()) { 285 System.out.println("WARNING: can not create directory " + outFile.getParentFile().getAbsolutePath() + ". Skipping"); 286 continue; 287 } 288 } 289 System.out.println("writing file " + outFileName); 290 Writer w = new OutputStreamWriter (new FileOutputStream (outFileName), "UTF-8"); 291 Writer fw = new XMLWriter(w); 292 String providerName ="CRX"; String segmentName = "Standard"; if(codes.size() > 0) { 295 DataproviderObject_1_0 obj = (DataproviderObject_1_0)codes.values().iterator().next(); 296 providerName = obj.path().get(2); 297 segmentName = obj.path().get(4); 298 } 299 String s = null; 300 s = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + 301 "<org.openmdx.base.Authority xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" name=\"org:opencrx:kernel:code1\" xsi:noNamespaceSchemaLocation=\"xri:+resource/org/opencrx/kernel/code1/xmi/code1.xsd\">\n" + 302 " <_object/>\n" + 303 " <_content>\n" + 304 " <provider>\n" + 305 " <org.openmdx.base.Provider qualifiedName=\"" + providerName + "\" _operation=\"null\">\n" + 306 " <_object/>\n" + 307 " <_content>\n" + 308 " <segment>\n" + 309 " <org.opencrx.kernel.code1.Segment qualifiedName=\"" + segmentName + "\" _operation=\"null\">\n" + 310 " <_object/>\n" + 311 " <_content>\n" + 312 " <valueContainer>\n"; 313 w.write(s, 0, s.length()); 314 boolean firstContainer = true; 315 for(Iterator i = codes.values().iterator(); i.hasNext(); ) { 316 DataproviderObject_1_0 element = (DataproviderObject_1_0)i.next(); 317 if("org:opencrx:kernel:code1:CodeValueContainer".equals(element.values(SystemAttributes.OBJECT_CLASS).get(0))) { 318 if(!firstContainer) { 319 s = " </entry>\n" + 320 " </_content>\n" + 321 " </org.opencrx.kernel.code1.CodeValueContainer>\n"; 322 w.write(s, 0, s.length()); 323 } 324 s = " <org.opencrx.kernel.code1.CodeValueContainer name=\"" + element.path().getBase() + "\" _operation=\"create\">\n" + 325 " <_object/>\n" + 326 " <_content>\n" + 327 " <entry>\n"; 328 w.write(s, 0, s.length()); 329 firstContainer = false; 330 } 331 else if("org:opencrx:kernel:code1:CodeValueEntry".equals(element.values(SystemAttributes.OBJECT_CLASS).get(0))) { 332 if( 334 ((element.values("shortText").size() > j) && (((String )element.values("shortText").get(j)).length() > 0)) || 335 ((element.values("longText").size() > j) && (((String )element.values("longText").get(j)).length() > 0)) 336 ) { 337 String shortText = element.values("shortText").size() > j 338 ? (String )element.values("shortText").get(j) 339 : ""; 340 String longText = element.values("longText").size() > j 341 ? (String )element.values("longText").get(j) 342 : ""; 343 s = " <org.opencrx.kernel.code1.CodeValueEntry code=\"" + element.path().getBase() + "\" _operation=\"create\">\n" + 344 " <_object>\n"; 345 w.write(s, 0, s.length()); 346 if(shortText.length() > 0) { 347 s = " <shortText>\n" + 348 " <_item>"; 349 w.write(s, 0, s.length()); 350 s = shortText; 351 fw.write(s, 0, s.length()); 352 s = "</_item>\n" + 353 " </shortText>\n"; 354 w.write(s, 0, s.length()); 355 } 356 if(longText.length() > 0) { 357 s = " <longText>\n" + 358 " <_item>"; 359 w.write(s, 0, s.length()); 360 s = longText; 361 fw.write(s, 0, s.length()); 362 s = "</_item>\n" + 363 " </longText>\n"; 364 w.write(s, 0, s.length()); 365 } 366 s = " </_object>\n" + 367 " <_content/>\n" + 368 " </org.opencrx.kernel.code1.CodeValueEntry>\n"; 369 w.write(s, 0, s.length()); 370 } 371 } 372 } 373 if(!firstContainer) { 374 s = " </entry>\n" + 375 " </_content>\n" + 376 " </org.opencrx.kernel.code1.CodeValueContainer>\n"; 377 w.write(s, 0, s.length()); 378 } 379 s = " </valueContainer>\n" + 380 " </_content>\n" + 381 " </org.opencrx.kernel.code1.Segment>\n" + 382 " </segment>\n" + 383 " </_content>\n" + 384 " </org.openmdx.base.Provider>\n" + 385 " </provider>\n" + 386 " </_content>\n" + 387 "</org.openmdx.base.Authority>\n"; 388 w.write(s, 0, s.length()); 389 w.close(); 390 } 391 catch(FileNotFoundException e) { 392 System.err.println("can not create file " + outFileName); 393 } 394 catch(UnsupportedEncodingException e) { 395 System.err.println("can not create file with encoding UTF-8 " + outFileName); 396 } 397 catch(IOException e) { 398 System.err.println("error writing to file " + outFileName); 399 } 400 } 401 } 402 } 403 404 protected void merge( 406 List locale, 407 File sourceDir, 408 File targetDir 409 ) throws ServiceException { 410 411 String en_US_Dir = sourceDir.getAbsolutePath() + File.separatorChar + "en_US"; 412 System.out.println("sourceDir=" + sourceDir.getAbsolutePath()); 413 File [] en_US_files = new File (en_US_Dir).listFiles(); 414 if(en_US_files == null) { 415 System.out.println("ERROR: directory not found: " + en_US_Dir); 416 return; 417 } 418 419 for(int u = 0; u < en_US_files.length; u++) { 421 422 Map mergedCodes = new TreeMap (); 424 Set codeValueContainers = new HashSet (); for(int i = 0; i < locale.size(); i++) { 426 427 File file = new File (sourceDir.getAbsolutePath() + File.separatorChar + locale.get(i) + File.separatorChar + en_US_files[u].getName()); 429 Map codes = new HashMap (); 430 if(file.exists()) { 431 XmlImporter importer = new XmlImporter( 432 codes, 433 false 434 ); 435 System.out.println("loading " + file); 436 try { 437 importer.process( 438 new String []{file.getAbsolutePath()} 439 ); 440 } 441 catch(ServiceException e) { 442 e.log(); 443 System.out.println("STATUS: " + e.getMessage()); 444 } 445 catch(Exception e) { 446 new ServiceException(e).log(); 447 System.out.println("STATUS: " + e.getMessage()); 448 } 449 } 450 451 Set keySet = i == 0 ? codes.keySet() : mergedCodes.keySet(); 453 try { 454 for(Iterator j = keySet.iterator(); j.hasNext(); ) { 455 Path key = (Path)j.next(); 456 if(mergedCodes.get(key) != null) { 458 DataproviderObject mergedCodeEntry = (DataproviderObject)mergedCodes.get(key); 459 if("org:opencrx:kernel:code1:CodeValueEntry".equals(mergedCodeEntry.values(SystemAttributes.OBJECT_CLASS).get(0))) { 460 DataproviderObject codeEntry = (DataproviderObject)codes.get(key); 461 if(mergedCodeEntry.getValues("shortText") != null) { 462 mergedCodeEntry.values("shortText").add( 463 (codeEntry != null) && (codeEntry.values("shortText").size() > 0) 464 ? codeEntry.values("shortText").get(0) 465 : "" ); 467 } 468 if(mergedCodeEntry.getValues("longText") != null) { 469 mergedCodeEntry.values("longText").add( 470 (codeEntry != null) && (codeEntry.values("longText").size() > 0) 471 ? codeEntry.values("longText").get(0) 472 : "" ); 474 } 475 } 476 } 477 else if(i == 0) { 479 DataproviderObject_1_0 entry = (DataproviderObject_1_0)codes.get(key); 480 if("org:opencrx:kernel:code1:CodeValueContainer".equals(entry.values(SystemAttributes.OBJECT_CLASS).get(0))) { 481 codeValueContainers.add(entry); 482 } 483 else { 484 mergedCodes.put( 485 key, 486 entry 487 ); 488 } 489 } 490 else { 493 System.err.println("entry " + key + " of locale " + locale.get(i) + " has no corresponding entry for locale " + locale.get(0) + ". Not loading"); 494 } 495 } 496 } 497 catch(Exception e) { 498 System.err.println("Can not import. Reason is " + e.getMessage()); 499 } 500 } 501 502 Map sortedCodes = new TreeMap (); 504 for(Iterator i = mergedCodes.entrySet().iterator(); i.hasNext(); ) { 505 Entry entry = (Entry)i.next(); 506 String codeKey = ((Path)entry.getKey()).getBase(); 507 try { 508 sortedCodes.put( 509 new Integer (codeKey), 510 entry.getValue() 511 ); 512 } 513 catch(NumberFormatException e) { 514 sortedCodes = mergedCodes; 515 break; 516 } 517 } 518 519 String outFileName = targetDir.getAbsolutePath() + File.separatorChar + en_US_files[u].getName(); 521 try { 522 File outFile = new File (outFileName); 524 if(outFile.exists()) { 525 File renamed = new File (outFile.getParent() + File.separatorChar + ".#" + outFile.getName()); 526 if(!outFile.renameTo(renamed)) { 527 System.out.println("WARNING: can not move file " + outFile.getAbsolutePath() + " to " + renamed.getAbsolutePath() + ". Skipping"); 528 continue; 529 } 530 } 531 else if(!outFile.getParentFile().exists()) { 532 if(!outFile.getParentFile().mkdir()) { 533 System.out.println("WARNING: can not create directory " + outFile.getParentFile().getAbsolutePath() + ". Skipping"); 534 continue; 535 } 536 } 537 System.out.println("writing file " + outFileName); 538 Writer w = new OutputStreamWriter (new FileOutputStream (outFileName), "UTF-8"); 539 Writer fw = new XMLWriter(w); 540 String s = null; 541 s = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"; 542 w.write(s, 0, s.length()); 543 s = "<CodeValueContainers>\n"; 544 w.write(s, 0, s.length()); 545 for(Iterator i = codeValueContainers.iterator(); i.hasNext(); ) { 546 DataproviderObject_1_0 codeValueContainer = (DataproviderObject_1_0)i.next(); 547 s = " <CodeValueContainer name=\"" + codeValueContainer.path().getBase() + "\">\n"; 548 w.write(s, 0, s.length()); 549 for(Iterator j = sortedCodes.values().iterator(); j.hasNext(); ) { 550 DataproviderObject_1_0 entry = (DataproviderObject_1_0)j.next(); 551 if(codeValueContainer.path().getBase().equals(entry.path().getParent().getParent().getBase())) { 552 s = " <CodeValueEntry code=\"" + entry.path().getBase() + "\">\n"; 553 w.write(s, 0, s.length()); 554 for(int k = 0; k < locale.size(); k++) { 555 s = " <" + locale.get(k) + "_short>"; 557 w.write(s, 0, s.length()); 558 s = (String )entry.values("shortText").get(k); 559 fw.write(s, 0, s.length()); 560 s = "</" + locale.get(k) + "_short>\n"; 561 w.write(s, 0, s.length()); 562 s = " <" + locale.get(k) + "_long>"; 564 w.write(s, 0, s.length()); 565 s = (String )entry.values("longText").get(k); 566 fw.write(s, 0, s.length()); 567 s = "</" + locale.get(k) + "_long>\n"; 568 w.write(s, 0, s.length()); 569 } 570 s = " </CodeValueEntry>\n"; 571 w.write(s, 0, s.length()); 572 } 573 } 574 s = " </CodeValueContainer>\n"; 575 w.write(s, 0, s.length()); 576 } 577 s = "</CodeValueContainers>\n"; 578 w.write(s, 0, s.length()); 579 w.close(); 580 } 581 catch(FileNotFoundException e) { 582 System.err.println("can not create file " + outFileName); 583 } 584 catch(UnsupportedEncodingException e) { 585 System.err.println("can not create file with encoding UTF-8 " + outFileName); 586 } 587 catch(IOException e) { 588 System.err.println("error writing to file " + outFileName); 589 } 590 } 591 } 592 593 protected void run( 595 ) throws Exception { 596 String command = "merge"; 597 if (getCmdLineArgs().hasArg("merge")) { 598 command = "merge"; 599 } 600 if (getCmdLineArgs().hasArg("split")) { 601 command = "split"; 602 } 603 if("merge".equals(command)){ 604 this.merge(locale, sourceDir, targetDir); 605 } 606 else if("split".equals(command)){ 607 this.split(locale, sourceDir, targetDir); 608 } 609 } 610 611 protected void release( 613 ) throws Exception { 614 System.out.println("shutdown"); 615 } 616 617 public static void main( 619 String [] args 620 ) { 621 ApplicationController controller = new ApplicationController(args); 622 controller.initLogging(LOG_CONFIG_NAME, LOG_SOURCE); 623 controller.registerApplication(new CodeUtility()); 624 controller.run(); 625 } 626 627 private static List createCmdLineOptions( 629 ) { 630 ArrayList options = new ArrayList (); 631 632 options.add( 634 new CmdLineOption( 635 "merge", 636 "Merge locale separated files to one merged file" 637 ) 638 ); 639 640 options.add( 642 new CmdLineOption( 643 "split", 644 "Split merged file into locale separated files" 645 ) 646 ); 647 648 options.add( 650 new CmdLineOption( 651 "sourceDir", 652 "directory containing the source files", 653 1, 654 1 655 ) 656 ); 657 options.add( 658 new CmdLineOption( 659 "targetDir", 660 "directory containing the target files", 661 1, 662 1 663 ) 664 ); 665 options.add( 667 new CmdLineOption( 668 "locale", 669 "list of locales to process", 670 0, 671 Integer.MAX_VALUE 672 ) 673 ); 674 return options; 675 } 676 677 681 private static final String VERSION = "$Revision: 1.4 $"; 683 684 private static final String APP_NAME = "CodeMapper"; 686 687 private static final String LOG_CONFIG_NAME = "CodeMapper"; 689 690 private static final String LOG_SOURCE = APP_NAME; 692 693 private static final String HELP_TEXT = "CodeMapper splits and merges code tables"; 695 696 private List locale = null; 698 private File sourceDir = null; 699 private File targetDir = null; 700 701 } 702 703
| Popular Tags
|