Skip to content

Commit 6941cfc

Browse files
authored
Merge pull request #129 from evolvedbinary/7.x.x/feature/config-from-stream
[7.x.x] Allow the database configuration to be loaded from an external Input Stream
2 parents c082976 + 091754b commit 6941cfc

File tree

1 file changed

+67
-60
lines changed

1 file changed

+67
-60
lines changed

exist-core/src/main/java/org/exist/util/Configuration.java

Lines changed: 67 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@ public Configuration(@Nullable String configFilename) throws DatabaseConfigurati
282282
}
283283

284284
public Configuration(@Nullable String configFilename, Optional<Path> existHomeDirname)
285-
throws DatabaseConfigurationException {
285+
throws DatabaseConfigurationException {
286286
InputStream is = null;
287287
try {
288288
if (configFilename == null) {
@@ -311,7 +311,7 @@ public Configuration(@Nullable String configFilename, Optional<Path> existHomeDi
311311
// location if necessary
312312
if (is == null) {
313313
existHome = existHomeDirname.map(Optional::of)
314-
.orElse(ConfigurationHelper.getExistHome(configFilename));
314+
.orElse(ConfigurationHelper.getExistHome(configFilename));
315315

316316
if (existHome.isEmpty()) {
317317

@@ -351,69 +351,76 @@ public Configuration(@Nullable String configFilename, Optional<Path> existHomeDi
351351
// path from conf file
352352
final Optional<Path> existHomePath = configFilePath.map(Path::getParent);
353353

354-
// initialize xml parser
355-
// we use eXist's in-memory DOM implementation to work
356-
// around a bug in Xerces
357-
final SAXParserFactory factory = ExistSAXParserFactory.getSAXParserFactory();
358-
factory.setNamespaceAware(true);
359-
360-
final InputSource src = new InputSource(is);
361-
final SAXParser parser = factory.newSAXParser();
362-
final XMLReader reader = parser.getXMLReader();
363-
364-
reader.setFeature("http://xml.org/sax/features/external-general-entities", false);
365-
reader.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
366-
reader.setFeature(FEATURE_SECURE_PROCESSING, true);
367-
368-
final SAXAdapter adapter = new SAXAdapter((Expression) null);
369-
reader.setContentHandler(adapter);
370-
reader.setProperty(Namespaces.SAX_LEXICAL_HANDLER, adapter);
371-
reader.parse(src);
372-
373-
final Document doc = adapter.getDocument();
374-
375-
//indexer settings
376-
configureElement(doc, Indexer.CONFIGURATION_ELEMENT_NAME, element -> configureIndexer(doc, element));
377-
//scheduler settings
378-
configureElement(doc, JobConfig.CONFIGURATION_ELEMENT_NAME, this::configureScheduler);
379-
//db connection settings
380-
configureElement(doc, CONFIGURATION_CONNECTION_ELEMENT_NAME, element -> configureBackend(existHomePath, element));
381-
// lock-table settings
382-
configureElement(doc, "lock-manager", this::configureLockManager);
383-
// repository settings
384-
configureElement(doc, "repository", this::configureRepository);
385-
// binary manager settings
386-
configureElement(doc, "binary-manager", this::configureBinaryManager);
387-
// transformer settings
388-
configureElement(doc, TransformerFactoryAllocator.CONFIGURATION_ELEMENT_NAME, this::configureTransformer);
389-
// saxon settings (most importantly license file for PE or EE features)
390-
configureElement(doc, SaxonConfiguration.SAXON_CONFIGURATION_ELEMENT_NAME, this::configureSaxon);
391-
// parser settings
392-
configureElement(doc, HtmlToXmlParser.PARSER_ELEMENT_NAME, this::configureParser);
393-
// serializer settings
394-
configureElement(doc, Serializer.CONFIGURATION_ELEMENT_NAME, this::configureSerializer);
395-
// XUpdate settings
396-
configureElement(doc, DBBroker.CONFIGURATION_ELEMENT_NAME, this::configureXUpdate);
397-
// XQuery settings
398-
configureElement(doc, XQUERY_CONFIGURATION_ELEMENT_NAME, this::configureXQuery);
399-
// Validation
400-
configureElement(doc, XMLReaderObjectFactory.CONFIGURATION_ELEMENT_NAME, element -> configureValidation(existHomePath, element));
401-
// RPC server
402-
configureElement(doc, "rpc-server", this::configureRpcServer);
354+
loadConfigFile(is, existHomePath);
355+
403356
} catch (final SAXException | IOException | ParserConfigurationException e) {
404-
LOG.error("error while reading config file: {}", configFilename, e);
357+
LOG.error("Error while reading config file: {}", configFilename, e);
358+
throw new DatabaseConfigurationException(e.getMessage(), e);
359+
}
360+
}
361+
362+
public Configuration(final InputStream config, final Optional<Path> existHome) throws DatabaseConfigurationException {
363+
try {
364+
this.existHome = existHome;
365+
loadConfigFile(config, existHome);
366+
} catch (final SAXException | IOException | ParserConfigurationException e) {
367+
LOG.error("Error while reading config file: {}", e.getMessage(), e);
405368
throw new DatabaseConfigurationException(e.getMessage(), e);
406-
} finally {
407-
if (is != null) {
408-
try {
409-
is.close();
410-
} catch (final IOException ioe) {
411-
LOG.error(ioe);
412-
}
413-
}
414369
}
415370
}
416371

372+
private void loadConfigFile(final InputStream is, final Optional<Path> existHomePath) throws ParserConfigurationException, IOException, SAXException, DatabaseConfigurationException {
373+
// initialize xml parser
374+
// we use eXist's in-memory DOM implementation to work
375+
// around a bug in Xerces
376+
final SAXParserFactory factory = ExistSAXParserFactory.getSAXParserFactory();
377+
factory.setNamespaceAware(true);
378+
379+
final InputSource src = new InputSource(is);
380+
final SAXParser parser = factory.newSAXParser();
381+
final XMLReader reader = parser.getXMLReader();
382+
383+
reader.setFeature("http://xml.org/sax/features/external-general-entities", false);
384+
reader.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
385+
reader.setFeature(FEATURE_SECURE_PROCESSING, true);
386+
387+
final SAXAdapter adapter = new SAXAdapter((Expression) null);
388+
reader.setContentHandler(adapter);
389+
reader.setProperty(Namespaces.SAX_LEXICAL_HANDLER, adapter);
390+
reader.parse(src);
391+
392+
final Document doc = adapter.getDocument();
393+
394+
//indexer settings
395+
configureElement(doc, Indexer.CONFIGURATION_ELEMENT_NAME, element -> configureIndexer(doc, element));
396+
//scheduler settings
397+
configureElement(doc, JobConfig.CONFIGURATION_ELEMENT_NAME, this::configureScheduler);
398+
//db connection settings
399+
configureElement(doc, CONFIGURATION_CONNECTION_ELEMENT_NAME, element -> configureBackend(existHomePath, element));
400+
// lock-table settings
401+
configureElement(doc, "lock-manager", this::configureLockManager);
402+
// repository settings
403+
configureElement(doc, "repository", this::configureRepository);
404+
// binary manager settings
405+
configureElement(doc, "binary-manager", this::configureBinaryManager);
406+
// transformer settings
407+
configureElement(doc, TransformerFactoryAllocator.CONFIGURATION_ELEMENT_NAME, this::configureTransformer);
408+
// saxon settings (most importantly license file for PE or EE features)
409+
configureElement(doc, SaxonConfiguration.SAXON_CONFIGURATION_ELEMENT_NAME, this::configureSaxon);
410+
// parser settings
411+
configureElement(doc, HtmlToXmlParser.PARSER_ELEMENT_NAME, this::configureParser);
412+
// serializer settings
413+
configureElement(doc, Serializer.CONFIGURATION_ELEMENT_NAME, this::configureSerializer);
414+
// XUpdate settings
415+
configureElement(doc, DBBroker.CONFIGURATION_ELEMENT_NAME, this::configureXUpdate);
416+
// XQuery settings
417+
configureElement(doc, XQUERY_CONFIGURATION_ELEMENT_NAME, this::configureXQuery);
418+
// Validation
419+
configureElement(doc, XMLReaderObjectFactory.CONFIGURATION_ELEMENT_NAME, element -> configureValidation(existHomePath, element));
420+
// RPC server
421+
configureElement(doc, "rpc-server", this::configureRpcServer);
422+
}
423+
417424
@FunctionalInterface
418425
interface ElementConfigurationAction {
419426
void apply(Element element) throws DatabaseConfigurationException;

0 commit comments

Comments
 (0)