71 int current = 0; 72 73 //System Id for this catalog 74 String systemId; 75 76 /* 77 A list of catalog entry files from the input, excluding the current catalog. 78 URIs in the List are verified during input validation or property retrieval. 79 */ 80 List<String> inputFiles; 81 82 //A list of catalogs specified using the nextCatalog element 83 List<NextCatalog> nextCatalogs; 84 85 //reuse the parser 86 SAXParser parser; 87 88 /** 89 * Construct a Catalog with specified URI. 90 * 91 * @param uris the uri(s) to one or more catalogs 92 * @throws CatalogException If an error happens while parsing the specified 93 * catalog file. 94 */ 95 public CatalogImpl(CatalogFeatures f, URI... uris) throws CatalogException { 96 this(null, f, uris); 97 } 98 99 /** 100 * Construct a Catalog with specified URI. 101 * 102 * @param parent The parent catalog 103 * @param uris the uri(s) to one or more catalogs 104 * @throws CatalogException If an error happens while parsing the specified 105 * catalog file. 106 */ 107 public CatalogImpl(CatalogImpl parent, CatalogFeatures f, URI... uris) throws CatalogException { 108 super(CatalogEntryType.CATALOG, parent); 109 if (f == null) { 110 throw new NullPointerException( 111 formatMessage(CatalogMessages.ERR_NULL_ARGUMENT, new Object[]{"CatalogFeatures"})); 112 } 113 114 init(f); 115 116 //Path of catalog files 117 String[] catalogFile = null; 118 if (level == 0 && uris.length == 0) { 119 String files = features.get(Feature.FILES); 120 if (files != null) { 121 catalogFile = files.split(";"); 122 } 123 } else { 124 catalogFile = new String[uris.length]; 125 for (int i=0; i<uris.length; i++) { 126 catalogFile[i] = uris[i].toASCIIString(); 127 } 128 } 129 130 /* 131 In accordance with 8. Resource Failures of the Catalog spec, missing 132 Catalog entry files are to be ignored. 133 */ 134 if ((catalogFile != null && catalogFile.length > 0)) { 135 int start = 0; 136 URI uri = null; 137 for (String temp : catalogFile) { 138 uri = URI.create(temp); 139 start++; 140 if (verifyCatalogFile(uri)) { 141 systemId = temp; 142 try { 143 baseURI = new URL(systemId); 144 } catch (MalformedURLException e) { 145 CatalogMessages.reportRunTimeError(CatalogMessages.ERR_INVALID_PATH, 146 new Object[]{temp}, e); 147 } 148 break; 149 } 150 } 151 152 //Save the rest of input files as alternative catalogs 153 if (level == 0 && catalogFile.length > start) { 154 inputFiles = new ArrayList<>(); 155 for (int i = start; i < catalogFile.length; i++) { 156 if (catalogFile[i] != null) { 157 inputFiles.add(catalogFile[i]); 158 } 159 } 160 } 161 } 162 } 163 164 /** 165 * Loads the catalog 166 */ 167 void load() { 168 if (systemId != null) { 169 parse(systemId); 170 } 171 172 //save this catalog before loading the next 173 loadedCatalogs.put(systemId, this); 174 175 //Load delegate and alternative catalogs if defer is false. 176 if (!isDeferred()) { 177 loadDelegateCatalogs(); 178 loadNextCatalogs(); 179 } 180 } 181 182 private void init(CatalogFeatures f) { 183 if (parent == null) { 184 level = 0; 185 } else { 186 level = parent.level + 1; 187 this.loadedCatalogs = parent.loadedCatalogs; 188 this.catalogsSearched = parent.catalogsSearched; 189 } 190 if (f == null) { 191 this.features = CatalogFeatures.defaults(); 192 } else { 193 this.features = f; 194 } 195 setPrefer(features.get(Feature.PREFER)); 196 setDeferred(features.get(Feature.DEFER)); 197 setResolve(features.get(Feature.RESOLVE)); 348 if (nextCatalog != null || hasNext()) { 349 Catalog catalog = nextCatalog; 350 nextCatalog = null; 351 return catalog; 352 } else { 353 throw new NoSuchElementException(); 354 } 355 } 356 357 /** 358 * Returns the next alternative catalog. 359 * 360 * @return the next catalog if any 361 */ 362 private Catalog nextCatalog() { 363 Catalog c = null; 364 365 //Check those specified in nextCatalogs 366 if (nextCatalogs != null) { 367 while (c == null && nextCatalogIndex < nextCatalogs.size()) { 368 c = getCatalog(nextCatalogs.get(nextCatalogIndex++).getCatalogURI()); 369 } 370 } 371 372 //Check the input list 373 if (c == null && inputFiles != null) { 374 while (c == null && inputFilesIndex < inputFiles.size()) { 375 c = getCatalog(URI.create(inputFiles.get(inputFilesIndex++))); 376 } 377 } 378 379 return c; 380 } 381 }; 382 383 return StreamSupport.stream(Spliterators.spliteratorUnknownSize( 384 iter, Spliterator.ORDERED | Spliterator.NONNULL), false); 385 } 386 387 /** 388 * Adds the catalog to the nextCatalog list 389 * 390 * @param catalog a catalog specified in a nextCatalog entry 391 */ 392 void addNextCatalog(NextCatalog catalog) { 393 if (catalog == null) { 394 return; 395 } 396 397 if (nextCatalogs == null) { 398 nextCatalogs = new ArrayList<>(); 399 } 400 401 nextCatalogs.add(catalog); 402 } 403 404 /** 405 * Loads all alternative catalogs. 406 */ 407 void loadNextCatalogs() { 408 //loads catalogs specified in nextCatalogs 409 if (nextCatalogs != null) { 410 nextCatalogs.stream().forEach((next) -> { 411 getCatalog(next.getCatalogURI()); 412 }); 413 } 414 415 //loads catalogs from the input list 416 if (inputFiles != null) { 417 inputFiles.stream().forEach((uri) -> { 418 getCatalog(URI.create(uri)); 419 }); 420 } 421 } 422 423 /** 424 * Returns a Catalog object by the specified path. 425 * 426 * @param path the path to a catalog 427 * @return a Catalog object 428 */ 429 Catalog getCatalog(URI uri) { 430 if (uri == null) { 431 return null; 432 } 433 434 CatalogImpl c = null; 435 436 if (verifyCatalogFile(uri)) { 437 c = getLoadedCatalog(uri.toASCIIString()); 438 if (c == null) { 439 c = new CatalogImpl(this, features, uri); 440 c.load(); 441 } 442 } 443 return c; 444 } 445 446 /** 447 * Saves a loaded Catalog. 448 * 449 * @param catalogId the catalogId associated with the Catalog object 450 * @param c the Catalog to be saved 451 */ 452 void saveLoadedCatalog(String catalogId, CatalogImpl c) { 453 loadedCatalogs.put(catalogId, c); 454 } 455 456 /** 457 * Returns a count of all loaded catalogs, including delegate catalogs. 458 * 459 * @return a count of all loaded catalogs 460 */ 461 int loadedCatalogCount() { 462 return loadedCatalogs.size() + delegateCatalogs.size(); 463 } 464 } | 71 int current = 0; 72 73 //System Id for this catalog 74 String systemId; 75 76 /* 77 A list of catalog entry files from the input, excluding the current catalog. 78 URIs in the List are verified during input validation or property retrieval. 79 */ 80 List<String> inputFiles; 81 82 //A list of catalogs specified using the nextCatalog element 83 List<NextCatalog> nextCatalogs; 84 85 //reuse the parser 86 SAXParser parser; 87 88 /** 89 * Construct a Catalog with specified URI. 90 * 91 * @param f the features object 92 * @param uris the uri(s) to one or more catalogs 93 * @throws CatalogException If an error happens while parsing the specified 94 * catalog file. 95 */ 96 public CatalogImpl(CatalogFeatures f, URI... uris) throws CatalogException { 97 this(null, f, uris); 98 } 99 100 /** 101 * Construct a Catalog with specified URI. 102 * 103 * @param parent The parent catalog 104 * @param f the features object 105 * @param uris the uri(s) to one or more catalogs 106 * @throws CatalogException If an error happens while parsing the specified 107 * catalog file. 108 */ 109 public CatalogImpl(CatalogImpl parent, CatalogFeatures f, URI... uris) throws CatalogException { 110 super(CatalogEntryType.CATALOG, parent); 111 if (f == null) { 112 throw new NullPointerException( 113 formatMessage(CatalogMessages.ERR_NULL_ARGUMENT, new Object[]{"CatalogFeatures"})); 114 } 115 116 init(f); 117 118 //Path of catalog files 119 String[] catalogFile = null; 120 if (level == 0 && uris.length == 0) { 121 String files = features.get(Feature.FILES); 122 if (files != null) { 123 catalogFile = files.split(";"); 124 } 125 } else { 126 catalogFile = new String[uris.length]; 127 for (int i=0; i<uris.length; i++) { 128 catalogFile[i] = uris[i].toASCIIString(); 129 } 130 } 131 132 /* 133 In accordance with 8. Resource Failures of the Catalog spec, missing 134 Catalog entry files are to be ignored. 135 */ 136 if ((catalogFile != null && catalogFile.length > 0)) { 137 int start = 0; 138 URI uri = null; 139 for (String temp : catalogFile) { 140 uri = URI.create(temp); 141 start++; 142 if (verifyCatalogFile(null, uri)) { 143 systemId = temp; 144 try { 145 baseURI = new URL(systemId); 146 } catch (MalformedURLException e) { 147 CatalogMessages.reportRunTimeError(CatalogMessages.ERR_INVALID_PATH, 148 new Object[]{temp}, e); 149 } 150 break; 151 } 152 } 153 154 //Save the rest of input files as alternative catalogs 155 if (level == 0 && catalogFile.length > start) { 156 inputFiles = new ArrayList<>(); 157 for (int i = start; i < catalogFile.length; i++) { 158 if (catalogFile[i] != null) { 159 inputFiles.add(catalogFile[i]); 160 } 161 } 162 } 163 } 164 } 165 166 /** 167 * Loads the catalog 168 */ 169 void load() { 170 if (systemId != null) { 171 parse(systemId); 172 } 173 174 setCatalog(this); 175 176 //save this catalog before loading the next 177 loadedCatalogs.put(systemId, this); 178 179 //Load delegate and alternative catalogs if defer is false. 180 if (!isDeferred()) { 181 loadDelegateCatalogs(this); 182 loadNextCatalogs(); 183 } 184 } 185 186 private void init(CatalogFeatures f) { 187 if (parent == null) { 188 level = 0; 189 } else { 190 level = parent.level + 1; 191 this.loadedCatalogs = parent.loadedCatalogs; 192 this.catalogsSearched = parent.catalogsSearched; 193 } 194 if (f == null) { 195 this.features = CatalogFeatures.defaults(); 196 } else { 197 this.features = f; 198 } 199 setPrefer(features.get(Feature.PREFER)); 200 setDeferred(features.get(Feature.DEFER)); 201 setResolve(features.get(Feature.RESOLVE)); 352 if (nextCatalog != null || hasNext()) { 353 Catalog catalog = nextCatalog; 354 nextCatalog = null; 355 return catalog; 356 } else { 357 throw new NoSuchElementException(); 358 } 359 } 360 361 /** 362 * Returns the next alternative catalog. 363 * 364 * @return the next catalog if any 365 */ 366 private Catalog nextCatalog() { 367 Catalog c = null; 368 369 //Check those specified in nextCatalogs 370 if (nextCatalogs != null) { 371 while (c == null && nextCatalogIndex < nextCatalogs.size()) { 372 c = getCatalog(catalog, 373 nextCatalogs.get(nextCatalogIndex++).getCatalogURI()); 374 } 375 } 376 377 //Check the input list 378 if (c == null && inputFiles != null) { 379 while (c == null && inputFilesIndex < inputFiles.size()) { 380 c = getCatalog(null, 381 URI.create(inputFiles.get(inputFilesIndex++))); 382 } 383 } 384 385 return c; 386 } 387 }; 388 389 return StreamSupport.stream(Spliterators.spliteratorUnknownSize( 390 iter, Spliterator.ORDERED | Spliterator.NONNULL), false); 391 } 392 393 /** 394 * Adds the catalog to the nextCatalog list 395 * 396 * @param catalog a catalog specified in a nextCatalog entry 397 */ 398 void addNextCatalog(NextCatalog catalog) { 399 if (catalog == null) { 400 return; 401 } 402 403 if (nextCatalogs == null) { 404 nextCatalogs = new ArrayList<>(); 405 } 406 407 nextCatalogs.add(catalog); 408 } 409 410 /** 411 * Loads all alternative catalogs. 412 */ 413 void loadNextCatalogs() { 414 //loads catalogs specified in nextCatalogs 415 if (nextCatalogs != null) { 416 nextCatalogs.stream().forEach((next) -> { 417 getCatalog(this, next.getCatalogURI()); 418 }); 419 } 420 421 //loads catalogs from the input list 422 if (inputFiles != null) { 423 inputFiles.stream().forEach((uri) -> { 424 getCatalog(null, URI.create(uri)); 425 }); 426 } 427 } 428 429 /** 430 * Returns a Catalog object by the specified path. 431 * 432 * @param parent the parent catalog for the alternative catalogs to be loaded. 433 * It will be null if the ones to be loaded are from the input list. 434 * @param uri the path to a catalog 435 * @return a Catalog object 436 */ 437 Catalog getCatalog(CatalogImpl parent, URI uri) { 438 if (uri == null) { 439 return null; 440 } 441 442 CatalogImpl c = null; 443 444 if (verifyCatalogFile(parent, uri)) { 445 c = getLoadedCatalog(uri.toASCIIString()); 446 if (c == null) { 447 c = new CatalogImpl(this, features, uri); 448 c.load(); 449 } 450 } 451 return c; 452 } 453 454 /** 455 * Saves a loaded Catalog. 456 * 457 * @param catalogId the catalogId associated with the Catalog object 458 * @param c the Catalog to be saved 459 */ 460 void saveLoadedCatalog(String catalogId, CatalogImpl c) { 461 loadedCatalogs.put(catalogId, c); 462 } 463 464 /** 465 * Returns a count of all loaded catalogs, including delegate catalogs. 466 * 467 * @return a count of all loaded catalogs 468 */ 469 int loadedCatalogCount() { 470 return loadedCatalogs.size(); 471 } 472 } |