308 lines
7.6 KiB
JavaScript
308 lines
7.6 KiB
JavaScript
|
//
|
||
|
// 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);
|
||
|
};
|