Skip to content

Commit b2e9a9b

Browse files
committed
[feature] Allow lazy loading of buid-in modules.
1 parent 2b0738c commit b2e9a9b

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
@@ -390,11 +390,13 @@ private void configureXQuery( Element xquery ) throws DatabaseConfigurationExcep
390390
config.put( PerformanceStats.CONFIG_PROPERTY_TRACE, trace );
391391

392392
// built-in-modules
393-
final Map<String, Class<?>> classMap = new HashMap<>();
394-
final Map<String, String> knownMappings = new HashMap<>();
393+
final Map<String, Class<?>> eagerModuleClassMap = new HashMap<>();
394+
final Map<String, Class<?>> lazyModuleClassMap = new HashMap<>();
395+
final Map<String, String> knownMappings = new HashMap<>();
395396
final Map<String, Map<String, List<? extends Object>>> moduleParameters = new HashMap<>();
396-
loadModuleClasses(xquery, classMap, knownMappings, moduleParameters);
397-
config.put( XQueryContext.PROPERTY_BUILT_IN_MODULES, classMap);
397+
loadModuleClasses(xquery, eagerModuleClassMap, lazyModuleClassMap, knownMappings, moduleParameters);
398+
config.put( XQueryContext.PROPERTY_BUILT_IN_MODULES, eagerModuleClassMap);
399+
config.put( XQueryContext.PROPERTY_BUILT_IN_LAZY_MODULES, lazyModuleClassMap);
398400
config.put( XQueryContext.PROPERTY_STATIC_MODULE_MAP, knownMappings);
399401
config.put( XQueryContext.PROPERTY_MODULE_PARAMETERS, moduleParameters);
400402
}
@@ -404,14 +406,15 @@ private void configureXQuery( Element xquery ) throws DatabaseConfigurationExcep
404406
* that the specified module class exists and is a subclass of {@link org.exist.xquery.Module}.
405407
*
406408
* @param xquery configuration root
407-
* @param modulesClassMap map containing all classes of modules
408-
* @param modulesSourceMap map containing all source uris to external resources
409+
* @param eagerModuleClassMap map containing all classes of modules which are always loaded to XQueryContext
410+
* @param lazyModuleClassMap map containing all classes of modules which are lazy loaded to XQueryContext only if they are explicitly imported
411+
* @param modulesSourceMap map containing all source uris to external resources
409412
*
410413
* @throws DatabaseConfigurationException
411414
*/
412-
private void loadModuleClasses( Element xquery, Map<String, Class<?>> modulesClassMap, Map<String, String> modulesSourceMap, Map<String, Map<String, List<? extends Object>>> moduleParameters) throws DatabaseConfigurationException {
415+
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 {
413416
// add the standard function module
414-
modulesClassMap.put(Namespaces.XPATH_FUNCTIONS_NS, org.exist.xquery.functions.fn.FnModule.class);
417+
eagerModuleClassMap.put(Namespaces.XPATH_FUNCTIONS_NS, org.exist.xquery.functions.fn.FnModule.class);
415418

416419
// add other modules specified in configuration
417420
final NodeList builtins = xquery.getElementsByTagName(XQUERY_BUILTIN_MODULES_CONFIGURATION_MODULES_ELEMENT_NAME);
@@ -433,6 +436,8 @@ private void loadModuleClasses( Element xquery, Map<String, Class<?>> modulesCla
433436
final String uri = elem.getAttribute(XQueryContext.BUILT_IN_MODULE_URI_ATTRIBUTE);
434437
final String clazz = elem.getAttribute(XQueryContext.BUILT_IN_MODULE_CLASS_ATTRIBUTE);
435438
final String source = elem.getAttribute(XQueryContext.BUILT_IN_MODULE_SOURCE_ATTRIBUTE);
439+
final String load = elem.getAttribute(XQueryContext.BUILT_IN_MODULE_LOAD_ATTRIBUTE);
440+
436441

437442
// uri attribute is the identifier and is always required
438443
if(uri == null) {
@@ -444,6 +449,10 @@ private void loadModuleClasses( Element xquery, Map<String, Class<?>> modulesCla
444449
throw(new DatabaseConfigurationException("element 'module' requires either an attribute " + "'class' or 'src'" ));
445450
}
446451

452+
if(load != null && !("always".equals(load) || "lazily".equals(load))) {
453+
throw(new DatabaseConfigurationException("parameter 'load' on module can contains only 'always' and 'lazily' values"));
454+
}
455+
447456
if(source != null) {
448457
// Store src attribute info
449458

@@ -460,10 +469,11 @@ private void loadModuleClasses( Element xquery, Map<String, Class<?>> modulesCla
460469
final Class<?> moduleClass = lookupModuleClass(uri, clazz);
461470

462471
// Store class if thw module class actually exists
463-
if( moduleClass != null) {
464-
modulesClassMap.put(uri, moduleClass);
472+
if( moduleClass != null && (load == null || "always".equals(load))) {
473+
eagerModuleClassMap.put(uri, moduleClass);
474+
}else if(moduleClass != null) {
475+
lazyModuleClassMap.put(uri, moduleClass);
465476
}
466-
467477
if(LOG.isDebugEnabled()) {
468478
LOG.debug("Configured module '{}' implemented in '{}'", uri, clazz);
469479
}

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

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,8 @@ public class XQueryContext implements BinaryValueManager, Context {
122122
public static final String BUILT_IN_MODULE_URI_ATTRIBUTE = "uri";
123123
public static final String BUILT_IN_MODULE_CLASS_ATTRIBUTE = "class";
124124
public static final String BUILT_IN_MODULE_SOURCE_ATTRIBUTE = "src";
125+
public static final String BUILT_IN_MODULE_LOAD_ATTRIBUTE = "load";
126+
125127

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

132134
//TODO : move elsewhere ?
133-
public static final String PROPERTY_BUILT_IN_MODULES = "xquery.modules";
135+
public static final String PROPERTY_BUILT_IN_MODULES = "xquery.modules";
136+
public static final String PROPERTY_BUILT_IN_LAZY_MODULES = "xquery.modules.lazy";
134137
public static final String PROPERTY_STATIC_MODULE_MAP = "xquery.modules.static";
135138
public static final String PROPERTY_MODULE_PARAMETERS = "xquery.modules.parameters";
136139

@@ -2431,6 +2434,19 @@ public Module[] importModule(@Nullable String namespaceURI, @Nullable String pre
24312434

24322435
if (namespaceURI != null) {
24332436
modules = getRootModules(namespaceURI);
2437+
2438+
//Lazy load modules
2439+
if (modules == null) {
2440+
final Class<Module> moduleClass = (Class<Module>) ((Map) getConfiguration()
2441+
.getProperty(PROPERTY_BUILT_IN_LAZY_MODULES))
2442+
.get(namespaceURI);
2443+
if(moduleClass != null) {
2444+
instantiateModule(namespaceURI, moduleClass ,
2445+
(Map<String, Map<String, List<? extends Object>>>) getConfiguration().getProperty(PROPERTY_MODULE_PARAMETERS));
2446+
2447+
modules = getRootModules(namespaceURI);
2448+
}
2449+
}
24342450
}
24352451

24362452
if (isNotEmpty(modules)) {

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

Lines changed: 33 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -938,33 +938,33 @@
938938
<module uri="http://www.w3.org/2005/xpath-functions/map" class="org.exist.xquery.functions.map.MapModule"/>
939939
<module uri="http://www.w3.org/2005/xpath-functions/math" class="org.exist.xquery.functions.math.MathModule"/>
940940
<module uri="http://www.w3.org/2005/xpath-functions/array" class="org.exist.xquery.functions.array.ArrayModule"/>
941-
<module uri="http://exist-db.org/xquery/backups" class="org.exist.backup.xquery.BackupModule"/>
942-
<module uri="http://exist-db.org/xquery/inspection" class="org.exist.xquery.functions.inspect.InspectionModule"/>
941+
<module uri="http://exist-db.org/xquery/backups" class="org.exist.backup.xquery.BackupModule" load="lazily"/>
942+
<module uri="http://exist-db.org/xquery/inspection" class="org.exist.xquery.functions.inspect.InspectionModule" load="lazily"/>
943943
<module uri="http://www.json.org" src="resource:org/exist/xquery/lib/json.xq"/>
944944
<module uri="http://www.jsonp.org" src="resource:org/exist/xquery/lib/jsonp.xq"/>
945945
<module uri="http://exist-db.org/xquery/kwic" src="resource:org/exist/xquery/lib/kwic.xql"/>
946946
<module uri="http://exist-db.org/xquery/request" class="org.exist.xquery.functions.request.RequestModule"/>
947947
<module uri="http://exist-db.org/xquery/response" class="org.exist.xquery.functions.response.ResponseModule"/>
948-
<module uri="http://exist-db.org/xquery/securitymanager" class="org.exist.xquery.functions.securitymanager.SecurityManagerModule"/>
948+
<module uri="http://exist-db.org/xquery/securitymanager" class="org.exist.xquery.functions.securitymanager.SecurityManagerModule" load="lazily"/>
949949
<module uri="http://exist-db.org/xquery/session" class="org.exist.xquery.functions.session.SessionModule"/>
950-
<module uri="http://exist-db.org/xquery/system" class="org.exist.xquery.functions.system.SystemModule"/>
950+
<module uri="http://exist-db.org/xquery/system" class="org.exist.xquery.functions.system.SystemModule" load="lazily"/>
951951
<module uri="http://exist-db.org/xquery/testing" src="resource:org/exist/xquery/lib/test.xq"/>
952-
<module uri="http://exist-db.org/xquery/transform" class="org.exist.xquery.functions.transform.TransformModule"/>
952+
<module uri="http://exist-db.org/xquery/transform" class="org.exist.xquery.functions.transform.TransformModule" load="lazily"/>
953953
<module uri="http://exist-db.org/xquery/util" class="org.exist.xquery.functions.util.UtilModule">
954954
<!-- set to true to disable the util:eval functions -->
955955
<parameter name="evalDisabled" value="false"/>
956956
</module>
957-
<module uri="http://exist-db.org/xquery/validation" class="org.exist.xquery.functions.validation.ValidationModule"/>
957+
<module uri="http://exist-db.org/xquery/validation" class="org.exist.xquery.functions.validation.ValidationModule" load="lazily"/>
958958
<module uri="http://exist-db.org/xquery/xmldb" class="org.exist.xquery.functions.xmldb.XMLDBModule"/>
959959

960960

961961
<!--
962962
Extension Indexes
963963
-->
964-
<module uri="http://exist-db.org/xquery/lucene" class="org.exist.xquery.modules.lucene.LuceneModule"/>
965-
<module uri="http://exist-db.org/xquery/ngram" class="org.exist.xquery.modules.ngram.NGramModule"/>
966-
<module uri="http://exist-db.org/xquery/range" class="org.exist.xquery.modules.range.RangeIndexModule"/>
967-
<module uri="http://exist-db.org/xquery/sort" class="org.exist.xquery.modules.sort.SortModule"/>
964+
<module uri="http://exist-db.org/xquery/lucene" class="org.exist.xquery.modules.lucene.LuceneModule" load="lazily"/>
965+
<module uri="http://exist-db.org/xquery/ngram" class="org.exist.xquery.modules.ngram.NGramModule" load="lazily"/>
966+
<module uri="http://exist-db.org/xquery/range" class="org.exist.xquery.modules.range.RangeIndexModule" load="lazily"/>
967+
<module uri="http://exist-db.org/xquery/sort" class="org.exist.xquery.modules.sort.SortModule" load="lazily"/>
968968
<!--
969969
<module uri="http://exist-db.org/xquery/spatial" class="org.exist.xquery.modules.spatial.SpatialModule"/>
970970
-->
@@ -973,23 +973,23 @@
973973
<!--
974974
Extensions
975975
-->
976-
<module uri="http://exist-db.org/xquery/contentextraction" class="org.exist.contentextraction.xquery.ContentExtractionModule"/>
976+
<module uri="http://exist-db.org/xquery/contentextraction" class="org.exist.contentextraction.xquery.ContentExtractionModule" load="lazily"/>
977977
<!-- module uri="http://exist-db.org/xquery/exiftool" class="org.exist.exiftool.xquery.ExiftoolModule">
978978
<parameter name="perl-path" value="/usr/bin/perl" description="file system path to the perl executable"/>
979979
<parameter name="exiftool-path" value="/usr/bin/exiftool" description="file system path to the exiftool perl script"/>
980980
</module -->
981-
<module uri="http://expath.org/ns/http-client" class="org.expath.exist.HttpClientModule"/>
982-
<module uri="http://expath.org/ns/zip" class="org.expath.exist.ZipModule"/>
983-
<module uri="http://exquery.org/ns/request" class="org.exist.extensions.exquery.modules.request.RequestModule"/>
984-
<module uri="http://exquery.org/ns/restxq" class="org.exist.extensions.exquery.restxq.impl.xquery.RestXqModule"/>
985-
<module uri="http://exquery.org/ns/restxq/exist" class="org.exist.extensions.exquery.restxq.impl.xquery.exist.ExistRestXqModule"/>
986-
<module uri="http://exist-db.org/xquery/xqdoc" class="org.exist.xqdoc.xquery.XQDocModule"/>
981+
<module uri="http://expath.org/ns/http-client" class="org.expath.exist.HttpClientModule" load="lazily"/>
982+
<module uri="http://expath.org/ns/zip" class="org.expath.exist.ZipModule" load="lazily"/>
983+
<module uri="http://exquery.org/ns/request" class="org.exist.extensions.exquery.modules.request.RequestModule" load="lazily"/>
984+
<module uri="http://exquery.org/ns/restxq" class="org.exist.extensions.exquery.restxq.impl.xquery.RestXqModule" load="lazily"/>
985+
<module uri="http://exquery.org/ns/restxq/exist" class="org.exist.extensions.exquery.restxq.impl.xquery.exist.ExistRestXqModule" load="lazily"/>
986+
<module uri="http://exist-db.org/xquery/xqdoc" class="org.exist.xqdoc.xquery.XQDocModule" load="lazily"/>
987987

988988

989989
<!--
990990
Extension Modules
991991
-->
992-
<module uri="http://exist-db.org/xquery/cache" class="org.exist.xquery.modules.cache.CacheModule">
992+
<module uri="http://exist-db.org/xquery/cache" class="org.exist.xquery.modules.cache.CacheModule" load="lazily">
993993
<!--
994994
If a named Cache does not exist it can be created lazily on-demand
995995
when an operation is first performed upon it.
@@ -1014,21 +1014,21 @@
10141014
<parameter name="enableLazyCreation" value="true"/>
10151015
<parameter name="lazy.maximumSize" value="128"/>
10161016
</module>
1017-
<module uri="http://exist-db.org/xquery/compression" class="org.exist.xquery.modules.compression.CompressionModule"/>
1018-
<module uri="http://exist-db.org/xquery/counter" class="org.exist.xquery.modules.counter.CounterModule"/>
1019-
<module uri="http://exist-db.org/xquery/cqlparser" class="org.exist.xquery.modules.cqlparser.CQLParserModule"/>
1017+
<module uri="http://exist-db.org/xquery/compression" class="org.exist.xquery.modules.compression.CompressionModule" load="lazily"/>
1018+
<module uri="http://exist-db.org/xquery/counter" class="org.exist.xquery.modules.counter.CounterModule" load="lazily"/>
1019+
<module uri="http://exist-db.org/xquery/cqlparser" class="org.exist.xquery.modules.cqlparser.CQLParserModule" load="lazily"/>
10201020
<!-- module uri="http://exist-db.org/xquery/exi" class="org.exist.xquery.modules.exi.ExiModule"/ -->
1021-
<module uri="http://exist-db.org/xquery/repo" class="org.exist.xquery.modules.expathrepo.ExpathPackageModule"/>
1022-
<module uri="http://exist-db.org/xquery/file" class="org.exist.xquery.modules.file.FileModule"/>
1023-
<module uri="http://exist-db.org/xquery/image" class="org.exist.xquery.modules.image.ImageModule"/>
1024-
<module uri="http://exist-db.org/xquery/jndi" class="org.exist.xquery.modules.jndi.JNDIModule"/>
1025-
<module uri="http://exist-db.org/xquery/mail" class="org.exist.xquery.modules.mail.MailModule"/>
1021+
<module uri="http://exist-db.org/xquery/repo" class="org.exist.xquery.modules.expathrepo.ExpathPackageModule" load="lazily"/>
1022+
<module uri="http://exist-db.org/xquery/file" class="org.exist.xquery.modules.file.FileModule" load="lazily"/>
1023+
<module uri="http://exist-db.org/xquery/image" class="org.exist.xquery.modules.image.ImageModule" load="lazily"/>
1024+
<module uri="http://exist-db.org/xquery/jndi" class="org.exist.xquery.modules.jndi.JNDIModule" load="lazily"/>
1025+
<module uri="http://exist-db.org/xquery/mail" class="org.exist.xquery.modules.mail.MailModule" load="lazily"/>
10261026
<!-- module uri="http://exist-db.org/xquery/oracle" class="org.exist.xquery.modules.oracle.OracleModule"/ -->
1027-
<module uri="http://exist-db.org/xquery/persistentlogin" class="org.exist.xquery.modules.persistentlogin.PersistentLoginModule"/>
1028-
<module uri="http://exist-db.org/xquery/process" class="org.exist.xquery.modules.process.ProcessModule"/>
1029-
<module uri="http://exist-db.org/xquery/scheduler" class="org.exist.xquery.modules.scheduler.SchedulerModule"/>
1030-
<module uri="http://exist-db.org/xquery/simple-ql" class="org.exist.xquery.modules.simpleql.SimpleQLModule"/>
1031-
<module uri="http://exist-db.org/xquery/sql" class="org.exist.xquery.modules.sql.SQLModule">
1027+
<module uri="http://exist-db.org/xquery/persistentlogin" class="org.exist.xquery.modules.persistentlogin.PersistentLoginModule" load="lazily"/>
1028+
<module uri="http://exist-db.org/xquery/process" class="org.exist.xquery.modules.process.ProcessModule" load="lazily"/>
1029+
<module uri="http://exist-db.org/xquery/scheduler" class="org.exist.xquery.modules.scheduler.SchedulerModule" load="lazily"/>
1030+
<module uri="http://exist-db.org/xquery/simple-ql" class="org.exist.xquery.modules.simpleql.SimpleQLModule" load="lazily"/>
1031+
<module uri="http://exist-db.org/xquery/sql" class="org.exist.xquery.modules.sql.SQLModule" load="lazily">
10321032

10331033
<!--
10341034
Connection Pools can be setup for SQL connections, for use with sql:get-connection-from-pool($pool-name)
@@ -1060,15 +1060,15 @@
10601060
<parameter name="pool.2.properties.registerMbeans" value="false"/>
10611061
-->
10621062
</module>
1063-
<module uri="http://exist-db.org/xquery/xmldiff" class="org.exist.xquery.modules.xmldiff.XmlDiffModule"/>
1063+
<module uri="http://exist-db.org/xquery/xmldiff" class="org.exist.xquery.modules.xmldiff.XmlDiffModule" load="lazily"/>
10641064
<!--
10651065
XSL:FO Transformation Module
10661066
Valid processor adapters are:
10671067
- org.exist.xquery.modules.xslfo.ApacheFopProcessorAdapter for Apache's FOP
10681068
- org.exist.xquery.modules.xslfo.RenderXXepProcessorAdapter for RenderX's XEP
10691069
- org.exist.xquery.modules.xslfo.AntennaHouseProcessorAdapter for AntennaHouse Formatter
10701070
-->
1071-
<module uri="http://exist-db.org/xquery/xslfo" class="org.exist.xquery.modules.xslfo.XSLFOModule">
1071+
<module uri="http://exist-db.org/xquery/xslfo" class="org.exist.xquery.modules.xslfo.XSLFOModule" load="lazily">
10721072
<parameter name="processorAdapter" value="org.exist.xquery.modules.xslfo.ApacheFopProcessorAdapter"/>
10731073
</module>
10741074

0 commit comments

Comments
 (0)