initial commit of modules with javascript library structure for Helma 1.5
This commit is contained in:
parent
72d15e11ab
commit
66876ba214
23 changed files with 6174 additions and 0 deletions
112
core/Array.js
Normal file
112
core/Array.js
Normal file
|
@ -0,0 +1,112 @@
|
||||||
|
/*
|
||||||
|
* Helma License Notice
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Helma License
|
||||||
|
* Version 2.0 (the "License"). You may not use this file except in
|
||||||
|
* compliance with the License. A copy of the License is available at
|
||||||
|
* http://adele.helma.org/download/helma/license.txt
|
||||||
|
*
|
||||||
|
* Copyright 1998-2006 Helma Software. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* $RCSfile: Array.js,v $
|
||||||
|
* $Author: czv $
|
||||||
|
* $Revision: 1.5 $
|
||||||
|
* $Date: 2006/04/18 13:06:58 $
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* retrieve the union set of a bunch of arrays
|
||||||
|
* @param Array (Array2, ...) the arrays to unify
|
||||||
|
* @return Array the union set
|
||||||
|
*/
|
||||||
|
Array.union = function() {
|
||||||
|
var result = [];
|
||||||
|
var map = {};
|
||||||
|
for (var i=0; i<arguments.length; i+=1) {
|
||||||
|
for (var n in arguments[i]) {
|
||||||
|
var item = arguments[i][n];
|
||||||
|
if (!map[item]) {
|
||||||
|
result.push(item);
|
||||||
|
map[item] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* retrieve the intersection set of a bunch of arrays
|
||||||
|
* @param Array (Array2, ...) the arrays to intersect
|
||||||
|
* @return Array the intersection set
|
||||||
|
*/
|
||||||
|
Array.intersection = function() {
|
||||||
|
var all = Array.union.apply(this, arguments);
|
||||||
|
var result = [];
|
||||||
|
for (var n in all) {
|
||||||
|
var chksum = 0;
|
||||||
|
var item = all[n];
|
||||||
|
for (var i=0; i<arguments.length; i+=1) {
|
||||||
|
if (arguments[i].contains(item))
|
||||||
|
chksum += 1;
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (chksum == arguments.length)
|
||||||
|
result.push(item);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return the first index position of a value
|
||||||
|
* contained in an array
|
||||||
|
* @param Object Array to use for checking
|
||||||
|
* @param String|Object the String or Object to check
|
||||||
|
*/
|
||||||
|
Array.prototype.indexOf = function(val) {
|
||||||
|
var i = -1;
|
||||||
|
while (i++ < this.length -1) {
|
||||||
|
if (this[i] == val)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return the last index position of a value
|
||||||
|
* contained in an array
|
||||||
|
* @param Object Array to use for checking
|
||||||
|
* @param String|Object the String or Object to check
|
||||||
|
*/
|
||||||
|
Array.prototype.lastIndexOf = function(val) {
|
||||||
|
var i = 1;
|
||||||
|
while (this.length - i++ >= 0) {
|
||||||
|
if (this[i] == val)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* check if an array passed as argument contains
|
||||||
|
* a specific value (start from end of array)
|
||||||
|
* @param Object Array to use for checking
|
||||||
|
* @param String|Object the String or Object to check
|
||||||
|
*/
|
||||||
|
Array.prototype.contains = function(val) {
|
||||||
|
if (this.indexOf(val) > -1)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// prevent any newly added properties from being enumerated
|
||||||
|
for (var i in Array)
|
||||||
|
Array.dontEnum(i);
|
||||||
|
for (var i in Array.prototype)
|
||||||
|
Array.prototype.dontEnum(i);
|
185
core/Date.js
Normal file
185
core/Date.js
Normal file
|
@ -0,0 +1,185 @@
|
||||||
|
/*
|
||||||
|
* Helma License Notice
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Helma License
|
||||||
|
* Version 2.0 (the "License"). You may not use this file except in
|
||||||
|
* compliance with the License. A copy of the License is available at
|
||||||
|
* http://adele.helma.org/download/helma/license.txt
|
||||||
|
*
|
||||||
|
* Copyright 1998-2005 Helma Software. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* $RCSfile: Date.js,v $
|
||||||
|
* $Author: czv $
|
||||||
|
* $Revision: 1.5 $
|
||||||
|
* $Date: 2006/04/18 13:06:58 $
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
Date.ONESECOND = 1000;
|
||||||
|
Date.ONEMINUTE = 60 * Date.ONESECOND;
|
||||||
|
Date.ONEHOUR = 60 * Date.ONEMINUTE;
|
||||||
|
Date.ONEDAY = 24 * Date.ONEHOUR;
|
||||||
|
Date.ONEWEEK = 7 * Date.ONEDAY;
|
||||||
|
Date.ONEMONTH = 30 * Date.ONEDAY;
|
||||||
|
Date.ONEYEAR = 12 * Date.ONEMONTH;
|
||||||
|
Date.ISOFORMAT = "yyyy-MM-dd'T'HH:mm:ss'Z'";
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* format a Date to a string
|
||||||
|
* @param String Format pattern
|
||||||
|
* @param Object Java Locale Object (optional)
|
||||||
|
* @param Object Java TimeZone Object (optional)
|
||||||
|
* @return String formatted Date
|
||||||
|
*/
|
||||||
|
Date.prototype.format = function (format, locale, timezone) {
|
||||||
|
if (!format)
|
||||||
|
return this.toString();
|
||||||
|
var sdf = locale ? new java.text.SimpleDateFormat(format, locale)
|
||||||
|
: new java.text.SimpleDateFormat(format);
|
||||||
|
if (timezone && timezone != sdf.getTimeZone())
|
||||||
|
sdf.setTimeZone(timezone);
|
||||||
|
return sdf.format(this);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* set the date/time to UTC by subtracting
|
||||||
|
* the timezone offset
|
||||||
|
*/
|
||||||
|
Date.prototype.toUtc = function() {
|
||||||
|
this.setMinutes(this.getMinutes() + this.getTimezoneOffset());
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* set the date/time to local time by adding
|
||||||
|
* the timezone offset
|
||||||
|
*/
|
||||||
|
Date.prototype.toLocalTime = function() {
|
||||||
|
this.setMinutes(this.getMinutes() - this.getTimezoneOffset());
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns the difference between this and another
|
||||||
|
* date object in milliseconds
|
||||||
|
*/
|
||||||
|
Date.prototype.diff = function(dateObj) {
|
||||||
|
return this.getTime() - dateObj.getTime();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return the timespan to current date/time or a different Date object
|
||||||
|
* @param Object parameter object containing optional properties:
|
||||||
|
* .now = String to use if difference is < 1 minute
|
||||||
|
* .day|days = String to use for single|multiple day(s)
|
||||||
|
* .hour|hours = String to use for single|multiple hour(s)
|
||||||
|
* .minute|minutes = String to use for single|multiple minute(s)
|
||||||
|
* .date = Date object to use for calculating the timespan
|
||||||
|
* @return Object containing properties:
|
||||||
|
* .isFuture = (Boolean)
|
||||||
|
* .span = (String) timespan
|
||||||
|
* @see Date.prototype.getAge, Date.prototype.getExpiry
|
||||||
|
*/
|
||||||
|
Date.prototype.getTimespan = function(param) {
|
||||||
|
if (!param)
|
||||||
|
param = {date: new Date()};
|
||||||
|
else if (!param.date)
|
||||||
|
param.date = new Date();
|
||||||
|
|
||||||
|
var result = {isFuture: this > param.date};
|
||||||
|
var diff = Math.abs(param.date.diff(this));
|
||||||
|
var age = {days: Math.floor((diff % Date.ONEMONTH) / Date.ONEDAY),
|
||||||
|
hours: Math.floor((diff % Date.ONEDAY) / Date.ONEHOUR),
|
||||||
|
minutes: Math.floor((diff % Date.ONEHOUR) / Date.ONEMINUTE)};
|
||||||
|
|
||||||
|
res.push();
|
||||||
|
if (diff < Date.ONEMINUTE)
|
||||||
|
res.write(param.now || "now");
|
||||||
|
else {
|
||||||
|
var arr = [{one: "day", many: "days"},
|
||||||
|
{one: "hour", many: "hours"},
|
||||||
|
{one: "minute", many: "minutes"}];
|
||||||
|
for (var i in arr) {
|
||||||
|
var value = age[arr[i].many];
|
||||||
|
if (value != 0) {
|
||||||
|
var prop = (value == 1 ? arr[i].one : arr[i].many);
|
||||||
|
res.write(value);
|
||||||
|
res.write(" ");
|
||||||
|
res.write(param[prop] || prop);
|
||||||
|
if (i < arr.length -1)
|
||||||
|
res.write(param.delimiter || ", ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result.span = res.pop();
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return the past timespan between this Date object and
|
||||||
|
* the current Date or a different Date object
|
||||||
|
* @see Date.prototype.getTimespan
|
||||||
|
*/
|
||||||
|
Date.prototype.getAge = function(param) {
|
||||||
|
var age = this.getTimespan(param);
|
||||||
|
if (!age.isFuture)
|
||||||
|
return age.span;
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return the future timespan between this Date object and
|
||||||
|
* the current Date or a different Date object
|
||||||
|
* @see Date.prototype.getTimespan
|
||||||
|
*/
|
||||||
|
Date.prototype.getExpiry = function(param) {
|
||||||
|
var age = this.getTimespan(param);
|
||||||
|
if (age.isFuture)
|
||||||
|
return age.span;
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* checks if a date object equals another date object
|
||||||
|
* @param Object Date object to compare
|
||||||
|
* @param Int indicating how far the comparison should go
|
||||||
|
* @return Boolean
|
||||||
|
*/
|
||||||
|
Date.prototype.equals = function(date, extend) {
|
||||||
|
if (!extend)
|
||||||
|
var extend = Date.ONEDAY;
|
||||||
|
switch (extend) {
|
||||||
|
case Date.ONESECOND:
|
||||||
|
if (this.getSeconds() != date.getSeconds())
|
||||||
|
return false;
|
||||||
|
case Date.ONEMINUTE:
|
||||||
|
if (this.getMinutes() != date.getMinutes())
|
||||||
|
return false;
|
||||||
|
case Date.ONEHOUR:
|
||||||
|
if (this.getHours() != date.getHours())
|
||||||
|
return false;
|
||||||
|
case Date.ONEDAY:
|
||||||
|
if (this.getDate() != date.getDate())
|
||||||
|
return false;
|
||||||
|
case Date.ONEMONTH:
|
||||||
|
if (this.getMonth() != date.getMonth())
|
||||||
|
return false;
|
||||||
|
case Date.ONEYEAR:
|
||||||
|
if (this.getFullYear() != date.getFullYear())
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// prevent any newly added properties from being enumerated
|
||||||
|
for (var i in Date)
|
||||||
|
Date.dontEnum(i);
|
||||||
|
for (var i in Date.prototype)
|
||||||
|
Date.prototype.dontEnum(i);
|
68
core/Number.js
Normal file
68
core/Number.js
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
/*
|
||||||
|
* Helma License Notice
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Helma License
|
||||||
|
* Version 2.0 (the "License"). You may not use this file except in
|
||||||
|
* compliance with the License. A copy of the License is available at
|
||||||
|
* http://adele.helma.org/download/helma/license.txt
|
||||||
|
*
|
||||||
|
* Copyright 1998-2006 Helma Software. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* $RCSfile: Number.js,v $
|
||||||
|
* $Author: hannes $
|
||||||
|
* $Revision: 1.5 $
|
||||||
|
* $Date: 2006/04/18 13:06:58 $
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* factory to create functions for sorting objects in an array
|
||||||
|
* @param String name of the field each object is compared with
|
||||||
|
* @param Number order (ascending or descending)
|
||||||
|
* @return Function ready for use in Array.prototype.sort
|
||||||
|
*/
|
||||||
|
Number.Sorter = function(field, order) {
|
||||||
|
if (!order)
|
||||||
|
order = 1;
|
||||||
|
return function(a, b) {
|
||||||
|
return (a[field] - b[field]) * order;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
Number.Sorter.ASC = 1;
|
||||||
|
Number.Sorter.DESC = -1;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* format a Number to a String
|
||||||
|
* @param String Format pattern
|
||||||
|
* @return String Number formatted to a String
|
||||||
|
* FIXME: this might need some localisation
|
||||||
|
*/
|
||||||
|
Number.prototype.format = function(fmt) {
|
||||||
|
var df = fmt ? new java.text.DecimalFormat(fmt)
|
||||||
|
: new java.text.DecimalFormat("#,##0.00");
|
||||||
|
return df.format(0+this);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return the percentage of a Number
|
||||||
|
* according to a given total Number
|
||||||
|
* @param Int Total
|
||||||
|
* @param String Format Pattern
|
||||||
|
* @return Int Percentage
|
||||||
|
*/
|
||||||
|
Number.prototype.toPercent = function(total, fmt) {
|
||||||
|
var p = this / (total / 100);
|
||||||
|
if (!fmt)
|
||||||
|
return Math.round(p * 100) / 100;
|
||||||
|
return p.format(fmt);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// prevent any newly added properties from being enumerated
|
||||||
|
for (var i in Number)
|
||||||
|
Number.dontEnum(i);
|
||||||
|
for (var i in Number.prototype)
|
||||||
|
Number.prototype.dontEnum(i);
|
105
core/Object.js
Normal file
105
core/Object.js
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
/*
|
||||||
|
* Helma License Notice
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Helma License
|
||||||
|
* Version 2.0 (the "License"). You may not use this file except in
|
||||||
|
* compliance with the License. A copy of the License is available at
|
||||||
|
* http://adele.helma.org/download/helma/license.txt
|
||||||
|
*
|
||||||
|
* Copyright 1998-2006 Helma Software. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* $RCSfile: Object.js,v $
|
||||||
|
* $Author: czv $
|
||||||
|
* $Revision: 1.6 $
|
||||||
|
* $Date: 2006/04/18 13:06:58 $
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* copy the properties of an object into
|
||||||
|
* a new object
|
||||||
|
* @param Object the source object
|
||||||
|
* @param Object the (optional) target object
|
||||||
|
* @return Object the resulting object
|
||||||
|
*/
|
||||||
|
Object.prototype.clone = function(clone, recursive) {
|
||||||
|
if (!clone)
|
||||||
|
clone = new this.constructor();
|
||||||
|
var value;
|
||||||
|
for (var propName in this) {
|
||||||
|
value = this[propName];
|
||||||
|
if (recursive && (value.constructor == HopObject || value.constructor == Object)) {
|
||||||
|
clone[propName] = value.clone(new value.constructor(), recursive);
|
||||||
|
} else {
|
||||||
|
clone[propName] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return clone;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* reduce an extended object (ie. a HopObject)
|
||||||
|
* to a generic javascript object
|
||||||
|
* @param HopObject the HopObject to be reduced
|
||||||
|
* @return Object the resulting generic object
|
||||||
|
*/
|
||||||
|
Object.prototype.reduce = function(recursive) {
|
||||||
|
var result = {};
|
||||||
|
for (var i in this) {
|
||||||
|
if (this[i] instanceof HopObject == false)
|
||||||
|
result[i] = this[i];
|
||||||
|
else if (recursive)
|
||||||
|
result[i] = this.reduce(true);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* print the contents of an object for debugging
|
||||||
|
* @param Object the object to dump
|
||||||
|
* @param Boolean recursive flag (if true, dump child objects, too)
|
||||||
|
*/
|
||||||
|
Object.prototype.dump = function(recursive) {
|
||||||
|
var beginList = "<ul>";
|
||||||
|
var endList = "</ul>";
|
||||||
|
var beginItem = "<li>";
|
||||||
|
var endItem = "</li>";
|
||||||
|
var beginKey = "<strong>";
|
||||||
|
var endKey = ":</strong> ";
|
||||||
|
res.write(beginList);
|
||||||
|
for (var p in this) {
|
||||||
|
res.write(beginItem);
|
||||||
|
res.write(beginKey);
|
||||||
|
res.write(p);
|
||||||
|
res.write(endKey);
|
||||||
|
if (recursive && typeof this[p] == "object") {
|
||||||
|
var recurse = true;
|
||||||
|
var types = [Function, Date, String, Number];
|
||||||
|
for (var i in types) {
|
||||||
|
if (this[p] instanceof types[i]) {
|
||||||
|
recurse = false
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (recurse == true)
|
||||||
|
this[p].dump(true);
|
||||||
|
else {
|
||||||
|
res.write(this[p].toSource());
|
||||||
|
}
|
||||||
|
} else if (this[p]) {
|
||||||
|
res.write(encode(this[p].toSource()));
|
||||||
|
}
|
||||||
|
res.write(endItem);
|
||||||
|
}
|
||||||
|
res.write(endList);
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// prevent any newly added properties from being enumerated
|
||||||
|
for (var i in Object)
|
||||||
|
Object.dontEnum(i);
|
||||||
|
for (var i in Object.prototype)
|
||||||
|
Object.prototype.dontEnum(i);
|
638
core/String.js
Normal file
638
core/String.js
Normal file
|
@ -0,0 +1,638 @@
|
||||||
|
/*
|
||||||
|
* Helma License Notice
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Helma License
|
||||||
|
* Version 2.0 (the "License"). You may not use this file except in
|
||||||
|
* compliance with the License. A copy of the License is available at
|
||||||
|
* http://adele.helma.org/download/helma/license.txt
|
||||||
|
*
|
||||||
|
* Copyright 1998-2006 Helma Software. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* $RCSfile: helma.String.js,v $
|
||||||
|
* $Author: czv $
|
||||||
|
* $Revision: 1.5 $
|
||||||
|
* $Date: 2006/04/18 13:06:58 $
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
String.ANUMPATTERN = /[^a-zA-Z0-9]/;
|
||||||
|
String.APATTERN = /[^a-zA-Z]/;
|
||||||
|
String.NUMPATTERN = /[^0-9]/;
|
||||||
|
String.FILEPATTERN = /[^a-zA-Z0-9-_\. ]/;
|
||||||
|
String.HEXPATTERN = /[^a-fA-F0-9]/;
|
||||||
|
String.EMAILPATTERN = /^.+@.+\.[a-zA-Z]+$/;
|
||||||
|
String.URLPATTERN = /^([^:]*):\/\/+(?:([^\/]*):)?(?:([^\/]*)@)?([\w\-_.]*[^.])(\/[^?]*)?(?:\?(.*))?$/;
|
||||||
|
String.LEFT = -1
|
||||||
|
String.BALANCE = 0
|
||||||
|
String.RIGHT = 1
|
||||||
|
String.ISOFORMAT = "yyyy-MM-dd'T'HH:mm:ssZ";
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* factory to create functions for sorting objects in an array
|
||||||
|
* @param String name of the field each object is compared with
|
||||||
|
* @param Number order (ascending or descending)
|
||||||
|
* @return Function ready for use in Array.prototype.sort
|
||||||
|
*/
|
||||||
|
String.Sorter = function(field, order) {
|
||||||
|
if (!order)
|
||||||
|
order = 1;
|
||||||
|
var key = field + ":" + order;
|
||||||
|
if (!String.Sorter.cache[key]) {
|
||||||
|
String.Sorter.cache[key] = function(a, b) {
|
||||||
|
var str1 = String(a[field] || "").toLowerCase();
|
||||||
|
var str2 = String(b[field] || "").toLowerCase();
|
||||||
|
if (str1 > str2)
|
||||||
|
return order * 1;
|
||||||
|
if (str1 < str2)
|
||||||
|
return order * -1;
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return String.Sorter.cache[key];
|
||||||
|
};
|
||||||
|
|
||||||
|
String.Sorter.ASC = 1;
|
||||||
|
String.Sorter.DESC = -1;
|
||||||
|
String.Sorter.cache = {};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create a string from a bunch of substrings
|
||||||
|
* @param String one or more strings as arguments
|
||||||
|
* @return String the resulting string
|
||||||
|
*/
|
||||||
|
String.compose = function() {
|
||||||
|
res.push();
|
||||||
|
for (var i=0; i<arguments.length; i++)
|
||||||
|
res.write(arguments[i]);
|
||||||
|
return res.pop();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* creates a random string (numbers and chars)
|
||||||
|
* @param len length of key
|
||||||
|
* @param mode determines which letters to use. null or 0 = all letters;
|
||||||
|
* 1 = skip 0, 1, l and o which can easily be mixed with numbers;
|
||||||
|
* 2 = use numbers only
|
||||||
|
* @returns random string
|
||||||
|
*/
|
||||||
|
String.random = function(len, mode) {
|
||||||
|
if (mode == 2) {
|
||||||
|
var x = Math.random() * Math.pow(10,len);
|
||||||
|
return Math.floor(x);
|
||||||
|
}
|
||||||
|
var keystr = "";
|
||||||
|
for (var i=0; i<len; i++) {
|
||||||
|
var x = Math.floor((Math.random() * 36));
|
||||||
|
if (mode == 1) {
|
||||||
|
// skip 0,1
|
||||||
|
x = (x<2) ? x + 2 : x;
|
||||||
|
// don't use the letters l (charCode 21+87) and o (24+87)
|
||||||
|
x = (x==21) ? 22 : x;
|
||||||
|
x = (x==24) ? 25 : x;
|
||||||
|
}
|
||||||
|
if (x<10) {
|
||||||
|
keystr += String(x);
|
||||||
|
} else {
|
||||||
|
keystr += String.fromCharCode(x+87);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return keystr;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* append one string onto another and add some "glue"
|
||||||
|
* if none of the strings is empty or null.
|
||||||
|
* @param String the first string
|
||||||
|
* @param String the string to be appended onto the first one
|
||||||
|
* @param String the "glue" to be inserted between both strings
|
||||||
|
* @return String the resulting string
|
||||||
|
*/
|
||||||
|
String.join = function(str1, str2, glue) {
|
||||||
|
if (glue == null)
|
||||||
|
glue = "";
|
||||||
|
if (str1 && str2)
|
||||||
|
return str1 + glue + str2;
|
||||||
|
else if (str2)
|
||||||
|
return str2;
|
||||||
|
return str1;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* checks if a date format pattern is correct
|
||||||
|
* @return Boolean true if the pattern is correct
|
||||||
|
*/
|
||||||
|
String.prototype.isDateFormat = function() {
|
||||||
|
try {
|
||||||
|
new java.text.SimpleDateFormat(this);
|
||||||
|
return true;
|
||||||
|
} catch (err) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* parse a timestamp into a date object. This is used when users
|
||||||
|
* want to set createtime explicitly when creating/editing stories.
|
||||||
|
* @param String date format to be applied
|
||||||
|
* @param Object Java TimeZone Object (optional)
|
||||||
|
* @return Object contains the resulting date
|
||||||
|
*/
|
||||||
|
String.prototype.toDate = function(format, timezone) {
|
||||||
|
var sdf = res.data._dateformat;
|
||||||
|
if (!sdf) {
|
||||||
|
sdf = new java.text.SimpleDateFormat(format);
|
||||||
|
res.data._dateformat = sdf;
|
||||||
|
} else if (format != sdf.toPattern())
|
||||||
|
sdf.applyPattern(format);
|
||||||
|
if (timezone && timezone != sdf.getTimeZone())
|
||||||
|
sdf.setTimeZone(timezone);
|
||||||
|
try {
|
||||||
|
return new Date(sdf.parse(this).getTime());
|
||||||
|
} catch (err) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* function checks if the string passed contains any characters that
|
||||||
|
* are forbidden in URLs and tries to create a java.net.URL from it
|
||||||
|
* FIXME: probably deprecated -> helma.Url
|
||||||
|
* @return Boolean
|
||||||
|
* @see helma.Url.PATTERN
|
||||||
|
*/
|
||||||
|
String.prototype.isUrl = function() {
|
||||||
|
if (String.URLPATTERN.test(this))
|
||||||
|
return true;
|
||||||
|
try {
|
||||||
|
return new java.net.URL(this);
|
||||||
|
} catch (err) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* function checks if the string passed contains any characters
|
||||||
|
* that are forbidden in image- or filenames
|
||||||
|
* @return Boolean
|
||||||
|
*/
|
||||||
|
String.prototype.isFileName = function() {
|
||||||
|
return !String.FILEPATTERN.test(this);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* function cleans the string passed as argument from any characters
|
||||||
|
* that are forbidden or shouldn't be used in filenames
|
||||||
|
* @return Boolean
|
||||||
|
*/
|
||||||
|
String.prototype.toFileName = function() {
|
||||||
|
return this.replace(new RegExp(String.FILEPATTERN.source, "g"), "");
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* function checks a string for a valid color value in hexadecimal format.
|
||||||
|
* it may also contain # as first character
|
||||||
|
* @returns Boolean false, if string length (without #) > 6 or < 6 or
|
||||||
|
* contains any character which is not a valid hex value
|
||||||
|
*/
|
||||||
|
String.prototype.isHexColor = function() {
|
||||||
|
var str = this;
|
||||||
|
if (this.indexOf("#") == 0)
|
||||||
|
str = this.substring(1);
|
||||||
|
if (str.length != 6)
|
||||||
|
return false;
|
||||||
|
return !String.HEXPATTERN.test(str);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* converts a string into a hexadecimal color
|
||||||
|
* representation (e.g. "ffcc33"). also knows how to
|
||||||
|
* convert a color string like "rgb (255, 204, 51)".
|
||||||
|
* @return String the resulting hex color (w/o "#")
|
||||||
|
*/
|
||||||
|
String.prototype.toHexColor = function() {
|
||||||
|
if (this.startsWith("rgb")) {
|
||||||
|
res.push();
|
||||||
|
var col = this.replace(/[^0-9,]/g,"");
|
||||||
|
var parts = col.split(",");
|
||||||
|
for (var i in parts) {
|
||||||
|
var num = parseInt(parts[i], 10);
|
||||||
|
var hex = num.toString(16);
|
||||||
|
res.write(hex.pad("0", 2, String.LEFT));
|
||||||
|
}
|
||||||
|
return res.pop();
|
||||||
|
}
|
||||||
|
var col = this.replace(new RegExp(String.HEXPATTERN.source), "");
|
||||||
|
return col.toLowerCase().pad("0", 6, String.LEFT);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* function returns true if the string contains
|
||||||
|
* only a-z and 0-9 (case insensitive!)
|
||||||
|
* @return Boolean true in case string is alpha, false otherwise
|
||||||
|
*/
|
||||||
|
String.prototype.isAlphanumeric = function() {
|
||||||
|
if (!this.length)
|
||||||
|
return false;
|
||||||
|
return !String.ANUMPATTERN.test(this);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* function cleans a string by throwing away all
|
||||||
|
* non-alphanumeric characters
|
||||||
|
* @return cleaned string
|
||||||
|
*/
|
||||||
|
String.prototype.toAlphanumeric = function() {
|
||||||
|
return this.replace(new RegExp(String.ANUMPATTERN.source, "g"), "");
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* function returns true if the string contains
|
||||||
|
* only characters a-z
|
||||||
|
* @return Boolean true in case string is alpha, false otherwise
|
||||||
|
*/
|
||||||
|
String.prototype.isAlpha = function() {
|
||||||
|
if (!this.length)
|
||||||
|
return false;
|
||||||
|
return !String.APATTERN.test(this);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* function returns true if the string contains
|
||||||
|
* only 0-9
|
||||||
|
* @return Boolean true in case string is numeric, false otherwise
|
||||||
|
*/
|
||||||
|
String.prototype.isNumeric = function() {
|
||||||
|
if (!this.length)
|
||||||
|
return false;
|
||||||
|
return !String.NUMPATTERN.test(this);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* transforms the first n characters of a string to uppercase
|
||||||
|
* @param Number amount of characters to transform
|
||||||
|
* @return String the resulting string
|
||||||
|
*/
|
||||||
|
String.prototype.capitalize = function(limit) {
|
||||||
|
if (limit == null)
|
||||||
|
limit = 1;
|
||||||
|
var head = this.substring(0, limit);
|
||||||
|
var tail = this.substring(limit, this.length);
|
||||||
|
return head.toUpperCase() + tail.toLowerCase();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* transforms the first n characters of each
|
||||||
|
* word in a string to uppercase
|
||||||
|
* @return String the resulting string
|
||||||
|
*/
|
||||||
|
String.prototype.titleize = function() {
|
||||||
|
var parts = this.split(" ");
|
||||||
|
res.push();
|
||||||
|
for (var i in parts) {
|
||||||
|
res.write(parts[i].capitalize());
|
||||||
|
if (i < parts.length-1)
|
||||||
|
res.write(" ");
|
||||||
|
}
|
||||||
|
return res.pop();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* translates all characters of a string into HTML entities
|
||||||
|
* @return String translated result
|
||||||
|
*/
|
||||||
|
String.prototype.entitize = function() {
|
||||||
|
res.push();
|
||||||
|
for (var i=0; i<this.length; i++) {
|
||||||
|
res.write("&#");
|
||||||
|
res.write(this.charCodeAt(i).toString());
|
||||||
|
res.write(";");
|
||||||
|
}
|
||||||
|
return res.pop();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* breaks up a string into two parts called
|
||||||
|
* head and tail at the given position
|
||||||
|
* don't apply this to HTML, i.e. use stripTags() in advance
|
||||||
|
* @param Number number of charactrers or of segments separated by the delimiter
|
||||||
|
* @param String pre-/suffix to be pre-/appended to shortened string
|
||||||
|
* @param String delimiter
|
||||||
|
* @return Object containing head and tail properties
|
||||||
|
*/
|
||||||
|
String.prototype.embody = function(limit, clipping, delimiter) {
|
||||||
|
if (typeof(limit) == "string")
|
||||||
|
limit = parseInt(limit, 10);
|
||||||
|
var result = {head: this, tail: ""};
|
||||||
|
if (!limit || limit < 1)
|
||||||
|
return result;
|
||||||
|
if (!delimiter || delimiter =="")
|
||||||
|
result.head= this.substring(0,limit);
|
||||||
|
else {
|
||||||
|
var re = new RegExp ("(" + delimiter + "+)");
|
||||||
|
result.head = this.split(re,2*limit-1).join("");
|
||||||
|
}
|
||||||
|
if (result.head != this) {
|
||||||
|
result.tail = this.substring(result.head.length).trim();
|
||||||
|
if (result.tail) {
|
||||||
|
if (clipping == null)
|
||||||
|
clipping = "...";
|
||||||
|
result.head = result.head.trim()+clipping;
|
||||||
|
result.tail = clipping + result.tail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the head of a string
|
||||||
|
* @see String.prototype.embody()
|
||||||
|
*/
|
||||||
|
String.prototype.head = function(limit, clipping, delimiter) {
|
||||||
|
return this.embody(limit, clipping, delimiter).head;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the tail of a string
|
||||||
|
* @see String.prototype.embody()
|
||||||
|
*/
|
||||||
|
String.prototype.tail = function(limit, clipping, delimiter) {
|
||||||
|
return this.embody(limit, clipping, delimiter).tail;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* set clip method out of compatibility/convenience reason
|
||||||
|
* FIXME: we eventually have to get rid of this one...
|
||||||
|
* @see String.prototype.head()
|
||||||
|
*/
|
||||||
|
String.prototype.clip = String.prototype.head;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* function inserts a string every number of characters
|
||||||
|
* @param Int number of characters after which insertion should take place
|
||||||
|
* @param String string to be inserted
|
||||||
|
* @param Boolean definitely insert at each interval position
|
||||||
|
* @return String resulting string
|
||||||
|
*/
|
||||||
|
String.prototype.group = function(interval, str, ignoreWhiteSpace) {
|
||||||
|
if (!interval || interval < 1)
|
||||||
|
interval = 20;
|
||||||
|
if (!str || this.length < interval)
|
||||||
|
return this;
|
||||||
|
res.push();
|
||||||
|
for (var i=0; i<this.length; i=i+interval) {
|
||||||
|
var strPart = this.substring(i, i+interval);
|
||||||
|
res.write(strPart);
|
||||||
|
if (ignoreWhiteSpace == true ||
|
||||||
|
(strPart.length == interval && !/\s/g.test(strPart))) {
|
||||||
|
res.write(str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res.pop();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* replace all linebreaks and optionally all w/br tags
|
||||||
|
* @param Boolean flag indicating if html tags should be replaced
|
||||||
|
* @param String replacement for the linebreaks / html tags
|
||||||
|
* @return String the unwrapped string
|
||||||
|
*/
|
||||||
|
String.prototype.unwrap = function(removeTags, replacement) {
|
||||||
|
if (replacement == null)
|
||||||
|
replacement = "";
|
||||||
|
var str = this.replace(/[\n|\r]/g, replacement);
|
||||||
|
if (removeTags)
|
||||||
|
str = str.replace(/<[w]?br *\/?>/g, replacement);
|
||||||
|
return str;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* function calculates the md5 hash of a string
|
||||||
|
* @return String md5 hash of the string
|
||||||
|
*/
|
||||||
|
String.prototype.md5 = function() {
|
||||||
|
return Packages.helma.util.MD5Encoder.encode(this);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* function repeats a string passed as argument
|
||||||
|
* @param Int amount of repetitions
|
||||||
|
* @return String resulting string
|
||||||
|
*/
|
||||||
|
String.prototype.repeat = function(multiplier) {
|
||||||
|
res.push();
|
||||||
|
for (var i=0; i<multiplier; i++)
|
||||||
|
res.write(this);
|
||||||
|
return res.pop();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* function returns true if the string starts with
|
||||||
|
* the string passed as argument
|
||||||
|
* @param String string pattern to search for
|
||||||
|
* @return Boolean true in case it matches the beginning
|
||||||
|
* of the string, false otherwise
|
||||||
|
*/
|
||||||
|
String.prototype.startsWith = function(str, offset) {
|
||||||
|
var javaObj = new java.lang.String(this);
|
||||||
|
if (offset != null)
|
||||||
|
return javaObj.startsWith(str, offset);
|
||||||
|
return javaObj.startsWith(str);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* function returns true if the string ends with
|
||||||
|
* the string passed as argument
|
||||||
|
* @param String string pattern to search for
|
||||||
|
* @return Boolean true in case it matches the end of
|
||||||
|
* the string, false otherwise
|
||||||
|
*/
|
||||||
|
String.prototype.endsWith = function(str) {
|
||||||
|
var javaObj = new java.lang.String(this);
|
||||||
|
return javaObj.endsWith(str);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fills a string with another string up to a desired length
|
||||||
|
* @param String the filling string
|
||||||
|
* @param Number the desired length of the resulting string
|
||||||
|
* @param Number the direction which the string will be padded in:
|
||||||
|
* -1: left 0: both (balance) 1: right
|
||||||
|
* (you can use the constants String.LEFT,
|
||||||
|
* String.BALANCE and String.RIGHT here as well.)
|
||||||
|
* @return String the resulting string
|
||||||
|
*/
|
||||||
|
String.prototype.pad = function(str, len, mode) {
|
||||||
|
if (str == null || len == null)
|
||||||
|
return this;
|
||||||
|
var diff = len - this.length;
|
||||||
|
if (diff == 0)
|
||||||
|
return this;
|
||||||
|
var left, right = 0;
|
||||||
|
if (mode == null || mode == String.RIGHT)
|
||||||
|
right = diff;
|
||||||
|
else if (mode == String.LEFT)
|
||||||
|
left = diff;
|
||||||
|
else if (mode == String.BALANCE) {
|
||||||
|
right = Math.round(diff / 2);
|
||||||
|
left = diff - right;
|
||||||
|
}
|
||||||
|
res.push();
|
||||||
|
for (var i=0; i<left; i++)
|
||||||
|
res.write(str);
|
||||||
|
res.write(this);
|
||||||
|
for (var i=0; i<right; i++)
|
||||||
|
res.write(str);
|
||||||
|
return res.pop();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* function returns true if a string contains the string
|
||||||
|
* passed as argument
|
||||||
|
* @param String string to search for
|
||||||
|
* @param Int Position to start search
|
||||||
|
* @param Boolean
|
||||||
|
*/
|
||||||
|
String.prototype.contains = function(str, fromIndex) {
|
||||||
|
if (this.indexOf(str, fromIndex ? fromIndex : 0) > -1)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* function compares a string with the one passed as argument
|
||||||
|
* using diff
|
||||||
|
* @param String String to compare against String object value
|
||||||
|
* @param String Optional regular expression string to use for
|
||||||
|
* splitting. If not defined, newlines will be used.
|
||||||
|
* @return Object Array containing one JS object for each line
|
||||||
|
* with the following properties:
|
||||||
|
* .num Line number
|
||||||
|
* .value String line if unchanged
|
||||||
|
* .deleted Obj Array containing deleted lines
|
||||||
|
* .inserted Obj Array containing added lines
|
||||||
|
*/
|
||||||
|
String.prototype.diff = function(mod, separator) {
|
||||||
|
// if no separator use line separator
|
||||||
|
var regexp = (typeof(separator) == "undefined") ?
|
||||||
|
new RegExp("\r\n|\r|\n") :
|
||||||
|
new RegExp(separator);
|
||||||
|
// split both strings into arrays
|
||||||
|
var orig = this.split(regexp);
|
||||||
|
var mod = mod.split(regexp);
|
||||||
|
// create the Diff object
|
||||||
|
var diff = new Packages.helma.util.Diff(orig, mod);
|
||||||
|
// get the diff.
|
||||||
|
var d = diff.diff();
|
||||||
|
if (!d)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
var max = Math.max(orig.length, mod.length);
|
||||||
|
var result = new Array();
|
||||||
|
for (var i=0;i<max;i++) {
|
||||||
|
var line = result[i];
|
||||||
|
if (!line) {
|
||||||
|
line = new Object();
|
||||||
|
line.num = (i+1);
|
||||||
|
result[i] = line;
|
||||||
|
}
|
||||||
|
if (d && i == d.line1) {
|
||||||
|
if (d.deleted) {
|
||||||
|
var del = new Array();
|
||||||
|
for (var j=d.line0; j<d.line0+d.deleted; j++)
|
||||||
|
del[del.length] = orig[j];
|
||||||
|
line.deleted = del;
|
||||||
|
}
|
||||||
|
if (d.inserted) {
|
||||||
|
var ins = new Array();
|
||||||
|
for (var j=d.line1; j<d.line1+d.inserted; j++)
|
||||||
|
ins[ins.length] = mod[j];
|
||||||
|
line.inserted = ins;
|
||||||
|
}
|
||||||
|
i = d.line1 + d.inserted -1;
|
||||||
|
d = d.link;
|
||||||
|
} else {
|
||||||
|
line.value = mod[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* remove leading and trailing whitespace
|
||||||
|
*/
|
||||||
|
String.prototype.trim = function () {
|
||||||
|
var s = new java.lang.String(this);
|
||||||
|
return String(s.trim());
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns true if the string looks like an e-mail
|
||||||
|
*/
|
||||||
|
String.prototype.isEmail = function() {
|
||||||
|
return String.EMAILPATTERN.test(this);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// wrapper methods for string-related
|
||||||
|
// global helma functions
|
||||||
|
|
||||||
|
String.prototype.encode = function() {
|
||||||
|
return encode(this);
|
||||||
|
};
|
||||||
|
|
||||||
|
String.prototype.encodeXml = function() {
|
||||||
|
return encodeXml(this);
|
||||||
|
};
|
||||||
|
|
||||||
|
String.prototype.encodeForm = function() {
|
||||||
|
return encodeForm(this);
|
||||||
|
};
|
||||||
|
|
||||||
|
String.prototype.format = function() {
|
||||||
|
return format(this);
|
||||||
|
};
|
||||||
|
|
||||||
|
String.prototype.stripTags = function() {
|
||||||
|
return stripTags(this);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// prevent any newly added properties from being enumerated
|
||||||
|
for (var i in String)
|
||||||
|
String.dontEnum(i);
|
||||||
|
for (var i in String.prototype)
|
||||||
|
String.prototype.dontEnum(i);
|
84
helma/Aspects.js
Normal file
84
helma/Aspects.js
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
/*
|
||||||
|
* Helma License Notice
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Helma License
|
||||||
|
* Version 2.0 (the "License"). You may not use this file except in
|
||||||
|
* compliance with the License. A copy of the License is available at
|
||||||
|
* http://adele.helma.org/download/helma/license.txt
|
||||||
|
*
|
||||||
|
* Copyright 1998-2006 Helma Software. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* $RCSfile: helma.Aspects.js,v $
|
||||||
|
* $Author: czv $
|
||||||
|
* $Revision: 1.9 $
|
||||||
|
* $Date: 2006/04/18 13:06:58 $
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
if (!global.helma) {
|
||||||
|
global.helma = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* library for adding Aspects (by roman porotnikov,
|
||||||
|
* http://www.jroller.com/page/deep/20030701)
|
||||||
|
*
|
||||||
|
* Note: Each prototype that uses aspects must implement a method
|
||||||
|
* onCodeUpdate() to prevent aspects being lost when the prototype
|
||||||
|
* is re-compiled
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
helma.Aspects = function() {
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
helma.Aspects.toString = function() {
|
||||||
|
return "[helma.Aspects]";
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
helma.Aspects.prototype.toString = function() {
|
||||||
|
return "[helma.Aspects Object]";
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
helma.Aspects.prototype.addBefore = function(obj, fname, before) {
|
||||||
|
var oldFunc = obj[fname];
|
||||||
|
obj[fname] = function() {
|
||||||
|
return oldFunc.apply(this, before(arguments, oldFunc, this));
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
helma.Aspects.prototype.addAfter = function(obj, fname, after) {
|
||||||
|
var oldFunc = obj[fname];
|
||||||
|
obj[fname] = function() {
|
||||||
|
return after(oldFunc.apply(this, arguments), arguments, oldFunc, this);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
helma.Aspects.prototype.addAround = function(obj, fname, around) {
|
||||||
|
var oldFunc = obj[fname];
|
||||||
|
obj[fname] = function() {
|
||||||
|
return around(arguments, oldFunc, this);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
helma.lib = "Aspects";
|
||||||
|
helma.dontEnum(helma.lib);
|
||||||
|
for (var i in helma[helma.lib])
|
||||||
|
helma[helma.lib].dontEnum(i);
|
||||||
|
for (var i in helma[helma.lib].prototype)
|
||||||
|
helma[helma.lib].prototype.dontEnum(i);
|
||||||
|
delete helma.lib;
|
||||||
|
|
||||||
|
|
||||||
|
helma.aspects = new helma.Aspects();
|
||||||
|
helma.dontEnum("aspects");
|
167
helma/Chart.js
vendored
Normal file
167
helma/Chart.js
vendored
Normal file
|
@ -0,0 +1,167 @@
|
||||||
|
/*
|
||||||
|
* Helma License Notice
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Helma License
|
||||||
|
* Version 2.0 (the "License"). You may not use this file except in
|
||||||
|
* compliance with the License. A copy of the License is available at
|
||||||
|
* http://adele.helma.org/download/helma/license.txt
|
||||||
|
*
|
||||||
|
* Copyright 1998-2006 Helma Software. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* $RCSfile: helma.Chart.js,v $
|
||||||
|
* $Author: czv $
|
||||||
|
* $Revision: 1.6 $
|
||||||
|
* $Date: 2006/04/18 13:06:58 $
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
// take care of any dependencies
|
||||||
|
app.addRepository('modules/helma/jxl.jar');
|
||||||
|
|
||||||
|
|
||||||
|
if (!global.helma) {
|
||||||
|
global.helma = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// chart package by tobi schaefer
|
||||||
|
// needs andy khan's java excel api: download jxl.jar at
|
||||||
|
// http://www.andykhan.com/jexcelapi/
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
helma.Chart = function(fpath, prefix, sheetName) {
|
||||||
|
var JXLPKG = Packages.jxl.Workbook;
|
||||||
|
var JXLPKGNAME = "jxl.jar";
|
||||||
|
var JXLPKGURL = "http://www.andykhan.com/jexcelapi/";
|
||||||
|
|
||||||
|
var workbook, file;
|
||||||
|
try {
|
||||||
|
file = new java.io.File(fpath);
|
||||||
|
workbook = JXLPKG.getWorkbook(file);
|
||||||
|
} catch (e) {
|
||||||
|
if (e instanceof TypeError == false)
|
||||||
|
throw(e);
|
||||||
|
throw("helma.Chart needs " + JXLPKGNAME +
|
||||||
|
" in lib/ext or application directory " +
|
||||||
|
"[" + JXLPKGURL + "]");
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCellStyle(c) {
|
||||||
|
if (!c)
|
||||||
|
return;
|
||||||
|
var result = new Object();
|
||||||
|
var format = c.getCellFormat();
|
||||||
|
var font = format.getFont();
|
||||||
|
if (font.getBoldWeight() > 400)
|
||||||
|
result.bold = true;
|
||||||
|
result.italic = font.isItalic();
|
||||||
|
result.wrap = format.getWrap();
|
||||||
|
var type = c.getType();
|
||||||
|
var align = format.getAlignment().getDescription();
|
||||||
|
if (align == "right" || type == "Number" || type == "Date")
|
||||||
|
result.align = "right";
|
||||||
|
else if (align == "centre")
|
||||||
|
result.align = "center";
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sheetName)
|
||||||
|
var sheet = workbook.getSheet(sheetName);
|
||||||
|
else
|
||||||
|
var sheet = workbook.getSheet(0);
|
||||||
|
if (!sheet)
|
||||||
|
return;
|
||||||
|
|
||||||
|
prefix = prefix ? prefix + "_" : "chart_";
|
||||||
|
|
||||||
|
this.render = function() {
|
||||||
|
res.write('<table border="0" cellspacing="1" class="' +
|
||||||
|
prefix + 'table">\n');
|
||||||
|
|
||||||
|
var rowBuf = [];
|
||||||
|
var rows = sheet.getRows();
|
||||||
|
var max = 0;
|
||||||
|
for (var i=0; i<rows; i+=1) {
|
||||||
|
var row = sheet.getRow(i);
|
||||||
|
if (row.length > max)
|
||||||
|
max = row.length;
|
||||||
|
rowBuf.push(row);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i in rowBuf) {
|
||||||
|
res.write('<tr class="' + prefix + 'row">\n');
|
||||||
|
for (var n=0; n<max; n+=1) {
|
||||||
|
if (n < rowBuf[i].length) {
|
||||||
|
var c = rowBuf[i][n];
|
||||||
|
var str = c.getContents();
|
||||||
|
if (str)
|
||||||
|
var style = getCellStyle(c);
|
||||||
|
}
|
||||||
|
res.write('<td class="' + prefix + 'cell"');
|
||||||
|
if (style) {
|
||||||
|
if (!style.wrap)
|
||||||
|
res.write(' nowrap="nowrap"');
|
||||||
|
if (style.align)
|
||||||
|
res.write(' align="' + style.align + '"');
|
||||||
|
res.write(">");
|
||||||
|
if (style.bold)
|
||||||
|
res.write("<b>");
|
||||||
|
if (style.italic)
|
||||||
|
res.write("<i>");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
res.write(">");
|
||||||
|
res.write(str);
|
||||||
|
if (style) {
|
||||||
|
if (style.italic)
|
||||||
|
res.write("</i>");
|
||||||
|
if (style.bold)
|
||||||
|
res.write("</b>");
|
||||||
|
}
|
||||||
|
res.write('</td>\n');
|
||||||
|
}
|
||||||
|
res.write('</tr>\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
res.write('</table>\n');
|
||||||
|
workbook.close();
|
||||||
|
};
|
||||||
|
|
||||||
|
this.renderAsString = function() {
|
||||||
|
res.push();
|
||||||
|
this.render();
|
||||||
|
return res.pop();
|
||||||
|
};
|
||||||
|
|
||||||
|
this.toString = function() {
|
||||||
|
return "[helma.Chart " + file + "]";
|
||||||
|
};
|
||||||
|
|
||||||
|
for (var i in this)
|
||||||
|
this.dontEnum(i);
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
helma.Chart.toString = function() {
|
||||||
|
return "[helma.Chart]";
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
helma.Chart.example = function(file) {
|
||||||
|
// var file = "/path/to/file.xls";
|
||||||
|
var chart = new helma.Chart(file);
|
||||||
|
chart.render();
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
helma.lib = "Chart";
|
||||||
|
helma.dontEnum(helma.lib);
|
||||||
|
for (var i in helma[helma.lib])
|
||||||
|
helma[helma.lib].dontEnum(i);
|
||||||
|
for (var i in helma[helma.lib].prototype)
|
||||||
|
helma[helma.lib].prototype.dontEnum(i);
|
||||||
|
delete helma.lib;
|
356
helma/Color.js
Normal file
356
helma/Color.js
Normal file
|
@ -0,0 +1,356 @@
|
||||||
|
/*
|
||||||
|
* Helma License Notice
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Helma License
|
||||||
|
* Version 2.0 (the "License"). You may not use this file except in
|
||||||
|
* compliance with the License. A copy of the License is available at
|
||||||
|
* http://adele.helma.org/download/helma/license.txt
|
||||||
|
*
|
||||||
|
* Copyright 1998-2006 Helma Software. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* $RCSfile: helma.Color.js,v $
|
||||||
|
* $Author: hannes $
|
||||||
|
* $Revision: 1.5 $
|
||||||
|
* $Date: 2006/04/18 13:06:58 $
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
if (!global.helma) {
|
||||||
|
global.helma = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* constructor for a color object
|
||||||
|
* @param IntegerOrRgbObject the red fraction or an rgb() object
|
||||||
|
* @param Integer the green fraction
|
||||||
|
* @param Integer the blue fraction
|
||||||
|
* @return the resulting color object
|
||||||
|
*/
|
||||||
|
helma.Color = function(R, G, B) {
|
||||||
|
var value = null, name, hex, rgb;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return the decimal value of a color object
|
||||||
|
* @return Integer the decimal value
|
||||||
|
*/
|
||||||
|
this.valueOf = function() {
|
||||||
|
if (arguments.length > 0) {
|
||||||
|
if (!rgb) {
|
||||||
|
var compose = function(n, bits) {
|
||||||
|
var div = Math.pow(2, bits);
|
||||||
|
remainder = n % div;
|
||||||
|
return Math.floor(n/div);
|
||||||
|
}
|
||||||
|
var remainder = value;
|
||||||
|
rgb = {
|
||||||
|
red: compose(remainder, 16),
|
||||||
|
green: compose(remainder, 8),
|
||||||
|
blue: compose(remainder, 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rgb[arguments[0]];
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return the hexidecimal value of a color object
|
||||||
|
* @return String the hexidecimal value
|
||||||
|
*/
|
||||||
|
this.toString = function() {
|
||||||
|
if (!value)
|
||||||
|
return null;
|
||||||
|
if (!hex)
|
||||||
|
hex = value.toString(16).pad("0", 6, String.LEFT);
|
||||||
|
return hex;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return the trivial name of this color
|
||||||
|
* @return String the trivial name
|
||||||
|
*/
|
||||||
|
this.getName = function() {
|
||||||
|
return helma.Color.COLORVALUES[value];
|
||||||
|
};
|
||||||
|
|
||||||
|
// the main code
|
||||||
|
if (arguments.length % 2 == 0)
|
||||||
|
throw("Insufficient arguments for creating Color");
|
||||||
|
if (arguments.length == 1) {
|
||||||
|
if (R.constructor == Number) {
|
||||||
|
value = R;
|
||||||
|
} else if (R.constructor == String) {
|
||||||
|
R = R.toLowerCase();
|
||||||
|
if (helma.Color.COLORNAMES[R]) {
|
||||||
|
this.name = R;
|
||||||
|
R = helma.Color.COLORNAMES[R];
|
||||||
|
} else if (helma.Color.COLORVALUES[R]) {
|
||||||
|
this.name = helma.Color.COLORVALUES[R];
|
||||||
|
} else if (R.startsWith("#"))
|
||||||
|
R = R.substring(1);
|
||||||
|
value = parseInt(R, 16);
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
value = R * Math.pow(2, 16) + G * Math.pow(2, 8) + B;
|
||||||
|
|
||||||
|
if (value == null || isNaN(value))
|
||||||
|
throw("Cannot create Color from " + R);
|
||||||
|
|
||||||
|
for (var i in this)
|
||||||
|
this.dontEnum(i);
|
||||||
|
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create a helma.Color from trivial name
|
||||||
|
* @param String the color's name (like "darkseagreen")
|
||||||
|
* @return helma.Color the resulting color object
|
||||||
|
*/
|
||||||
|
helma.Color.fromName = function(name) {
|
||||||
|
var value = helma.Color.COLORNAMES[name.toLowerCase()];
|
||||||
|
if (!value)
|
||||||
|
value = 0;
|
||||||
|
return new helma.Color(value);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* transform a hsl representation of a color
|
||||||
|
* to the equivalent decimal value
|
||||||
|
* @param Integer the hue fraction
|
||||||
|
* @param Integer the saturation fraction
|
||||||
|
* @param Integer the lightness fraction
|
||||||
|
* @return Object the resulting color object
|
||||||
|
*
|
||||||
|
* note: this function is adapted from the
|
||||||
|
* HSLtoRGB conversion method as described at
|
||||||
|
* http://www1.tip.nl/~t876506/ColorDesign.html#hr
|
||||||
|
* (thanks!)
|
||||||
|
*/
|
||||||
|
helma.Color.fromHsl = function(H,S,L) {
|
||||||
|
function H1(H,S,L) {
|
||||||
|
var R = 1; var G = 6*H; var B = 0;
|
||||||
|
G = G*S + 1 - S; B = B*S + 1 - S;
|
||||||
|
R = R*L; G = G*L; B = B*L;
|
||||||
|
return [R,G,B];
|
||||||
|
}
|
||||||
|
|
||||||
|
function H2(H,S,L) {
|
||||||
|
var R = 1-6*(H - 1/6); var G = 1; var B = 0;
|
||||||
|
R = R*S + 1 - S; B = B*S + 1 - S;
|
||||||
|
R = R*L; G = G*L; B = B*L;
|
||||||
|
return [R,G,B];
|
||||||
|
}
|
||||||
|
|
||||||
|
function H3(H,S,L) {
|
||||||
|
var R = 0; var G = 1; var B = 6*(H - 1/3);
|
||||||
|
R = R*S + 1 - S; B = B*S + 1 - S;
|
||||||
|
R = R*L; G = G*L; B = B*L
|
||||||
|
return [R,G,B];
|
||||||
|
}
|
||||||
|
|
||||||
|
function H4(H,S,L) {
|
||||||
|
var R = 0; var G = 1-6*(H - 1/2); var B = 1;
|
||||||
|
R = R*S + 1 - S; G = G*S + 1 - S;
|
||||||
|
R = R*L; G = G*L; B = B*L;
|
||||||
|
return [R,G,B];
|
||||||
|
}
|
||||||
|
|
||||||
|
function H5(H,S,L) {
|
||||||
|
var R = 6*(H - 2/3); var G = 0; var B = 1;
|
||||||
|
R = R*S + 1 - S; G = G*S + 1 - S;
|
||||||
|
R = R*L; G = G*L; B = B*L;
|
||||||
|
return [R,G,B];
|
||||||
|
}
|
||||||
|
|
||||||
|
function H6(H,S,L) {
|
||||||
|
var R = 1; var G = 0; var B = 1-6*(H - 5/6);
|
||||||
|
G = G*S + 1 - S; B = B*S + 1 - S;
|
||||||
|
R = R*L; G = G*L; B = B*L;
|
||||||
|
return [R,G,B];
|
||||||
|
}
|
||||||
|
|
||||||
|
// H [0-1] is divided into 6 equal sectors.
|
||||||
|
// From within each sector the proper conversion function is called.
|
||||||
|
var rgb;
|
||||||
|
if (H < 1/6) rgb = H1(H,S,L);
|
||||||
|
else if (H < 1/3) rgb = H2(H,S,L);
|
||||||
|
else if (H < 1/2) rgb = H3(H,S,L);
|
||||||
|
else if (H < 2/3) rgb = H4(H,S,L);
|
||||||
|
else if (H < 5/6) rgb = H5(H,S,L);
|
||||||
|
else rgb = H6(H,S,L);
|
||||||
|
|
||||||
|
return new Color(
|
||||||
|
Math.round(rgb[0]*255),
|
||||||
|
Math.round(rgb[1]*255),
|
||||||
|
Math.round(rgb[2]*255)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* object containig the hex values of named colors
|
||||||
|
*/
|
||||||
|
helma.Color.COLORNAMES = {
|
||||||
|
black: 0x000000,
|
||||||
|
maroon: 0x800000,
|
||||||
|
green: 0x008000,
|
||||||
|
olive: 0x808000,
|
||||||
|
navy: 0x000080,
|
||||||
|
purple: 0x800080,
|
||||||
|
teal: 0x008080,
|
||||||
|
silver: 0xc0c0c0,
|
||||||
|
gray: 0x808080,
|
||||||
|
red: 0xff0000,
|
||||||
|
lime: 0x00ff00,
|
||||||
|
yellow: 0xffff00,
|
||||||
|
blue: 0x0000ff,
|
||||||
|
fuchsia: 0xff00ff,
|
||||||
|
aqua: 0x00ffff,
|
||||||
|
white: 0xffffff,
|
||||||
|
aliceblue: 0xf0f8ff,
|
||||||
|
antiquewhite: 0xfaebd7,
|
||||||
|
aquamarine: 0x7fffd4,
|
||||||
|
azure: 0xf0ffff,
|
||||||
|
beige: 0xf5f5dc,
|
||||||
|
blueviolet: 0x8a2be2,
|
||||||
|
brown: 0xa52a2a,
|
||||||
|
burlywood: 0xdeb887,
|
||||||
|
cadetblue: 0x5f9ea0,
|
||||||
|
chartreuse: 0x7fff00,
|
||||||
|
chocolate: 0xd2691e,
|
||||||
|
coral: 0xff7f50,
|
||||||
|
cornflowerblue: 0x6495ed,
|
||||||
|
cornsilk: 0xfff8dc,
|
||||||
|
crimson: 0xdc143c,
|
||||||
|
darkblue: 0x00008b,
|
||||||
|
darkcyan: 0x008b8b,
|
||||||
|
darkgoldenrod: 0xb8860b,
|
||||||
|
darkgray: 0xa9a9a9,
|
||||||
|
darkgreen: 0x006400,
|
||||||
|
darkkhaki: 0xbdb76b,
|
||||||
|
darkmagenta: 0x8b008b,
|
||||||
|
darkolivegreen: 0x556b2f,
|
||||||
|
darkorange: 0xff8c00,
|
||||||
|
darkorchid: 0x9932cc,
|
||||||
|
darkred: 0x8b0000,
|
||||||
|
darksalmon: 0xe9967a,
|
||||||
|
darkseagreen: 0x8fbc8f,
|
||||||
|
darkslateblue: 0x483d8b,
|
||||||
|
darkslategray: 0x2f4f4f,
|
||||||
|
darkturquoise: 0x00ced1,
|
||||||
|
darkviolet: 0x9400d3,
|
||||||
|
deeppink: 0xff1493,
|
||||||
|
deepskyblue: 0x00bfff,
|
||||||
|
dimgray: 0x696969,
|
||||||
|
dodgerblue: 0x1e90ff,
|
||||||
|
firebrick: 0xb22222,
|
||||||
|
floralwhite: 0xfffaf0,
|
||||||
|
forestgreen: 0x228b22,
|
||||||
|
gainsboro: 0xdcdcdc,
|
||||||
|
ghostwhite: 0xf8f8ff,
|
||||||
|
gold: 0xffd700,
|
||||||
|
goldenrod: 0xdaa520,
|
||||||
|
greenyellow: 0xadff2f,
|
||||||
|
honeydew: 0xf0fff0,
|
||||||
|
hotpink: 0xff69b4,
|
||||||
|
indianred: 0xcd5c5c,
|
||||||
|
indigo: 0x4b0082,
|
||||||
|
ivory: 0xfffff0,
|
||||||
|
khaki: 0xf0e68c,
|
||||||
|
lavender: 0xe6e6fa,
|
||||||
|
lavenderblush: 0xfff0f5,
|
||||||
|
lawngreen: 0x7cfc00,
|
||||||
|
lemonchiffon: 0xfffacd,
|
||||||
|
lightblue: 0xadd8e6,
|
||||||
|
lightcoral: 0xf08080,
|
||||||
|
lightcyan: 0xe0ffff,
|
||||||
|
lightgoldenrodyellow: 0xfafad2,
|
||||||
|
lightgreen: 0x90ee90,
|
||||||
|
lightgrey: 0xd3d3d3,
|
||||||
|
lightpink: 0xffb6c1,
|
||||||
|
lightsalmon: 0xffa07a,
|
||||||
|
lightseagreen: 0x20b2aa,
|
||||||
|
lightskyblue: 0x87cefa,
|
||||||
|
lightslategray: 0x778899,
|
||||||
|
lightsteelblue: 0xb0c4de,
|
||||||
|
lightyellow: 0xffffe0,
|
||||||
|
limegreen: 0x32cd32,
|
||||||
|
linen: 0xfaf0e6,
|
||||||
|
mediumaquamarine: 0x66cdaa,
|
||||||
|
mediumblue: 0x0000cd,
|
||||||
|
mediumorchid: 0xba55d3,
|
||||||
|
mediumpurple: 0x9370db,
|
||||||
|
mediumseagreen: 0x3cb371,
|
||||||
|
mediumslateblue: 0x7b68ee,
|
||||||
|
mediumspringgreen: 0x00fa9a,
|
||||||
|
mediumturquoise: 0x48d1cc,
|
||||||
|
mediumvioletred: 0xc71585,
|
||||||
|
midnightblue: 0x191970,
|
||||||
|
mintcream: 0xf5fffa,
|
||||||
|
mistyrose: 0xffe4e1,
|
||||||
|
moccasin: 0xffe4b5,
|
||||||
|
navajowhite: 0xffdead,
|
||||||
|
oldlace: 0xfdf5e6,
|
||||||
|
olivedrab: 0x6b8e23,
|
||||||
|
orange: 0xffa500,
|
||||||
|
orangered: 0xff4500,
|
||||||
|
orchid: 0xda70d6,
|
||||||
|
palegoldenrod: 0xeee8aa,
|
||||||
|
palegreen: 0x98fb98,
|
||||||
|
paleturquoise: 0xafeeee,
|
||||||
|
palevioletred: 0xdb7093,
|
||||||
|
papayawhip: 0xffefd5,
|
||||||
|
peachpuff: 0xffdab9,
|
||||||
|
peru: 0xcd853f,
|
||||||
|
pink: 0xffc0cb,
|
||||||
|
plum: 0xdda0dd,
|
||||||
|
powderblue: 0xb0e0e6,
|
||||||
|
rosybrown: 0xbc8f8f,
|
||||||
|
royalblue: 0x4169e1,
|
||||||
|
saddlebrown: 0x8b4513,
|
||||||
|
salmon: 0xfa8072,
|
||||||
|
sandybrown: 0xf4a460,
|
||||||
|
seagreen: 0x2e8b57,
|
||||||
|
seashell: 0xfff5ee,
|
||||||
|
sienna: 0xa0522d,
|
||||||
|
skyblue: 0x87ceeb,
|
||||||
|
slateblue: 0x6a5acd,
|
||||||
|
slategray: 0x708090,
|
||||||
|
snow: 0xfffafa,
|
||||||
|
springgreen: 0x00ff7f,
|
||||||
|
steelblue: 0x4682b4,
|
||||||
|
tan: 0xd2b48c,
|
||||||
|
thistle: 0xd8bfd8,
|
||||||
|
tomato: 0xff6347,
|
||||||
|
turquoise: 0x40e0d0,
|
||||||
|
violet: 0xee82ee,
|
||||||
|
wheat: 0xf5deb3,
|
||||||
|
whitesmoke: 0xf5f5f5,
|
||||||
|
yellowgreen: 0x9acd32
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* object containig the color names for specific hex values
|
||||||
|
*/
|
||||||
|
helma.Color.COLORVALUES = {};
|
||||||
|
|
||||||
|
for (var i in helma.Color.COLORNAMES)
|
||||||
|
helma.Color.COLORVALUES[helma.Color.COLORNAMES[i]] = i;
|
||||||
|
|
||||||
|
|
||||||
|
helma.Color.toString = function() {
|
||||||
|
return "[helma.Color]";
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
helma.lib = "Color";
|
||||||
|
helma.dontEnum(helma.lib);
|
||||||
|
for (var i in helma[helma.lib])
|
||||||
|
helma[helma.lib].dontEnum(i);
|
||||||
|
for (var i in helma[helma.lib].prototype)
|
||||||
|
helma[helma.lib].prototype.dontEnum(i);
|
||||||
|
delete helma.lib;
|
138
helma/Database.js
Normal file
138
helma/Database.js
Normal file
|
@ -0,0 +1,138 @@
|
||||||
|
/*
|
||||||
|
* Helma License Notice
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Helma License
|
||||||
|
* Version 2.0 (the "License"). You may not use this file except in
|
||||||
|
* compliance with the License. A copy of the License is available at
|
||||||
|
* http://adele.helma.org/download/helma/license.txt
|
||||||
|
*
|
||||||
|
* Copyright 1998-2006 Helma Software. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* $RCSfile: helma.Database.js,v $
|
||||||
|
* $Author: czv $
|
||||||
|
* $Revision: 1.5 $
|
||||||
|
* $Date: 2006/04/18 13:06:58 $
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
if (!global.helma) {
|
||||||
|
global.helma = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
helma.Database = function(driver, url, user, password, name) {
|
||||||
|
if (!driver || !url || !user)
|
||||||
|
throw("Insufficient arguments to create helma.db.Connection");
|
||||||
|
if (!name)
|
||||||
|
name = "db" + new Date().getTime();
|
||||||
|
if (typeof password != "string")
|
||||||
|
password = "";
|
||||||
|
|
||||||
|
MYSQL = "mysql";
|
||||||
|
ORACLE = "oracle";
|
||||||
|
JDBC = "jdbc:";
|
||||||
|
DRIVER_MYSQL = "org.gjt.mm.mysql.Driver";
|
||||||
|
DRIVER_ORACLE = "oracle.jdbc.driver.OracleDriver";
|
||||||
|
|
||||||
|
if (driver == MYSQL) {
|
||||||
|
driver = DRIVER_MYSQL;
|
||||||
|
if (url.indexOf(JDBC) != 0)
|
||||||
|
url = "jdbc:mysql://" + url + "/" + name;
|
||||||
|
} else if (driver == ORACLE) {
|
||||||
|
driver = DRIVER_ORACLE;
|
||||||
|
if (url.indexOf(JDBC) != 0)
|
||||||
|
url = "jdbc:oracle:thin:@" + url + ":" + name;
|
||||||
|
}
|
||||||
|
|
||||||
|
var DbSource = Packages.helma.objectmodel.db.DbSource;
|
||||||
|
var DatabaseObject = Packages.helma.scripting.rhino.extensions.DatabaseObject;
|
||||||
|
|
||||||
|
var DbSource = Packages.helma.objectmodel.db.DbSource;
|
||||||
|
var props = new Packages.helma.util.ResourceProperties();
|
||||||
|
props.put(name + ".url", url);
|
||||||
|
props.put(name + ".driver", driver);
|
||||||
|
if (user) {
|
||||||
|
props.put(name + ".user", user);
|
||||||
|
props.put(name + ".password", password);
|
||||||
|
}
|
||||||
|
var source = new DbSource(name, props);
|
||||||
|
var connection = source.getConnection();
|
||||||
|
|
||||||
|
this.getConnection = function() {
|
||||||
|
return connection;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.getObject = function() {
|
||||||
|
return new DatabaseObject(source);
|
||||||
|
};
|
||||||
|
|
||||||
|
this.getProductName = function() {
|
||||||
|
return connection.getMetaData().getDatabaseProductName().toLowerCase();
|
||||||
|
};
|
||||||
|
|
||||||
|
this.isOracle = function() {
|
||||||
|
return source.isOracle();
|
||||||
|
};
|
||||||
|
|
||||||
|
this.isMySql = function() {
|
||||||
|
return this.getProductName() == MYSQL;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.query = function(query) {
|
||||||
|
var statement = connection.createStatement();
|
||||||
|
var resultSet = statement.executeQuery(query);
|
||||||
|
var metaData = resultSet.getMetaData();
|
||||||
|
var max = metaData.getColumnCount();
|
||||||
|
var result = [];
|
||||||
|
while (resultSet.next()) {
|
||||||
|
var row = {}
|
||||||
|
for (var i=1; i<=max; i+=1)
|
||||||
|
row[metaData.getColumnName(i)] = resultSet.getString(i);
|
||||||
|
result.push(row);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.getName = function() {
|
||||||
|
return source.getName();
|
||||||
|
};
|
||||||
|
|
||||||
|
this.getDriverName = function() {
|
||||||
|
return source.getDriverName();
|
||||||
|
};
|
||||||
|
|
||||||
|
this.toString = function() {
|
||||||
|
return "[helma.Database " + this.getName() + "]";
|
||||||
|
};
|
||||||
|
|
||||||
|
for (var i in this)
|
||||||
|
this.dontEnum(i);
|
||||||
|
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
helma.Database.toString = function() {
|
||||||
|
return "[helma.Database]";
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
helma.Database.example = function() {
|
||||||
|
var type = "mysql";
|
||||||
|
var host = "localhost";
|
||||||
|
var user = "root";
|
||||||
|
var pw = "";
|
||||||
|
var name = "mysql";
|
||||||
|
var db = new helma.Database(type, host, user, pw, name);
|
||||||
|
var result = db.query("select count(*) from db");
|
||||||
|
res.write(result.toSource());
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
helma.lib = "Database";
|
||||||
|
helma.dontEnum(helma.lib);
|
||||||
|
for (var i in helma[helma.lib])
|
||||||
|
helma[helma.lib].dontEnum(i);
|
||||||
|
for (var i in helma[helma.lib].prototype)
|
||||||
|
helma[helma.lib].prototype.dontEnum(i);
|
||||||
|
delete helma.lib;
|
492
helma/File.js
Normal file
492
helma/File.js
Normal file
|
@ -0,0 +1,492 @@
|
||||||
|
/*
|
||||||
|
* Helma License Notice
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Helma License
|
||||||
|
* Version 2.0 (the "License"). You may not use this file except in
|
||||||
|
* compliance with the License. A copy of the License is available at
|
||||||
|
* http://adele.helma.org/download/helma/license.txt
|
||||||
|
*
|
||||||
|
* Copyright 1998-2006 Helma Software. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* $RCSfile: helma.File.js,v $
|
||||||
|
* $Author: czv $
|
||||||
|
* $Revision: 1.9 $
|
||||||
|
* $Date: 2006/04/18 13:06:58 $
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
if (!global.helma) {
|
||||||
|
global.helma = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
helma.File = function(path) {
|
||||||
|
var BufferedReader = java.io.BufferedReader;
|
||||||
|
var File = java.io.File;
|
||||||
|
var Reader = java.io.Reader;
|
||||||
|
var Writer = java.io.Writer;
|
||||||
|
var FileReader = java.io.FileReader;
|
||||||
|
var FileWriter = java.io.FileWriter;
|
||||||
|
var PrintWriter = java.io.PrintWriter;
|
||||||
|
var EOFException = java.io.EOFException;
|
||||||
|
var IOException = java.io.IOException;
|
||||||
|
var IllegalStateException = java.lang.IllegalStateException;
|
||||||
|
var IllegalArgumentException = java.lang.IllegalArgumentException
|
||||||
|
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
var file;
|
||||||
|
try {
|
||||||
|
if (arguments.length > 1)
|
||||||
|
file = new File(path, arguments[1]);
|
||||||
|
else
|
||||||
|
file = new File(path);
|
||||||
|
} catch (e) {
|
||||||
|
throw(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
var readerWriter;
|
||||||
|
var atEOF = false;
|
||||||
|
var lastLine = null;
|
||||||
|
|
||||||
|
var setError = function(e) {
|
||||||
|
this.lastError = e;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.lastError = null;
|
||||||
|
|
||||||
|
this.toString = function() {
|
||||||
|
return file.toString();
|
||||||
|
};
|
||||||
|
|
||||||
|
this.getName = function() {
|
||||||
|
var name = file.getName();
|
||||||
|
return (name == null ? "" : name);
|
||||||
|
};
|
||||||
|
|
||||||
|
this.isOpened = function() {
|
||||||
|
return (readerWriter != null);
|
||||||
|
};
|
||||||
|
|
||||||
|
this.open = function() {
|
||||||
|
if (self.isOpened()) {
|
||||||
|
setError(new IllegalStateException("File already open"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// We assume that the BufferedReader and PrintWriter creation
|
||||||
|
// cannot fail except if the FileReader/FileWriter fails.
|
||||||
|
// Otherwise we have an open file until the reader/writer
|
||||||
|
// get garbage collected.
|
||||||
|
try{
|
||||||
|
if (file.exists()) {
|
||||||
|
readerWriter = new BufferedReader(new FileReader(file));
|
||||||
|
} else {
|
||||||
|
readerWriter = new PrintWriter(new FileWriter(file));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
} catch (e) {
|
||||||
|
setError(e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.exists = function() {
|
||||||
|
return file.exists();
|
||||||
|
};
|
||||||
|
|
||||||
|
this.getParent = function() {
|
||||||
|
if (!file.getParent())
|
||||||
|
return null;
|
||||||
|
return new helma.File(file.getParent());
|
||||||
|
};
|
||||||
|
|
||||||
|
this.readln = function() {
|
||||||
|
if (!self.isOpened()) {
|
||||||
|
setError(new IllegalStateException("File not opened"));
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (!(readerWriter instanceof BufferedReader)) {
|
||||||
|
setError(new IllegalStateException("File not opened for reading"));
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (atEOF) {
|
||||||
|
setError(new EOFException());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (lastLine != null) {
|
||||||
|
var line = lastLine;
|
||||||
|
lastLine = null;
|
||||||
|
return line;
|
||||||
|
}
|
||||||
|
var reader = readerWriter;
|
||||||
|
// Here lastLine is null, return a new line
|
||||||
|
try {
|
||||||
|
var line = readerWriter.readLine();
|
||||||
|
if (line == null) {
|
||||||
|
atEOF = true;
|
||||||
|
setError(new EOFException());
|
||||||
|
}
|
||||||
|
return line;
|
||||||
|
} catch (e) {
|
||||||
|
setError(e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.write = function(what) {
|
||||||
|
if (!self.isOpened()) {
|
||||||
|
setError(new IllegalStateException("File not opened"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!(readerWriter instanceof PrintWriter)) {
|
||||||
|
setError(new IllegalStateException("File not opened for writing"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (what != null) {
|
||||||
|
readerWriter.print(what.toString());
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.writeln = function(what) {
|
||||||
|
if (self.write(what)) {
|
||||||
|
readerWriter.println();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.isAbsolute = function() {
|
||||||
|
return file.isAbsolute();
|
||||||
|
};
|
||||||
|
|
||||||
|
this.remove = function() {
|
||||||
|
if (self.isOpened()) {
|
||||||
|
setError(new IllegalStateException("An openened file cannot be removed"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return file["delete"]();
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* will list all files within a directory
|
||||||
|
* you may pass a RegExp Pattern to return just
|
||||||
|
* files matching this pattern
|
||||||
|
* @example var xmlFiles = dir.list(/.*\.xml/);
|
||||||
|
* @param RegExp pattern to test each file name against
|
||||||
|
* @return Array the list of file names
|
||||||
|
*/
|
||||||
|
this.list = function(pattern) {
|
||||||
|
if (self.isOpened())
|
||||||
|
return null;
|
||||||
|
if (!file.isDirectory())
|
||||||
|
return null;
|
||||||
|
if (pattern) {
|
||||||
|
var fileList = file.list();
|
||||||
|
var result = [];
|
||||||
|
for (var i in fileList) {
|
||||||
|
if (pattern.test(fileList[i]))
|
||||||
|
result.push(fileList[i]);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return file.list();
|
||||||
|
};
|
||||||
|
|
||||||
|
this.flush = function() {
|
||||||
|
if (!self.isOpened()) {
|
||||||
|
setError(new IllegalStateException("File not opened"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (readerWriter instanceof Writer) {
|
||||||
|
try {
|
||||||
|
readerWriter.flush();
|
||||||
|
} catch (e) {
|
||||||
|
setError(e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
setError(new IllegalStateException("File not opened for write"));
|
||||||
|
return false; // not supported by reader
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.close = function() {
|
||||||
|
if (!self.isOpened())
|
||||||
|
return false;
|
||||||
|
try {
|
||||||
|
readerWriter.close();
|
||||||
|
readerWriter = null;
|
||||||
|
return true;
|
||||||
|
} catch (e) {
|
||||||
|
setError(e);
|
||||||
|
readerWriter = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
this.getPath = function() {
|
||||||
|
var path = file.getPath();
|
||||||
|
return (path == null ? "" : path);
|
||||||
|
};
|
||||||
|
|
||||||
|
this.error = function() {
|
||||||
|
if (this.lastError == null) {
|
||||||
|
return "";
|
||||||
|
} else {
|
||||||
|
var exceptionName = this.lastError.getClass().getName();
|
||||||
|
var l = exceptionName.lastIndexOf(".");
|
||||||
|
if (l > 0)
|
||||||
|
exceptionName = exceptionName.substring(l + 1);
|
||||||
|
return exceptionName + ": " + this.lastError.getMessage();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
this.clearError = function() {
|
||||||
|
this.lastError = null;
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.canRead = function() {
|
||||||
|
return file.canRead();
|
||||||
|
};
|
||||||
|
|
||||||
|
this.canWrite = function() {
|
||||||
|
return file.canWrite();
|
||||||
|
};
|
||||||
|
|
||||||
|
this.getAbsolutePath = function() {
|
||||||
|
var absolutPath = file.getAbsolutePath();
|
||||||
|
return (absolutPath == null ? "" : absolutPath);
|
||||||
|
};
|
||||||
|
|
||||||
|
this.getLength = function() {
|
||||||
|
return file.length();
|
||||||
|
};
|
||||||
|
|
||||||
|
this.isDirectory = function() {
|
||||||
|
return file.isDirectory();
|
||||||
|
};
|
||||||
|
|
||||||
|
this.isFile = function() {
|
||||||
|
return file.isFile();
|
||||||
|
};
|
||||||
|
|
||||||
|
this.lastModified = function() {
|
||||||
|
return file.lastModified();
|
||||||
|
};
|
||||||
|
|
||||||
|
this.makeDirectory = function() {
|
||||||
|
if (self.isOpened())
|
||||||
|
return false;
|
||||||
|
// don't do anything if file exists or use multi directory version
|
||||||
|
return (file.exists() || file.mkdirs());
|
||||||
|
};
|
||||||
|
|
||||||
|
this.renameTo = function(toFile) {
|
||||||
|
if (toFile == null) {
|
||||||
|
setError(new IllegalArgumentException("Uninitialized target File object"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (self.isOpened()) {
|
||||||
|
setError(new IllegalStateException("An openened file cannot be renamed"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (toFile.isOpened()) {
|
||||||
|
setError(new IllegalStateException("You cannot rename to an openened file"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return file.renameTo(new java.io.File(toFile.getAbsolutePath()));
|
||||||
|
};
|
||||||
|
|
||||||
|
this.eof = function() {
|
||||||
|
if (!self.isOpened()) {
|
||||||
|
setError(new IllegalStateException("File not opened"));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!(readerWriter instanceof BufferedReader)) {
|
||||||
|
setError(new IllegalStateException("File not opened for read"));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (atEOF)
|
||||||
|
return true;
|
||||||
|
if (lastLine != null)
|
||||||
|
return false;
|
||||||
|
try {
|
||||||
|
lastLine = readerWriter.readLine();
|
||||||
|
if (lastLine == null)
|
||||||
|
atEOF = true;
|
||||||
|
return atEOF;
|
||||||
|
} catch (e) {
|
||||||
|
setError(e);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
this.readAll = function() {
|
||||||
|
// Open the file for readAll
|
||||||
|
if (self.isOpened()) {
|
||||||
|
setError(new IllegalStateException("File already open"));
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
if (file.exists()) {
|
||||||
|
readerWriter = new BufferedReader(new FileReader(file));
|
||||||
|
} else {
|
||||||
|
setError(new IllegalStateException("File does not exist"));
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (!file.isFile()) {
|
||||||
|
setError(new IllegalStateException("File is not a regular file"));
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// read content line by line to setup proper eol
|
||||||
|
var buffer = new java.lang.StringBuffer(file.length() * 1.10);
|
||||||
|
while (true) {
|
||||||
|
var line = readerWriter.readLine();
|
||||||
|
if (line == null)
|
||||||
|
break;
|
||||||
|
if (buffer.length() > 0)
|
||||||
|
buffer.append("\n"); // EcmaScript EOL
|
||||||
|
buffer.append(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close the file
|
||||||
|
readerWriter.close();
|
||||||
|
readerWriter = null;
|
||||||
|
return buffer.toString();
|
||||||
|
} catch (e) {
|
||||||
|
readerWriter = null;
|
||||||
|
setError(e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// DANGER! DANGER! HIGH VOLTAGE!
|
||||||
|
// this method removes a directory recursively
|
||||||
|
// without any warning or precautious measures
|
||||||
|
this.removeDirectory = function() {
|
||||||
|
if (!file.isDirectory())
|
||||||
|
return false;
|
||||||
|
var arr = file.list();
|
||||||
|
for (var i=0; i<arr.length; i++) {
|
||||||
|
var f = new helma.File(file, arr[i]);
|
||||||
|
if (f.isDirectory())
|
||||||
|
f.removeDirectory();
|
||||||
|
else
|
||||||
|
f.remove();
|
||||||
|
}
|
||||||
|
file["delete"]();
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* recursivly lists all files below a given directory
|
||||||
|
* you may pass a RegExp Pattern to return just
|
||||||
|
* files matching this pattern
|
||||||
|
* @param RegExp pattern to test each file name against
|
||||||
|
* @returns Array the list of absolute file paths
|
||||||
|
*/
|
||||||
|
this.listRecursive = function(pattern) {
|
||||||
|
if (!file.isDirectory())
|
||||||
|
return false;
|
||||||
|
if (!pattern || pattern.test(file.getName()))
|
||||||
|
var result = [file.getAbsolutePath()];
|
||||||
|
else
|
||||||
|
var result = [];
|
||||||
|
var arr = file.list();
|
||||||
|
for (var i=0; i<arr.length; i++) {
|
||||||
|
var f = new helma.File(file, arr[i]);
|
||||||
|
if (f.isDirectory())
|
||||||
|
result = result.concat(f.listRecursive(pattern));
|
||||||
|
else if (!pattern || pattern.test(arr[i]))
|
||||||
|
result.push(f.getAbsolutePath());
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* function makes a copy of a file over partitions
|
||||||
|
* @param StringOrFile full path of the new file
|
||||||
|
*/
|
||||||
|
this.hardCopy = function(dest) {
|
||||||
|
var inStream = new java.io.BufferedInputStream(
|
||||||
|
new java.io.FileInputStream(file)
|
||||||
|
);
|
||||||
|
var outStream = new java.io.BufferedOutputStream(
|
||||||
|
new java.io.FileOutputStream(dest)
|
||||||
|
);
|
||||||
|
var buffer = java.lang.reflect.Array.newInstance(
|
||||||
|
java.lang.Byte.TYPE, 4096
|
||||||
|
);
|
||||||
|
var bytesRead = 0;
|
||||||
|
while ((bytesRead = inStream.read(buffer, 0, buffer.length)) != -1) {
|
||||||
|
outStream.write(buffer, 0, bytesRead);
|
||||||
|
}
|
||||||
|
outStream.flush();
|
||||||
|
inStream.close();
|
||||||
|
outStream.close();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* function moves a file to a new destination directory
|
||||||
|
* @param String full path of the new file
|
||||||
|
* @return Boolean true in case file could be moved, false otherwise
|
||||||
|
*/
|
||||||
|
this.move = function(dest) {
|
||||||
|
// instead of using the standard File method renameTo()
|
||||||
|
// do a hardCopy and then remove the source file. This way
|
||||||
|
// file locking shouldn't be an issue
|
||||||
|
self.hardCopy(dest);
|
||||||
|
// remove the source file
|
||||||
|
file["delete"]();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns file as ByteArray
|
||||||
|
* useful for passing it to a function instead of an request object
|
||||||
|
*/
|
||||||
|
this.toByteArray = function() {
|
||||||
|
if (!this.exists())
|
||||||
|
return null;
|
||||||
|
var body = new java.io.ByteArrayOutputStream();
|
||||||
|
var stream = new java.io.BufferedInputStream(
|
||||||
|
new java.io.FileInputStream(this.getAbsolutePath())
|
||||||
|
);
|
||||||
|
var buf = java.lang.reflect.Array.newInstance(
|
||||||
|
java.lang.Byte.TYPE, 1024
|
||||||
|
);
|
||||||
|
var read;
|
||||||
|
while ((read = stream.read(buf)) > -1)
|
||||||
|
body.write(buf, 0, read);
|
||||||
|
stream.close();
|
||||||
|
return body.toByteArray();
|
||||||
|
};
|
||||||
|
|
||||||
|
for (var i in this)
|
||||||
|
this.dontEnum(i);
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
helma.File.toString = function() {
|
||||||
|
return "[helma.File]";
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
helma.File.separator = java.io.File.separator;
|
||||||
|
|
||||||
|
|
||||||
|
helma.lib = "File";
|
||||||
|
helma.dontEnum(helma.lib);
|
||||||
|
for (var i in helma[helma.lib])
|
||||||
|
helma[helma.lib].dontEnum(i);
|
||||||
|
for (var i in helma[helma.lib].prototype)
|
||||||
|
helma[helma.lib].prototype.dontEnum(i);
|
||||||
|
delete helma.lib;
|
364
helma/Ftp.js
Normal file
364
helma/Ftp.js
Normal file
|
@ -0,0 +1,364 @@
|
||||||
|
/*
|
||||||
|
* Helma License Notice
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Helma License
|
||||||
|
* Version 2.0 (the "License"). You may not use this file except in
|
||||||
|
* compliance with the License. A copy of the License is available at
|
||||||
|
* http://adele.helma.org/download/helma/license.txt
|
||||||
|
*
|
||||||
|
* Copyright 1998-2006 Helma Software. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* $RCSfile: helma.Ftp.js,v $
|
||||||
|
* $Author: czv $
|
||||||
|
* $Revision: 1.7 $
|
||||||
|
* $Date: 2006/04/18 13:06:58 $
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
if (!global.helma) {
|
||||||
|
global.helma = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
helma.Ftp = function(server) {
|
||||||
|
var OK = 0;
|
||||||
|
var SOCKET = 1;
|
||||||
|
var TIMEOUT = 2;
|
||||||
|
var LOGIN = 10;
|
||||||
|
var LOGOUT = 11;
|
||||||
|
var BINARY = 20;
|
||||||
|
var ASCII = 21;
|
||||||
|
var ACTIVE = 22;
|
||||||
|
var PASSIVE = 23;
|
||||||
|
var CD = 30;
|
||||||
|
var LCD = 31;
|
||||||
|
var PWD = 32;
|
||||||
|
var DIR = 33;
|
||||||
|
var MKDIR = 34;
|
||||||
|
var RMDIR = 35;
|
||||||
|
var GET = 40;
|
||||||
|
var PUT = 41;
|
||||||
|
var DELETE = 42;
|
||||||
|
|
||||||
|
var FTP = Packages.com.oroinc.net.ftp.FTP;
|
||||||
|
var FtpClient = Packages.com.oroinc.net.ftp.FTPClient;
|
||||||
|
var BufferedInputStream = java.io.BufferedInputStream;
|
||||||
|
var BufferedOutputStream = java.io.BufferedOutputStream;
|
||||||
|
var FileInputStream = java.io.FileInputStream;
|
||||||
|
var FileOutputStream = java.io.FileOutputStream;
|
||||||
|
var ByteArrayInputStream = java.io.ByteArrayInputStream;
|
||||||
|
var ByteArrayOutputStream = java.io.ByteArrayOutputStream;
|
||||||
|
|
||||||
|
var self = this;
|
||||||
|
var className = "helma.Ftp";
|
||||||
|
|
||||||
|
var ftpclient = new FtpClient();
|
||||||
|
var localDir;
|
||||||
|
|
||||||
|
var error = function(methName, errMsg) {
|
||||||
|
var tx = java.lang.Thread.currentThread();
|
||||||
|
tx.dumpStack();
|
||||||
|
app.log("Error in " + className + ":" + methName + ": " + errMsg);
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
var debug = function(methName, msg) {
|
||||||
|
var msg = msg ? " " + msg : "";
|
||||||
|
app.debug(className + ":" + methName + msg);
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
var setStatus = function(status) {
|
||||||
|
if (self.status === OK) {
|
||||||
|
self.status = status;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
var getStatus = function() {
|
||||||
|
return self.status;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.server = server;
|
||||||
|
this.status = OK;
|
||||||
|
|
||||||
|
this.toString = function() {
|
||||||
|
return "[helma.Ftp " + server + "]";
|
||||||
|
};
|
||||||
|
|
||||||
|
this.setReadTimeout = function(timeout) {
|
||||||
|
try {
|
||||||
|
ftpclient.setDefaultTimeout(timeout);
|
||||||
|
debug("setReadTimeout", timeout);
|
||||||
|
return true;
|
||||||
|
} catch(x) {
|
||||||
|
error("setReadTimeout", x);
|
||||||
|
setStatus(SOCKET);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.setTimeout = function(timeout) {
|
||||||
|
try {
|
||||||
|
ftpclient.setDataTimeout(timeout);
|
||||||
|
debug("setTimeout", timeout);
|
||||||
|
return true;
|
||||||
|
} catch(x) {
|
||||||
|
error("setTimeout", x);
|
||||||
|
setStatus(TIMEOUT);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.login = function(username, password) {
|
||||||
|
try {
|
||||||
|
ftpclient.connect(this.server);
|
||||||
|
ftpclient.login(username, password);
|
||||||
|
debug("login", username + "@" + server);
|
||||||
|
return true;
|
||||||
|
} catch(x) {
|
||||||
|
error("login", x);
|
||||||
|
setStatus(LOGIN);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.binary = function() {
|
||||||
|
try {
|
||||||
|
ftpclient.setFileType(FTP.BINARY_FILE_TYPE);
|
||||||
|
debug("binary");
|
||||||
|
return true;
|
||||||
|
} catch(x) {
|
||||||
|
error("binary", x);
|
||||||
|
setStatus(BINARY);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.ascii = function() {
|
||||||
|
try {
|
||||||
|
ftpclient.setFileType(FTP.ASCII_FILE_TYPE);
|
||||||
|
debug("ascii");
|
||||||
|
return true;
|
||||||
|
} catch(x) {
|
||||||
|
error("ascii", x);
|
||||||
|
setStatus(ASCII);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.active = function() {
|
||||||
|
try {
|
||||||
|
ftpclient.enterLocalActiveMode();
|
||||||
|
debug("active");
|
||||||
|
return true;
|
||||||
|
} catch(x) {
|
||||||
|
error("active", x);
|
||||||
|
setStatus(ACTIVE);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.passive = function() {
|
||||||
|
try {
|
||||||
|
ftpclient.enterLocalPassiveMode();
|
||||||
|
debug("passive");
|
||||||
|
return true;
|
||||||
|
} catch(x) {
|
||||||
|
error("passive", x);
|
||||||
|
setStatus(PASSIVE);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.pwd = function() {
|
||||||
|
try {
|
||||||
|
debug("pwd");
|
||||||
|
return ftpclient.printWorkingDirectory();
|
||||||
|
} catch(x) {
|
||||||
|
error("pwd", x);
|
||||||
|
setStatus(PWD);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.dir = function(path) {
|
||||||
|
try {
|
||||||
|
debug("dir", path);
|
||||||
|
return ftpclient.listNames(path ? path : ".");
|
||||||
|
} catch(x) {
|
||||||
|
error("dir", x);
|
||||||
|
setStatus(DIR);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.mkdir = function(dir) {
|
||||||
|
try {
|
||||||
|
ftpclient.makeDirectory(dir);
|
||||||
|
debug("mkdir", dir);
|
||||||
|
return true;
|
||||||
|
} catch(x) {
|
||||||
|
error("mkdir", x);
|
||||||
|
setStatus(MKDIR);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.rmdir = function(dir) {
|
||||||
|
try {
|
||||||
|
ftpclient.removeDirectory(dir);
|
||||||
|
debug("rmdir", dir);
|
||||||
|
return true;
|
||||||
|
} catch(x) {
|
||||||
|
error("rmdir", x);
|
||||||
|
setStatus(RMDIR);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.cd = function(path) {
|
||||||
|
try {
|
||||||
|
ftpclient.changeWorkingDirectory(path);
|
||||||
|
debug("cd", path);
|
||||||
|
return true;
|
||||||
|
} catch(x) {
|
||||||
|
error("cd", x);
|
||||||
|
setStatus(CD);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.lcd = function(dir) {
|
||||||
|
try {
|
||||||
|
localDir = new File(dir);
|
||||||
|
if (!localDir.exists()) {
|
||||||
|
localDir.mkdir();
|
||||||
|
debug("lcd", dir);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
} catch(x) {
|
||||||
|
error("lcd", x);
|
||||||
|
setStatus(LCD);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.putFile = function(localFile, remoteFile) {
|
||||||
|
try {
|
||||||
|
if (localFile instanceof File) {
|
||||||
|
var f = localFile;
|
||||||
|
} else if (typeof localFile == "string") {
|
||||||
|
if (localDir == null)
|
||||||
|
var f = new File(localFile);
|
||||||
|
else
|
||||||
|
var f = new File(localDir, localFile);
|
||||||
|
}
|
||||||
|
var stream = new BufferedInputStream(
|
||||||
|
new FileInputStream(f.getPath())
|
||||||
|
);
|
||||||
|
if (!remoteFile) {
|
||||||
|
remoteFile = f.getName();
|
||||||
|
}
|
||||||
|
ftpclient.storeFile(remoteFile, stream);
|
||||||
|
stream.close();
|
||||||
|
debug("putFile", remoteFile);
|
||||||
|
return true;
|
||||||
|
} catch(x) {
|
||||||
|
error("putFile", x);
|
||||||
|
setStatus(PUT);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.putString = function(str, remoteFile, charset) {
|
||||||
|
try {
|
||||||
|
str = new java.lang.String(str);
|
||||||
|
var bytes = charset ? str.getBytes(charset) : str.getBytes();
|
||||||
|
var stream = ByteArrayInputStream(bytes);
|
||||||
|
ftpclient.storeFile(remoteFile, stream);
|
||||||
|
debug("putString", remoteFile);
|
||||||
|
return true;
|
||||||
|
} catch(x) {
|
||||||
|
error("putString", x);
|
||||||
|
setStatus(PUT);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.getFile = function(remoteFile, localFile) {
|
||||||
|
try {
|
||||||
|
if (localDir == null)
|
||||||
|
var f = new File(localFile);
|
||||||
|
else
|
||||||
|
var f = new File(localDir, localFile);
|
||||||
|
var stream = new BufferedOutputStream(
|
||||||
|
new FileOutputStream(f.getPath())
|
||||||
|
);
|
||||||
|
ftpclient.retrieveFile(remoteFile, stream);
|
||||||
|
stream.close();
|
||||||
|
debug("getFile", remoteFile);
|
||||||
|
return true;
|
||||||
|
} catch(x) {
|
||||||
|
error("getFile", x);
|
||||||
|
setStatus(GET);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.getString = function(remoteFile) {
|
||||||
|
try {
|
||||||
|
var stream = ByteArrayOutputStream();
|
||||||
|
ftpclient.retrieveFile(remoteFile, stream);
|
||||||
|
debug("getString", remoteFile);
|
||||||
|
return stream.toString();
|
||||||
|
} catch(x) {
|
||||||
|
error("getString", x);
|
||||||
|
setStatus(GET);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.deleteFile = function(remoteFile) {
|
||||||
|
try {
|
||||||
|
ftpclient.deleteFile(remoteFile);
|
||||||
|
debug("deleteFile", remoteFile);
|
||||||
|
return true;
|
||||||
|
} catch(x) {
|
||||||
|
error("deleteFile", x);
|
||||||
|
setStatus(DELETE);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.logout = function() {
|
||||||
|
try {
|
||||||
|
ftpclient.logout();
|
||||||
|
ftpclient.disconnect();
|
||||||
|
debug("logout");
|
||||||
|
return true;
|
||||||
|
} catch(x) {
|
||||||
|
error("logout", x);
|
||||||
|
setStatus(LOGOUT);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
for (var i in this)
|
||||||
|
this.dontEnum(i);
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
helma.Ftp.toString = function() {
|
||||||
|
return "[helma.Ftp]";
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
helma.lib = "Ftp";
|
||||||
|
helma.dontEnum(helma.lib);
|
||||||
|
for (var i in helma[helma.lib])
|
||||||
|
helma[helma.lib].dontEnum(i);
|
||||||
|
for (var i in helma[helma.lib].prototype)
|
||||||
|
helma[helma.lib].prototype.dontEnum(i);
|
||||||
|
delete helma.lib;
|
835
helma/Html.js
Normal file
835
helma/Html.js
Normal file
|
@ -0,0 +1,835 @@
|
||||||
|
/*
|
||||||
|
* Helma License Notice
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Helma License
|
||||||
|
* Version 2.0 (the "License"). You may not use this file except in
|
||||||
|
* compliance with the License. A copy of the License is available at
|
||||||
|
* http://adele.helma.org/download/helma/license.txt
|
||||||
|
*
|
||||||
|
* Copyright 1998-2006 Helma Software. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* $RCSfile: helma.Html.js,v $
|
||||||
|
* $Author: czv $
|
||||||
|
* $Revision: 1.5 $
|
||||||
|
* $Date: 2006/04/18 13:06:58 $
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
// take care of any dependencies
|
||||||
|
app.addRepository('modules/core/String.js');
|
||||||
|
|
||||||
|
|
||||||
|
if (!global.helma) {
|
||||||
|
global.helma = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
helma.Html = function() {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* helper function to render an arbitrary markup part
|
||||||
|
* @param String the element's name
|
||||||
|
* @param String prefix of each rendered element
|
||||||
|
* @param String suffix of each rendered element
|
||||||
|
* @param Object optional element's attributes
|
||||||
|
*/
|
||||||
|
var renderMarkupPart = function(name, start, end, attr) {
|
||||||
|
res.write(start);
|
||||||
|
res.write(name);
|
||||||
|
if (attr) {
|
||||||
|
for (var i in attr) {
|
||||||
|
if (i == "prefix" || i == "suffix" ||
|
||||||
|
i == "default" || attr[i] == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
res.write(" ");
|
||||||
|
res.write(i);
|
||||||
|
res.write("=\"");
|
||||||
|
res.write(attr[i]);
|
||||||
|
res.write("\"");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
res.write(end);
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* helper function used in Html.checkBox
|
||||||
|
* and Html.dropDown to check if a current value
|
||||||
|
* matches against one or more selected values
|
||||||
|
* @param String the current value
|
||||||
|
* @param StringOrArray the selectedValue
|
||||||
|
*/
|
||||||
|
var isSelected = function(value, selectedValue) {
|
||||||
|
if (selectedValue == null || value == null)
|
||||||
|
return false;
|
||||||
|
if (selectedValue instanceof Array)
|
||||||
|
return Array.contains(selectedValue, value);
|
||||||
|
return value == selectedValue;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return a textual representation of this object
|
||||||
|
* @return String
|
||||||
|
*/
|
||||||
|
this.toString = function() {
|
||||||
|
return "[Antville Html Library]";
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* render the opening tag of an arbitrary x/html element
|
||||||
|
* @param String the element's name
|
||||||
|
* @param Object the element's attributes
|
||||||
|
*/
|
||||||
|
this.openTag = function(name, attr) {
|
||||||
|
renderMarkupPart(name, "<", ">", attr);
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return the opening tag of an arbitrary x/html element
|
||||||
|
* @see this.openTag
|
||||||
|
* @return String the rendered element
|
||||||
|
*/
|
||||||
|
this.openTagAsString = function(name, attr) {
|
||||||
|
res.push();
|
||||||
|
renderMarkupPart(name, "<", ">", attr);
|
||||||
|
return res.pop();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* render the closing tag of an arbitrary x/html element
|
||||||
|
* directly to response
|
||||||
|
* @param String the element's name
|
||||||
|
*/
|
||||||
|
this.closeTag = function(name) {
|
||||||
|
renderMarkupPart(name, "</", ">", null);
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return the closing tag of an arbitray x/html element
|
||||||
|
* @see this.closeTag
|
||||||
|
* @return String the rendered element
|
||||||
|
*/
|
||||||
|
this.closeTagAsString = function(name) {
|
||||||
|
res.push();
|
||||||
|
renderMarkupPart(name, "</", ">", null);
|
||||||
|
return res.pop();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* render an empty arbitrary x/html element ("contentless tag")
|
||||||
|
* @param String the element's name
|
||||||
|
* @param Object the element's attributes
|
||||||
|
*/
|
||||||
|
this.tag = function(name, attr) {
|
||||||
|
renderMarkupPart(name, "<", " />", attr);
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return an empty arbitrary x/html element ("contentless tag")
|
||||||
|
* @see this.tag
|
||||||
|
* @return String the rendered element
|
||||||
|
*/
|
||||||
|
this.tagAsString = function(name, attr) {
|
||||||
|
res.push();
|
||||||
|
renderMarkupPart(name, "<", " />", attr);
|
||||||
|
return res.pop();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* render an arbitrary x/html element
|
||||||
|
* @param String the element's name
|
||||||
|
* @param String the element's content
|
||||||
|
* @param Object the element's attributes
|
||||||
|
*/
|
||||||
|
this.element = function(name, str, attr) {
|
||||||
|
renderMarkupPart(name, "<", ">", attr);
|
||||||
|
res.write(str);
|
||||||
|
renderMarkupPart(name, "</", ">");
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return an arbitrary x/html element
|
||||||
|
* @see this.element
|
||||||
|
* @param String the rendered element
|
||||||
|
*/
|
||||||
|
this.elementAsString = function(name, str, attr) {
|
||||||
|
res.push();
|
||||||
|
self.element(name, str, attr);
|
||||||
|
return res.pop();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* render an x/html link element
|
||||||
|
* @param Object the element's attributes
|
||||||
|
* @param String the element's content
|
||||||
|
*/
|
||||||
|
this.link = function(attr, text) {
|
||||||
|
if (!attr) {
|
||||||
|
res.write("[Html.link: insufficient arguments]");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
self.openTag("a", attr);
|
||||||
|
res.write(text);
|
||||||
|
self.closeTag("a");
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return an x/html link element
|
||||||
|
* @see this.link
|
||||||
|
* @return String the rendered element
|
||||||
|
*/
|
||||||
|
this.linkAsString = function(attr, text) {
|
||||||
|
res.push();
|
||||||
|
self.link(attr, text);
|
||||||
|
return res.pop();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* render an x/html hidden input element
|
||||||
|
* @param Object the element's attributes
|
||||||
|
*/
|
||||||
|
this.hidden = function(param) {
|
||||||
|
if (!param) {
|
||||||
|
res.write("[Html.hidden: insufficient arguments]");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var attr = Object.clone(param);
|
||||||
|
attr.type = "hidden";
|
||||||
|
attr.value = (attr.value != null) ? encodeForm(attr.value) : "";
|
||||||
|
self.tag("input", attr);
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return an x/html hidden input element
|
||||||
|
* @see this.hidden
|
||||||
|
* @return String the rendered element
|
||||||
|
*/
|
||||||
|
this.hiddenAsString = function(attr) {
|
||||||
|
res.push();
|
||||||
|
self.hidden(attr);
|
||||||
|
return res.pop();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* render an x/html text input element
|
||||||
|
* @param Object the element's attributes
|
||||||
|
*/
|
||||||
|
this.input = function(param) {
|
||||||
|
if (!param) {
|
||||||
|
res.write("[Html.input: insufficient arguments]");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var attr = Object.clone(param);
|
||||||
|
attr.type = "text";
|
||||||
|
if (!attr.size)
|
||||||
|
attr.size = 20;
|
||||||
|
attr.value = (attr.value != null) ? encodeForm(attr.value) : "";
|
||||||
|
self.tag("input", attr);
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return an x/html text input element
|
||||||
|
* @see this.input
|
||||||
|
* @return String the rendered element
|
||||||
|
*/
|
||||||
|
this.inputAsString = function(attr) {
|
||||||
|
res.push();
|
||||||
|
self.input(attr);
|
||||||
|
return res.pop();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* render an x/html textarea element
|
||||||
|
* @param Object the element's attributes
|
||||||
|
*/
|
||||||
|
this.textArea = function(param) {
|
||||||
|
if (!param) {
|
||||||
|
res.write("[Html.textArea: insufficient arguments]");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var attr = Object.clone(param);
|
||||||
|
var value = (attr.value != null) ? encodeForm(attr.value) : "";
|
||||||
|
delete attr.value;
|
||||||
|
self.openTag("textarea", attr);
|
||||||
|
res.write(value);
|
||||||
|
self.closeTag("textarea");
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return an x/html textarea element
|
||||||
|
* @see this.textArea
|
||||||
|
* @return String the rendered element
|
||||||
|
*/
|
||||||
|
this.textAreaAsString = function(attr) {
|
||||||
|
res.push();
|
||||||
|
self.textArea(attr);
|
||||||
|
return res.pop();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* render an x/html checkbox input element
|
||||||
|
* @param Object the element's attributes
|
||||||
|
*/
|
||||||
|
this.checkBox = function(param) {
|
||||||
|
if (!param) {
|
||||||
|
res.write("[Html.checkBox: insufficient arguments]");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var attr = Object.clone(param);
|
||||||
|
attr.type = "checkbox";
|
||||||
|
if (attr.selectedValue != null) {
|
||||||
|
if (isSelected(param.value, param.selectedValue))
|
||||||
|
attr.checked = "checked";
|
||||||
|
else
|
||||||
|
delete attr.checked;
|
||||||
|
delete attr.selectedValue;
|
||||||
|
}
|
||||||
|
self.tag("input", attr);
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return an x/html checkbox input element
|
||||||
|
* @see this.checkBox
|
||||||
|
* @return String the rendered element
|
||||||
|
*/
|
||||||
|
this.checkBoxAsString = function(attr) {
|
||||||
|
res.push();
|
||||||
|
self.checkBox(attr);
|
||||||
|
return res.pop();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* render an x/html radiobutton input element
|
||||||
|
* @param Object the element's attributes
|
||||||
|
*/
|
||||||
|
this.radioButton = function(param) {
|
||||||
|
if (!param) {
|
||||||
|
res.write("[Html.radioButton: insufficient arguments]");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var attr = Object.clone(param);
|
||||||
|
attr.type = "radio";
|
||||||
|
if (attr.selectedValue != null) {
|
||||||
|
if (attr.value == attr.selectedValue)
|
||||||
|
attr.checked = "checked";
|
||||||
|
else
|
||||||
|
delete attr.checked;
|
||||||
|
delete attr.selectedValue;
|
||||||
|
}
|
||||||
|
self.tag("input", attr);
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return an x/html radiobutton input element
|
||||||
|
* @see this.radioButton
|
||||||
|
* @return String the rendered element
|
||||||
|
*/
|
||||||
|
this.radioButtonAsString = function(attr) {
|
||||||
|
res.push();
|
||||||
|
self.radioButton(attr);
|
||||||
|
return res.pop();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* render an x/html submit input element
|
||||||
|
* @param Object the element's attributes
|
||||||
|
*/
|
||||||
|
this.submit = function(param) {
|
||||||
|
if (!param) {
|
||||||
|
res.write("[Html.submit: insufficient arguments]");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var attr = Object.clone(param);
|
||||||
|
attr.type = "submit";
|
||||||
|
if (!attr.name)
|
||||||
|
attr.name = attr.type;
|
||||||
|
attr.value = (attr.value != null) ? encodeForm(attr.value) : attr.type;
|
||||||
|
self.tag("input", attr);
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return an x/html submit input element
|
||||||
|
* @see this.submit
|
||||||
|
* @return String the rendered element
|
||||||
|
*/
|
||||||
|
this.submitAsString = function(attr) {
|
||||||
|
res.push();
|
||||||
|
self.submit(attr);
|
||||||
|
return res.pop();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* render an x/html button input element
|
||||||
|
* @param Object the element's attributes
|
||||||
|
*/
|
||||||
|
this.button = function(param) {
|
||||||
|
if (!param) {
|
||||||
|
res.write("[Html.button: insufficient arguments]");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var attr = Object.clone(param);
|
||||||
|
attr.type = "button";
|
||||||
|
if (!attr.name)
|
||||||
|
attr.name = attr.type;
|
||||||
|
attr.value = (attr.value != null) ? encodeForm(attr.value) : attr.type;
|
||||||
|
self.tag("input", attr);
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return an x/html button input element
|
||||||
|
* @see this.button
|
||||||
|
* @return String the rendered element
|
||||||
|
*/
|
||||||
|
this.buttonAsString = function(attr) {
|
||||||
|
res.push();
|
||||||
|
self.button(attr);
|
||||||
|
return res.pop();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* render a x/html drop down box
|
||||||
|
* @param Object the element's attributes
|
||||||
|
* @param Array either an array of strings, an array with
|
||||||
|
* several {value: v, display: d} objects, or a collection
|
||||||
|
* of ["value", "display"] arrays in an array
|
||||||
|
* @param String the currently selected value
|
||||||
|
* @param String the first option (without a value)
|
||||||
|
*/
|
||||||
|
this.dropDown = function(param, options, selectedValue, firstOption) {
|
||||||
|
if (!param) {
|
||||||
|
res.write("[Html.dropDown: insufficient arguments]");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var attr = Object.clone(param);
|
||||||
|
if (!attr.size)
|
||||||
|
attr.size = 1;
|
||||||
|
self.openTag("select", attr);
|
||||||
|
res.write("\n ");
|
||||||
|
if (firstOption) {
|
||||||
|
self.openTag("option", {value: ""});
|
||||||
|
res.write(firstOption);
|
||||||
|
self.closeTag("option");
|
||||||
|
res.write("\n ");
|
||||||
|
}
|
||||||
|
for (var i in options) {
|
||||||
|
var attr = new Object();
|
||||||
|
var display = "";
|
||||||
|
if ((options[i] instanceof Array) && options[i].length > 0) {
|
||||||
|
// option is an array
|
||||||
|
attr.value = options[i][0];
|
||||||
|
display = options[i][1];
|
||||||
|
} else if (options[i].value != null && options[i].display != null) {
|
||||||
|
// option is an object
|
||||||
|
attr.value = options[i].value;
|
||||||
|
display = options[i].display;
|
||||||
|
} else {
|
||||||
|
// assume option is a string
|
||||||
|
attr.value = i;
|
||||||
|
display = options[i];
|
||||||
|
}
|
||||||
|
if (isSelected(attr.value, selectedValue))
|
||||||
|
attr.selected = "selected";
|
||||||
|
self.openTag("option", attr);
|
||||||
|
res.write(display);
|
||||||
|
self.closeTag("option");
|
||||||
|
res.write("\n ");
|
||||||
|
}
|
||||||
|
self.closeTag("select");
|
||||||
|
res.write("\n ");
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return an x/html drop down box
|
||||||
|
* @see this.dropDown
|
||||||
|
* @return String the rendered drop down box
|
||||||
|
*/
|
||||||
|
this.dropDownAsString = function(attr, options, selectedValue, firstOption) {
|
||||||
|
res.push();
|
||||||
|
self.dropDown(attr, options, selectedValue, firstOption);
|
||||||
|
return res.pop();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders an image map from an array
|
||||||
|
* each array contains an object describing the parameters
|
||||||
|
* for the area of the image map
|
||||||
|
* @param String name of the image map
|
||||||
|
* @param String array of image map objects
|
||||||
|
*/
|
||||||
|
this.map = function(name, param) {
|
||||||
|
self.openTag("map", {name: name});
|
||||||
|
var areas = Object.clone(param);
|
||||||
|
for (var i in areas) {
|
||||||
|
if (!areas[i].alt)
|
||||||
|
areas[i].alt = "";
|
||||||
|
if (!areas[i].shape)
|
||||||
|
areas[i].shape = "rect";
|
||||||
|
self.openTag("area", areas[i]);
|
||||||
|
}
|
||||||
|
self.closeTag("map");
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see Html.map
|
||||||
|
* @return the rendered element
|
||||||
|
*/
|
||||||
|
this.mapAsString = function(name, areas) {
|
||||||
|
res.push();
|
||||||
|
self.map(name, areas);
|
||||||
|
return res.pop();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* render a complete x/html table
|
||||||
|
* @param Array an array containing table headers
|
||||||
|
* @param Array a 2 dimensional array containing the table data
|
||||||
|
* @param Object the table's, its rows' and cells' attributes
|
||||||
|
*/
|
||||||
|
this.table = function(headers, data, param) {
|
||||||
|
if (!param) {
|
||||||
|
res.write("[Html.table: insufficient arguments]");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var attr = Object.clone(param);
|
||||||
|
if (!attr.trHead) attr.trHead = attr.tr;
|
||||||
|
if (!attr.trEven) attr.trEven = attr.tr;
|
||||||
|
if (!attr.trOdd) attr.trOdd = attr.tr;
|
||||||
|
if (!attr.tdEven) attr.tdEven = attr.td;
|
||||||
|
if (!attr.tdOdd) attr.tdOdd = attr.td;
|
||||||
|
if (!attr.thEven) attr.thEven = attr.th;
|
||||||
|
if (!attr.thOdd) attr.thOdd = attr.th;
|
||||||
|
self.openTag("table", attr.table);
|
||||||
|
if (headers) {
|
||||||
|
self.openTag("tr", attr.trHead);
|
||||||
|
for (var i in headers) {
|
||||||
|
var evenOdd = i % 2 == 0 ? "Even" : "Odd";
|
||||||
|
self.openTag("th", attr["th"+evenOdd]);
|
||||||
|
res.write(headers[i]);
|
||||||
|
self.closeTag("th");
|
||||||
|
}
|
||||||
|
self.closeTag("tr");
|
||||||
|
}
|
||||||
|
for (var i in data) {
|
||||||
|
var evenOdd = i % 2 == 0 ? "Even" : "Odd";
|
||||||
|
self.openTag("tr", attr["tr"+evenOdd]);
|
||||||
|
for (var j in data[i]) {
|
||||||
|
var evenOddCell = j % 2 == 0 ? "Even" : "Odd";
|
||||||
|
self.openTag("td", attr["td"+evenOddCell]);
|
||||||
|
res.write(data[i][j]);
|
||||||
|
self.closeTag("td");
|
||||||
|
}
|
||||||
|
self.closeTag("tr");
|
||||||
|
}
|
||||||
|
self.closeTag("table");
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return a complete x/html table
|
||||||
|
* @see this.table
|
||||||
|
* @return String the rendered table
|
||||||
|
*/
|
||||||
|
this.tableAsString = function(headers, data, attr) {
|
||||||
|
res.push();
|
||||||
|
self.table(headers, data, attr);
|
||||||
|
return res.pop();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* utility object to provide an easy way
|
||||||
|
* for programmatically creating an x/html table.
|
||||||
|
* @param Number the number of columns in the table
|
||||||
|
* @param Object the table's, its rows' and cells' attributes
|
||||||
|
* @return Object an instance of TableWriter
|
||||||
|
*/
|
||||||
|
this.TableWriter = function(numberOfColumns, attr) {
|
||||||
|
this.ncols = numberOfColumns;
|
||||||
|
if (isNaN(this.ncols))
|
||||||
|
throw "Illegal argument in TableWriter(): first argument must be a number";
|
||||||
|
if (this.ncols < 1)
|
||||||
|
throw "Illegal argument in TableWriter(): first argument must be > 1";
|
||||||
|
this.written = 0;
|
||||||
|
// if no attributes object given, create an empty one
|
||||||
|
if (!attr)
|
||||||
|
attr = {};
|
||||||
|
if (!attr.trEven) attr.trEven = attr.tr;
|
||||||
|
if (!attr.trOdd) attr.trOdd = attr.tr;
|
||||||
|
if (!attr.trHead) attr.trHead = attr.trEven;
|
||||||
|
if (!attr.tdEven) attr.tdEven = attr.td;
|
||||||
|
if (!attr.tdOdd) attr.tdOdd = attr.td;
|
||||||
|
if (!attr.thEven) attr.thEven = attr.th;
|
||||||
|
if (!attr.thOdd) attr.thOdd = attr.th;
|
||||||
|
this.attr = attr;
|
||||||
|
|
||||||
|
// write header row? set to true to use "th" tags for first row
|
||||||
|
this.writeHeader = false;
|
||||||
|
// write to string buffer rather than response?
|
||||||
|
this.writeString = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write a table cell.
|
||||||
|
* @param String the table cell content as text
|
||||||
|
* @param attr an optional attributes holder for the td tag
|
||||||
|
*/
|
||||||
|
this.write = function(text, attr) {
|
||||||
|
// set up some variables
|
||||||
|
var isHeaderRow = (this.writeHeader && this.written < this.ncols);
|
||||||
|
var isNewRow = (this.written % this.ncols == 0);
|
||||||
|
var isEvenRow = ((this.written / this.ncols) % 2 == 0);
|
||||||
|
var isEvenCol = ((this.written % this.ncols) % 2 == 0);
|
||||||
|
// write out table and table row tags
|
||||||
|
if (this.written == 0) {
|
||||||
|
if (this.writeString)
|
||||||
|
res.push();
|
||||||
|
self.openTag("table", this.attr.table);
|
||||||
|
self.openTag("tr", this.attr.trHead);
|
||||||
|
} else if (isNewRow) {
|
||||||
|
self.closeTag("tr");
|
||||||
|
if (isEvenRow)
|
||||||
|
self.openTag("tr", this.attr.trEven);
|
||||||
|
else
|
||||||
|
self.openTag("tr", this.attr.trOdd);
|
||||||
|
}
|
||||||
|
// get the attribute object for the table cell
|
||||||
|
if (!attr) {
|
||||||
|
// no explicit attribute given
|
||||||
|
if (isEvenCol)
|
||||||
|
attr = isHeaderRow ? this.attr.thEven : this.attr.tdEven;
|
||||||
|
else
|
||||||
|
attr = isHeaderRow ? this.attr.thOdd : this.attr.tdOdd;
|
||||||
|
}
|
||||||
|
// write out table cell tag
|
||||||
|
self.openTag(isHeaderRow ? "th" : "td", attr);
|
||||||
|
// write out table cell contents
|
||||||
|
if (text)
|
||||||
|
res.write(text);
|
||||||
|
// close table cell
|
||||||
|
self.closeTag(isHeaderRow ? "th" : "td");
|
||||||
|
if (attr && !isNaN(attr.colspan))
|
||||||
|
this.written += attr.colspan;
|
||||||
|
else
|
||||||
|
this.written += 1;
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close all open table tags.
|
||||||
|
*/
|
||||||
|
this.close = function() {
|
||||||
|
if (this.written > 0) {
|
||||||
|
while (this.written++ % this.ncols != 0)
|
||||||
|
res.write("<td></td>");
|
||||||
|
res.write("</tr></table>");
|
||||||
|
this.written = 0;
|
||||||
|
}
|
||||||
|
if (this.writeString)
|
||||||
|
return res.pop();
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.dontEnum("ncols", "written", "attr", "writeHeader");
|
||||||
|
this.dontEnum("writeString", "write", "close");
|
||||||
|
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*********************************************************************/
|
||||||
|
/* */
|
||||||
|
/* the following functions should be deliberately altered or removed */
|
||||||
|
/* (most of these can easily be replaced by the methods they call) */
|
||||||
|
/* */
|
||||||
|
/*********************************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* render an x/html open link tag
|
||||||
|
* @param Object the element's attributes
|
||||||
|
*/
|
||||||
|
this.openLink = function(attr) {
|
||||||
|
self.openTag("a", attr);
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return an x/html open link tag
|
||||||
|
* @see this.openTag
|
||||||
|
* @return String the rendered element
|
||||||
|
*/
|
||||||
|
this.openLinkAsString = function(attr) {
|
||||||
|
return self.openTagAsString("a", attr);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* render an x/html close link tag
|
||||||
|
*/
|
||||||
|
this.closeLink = function() {
|
||||||
|
self.closeTag("a");
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return an x/html close link tag
|
||||||
|
* @see this.closeLink
|
||||||
|
* @return String the rendered element
|
||||||
|
*/
|
||||||
|
this.closeLinkAsString = function() {
|
||||||
|
return self.closeTagAsString("a");
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* render a color string
|
||||||
|
* if it contains hex characters only prefix it with "#"
|
||||||
|
* otherwise assume that it is a named color (eg. "yellow")
|
||||||
|
* @param String the color string
|
||||||
|
* @deprecated
|
||||||
|
*/
|
||||||
|
this.color = function(c) {
|
||||||
|
if (c) {
|
||||||
|
var nonhex = /[^0-9,a-f]/gi;
|
||||||
|
if (!c.match(nonhex)) {
|
||||||
|
c = c.pad("0", 6);
|
||||||
|
res.write("#");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
res.write(c);
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return a color string
|
||||||
|
* @see this.color
|
||||||
|
* @return String the resulting color string
|
||||||
|
* @deprecated
|
||||||
|
*/
|
||||||
|
this.colorAsString = function(c) {
|
||||||
|
res.push();
|
||||||
|
return self.color(c);
|
||||||
|
return res.pop();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* render an x/html open form tag
|
||||||
|
* @param Object the element's attributes
|
||||||
|
*/
|
||||||
|
this.form = function(attr) {
|
||||||
|
self.openTag("form", attr);
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return an x/html open form tag
|
||||||
|
* @see this.form
|
||||||
|
* @return String the rendered element
|
||||||
|
*/
|
||||||
|
this.formAsString = function(attr) {
|
||||||
|
res.push();
|
||||||
|
self.form(attr);
|
||||||
|
return res.pop();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* render an x/html password input element
|
||||||
|
* @param Object the element's attributes
|
||||||
|
*/
|
||||||
|
this.password = function(attr) {
|
||||||
|
if (!attr) {
|
||||||
|
res.write("[Html.password: insufficient arguments]");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
attr.type = "password";
|
||||||
|
if (!attr.size)
|
||||||
|
attr.size = 20;
|
||||||
|
self.tag("input", attr);
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* render an x/html password input element
|
||||||
|
* @see this.password
|
||||||
|
* @return String the rendered element
|
||||||
|
*/
|
||||||
|
this.passwordAsString = function(attr) {
|
||||||
|
res.push();
|
||||||
|
self.password(attr);
|
||||||
|
return res.pop();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* render an x/html file input element
|
||||||
|
* @param Object the element's attributes
|
||||||
|
*/
|
||||||
|
this.file = function(attr) {
|
||||||
|
if (!attr) {
|
||||||
|
res.write("[Html.file: insufficient arguments]");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
attr.type = "file";
|
||||||
|
self.tag("input", attr);
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return an x/html file input element
|
||||||
|
* @see this.file
|
||||||
|
* @return String the rendered element
|
||||||
|
*/
|
||||||
|
this.fileAsString = function(attr) {
|
||||||
|
res.push();
|
||||||
|
self.file(attr);
|
||||||
|
return res.pop();
|
||||||
|
};
|
||||||
|
|
||||||
|
for (var i in this)
|
||||||
|
this.dontEnum(i);
|
||||||
|
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
helma.Html.toString = function() {
|
||||||
|
return "[helma.Html]";
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* function parses a string and converts any
|
||||||
|
* found URL into a HTML link tag
|
||||||
|
* @return String resulting string with activated URLs
|
||||||
|
*/
|
||||||
|
helma.Html.prototype.activateUrls = function(str) {
|
||||||
|
var re = /(^|\/>|\s+)([fhtpsr]+:\/\/[^\s]+?)([\.,;:\)\]\"]?)(?=[\s<]|$)/gim;
|
||||||
|
var func = function(str, p1, p2, p3) {
|
||||||
|
res.push();
|
||||||
|
res.write(p1);
|
||||||
|
res.write('<a href="');
|
||||||
|
res.write(p2);
|
||||||
|
res.write('">');
|
||||||
|
res.write(p2.clip(50, "...", true));
|
||||||
|
res.write('</a>');
|
||||||
|
res.write(p3);
|
||||||
|
return res.pop();
|
||||||
|
};
|
||||||
|
return str.replace(re, func);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
helma.lib = "Html";
|
||||||
|
helma.dontEnum(helma.lib);
|
||||||
|
for (var i in helma[helma.lib])
|
||||||
|
helma[helma.lib].dontEnum(i);
|
||||||
|
for (var i in helma[helma.lib].prototype)
|
||||||
|
helma[helma.lib].prototype.dontEnum(i);
|
||||||
|
delete helma.lib;
|
340
helma/Http.js
Normal file
340
helma/Http.js
Normal file
|
@ -0,0 +1,340 @@
|
||||||
|
/*
|
||||||
|
* Helma License Notice
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Helma License
|
||||||
|
* Version 2.0 (the "License"). You may not use this file except in
|
||||||
|
* compliance with the License. A copy of the License is available at
|
||||||
|
* http://adele.helma.org/download/helma/license.txt
|
||||||
|
*
|
||||||
|
* Copyright 1998-2006 Helma Software. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* $RCSfile: helma.Http.js,v $
|
||||||
|
* $Author: czv $
|
||||||
|
* $Revision: 1.11 $
|
||||||
|
* $Date: 2006/04/18 13:06:58 $
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
if (!global.helma) {
|
||||||
|
global.helma = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
helma.Http = function() {
|
||||||
|
var proxy = null;
|
||||||
|
var content = "";
|
||||||
|
var userAgent = "Helma Http Client";
|
||||||
|
var method = "GET";
|
||||||
|
var credentials = null;
|
||||||
|
var followRedirects = true;
|
||||||
|
var headers = {};
|
||||||
|
var timeout = {
|
||||||
|
"connect": 0,
|
||||||
|
"socket": 0
|
||||||
|
};
|
||||||
|
|
||||||
|
var setTimeout = function(type, value) {
|
||||||
|
var v = java.lang.System.getProperty("java.specification.version");
|
||||||
|
if (parseFloat(v, 10) >= 1.5) {
|
||||||
|
timeout[type] = value;
|
||||||
|
} else {
|
||||||
|
app.log("[Helma Http Client] WARNING: timeouts can only be set with Java Runtime version >= 1.5");
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sets the proxy host and port for later use
|
||||||
|
*/
|
||||||
|
this.setProxy = function(proxyString) {
|
||||||
|
var idx = proxyString.indexOf(":");
|
||||||
|
var host = proxyString.substring(0, idx);
|
||||||
|
var port = proxyString.substring(idx+1);
|
||||||
|
if (java.lang.Class.forName("java.net.Proxy") != null) {
|
||||||
|
// construct a proxy instance
|
||||||
|
var socket = new java.net.InetSocketAddress(host, port);
|
||||||
|
proxy = new java.net.Proxy(java.net.Proxy.Type.HTTP, socket);
|
||||||
|
} else {
|
||||||
|
// the pre jdk1.5 way: set the system properties
|
||||||
|
var sys = java.lang.System.getProperties();
|
||||||
|
if (host) {
|
||||||
|
app.log("[Helma Http Client] WARNING: setting system http proxy to " + host + ":" + port);
|
||||||
|
sys.put("http.proxySet", "true");
|
||||||
|
sys.put("http.proxyHost", host);
|
||||||
|
sys.put("http.proxyPort", port);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns the proxy in "host:port" format
|
||||||
|
*/
|
||||||
|
this.getProxy = function() {
|
||||||
|
if (proxy != null) {
|
||||||
|
return proxy.address().getHostName() + ":" + proxy.address().getPort();
|
||||||
|
} else if (sys.get("http.proxySet") == "true") {
|
||||||
|
return sys.get("http.proxyHost") + ":" + sys.get("http.proxyPort");
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sets the credentials for basic http authentication
|
||||||
|
*/
|
||||||
|
this.setCredentials = function(username, password) {
|
||||||
|
var str = new java.lang.String(username + ":" + password);
|
||||||
|
credentials = (new Packages.sun.misc.BASE64Encoder()).encode(str.getBytes());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setContent = function(stringOrObject) {
|
||||||
|
if (stringOrObject.constructor == Object) {
|
||||||
|
res.push();
|
||||||
|
var value;
|
||||||
|
for (var key in stringOrObject) {
|
||||||
|
value = stringOrObject[key];
|
||||||
|
res.write(encodeURIComponent(key));
|
||||||
|
res.write("=");
|
||||||
|
res.write(encodeURIComponent(value));
|
||||||
|
res.write("&");
|
||||||
|
}
|
||||||
|
content = res.pop();
|
||||||
|
content = content.substring(0, content.length-1);
|
||||||
|
} else
|
||||||
|
content = stringOrObject.toString();
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getter/setter for method
|
||||||
|
*/
|
||||||
|
this.setMethod = function(m) {
|
||||||
|
method = m;
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
this.getMethod = function() {
|
||||||
|
return method;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.setHeader = function(name, value) {
|
||||||
|
headers[name] = value;
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
this.getHeader = function(name) {
|
||||||
|
return headers[name];
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getter/setter for timeouts
|
||||||
|
*/
|
||||||
|
this.setTimeout = function(timeout) {
|
||||||
|
setTimeout("connect", timeout);
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
this.setReadTimeout = function(timeout) {
|
||||||
|
setTimeout("socket", timeout);
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
this.getTimeout = function() {
|
||||||
|
return timeout.connect;
|
||||||
|
};
|
||||||
|
this.getReadTimeout = function() {
|
||||||
|
return timeout.socket;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getter/setter for following redirects
|
||||||
|
*/
|
||||||
|
this.setFollowRedirects = function(value) {
|
||||||
|
followRedirects = value;
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
this.getFollowRedirects = function() {
|
||||||
|
return followRedirects;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getter/setter for user agent string
|
||||||
|
*/
|
||||||
|
this.setUserAgent = function(agent) {
|
||||||
|
userAgent = agent;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
this.getUserAgent = function() {
|
||||||
|
return userAgent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* executes a http request
|
||||||
|
*/
|
||||||
|
this.getUrl = function(url, opt) {
|
||||||
|
if (typeof url == "string") {
|
||||||
|
if (!(url = helma.Http.evalUrl(url)))
|
||||||
|
throw new Error("'" + url + "' is not a valid URL.");
|
||||||
|
} else if (!(url instanceof java.net.URL)) {
|
||||||
|
throw new Error("'" + url + "' is not a valid URL.");
|
||||||
|
}
|
||||||
|
|
||||||
|
var conn = proxy ? url.openConnection(proxy) : url.openConnection();
|
||||||
|
conn.setFollowRedirects(followRedirects);
|
||||||
|
conn.setAllowUserInteraction(false);
|
||||||
|
conn.setRequestMethod(method);
|
||||||
|
conn.setRequestProperty("User-Agent", userAgent);
|
||||||
|
|
||||||
|
if (opt) {
|
||||||
|
if (opt instanceof Date)
|
||||||
|
conn.setIfModifiedSince(opt.getTime());
|
||||||
|
else if ((typeof opt == "string") && (opt.length > 0))
|
||||||
|
conn.setRequestProperty("If-None-Match", opt);
|
||||||
|
}
|
||||||
|
if (credentials != null) {
|
||||||
|
conn.setRequestProperty("Authorization", "Basic " + credentials);
|
||||||
|
}
|
||||||
|
if (parseFloat(java.lang.System.getProperty("java.specification.version"), 10) >= 1.5) {
|
||||||
|
conn.setConnectTimeout(timeout.connect);
|
||||||
|
conn.setReadTimeout(timeout.socket);
|
||||||
|
} else {
|
||||||
|
app.debug("WARNING: timeouts can only be set due to Java version < 1.5");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i in headers)
|
||||||
|
conn.setRequestProperty(i, headers[i]);
|
||||||
|
|
||||||
|
if (content) {
|
||||||
|
conn.setRequestProperty("Content-Length", content.length);
|
||||||
|
conn.setDoOutput(true);
|
||||||
|
var out = new java.io.DataOutputStream(conn.getOutputStream());
|
||||||
|
out.writeBytes(new java.lang.String(content));
|
||||||
|
out.flush();
|
||||||
|
out.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
var result = {
|
||||||
|
url: conn.getURL(),
|
||||||
|
location: conn.getHeaderField("location"),
|
||||||
|
code: conn.getResponseCode(),
|
||||||
|
message: conn.getResponseMessage(),
|
||||||
|
length: conn.getContentLength(),
|
||||||
|
type: conn.getContentType(),
|
||||||
|
encoding: conn.getContentEncoding(),
|
||||||
|
lastModified: null,
|
||||||
|
eTag: null,
|
||||||
|
content: null
|
||||||
|
}
|
||||||
|
var lastmod = conn.getLastModified();
|
||||||
|
if (lastmod)
|
||||||
|
result.lastModified = new Date(lastmod);
|
||||||
|
result.eTag = conn.getHeaderField("ETag");
|
||||||
|
|
||||||
|
if (result.length != 0 && result.code == 200) {
|
||||||
|
var body = new java.io.ByteArrayOutputStream();
|
||||||
|
var input = new java.io.BufferedInputStream(conn.getInputStream());
|
||||||
|
var buf = java.lang.reflect.Array.newInstance(java.lang.Byte.TYPE, 1024);
|
||||||
|
var str;
|
||||||
|
while ((str = input.read(buf)) > -1) {
|
||||||
|
body.write(buf, 0, str);
|
||||||
|
}
|
||||||
|
input.close();
|
||||||
|
result.content = result.encoding ? body.toString(result.encoding) : body.toString();
|
||||||
|
result.length = result.content.length;
|
||||||
|
}
|
||||||
|
conn.disconnect();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.toString = function() {
|
||||||
|
return "[Helma Http Client]";
|
||||||
|
};
|
||||||
|
|
||||||
|
for (var i in this)
|
||||||
|
this.dontEnum(i);
|
||||||
|
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* removes trailing slash from and evaluates a url
|
||||||
|
* @param String the url or uri string
|
||||||
|
* @return Object the result with error and result properties
|
||||||
|
*/
|
||||||
|
helma.Http.evalUrl = function(url) {
|
||||||
|
try {
|
||||||
|
return new java.net.URL(url);
|
||||||
|
} catch (err) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* set global http proxy
|
||||||
|
*/
|
||||||
|
helma.Http.setProxy = function(proxyString) {
|
||||||
|
var sys = java.lang.System.getProperties();
|
||||||
|
if (proxyString) {
|
||||||
|
var idx = proxyString.indexOf(":");
|
||||||
|
var host = proxyString.substring(0, idx);
|
||||||
|
var port = proxyString.substring(idx+1);
|
||||||
|
if (!port)
|
||||||
|
port = "3128";
|
||||||
|
else if (typeof port == "number")
|
||||||
|
port = port.toString();
|
||||||
|
app.log("helma.Http.setProxy " + proxyString);
|
||||||
|
sys.put("http.proxySet", "true");
|
||||||
|
sys.put("http.proxyHost", host);
|
||||||
|
sys.put("http.proxyPort", port);
|
||||||
|
} else {
|
||||||
|
sys.put("http.proxySet", "false");
|
||||||
|
sys.put("http.proxyHost", "");
|
||||||
|
sys.put("http.prodyPort", "");
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return global proxy settings
|
||||||
|
*/
|
||||||
|
helma.Http.getProxy = function() {
|
||||||
|
var sys = java.lang.System.getProperties();
|
||||||
|
if (sys.get("http.proxySet") == "true")
|
||||||
|
return sys.get("http.proxyHost") + ":" + sys.get("http.proxyPort");
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* static method to check if a request is authorized or not
|
||||||
|
* @param String username to check req.username against
|
||||||
|
* @param String password to check req.password against
|
||||||
|
* @return Boolean true if request is authorized, false otherwise
|
||||||
|
*/
|
||||||
|
helma.Http.isAuthorized = function(name, pwd) {
|
||||||
|
if (!req.username || !req.password ||
|
||||||
|
req.username != name || req.password != pwd) {
|
||||||
|
res.reset();
|
||||||
|
res.status = 401;
|
||||||
|
res.realm = "Helma Http Authorization";
|
||||||
|
res.write("Authorization required.");
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
helma.Http.toString = function() {
|
||||||
|
return "[helma.Http]";
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
helma.lib = "Http";
|
||||||
|
helma.dontEnum(helma.lib);
|
||||||
|
for (var i in helma[helma.lib])
|
||||||
|
helma[helma.lib].dontEnum(i);
|
||||||
|
for (var i in helma[helma.lib].prototype)
|
||||||
|
helma[helma.lib].prototype.dontEnum(i);
|
||||||
|
delete helma.lib;
|
108
helma/Image.js
Normal file
108
helma/Image.js
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
/*
|
||||||
|
* Helma License Notice
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Helma License
|
||||||
|
* Version 2.0 (the "License"). You may not use this file except in
|
||||||
|
* compliance with the License. A copy of the License is available at
|
||||||
|
* http://adele.helma.org/download/helma/license.txt
|
||||||
|
*
|
||||||
|
* Copyright 1998-2006 Helma Software. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* $RCSfile: helma.Image.js,v $
|
||||||
|
* $Author: czv $
|
||||||
|
* $Revision: 1.6 $
|
||||||
|
* $Date: 2006/04/18 13:06:58 $
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
if (!global.helma) {
|
||||||
|
global.helma = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
helma.Image = function(arg) {
|
||||||
|
// according to
|
||||||
|
// http://grazia.helma.org/pipermail/helma-dev/2004-June/001253.html
|
||||||
|
var generator = Packages.helma.image.ImageGenerator.getInstance();
|
||||||
|
return generator.createImage(arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
helma.Image.toString = function() {
|
||||||
|
return "[helma.Image]";
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
helma.Image.getInfo = function(arg) {
|
||||||
|
if (arguments.length != 1) {
|
||||||
|
throw new java.lang.IllegalArgumentException(
|
||||||
|
"Image.getInfo() expects one argument"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
var inp, result;
|
||||||
|
var info = new Packages.helma.image.ImageInfo();
|
||||||
|
// FIXME: we need a byte object for comparison
|
||||||
|
var b = java.lang.reflect.Array.newInstance(java.lang.Byte.TYPE, 1024);
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (arg instanceof java.io.InputStream) {
|
||||||
|
inp = new java.io.InputStream(arg);
|
||||||
|
// FIXME: here comes a dirty hack to check for a byte array
|
||||||
|
} else if (arg.getClass && arg.getClass() == b.getClass()) {
|
||||||
|
inp = new java.io.ByteArrayInputStream(arg);
|
||||||
|
} else if (arg instanceof java.io.File) {
|
||||||
|
inp = new java.io.FileInputStream(arg);
|
||||||
|
} else if (arg instanceof helma.File) {
|
||||||
|
inp = new java.io.FileInputStream(arg.getFile());
|
||||||
|
} else if (typeof arg == "string") {
|
||||||
|
var str = arg;
|
||||||
|
// try to interpret argument as URL if it contains a colon,
|
||||||
|
// otherwise or if URL is malformed interpret as file name.
|
||||||
|
if (str.indexOf(":") > -1) {
|
||||||
|
try {
|
||||||
|
var url = new java.net.URL(str);
|
||||||
|
inp = url.openStream();
|
||||||
|
} catch (mux) {
|
||||||
|
inp = new java.io.FileInputStream(str);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
inp = new java.io.FileInputStream(str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (inp == null) {
|
||||||
|
var msg = "Unrecognized argument in Image.getInfo(): ";
|
||||||
|
msg += (arg == null ? "null" : arg.getClass().toString());
|
||||||
|
throw new java.lang.IllegalArgumentException(msg);
|
||||||
|
}
|
||||||
|
info.setInput(inp);
|
||||||
|
if (info.check()) {
|
||||||
|
result = info;
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
// do nothing, returns null later
|
||||||
|
} finally {
|
||||||
|
if (inp != null) {
|
||||||
|
try {
|
||||||
|
inp.close();
|
||||||
|
} catch (e) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
helma.Image.spacer = function() {
|
||||||
|
res.contentType = "image/gif";
|
||||||
|
res.writeBinary([71,73,70,56,57,97,2,0,2,0,-128,-1,0,-64,-64,-64,0,0,0,33,-7,4,1,0,0,0,0,44,0,0,0,0,1,0,1,0,64,2,2,68,1,0,59]);
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
helma.lib = "Image";
|
||||||
|
helma.dontEnum(helma.lib);
|
||||||
|
for (var i in helma[helma.lib])
|
||||||
|
helma[helma.lib].dontEnum(i);
|
||||||
|
for (var i in helma[helma.lib].prototype)
|
||||||
|
helma[helma.lib].prototype.dontEnum(i);
|
||||||
|
delete helma.lib;
|
315
helma/Mail.js
Normal file
315
helma/Mail.js
Normal file
|
@ -0,0 +1,315 @@
|
||||||
|
/*
|
||||||
|
* Helma License Notice
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Helma License
|
||||||
|
* Version 2.0 (the "License"). You may not use this file except in
|
||||||
|
* compliance with the License. A copy of the License is available at
|
||||||
|
* http://adele.helma.org/download/helma/license.txt
|
||||||
|
*
|
||||||
|
* Copyright 1998-2006 Helma Software. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* $RCSfile: helma.Mail.js,v $
|
||||||
|
* $Author: czv $
|
||||||
|
* $Revision: 1.6 $
|
||||||
|
* $Date: 2006/04/18 13:06:58 $
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
if (!global.helma) {
|
||||||
|
global.helma = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
helma.Mail = function(smtp) {
|
||||||
|
var OK = 0;
|
||||||
|
var SUBJECT = 10;
|
||||||
|
var TEXT = 11;
|
||||||
|
var MIMEPART = 12;
|
||||||
|
var TO = 20;
|
||||||
|
var CC = 21;
|
||||||
|
var BCC = 22;
|
||||||
|
var FROM = 23;
|
||||||
|
var REPLYTO = 24;
|
||||||
|
var SEND = 30;
|
||||||
|
var MAILPKG = Packages.javax.mail;
|
||||||
|
|
||||||
|
var self = this;
|
||||||
|
var errStr = "Error in helma.Mail";
|
||||||
|
|
||||||
|
var System = java.lang.System;
|
||||||
|
var Properties = java.util.Properties;
|
||||||
|
var IOException = java.io.IOException;
|
||||||
|
var Wrapper = Packages.org.mozilla.javascript.Wrapper;
|
||||||
|
var FileDataSource = Packages.javax.activation.FileDataSource;
|
||||||
|
var DataHandler = Packages.javax.activation.DataHandler;
|
||||||
|
|
||||||
|
var Address = MAILPKG.Address;
|
||||||
|
var Message = MAILPKG.Message;
|
||||||
|
var Multipart = MAILPKG.Multipart;
|
||||||
|
var Session = MAILPKG.Session;
|
||||||
|
var Transport = MAILPKG.Transport;
|
||||||
|
var InternetAddress = MAILPKG.internet.InternetAddress;
|
||||||
|
var AddressException = MAILPKG.internet.AddressException;
|
||||||
|
var MimePart = MAILPKG.internet.MimePart;
|
||||||
|
var MimeBodyPart = MAILPKG.internet.MimeBodyPart;
|
||||||
|
var MimeMessage = MAILPKG.internet.MimeMessage;
|
||||||
|
var MimeUtility = MAILPKG.internet.MimeUtility;
|
||||||
|
var MimeMultipart = MAILPKG.internet.MimeMultipart;
|
||||||
|
var MimePartDataSource = MAILPKG.internet.MimePartDataSource;
|
||||||
|
|
||||||
|
var buffer, multipart;
|
||||||
|
|
||||||
|
var props = new Properties();
|
||||||
|
System.setProperty(
|
||||||
|
"mail.mime.charset",
|
||||||
|
System.getProperty("mail.charset", "ISO-8859-15")
|
||||||
|
);
|
||||||
|
|
||||||
|
var host = smtp || getProperty("smtp");
|
||||||
|
if (host != null) {
|
||||||
|
props.put("mail.smtp.host", host);
|
||||||
|
}
|
||||||
|
|
||||||
|
var session = Session.getInstance(props);
|
||||||
|
var message = new MimeMessage(session);
|
||||||
|
|
||||||
|
var setStatus = function(status) {
|
||||||
|
if (self.status === OK) {
|
||||||
|
self.status = status;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
var getStatus = function() {
|
||||||
|
return self.status;
|
||||||
|
};
|
||||||
|
|
||||||
|
var addRecipient = function(addstr, name, type) {
|
||||||
|
if (addstr.indexOf("@") < 0) {
|
||||||
|
throw new AddressException();
|
||||||
|
}
|
||||||
|
if (name != null) {
|
||||||
|
var address = new InternetAddress(addstr,
|
||||||
|
MimeUtility.encodeWord(name.toString()));
|
||||||
|
} else {
|
||||||
|
var address = new InternetAddress(addstr);
|
||||||
|
}
|
||||||
|
message.addRecipient(type, address);
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.status = OK;
|
||||||
|
|
||||||
|
this.setFrom = function(addstr, name) {
|
||||||
|
try {
|
||||||
|
if (addstr.indexOf("@") < 0) {
|
||||||
|
throw new AddressException();
|
||||||
|
}
|
||||||
|
if (name != null) {
|
||||||
|
var address = new InternetAddress(addstr,
|
||||||
|
MimeUtility.encodeWord(name.toString()));
|
||||||
|
} else {
|
||||||
|
var address = new InternetAddress(addstr);
|
||||||
|
}
|
||||||
|
message.setFrom(address);
|
||||||
|
} catch (mx) {
|
||||||
|
res.debug(errStr + ".setFrom(): " + mx);
|
||||||
|
setStatus(FROM);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.setReplyTo = function(addstr) {
|
||||||
|
try {
|
||||||
|
if (addstr.indexOf("@") < 0) {
|
||||||
|
throw new AddressException();
|
||||||
|
}
|
||||||
|
var address = [new InternetAddress(addstr)];
|
||||||
|
message.setReplyTo(address);
|
||||||
|
} catch (mx) {
|
||||||
|
res.debug(errStr + ".setReplyTo(): " + mx);
|
||||||
|
setStatus(REPLYTO);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setTo = function(addstr, name) {
|
||||||
|
try {
|
||||||
|
addRecipient(addstr, name, Message.RecipientType.TO);
|
||||||
|
} catch (mx) {
|
||||||
|
res.debug(errStr + ".setTo(): " + mx);
|
||||||
|
setStatus(TO);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.addTo = function(addstr, name) {
|
||||||
|
try {
|
||||||
|
addRecipient(addstr, name, Message.RecipientType.TO);
|
||||||
|
} catch (mx) {
|
||||||
|
res.debug(errStr + ".addTo(): " + mx);
|
||||||
|
setStatus(TO);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.addCC = function(addstr, name) {
|
||||||
|
try {
|
||||||
|
addRecipient(addstr, name, Message.RecipientType.CC);
|
||||||
|
} catch (mx) {
|
||||||
|
res.debug(errStr + ".addCC(): " + mx);
|
||||||
|
setStatus(CC);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.addBCC = function(addstr, name) {
|
||||||
|
try {
|
||||||
|
addRecipient(addstr, name, Message.RecipientType.BCC);
|
||||||
|
} catch (mx) {
|
||||||
|
res.debug(errStr + ".addBCC(): " + mx);
|
||||||
|
setStatus(BCC);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setSubject = function(subject) {
|
||||||
|
if (!subject) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
message.setSubject(MimeUtility.encodeWord(subject.toString()));
|
||||||
|
} catch (mx) {
|
||||||
|
res.debug(errStr + ".setSubject(): " + mx);
|
||||||
|
setStatus(SUBJECT);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.setText = function(text) {
|
||||||
|
if (text) {
|
||||||
|
buffer = new java.lang.StringBuffer(text);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.addText = function(text) {
|
||||||
|
if (buffer == null) {
|
||||||
|
buffer = new java.lang.StringBuffer(text);
|
||||||
|
} else {
|
||||||
|
buffer.append(text);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.addPart = function(obj, filename) {
|
||||||
|
try {
|
||||||
|
if (obj == null) {
|
||||||
|
throw new IOException(
|
||||||
|
errStr + ".addPart: method called with wrong number of arguments."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (multipart == null) {
|
||||||
|
multipart = new MimeMultipart();
|
||||||
|
}
|
||||||
|
if (obj instanceof Wrapper) {
|
||||||
|
obj = obj.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
var part = new MimeBodyPart();
|
||||||
|
if (typeof obj == "string") {
|
||||||
|
part.setContent(obj.toString(), "text/plain");
|
||||||
|
} else if (obj instanceof File) {
|
||||||
|
// FIXME: the following line did not work under windows:
|
||||||
|
//var source = new FileDataSource(obj);
|
||||||
|
var source = new FileDataSource(obj.getPath());
|
||||||
|
part.setDataHandler(new DataHandler(source));
|
||||||
|
} else if (obj instanceof MimePart) {
|
||||||
|
var source = new MimePartDataSource(obj);
|
||||||
|
part.setDataHandler(new DataHandler(source));
|
||||||
|
}
|
||||||
|
if (filename != null) {
|
||||||
|
try {
|
||||||
|
part.setFileName(filename.toString());
|
||||||
|
} catch (x) {}
|
||||||
|
} else if (obj instanceof File) {
|
||||||
|
try {
|
||||||
|
part.setFileName(obj.getName());
|
||||||
|
} catch (x) {}
|
||||||
|
}
|
||||||
|
multipart.addBodyPart(part);
|
||||||
|
} catch (mx) {
|
||||||
|
res.debug(errStr + ".addPart(): " + mx);
|
||||||
|
setStatus(MIMEPART);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.send = function() {
|
||||||
|
if (this.status > OK) {
|
||||||
|
res.debug(errStr + ".send(): Status is " + this.status);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
if (buffer != null) {
|
||||||
|
if (multipart != null) {
|
||||||
|
var part = new MimeBodyPart();
|
||||||
|
part.setContent(buffer.toString(), "text/plain");
|
||||||
|
multipart.addBodyPart(part, 0);
|
||||||
|
message.setContent(multipart);
|
||||||
|
} else {
|
||||||
|
message.setText(buffer.toString());
|
||||||
|
}
|
||||||
|
} else if (multipart != null) {
|
||||||
|
message.setContent(multipart);
|
||||||
|
} else {
|
||||||
|
message.setText("");
|
||||||
|
}
|
||||||
|
Transport.send(message);
|
||||||
|
} catch (mx) {
|
||||||
|
res.debug(errStr + ".send(): " + mx);
|
||||||
|
setStatus(SEND);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
for (var i in this)
|
||||||
|
this.dontEnum(i);
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
helma.Mail.toString = function() {
|
||||||
|
return "[helma.Mail]";
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
helma.Mail.prototype.toString = function() {
|
||||||
|
return "[helma.Mail Object]";
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
helma.Mail.example = function(smtp, sender, addr, subject, text) {
|
||||||
|
// var smtp = "smtp.host.dom";
|
||||||
|
// var sender = "sender@host.dom";
|
||||||
|
// var addr = "recipient@host.dom";
|
||||||
|
// var subject = "Hello, World!";
|
||||||
|
// var text = "This is a test.";
|
||||||
|
var msg = new helma.Mail(smtp);
|
||||||
|
msg.setFrom(sender);
|
||||||
|
msg.addTo(addr);
|
||||||
|
msg.setSubject(subject);
|
||||||
|
msg.setText(text);
|
||||||
|
msg.send();
|
||||||
|
res.write(msg.status);
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
helma.lib = "Mail";
|
||||||
|
helma.dontEnum(helma.lib);
|
||||||
|
for (var i in helma[helma.lib])
|
||||||
|
helma[helma.lib].dontEnum(i);
|
||||||
|
for (var i in helma[helma.lib].prototype)
|
||||||
|
helma[helma.lib].prototype.dontEnum(i);
|
||||||
|
delete helma.lib;
|
965
helma/Search.js
Normal file
965
helma/Search.js
Normal file
|
@ -0,0 +1,965 @@
|
||||||
|
//
|
||||||
|
// A wrapper for Apache Lucene for use with Helma Object Publisher
|
||||||
|
// Copyright (c) 2005-2006 Robert Gaggl
|
||||||
|
//
|
||||||
|
// This library is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU Lesser General Public
|
||||||
|
// License as published by the Free Software Foundation; either
|
||||||
|
// version 2.1 of the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public
|
||||||
|
// License along with this library; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// $Revision: 1.7 $
|
||||||
|
// $Author: czv $
|
||||||
|
// $Date: 2006/04/18 13:06:58 $
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
// take care of any dependencies
|
||||||
|
app.addRepository('modules/helma/lucene.jar');
|
||||||
|
|
||||||
|
|
||||||
|
if (!global.helma) {
|
||||||
|
global.helma = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Search constructor
|
||||||
|
*/
|
||||||
|
helma.Search = function() {
|
||||||
|
|
||||||
|
this.toString = function() {
|
||||||
|
return helma.Search.toString();
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
var c = java.lang.Class.forName("org.apache.lucene.analysis.Analyzer",
|
||||||
|
true, app.__app__.typemgr.getClassLoader());
|
||||||
|
} catch (e) {
|
||||||
|
throw("helma.Search needs lucene.jar \
|
||||||
|
in lib/ext or application directory \
|
||||||
|
[http://lucene.apache.org/]");
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
helma.Search.PKG = Packages.org.apache.lucene;
|
||||||
|
|
||||||
|
///////////////////////////////////////////
|
||||||
|
// static methods
|
||||||
|
///////////////////////////////////////////
|
||||||
|
|
||||||
|
helma.Search.toString = function() {
|
||||||
|
return "[helma.Search]";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* static method that returns a new Analyzer instance
|
||||||
|
* depending on the language passed as argument
|
||||||
|
* @param String language
|
||||||
|
* @return Object analyzer
|
||||||
|
*/
|
||||||
|
helma.Search.getAnalyzer = function(lang) {
|
||||||
|
switch (lang) {
|
||||||
|
case "de":
|
||||||
|
return new helma.Search.PKG.analysis.de.GermanAnalyzer();
|
||||||
|
case "ru":
|
||||||
|
return new helma.Search.PKG.analysis.ru.RussianAnalyzer();
|
||||||
|
case "si":
|
||||||
|
case "simple":
|
||||||
|
return new helma.Search.PKG.analysis.SimpleAnalyzer();
|
||||||
|
case "whitespace":
|
||||||
|
return new helma.Search.PKG.analysis.WhitespaceAnalyzer();
|
||||||
|
default:
|
||||||
|
return new helma.Search.PKG.analysis.standard.StandardAnalyzer();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* constructor for QueryFilter objects
|
||||||
|
* @param Object instance of Search.Query
|
||||||
|
*/
|
||||||
|
helma.Search.QueryFilter = function(q) {
|
||||||
|
var wrappedFilter = new helma.Search.PKG.search.QueryFilter(q.getQuery());
|
||||||
|
|
||||||
|
this.getFilter = function() {
|
||||||
|
return wrappedFilter;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.toString = function() {
|
||||||
|
return wrappedFilter.toString();
|
||||||
|
};
|
||||||
|
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////
|
||||||
|
// prototype methods
|
||||||
|
///////////////////////////////////////////
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns an instance of org.apache.lucene.store.FSDirectory
|
||||||
|
* @param Object an instance of File, helma.File, java.io.File or the
|
||||||
|
* path to the directory as String
|
||||||
|
* @return Object org.apache.lucene.store.FSDirectory
|
||||||
|
*/
|
||||||
|
helma.Search.prototype.getDirectory = function(dir, create) {
|
||||||
|
if (!dir) {
|
||||||
|
throw("helma.Search.getDirectory(): insufficient arguments.");
|
||||||
|
}
|
||||||
|
var d;
|
||||||
|
if (dir.constructor == String) {
|
||||||
|
d = new java.io.File(dir);
|
||||||
|
} else if (dir.constructor == File || dir.constructor == helma.File) {
|
||||||
|
d = new java.io.File(dir.getAbsolutePath());
|
||||||
|
} else if (!((d = dir) instanceof java.io.File)) {
|
||||||
|
throw("helma.Search.getDirectory(): " + dir + " is not a valid argument.");
|
||||||
|
}
|
||||||
|
return helma.Search.PKG.store.FSDirectory.getDirectory(d,
|
||||||
|
create == true ? true : !d.exists());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns an instance of org.apache.lucene.store.RAMDirectory
|
||||||
|
* @param Object the directory to create the RAMDirectory from. Argument
|
||||||
|
* can be an instance of File, helma.File, java.io.File or the
|
||||||
|
* path to the directory as String
|
||||||
|
* @return Object org.apache.lucene.store.RAMDirectory
|
||||||
|
*/
|
||||||
|
helma.Search.prototype.getRAMDirectory = function(dir) {
|
||||||
|
if (dir != null) {
|
||||||
|
var d;
|
||||||
|
if (dir.constructor == String) {
|
||||||
|
d = new java.io.File(dir);
|
||||||
|
} else if (dir.constructor == File || dir.constructor == helma.File) {
|
||||||
|
d = new java.io.File(dir.getAbsolutePath());
|
||||||
|
} else if (!((d = dir) instanceof java.io.File)) {
|
||||||
|
throw("helma.Search.getRAMDirectory(): " + dir + " is not a valid argument.");
|
||||||
|
}
|
||||||
|
if (!d.exists()) {
|
||||||
|
throw("helma.Search.getRAMDirectory(): " + dir + " does not exist.");
|
||||||
|
}
|
||||||
|
return helma.Search.PKG.store.RAMDirectory(d);
|
||||||
|
}
|
||||||
|
return helma.Search.PKG.store.RAMDirectory();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns a new index Object
|
||||||
|
* @param String name of the index
|
||||||
|
* @param Object Analyzer to use (instance of analysis.Analyzer)
|
||||||
|
* @param Object base directory of the index (File object)
|
||||||
|
* @return Object Index object
|
||||||
|
*/
|
||||||
|
helma.Search.prototype.createIndex = function(dir, analyzer) {
|
||||||
|
if (arguments.length == 0) {
|
||||||
|
throw("helma.Search.createIndex(): insufficient arguments.");
|
||||||
|
} else if (arguments.length == 1) {
|
||||||
|
analyzer = helma.Search.getAnalyzer();
|
||||||
|
forceCreate = false;
|
||||||
|
} else if (arguments.length == 2) {
|
||||||
|
if (arguments[1].constructor == Boolean) {
|
||||||
|
analyzer = helma.Search.getAnalyzer();
|
||||||
|
forceCreate = arguments[1];
|
||||||
|
} else {
|
||||||
|
forceCreate = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var index = new helma.Search.Index(dir, analyzer);
|
||||||
|
if (!helma.Search.PKG.index.IndexReader.indexExists(dir)) {
|
||||||
|
index.create();
|
||||||
|
}
|
||||||
|
return index;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////
|
||||||
|
// Index
|
||||||
|
///////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* static constructor for Index objects
|
||||||
|
* @param Object index directory, either an instance of FSDirectory or RAMDirectory
|
||||||
|
* @param Object Lucene analyzer object
|
||||||
|
*/
|
||||||
|
helma.Search.Index = function(directory, analyzer) {
|
||||||
|
/**
|
||||||
|
* returns an IndexWriter object
|
||||||
|
* @param Boolean if true a new index is created
|
||||||
|
*/
|
||||||
|
this.getWriter = function(create) {
|
||||||
|
return new helma.Search.PKG.index.IndexWriter(directory,
|
||||||
|
analyzer, create == true ? true : false);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns an IndexReader object
|
||||||
|
*/
|
||||||
|
this.getReader = function() {
|
||||||
|
return helma.Search.PKG.index.IndexReader.open(directory);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return the directory of the index
|
||||||
|
* @param Object helma.File object representing the index' directory
|
||||||
|
*/
|
||||||
|
this.getDirectory = function() {
|
||||||
|
return directory;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* constructor function for Searcher objects
|
||||||
|
*/
|
||||||
|
this.Searcher = function() {
|
||||||
|
var s = new helma.Search.PKG.search.IndexSearcher(directory);
|
||||||
|
var sortFields;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* wraps a org.lucene.search.Hits collection
|
||||||
|
* @param Object instance of org.lucene.search.Hits
|
||||||
|
*/
|
||||||
|
var HitCollection = function(hits) {
|
||||||
|
/**
|
||||||
|
* silently converts the requested hit into
|
||||||
|
* an instance of helma.Search.Document
|
||||||
|
* @param Int index position of hit in collection
|
||||||
|
* @return instance of helma.Search.Document
|
||||||
|
*/
|
||||||
|
this.get = function(idx) {
|
||||||
|
var doc = new helma.Search.Document(hits.doc(idx));
|
||||||
|
doc.score = hits.score(idx);
|
||||||
|
doc.rank = idx +1;
|
||||||
|
return doc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns the nr. of hits
|
||||||
|
*/
|
||||||
|
this.size = this.length = function() {
|
||||||
|
return (hits != null) ? hits.length() : 0;
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.hits = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* main search method. the resulting hits collection is
|
||||||
|
* stored in the property hits. don't forget to do a close()
|
||||||
|
* when finished processing the resulting hits, otherwise
|
||||||
|
* the index files will stay locked!
|
||||||
|
* @param Object instance of Search.Query
|
||||||
|
* @param Object instance of QueryFilter
|
||||||
|
* @return Int number of hits
|
||||||
|
*/
|
||||||
|
this.search = function(query, filter) {
|
||||||
|
var pkg = helma.Search.PKG.search;
|
||||||
|
var hits;
|
||||||
|
if (sortFields) {
|
||||||
|
var arr = java.lang.reflect.Array.newInstance(pkg.SortField, sortFields.size());
|
||||||
|
var sort = pkg.Sort(sortFields.toArray(arr));
|
||||||
|
if (filter) {
|
||||||
|
hits = s.search(query.getQuery(), filter.getFilter(), sort);
|
||||||
|
} else {
|
||||||
|
hits = s.search(query.getQuery(), sort);
|
||||||
|
}
|
||||||
|
} else if (filter) {
|
||||||
|
hits = s.search(query.getQuery(), filter.getFilter());
|
||||||
|
} else {
|
||||||
|
hits = s.search(query.getQuery());
|
||||||
|
}
|
||||||
|
this.hits = new HitCollection(hits);
|
||||||
|
return this.hits.length();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sets a field as result sorting field
|
||||||
|
*/
|
||||||
|
this.sortBy = function(field) {
|
||||||
|
var pkg = helma.Search.PKG.search;
|
||||||
|
if (!sortFields)
|
||||||
|
sortFields = new java.util.Vector();
|
||||||
|
var f = field;
|
||||||
|
var t = pkg.SortField.AUTO;
|
||||||
|
var r = false;
|
||||||
|
if (arguments.length == 3) {
|
||||||
|
t = pkg.SortField[arguments[1].toUpperCase()];
|
||||||
|
r = arguments[2];
|
||||||
|
} else if (arguments.length == 2) {
|
||||||
|
if (arguments[1].constructor == Boolean) {
|
||||||
|
r = arguments[1];
|
||||||
|
} else {
|
||||||
|
t = pkg.SortField[arguments[1].toUpperCase()];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sortFields.add(new pkg.SortField(f, t, r));
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* closes the wrapped IndexSearcher
|
||||||
|
*/
|
||||||
|
this.close = function() {
|
||||||
|
s.close();
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.toString = function() {
|
||||||
|
return ("[Lucene Index " + directory + "]");
|
||||||
|
};
|
||||||
|
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* check if the index is locked. if true wait a bit
|
||||||
|
* and return it again until the timeout is reached
|
||||||
|
*/
|
||||||
|
helma.Search.Index.prototype.checkWriteLock = function() {
|
||||||
|
var interval = 500;
|
||||||
|
var timeout = 5000;
|
||||||
|
var isLocked = helma.Search.PKG.index.IndexReader.isLocked(this.getDirectory());
|
||||||
|
if (isLocked) {
|
||||||
|
var elapsed = 0;
|
||||||
|
while (elapsed < timeout) {
|
||||||
|
java.lang.Thread.sleep(interval);
|
||||||
|
elapsed += interval;
|
||||||
|
isLocked = helma.Search.PKG.index.IndexReader.isLocked(this.getDirectory());
|
||||||
|
if (!isLocked)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
throw("Timeout while waiting for Index unlock");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* merge indexes into this one
|
||||||
|
*/
|
||||||
|
helma.Search.Index.prototype.addIndexes = function(dirs) {
|
||||||
|
try {
|
||||||
|
var writer = this.getWriter();
|
||||||
|
writer.addIndexes(dirs);
|
||||||
|
} finally {
|
||||||
|
writer.close();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return the analyzer used within this index
|
||||||
|
*/
|
||||||
|
helma.Search.Index.prototype.getAnalyzer = function() {
|
||||||
|
this.checkWriteLock();
|
||||||
|
try {
|
||||||
|
var writer = this.getWriter();
|
||||||
|
return writer.getAnalyzer();
|
||||||
|
} finally {
|
||||||
|
writer.close();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create a new index
|
||||||
|
*/
|
||||||
|
helma.Search.Index.prototype.create = function() {
|
||||||
|
try {
|
||||||
|
var writer = this.getWriter(true);
|
||||||
|
return true;
|
||||||
|
} finally {
|
||||||
|
writer.close();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clear the index by re-creating it
|
||||||
|
*/
|
||||||
|
helma.Search.Index.prototype.clear = function() {
|
||||||
|
this.create();
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return the number of documents in the index
|
||||||
|
*/
|
||||||
|
helma.Search.Index.prototype.size = function() {
|
||||||
|
this.checkWriteLock();
|
||||||
|
try {
|
||||||
|
var writer = this.getWriter();
|
||||||
|
var size = writer.docCount();
|
||||||
|
return size;
|
||||||
|
} finally {
|
||||||
|
writer.close();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* optimize the index
|
||||||
|
*/
|
||||||
|
helma.Search.Index.prototype.optimize = function() {
|
||||||
|
this.checkWriteLock();
|
||||||
|
try {
|
||||||
|
var writer = this.getWriter();
|
||||||
|
writer.optimize();
|
||||||
|
} finally {
|
||||||
|
writer.close();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return an array containing all field Names
|
||||||
|
* indexed in this index
|
||||||
|
* @return Object java Array
|
||||||
|
*/
|
||||||
|
helma.Search.Index.prototype.getFieldNames = function() {
|
||||||
|
try {
|
||||||
|
var reader = this.getReader();
|
||||||
|
var coll = reader.getFieldNames();
|
||||||
|
// FIXME: should return a JS Array, not a Java Array
|
||||||
|
return coll.toArray();
|
||||||
|
} finally {
|
||||||
|
reader.close();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* check if the index is locked
|
||||||
|
* @return Boolean
|
||||||
|
*/
|
||||||
|
helma.Search.Index.prototype.isLocked = function() {
|
||||||
|
try {
|
||||||
|
var reader = this.getReader();
|
||||||
|
return helma.Search.PKG.index.IndexReader.isLocked(reader.directory());
|
||||||
|
} finally {
|
||||||
|
reader.close();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* unlock the index
|
||||||
|
*/
|
||||||
|
helma.Search.Index.prototype.unlock = function() {
|
||||||
|
try {
|
||||||
|
var reader = this.getReader();
|
||||||
|
helma.Search.PKG.index.IndexReader.unlock(reader.directory());
|
||||||
|
return true;
|
||||||
|
} finally {
|
||||||
|
reader.close();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return an Array containing all terms of an index
|
||||||
|
* @param String field name (optional)
|
||||||
|
* @param String field value (optional)
|
||||||
|
* @return Object Array containing terms
|
||||||
|
*/
|
||||||
|
helma.Search.Index.prototype.getTerms = function(field, str) {
|
||||||
|
try {
|
||||||
|
var reader = this.getReader();
|
||||||
|
var arr = [];
|
||||||
|
var e;
|
||||||
|
if (field && str) {
|
||||||
|
e = reader.terms(new helma.Search.PKG.index.Term(field, str));
|
||||||
|
} else {
|
||||||
|
e = reader.terms();
|
||||||
|
}
|
||||||
|
while (e.next()) {
|
||||||
|
arr.push(e.term());
|
||||||
|
}
|
||||||
|
e.close();
|
||||||
|
return arr;
|
||||||
|
} finally {
|
||||||
|
reader.close();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* close the directory of this index to
|
||||||
|
* future operations
|
||||||
|
*/
|
||||||
|
helma.Search.Index.prototype.close = function() {
|
||||||
|
this.checkWriteLock();
|
||||||
|
try {
|
||||||
|
var reader = this.getReader();
|
||||||
|
var dir = reader.directory();
|
||||||
|
dir.close();
|
||||||
|
} finally {
|
||||||
|
reader.close();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* add a document object to the index
|
||||||
|
* @param Object either a single Document object
|
||||||
|
* or a Hashtable/Vector containing numerous
|
||||||
|
* Document objects to add to the index
|
||||||
|
*/
|
||||||
|
helma.Search.Index.prototype.addDocument = function(d) {
|
||||||
|
this.checkWriteLock();
|
||||||
|
try {
|
||||||
|
var writer = this.getWriter();
|
||||||
|
if (d instanceof java.util.Hashtable || d instanceof java.util.Vector) {
|
||||||
|
var e = d.elements();
|
||||||
|
while (e.hasMoreElements())
|
||||||
|
writer.addDocument(e.nextElement().getDocument());
|
||||||
|
} else {
|
||||||
|
writer.addDocument(d.getDocument());
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
writer.close();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* remove those document(s) from the index whose
|
||||||
|
* field-value matches the passed arguments
|
||||||
|
* @param String Name of the field
|
||||||
|
* @param Object either a single string value or a
|
||||||
|
* Hashtable/Vector containing numerous
|
||||||
|
* key values of Documents to remove from index
|
||||||
|
*/
|
||||||
|
helma.Search.Index.prototype.removeDocument = function(fieldName, fieldValue) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* private method that does the actual
|
||||||
|
* removal in the index
|
||||||
|
*/
|
||||||
|
var remove = function(name, value) {
|
||||||
|
return reader["delete"](new helma.Search.PKG.index.Term(name, value));
|
||||||
|
}
|
||||||
|
|
||||||
|
this.checkWriteLock();
|
||||||
|
try {
|
||||||
|
var reader = this.getReader();
|
||||||
|
if (fieldValue instanceof java.util.Hashtable || fieldValue instanceof java.util.Vector) {
|
||||||
|
var result = [];
|
||||||
|
var e = fieldValue.elements();
|
||||||
|
while (e.hasMoreElements())
|
||||||
|
result.push(remove(fieldName, e.nextElement()));
|
||||||
|
return result;
|
||||||
|
} else
|
||||||
|
return remove(fieldName, fieldValue);
|
||||||
|
} finally {
|
||||||
|
reader.close();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
///////////////////////////////////////////
|
||||||
|
// Query constructors
|
||||||
|
///////////////////////////////////////////
|
||||||
|
|
||||||
|
/**
|
||||||
|
* static constructor for Query objects
|
||||||
|
* contains basic methods inherited by other types of Query objects
|
||||||
|
*/
|
||||||
|
helma.Search.QueryBase = function() {
|
||||||
|
this.toString = function(field) {
|
||||||
|
return "[" + this.getQuery().toString(field) + "]";
|
||||||
|
};
|
||||||
|
this.getBoost = function() {
|
||||||
|
return this.getQuery().getBoost();
|
||||||
|
};
|
||||||
|
this.setBoost = function(fact) {
|
||||||
|
this.getQuery().setBoost(fact);
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Term Query constructor
|
||||||
|
* @param String name of the field
|
||||||
|
* @param String query string
|
||||||
|
* @return Object TermQuery object
|
||||||
|
*/
|
||||||
|
helma.Search.TermQuery = function(field, str) {
|
||||||
|
var t = new helma.Search.PKG.index.Term(field, str);
|
||||||
|
var wrappedQuery = new helma.Search.PKG.search.TermQuery(t);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getter for wrapped java object
|
||||||
|
*/
|
||||||
|
this.getQuery = function() {
|
||||||
|
return wrappedQuery;
|
||||||
|
};
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
helma.Search.TermQuery.prototype = new helma.Search.QueryBase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Boolean Query constructor
|
||||||
|
* @param String name of the field
|
||||||
|
* @param String query string
|
||||||
|
* @return Object BooleanQuery object
|
||||||
|
*/
|
||||||
|
helma.Search.BooleanQuery = function(field, str, clause, analyzer) {
|
||||||
|
var wrappedQuery = new helma.Search.PKG.search.BooleanQuery();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getter for wrapped java object
|
||||||
|
*/
|
||||||
|
this.getQuery = function() {
|
||||||
|
return wrappedQuery;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* directly call addTerm if constructor was
|
||||||
|
* called with arguments
|
||||||
|
*/
|
||||||
|
if (field && str) {
|
||||||
|
this.addTerm.apply(this, arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
helma.Search.BooleanQuery.prototype = new helma.Search.QueryBase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* add a term to the wrappedQuery object. this method can be called
|
||||||
|
* with two, three or four arguments, eg.:
|
||||||
|
* addTerm("fieldname", "querystring")
|
||||||
|
* addTerm("fieldname", "querystring", "and")
|
||||||
|
* addTerm("fieldname", "querystring", helma.Search.getAnalyzer("de"))
|
||||||
|
* addTerm("fieldname", "querystring", "not", helma.Search.getAnalyzer("simple"))
|
||||||
|
*
|
||||||
|
* @param Object either a String or an Array containing Strings
|
||||||
|
* that determine the index field(s) to match
|
||||||
|
* @param String string to match
|
||||||
|
* @param String boolean clause ("or"|"not", default is "and")
|
||||||
|
* @param Object instance of analysis.Analyzer
|
||||||
|
*/
|
||||||
|
helma.Search.BooleanQuery.prototype.addTerm = function(field, str, clause, analyzer) {
|
||||||
|
if (arguments.length == 3 && arguments[2] instanceof helma.Search.PKG.analysis.Analyzer) {
|
||||||
|
analyzer = arguments[2];
|
||||||
|
clause = "or";
|
||||||
|
}
|
||||||
|
if (!analyzer)
|
||||||
|
analyzer = helma.Search.getAnalyzer();
|
||||||
|
|
||||||
|
var q;
|
||||||
|
try {
|
||||||
|
if (field instanceof Array)
|
||||||
|
q = helma.Search.PKG.queryParser.MultiFieldQueryParser.parse(str, field, analyzer);
|
||||||
|
else
|
||||||
|
q = helma.Search.PKG.queryParser.QueryParser.parse(str, field, analyzer);
|
||||||
|
} catch (e) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (clause) {
|
||||||
|
case "or":
|
||||||
|
this.getQuery().add(q, false, false);
|
||||||
|
break;
|
||||||
|
case "not":
|
||||||
|
this.getQuery().add(q, false, true);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
this.getQuery().add(q, true, false);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* "merge" a query object with a query object passed as
|
||||||
|
* argument
|
||||||
|
* @param Object Query object
|
||||||
|
* @param String boolean clause ("or"|"not", default is "and")
|
||||||
|
*/
|
||||||
|
helma.Search.BooleanQuery.prototype.addQuery = function(q, clause) {
|
||||||
|
switch (clause) {
|
||||||
|
case "or":
|
||||||
|
this.getQuery().add(q.getQuery(), false, false);
|
||||||
|
break;
|
||||||
|
case "not":
|
||||||
|
this.getQuery().add(q.getQuery(), false, true);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
this.getQuery().add(q.getQuery(), true, false);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Phrase Query constructor
|
||||||
|
* @param String name of the field
|
||||||
|
* @param String query string
|
||||||
|
* @return Object PhraseQuery object
|
||||||
|
*/
|
||||||
|
helma.Search.PhraseQuery = function(field, str) {
|
||||||
|
var wrappedQuery = new helma.Search.PKG.search.PhraseQuery();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* add a term to the end of the phrase query
|
||||||
|
*/
|
||||||
|
this.addTerm = function(field, str) {
|
||||||
|
var t = new helma.Search.PKG.index.Term(field, str);
|
||||||
|
wrappedQuery.add(t);
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getter for wrapped java object
|
||||||
|
*/
|
||||||
|
this.getQuery = function() {
|
||||||
|
return wrappedQuery;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (field && str)
|
||||||
|
this.addTerm(field, str);
|
||||||
|
delete this.base;
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
helma.Search.PhraseQuery.prototype = new helma.Search.QueryBase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Range Query constructor
|
||||||
|
* @param String name of the field
|
||||||
|
* @param String min value (can be null)
|
||||||
|
* @param String max value (can be null)
|
||||||
|
* @param Boolean if true min/max values are included
|
||||||
|
* @return Obj JS wrapper object
|
||||||
|
*/
|
||||||
|
helma.Search.RangeQuery = function(field, from, to, inclusive) {
|
||||||
|
if (!field)
|
||||||
|
throw("Missing field name in RangeQuery()");
|
||||||
|
if (arguments.length < 4)
|
||||||
|
inclusive = true;
|
||||||
|
var t1 = from ? new helma.Search.PKG.index.Term(field, from) : null;
|
||||||
|
var t2 = to ? new helma.Search.PKG.index.Term(field, to) : null;
|
||||||
|
var wrappedQuery = new helma.Search.PKG.search.RangeQuery(t1, t2, inclusive);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getter for wrapped java object
|
||||||
|
*/
|
||||||
|
this.getQuery = function() {
|
||||||
|
return wrappedQuery;
|
||||||
|
};
|
||||||
|
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
helma.Search.RangeQuery.prototype = new helma.Search.QueryBase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fuzzy Query constructor
|
||||||
|
* @param String name of the field
|
||||||
|
* @param String query string
|
||||||
|
* @return Object FuzzyQuery object
|
||||||
|
*/
|
||||||
|
helma.Search.FuzzyQuery = function(field, str) {
|
||||||
|
var t = new helma.Search.PKG.index.Term(field, str);
|
||||||
|
var wrappedQuery = new helma.Search.PKG.search.FuzzyQuery(t);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getter for wrapped java object
|
||||||
|
*/
|
||||||
|
this.getQuery = function() {
|
||||||
|
return wrappedQuery;
|
||||||
|
};
|
||||||
|
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
helma.Search.FuzzyQuery.prototype = new helma.Search.QueryBase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prefix Query constructor
|
||||||
|
* @param String name of the field
|
||||||
|
* @param String query string
|
||||||
|
* @return Object PrefixQuery object
|
||||||
|
*/
|
||||||
|
helma.Search.PrefixQuery = function(field, str) {
|
||||||
|
var t = new helma.Search.PKG.index.Term(field, str);
|
||||||
|
var wrappedQuery = new helma.Search.PKG.search.PrefixQuery(t);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getter for wrapped java object
|
||||||
|
*/
|
||||||
|
this.getQuery = function() {
|
||||||
|
return wrappedQuery;
|
||||||
|
};
|
||||||
|
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
helma.Search.PrefixQuery.prototype = new helma.Search.QueryBase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wildcard Query constructor
|
||||||
|
* @param String name of the field
|
||||||
|
* @param String query string
|
||||||
|
* @return Object WildcardQuery object
|
||||||
|
*/
|
||||||
|
helma.Search.WildcardQuery = function(field, str) {
|
||||||
|
var t = new helma.Search.PKG.index.Term(field, str);
|
||||||
|
var wrappedQuery = new helma.Search.PKG.search.WildcardQuery(t);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getter for wrapped java object
|
||||||
|
*/
|
||||||
|
this.getQuery = function() {
|
||||||
|
return wrappedQuery;
|
||||||
|
};
|
||||||
|
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
helma.Search.WildcardQuery.prototype = new helma.Search.QueryBase;
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////
|
||||||
|
// Document
|
||||||
|
///////////////////////////////////////////
|
||||||
|
|
||||||
|
/**
|
||||||
|
* constructor function for Document objects that wrap
|
||||||
|
* a Lucene Document object
|
||||||
|
* @param Object (optional) Lucene Document object
|
||||||
|
*/
|
||||||
|
helma.Search.Document = function(document) {
|
||||||
|
if (!document)
|
||||||
|
document = new helma.Search.PKG.document.Document();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return the Lucene Document object wrapped
|
||||||
|
* by this javascript Document object
|
||||||
|
*/
|
||||||
|
this.getDocument = function() {
|
||||||
|
return document;
|
||||||
|
};
|
||||||
|
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* adds a field to this document.
|
||||||
|
* @param String Name of the field
|
||||||
|
* @param String Value of the field
|
||||||
|
* @param Object Parameter object (optional) containing
|
||||||
|
* the following properties:
|
||||||
|
* .store (Boolean)
|
||||||
|
* .index (Boolean)
|
||||||
|
* .tokenize (Boolean)
|
||||||
|
*/
|
||||||
|
helma.Search.Document.prototype.addField = function(name, value, param) {
|
||||||
|
if (!param)
|
||||||
|
param = {store: true, index: true, tokenize: true};
|
||||||
|
if (value === null)
|
||||||
|
value = "";
|
||||||
|
// if value is a date convert it
|
||||||
|
if (value instanceof Date)
|
||||||
|
value = helma.Search.PKG.document.DateField.timeToString(value.getTime());
|
||||||
|
var f = new helma.Search.PKG.document.Field(String(name),
|
||||||
|
String(value),
|
||||||
|
param.store,
|
||||||
|
param.index,
|
||||||
|
param.tokenize);
|
||||||
|
this.getDocument().add(f);
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return a single document field
|
||||||
|
* @param String name of the field
|
||||||
|
* @return Object containing the following parameters:
|
||||||
|
* .name (String) name of the Field
|
||||||
|
* .boost (Int) boost factor
|
||||||
|
* .indexed (Boolean) true if Field is indexed, false otherwise
|
||||||
|
* .stored (Boolean) true if Field is stored, false otherwise
|
||||||
|
* .tokenized (Boolean) true if Field is tokenized, false otherwise
|
||||||
|
* .value (String) value of the Field
|
||||||
|
*/
|
||||||
|
helma.Search.Document.prototype.getField = function(name) {
|
||||||
|
var f = this.getDocument().getField(name);
|
||||||
|
if (f != null) {
|
||||||
|
return ({name: name,
|
||||||
|
boost: f.getBoost(),
|
||||||
|
indexed: f.isIndexed(),
|
||||||
|
stored: f.isStored(),
|
||||||
|
tokenized: f.isTokenized(),
|
||||||
|
value: f.stringValue()});
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return a single document field as Date Object
|
||||||
|
* @param String name of the field
|
||||||
|
*/
|
||||||
|
helma.Search.Document.prototype.getDateField = function(name) {
|
||||||
|
var f = this.getDocument().getField(name);
|
||||||
|
if (f != null) {
|
||||||
|
return ({name: name,
|
||||||
|
boost: f.getBoost(),
|
||||||
|
indexed: f.isIndexed(),
|
||||||
|
stored: f.isStored(),
|
||||||
|
tokenized: f.isTokenized(),
|
||||||
|
value: new Date(helma.Search.PKG.document.DateField.stringToTime(f.stringValue()))});
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return the fields of a document
|
||||||
|
*/
|
||||||
|
helma.Search.Document.prototype.getFields = function() {
|
||||||
|
var e = this.getDocument().fields();
|
||||||
|
var result = [];
|
||||||
|
while (e.hasMoreElements()) {
|
||||||
|
result.push(this.getField(e.nextElement().name()));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns the boost factor of a document
|
||||||
|
*/
|
||||||
|
helma.Search.Document.prototype.getBoost = function() {
|
||||||
|
return this.getDocument().getBoost();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sets the boost factor of a document
|
||||||
|
*/
|
||||||
|
helma.Search.Document.prototype.setBoost = function(boost) {
|
||||||
|
this.getDocument().setBoost(boost);
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
helma.Search.Document.prototype.toString = function() {
|
||||||
|
return "[Document Object]";
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////
|
||||||
|
// helma library stuff
|
||||||
|
///////////////////////////////////////////
|
||||||
|
|
||||||
|
helma.lib = "Search";
|
||||||
|
helma.dontEnum(helma.lib);
|
||||||
|
for (var i in helma[helma.lib])
|
||||||
|
helma[helma.lib].dontEnum(i);
|
||||||
|
for (var i in helma[helma.lib].prototype)
|
||||||
|
helma[helma.lib].prototype.dontEnum(i);
|
||||||
|
delete helma.lib;
|
82
helma/Skin.js
Normal file
82
helma/Skin.js
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
/*
|
||||||
|
* Helma License Notice
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Helma License
|
||||||
|
* Version 2.0 (the "License"). You may not use this file except in
|
||||||
|
* compliance with the License. A copy of the License is available at
|
||||||
|
* http://adele.helma.org/download/helma/license.txt
|
||||||
|
*
|
||||||
|
* Copyright 1998-2006 Helma Software. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* $RCSfile: helma.Skin.js,v $
|
||||||
|
* $Author: czv $
|
||||||
|
* $Revision: 1.5 $
|
||||||
|
* $Date: 2006/04/18 13:06:58 $
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
if (!global.helma) {
|
||||||
|
global.helma = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
helma.Skin = function(source, encFlag) {
|
||||||
|
var Base64 = Packages.helma.util.Base64;
|
||||||
|
|
||||||
|
if (!encFlag) {
|
||||||
|
var skin = createSkin(source);
|
||||||
|
} else {
|
||||||
|
var encoded = source;
|
||||||
|
source = new java.lang.String(source);
|
||||||
|
var bytes = Base64.decode(source.toCharArray());
|
||||||
|
var skin = createSkin(new java.lang.String(bytes, "UTF-8"));
|
||||||
|
}
|
||||||
|
|
||||||
|
this.toString = function() {
|
||||||
|
return source;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.valueOf = function() {
|
||||||
|
if (encFlag)
|
||||||
|
return encoded;
|
||||||
|
var bytes = new java.lang.String(source).getBytes("UTF-8");
|
||||||
|
return new java.lang.String(Base64.encode(bytes));
|
||||||
|
};
|
||||||
|
|
||||||
|
this.render = function(param) {
|
||||||
|
return renderSkin(skin, param);
|
||||||
|
};
|
||||||
|
|
||||||
|
this.renderAsString = function(param) {
|
||||||
|
return renderSkinAsString(skin, param);
|
||||||
|
};
|
||||||
|
|
||||||
|
this.containsMacro = function(name, handler) {
|
||||||
|
res.push();
|
||||||
|
res.write("<% *");
|
||||||
|
if (handler) {
|
||||||
|
res.write(handler);
|
||||||
|
res.write(".");
|
||||||
|
}
|
||||||
|
res.write(name);
|
||||||
|
res.write(" *%>");
|
||||||
|
var re = new RegExp(res.pop(), "g");
|
||||||
|
return re.test(source);
|
||||||
|
};
|
||||||
|
|
||||||
|
for (var i in this)
|
||||||
|
this.dontEnum(i);
|
||||||
|
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
helma.Skin.BASE64 = true;
|
||||||
|
|
||||||
|
|
||||||
|
helma.lib = "Skin";
|
||||||
|
helma.dontEnum(helma.lib);
|
||||||
|
for (var i in helma[helma.lib])
|
||||||
|
helma[helma.lib].dontEnum(i);
|
||||||
|
for (var i in helma[helma.lib].prototype)
|
||||||
|
helma[helma.lib].prototype.dontEnum(i);
|
||||||
|
delete helma.lib;
|
331
helma/Ssh.js
Normal file
331
helma/Ssh.js
Normal file
|
@ -0,0 +1,331 @@
|
||||||
|
/*
|
||||||
|
* Helma License Notice
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Helma License
|
||||||
|
* Version 2.0 (the "License"). You may not use this file except in
|
||||||
|
* compliance with the License. A copy of the License is available at
|
||||||
|
* http://adele.helma.org/download/helma/license.txt
|
||||||
|
*
|
||||||
|
* Copyright 1998-2006 Helma Software. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* $RCSfile: helma.Ssh.js,v $
|
||||||
|
* $Author: czv $
|
||||||
|
* $Revision: 1.4 $
|
||||||
|
* $Date: 2006/04/18 13:06:58 $
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
// take care of any dependencies
|
||||||
|
app.addRepository('modules/helma/File.js');
|
||||||
|
app.addRepository('modules/helma/ganymed-ssh2.jar');
|
||||||
|
|
||||||
|
|
||||||
|
if (!global.helma) {
|
||||||
|
global.helma = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* constructor
|
||||||
|
*/
|
||||||
|
helma.Ssh = function(server, hosts) {
|
||||||
|
var SSHPKG = Packages.ch.ethz.ssh2;
|
||||||
|
var SSHPKGNAME = "ganymed-ssh2.jar";
|
||||||
|
var SSHPKGURL = "http://www.ganymed.ethz.ch/ssh2";
|
||||||
|
var className = "helma.Ssh";
|
||||||
|
var paranoid = false;
|
||||||
|
var verifier = null;
|
||||||
|
var knownHosts, connection;
|
||||||
|
|
||||||
|
try {
|
||||||
|
knownHosts = new SSHPKG.KnownHosts();
|
||||||
|
connection = new SSHPKG.Connection(server);
|
||||||
|
} catch (e) {
|
||||||
|
if (e instanceof TypeError == false)
|
||||||
|
throw(e);
|
||||||
|
throw("helma.Ssh needs " + SSHPKGNAME +
|
||||||
|
" in lib/ext or application directory " +
|
||||||
|
"[" + SSHPKGURL + "]");
|
||||||
|
}
|
||||||
|
|
||||||
|
var SimpleVerifier = {
|
||||||
|
verifyServerHostKey: function(hostname, port, serverHostKeyAlgorithm, serverHostKey) {
|
||||||
|
var result = knownHosts.verifyHostkey(hostname, serverHostKeyAlgorithm, serverHostKey);
|
||||||
|
switch (result) {
|
||||||
|
case SSHPKG.KnownHosts.HOSTKEY_IS_OK:
|
||||||
|
debug("verifyServerHostKey", "received known host key, proceeding");
|
||||||
|
return true;
|
||||||
|
case SSHPKG.KnownHosts.HOSTKEY_IS_NEW:
|
||||||
|
if (paranoid == true) {
|
||||||
|
debug("verifyServerHostKey", "received unknown host key, rejecting");
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
debug("verifyServerHostKey", "received new host key, adding temporarily to known hosts");
|
||||||
|
var hn = java.lang.reflect.Array.newInstance(java.lang.String, 1);
|
||||||
|
hn[0] = hostname;
|
||||||
|
knownHosts.addHostkey(hn, serverHostKeyAlgorithm, serverHostKey);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
case SSHPKG.KnownHosts.HOSTKEY_HAS_CHANGED:
|
||||||
|
debug("verifyServerHostKey", "WARNING: host key has changed, rejecting");
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* private method for creating an instance of
|
||||||
|
* java.io.File based on various argument types
|
||||||
|
* @param a String or an instance of helma.File or java.io.File
|
||||||
|
*/
|
||||||
|
var getFile = function(arg) {
|
||||||
|
if (arg instanceof helma.File) {
|
||||||
|
return new java.io.File(arg.getAbsolutePath());
|
||||||
|
} else if (arg instanceof java.io.File) {
|
||||||
|
return arg;
|
||||||
|
} else if (arg.constructor == String) {
|
||||||
|
return new java.io.File(arg);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* private method that connects to the remote server
|
||||||
|
* @return Boolean
|
||||||
|
*/
|
||||||
|
var connect = function() {
|
||||||
|
try {
|
||||||
|
var info = connection.connect(verifier);
|
||||||
|
debug("connect", "connected to server " + server);
|
||||||
|
return true;
|
||||||
|
} catch (e) {
|
||||||
|
error("connect", "connection to " + server + " failed.");
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* debug output method
|
||||||
|
* @param String name of method
|
||||||
|
* @param String debug message
|
||||||
|
*/
|
||||||
|
var debug = function(methodName, msg) {
|
||||||
|
var msg = msg ? " " + msg : "";
|
||||||
|
app.debug(className + ":" + methodName + msg);
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* error output method
|
||||||
|
* @param String name of method
|
||||||
|
* @param String error message
|
||||||
|
*/
|
||||||
|
var error = function(methodName, msg) {
|
||||||
|
var tx = java.lang.Thread.currentThread();
|
||||||
|
tx.dumpStack();
|
||||||
|
app.log("Error in " + className + ":" + methodName + ": " + msg);
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* reads a known hosts file
|
||||||
|
* @param Object String or instance of helma.File or java.io.File
|
||||||
|
*/
|
||||||
|
this.addKnownHosts = function(file) {
|
||||||
|
try {
|
||||||
|
knownHosts.addHostkeys(getFile(file));
|
||||||
|
verifier = new SSHPKG.ServerHostKeyVerifier(SimpleVerifier);
|
||||||
|
return true;
|
||||||
|
} catch (e) {
|
||||||
|
error("addKnownHosts", "Missing or invalid known hosts file '" + file + "'");
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* connects to a remote host with username/password authentication
|
||||||
|
* @param String username
|
||||||
|
* @param String password
|
||||||
|
* @return Boolean
|
||||||
|
*/
|
||||||
|
this.connect = function(username, password) {
|
||||||
|
if (!username || !password) {
|
||||||
|
error("connect", "Insufficient arguments.");
|
||||||
|
} else if (connect() && connection.authenticateWithPassword(username, password)) {
|
||||||
|
debug("connect", "authenticated using password");
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
error("connect", "Authentication failed!");
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* connects to a remote host using private key and passphrase
|
||||||
|
* @param String username
|
||||||
|
* @param String path to keyfile
|
||||||
|
* @param String passphrase (if needed by key)
|
||||||
|
* @return Boolean
|
||||||
|
*/
|
||||||
|
this.connectWithKey = function(username, key, passphrase) {
|
||||||
|
var keyFile;
|
||||||
|
if (!username || !(keyFile = getFile(key))) {
|
||||||
|
error("connectWithKey", "Insufficient or wrong arguments.");
|
||||||
|
} else if (connect() && connection.authenticateWithPublicKey(username, keyFile, passphrase)) {
|
||||||
|
debug("connectWithKey", "authenticated with key");
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
error("connectWithKey", "Authentication failed!");
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* disconnect a session
|
||||||
|
*/
|
||||||
|
this.disconnect = function() {
|
||||||
|
connection.close();
|
||||||
|
debug("disconnect", "disconnected from server " + server);
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns true if the ssh client is connected
|
||||||
|
* @return Boolean
|
||||||
|
*/
|
||||||
|
this.isConnected = function() {
|
||||||
|
return (connection != null && connection.isAuthenticationComplete());
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* copies a file to the remote server
|
||||||
|
* @param String path to local file that should be copied
|
||||||
|
* to remote server. If the argument is a
|
||||||
|
* String Array, all files specified in the
|
||||||
|
* Array are copied to the server
|
||||||
|
* @param String path to remote destination directory
|
||||||
|
* @param String (optional) 4-digit permission mode string (eg. "0755");
|
||||||
|
* @return Boolean
|
||||||
|
*/
|
||||||
|
this.put = function(localFile, remoteDir, mode) {
|
||||||
|
if (!localFile || !remoteDir) {
|
||||||
|
error("put", "Insufficient arguments.");
|
||||||
|
} else if (!this.isConnected()) {
|
||||||
|
error("put", "Not connected. Please establish a connection first.");
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
var scp = connection.createSCPClient();
|
||||||
|
if (mode != null)
|
||||||
|
scp.put(localFile, remoteDir, mode);
|
||||||
|
else
|
||||||
|
scp.put(localFile, remoteDir);
|
||||||
|
debug("put", "copied '" + localFile + "' to '" + remoteDir + "'");
|
||||||
|
return true;
|
||||||
|
} catch (e) {
|
||||||
|
error("put", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* copies a file from the remote server.
|
||||||
|
* @param String path to remote file that should be copied
|
||||||
|
* to remote server. If the argument is a
|
||||||
|
* String Array, all files specified in the
|
||||||
|
* Array are copied from the remote server
|
||||||
|
* @param String path to local destination directory
|
||||||
|
* @return Boolean
|
||||||
|
*/
|
||||||
|
this.get = function(remoteFile, targetDir) {
|
||||||
|
if (!remoteFile || !targetDir) {
|
||||||
|
error("get", "Insufficient arguments.");
|
||||||
|
} else if (!this.isConnected()) {
|
||||||
|
error("get", "Not connected. Please establish a connection first.");
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
var scp = connection.createSCPClient();
|
||||||
|
scp.get(remoteFile, targetDir);
|
||||||
|
debug("get", "copied '" + remoteFile + "' to '" + targetDir + "'");
|
||||||
|
return true;
|
||||||
|
} catch (e) {
|
||||||
|
error("get", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* executes a command on the remote server
|
||||||
|
* (scp must be in PATH on the remote server)
|
||||||
|
* @param String the command to execute
|
||||||
|
* @return String result of the command
|
||||||
|
*/
|
||||||
|
this.execCommand = function(cmd) {
|
||||||
|
if (!this.isConnected()) {
|
||||||
|
error("execCommand", "Not connected. Please establish a connection first.");
|
||||||
|
} else {
|
||||||
|
var session = connection.openSession();
|
||||||
|
try {
|
||||||
|
session.execCommand(cmd);
|
||||||
|
var stdout = new SSHPKG.StreamGobbler(session.getStdout());
|
||||||
|
var br = new java.io.BufferedReader(new java.io.InputStreamReader(stdout));
|
||||||
|
res.push();
|
||||||
|
while (true) {
|
||||||
|
if (!(line = br.readLine()))
|
||||||
|
break;
|
||||||
|
res.writeln(line);
|
||||||
|
}
|
||||||
|
debug("execCommand", "executed command '" + cmd + "'");
|
||||||
|
return res.pop();
|
||||||
|
} catch (e) {
|
||||||
|
error("execCommand", e);
|
||||||
|
} finally {
|
||||||
|
session.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* toggle paranoia mode
|
||||||
|
* @param Boolean
|
||||||
|
*/
|
||||||
|
this.setParanoid = function(p) {
|
||||||
|
paranoid = (p == true) ? true : false;
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns true if in paranoid mode
|
||||||
|
* @return Boolean
|
||||||
|
*/
|
||||||
|
this.isParanoid = function() {
|
||||||
|
return paranoid;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* main constructor body
|
||||||
|
*/
|
||||||
|
if (hosts) {
|
||||||
|
this.addKnownHosts(hosts);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i in this)
|
||||||
|
this.dontEnum(i);
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
helma.Ssh.toString = function() {
|
||||||
|
return "[helma.Ssh]";
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
helma.lib = "Ssh";
|
||||||
|
helma.dontEnum(helma.lib);
|
||||||
|
for (var i in helma[helma.lib])
|
||||||
|
helma[helma.lib].dontEnum(i);
|
||||||
|
for (var i in helma[helma.lib].prototype)
|
||||||
|
helma[helma.lib].prototype.dontEnum(i);
|
||||||
|
delete helma.lib;
|
78
helma/Url.js
Normal file
78
helma/Url.js
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
/*
|
||||||
|
* Helma License Notice
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Helma License
|
||||||
|
* Version 2.0 (the "License"). You may not use this file except in
|
||||||
|
* compliance with the License. A copy of the License is available at
|
||||||
|
* http://adele.helma.org/download/helma/license.txt
|
||||||
|
*
|
||||||
|
* Copyright 1998-2006 Helma Software. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* $RCSfile: helma.Url.js,v $
|
||||||
|
* $Author: czv $
|
||||||
|
* $Revision: 1.4 $
|
||||||
|
* $Date: 2006/04/18 13:06:58 $
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
if (!global.helma) {
|
||||||
|
global.helma = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
helma.Url = function(str) {
|
||||||
|
if (!str || !helma.Url.PATTERN.test(str))
|
||||||
|
throw Error("Cannot create helma.Url: insufficient arguments");
|
||||||
|
|
||||||
|
// filter punctuation from user-generated urls
|
||||||
|
// FIXME: a) can this be done in helma.Url.PATTERN?
|
||||||
|
// b) should it be done rather in methods like activateUrls?
|
||||||
|
str = str.replace(/[,.;:]\s/, "");
|
||||||
|
|
||||||
|
var parts = helma.Url.PATTERN.exec(str);
|
||||||
|
this.protocol = parts[1];
|
||||||
|
|
||||||
|
if (!parts[2]) {
|
||||||
|
if (parts[3])
|
||||||
|
this.user = parts[3];
|
||||||
|
} else {
|
||||||
|
this.user = parts[2];
|
||||||
|
if (parts[3])
|
||||||
|
this.password = parts[3];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!parts[4])
|
||||||
|
throw Error("Cannot create helma.Url: missing host part");
|
||||||
|
|
||||||
|
this.domainName = parts[4]; // actually, the fully-qualified domain name
|
||||||
|
var fqdnParts = this.domainName.split(".");
|
||||||
|
if (fqdnParts.length < 3)
|
||||||
|
this.host = "";
|
||||||
|
else {
|
||||||
|
this.host = fqdnParts[0];
|
||||||
|
fqdnParts.splice(0, 1);
|
||||||
|
}
|
||||||
|
this.topLevelDomain = fqdnParts[fqdnParts.length-1];
|
||||||
|
this.domain = fqdnParts.join(".");
|
||||||
|
|
||||||
|
this.pathString = parts[5] || "";
|
||||||
|
if (this.pathString.indexOf("/") == 0)
|
||||||
|
this.pathString = this.pathString.substring(1);
|
||||||
|
this.path = this.pathString.split("/");
|
||||||
|
this.file = this.path.pop();
|
||||||
|
|
||||||
|
if (parts[6]) {
|
||||||
|
this.queryString = parts[6];
|
||||||
|
var pairs;
|
||||||
|
this.query = {};
|
||||||
|
parts = parts[6].split("&");
|
||||||
|
for (var i in parts) {
|
||||||
|
pairs = parts[i].split("=");
|
||||||
|
this.query[pairs[0]] = pairs[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
helma.Url.PATTERN = /^([^:]*):\/\/+(?:([^\/]*):)?(?:([^\/]*)@)?([\w\-_.]*[^.])(\/[^?]*)?(?:\?(.*))?$/;
|
411
helma/Zip.js
Normal file
411
helma/Zip.js
Normal file
|
@ -0,0 +1,411 @@
|
||||||
|
/*
|
||||||
|
* Helma License Notice
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Helma License
|
||||||
|
* Version 2.0 (the "License"). You may not use this file except in
|
||||||
|
* compliance with the License. A copy of the License is available at
|
||||||
|
* http://adele.helma.org/download/helma/license.txt
|
||||||
|
*
|
||||||
|
* Copyright 1998-2006 Helma Software. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* $RCSfile: helma.Zip.js,v $
|
||||||
|
* $Author: czv $
|
||||||
|
* $Revision: 1.6 $
|
||||||
|
* $Date: 2006/04/18 13:06:58 $
|
||||||
|
*/
|
||||||
|
|
||||||
|
// take care of any dependencies
|
||||||
|
app.addRepository('modules/helma/File.js');
|
||||||
|
|
||||||
|
|
||||||
|
if (!global.helma) {
|
||||||
|
global.helma = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* constructor function for Zip Objects
|
||||||
|
* @param either
|
||||||
|
* - (Object) a File object
|
||||||
|
* - (Object) an instance of Helma.File
|
||||||
|
* - (Object) an instance of java.io.File
|
||||||
|
* - (String) the path to the zip file
|
||||||
|
*/
|
||||||
|
helma.Zip = function (file) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* private function that extracts the data of a file
|
||||||
|
* in a .zip archive. If a destination Path is given it
|
||||||
|
* writes the extracted data directly to disk using the
|
||||||
|
* name of the ZipEntry Object, otherwise it returns the
|
||||||
|
* byte array containing the extracted data
|
||||||
|
* @param Object jAva.util.zip.ZipFile Object
|
||||||
|
* @param Object java.util.zip.ZipEntry Object to extract
|
||||||
|
* @param String destination path to extract ZipEntry Object to
|
||||||
|
* @return Object ByteArray containing the data of the ZipEntry
|
||||||
|
*/
|
||||||
|
var extractEntry = function(zFile, entry, destPath) {
|
||||||
|
var size = entry.getSize();
|
||||||
|
if (entry.isDirectory() || size <= 0)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
var zInStream = new java.io.BufferedInputStream(zFile.getInputStream(entry));
|
||||||
|
var buf = new java.lang.reflect.Array.newInstance(java.lang.Byte.TYPE, size);
|
||||||
|
zInStream.read(buf, 0, size);
|
||||||
|
zInStream.close();
|
||||||
|
|
||||||
|
if (!destPath) {
|
||||||
|
// no filesystem destination given, so return
|
||||||
|
// the byte array containing the extracted data
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
// extract the file to the given path
|
||||||
|
var dest = new java.io.File(destPath, entry.getName());
|
||||||
|
if (entry.isDirectory())
|
||||||
|
dest.mkdirs();
|
||||||
|
else if (buf) {
|
||||||
|
if (!dest.getParentFile().exists())
|
||||||
|
dest.getParentFile().mkdirs();
|
||||||
|
try {
|
||||||
|
var outStream = new java.io.BufferedOutputStream(new java.io.FileOutputStream(dest));
|
||||||
|
outStream.write(buf, 0, size);
|
||||||
|
} finally {
|
||||||
|
outStream.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* private function for adding a single file to the .zip archive
|
||||||
|
* @param Object java.util.zip.ZipOutputStream
|
||||||
|
* @param Object instance of java.io.File representing the file to be added
|
||||||
|
* @param Int compression-level (0-9)
|
||||||
|
* @param String path of the directory in the archive to which the
|
||||||
|
* file should be added (optional)
|
||||||
|
*/
|
||||||
|
var addFile = function(zOutStream, f, level, pathPrefix) {
|
||||||
|
var fInStream = new java.io.BufferedInputStream(new java.io.FileInputStream(f), f.length());
|
||||||
|
buf = new java.lang.reflect.Array.newInstance(java.lang.Byte.TYPE, f.length());
|
||||||
|
fInStream.read(buf, 0, f.length());
|
||||||
|
|
||||||
|
var name = new java.lang.StringBuffer();
|
||||||
|
if (pathPrefix) {
|
||||||
|
// append clean pathPrefix to name buffer
|
||||||
|
var st = new java.util.StringTokenizer(pathPrefix, "\\/");
|
||||||
|
while (st.hasMoreTokens()) {
|
||||||
|
name.append(st.nextToken());
|
||||||
|
name.append("/");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
name.append(f.getName());
|
||||||
|
var entry = new java.util.zip.ZipEntry(name.toString());
|
||||||
|
entry.setSize(f.length());
|
||||||
|
entry.setTime(f.lastModified());
|
||||||
|
zOutStream.setLevel(level);
|
||||||
|
zOutStream.putNextEntry(entry);
|
||||||
|
zOutStream.write(buf, 0, buf.length);
|
||||||
|
zOutStream.closeEntry();
|
||||||
|
fInStream.close();
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* private function that constructs an instance
|
||||||
|
* of java.io.File based on a JS File or Helma.File object
|
||||||
|
* @param Object either a string or an instance of java.io.File, File or Helma.File
|
||||||
|
* @return Object instance of java.io.File
|
||||||
|
*/
|
||||||
|
var evalFile = function(f) {
|
||||||
|
if (f instanceof java.io.File)
|
||||||
|
return f;
|
||||||
|
var result;
|
||||||
|
if (typeof f == "string")
|
||||||
|
result = new java.io.File(f);
|
||||||
|
else
|
||||||
|
result = new java.io.File(f.getAbsolutePath());
|
||||||
|
if (!result.exists())
|
||||||
|
throw("Error creating Zip Object: File '" + f + "' doesn't exist.");
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns an array containing the entries of a .zip file as objects
|
||||||
|
* (see Entry for description)
|
||||||
|
* @param Object File object representing the .zip file on disk
|
||||||
|
* @return Object result object
|
||||||
|
*/
|
||||||
|
this.list = function() {
|
||||||
|
var result = new helma.Zip.Content();
|
||||||
|
var zFile = new java.util.zip.ZipFile(file);
|
||||||
|
var entries = zFile.entries();
|
||||||
|
while (entries.hasMoreElements())
|
||||||
|
result.add(new helma.Zip.Entry(entries.nextElement()));
|
||||||
|
zFile.close();
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* extracts a single file from a .zip archive
|
||||||
|
* if a destination path is given it directly writes
|
||||||
|
* the extracted file to disk
|
||||||
|
* @param Object File object representing the .zip file on disk
|
||||||
|
* @param String Name of the file to extract
|
||||||
|
* @param String (optional) destination path to write file to
|
||||||
|
* @return Object JS Object (see Entry for description)
|
||||||
|
*/
|
||||||
|
this.extract = function(name, destPath) {
|
||||||
|
var zFile = new java.util.zip.ZipFile(file);
|
||||||
|
var entry = zFile.getEntry(name);
|
||||||
|
if (!entry)
|
||||||
|
return null;
|
||||||
|
var result = new helma.Zip.Entry(entry);
|
||||||
|
result.data = extractEntry(zFile, entry, destPath);
|
||||||
|
zFile.close();
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* extracts all files in a .zip archive
|
||||||
|
* if a destination path is given it directly writes
|
||||||
|
* the extracted files to disk (preserves directory structure
|
||||||
|
* of .zip archive if existing!)
|
||||||
|
* @param String (optional) destination path to write file to
|
||||||
|
* @return Object Array containing JS objects for each entry
|
||||||
|
* (see Entry for description)
|
||||||
|
*/
|
||||||
|
this.extractAll = function(destPath) {
|
||||||
|
var result = new helma.Zip.Content();
|
||||||
|
var zFile = new java.util.zip.ZipFile(file);
|
||||||
|
var entries = zFile.entries();
|
||||||
|
while (entries.hasMoreElements()) {
|
||||||
|
var entry = entries.nextElement();
|
||||||
|
var e = new helma.Zip.Entry(entry);
|
||||||
|
e.data = extractEntry(zFile, entry, destPath);
|
||||||
|
result.add(e);
|
||||||
|
}
|
||||||
|
zFile.close();
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* adds a single file or a whole directory (recursive!) to the .zip archive
|
||||||
|
* @param either
|
||||||
|
* - (Object) a File object
|
||||||
|
* - (Object) an instance of java.io.File
|
||||||
|
* - (String) the path to the file that should be added
|
||||||
|
* @param Int Level to use for compression (default: 9 = best compression)
|
||||||
|
* @param String name of the directory in the archive into which the
|
||||||
|
* file should be added (optional)
|
||||||
|
* @return Boolean true
|
||||||
|
*/
|
||||||
|
this.add = function (f, level, pathPrefix) {
|
||||||
|
var f = evalFile(f);
|
||||||
|
|
||||||
|
// evaluate arguments
|
||||||
|
if (arguments.length == 2) {
|
||||||
|
if (typeof arguments[1] == "string") {
|
||||||
|
pathPrefix = arguments[1];
|
||||||
|
level = 9;
|
||||||
|
} else {
|
||||||
|
level = parseInt(arguments[1], 10);
|
||||||
|
pathPrefix = null;
|
||||||
|
}
|
||||||
|
} else if (level == null || isNaN(level)) {
|
||||||
|
level = 9;
|
||||||
|
}
|
||||||
|
// only levels between 0 and 9 are allowed
|
||||||
|
level = Math.max(0, Math.min(9, arguments[1]));
|
||||||
|
|
||||||
|
if (f.isDirectory()) {
|
||||||
|
// add a whole directory to the zip file (recursive!)
|
||||||
|
var files = (new helma.File(f.getAbsolutePath())).listRecursive();
|
||||||
|
for (var i in files) {
|
||||||
|
var fAdd = new java.io.File(files[i]);
|
||||||
|
if (!fAdd.isDirectory()) {
|
||||||
|
var p = fAdd.getPath().substring(f.getAbsolutePath().length, fAdd.getParent().length);
|
||||||
|
if (pathPrefix)
|
||||||
|
p = pathPrefix + p;
|
||||||
|
addFile(zOutStream, fAdd, level, p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
addFile(zOutStream, f, level, pathPrefix);
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* adds a new entry to the zip file
|
||||||
|
* @param Object byte[] containing the data to add
|
||||||
|
* @param String name of the file to add
|
||||||
|
* @param Int compression level (0-9, default: 9)
|
||||||
|
* @return Boolean true
|
||||||
|
*/
|
||||||
|
this.addData = function(buf, name, level) {
|
||||||
|
var entry = new java.util.zip.ZipEntry(name);
|
||||||
|
entry.setSize(buf.length);
|
||||||
|
entry.setTime(new Date());
|
||||||
|
if (level == null || isNaN(level))
|
||||||
|
zOutStream.setLevel(9);
|
||||||
|
else
|
||||||
|
zOutStream.setLevel(Math.max(0, Math.min(9, parseInt(level, 10))));
|
||||||
|
zOutStream.putNextEntry(entry);
|
||||||
|
zOutStream.write(buf, 0, buf.length);
|
||||||
|
zOutStream.closeEntry();
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* closes the ZipOutputStream
|
||||||
|
*/
|
||||||
|
this.close = function() {
|
||||||
|
zOutStream.close();
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns the binary data of the zip file
|
||||||
|
* @return Object ByteArray containing the binary data of the zip file
|
||||||
|
*/
|
||||||
|
this.getData = function() {
|
||||||
|
return bOutStream.toByteArray();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* saves the archive by closing the output stream
|
||||||
|
* @param String path (including the name) to save the zip file to
|
||||||
|
* @return Boolean true
|
||||||
|
*/
|
||||||
|
this.save = function(dest) {
|
||||||
|
if (!dest)
|
||||||
|
throw new Error("no destination for ZipFile given");
|
||||||
|
// first of all, close the ZipOutputStream
|
||||||
|
zOutStream.close();
|
||||||
|
var destFile = new java.io.File(dest);
|
||||||
|
try {
|
||||||
|
var outStream = new java.io.FileOutputStream(destFile);
|
||||||
|
bOutStream.writeTo(outStream);
|
||||||
|
} finally {
|
||||||
|
outStream.close();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.toString = function() {
|
||||||
|
if (file)
|
||||||
|
return "[Zip Object " + file.getAbsolutePath() + "]";
|
||||||
|
else
|
||||||
|
return "[Zip Object]";
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* constructor body
|
||||||
|
*/
|
||||||
|
var bOutStream = new java.io.ByteArrayOutputStream();
|
||||||
|
var zOutStream = new java.util.zip.ZipOutputStream(bOutStream);
|
||||||
|
if (file) {
|
||||||
|
file = evalFile(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i in this)
|
||||||
|
this.dontEnum(i);
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* constructor for Content Objects
|
||||||
|
*/
|
||||||
|
helma.Zip.Content = function() {
|
||||||
|
this.toc = [];
|
||||||
|
this.files = {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* adds a Zip Entry object to the table of contents
|
||||||
|
* and the files collection
|
||||||
|
* @param Object instance of helma.Zip.Entry
|
||||||
|
*/
|
||||||
|
this.add = function(entry) {
|
||||||
|
// add the file to the table of contents array
|
||||||
|
this.toc.push(entry);
|
||||||
|
// plus add it to the files tree
|
||||||
|
var re = /[\\\/]/;
|
||||||
|
var arr = entry.name.split(re);
|
||||||
|
var cnt = 0;
|
||||||
|
var curr = this.files;
|
||||||
|
var propName;
|
||||||
|
while (cnt < arr.length-1) {
|
||||||
|
propName = arr[cnt++];
|
||||||
|
if (!curr[propName])
|
||||||
|
curr[propName] = new Object();
|
||||||
|
curr = curr[propName];
|
||||||
|
}
|
||||||
|
curr[arr[cnt]] = entry;
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
for (var i in this)
|
||||||
|
this.dontEnum(i);
|
||||||
|
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* constructor for Entry objects holding the meta-data of a zip entry:
|
||||||
|
* .name (String) name of the entry
|
||||||
|
* .size (Int) decompressed size of the entry in bytes
|
||||||
|
* .time (Date) last modification timestamp of the entry or null
|
||||||
|
* .isDirectory (Boolean) true in case entry is a directory, false otherwise
|
||||||
|
* .data (ByteArray) ByteArray containing the data of the entry
|
||||||
|
* @param Object java.util.zip.ZipEntry Object
|
||||||
|
*/
|
||||||
|
helma.Zip.Entry = function(entry) {
|
||||||
|
this.name = entry.getName();
|
||||||
|
this.size = entry.getSize();
|
||||||
|
this.time = entry.getTime() ? new Date(entry.getTime()) : null;
|
||||||
|
this.isDirectory = entry.isDirectory();
|
||||||
|
this.data = null;
|
||||||
|
for (var i in this)
|
||||||
|
this.dontEnum(i);
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* extract all files in a ByteArray passed as argument
|
||||||
|
* and return them as result Array
|
||||||
|
* @param Object ByteArray containing the data of the .zip File
|
||||||
|
* @return Object instance of helma.Zip.Content
|
||||||
|
*/
|
||||||
|
helma.Zip.extractData = function(zipData) {
|
||||||
|
var zInStream = new java.util.zip.ZipInputStream(new java.io.ByteArrayInputStream(zipData));
|
||||||
|
var result = new helma.Zip.Content();
|
||||||
|
|
||||||
|
var entry;
|
||||||
|
while ((entry = zInStream.getNextEntry()) != null) {
|
||||||
|
var eParam = new helma.Zip.Entry(entry);
|
||||||
|
if (eParam.isDirectory)
|
||||||
|
continue;
|
||||||
|
if (eParam.size == -1)
|
||||||
|
eParam.size = 16384;
|
||||||
|
var bos = new java.io.ByteArrayOutputStream(eParam.size);
|
||||||
|
var buf = java.lang.reflect.Array.newInstance(java.lang.Byte.TYPE, 8192);
|
||||||
|
var count;
|
||||||
|
while ((count = zInStream.read(buf)) != -1)
|
||||||
|
bos.write(buf, 0, count);
|
||||||
|
eParam.data = bos.toByteArray();
|
||||||
|
eParam.size = bos.size();
|
||||||
|
result.add(eParam);
|
||||||
|
}
|
||||||
|
zInStream.close();
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
helma.lib = "Zip";
|
||||||
|
helma.dontEnum(helma.lib);
|
||||||
|
for (var i in helma[helma.lib])
|
||||||
|
helma[helma.lib].dontEnum(i);
|
||||||
|
for (var i in helma[helma.lib].prototype)
|
||||||
|
helma[helma.lib].prototype.dontEnum(i);
|
||||||
|
delete helma.lib;
|
BIN
helma/ganymed-ssh2.jar
Normal file
BIN
helma/ganymed-ssh2.jar
Normal file
Binary file not shown.
BIN
helma/jxl.jar
Normal file
BIN
helma/jxl.jar
Normal file
Binary file not shown.
BIN
helma/lucene.jar
Normal file
BIN
helma/lucene.jar
Normal file
Binary file not shown.
Loading…
Add table
Reference in a new issue