1 19 20 28 29 package org.netbeans.modules.xml.retriever.catalog.impl; 30 31 import java.io.File ; 32 import java.io.FileInputStream ; 33 import java.io.FileNotFoundException ; 34 import java.io.IOException ; 35 import java.io.Reader ; 36 import java.net.MalformedURLException ; 37 import java.net.URI ; 38 import java.net.URISyntaxException ; 39 import java.util.ArrayList ; 40 import java.util.Collection ; 41 import java.util.List ; 42 import java.util.logging.Level ; 43 import java.util.logging.Logger ; 44 import javax.xml.parsers.DocumentBuilderFactory ; 45 import javax.xml.parsers.ParserConfigurationException ; 46 import org.apache.xml.resolver.Catalog; 47 import org.apache.xml.resolver.CatalogManager; 48 import org.apache.xml.resolver.helpers.Debug; 49 import org.apache.xml.resolver.tools.CatalogResolver; 50 import org.netbeans.api.project.FileOwnerQuery; 51 import org.netbeans.api.project.Project; 52 import org.netbeans.modules.xml.retriever.XMLCatalogProvider; 53 import org.netbeans.modules.xml.retriever.catalog.Utilities; 54 import org.netbeans.modules.xml.xam.locator.CatalogModel; 55 import org.netbeans.modules.xml.xam.locator.CatalogModelException; 56 import org.netbeans.modules.xml.retriever.catalog.CatalogWriteModel; 57 import org.netbeans.modules.xml.retriever.catalog.CatalogWriteModelFactory; 58 import org.netbeans.modules.xml.retriever.catalog.ProjectCatalogSupport; 59 import org.netbeans.modules.xml.xam.ModelSource; 60 import org.netbeans.spi.xml.cookies.DataObjectAdapters; 61 import org.openide.filesystems.FileObject; 62 import org.openide.filesystems.FileUtil; 63 import org.openide.loaders.DataObject; 64 import org.openide.loaders.DataObjectNotFoundException; 65 import org.openide.util.Lookup; 66 import org.w3c.dom.DOMImplementation ; 67 import org.w3c.dom.ls.DOMImplementationLS ; 68 import org.w3c.dom.ls.LSInput ; 69 import org.xml.sax.InputSource ; 70 import org.xml.sax.SAXException ; 71 72 76 public class CatalogModelImpl implements CatalogModel { 77 protected FileObject catalogFileObject = null; 78 private static final Logger logger = Utilities.getLogger(); 79 80 public CatalogModelImpl(Project myProject) throws IOException { 81 assert(myProject != null); 82 this.catalogFileObject = Utilities.getProjectCatalogFileObject(myProject); 83 } 84 85 86 87 public CatalogModelImpl(FileObject catalogFileObject) throws IOException { 88 assert(catalogFileObject != null); 89 this.catalogFileObject = catalogFileObject; 90 } 91 92 93 public CatalogModelImpl(){ 94 } 95 96 97 100 public CatalogModelImpl(File tempFolder) throws IOException { 101 tempFolder = FileUtil.normalizeFile(tempFolder); 102 FileObject fo = FileUtil.toFileObject(tempFolder); 103 String fileName = CatalogWriteModel.PUBLIC_CATALOG_FILE_NAME+ 104 CatalogWriteModel.CATALOG_FILE_EXTENSION; 105 this.catalogFileObject = FileUtil.createData(fo, fileName); 106 } 107 108 public synchronized ModelSource getModelSource(URI locationURI, 109 ModelSource modelSourceOfSourceDocument) throws CatalogModelException { 110 logger.entering("CatalogModelImpl", "getModelSource", locationURI); 111 Exception exn = null; 112 ModelSource result = null; 113 useSuitableCatalogFile(modelSourceOfSourceDocument); 115 if(isOrphan()) 116 return tryOrphanResolution(locationURI, modelSourceOfSourceDocument); 117 File absResourceFile = null; 118 FileObject fob = null; 119 if(modelSourceOfSourceDocument != null) 120 fob = (FileObject) modelSourceOfSourceDocument.getLookup().lookup(FileObject.class); 121 try { 122 absResourceFile = resolveUsingCatalog(locationURI, fob); 124 } catch (IOException ex) { 125 exn = ex; 126 } catch(CatalogModelException ex){ 127 exn = ex; 128 } 129 if( (absResourceFile == null) || (exn != null) ){ 130 132 ModelSource rms = getModelSourceFromSystemWideCatalog(locationURI, modelSourceOfSourceDocument); 134 if(rms != null) 135 return rms; 136 try { 137 absResourceFile = retrieveCacheAndLookup(locationURI, fob); 139 } catch (IOException ex) { 140 throw new CatalogModelException(ex); 141 } 142 } 143 if(absResourceFile != null){ 144 logger.finer("Found abs file res:"+absResourceFile); 145 File normalizedFile = org.openide.filesystems.FileUtil.normalizeFile(absResourceFile); 146 FileObject thisFileObj = org.openide.filesystems.FileUtil.toFileObject(normalizedFile); 147 boolean editable = isEditable(absResourceFile); 148 result = createModelSource(thisFileObj, editable); 149 }else if(exn!= null) { 150 throw new CatalogModelException(exn); 151 } 152 logger.exiting("CatalogModelImpl", "getModelSource", result); 153 return result; 154 } 155 156 private void useSuitableCatalogFile(ModelSource modelSourceOfSourceDocument) { 157 if(modelSourceOfSourceDocument != null){ 160 FileObject msfo = (FileObject) modelSourceOfSourceDocument.getLookup(). 161 lookup(FileObject.class); 162 if(msfo == null) 163 return; 164 Project prj = FileOwnerQuery.getOwner(msfo); 165 if(prj == null) 166 return; 167 XMLCatalogProvider catPovider = (XMLCatalogProvider) prj.getLookup(). 168 lookup(XMLCatalogProvider.class); 169 if(catPovider == null) 170 return; 171 URI caturi = catPovider.getCatalog(msfo); 172 if(caturi == null) 173 return; 174 URI prjuri = FileUtil.toFile(prj.getProjectDirectory()).toURI(); 175 URI catFileURI = prjuri.resolve(caturi); 176 if(catFileURI == null) 177 return; 178 File catFile = new File (catFileURI); 179 if(!catFile.isFile()){ 180 try { 181 catFile.createNewFile(); 182 } catch (IOException ex) { 183 return; 184 } 185 } 186 FileObject catFO = FileUtil.toFileObject(FileUtil.normalizeFile(catFile)); 187 if(catFO == null) 188 return; 189 this.catalogFileObject = catFO; 191 } 192 } 193 194 195 public ModelSource getModelSource(URI locationURI) throws CatalogModelException{ 196 if(isOrphan()){ 197 return tryOrphanResolution(locationURI, null); 200 } 201 return getModelSource(locationURI, null); 203 } 204 205 206 211 protected ModelSource createModelSource(final FileObject thisFileObj, boolean editable) throws CatalogModelException{ 212 final ModelSource ms = Utilities.getModelSource(thisFileObj,editable); 213 return ms; 214 } 215 216 217 protected CatalogModel createCatalogModel(FileObject fo) throws CatalogModelException{ 218 return new CatalogModelFactoryImpl().getCatalogModel(fo); 219 } 220 221 222 private ModelSource tryOrphanResolution(URI locationURI, ModelSource modelSource){ 223 logger.entering("CatalogModelImpl", "getModelSource", locationURI); 224 if(catalogFileObject == null){ 225 try{ 226 if(locationURI.isAbsolute()){ 227 File file = new File (locationURI); 229 if(file.isFile()){ 230 file = FileUtil.normalizeFile(file); 231 FileObject fo = FileUtil.toFileObject(file); 232 return createModelSource(fo, isEditable(file)); 233 } 234 } else { 235 if(modelSource != null){ 237 FileObject fo = (FileObject) modelSource.getLookup().lookup(FileObject.class); 239 File file = resolveRelativeURI(locationURI, fo); 240 if(file != null){ 241 file = FileUtil.normalizeFile(file); 242 FileObject fobj = FileUtil.toFileObject(file); 243 return createModelSource(fobj, isEditable(file)); 244 } 245 } 246 } 247 }catch (Exception e){ 248 return null; 249 } 250 } 251 return null; 252 } 253 254 255 private boolean isOrphan(){ 256 if(catalogFileObject == null) 257 return true; 258 return false; 259 } 260 261 262 protected File resolveUsingCatalog(URI locationURI, FileObject sourceFileObject 263 ) throws CatalogModelException, IOException { 264 logger.entering("CatalogModelImpl", "resolveUsingCatalog", locationURI); 265 if(locationURI == null) 266 return null; 267 File result = null; 268 result = resolveUsingPublicCatalog(locationURI); 269 if(result != null) 270 return result; 271 if(sourceFileObject != null){ 272 result = resolveRelativeURI(locationURI, sourceFileObject); 273 } 274 if(result != null) 275 return result; 276 if( (locationURI.isAbsolute()) && locationURI.getScheme().equalsIgnoreCase("file")){ 277 result = new File (locationURI); 279 if(result.isFile()){ 280 logger.exiting("CatalogModelImpl", "resolveUsingCatalog",result); 281 return result; 282 } else 283 throw new FileNotFoundException (locationURI.toString()+": is absolute but "+result.getAbsolutePath()+" Not Found."); 284 } 285 throw new CatalogModelException(locationURI.toString()+" : Entry is not a relative or absolute and catalog entry not found"); 286 } 287 288 289 private File retrieveCacheAndLookup(URI locationURI, FileObject sourceFileObject) throws IOException , CatalogModelException{ 290 File result = null; 291 if((locationURI.isAbsolute()) && locationURI.getScheme().toLowerCase(). 292 startsWith("http") && !CatalogFileWrapperDOMImpl.TEST_ENVIRONMENT){ 293 boolean res = false; 297 try{ 298 res = Utilities.retrieveAndCache(locationURI, sourceFileObject); 299 }catch (Exception e){ } 301 if(res){ 302 result = resolveUsingPublicCatalog(locationURI); 304 if(result != null) 305 return result; 306 } 307 } 308 return result; 309 } 310 311 protected File resolveUsingPublicCatalog(URI locationURI) throws IOException , CatalogModelException{ 312 File result = null; 313 if(catalogFileObject != null){ 314 File publicCatalogFile = FileUtil.toFile(catalogFileObject); 316 if(publicCatalogFile.isFile()){ 317 if(publicCatalogFile.length() < 20) 319 return null; 320 URI strRes = resolveUsingApacheCatalog(publicCatalogFile, locationURI.toString()); 321 if(strRes != null){ 322 if(strRes.isAbsolute()){ 323 if(strRes.getScheme().equalsIgnoreCase("file")){ 324 result = new File (strRes); 325 if(result.isFile()){ 326 logger.exiting("CatalogModelImpl", "resolveUsingCatalog",result); 327 return result; 328 } else 329 throw new FileNotFoundException (result.getAbsolutePath()+" Not Found."); 330 }else{ 331 throw new CatalogModelException("Catalog contains non-file URI. Catalog Maps URI to a local file only."); 332 } 333 } 334 } 335 } 336 } 337 return null; 338 } 339 340 341 protected File resolveRelativeURI(URI locationURI, FileObject sourceFileObject) throws CatalogModelException, FileNotFoundException { 342 File result = null; 343 if(!locationURI.isAbsolute()){ 344 if(sourceFileObject == null) 346 throw new CatalogModelException(locationURI.toString()+" : Entry is relative but base file now known. Pass base file to the factory"); 347 URI sourceFileObjectURI = FileUtil.toFile(sourceFileObject).toURI(); 348 URI resultURI = sourceFileObjectURI.resolve(locationURI); 349 try{ 350 result = new File (resultURI); 351 } catch(Exception e){ 352 throw new CatalogModelException(locationURI.toString()+" : Entry is relative but resolved entry is not absolute"); 353 } 354 if(result.isFile()){ 355 logger.exiting("CatalogModelImpl", "resolveUsingCatalog",result); 356 return result; 357 } else 358 throw new FileNotFoundException (result.getAbsolutePath()+" Not Found."); 359 } 360 return null; 361 } 362 363 364 protected URI resolveUsingApacheCatalog(File catalogFile, String locationURI) throws IOException , CatalogModelException{ 365 List <File > catalogFileList = new ArrayList <File >(); 366 catalogFileList.add(catalogFile); 367 return resolveUsingApacheCatalog(catalogFileList, locationURI); 368 } 369 370 371 CatalogResolver catalogResolver; 372 Catalog apacheCatalogResolverObj; 373 protected URI resolveUsingApacheCatalog(List <File > catalogFileList, String locationURI) throws CatalogModelException, IOException { 374 if((logger.getLevel() != null) && (logger.getLevel().intValue() <= Level.FINER.intValue())){ 375 Debug debug = CatalogManager.getStaticManager().debug; 376 debug.setDebug(logger.getLevel().intValue()); 377 } 378 382 if(reparseRequired(catalogFileList)){ 384 CatalogManager manager = new CatalogManager(null); 385 manager.setUseStaticCatalog(false); 386 manager.setPreferPublic(false); 387 catalogResolver = new CatalogResolver(manager); 388 apacheCatalogResolverObj = catalogResolver.getCatalog(); 390 for(File catFile : catalogFileList){ 391 try { 392 apacheCatalogResolverObj.parseCatalog(catFile.getAbsolutePath()); 393 } catch (MalformedURLException ex) { 394 throw new CatalogModelException(ex); 395 } 396 } 397 } 398 String result = null; 399 try { 400 result = apacheCatalogResolverObj.resolveSystem(locationURI); 401 } catch (MalformedURLException ex) { 402 result = ""; 403 } catch (IOException ex) { 404 result = ""; 405 } 406 if(result == null){ 407 result = ""; 408 }else{ 409 try { 410 result = Utilities.normalizeURI(result); 413 URI uri = new URI (result); 414 if(uri.isOpaque()){ 415 if(uri.getScheme().equalsIgnoreCase("file")){ 416 StringBuffer resBuff = new StringBuffer (result); 417 result = resBuff.insert("file:".length(), "/").toString(); 418 } 419 } 420 } catch (URISyntaxException ex) { 421 return null; 422 } 423 } 424 if(result.length() > 0 ){ 425 try { 426 URI res = new URI (result); 427 return res; 428 } catch (URISyntaxException ex) { 429 } 430 } 431 return null; 432 } 433 434 435 long lastModTime = 0; 436 protected boolean reparseRequired(List <File > catalogFileList){ 437 454 return true; 455 } 456 457 458 boolean isEditable(File absResourceFile) { 459 return true; 460 } 461 462 463 public InputSource resolveEntity(String publicId, String systemId) throws SAXException , IOException { 464 try { 465 return getInputSource(new URI (systemId)); 466 } catch (CatalogModelException ex) { 467 throw new IOException (ex.getMessage()); 468 } catch (URISyntaxException e){ 469 throw new IOException ("SystemID not a URL"); 470 } 471 } 472 473 474 private InputSource getInputSource(URI locationURI) throws CatalogModelException, IOException { 475 logger.entering("CatalogModelImpl", "getInputSource", locationURI); 476 File absResourceFile = resolveUsingCatalog(locationURI, null); 477 logger.finer("Found abs file res:"+absResourceFile); 478 InputSource result = new InputSource (new FileInputStream (absResourceFile)); 479 result.setSystemId(locationURI.toString()); 480 logger.exiting("CatalogModelImpl", "getInputSource", result); 481 return result; 482 } 483 484 485 public LSInput resolveResource(String type, String namespaceURI, String publicId, String systemId, String baseURIStr) { 486 if((systemId == null) || (systemId.trim().length() <=0 )) 488 return null; 489 URI systemIdURI = null; 490 try { 491 systemIdURI = new URI (systemId); 492 } catch (URISyntaxException ex) { 493 return null; 494 } 495 FileObject baseFO = null; 496 CatalogModel depRez = null; 498 try { 499 baseFO = getFileObject(baseURIStr); 500 depRez = getResolver(baseFO); 501 } catch (CatalogModelException ex) { 502 return null; 503 } catch (IOException ex) { 504 return null; 505 } 506 if(depRez == null) 507 return null; 508 ModelSource baseMS = null; 509 try { 510 baseMS = createModelSource(baseFO, false); 511 } catch (CatalogModelException ex) { 512 } 513 ModelSource resultMS = null; 515 try { 516 resultMS = depRez.getModelSource(systemIdURI, baseMS); 517 } catch (CatalogModelException ex) { 518 return null; 519 } 520 if(resultMS == null) 521 return null; 522 FileObject resultFob = (FileObject) resultMS.getLookup().lookup(FileObject.class); 524 if(resultFob == null) 525 return null; 526 File resultFile = FileUtil.toFile(resultFob); 528 if(resultFile == null) 529 return null; 530 URI resultURI = resultFile.toURI(); 532 DOMImplementation domImpl = null; 534 try { 535 domImpl = DocumentBuilderFactory.newInstance().newDocumentBuilder().getDOMImplementation(); 536 } catch (ParserConfigurationException ex) { 537 return null; 538 } 539 DOMImplementationLS dols = (DOMImplementationLS ) domImpl.getFeature("LS","3.0"); 540 LSInput lsi = dols.createLSInput(); 541 Reader is = getFileStreamFromDocument(resultFile); 542 if(is != null) 543 lsi.setCharacterStream(is); 544 lsi.setSystemId(resultURI.toString()); 545 return lsi; 546 } 547 548 549 private FileObject getFileObject(String baseURIStr) throws IOException { 550 if(baseURIStr == null) 551 return null; 552 URI baseURI = null; 553 try { 554 baseURI = new URI (baseURIStr); 555 } catch (URISyntaxException ex) { 556 IOException ioe = new IOException (); 557 ioe.initCause(ex); 558 throw ioe; 559 } 560 if(baseURI.isAbsolute()){ 561 if(baseURI.getScheme().equalsIgnoreCase("file")){ File baseFile = null; 563 try{ 564 baseFile = new File (baseURI); 565 } catch(Exception e){ 566 IOException ioe = new IOException (); 567 ioe.initCause(e); 568 throw ioe; 569 } 570 baseFile = FileUtil.normalizeFile(baseFile); 571 FileObject baseFileObject = null; 572 try{ 573 baseFileObject = FileUtil.toFileObject(baseFile); 574 }catch(Exception e){ 575 IOException ioe = new IOException (); 576 ioe.initCause(e); 577 throw ioe; 578 } 579 return baseFileObject; 580 } 581 } 582 return null; 583 } 584 585 586 private CatalogModel getResolver(FileObject baseFileObject) throws CatalogModelException{ 587 if(baseFileObject != null && FileOwnerQuery.getOwner(baseFileObject) != null) { 588 return CatalogWriteModelFactory.getInstance().getCatalogWriteModelForProject(baseFileObject); 589 } 590 return this; 591 } 592 593 594 private Reader getFileStreamFromDocument(File resultFile) { 595 FileObject fo = FileUtil.toFileObject(FileUtil.normalizeFile(resultFile)); 596 if(fo != null){ 597 DataObject dobj = null; 598 try { 599 dobj = DataObject.find(fo); 600 } catch (DataObjectNotFoundException ex) { 601 return null; 602 } 603 if(dobj.isValid() && dobj.isModified()){ 604 return DataObjectAdapters.inputSource(dobj).getCharacterStream(); 607 } else{ 608 return null; 610 } 611 } 612 return null; 613 } 614 615 616 protected File resolveProjectProtocol(URI strRes) { 617 File result = null; 618 Project prj = FileOwnerQuery.getOwner(this.catalogFileObject); 619 if(prj != null){ 620 ProjectCatalogSupport pcs = (ProjectCatalogSupport) prj.getLookup().lookup(ProjectCatalogSupport.class); 621 if(pcs.isProjectProtocol(strRes)){ 622 FileObject resFO = pcs.resolveProjectProtocol(strRes); 623 if(resFO != null){ 624 return FileUtil.toFile(resFO); 625 } 626 } 627 } 628 return result; 629 } 630 631 632 private ModelSource getModelSourceFromSystemWideCatalog(URI locationURI, 633 ModelSource modelSourceOfSourceDocument) { 634 if( locationURI == null) 635 return null; 636 637 try { 638 Lookup.Template templ = new Lookup.Template(CatalogModel.class); 639 Lookup.Result res = Lookup.getDefault().lookup(templ); 640 Collection impls = res.allInstances(); 641 for(Object obj : impls){ 642 CatalogModel cm = (CatalogModel) obj; 643 return cm.getModelSource(locationURI, 644 modelSourceOfSourceDocument); 645 } 646 } catch (CatalogModelException ex) { 647 } 649 650 return null; 651 } 652 } 653 654 | Popular Tags |