helma/modules/jala/code/RemoteContent.js

308 lines
7.6 KiB
JavaScript
Raw Normal View History

2020-03-16 16:53:52 +01:00
//
// Jala Project [http://opensvn.csie.org/traccgi/jala]
//
// Copyright 2004 ORF Online und Teletext GmbH
//
// Licensed under the Apache License, Version 2.0 (the ``License'');
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an ``AS IS'' BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// $Revision$
// $LastChangedBy$
// $LastChangedDate$
// $HeadURL$
//
/**
* @fileoverview Fields and methods of the jala.RemoteContent class.
*/
// HelmaLib dependencies
app.addRepository("modules/core/String.js");
app.addRepository("modules/core/Object.js");
app.addRepository("modules/core/Date.js");
app.addRepository("modules/helma/Http.js");
// Define the global namespace for Jala modules
if (!global.jala) {
global.jala = {};
}
/**
* Construct a new remote content handler.
* @class API to define, fetch and update content
* from a remote site.
* @param {String} url The URL string of the remote site.
* @param {Integer} method The method to retrieve the remote content.
* @param {File} storage The cache directory.
* @returns A new remote content handler.
* @extends helma.Http
* @constructor
*/
jala.RemoteContent = function(url, method, storage) {
if (typeof PropertyMgr == "undefined")
var PropertyMgr = {};
var NULLSTR = "";
var key = url.md5();
var fname = key + jala.RemoteContent.SUFFIX;
var cache;
method = (method != null ? method.toLowerCase() : null);
// depending on the method argument the instance
// becomes extent of the appropriate remote client
switch (method) {
case jala.RemoteContent.XMLRPC:
break;
default:
helma.Http.call(this);
break;
}
if (!storage) {
storage = jala.RemoteContent.CACHEDIR;
if (!storage.exists() || !storage.isDirectory())
storage.mkdir(storage.getAbsolutePath());
}
var getCache = function() {
switch (storage.constructor) {
case HopObject:
cache = storage;
break;
case PropertyMgr:
cache = storage.getAll();
break;
default:
var f = new File(storage, fname);
cache = f.exists() ? Xml.read(f) : new HopObject();
}
return cache;
};
var setCache = function() {
cache.url = url;
cache.method = method;
if (!cache.interval) {
cache.interval = Date.ONEHOUR;
}
cache.lastUpdate = new Date();
cache = cache.clone(new HopObject());
switch (storage.constructor) {
case HopObject:
for (var i in cache)
storage[i] = cache[i];
break;
case PropertyMgr:
storage.setAll(cache);
break;
default:
var f = new File(storage, fname);
Xml.write(cache, f);
}
return;
};
cache = getCache();
/**
* Set the interval the remote content's
* cache is bound to be updated.
* @param {Number} interval The interval value in milliseconds.
*/
this.setInterval = function(interval) {
cache.interval = parseInt(interval, 10);
return;
};
/**
* Get an arbitrary property of the remote content.
* @param {String} key The name of the property.
* @returns The value of the property.
*/
this.get = function(key) {
return cache[key];
}
/**
* Get all available property names.
* @returns The list of property names.
* @type Array
*/
this.getKeys = function() {
var keys = [];
for (var i in cache) {
keys.push(i);
}
return keys.sort();
};
/**
* Tests whether the remote content needs to be updated.
* @returns True if the remote content needs to be updated.
* @type Boolean
*/
this.needsUpdate = function() {
if (!cache.lastUpdate) {
return true;
} else {
var max = new Date() - cache.interval;
if (max - cache.lastUpdate > 0) {
return true;
}
}
return false;
};
/**
* Get the updated and cached remote content.
* @returns The content as retrieved from the remote site.
* @type String
*/
this.update = function() {
app.debug("[jala.RemoteContent] Retrieving " + url);
var result;
switch (method) {
case jala.RemoteContent.XMLRPC:
break;
default:
result = this.getUrl(url, cache.lastModified || cache.eTag);
if (result.code != 200 && cache.content) {
// preserve the content received before
result.content = cache.content;
}
result.interval = cache.interval;
cache = result;
}
setCache();
return cache.content;
};
/**
* Flushes (empties) the cached remote content.
*/
this.clear = function() {
switch (storage.constructor) {
case HopObject:
for (var i in storage)
delete storage[i];
break;
case PropertyMgr:
storage.reset();
break;
default:
var f = new File(storage, fname);
f.remove();
}
return;
};
/**
* Get a string representation of the remote content.
* @returns The remote content as string.
* @type String
*/
this.toString = function() {
return cache.content || NULLSTR;
};
/**
* Get the value of the remote content.
* @returns The remote content including response header data.
* @type Object
*/
this.valueOf = function() {
return cache;
};
return this;
};
/**
* A constant representing the HTTP retrieval method.
* @type int
* @final
*/
jala.RemoteContent.HTTP = 1;
/**
* A constant representing the XML-RPC retrieval method.
* @type int
* @final
*/
jala.RemoteContent.XMLRPC = 2;
/**
* The default name of the cache directory.
* @type String
* @final
*/
jala.RemoteContent.SUFFIX = ".cache";
/**
* The default cache directory.
* @type File
* @final
*/
jala.RemoteContent.CACHEDIR = new File(app.dir, jala.RemoteContent.SUFFIX);
/**
* Remove all remote content from a file-based cache.
* @param {File} cache An optional target directory.
*/
jala.RemoteContent.flush = function(cache) {
jala.RemoteContent.forEach(function(rc) {
rc.clear();
return;
});
return;
};
/**
* Apply a custom method on all remote content in a file-based cache.
* @param {Function} callback The callback method to be executed
* for each remote content file.
* @param {File} cache An optional target directory.
*/
jala.RemoteContent.forEach = function(callback, cache) {
if (!cache)
cache = jala.RemoteContent.CACHEDIR;
var f, rc;
var files = cache.list();
for (var i in files) {
f = new File(cache, files[i]);
if (!files[i].endsWith(jala.RemoteContent.SUFFIX))
continue;
rc = new jala.RemoteContent(Xml.read(f).url);
if (callback && callback.constructor == Function)
callback(rc);
}
return;
};
/**
* Apply a custom method on all remote content in a file-based cache.
* @param {Function} callback The callback method to be executed
* for each remote content file.
* @param {File} cache An optional target directory.
* @deprecated Use {@link #forEach} instead.
*/
jala.RemoteContent.exec = function() {
jala.RemoteContent.forEach.apply(this, arguments);
};