Skip to content

Commit d539bf5

Browse files
rhubneradamretter
authored andcommitted
[feature] Allow lazy loading of buid-in modules.
1 parent 8a6653e commit d539bf5

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
@@ -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

@@ -2435,6 +2438,19 @@ public Module[] importModule(@Nullable String namespaceURI, @Nullable String pre
24352438

24362439
if (namespaceURI != null) {
24372440
modules = getRootModules(namespaceURI);
2441+
2442+
//Lazy load modules
2443+
if (modules == null) {
2444+
final Class<Module> moduleClass = (Class<Module>) ((Map) getConfiguration()
2445+
.getProperty(PROPERTY_BUILT_IN_LAZY_MODULES))
2446+
.get(namespaceURI);
2447+
if(moduleClass != null) {
2448+
instantiateModule(namespaceURI, moduleClass ,
2449+
(Map<String, Map<String, List<? extends Object>>>) getConfiguration().getProperty(PROPERTY_MODULE_PARAMETERS));
2450+
2451+
modules = getRootModules(namespaceURI);
2452+
}
2453+
}
24382454
}
24392455

24402456
if (isNotEmpty(modules)) {

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

Lines changed: 33 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -942,23 +942,23 @@
942942
<module uri="http://www.w3.org/2005/xpath-functions/map" class="org.exist.xquery.functions.map.MapModule"/>
943943
<module uri="http://www.w3.org/2005/xpath-functions/math" class="org.exist.xquery.functions.math.MathModule"/>
944944
<module uri="http://www.w3.org/2005/xpath-functions/array" class="org.exist.xquery.functions.array.ArrayModule"/>
945-
<module uri="http://exist-db.org/xquery/backups" class="org.exist.backup.xquery.BackupModule"/>
946-
<module uri="http://exist-db.org/xquery/inspection" class="org.exist.xquery.functions.inspect.InspectionModule"/>
945+
<module uri="http://exist-db.org/xquery/backups" class="org.exist.backup.xquery.BackupModule" load="lazily"/>
946+
<module uri="http://exist-db.org/xquery/inspection" class="org.exist.xquery.functions.inspect.InspectionModule" load="lazily"/>
947947
<module uri="http://www.json.org" src="resource:org/exist/xquery/lib/json.xq"/>
948948
<module uri="http://www.jsonp.org" src="resource:org/exist/xquery/lib/jsonp.xq"/>
949949
<module uri="http://exist-db.org/xquery/kwic" src="resource:org/exist/xquery/lib/kwic.xql"/>
950950
<module uri="http://exist-db.org/xquery/request" class="org.exist.xquery.functions.request.RequestModule"/>
951951
<module uri="http://exist-db.org/xquery/response" class="org.exist.xquery.functions.response.ResponseModule"/>
952-
<module uri="http://exist-db.org/xquery/securitymanager" class="org.exist.xquery.functions.securitymanager.SecurityManagerModule"/>
952+
<module uri="http://exist-db.org/xquery/securitymanager" class="org.exist.xquery.functions.securitymanager.SecurityManagerModule" load="lazily"/>
953953
<module uri="http://exist-db.org/xquery/session" class="org.exist.xquery.functions.session.SessionModule"/>
954-
<module uri="http://exist-db.org/xquery/system" class="org.exist.xquery.functions.system.SystemModule"/>
954+
<module uri="http://exist-db.org/xquery/system" class="org.exist.xquery.functions.system.SystemModule" load="lazily"/>
955955
<module uri="http://exist-db.org/xquery/testing" src="resource:org/exist/xquery/lib/test.xq"/>
956-
<module uri="http://exist-db.org/xquery/transform" class="org.exist.xquery.functions.transform.TransformModule"/>
956+
<module uri="http://exist-db.org/xquery/transform" class="org.exist.xquery.functions.transform.TransformModule" load="lazily"/>
957957
<module uri="http://exist-db.org/xquery/util" class="org.exist.xquery.functions.util.UtilModule">
958958
<!-- set to true to disable the util:eval functions -->
959959
<parameter name="evalDisabled" value="false"/>
960960
</module>
961-
<module uri="http://exist-db.org/xquery/validation" class="org.exist.xquery.functions.validation.ValidationModule"/>
961+
<module uri="http://exist-db.org/xquery/validation" class="org.exist.xquery.functions.validation.ValidationModule" load="lazily"/>
962962
<module uri="http://exist-db.org/xquery/xmldb" class="org.exist.xquery.functions.xmldb.XMLDBModule">
963963
<!-- set to false to disable the use of xs:anyURI as a $contents value for xmldb:store and xmldb:store-as-binary function -->
964964
<parameter name="allowAnyUri" value="false"/>
@@ -968,10 +968,10 @@
968968
<!--
969969
Extension Indexes
970970
-->
971-
<module uri="http://exist-db.org/xquery/lucene" class="org.exist.xquery.modules.lucene.LuceneModule"/>
972-
<module uri="http://exist-db.org/xquery/ngram" class="org.exist.xquery.modules.ngram.NGramModule"/>
973-
<module uri="http://exist-db.org/xquery/range" class="org.exist.xquery.modules.range.RangeIndexModule"/>
974-
<module uri="http://exist-db.org/xquery/sort" class="org.exist.xquery.modules.sort.SortModule"/>
971+
<module uri="http://exist-db.org/xquery/lucene" class="org.exist.xquery.modules.lucene.LuceneModule" load="lazily"/>
972+
<module uri="http://exist-db.org/xquery/ngram" class="org.exist.xquery.modules.ngram.NGramModule" load="lazily"/>
973+
<module uri="http://exist-db.org/xquery/range" class="org.exist.xquery.modules.range.RangeIndexModule" load="lazily"/>
974+
<module uri="http://exist-db.org/xquery/sort" class="org.exist.xquery.modules.sort.SortModule" load="lazily"/>
975975
<!--
976976
<module uri="http://exist-db.org/xquery/spatial" class="org.exist.xquery.modules.spatial.SpatialModule"/>
977977
-->
@@ -980,23 +980,23 @@
980980
<!--
981981
Extensions
982982
-->
983-
<module uri="http://exist-db.org/xquery/contentextraction" class="org.exist.contentextraction.xquery.ContentExtractionModule"/>
983+
<module uri="http://exist-db.org/xquery/contentextraction" class="org.exist.contentextraction.xquery.ContentExtractionModule" load="lazily"/>
984984
<!-- module uri="http://exist-db.org/xquery/exiftool" class="org.exist.exiftool.xquery.ExiftoolModule">
985985
<parameter name="perl-path" value="/usr/bin/perl" description="file system path to the perl executable"/>
986986
<parameter name="exiftool-path" value="/usr/bin/exiftool" description="file system path to the exiftool perl script"/>
987987
</module -->
988-
<module uri="http://expath.org/ns/http-client" class="org.expath.exist.HttpClientModule"/>
989-
<module uri="http://expath.org/ns/zip" class="org.expath.exist.ZipModule"/>
990-
<module uri="http://exquery.org/ns/request" class="org.exist.extensions.exquery.modules.request.RequestModule"/>
991-
<module uri="http://exquery.org/ns/restxq" class="org.exist.extensions.exquery.restxq.impl.xquery.RestXqModule"/>
992-
<module uri="http://exquery.org/ns/restxq/exist" class="org.exist.extensions.exquery.restxq.impl.xquery.exist.ExistRestXqModule"/>
993-
<module uri="http://exist-db.org/xquery/xqdoc" class="org.exist.xqdoc.xquery.XQDocModule"/>
988+
<module uri="http://expath.org/ns/http-client" class="org.expath.exist.HttpClientModule" load="lazily"/>
989+
<module uri="http://expath.org/ns/zip" class="org.expath.exist.ZipModule" load="lazily"/>
990+
<module uri="http://exquery.org/ns/request" class="org.exist.extensions.exquery.modules.request.RequestModule" load="lazily"/>
991+
<module uri="http://exquery.org/ns/restxq" class="org.exist.extensions.exquery.restxq.impl.xquery.RestXqModule" load="lazily"/>
992+
<module uri="http://exquery.org/ns/restxq/exist" class="org.exist.extensions.exquery.restxq.impl.xquery.exist.ExistRestXqModule" load="lazily"/>
993+
<module uri="http://exist-db.org/xquery/xqdoc" class="org.exist.xqdoc.xquery.XQDocModule" load="lazily"/>
994994

995995

996996
<!--
997997
Extension Modules
998998
-->
999-
<module uri="http://exist-db.org/xquery/cache" class="org.exist.xquery.modules.cache.CacheModule">
999+
<module uri="http://exist-db.org/xquery/cache" class="org.exist.xquery.modules.cache.CacheModule" load="lazily">
10001000
<!--
10011001
If a named Cache does not exist it can be created lazily on-demand
10021002
when an operation is first performed upon it.
@@ -1021,21 +1021,21 @@
10211021
<parameter name="enableLazyCreation" value="true"/>
10221022
<parameter name="lazy.maximumSize" value="128"/>
10231023
</module>
1024-
<module uri="http://exist-db.org/xquery/compression" class="org.exist.xquery.modules.compression.CompressionModule"/>
1025-
<module uri="http://exist-db.org/xquery/counter" class="org.exist.xquery.modules.counter.CounterModule"/>
1026-
<module uri="http://exist-db.org/xquery/cqlparser" class="org.exist.xquery.modules.cqlparser.CQLParserModule"/>
1024+
<module uri="http://exist-db.org/xquery/compression" class="org.exist.xquery.modules.compression.CompressionModule" load="lazily"/>
1025+
<module uri="http://exist-db.org/xquery/counter" class="org.exist.xquery.modules.counter.CounterModule" load="lazily"/>
1026+
<module uri="http://exist-db.org/xquery/cqlparser" class="org.exist.xquery.modules.cqlparser.CQLParserModule" load="lazily"/>
10271027
<!-- module uri="http://exist-db.org/xquery/exi" class="org.exist.xquery.modules.exi.ExiModule"/ -->
1028-
<module uri="http://exist-db.org/xquery/repo" class="org.exist.xquery.modules.expathrepo.ExpathPackageModule"/>
1029-
<module uri="http://exist-db.org/xquery/file" class="org.exist.xquery.modules.file.FileModule"/>
1030-
<module uri="http://exist-db.org/xquery/image" class="org.exist.xquery.modules.image.ImageModule"/>
1031-
<module uri="http://exist-db.org/xquery/jndi" class="org.exist.xquery.modules.jndi.JNDIModule"/>
1032-
<module uri="http://exist-db.org/xquery/mail" class="org.exist.xquery.modules.mail.MailModule"/>
1028+
<module uri="http://exist-db.org/xquery/repo" class="org.exist.xquery.modules.expathrepo.ExpathPackageModule" load="lazily"/>
1029+
<module uri="http://exist-db.org/xquery/file" class="org.exist.xquery.modules.file.FileModule" load="lazily"/>
1030+
<module uri="http://exist-db.org/xquery/image" class="org.exist.xquery.modules.image.ImageModule" load="lazily"/>
1031+
<module uri="http://exist-db.org/xquery/jndi" class="org.exist.xquery.modules.jndi.JNDIModule" load="lazily"/>
1032+
<module uri="http://exist-db.org/xquery/mail" class="org.exist.xquery.modules.mail.MailModule" load="lazily"/>
10331033
<!-- module uri="http://exist-db.org/xquery/oracle" class="org.exist.xquery.modules.oracle.OracleModule"/ -->
1034-
<module uri="http://exist-db.org/xquery/persistentlogin" class="org.exist.xquery.modules.persistentlogin.PersistentLoginModule"/>
1035-
<module uri="http://exist-db.org/xquery/process" class="org.exist.xquery.modules.process.ProcessModule"/>
1036-
<module uri="http://exist-db.org/xquery/scheduler" class="org.exist.xquery.modules.scheduler.SchedulerModule"/>
1037-
<module uri="http://exist-db.org/xquery/simple-ql" class="org.exist.xquery.modules.simpleql.SimpleQLModule"/>
1038-
<module uri="http://exist-db.org/xquery/sql" class="org.exist.xquery.modules.sql.SQLModule">
1034+
<module uri="http://exist-db.org/xquery/persistentlogin" class="org.exist.xquery.modules.persistentlogin.PersistentLoginModule" load="lazily"/>
1035+
<module uri="http://exist-db.org/xquery/process" class="org.exist.xquery.modules.process.ProcessModule" load="lazily"/>
1036+
<module uri="http://exist-db.org/xquery/scheduler" class="org.exist.xquery.modules.scheduler.SchedulerModule" load="lazily"/>
1037+
<module uri="http://exist-db.org/xquery/simple-ql" class="org.exist.xquery.modules.simpleql.SimpleQLModule" load="lazily"/>
1038+
<module uri="http://exist-db.org/xquery/sql" class="org.exist.xquery.modules.sql.SQLModule" load="lazily">
10391039

10401040
<!--
10411041
Connection Pools can be setup for SQL connections, for use with sql:get-connection-from-pool($pool-name)
@@ -1067,15 +1067,15 @@
10671067
<parameter name="pool.2.properties.registerMbeans" value="false"/>
10681068
-->
10691069
</module>
1070-
<module uri="http://exist-db.org/xquery/xmldiff" class="org.exist.xquery.modules.xmldiff.XmlDiffModule"/>
1070+
<module uri="http://exist-db.org/xquery/xmldiff" class="org.exist.xquery.modules.xmldiff.XmlDiffModule" load="lazily"/>
10711071
<!--
10721072
XSL:FO Transformation Module
10731073
Valid processor adapters are:
10741074
- org.exist.xquery.modules.xslfo.ApacheFopProcessorAdapter for Apache's FOP
10751075
- org.exist.xquery.modules.xslfo.RenderXXepProcessorAdapter for RenderX's XEP
10761076
- org.exist.xquery.modules.xslfo.AntennaHouseProcessorAdapter for AntennaHouse Formatter
10771077
-->
1078-
<module uri="http://exist-db.org/xquery/xslfo" class="org.exist.xquery.modules.xslfo.XSLFOModule">
1078+
<module uri="http://exist-db.org/xquery/xslfo" class="org.exist.xquery.modules.xslfo.XSLFOModule" load="lazily">
10791079
<parameter name="processorAdapter" value="org.exist.xquery.modules.xslfo.ApacheFopProcessorAdapter"/>
10801080
</module>
10811081

0 commit comments

Comments
 (0)