1 19 20 package org.netbeans.core.windows.persistence; 21 22 import java.util.logging.Level ; 23 import org.netbeans.core.windows.Debug; 24 import org.openide.filesystems.FileLock; 25 import org.openide.filesystems.FileObject; 26 import org.openide.filesystems.FileUtil; 27 import org.openide.modules.ModuleInfo; 28 import org.openide.modules.SpecificationVersion; 29 import org.openide.util.NbBundle; 30 import org.xml.sax.*; 31 import org.xml.sax.helpers.DefaultHandler ; 32 33 import java.io.*; 34 import java.util.*; 35 import java.util.logging.Logger ; 36 37 42 43 class GroupParser { 44 45 public static final String INSTANCE_DTD_ID_2_0 46 = "-//NetBeans//DTD Group Properties 2.0//EN"; 48 private static final boolean DEBUG = Debug.isLoggable(GroupParser.class); 49 50 51 private FileObject moduleParentFolder; 52 53 54 private FileObject localParentFolder; 55 56 private InternalConfig internalConfig; 57 58 private Map<String , TCGroupParser> tcGroupParserMap = new HashMap<String , TCGroupParser>(19); 59 60 61 private String groupName; 62 63 64 private boolean inModuleFolder; 65 66 private boolean inLocalFolder; 67 68 public GroupParser(String name) { 69 this.groupName = name; 70 } 71 72 73 GroupConfig load () throws IOException { 74 GroupConfig sc = new GroupConfig(); 77 readProperties(sc); 78 readTCGroups(sc); 79 return sc; 82 } 83 84 85 void save (GroupConfig sc) throws IOException { 86 writeProperties(sc); 88 writeTCGroups(sc); 89 } 91 92 private void readProperties (GroupConfig sc) throws IOException { 93 if (DEBUG) Debug.log(GroupParser.class, "readProperties ENTER" + " group:" + getName()); 94 PropertyHandler propertyHandler = new PropertyHandler(); 95 InternalConfig internalCfg = getInternalConfig(); 96 internalCfg.clear(); 97 propertyHandler.readData(sc, internalCfg); 98 99 103 if (DEBUG) Debug.log(GroupParser.class, "readProperties LEAVE" + " group:" + getName()); 104 } 105 106 private void readTCGroups (GroupConfig sc) throws IOException { 107 if (DEBUG) Debug.log(GroupParser.class, "readTCGroups ENTER" + " group:" + getName()); 108 109 for (Iterator it = tcGroupParserMap.keySet().iterator(); it.hasNext(); ) { 110 TCGroupParser tcGroupParser = (TCGroupParser) tcGroupParserMap.get(it.next()); 111 tcGroupParser.setInModuleFolder(false); 112 tcGroupParser.setInLocalFolder(false); 113 } 114 115 119 120 if (isInModuleFolder()) { 121 FileObject moduleGroupFolder = moduleParentFolder.getFileObject(groupName); 122 if (moduleGroupFolder != null) { 123 FileObject [] files = moduleGroupFolder.getChildren(); 124 for (int i = 0; i < files.length; i++) { 125 if (!files[i].isFolder() && PersistenceManager.TCGROUP_EXT.equals(files[i].getExt())) { 127 TCGroupParser tcGroupParser = (TCGroupParser) tcGroupParserMap.get(files[i].getName()); 129 if (tcGroupParser == null) { 130 tcGroupParser = new TCGroupParser(files[i].getName()); 131 tcGroupParserMap.put(files[i].getName(), tcGroupParser); 132 } 133 tcGroupParser.setInModuleFolder(true); 134 tcGroupParser.setModuleParentFolder(moduleGroupFolder); 135 } 136 } 137 } 138 } 139 140 if (isInLocalFolder()) { 141 FileObject localGroupFolder = localParentFolder.getFileObject(groupName); 142 if (localGroupFolder != null) { 143 FileObject [] files = localGroupFolder.getChildren(); 144 for (int i = 0; i < files.length; i++) { 145 if (!files[i].isFolder() && PersistenceManager.TCGROUP_EXT.equals(files[i].getExt())) { 147 TCGroupParser tcGroupParser; 149 if (tcGroupParserMap.containsKey(files[i].getName())) { 150 tcGroupParser = (TCGroupParser) tcGroupParserMap.get(files[i].getName()); 151 } else { 152 tcGroupParser = new TCGroupParser(files[i].getName()); 153 tcGroupParserMap.put(files[i].getName(), tcGroupParser); 154 } 155 tcGroupParser.setInLocalFolder(true); 156 tcGroupParser.setLocalParentFolder(localGroupFolder); 157 } 158 } 159 } 160 } 161 162 168 169 List<TCGroupConfig> tcGroupCfgList = new ArrayList<TCGroupConfig>(tcGroupParserMap.size()); 172 List<TCGroupParser> toRemove = new ArrayList<TCGroupParser>(tcGroupParserMap.size()); 173 for (Iterator it = tcGroupParserMap.keySet().iterator(); it.hasNext(); ) { 174 TCGroupParser tcGroupParser = (TCGroupParser) tcGroupParserMap.get(it.next()); 175 TCGroupConfig tcGroupCfg; 176 try { 177 tcGroupCfg = tcGroupParser.load(); 178 } catch (IOException exc) { 179 toRemove.add(tcGroupParser); 183 deleteLocalTCGroup(tcGroupParser.getName()); 184 Logger.getLogger(GroupParser.class.getName()).log(Level.WARNING, null, exc); 185 continue; 186 } 187 boolean tcGroupAccepted = acceptTCGroup(tcGroupParser, tcGroupCfg); 188 if (tcGroupAccepted) { 189 tcGroupCfgList.add(tcGroupCfg); 190 } else { 191 toRemove.add(tcGroupParser); 192 deleteLocalTCGroup(tcGroupParser.getName()); 193 } 194 } 195 for (int i = 0; i < toRemove.size(); i++) { 196 TCGroupParser tcGroupParser = (TCGroupParser) toRemove.get(i); 197 tcGroupParserMap.remove(tcGroupParser.getName()); 198 } 199 200 sc.tcGroupConfigs = (TCGroupConfig []) 201 tcGroupCfgList.toArray(new TCGroupConfig[tcGroupCfgList.size()]); 204 205 PersistenceManager pm = PersistenceManager.getDefault(); 206 for (int i = 0; i < sc.tcGroupConfigs.length; i++) { 207 pm.addUsedTCId(sc.tcGroupConfigs[i].tc_id); 208 } 209 210 if (DEBUG) Debug.log(GroupParser.class, "readTCGroups LEAVE" + " group:" + getName()); 211 } 212 213 216 private boolean acceptTCGroup (TCGroupParser tcGroupParser, TCGroupConfig config) { 217 InternalConfig cfg = tcGroupParser.getInternalConfig(); 218 if (cfg.moduleCodeNameBase != null) { 220 ModuleInfo curModuleInfo = PersistenceManager.findModule 221 (cfg.moduleCodeNameBase, cfg.moduleCodeNameRelease, 222 cfg.moduleSpecificationVersion); 223 if (curModuleInfo == null) { 224 PersistenceManager.LOG.fine("Cannot find module \'" + 225 cfg.moduleCodeNameBase + " " + cfg.moduleCodeNameRelease + " " + 226 cfg.moduleSpecificationVersion + "\' for tcgrp with name \'" + config.tc_id + "\'"); } 228 if ((curModuleInfo != null) && curModuleInfo.isEnabled()) { 229 return true; 231 } else { 232 return false; 235 } 236 } else { 237 return true; 239 } 240 } 241 242 private void writeProperties (GroupConfig sc) throws IOException { 243 if (DEBUG) Debug.log(GroupParser.class, "writeProperties ENTER" + " group:" + getName()); 244 PropertyHandler propertyHandler = new PropertyHandler(); 245 InternalConfig internalCfg = getInternalConfig(); 246 propertyHandler.writeData(sc, internalCfg); 247 if (DEBUG) Debug.log(GroupParser.class, "writeProperties LEAVE" + " group:" + getName()); 248 } 249 250 private void writeTCGroups (GroupConfig sc) throws IOException { 251 if (DEBUG) Debug.log(GroupParser.class, "writeTCGroups ENTER" + " group:" + getName()); 252 Map<String , TCGroupConfig> tcGroupConfigMap = new HashMap<String , TCGroupConfig>(19); 254 for (int i = 0; i < sc.tcGroupConfigs.length; i++) { 255 tcGroupConfigMap.put(sc.tcGroupConfigs[i].tc_id, sc.tcGroupConfigs[i]); 256 } 257 List<String > toDelete = new ArrayList<String >(10); 258 for (String s: tcGroupParserMap.keySet()) { 259 TCGroupParser tcGroupParser = tcGroupParserMap.get(s); 260 if (!tcGroupConfigMap.containsKey(tcGroupParser.getName())) { 261 toDelete.add(tcGroupParser.getName()); 262 } 263 } 264 for (int i = 0; i < toDelete.size(); i++) { 265 267 tcGroupParserMap.remove(toDelete.get(i)); 268 270 deleteLocalTCGroup(toDelete.get(i)); 271 } 272 273 for (int i = 0; i < sc.tcGroupConfigs.length; i++) { 275 if (!tcGroupParserMap.containsKey(sc.tcGroupConfigs[i].tc_id)) { 276 TCGroupParser tcGroupParser = new TCGroupParser(sc.tcGroupConfigs[i].tc_id); 277 tcGroupParserMap.put(sc.tcGroupConfigs[i].tc_id, tcGroupParser); 278 } 279 } 280 281 FileObject localFolder = localParentFolder.getFileObject(getName()); 283 if ((localFolder == null) && (tcGroupParserMap.size() > 0)) { 284 localFolder = FileUtil.createFolder(localParentFolder, getName()); 287 } 288 290 for (Iterator it = tcGroupParserMap.keySet().iterator(); it.hasNext(); ) { 291 TCGroupParser tcGroupParser = (TCGroupParser) tcGroupParserMap.get(it.next()); 292 tcGroupParser.setLocalParentFolder(localFolder); 293 tcGroupParser.setInLocalFolder(true); 294 tcGroupParser.save((TCGroupConfig) tcGroupConfigMap.get(tcGroupParser.getName())); 295 } 296 297 if (DEBUG) Debug.log(GroupParser.class, "writeTCGroups LEAVE" + " group:" + getName()); 298 } 299 300 private void deleteLocalTCGroup (String tcGroupName) { 301 if (DEBUG) Debug.log(GroupParser.class, "deleteLocalTCGroup" + " group:" + tcGroupName); 302 if (localParentFolder == null) { 303 return; 304 } 305 FileObject localGroupFolder = localParentFolder.getFileObject(groupName); 306 if (localGroupFolder == null) { 307 return; 308 } 309 FileObject tcGroupFO = localGroupFolder.getFileObject(tcGroupName, PersistenceManager.TCGROUP_EXT); 310 if (tcGroupFO != null) { 311 PersistenceManager.deleteOneFO(tcGroupFO); 312 } 313 } 314 315 318 void removeTCGroup (String tcGroupName) { 319 tcGroupParserMap.remove(tcGroupName); 321 deleteLocalTCGroup(tcGroupName); 322 } 323 324 327 TCGroupConfig addTCGroup (String tcGroupName) { 328 TCGroupParser tcGroupParser = (TCGroupParser) tcGroupParserMap.get(tcGroupName); 331 if (tcGroupParser != null) { 332 PersistenceManager.LOG.log(Level.WARNING, 333 "[WinSys.GroupParser.addTCGroup]" + " Warning: GroupParser " + getName() + ". TCGroupParser " + tcGroupName + " exists but it should not."); tcGroupParserMap.remove(tcGroupName); 337 } 338 tcGroupParser = new TCGroupParser(tcGroupName); 339 FileObject moduleFolder = moduleParentFolder.getFileObject(groupName); 340 tcGroupParser.setModuleParentFolder(moduleFolder); 341 tcGroupParser.setInModuleFolder(true); 342 tcGroupParserMap.put(tcGroupName, tcGroupParser); 343 TCGroupConfig tcGroupConfig = null; 344 try { 345 tcGroupConfig = tcGroupParser.load(); 346 } catch (IOException exc) { 347 PersistenceManager.LOG.log(Level.WARNING, 348 "[WinSys.GroupParser.addTCGroup]" + " Warning: GroupParser " + getName() + ". Cannot load tcGroup " + tcGroupName, exc); } 351 return tcGroupConfig; 352 } 353 354 357 InternalConfig getInternalConfig () { 358 if (internalConfig == null) { 359 internalConfig = new InternalConfig(); 360 } 361 return internalConfig; 362 } 363 364 void setModuleParentFolder (FileObject moduleParentFolder) { 365 this.moduleParentFolder = moduleParentFolder; 366 } 367 368 void setLocalParentFolder (FileObject localParentFolder) { 369 this.localParentFolder = localParentFolder; 370 } 371 372 String getName () { 373 return groupName; 374 } 375 376 boolean isInModuleFolder () { 377 return inModuleFolder; 378 } 379 380 void setInModuleFolder (boolean inModuleFolder) { 381 this.inModuleFolder = inModuleFolder; 382 } 383 384 boolean isInLocalFolder () { 385 return inLocalFolder; 386 } 387 388 void setInLocalFolder (boolean inLocalFolder) { 389 this.inLocalFolder = inLocalFolder; 390 } 391 392 private final class PropertyHandler extends DefaultHandler { 393 394 395 private GroupConfig groupConfig = null; 396 397 398 private InternalConfig internalConfig = null; 399 400 401 private final Object RW_LOCK = new Object (); 402 403 public PropertyHandler () { 404 } 405 406 private FileObject getConfigFOInput () { 407 FileObject groupConfigFO; 408 if (isInLocalFolder()) { 409 groupConfigFO = localParentFolder.getFileObject 411 (GroupParser.this.getName(), PersistenceManager.GROUP_EXT); 412 } else if (isInModuleFolder()) { 413 groupConfigFO = moduleParentFolder.getFileObject 415 (GroupParser.this.getName(), PersistenceManager.GROUP_EXT); 416 } else { 417 groupConfigFO = null; 419 } 420 return groupConfigFO; 422 } 423 424 private FileObject getConfigFOOutput () throws IOException { 425 FileObject groupConfigFO; 426 groupConfigFO = localParentFolder.getFileObject 427 (GroupParser.this.getName(), PersistenceManager.GROUP_EXT); 428 if (groupConfigFO != null) { 429 return groupConfigFO; 431 } else { 432 StringBuffer buffer = new StringBuffer (); 433 buffer.append(GroupParser.this.getName()); 434 buffer.append('.'); 435 buffer.append(PersistenceManager.GROUP_EXT); 436 groupConfigFO = FileUtil.createData(localParentFolder, buffer.toString()); 438 440 return groupConfigFO; 441 } 442 } 443 444 448 void readData (GroupConfig groupCfg, InternalConfig internalCfg) 449 throws IOException { 450 groupConfig = groupCfg; 451 internalConfig = internalCfg; 452 453 FileObject cfgFOInput = getConfigFOInput(); 454 if (cfgFOInput == null) { 455 throw new FileNotFoundException("[WinSys] Missing Group configuration file:" + GroupParser.this.getName()); 457 } 458 InputStream is = null; 459 try { 460 synchronized (RW_LOCK) { 461 468 is = cfgFOInput.getInputStream(); 470 PersistenceManager.getDefault().getXMLParser(this).parse(new InputSource(is)); 471 } 472 } catch (SAXException exc) { 473 String msg = NbBundle.getMessage(GroupParser.class, 475 "EXC_GroupParse", cfgFOInput); 476 477 throw (IOException) new IOException(msg).initCause(exc); 478 } finally { 479 try { 480 if (is != null) { 481 is.close(); 482 } 483 } catch (IOException exc) { 484 Logger.getLogger(GroupParser.class.getName()).log(Level.WARNING, null, exc); 485 } 486 } 487 488 groupCfg = groupConfig; 489 internalCfg = internalConfig; 490 491 groupConfig = null; 492 internalConfig = null; 493 } 494 495 public void startElement (String nameSpace, String name, String qname, Attributes attrs) throws SAXException { 496 if ("group".equals(qname)) { handleGroup(attrs); 498 } else if (internalConfig.specVersion.compareTo(new SpecificationVersion("2.0")) == 0) { if ("module".equals(qname)) { handleModule(attrs); 502 } else if ("name".equals(qname)) { handleName(attrs); 504 } else if ("state".equals(qname)) { handleState(attrs); 506 } 507 } else { 508 if (DEBUG) Debug.log(GroupParser.class, "-- GroupParser.startElement PARSING OLD"); 509 } 511 } 512 513 public void error(SAXParseException ex) throws SAXException { 514 throw ex; 515 } 516 517 518 private void handleGroup (Attributes attrs) { 519 String version = attrs.getValue("version"); if (version != null) { 521 internalConfig.specVersion = new SpecificationVersion(version); 522 } else { 523 PersistenceManager.LOG.log(Level.WARNING, 524 "[WinSys.GroupParser.handleGroup]" + " Warning: Missing attribute \"version\" of element \"group\"."); internalConfig.specVersion = new SpecificationVersion("2.0"); } 528 } 529 530 531 private void handleModule (Attributes attrs) { 532 String moduleCodeName = attrs.getValue("name"); internalConfig.moduleCodeNameBase = null; 535 internalConfig.moduleCodeNameRelease = null; 536 internalConfig.moduleSpecificationVersion = null; 537 if (moduleCodeName != null) { 538 int i = moduleCodeName.indexOf('/'); 539 if (i != -1) { 540 internalConfig.moduleCodeNameBase = moduleCodeName.substring(0, i); 541 internalConfig.moduleCodeNameRelease = moduleCodeName.substring(i + 1); 542 checkReleaseCode(internalConfig); 543 } else { 544 internalConfig.moduleCodeNameBase = moduleCodeName; 545 } 546 internalConfig.moduleSpecificationVersion = attrs.getValue("spec"); } 548 } 549 550 552 private void checkReleaseCode (InternalConfig internalConfig) { 553 if("null".equals(internalConfig.moduleCodeNameRelease)) { Logger.getLogger(GroupParser.class.getName()).log(Level.WARNING, null, 557 new IllegalStateException ("Module release code was saved as null string" + 558 " for module " + 559 internalConfig.moduleCodeNameBase + 560 "! Repairing.")); 561 internalConfig.moduleCodeNameRelease = null; 562 } 563 } 564 565 566 private void handleName (Attributes attrs) throws SAXException { 567 String name = attrs.getValue("unique"); if (name != null) { 569 groupConfig.name = name; 570 if (!name.equals(GroupParser.this.getName())) { 571 PersistenceManager.LOG.log(Level.WARNING, 572 "[WinSys.GroupParser.handleName]" + " Error: Value of attribute \"unique\" of element \"name\"" + " and configuration file name must be the same."); throw new SAXException("Invalid attribute value"); } 577 } else { 578 PersistenceManager.LOG.log(Level.WARNING, 579 "[WinSys.GroupParser.handleName]" + " Error: Missing required attribute \"unique\" of element \"name\"."); throw new SAXException("Missing required attribute"); } 583 } 584 585 586 private void handleState (Attributes attrs) throws SAXException { 587 String opened = attrs.getValue("opened"); if (opened != null) { 589 if ("true".equals(opened)) { groupConfig.opened = true; 591 } else if ("false".equals(opened)) { groupConfig.opened = false; 593 } else { 594 PersistenceManager.LOG.log(Level.WARNING, 595 "[WinSys.GroupParser.handleState]" + " Warning: Invalid value of attribute \"opened\" of element \"state\"."); groupConfig.opened = false; 598 } 599 } else { 600 PersistenceManager.LOG.log(Level.WARNING, 601 "[WinSys.GroupParser.handleState]" + " Error: Missing required attribute \"opened\" of element \"state\"."); groupConfig.opened = false; 604 } 605 } 606 607 608 void writeData (GroupConfig sc, InternalConfig ic) throws IOException { 609 final StringBuffer buff = fillBuffer(sc, ic); 610 synchronized (RW_LOCK) { 611 FileObject cfgFOOutput = getConfigFOOutput(); 612 FileLock lock = null; 613 OutputStream os = null; 614 OutputStreamWriter osw = null; 615 try { 616 lock = cfgFOOutput.lock(); 617 os = cfgFOOutput.getOutputStream(lock); 618 osw = new OutputStreamWriter(os, "UTF-8"); osw.write(buff.toString()); 620 } finally { 623 try { 624 if (osw != null) { 625 osw.close(); 626 } 627 } catch (IOException exc) { 628 Logger.getLogger(GroupParser.class.getName()).log(Level.WARNING, null, exc); 629 } 630 if (lock != null) { 631 lock.releaseLock(); 632 } 633 } 634 } 635 } 636 637 639 private StringBuffer fillBuffer (GroupConfig gc, InternalConfig ic) throws IOException { 640 StringBuffer buff = new StringBuffer (800); 641 buff.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n"); 646 buff.append("<group version=\"2.0\">\n"); 648 appendModule(ic, buff); 649 appendName(gc, buff); 650 appendState(gc, buff); 651 652 buff.append("</group>\n"); return buff; 654 } 655 656 private void appendModule (InternalConfig ic, StringBuffer buff) { 657 if (ic == null) { 658 return; 659 } 660 if (ic.moduleCodeNameBase != null) { 661 buff.append(" <module"); buff.append(" name=\""); buff.append(ic.moduleCodeNameBase); 664 if (ic.moduleCodeNameRelease != null) { 665 buff.append("/" + ic.moduleCodeNameRelease); } 667 if (ic.moduleSpecificationVersion != null) { 668 buff.append("\" spec=\""); buff.append(ic.moduleSpecificationVersion); 670 } 671 buff.append("\" />\n"); } 673 } 674 675 private void appendName (GroupConfig gc, StringBuffer buff) { 676 buff.append(" <name"); buff.append(" unique=\""); buff.append(gc.name); 679 buff.append("\""); buff.append(" />\n"); } 682 683 private void appendState (GroupConfig gc, StringBuffer buff) { 684 buff.append(" <state"); buff.append(" opened=\""); if (gc.opened) { 687 buff.append("true"); } else { 689 buff.append("false"); } 691 buff.append("\""); buff.append(" />\n"); } 694 695 697 public InputSource resolveEntity (String publicId, String systemId) 698 throws SAXException { 699 if (INSTANCE_DTD_ID_2_0.equals(publicId)) { 700 InputStream is = new ByteArrayInputStream(new byte[0]); 701 return new InputSource(is); 706 } 707 return null; } 709 } 710 711 } 712 713 | Popular Tags |