From 832ca857b2ce661aea176324daf013313c914e20 Mon Sep 17 00:00:00 2001 From: Eric van der Vlist Date: Fri, 30 Apr 2021 18:50:49 +0200 Subject: [PATCH] js-options: implementing housekeeping tasks --- oxygen/js-options/hello.js | 3 +- oxygen/js-options/options.js | 72 +++++++++++++++++++++++++++++++----- 2 files changed, 64 insertions(+), 11 deletions(-) diff --git a/oxygen/js-options/hello.js b/oxygen/js-options/hello.js index 79cfbdf..492777d 100644 --- a/oxygen/js-options/hello.js +++ b/oxygen/js-options/hello.js @@ -2,7 +2,7 @@ hello = function () { include('options.js'); // Instanciation - var options = new Options(authorAccess, 'hello'); + var options = new Options(authorAccess, 'hello', 10); // Set up a couple of options options.setOption('Hello', 'World'); @@ -16,6 +16,7 @@ hello = function () { } // Do the same with file specific options + options.setSystemId(undefined, 2); options.setSystemIdOption('Hello', 'aligator'); options.setSystemIdOption('See you later', 'World'); var myOptions = options.getSystemIdOptions(); diff --git a/oxygen/js-options/options.js b/oxygen/js-options/options.js index 2714b35..3c8b814 100644 --- a/oxygen/js-options/options.js +++ b/oxygen/js-options/options.js @@ -2,21 +2,38 @@ * Main features */ -Options = function (authorAccess, namespace) { +Options = function (authorAccess, namespace, lifetime) { this.namespace = namespace; this.authorAccess = authorAccess; this.optionsStorage = this.authorAccess.getOptionsStorage(); + this.lifetime = lifetime; + this.expiration = Options.getExpiration(lifetime); + // Consider namespaces as a SYSTEM option if (namespace != Options.SYSTEM) { this.systemOptions = new Options(authorAccess, Options.SYSTEM); var namespaces = JSON.parse(this.systemOptions.getOption(Options.NAMESPACES, '{}')); - namespaces[ this.namespace] = (new Date()).toISOString(); - this.systemOptions.setOption(Options.NAMESPACES, JSON.stringify(namespaces)) + namespaces[ this.namespace] = this.expiration; + this.systemOptions.setOption(Options.NAMESPACES, JSON.stringify(namespaces)); + this.__cleanup__(); } } Options.SYSTEM = '__system__'; Options.NAMESPACES = '__namespaces__'; +Options.HOUSEKEEPING = '__housekeeping__'; +Options.HOUSEKEEPING_PERIOD = 1; + +Options.getExpiration = function (lifetime) { + if (lifetime === undefined) { + return null; + } else { + var d = new Date(); + d.setDate(d.getDate() + lifetime); + return d.toISOString(); + } +} + Options.prototype.getOption = function (key, defaultValue) { this.optionsStorage.setOptionsDoctypePrefix(this.namespace); @@ -26,7 +43,7 @@ Options.prototype.getOption = function (key, defaultValue) { Options.prototype.setOption = function (key, value) { this.optionsStorage.setOptionsDoctypePrefix(Options.SYSTEM); var options = JSON.parse(this.optionsStorage.getOption(this.namespace, '{}')); - options[key] = (new Date()).toISOString(); + options[key] = this.expiration; this.optionsStorage.setOption(this.namespace, JSON.stringify(options)); this.optionsStorage.setOptionsDoctypePrefix(this.namespace); this.optionsStorage.setOption(key, value); @@ -38,7 +55,8 @@ Options.prototype.getOptionsKeys = function () { } Options.prototype.getOptions = function () { - var results = {}; + var results = { + }; var options = this.getOptionsKeys(); for (var key in options) { results[key] = this.getOption(key, ''); @@ -48,24 +66,29 @@ Options.prototype.getOptions = function () { /* * Per file extensions - * + * * Setting a systemID creates a new namespace that concatenates the current namespace * and the SHA1 of the document ID. - * + * * Access to the options of this namespace is done through specific methods. - * + * * The reverse mapping (SHA1 to system ID) is stored using the __systemIds__ namespace. * */ Options.SYSTEMIDS = '__systemIds__'; -Options.prototype.setSystemId = function (systemID) { +Options.prototype.setSystemId = function (systemID, lifetime) { if (systemID === undefined) { this.systemId = String(this.authorAccess.getDocumentController().getAuthorDocumentNode().getSystemID()); } else { this.systemId = String(systemID); } + if (lifetime === undefined) { + this.systemIdLifetime = this.lifetime; + } else { + this.systemIdLifetime = lifetime; + } var md = java.security.MessageDigest.getInstance("SHA-1"); var digestBytes = md.digest(java.lang.String(this.systemId).getBytes(java.nio.charset.Charset.forName("UTF-8"))); this.systemIdDigest = javax.xml.bind.DatatypeConverter.printHexBinary(digestBytes); @@ -75,7 +98,7 @@ Options.prototype.setSystemId = function (systemID) { systemId: this.systemId } this.systemOptions.setOption(Options.SYSTEMIDS, JSON.stringify(systemIds)); - this.systemIdOptions = new Options(this.authorAccess, this.namespace + '.' + this.systemIdDigest); + this.systemIdOptions = new Options(this.authorAccess, this.namespace + '.' + this.systemIdDigest, this.systemIdLifetime); } Options.prototype.setSystemIdOption = function (key, value) { @@ -112,3 +135,32 @@ Options.prototype.getSystemOptions = function () { } return this.systemIdOptions.getSystemOptions(); } + +/* + * + * Housekeeping + * + */ + + +Options.prototype.__cleanup__ = function () { + + var nextCleanup = this.systemOptions.getOption(Options.HOUSEKEEPING, null); + Packages.java.lang.System.out.println('nextCleanup: ' + nextCleanup); + if (nextCleanup === null) { + this.systemOptions.setOption(Options.HOUSEKEEPING, Options.getExpiration(Options.HOUSEKEEPING_PERIOD)); + } else { + var currentDate = (new Date()).toISOString(); + if (nextCleanup <= currentDate || true) { + Packages.java.lang.System.out.println('Time to clean !'); + var namespaces = JSON.parse(this.systemOptions.getOption(Options.NAMESPACES, '{}')); + for (var name in namespaces) { + this.__cleanupNamespace__(name, namespaces[name], currentDate); + } + } + } +} + +Options.prototype.__cleanupNamespace__ = function (name, expiration, currentDate) { + Packages.java.lang.System.out.println('Cleanup for ' + name) +}