Skip to content

Commit 49e377b

Browse files
rhubneradamretter
authored andcommitted
[feature] Allow lazy loading of buid-in modules.
1 parent be38896 commit 49e377b

File tree

4 files changed

+79
-45
lines changed

4 files changed

+79
-45
lines changed

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

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -393,11 +393,13 @@ private void configureXQuery( Element xquery ) throws DatabaseConfigurationExcep
393393
config.put( PerformanceStats.CONFIG_PROPERTY_TRACE, trace );
394394

395395
// built-in-modules
396-
final Map<String, Class<?>> classMap = new HashMap<>();
397-
final Map<String, String> knownMappings = new HashMap<>();
396+
final Map<String, Class<?>> eagerModuleClassMap = new HashMap<>();
397+
final Map<String, Class<?>> lazyModuleClassMap = new HashMap<>();
398+
final Map<String, String> knownMappings = new HashMap<>();
398399
final Map<String, Map<String, List<? extends Object>>> moduleParameters = new HashMap<>();
399-
loadModuleClasses(xquery, classMap, knownMappings, moduleParameters);
400-
config.put( XQueryContext.PROPERTY_BUILT_IN_MODULES, classMap);
400+
loadModuleClasses(xquery, eagerModuleClassMap, lazyModuleClassMap, knownMappings, moduleParameters);
401+
config.put( XQueryContext.PROPERTY_BUILT_IN_MODULES, eagerModuleClassMap);
402+
config.put( XQueryContext.PROPERTY_BUILT_IN_LAZY_MODULES, lazyModuleClassMap);
401403
config.put( XQueryContext.PROPERTY_STATIC_MODULE_MAP, knownMappings);
402404
config.put( XQueryContext.PROPERTY_MODULE_PARAMETERS, moduleParameters);
403405
}
@@ -407,14 +409,15 @@ private void configureXQuery( Element xquery ) throws DatabaseConfigurationExcep
407409
* that the specified module class exists and is a subclass of {@link org.exist.xquery.Module}.
408410
*
409411
* @param xquery configuration root
410-
* @param modulesClassMap map containing all classes of modules
411-
* @param modulesSourceMap map containing all source uris to external resources
412+
* @param eagerModuleClassMap map containing all classes of modules which are always loaded to XQueryContext
413+
* @param lazyModuleClassMap map containing all classes of modules which are lazy loaded to XQueryContext only if they are explicitly imported
414+
* @param modulesSourceMap map containing all source uris to external resources
412415
*
413416
* @throws DatabaseConfigurationException
414417
*/
415-
private void loadModuleClasses( Element xquery, Map<String, Class<?>> modulesClassMap, Map<String, String> modulesSourceMap, Map<String, Map<String, List<? extends Object>>> moduleParameters) throws DatabaseConfigurationException {
418+
private void loadModuleClasses( Element xquery, Map<String, Class<?>> eagerModuleClassMap, Map<String, Class<?>> lazyModuleClassMap, Map<String, String> modulesSourceMap, Map<String, Map<String, List<? extends Object>>> moduleParameters) throws DatabaseConfigurationException {
416419
// add the standard function module
417-
modulesClassMap.put(Namespaces.XPATH_FUNCTIONS_NS, org.exist.xquery.functions.fn.FnModule.class);
420+
eagerModuleClassMap.put(Namespaces.XPATH_FUNCTIONS_NS, org.exist.xquery.functions.fn.FnModule.class);
418421

419422
// add other modules specified in configuration
420423
final NodeList builtins = xquery.getElementsByTagName(XQUERY_BUILTIN_MODULES_CONFIGURATION_MODULES_ELEMENT_NAME);
@@ -436,6 +439,8 @@ private void loadModuleClasses( Element xquery, Map<String, Class<?>> modulesCla
436439
final String uri = elem.getAttribute(XQueryContext.BUILT_IN_MODULE_URI_ATTRIBUTE);
437440
final String clazz = elem.getAttribute(XQueryContext.BUILT_IN_MODULE_CLASS_ATTRIBUTE);
438441
final String source = elem.getAttribute(XQueryContext.BUILT_IN_MODULE_SOURCE_ATTRIBUTE);
442+
final String load = elem.getAttribute(XQueryContext.BUILT_IN_MODULE_LOAD_ATTRIBUTE);
443+
439444

440445
// uri attribute is the identifier and is always required
441446
if(uri == null) {
@@ -447,6 +452,10 @@ private void loadModuleClasses( Element xquery, Map<String, Class<?>> modulesCla
447452
throw(new DatabaseConfigurationException("element 'module' requires either an attribute " + "'class' or 'src'" ));
448453
}
449454

455+
if(load != null && !("always".equals(load) || "lazily".equals(load))) {
456+
throw(new DatabaseConfigurationException("parameter 'load' on module can contains only 'always' and 'lazily' values"));
457+
}
458+
450459
if(source != null) {
451460
// Store src attribute info
452461

@@ -463,10 +472,11 @@ private void loadModuleClasses( Element xquery, Map<String, Class<?>> modulesCla
463472
final Class<?> moduleClass = lookupModuleClass(uri, clazz);
464473

465474
// Store class if thw module class actually exists
466-
if( moduleClass != null) {
467-
modulesClassMap.put(uri, moduleClass);
475+
if( moduleClass != null && (load == null || "always".equals(load))) {
476+
eagerModuleClassMap.put(uri, moduleClass);
477+
}else if(moduleClass != null) {
478+
lazyModuleClassMap.put(uri, moduleClass);
468479
}
469-
470480
if(LOG.isDebugEnabled()) {
471481
LOG.debug("Configured module '{}' implemented in '{}'", uri, clazz);
472482
}

exist-core/src/main/java/org/exist/xquery/XQueryContext.java

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,8 @@ public class XQueryContext implements BinaryValueManager, Context {
126126
public static final String BUILT_IN_MODULE_URI_ATTRIBUTE = "uri";
127127
public static final String BUILT_IN_MODULE_CLASS_ATTRIBUTE = "class";
128128
public static final String BUILT_IN_MODULE_SOURCE_ATTRIBUTE = "src";
129+
public static final String BUILT_IN_MODULE_LOAD_ATTRIBUTE = "load";
130+
129131

130132
public static final String PROPERTY_XQUERY_BACKWARD_COMPATIBLE = "xquery.backwardCompatible";
131133
public static final String PROPERTY_ENABLE_QUERY_REWRITING = "xquery.enable-query-rewriting";
@@ -134,7 +136,8 @@ public class XQueryContext implements BinaryValueManager, Context {
134136
public static final String PROPERTY_ENFORCE_INDEX_USE = "xquery.enforce-index-use";
135137

136138
//TODO : move elsewhere ?
137-
public static final String PROPERTY_BUILT_IN_MODULES = "xquery.modules";
139+
public static final String PROPERTY_BUILT_IN_MODULES = "xquery.modules";
140+
public static final String PROPERTY_BUILT_IN_LAZY_MODULES = "xquery.modules.lazy";
138141
public static final String PROPERTY_STATIC_MODULE_MAP = "xquery.modules.static";
139142
public static final String PROPERTY_MODULE_PARAMETERS = "xquery.modules.parameters";
140143

@@ -2512,6 +2515,19 @@ public Module[] importModule(@Nullable String namespaceURI, @Nullable String pre
25122515

25132516
if (namespaceURI != null) {
25142517
modules = getRootModules(namespaceURI);
2518+
2519+
//Lazy load modules
2520+
if (modules == null) {
2521+
final Class<Module> moduleClass = (Class<Module>) ((Map) getConfiguration()
2522+
.getProperty(PROPERTY_BUILT_IN_LAZY_MODULES))
2523+
.get(namespaceURI);
2524+
if(moduleClass != null) {
2525+
instantiateModule(namespaceURI, moduleClass ,
2526+
(Map<String, Map<String, List<? extends Object>>>) getConfiguration().getProperty(PROPERTY_MODULE_PARAMETERS));
2527+
2528+
modules = getRootModules(namespaceURI);
2529+
}
2530+
}
25152531
}
25162532

25172533
if (isNotEmpty(modules)) {

exist-distribution/src/main/config/conf.xml

Lines changed: 33 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -952,21 +952,21 @@
952952
<module uri="http://www.w3.org/2005/xpath-functions/map" class="org.exist.xquery.functions.map.MapModule"/>
953953
<module uri="http://www.w3.org/2005/xpath-functions/math" class="org.exist.xquery.functions.math.MathModule"/>
954954
<module uri="http://www.w3.org/2005/xpath-functions/array" class="org.exist.xquery.functions.array.ArrayModule"/>
955-
<module uri="http://exist-db.org/xquery/backups" class="org.exist.backup.xquery.BackupModule"/>
956-
<module uri="http://exist-db.org/xquery/inspection" class="org.exist.xquery.functions.inspect.InspectionModule"/>
955+
<module uri="http://exist-db.org/xquery/backups" class="org.exist.backup.xquery.BackupModule" load="lazily"/>
956+
<module uri="http://exist-db.org/xquery/inspection" class="org.exist.xquery.functions.inspect.InspectionModule" load="lazily"/>
957957
<module uri="http://exist-db.org/xquery/kwic" src="resource:org/exist/xquery/lib/kwic.xql"/>
958958
<module uri="http://exist-db.org/xquery/request" class="org.exist.xquery.functions.request.RequestModule"/>
959959
<module uri="http://exist-db.org/xquery/response" class="org.exist.xquery.functions.response.ResponseModule"/>
960-
<module uri="http://exist-db.org/xquery/securitymanager" class="org.exist.xquery.functions.securitymanager.SecurityManagerModule"/>
960+
<module uri="http://exist-db.org/xquery/securitymanager" class="org.exist.xquery.functions.securitymanager.SecurityManagerModule" load="lazily"/>
961961
<module uri="http://exist-db.org/xquery/session" class="org.exist.xquery.functions.session.SessionModule"/>
962-
<module uri="http://exist-db.org/xquery/system" class="org.exist.xquery.functions.system.SystemModule"/>
962+
<module uri="http://exist-db.org/xquery/system" class="org.exist.xquery.functions.system.SystemModule" load="lazily"/>
963963
<module uri="http://exist-db.org/xquery/testing" src="resource:org/exist/xquery/lib/test.xq"/>
964-
<module uri="http://exist-db.org/xquery/transform" class="org.exist.xquery.functions.transform.TransformModule"/>
964+
<module uri="http://exist-db.org/xquery/transform" class="org.exist.xquery.functions.transform.TransformModule" load="lazily"/>
965965
<module uri="http://exist-db.org/xquery/util" class="org.exist.xquery.functions.util.UtilModule">
966966
<!-- set to true to disable the util:eval functions -->
967967
<parameter name="evalDisabled" value="false"/>
968968
</module>
969-
<module uri="http://exist-db.org/xquery/validation" class="org.exist.xquery.functions.validation.ValidationModule"/>
969+
<module uri="http://exist-db.org/xquery/validation" class="org.exist.xquery.functions.validation.ValidationModule" load="lazily"/>
970970
<module uri="http://exist-db.org/xquery/xmldb" class="org.exist.xquery.functions.xmldb.XMLDBModule">
971971
<!-- set to false to disable the use of xs:anyURI as a $contents value for xmldb:store and xmldb:store-as-binary function -->
972972
<parameter name="allowAnyUri" value="false"/>
@@ -976,10 +976,10 @@
976976
<!--
977977
Extension Indexes
978978
-->
979-
<module uri="http://exist-db.org/xquery/lucene" class="org.exist.xquery.modules.lucene.LuceneModule"/>
980-
<module uri="http://exist-db.org/xquery/ngram" class="org.exist.xquery.modules.ngram.NGramModule"/>
981-
<module uri="http://exist-db.org/xquery/range" class="org.exist.xquery.modules.range.RangeIndexModule"/>
982-
<module uri="http://exist-db.org/xquery/sort" class="org.exist.xquery.modules.sort.SortModule"/>
979+
<module uri="http://exist-db.org/xquery/lucene" class="org.exist.xquery.modules.lucene.LuceneModule" load="lazily"/>
980+
<module uri="http://exist-db.org/xquery/ngram" class="org.exist.xquery.modules.ngram.NGramModule" load="lazily"/>
981+
<module uri="http://exist-db.org/xquery/range" class="org.exist.xquery.modules.range.RangeIndexModule" load="lazily"/>
982+
<module uri="http://exist-db.org/xquery/sort" class="org.exist.xquery.modules.sort.SortModule" load="lazily"/>
983983
<!--
984984
<module uri="http://exist-db.org/xquery/spatial" class="org.exist.xquery.modules.spatial.SpatialModule"/>
985985
-->
@@ -988,23 +988,23 @@
988988
<!--
989989
Extensions
990990
-->
991-
<module uri="http://exist-db.org/xquery/contentextraction" class="org.exist.contentextraction.xquery.ContentExtractionModule"/>
991+
<module uri="http://exist-db.org/xquery/contentextraction" class="org.exist.contentextraction.xquery.ContentExtractionModule" load="lazily"/>
992992
<!-- module uri="http://exist-db.org/xquery/exiftool" class="org.exist.exiftool.xquery.ExiftoolModule">
993993
<parameter name="perl-path" value="/usr/bin/perl" description="file system path to the perl executable"/>
994994
<parameter name="exiftool-path" value="/usr/bin/exiftool" description="file system path to the exiftool perl script"/>
995995
</module -->
996-
<module uri="http://expath.org/ns/http-client" class="org.expath.exist.HttpClientModule"/>
997-
<module uri="http://expath.org/ns/zip" class="org.expath.exist.ZipModule"/>
998-
<module uri="http://exquery.org/ns/request" class="org.exist.extensions.exquery.modules.request.RequestModule"/>
999-
<module uri="http://exquery.org/ns/restxq" class="org.exist.extensions.exquery.restxq.impl.xquery.RestXqModule"/>
1000-
<module uri="http://exquery.org/ns/restxq/exist" class="org.exist.extensions.exquery.restxq.impl.xquery.exist.ExistRestXqModule"/>
1001-
<module uri="http://exist-db.org/xquery/xqdoc" class="org.exist.xqdoc.xquery.XQDocModule"/>
996+
<module uri="http://expath.org/ns/http-client" class="org.expath.exist.HttpClientModule" load="lazily"/>
997+
<module uri="http://expath.org/ns/zip" class="org.expath.exist.ZipModule" load="lazily"/>
998+
<module uri="http://exquery.org/ns/request" class="org.exist.extensions.exquery.modules.request.RequestModule" load="lazily"/>
999+
<module uri="http://exquery.org/ns/restxq" class="org.exist.extensions.exquery.restxq.impl.xquery.RestXqModule" load="lazily"/>
1000+
<module uri="http://exquery.org/ns/restxq/exist" class="org.exist.extensions.exquery.restxq.impl.xquery.exist.ExistRestXqModule" load="lazily"/>
1001+
<module uri="http://exist-db.org/xquery/xqdoc" class="org.exist.xqdoc.xquery.XQDocModule" load="lazily"/>
10021002

10031003

10041004
<!--
10051005
Extension Modules
10061006
-->
1007-
<module uri="http://exist-db.org/xquery/cache" class="org.exist.xquery.modules.cache.CacheModule">
1007+
<module uri="http://exist-db.org/xquery/cache" class="org.exist.xquery.modules.cache.CacheModule" load="lazily">
10081008
<!--
10091009
If a named Cache does not exist it can be created lazily on-demand
10101010
when an operation is first performed upon it.
@@ -1029,21 +1029,21 @@
10291029
<parameter name="enableLazyCreation" value="true"/>
10301030
<parameter name="lazy.maximumSize" value="128"/>
10311031
</module>
1032-
<module uri="http://exist-db.org/xquery/compression" class="org.exist.xquery.modules.compression.CompressionModule"/>
1033-
<module uri="http://exist-db.org/xquery/counter" class="org.exist.xquery.modules.counter.CounterModule"/>
1034-
<module uri="http://exist-db.org/xquery/cqlparser" class="org.exist.xquery.modules.cqlparser.CQLParserModule"/>
1032+
<module uri="http://exist-db.org/xquery/compression" class="org.exist.xquery.modules.compression.CompressionModule" load="lazily"/>
1033+
<module uri="http://exist-db.org/xquery/counter" class="org.exist.xquery.modules.counter.CounterModule" load="lazily"/>
1034+
<module uri="http://exist-db.org/xquery/cqlparser" class="org.exist.xquery.modules.cqlparser.CQLParserModule" load="lazily"/>
10351035
<!-- module uri="http://exist-db.org/xquery/exi" class="org.exist.xquery.modules.exi.ExiModule"/ -->
1036-
<module uri="http://exist-db.org/xquery/repo" class="org.exist.xquery.modules.expathrepo.ExpathPackageModule"/>
1037-
<module uri="http://exist-db.org/xquery/file" class="org.exist.xquery.modules.file.FileModule"/>
1038-
<module uri="http://exist-db.org/xquery/image" class="org.exist.xquery.modules.image.ImageModule"/>
1039-
<module uri="http://exist-db.org/xquery/jndi" class="org.exist.xquery.modules.jndi.JNDIModule"/>
1040-
<module uri="http://exist-db.org/xquery/mail" class="org.exist.xquery.modules.mail.MailModule"/>
1036+
<module uri="http://exist-db.org/xquery/repo" class="org.exist.xquery.modules.expathrepo.ExpathPackageModule" load="lazily"/>
1037+
<module uri="http://exist-db.org/xquery/file" class="org.exist.xquery.modules.file.FileModule" load="lazily"/>
1038+
<module uri="http://exist-db.org/xquery/image" class="org.exist.xquery.modules.image.ImageModule" load="lazily"/>
1039+
<module uri="http://exist-db.org/xquery/jndi" class="org.exist.xquery.modules.jndi.JNDIModule" load="lazily"/>
1040+
<module uri="http://exist-db.org/xquery/mail" class="org.exist.xquery.modules.mail.MailModule" load="lazily"/>
10411041
<!-- module uri="http://exist-db.org/xquery/oracle" class="org.exist.xquery.modules.oracle.OracleModule"/ -->
1042-
<module uri="http://exist-db.org/xquery/persistentlogin" class="org.exist.xquery.modules.persistentlogin.PersistentLoginModule"/>
1043-
<module uri="http://exist-db.org/xquery/process" class="org.exist.xquery.modules.process.ProcessModule"/>
1044-
<module uri="http://exist-db.org/xquery/scheduler" class="org.exist.xquery.modules.scheduler.SchedulerModule"/>
1045-
<module uri="http://exist-db.org/xquery/simple-ql" class="org.exist.xquery.modules.simpleql.SimpleQLModule"/>
1046-
<module uri="http://exist-db.org/xquery/sql" class="org.exist.xquery.modules.sql.SQLModule">
1042+
<module uri="http://exist-db.org/xquery/persistentlogin" class="org.exist.xquery.modules.persistentlogin.PersistentLoginModule" load="lazily"/>
1043+
<module uri="http://exist-db.org/xquery/process" class="org.exist.xquery.modules.process.ProcessModule" load="lazily"/>
1044+
<module uri="http://exist-db.org/xquery/scheduler" class="org.exist.xquery.modules.scheduler.SchedulerModule" load="lazily"/>
1045+
<module uri="http://exist-db.org/xquery/simple-ql" class="org.exist.xquery.modules.simpleql.SimpleQLModule" load="lazily"/>
1046+
<module uri="http://exist-db.org/xquery/sql" class="org.exist.xquery.modules.sql.SQLModule" load="lazily">
10471047

10481048
<!--
10491049
Connection Pools can be setup for SQL connections, for use with sql:get-connection-from-pool($pool-name)
@@ -1075,15 +1075,15 @@
10751075
<parameter name="pool.2.properties.registerMbeans" value="false"/>
10761076
-->
10771077
</module>
1078-
<module uri="http://exist-db.org/xquery/xmldiff" class="org.exist.xquery.modules.xmldiff.XmlDiffModule"/>
1078+
<module uri="http://exist-db.org/xquery/xmldiff" class="org.exist.xquery.modules.xmldiff.XmlDiffModule" load="lazily"/>
10791079
<!--
10801080
XSL:FO Transformation Module
10811081
Valid processor adapters are:
10821082
- org.exist.xquery.modules.xslfo.ApacheFopProcessorAdapter for Apache's FOP
10831083
- org.exist.xquery.modules.xslfo.RenderXXepProcessorAdapter for RenderX's XEP
10841084
- org.exist.xquery.modules.xslfo.AntennaHouseProcessorAdapter for AntennaHouse Formatter
10851085
-->
1086-
<module uri="http://exist-db.org/xquery/xslfo" class="org.exist.xquery.modules.xslfo.XSLFOModule">
1086+
<module uri="http://exist-db.org/xquery/xslfo" class="org.exist.xquery.modules.xslfo.XSLFOModule" load="lazily">
10871087
<parameter name="processorAdapter" value="org.exist.xquery.modules.xslfo.ApacheFopProcessorAdapter"/>
10881088
</module>
10891089

0 commit comments

Comments
 (0)