Merge branch 'helma-js' into helma-🐜

This commit is contained in:
Tobi Schäfer 2020-03-21 15:46:12 +01:00
commit 768b7b5ed3
72 changed files with 901 additions and 922 deletions

15
.eslintrc Normal file
View file

@ -0,0 +1,15 @@
{
"extends": "eslint:recommended",
"env": {
"es6": true,
"commonjs": true
},
"globals": {
"app": "readonly",
"HopObject": "readonly",
"java": "readonly",
"Packages": "readonly",
"req": "readonly",
"res": "readonly"
}
}

View file

@ -46,11 +46,12 @@ configurations {
}
dependencies {
implementation 'com.google.code.gson:gson:2.8.6'
implementation 'com.sun.activation:javax.activation:1.2.0'
implementation 'commons-codec:commons-codec:1.14'
implementation 'commons-fileupload:commons-fileupload:1.4'
implementation 'commons-logging:commons-logging:1.2'
implementation 'commons-net:commons-net:3.6'
implementation 'com.sun.activation:javax.activation:1.2.0'
implementation 'javax.mail:javax.mail-api:1.6.2'
implementation 'javax.servlet:javax.servlet-api:4.0.1'
implementation 'org.ccil.cowan.tagsoup:tagsoup:1.2.1'

View file

@ -19,6 +19,7 @@ package helma.main.launcher;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
@ -135,10 +136,10 @@ public class Main {
* @throws MalformedURLException
*/
public static ClassLoader createClassLoader(String installDir)
throws MalformedURLException {
throws MalformedURLException, UnsupportedEncodingException {
// decode installDir in case it is URL-encoded
installDir = URLDecoder.decode(installDir);
installDir = URLDecoder.decode(installDir, System.getProperty("helma.urlEncoding", "UTF-8"));
// set up the class path
File libdir = new File(installDir, "lib");

View file

@ -28,9 +28,7 @@
* @param {Object} val the value to check
* @return {boolean} true if the value is contained
*/
Array.prototype.contains = function(val) {
return this.indexOf(val) > -1;
};
Array.prototype.contains = Array.prototype.includes
/**
* Retrieve the union set of a bunch of arrays
@ -40,18 +38,9 @@ Array.prototype.contains = function(val) {
* @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;
return Array.from(arguments).reduce((result, array) => {
return result.concat(array.filter(element => !result.includes(element)));
}, []);
};
/**
@ -62,21 +51,9 @@ Array.union = function() {
* @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 Array.from(arguments).reduce((result, array) => {
return result.filter(element => array.includes(element));
});
};
// prevent any newly added properties from being enumerated

View file

@ -180,7 +180,7 @@ Date.prototype.getExpiry = function(param) {
*/
Date.prototype.equals = function(date, extend) {
if (!extend)
var extend = Date.ONEDAY;
extend = Date.ONEDAY;
switch (extend) {
case Date.ONESECOND:
if (this.getSeconds() != date.getSeconds())

View file

@ -17,7 +17,7 @@
/**
* @fileoverview Adds useful global macros.
* <br /><br />
* To use this optional module, its repository needs to be added to the
* To use this optional module, its repository needs to be added to the
* application, for example by calling app.addRepository('modules/core/Global.js')
*/
@ -77,3 +77,180 @@ var skin_macro = function(param, name) {
return;
}
/**
* Encodes a string for HTML output and inserts linebreak tags.
*
* Performs the following string manipulations:
* All line breaks (i.e. line feeds) are replaced with <br/> tags.
* All special characters are being replaced with their equivalent HTML entity.
* Existing markup tags are being encoded.
*
* @param {string} text
* The string to encode for HTML output.
* @param {boolean} [encodeNewLine = true]
* If or if not to encode line breaks (i.e. line feeds).
* @return {string}
* The encoded string.
*/
function encode(text, encodeNewLine) {
text = String(text);
if (text === null || !text.length) return text;
var buffer = [];
if (typeof encodeNewLine === 'undefined') encodeNewLine = true;
for (var i = 0, len = text.length; i < len; i += 1) {
var char = text.charAt(i);
switch (char) {
case '<':
buffer.push('&lt;');
break;
case '>':
buffer.push('&gt;');
break;
case '&':
buffer.push('&amp;');
break;
case '"':
buffer.push('&quot;');
break;
case '\n':
if (encodeNewLine) {
buffer.push("<br/>");
}
buffer.push('\n');
break;
default:
buffer.push(char);
}
}
return buffer.join('');
}
/**
* Encodes a string for XML output.
*
* Performs the following string manipulations:
* All special characters are being replaced with their equivalent HTML entity.
* Existing tags, single and double quotes, as well as ampersands are being encoded.
* Some invalid XML characters below '0x20' are removed
*
* @param {string} text
* The string to encode for XML output.
* @return {string}
* The string encoded for XML output.
*/
function encodeXml(text) {
text = String(text);
if (text === null || !text.length) return text;
var buffer = [];
for (var i = 0, len = text.length; i < len; i += 1) {
var char = text.charAt(i);
switch (char) {
case '<':
buffer.push('&lt;');
break;
case '>':
buffer.push('&gt;');
break;
case '&':
buffer.push('&amp;');
break;
case '"':
buffer.push('&quot;');
break;
case '\'':
buffer.push('&#39;');
break;
default:
var charCode = text.charCodeAt(i);
if (charCode < 0x20) {
// sort out invalid XML characters below 0x20 - all but 0x9, 0xA and 0xD.
// The trick is an adaption of java.lang.Character.isSpace().
if (((((1 << 0x9) | (1 << 0xA) | (1 << 0xD)) >> charCode) & 1) !== 0) {
buffer.push(char);
}
} else {
buffer.push(char);
}
}
}
return buffer.join('');
}
/**
* Encodes a string for HTML output, leaving linebreaks untouched.
*
* Performs the following string manipulations:
* Unlike encode, leaves linebreaks untouched. This is what you usually want to do for encoding form content (esp.
* with text input values).
* All special characters (i.e. non ASCII) are being replaced with their equivalent HTML entity.
* Existing markup tags are being encoded.
*
* @param {string} text
* The string to format for HTML output.
* @return {string}
* The string formatted for HTML output.
*/
var encodeForm = function(text) {
text = String(text);
if (text === null || !text.length) return text;
return encode(text, false);
};
/**
* Removes any markup tags contained in the passed string, and returns the modified string.
*
* @param {string} markup
* The text that is to be stripped of tags.
* @return {string}
* The text with the tags stripped out.
*/
var stripTags = function (markup) {
if (markup === null) return markup;
var chars = String(markup).split('');
var charCounter = 0;
var inTag = false;
for (var i = 0, len = markup.length; i < len; i += 1) {
if (chars[i] === '<') inTag = true;
if (!inTag) {
if (i > charCounter) {
chars[charCounter] = chars[i];
}
charCounter += 1;
}
if (chars[i] === '>') {
inTag = false;
}
}
if (i > charCounter) {
chars.length = charCounter;
return chars.join('');
}
return markup;
};

View file

@ -21,6 +21,8 @@
* application, for example by calling app.addRepository('modules/core/Object.js')
*/
app.addRepository('modules/core/Global.js');
/**
* Copies the properties of this object into a clone.
* @external

View file

@ -42,6 +42,8 @@ String.URLPATTERN = /^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\
* application, for example by calling app.addRepository('modules/core/String.js')
*/
app.addRepository('modules/core/Global.js');
/**
* checks if a date format pattern is correct
* @external
@ -392,54 +394,7 @@ String.prototype.unwrap = function(removeTags, replacement) {
* @return String md5 hash of the string
*/
String.prototype.md5 = function() {
return Packages.helma.util.MD5Encoder.encode(this);
};
/**
* function repeats a string the specified amount of times
* @external
* @memberof {String}
* @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
* @external
* @memberof {String}
* @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
* @external
* @memberof {String}
* @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);
return Packages.org.apache.commons.codec.digest.DigestUtils.md5Hex(this);
};
@ -455,28 +410,21 @@ String.prototype.endsWith = function(str) {
* 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;
String.prototype.pad = function(str, length, mode) {
if (mode === null || mode === String.RIGHT) return this.padEnd(length, str);
if (mode === String.LEFT) return this.padStart(length, str);
if (mode === String.BALANCE && str && length) {
const pos = Math.ceil(this.length / 2);
const head = this.substr(0, pos);
const tail = this.substr(pos);
const additionalLength = (length - this.length) / 2;
const startLength = head.length + Math.floor(additionalLength);
const endLength = tail.length + Math.ceil(additionalLength);
return head.padStart(startLength, str) + tail.padEnd(endLength, str);
}
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();
return this;
};
@ -490,9 +438,7 @@ String.prototype.pad = function(str, len, mode) {
* @param Boolean
*/
String.prototype.contains = function(str, fromIndex) {
if (this.indexOf(str, fromIndex ? fromIndex : 0) > -1)
return true;
return false;
return this.indexOf(str, fromIndex || 0) > -1;
};
@ -558,17 +504,6 @@ String.prototype.diff = function(mod, separator) {
};
/**
* remove leading and trailing whitespace
* @external
* @memberof {String}
*/
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
* @external

View file

@ -49,7 +49,7 @@ helma.auth = function(realm) {
var accessAllowed = true;
if (req.data.username && req.data.password) {
if (pw && hostIsAllowed()) {
if (pw == Packages.helma.util.MD5Encoder.encode(req.data.username + "-" + req.data.password)) {
if (pw == Packages.org.apache.commons.codec.digest.DigestUtils.md5Hex(req.data.username + "-" + req.data.password)) {
session.data[realm+'Authenticated'] = true;
res.redirect(res.data.href);
} else {
@ -61,7 +61,7 @@ helma.auth = function(realm) {
The adminAccess property is not set.<br />\
Before proceeding, add the following line to your app.properties or server.properties file:\
<br /><br />adminAccess='
+ Packages.helma.util.MD5Encoder.encode(req.data.username + "-" + req.data.password);
+ Packages.org.apache.commons.codec.digest.DigestUtils.md5Hex(req.data.username + "-" + req.data.password);
else param.message += 'The '+ realm +'AccessAllowed property does not match your host.<br />\
Before proceeding, remove this property from your app.properties or server.properties file \
or include your host as follows:<br /><br />'

View file

@ -46,7 +46,7 @@ function createAddressFilter() {
}
/**
/**
* updates the stats in app.data.stat every 5 minutes
*/
function appStat() {
@ -123,7 +123,7 @@ function checkAuth(appObj) {
if (uname == null || uname == "" || pwd == null || pwd == "")
return forceAuth();
var md5key = Packages.helma.util.MD5Encoder.encode(uname + "-" + pwd);
var md5key = Packages.org.apache.commons.codec.digest.DigestUtils.md5Hex(uname + "-" + pwd);
if (md5key == adminAccess)
return true;

View file

@ -75,7 +75,7 @@ function makekey_action() {
res.data.body = renderSkinAsString("pwdform", obj);
} else {
// render the md5-string:
obj.propsString = "adminAccess=" + Packages.helma.util.MD5Encoder.encode(req.data.username + "-" + req.data.password) + "<br>\n";
obj.propsString = "adminAccess=" + Packages.org.apache.commons.codec.digest.DigestUtils.md5Hex(req.data.username + "-" + req.data.password) + "<br>\n";
res.data.body = renderSkinAsString("pwdfeedback", obj);
}
@ -127,4 +127,4 @@ function mrtg_action() {
} else {
res.write("0\n0\n0\n0\n");
}
}
}

View file

@ -20,6 +20,8 @@ package helma.extensions;
*
*/
public class ConfigurationException extends RuntimeException {
private static final long serialVersionUID = 6428439427909728917L;
/**
* Creates a new ConfigurationException object.
*

View file

@ -24,4 +24,6 @@ package helma.framework;
*/
public class AbortException extends Error {
private static final long serialVersionUID = -7536693051844908815L;
}

View file

@ -22,6 +22,8 @@ package helma.framework;
* application
*/
public class ApplicationStoppedException extends RuntimeException {
private static final long serialVersionUID = 7125229844095452333L;
/**
* Creates a new ApplicationStoppedException object.
*/

View file

@ -24,6 +24,8 @@ import javax.servlet.http.Cookie;
* of an HTTP cookie.
*/
public final class CookieTrans implements Serializable {
private static final long serialVersionUID = 1811202114296536258L;
String name;
String value;
String path;

View file

@ -22,6 +22,8 @@ package helma.framework;
* wrong in evaluation of requests.
*/
public class FrameworkException extends RuntimeException {
private static final long serialVersionUID = -8477797850472128617L;
/**
* Creates a new FrameworkException object.
*

View file

@ -22,6 +22,8 @@ package helma.framework;
* wrong in evaluation of requests.
*/
public class NotFoundException extends RuntimeException {
private static final long serialVersionUID = -715022974097617658L;
/**
* Creates a new NotFoundException object.
*

View file

@ -24,6 +24,8 @@ package helma.framework;
* java.lang.ThreadDeath).
*/
public class RedirectException extends Error {
private static final long serialVersionUID = 2362170037476457592L;
String url;
/**

View file

@ -24,6 +24,8 @@ import java.util.Map;
*
*/
public class RequestBean implements Serializable {
private static final long serialVersionUID = -6826881712426326687L;
RequestTrans req;
/**

View file

@ -16,13 +16,15 @@
package helma.framework;
import helma.util.Base64;
import helma.util.SystemMap;
import helma.util.StringUtils;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Cookie;
import org.apache.commons.codec.binary.Base64;
import java.io.*;
import java.util.*;
import java.util.regex.Pattern;
@ -67,7 +69,7 @@ public class RequestTrans implements Serializable {
private ParamComboMap params;
private ParameterMap queryParams, postParams, cookies;
// the HTTP request method
private String method;
@ -601,11 +603,11 @@ public class RequestTrans implements Serializable {
StringTokenizer tok;
if (auth.startsWith("Basic ")) {
tok = new StringTokenizer(new String(Base64.decode((auth.substring(6)).toCharArray())),
":");
if (auth.startsWith("Basic ")) { //$NON-NLS-1$
tok = new StringTokenizer(new String(Base64.decodeBase64(auth.substring(6))),
":"); //$NON-NLS-1$
} else {
tok = new StringTokenizer(new String(Base64.decode(auth.toCharArray())), ":");
tok = new StringTokenizer(new String(Base64.decodeBase64(auth)), ":"); //$NON-NLS-1$
}
try {
@ -632,6 +634,8 @@ public class RequestTrans implements Serializable {
class ParameterMap extends SystemMap {
private static final long serialVersionUID = 7632860503639617076L;
public ParameterMap() {
super();
}
@ -708,6 +712,8 @@ public class RequestTrans implements Serializable {
class DataComboMap extends SystemMap {
private static final long serialVersionUID = 5737810055554406299L;
public Object get(Object key) {
Object value = super.get(key);
if (value != null)
@ -743,6 +749,8 @@ public class RequestTrans implements Serializable {
}
class ParamComboMap extends SystemMap {
private static final long serialVersionUID = -9177176570950359431L;
public Object get(Object key) {
Object value;
if (postParams != null && (value = postParams.get(key)) != null)

View file

@ -30,6 +30,8 @@ import java.util.Map;
*
*/
public class ResponseBean implements Serializable {
private static final long serialVersionUID = -6807623667477109800L;
ResponseTrans res;
/**
@ -584,6 +586,7 @@ public class ResponseBean implements Serializable {
* Old version for push() kept for compatibility
* @deprecated
*/
@Deprecated
public void pushStringBuffer() {
res.pushBuffer(null);
}
@ -593,6 +596,7 @@ public class ResponseBean implements Serializable {
* @deprecated
* @return ...
*/
@Deprecated
public String popStringBuffer() {
return res.popString();
}

View file

@ -26,6 +26,7 @@ import java.io.*;
import java.security.*;
import java.util.*;
import org.apache.commons.codec.binary.Base64;
import org.apache.xmlrpc.XmlRpcResponseProcessor;
/**
@ -712,8 +713,8 @@ public final class ResponseTrans extends Writer implements Serializable {
digest = MessageDigest.getInstance("MD5");
// if (contentType != null)
// digest.update (contentType.getBytes());
byte[] b = digest.digest(response);
etag = "\"" + new String(helma.util.Base64.encode(b)) + "\"";
byte[] b = this.digest.digest(this.response);
this.etag = "\"" + new String(Base64.encodeBase64(b)) + "\""; //$NON-NLS-1$ //$NON-NLS-2$
// only set response to 304 not modified if no cookies were set
if (reqtrans.hasETag(etag) && countCookies() == 0) {
response = new byte[0];
@ -864,7 +865,7 @@ public final class ResponseTrans extends Writer implements Serializable {
if (what == null) {
digest.update(new byte[0]);
} else if (what instanceof Date) {
digest.update(MD5Encoder.toBytes(((Date) what).getTime()));
digest.update(Long.toBinaryString(((Date) what).getTime()).getBytes());
} else if (what instanceof byte[]) {
digest.update((byte[]) what);
} else {
@ -888,9 +889,9 @@ public final class ResponseTrans extends Writer implements Serializable {
// add the application checksum as dependency to make ETag
// generation sensitive to changes in the app
byte[] b = digest.digest(MD5Encoder.toBytes(app.getChecksum()));
byte[] b = digest.digest(Long.toBinaryString((this.app.getChecksum())).getBytes());
setETag(new String(helma.util.Base64.encode(b)));
setETag(new String(Base64.encodeBase64(b)));
}
/**

View file

@ -22,6 +22,8 @@ package helma.framework;
* not be serviced within the timeout period specified for an application.
*/
public class TimeoutException extends RuntimeException {
private static final long serialVersionUID = 3853135482278393735L;
/**
* Creates a new TimeoutException object.
*/

View file

@ -20,6 +20,8 @@ import java.io.Serializable;
public class UploadStatus implements Serializable {
private static final long serialVersionUID = 8335579045959177198L;
long current = 0;
long total = 0;
int itemsRead = 0;

View file

@ -38,6 +38,8 @@ import org.apache.commons.logging.LogFactory;
* application specific functionality.
*/
public class ApplicationBean implements Serializable {
private static final long serialVersionUID = -5053315391709405106L;
transient Application app;
WrappedMap properties = null;

View file

@ -415,6 +415,11 @@ public final class Prototype {
* @return an iterator of this prototype's code resources
*/
public synchronized Iterator getCodeResources() {
// if code has never been updated, do so now before returning an empty or incomplete list
if (lastCodeUpdate == 0) {
checkForUpdates();
}
// we copy over to a new list, because the underlying set may grow
// during compilation through use of app.addRepository()
return new ArrayList(code).iterator();
@ -487,6 +492,8 @@ public final class Prototype {
* A Map that dynamically expands to all skins in this prototype.
*/
class SkinMap extends HashMap {
private static final long serialVersionUID = -8855785541204100909L;
volatile long lastSkinmapLoad = -1;
Object[] skinpath;

View file

@ -142,6 +142,7 @@ public class RequestPath {
* @return the index of the element, or -1 if it isn't contained
* @deprecated use {@link #indexOf(Object)} instead.
*/
@Deprecated
public int contains(Object obj) {
return objects.indexOf(obj);
}

View file

@ -27,6 +27,8 @@ import java.util.Date;
* exposes it to the scripting framework.
*/
public class SessionBean implements Serializable {
private static final long serialVersionUID = 7500231949937123265L;
// the wrapped session object
Session session;

View file

@ -1190,6 +1190,8 @@ public final class Skin {
* Exception type for unhandled, forbidden or failed macros
*/
class MacroException extends Exception {
private static final long serialVersionUID = 396025641010781784L;
MacroException(String message) {
super(message);
}

View file

@ -7,31 +7,30 @@
* http://adele.helma.org/download/helma/license.txt
*
* Copyright 1998-2003 Helma Software. All Rights Reserved.
*
* $RCSfile$
* $Author$
* $Revision$
* $Date$
*/
package helma.main;
import helma.framework.core.*;
import helma.framework.repository.Repository;
import helma.framework.repository.FileRepository;
import helma.util.StringUtils;
import org.apache.xmlrpc.XmlRpcHandler;
import java.io.File;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;
import org.apache.commons.logging.Log;
import org.apache.xmlrpc.XmlRpcHandler;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
import org.eclipse.jetty.server.handler.ResourceHandler;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import java.io.*;
import java.util.*;
import helma.util.ResourceProperties;
import helma.framework.core.Application;
import helma.framework.repository.FileRepository;
import helma.framework.repository.Repository;
import helma.servlet.EmbeddedServletClient;
import helma.util.ResourceProperties;
import helma.util.StringUtils;
/**
* This class is responsible for starting and stopping Helma applications.
@ -55,11 +54,11 @@ public class ApplicationManager implements XmlRpcHandler {
public ApplicationManager(ResourceProperties props, Server server) {
this.props = props;
this.server = server;
descriptors = new Hashtable();
applications = new Hashtable();
xmlrpcHandlers = new Hashtable();
lastModified = 0;
jetty = server.jetty;
this.descriptors = new Hashtable();
this.applications = new Hashtable();
this.xmlrpcHandlers = new Hashtable();
this.lastModified = 0;
this.jetty = server.jetty;
}
/**
@ -67,13 +66,13 @@ public class ApplicationManager implements XmlRpcHandler {
* to create and start new applications.
*/
protected void checkForChanges() {
if (props.lastModified() > lastModified && server.getApplicationsOption() == null) {
if (this.props.lastModified() > this.lastModified && this.server.getApplicationsOption() == null) {
try {
for (Enumeration e = props.keys(); e.hasMoreElements();) {
for (Enumeration e = this.props.keys(); e.hasMoreElements();) {
String appName = (String) e.nextElement();
if ((appName.indexOf(".") == -1) &&
(applications.get(appName) == null)) {
if ((appName.indexOf(".") == -1) && //$NON-NLS-1$
(this.applications.get(appName) == null)) {
AppDescriptor appDesc = new AppDescriptor(appName);
appDesc.start();
appDesc.bind();
@ -81,27 +80,27 @@ public class ApplicationManager implements XmlRpcHandler {
}
// then stop deleted ones
for (Enumeration e = descriptors.elements(); e.hasMoreElements();) {
for (Enumeration e = this.descriptors.elements(); e.hasMoreElements();) {
AppDescriptor appDesc = (AppDescriptor) e.nextElement();
// check if application has been removed and should be stopped
if (!props.containsKey(appDesc.appName)) {
if (!this.props.containsKey(appDesc.appName)) {
appDesc.stop();
} else if (server.jetty != null) {
} else if (this.server.jetty != null) {
// If application continues to run, remount
// as the mounting options may have changed.
AppDescriptor ndesc = new AppDescriptor(appDesc.appName);
ndesc.app = appDesc.app;
appDesc.unbind();
ndesc.bind();
descriptors.put(ndesc.appName, ndesc);
this.descriptors.put(ndesc.appName, ndesc);
}
}
} catch (Exception mx) {
getLogger().error("Error checking applications", mx);
}
lastModified = System.currentTimeMillis();
this.lastModified = System.currentTimeMillis();
}
}
@ -118,7 +117,7 @@ public class ApplicationManager implements XmlRpcHandler {
* Bind an application by name
*/
public void register(String appName) {
AppDescriptor desc = (AppDescriptor) descriptors.get(appName);
AppDescriptor desc = (AppDescriptor) this.descriptors.get(appName);
if (desc != null) {
desc.bind();
}
@ -128,7 +127,7 @@ public class ApplicationManager implements XmlRpcHandler {
* Stop an application by name
*/
public void stop(String appName) {
AppDescriptor desc = (AppDescriptor) descriptors.get(appName);
AppDescriptor desc = (AppDescriptor) this.descriptors.get(appName);
if (desc != null) {
desc.stop();
}
@ -140,18 +139,18 @@ public class ApplicationManager implements XmlRpcHandler {
*/
public void startAll() {
try {
String[] apps = server.getApplicationsOption();
String[] apps = this.server.getApplicationsOption();
if (apps != null) {
for (int i = 0; i < apps.length; i++) {
AppDescriptor desc = new AppDescriptor(apps[i]);
desc.start();
}
} else {
for (Enumeration e = props.keys(); e.hasMoreElements();) {
for (Enumeration e = this.props.keys(); e.hasMoreElements();) {
String appName = (String) e.nextElement();
if (appName.indexOf(".") == -1) {
String appValue = props.getProperty(appName);
if (appName.indexOf(".") == -1) { //$NON-NLS-1$
String appValue = this.props.getProperty(appName);
if (appValue != null && appValue.length() > 0) {
appName = appValue;
@ -163,12 +162,12 @@ public class ApplicationManager implements XmlRpcHandler {
}
}
for (Enumeration e = descriptors.elements(); e.hasMoreElements();) {
for (Enumeration e = this.descriptors.elements(); e.hasMoreElements();) {
AppDescriptor appDesc = (AppDescriptor) e.nextElement();
appDesc.bind();
}
lastModified = System.currentTimeMillis();
this.lastModified = System.currentTimeMillis();
} catch (Exception mx) {
getLogger().error("Error starting applications", mx);
mx.printStackTrace();
@ -179,7 +178,7 @@ public class ApplicationManager implements XmlRpcHandler {
* Stop all running applications.
*/
public void stopAll() {
for (Enumeration en = descriptors.elements(); en.hasMoreElements();) {
for (Enumeration en = this.descriptors.elements(); en.hasMoreElements();) {
try {
AppDescriptor appDesc = (AppDescriptor) en.nextElement();
@ -194,14 +193,14 @@ public class ApplicationManager implements XmlRpcHandler {
* Get an array containing all currently running applications.
*/
public Object[] getApplications() {
return applications.values().toArray();
return this.applications.values().toArray();
}
/**
* Get an application by name.
*/
public Application getApplication(String name) {
return (Application) applications.get(name);
return (Application) this.applications.get(name);
}
/**
@ -209,7 +208,7 @@ public class ApplicationManager implements XmlRpcHandler {
*/
public Object execute(String method, Vector params)
throws Exception {
int dot = method.indexOf(".");
int dot = method.indexOf("."); //$NON-NLS-1$
if (dot == -1) {
throw new Exception("Method name \"" + method +
@ -222,10 +221,10 @@ public class ApplicationManager implements XmlRpcHandler {
String handler = method.substring(0, dot);
String method2 = method.substring(dot + 1);
Application app = (Application) xmlrpcHandlers.get(handler);
Application app = (Application) this.xmlrpcHandlers.get(handler);
if (app == null) {
app = (Application) xmlrpcHandlers.get("*");
app = (Application) this.xmlrpcHandlers.get("*"); //$NON-NLS-1$
// use the original method name, the handler is resolved within the app.
method2 = method;
}
@ -240,33 +239,32 @@ public class ApplicationManager implements XmlRpcHandler {
private String getMountpoint(String mountpoint) {
mountpoint = mountpoint.trim();
if ("".equals(mountpoint)) {
return "/";
} else if (!mountpoint.startsWith("/")) {
return "/" + mountpoint;
if ("".equals(mountpoint)) { //$NON-NLS-1$
return "/"; //$NON-NLS-1$
} else if (!mountpoint.startsWith("/")) { //$NON-NLS-1$
return "/" + mountpoint; //$NON-NLS-1$
}
return mountpoint;
}
private String joinMountpoint(String prefix, String suffix) {
if (prefix.endsWith("/") || suffix.startsWith("/")) {
if (prefix.endsWith("/") || suffix.startsWith("/")) { //$NON-NLS-1$//$NON-NLS-2$
return prefix+suffix;
} else {
return prefix+"/"+suffix;
}
return prefix+"/"+suffix; //$NON-NLS-1$
}
private String getPathPattern(String mountpoint) {
if (!mountpoint.startsWith("/")) {
mountpoint = "/"+mountpoint;
if (!mountpoint.startsWith("/")) { //$NON-NLS-1$
mountpoint = "/"+mountpoint; //$NON-NLS-1$
}
if ("/".equals(mountpoint)) {
return "/";
if ("/".equals(mountpoint)) { //$NON-NLS-1$
return "/"; //$NON-NLS-1$
}
if (mountpoint.endsWith("/")) {
if (mountpoint.endsWith("/")) { //$NON-NLS-1$
return mountpoint.substring(0, mountpoint.length()-1);
}
@ -279,19 +277,18 @@ public class ApplicationManager implements XmlRpcHandler {
File file = new File(path);
if (file.isAbsolute()) {
return file;
} else {
return file.getAbsoluteFile();
}
return file.getAbsoluteFile();
}
private Log getLogger() {
return server.getLogger();
return this.server.getLogger();
}
private String findResource(String path) {
File file = new File(path);
if (!file.isAbsolute() && !file.exists()) {
file = new File(server.getHopHome(), path);
file = new File(this.server.getHopHome(), path);
}
return file.getAbsolutePath();
}
@ -336,58 +333,58 @@ public class ApplicationManager implements XmlRpcHandler {
* @param name the application name
*/
AppDescriptor(String name) {
ResourceProperties conf = props.getSubProperties(name + '.');
appName = name;
mountpoint = getMountpoint(conf.getProperty("mountpoint", appName));
pathPattern = getPathPattern(mountpoint);
staticDir = conf.getProperty("static");
staticMountpoint = getPathPattern(conf.getProperty("staticMountpoint",
joinMountpoint(mountpoint, "static")));
staticIndex = "true".equalsIgnoreCase(conf.getProperty("staticIndex"));
String home = conf.getProperty("staticHome");
ResourceProperties conf = ApplicationManager.this.props.getSubProperties(name + '.');
this.appName = name;
this.mountpoint = getMountpoint(conf.getProperty("mountpoint", this.appName)); //$NON-NLS-1$
this.pathPattern = getPathPattern(this.mountpoint);
this.staticDir = conf.getProperty("static"); //$NON-NLS-1$
this.staticMountpoint = getPathPattern(conf.getProperty("staticMountpoint", //$NON-NLS-1$
joinMountpoint(this.mountpoint, "static"))); //$NON-NLS-1$
this.staticIndex = "true".equalsIgnoreCase(conf.getProperty("staticIndex")); //$NON-NLS-1$//$NON-NLS-2$
String home = conf.getProperty("staticHome"); //$NON-NLS-1$
if (home == null) {
staticHome = new String[] {"index.html", "index.htm"};
this.staticHome = new String[] {"index.html", "index.htm"}; //$NON-NLS-1$ //$NON-NLS-2$
} else {
staticHome = StringUtils.split(home, ",");
this.staticHome = StringUtils.split(home, ","); //$NON-NLS-1$
}
protectedStaticDir = conf.getProperty("protectedStatic");
this.protectedStaticDir = conf.getProperty("protectedStatic"); //$NON-NLS-1$
cookieDomain = conf.getProperty("cookieDomain");
sessionCookieName = conf.getProperty("sessionCookieName");
protectedSessionCookie = conf.getProperty("protectedSessionCookie");
uploadLimit = conf.getProperty("uploadLimit");
uploadSoftfail = conf.getProperty("uploadSoftfail");
debug = conf.getProperty("debug");
String appDirName = conf.getProperty("appdir");
appDir = (appDirName == null) ? null : getAbsoluteFile(appDirName);
String dbDirName = conf.getProperty("dbdir");
dbDir = (dbDirName == null) ? null : getAbsoluteFile(dbDirName);
servletClassName = conf.getProperty("servletClass");
this.cookieDomain = conf.getProperty("cookieDomain"); //$NON-NLS-1$
this.sessionCookieName = conf.getProperty("sessionCookieName"); //$NON-NLS-1$
this.protectedSessionCookie = conf.getProperty("protectedSessionCookie"); //$NON-NLS-1$
this.uploadLimit = conf.getProperty("uploadLimit"); //$NON-NLS-1$
this.uploadSoftfail = conf.getProperty("uploadSoftfail"); //$NON-NLS-1$
this.debug = conf.getProperty("debug"); //$NON-NLS-1$
String appDirName = conf.getProperty("appdir"); //$NON-NLS-1$
this.appDir = (appDirName == null) ? null : getAbsoluteFile(appDirName);
String dbDirName = conf.getProperty("dbdir"); //$NON-NLS-1$
this.dbDir = (dbDirName == null) ? null : getAbsoluteFile(dbDirName);
this.servletClassName = conf.getProperty("servletClass"); //$NON-NLS-1$
// got ignore dirs
ignoreDirs = conf.getProperty("ignore");
this.ignoreDirs = conf.getProperty("ignore"); //$NON-NLS-1$
// read and configure app repositories
ArrayList repositoryList = new ArrayList();
Class[] parameters = { String.class };
for (int i = 0; true; i++) {
String repositoryArgs = conf.getProperty("repository." + i);
String repositoryArgs = conf.getProperty("repository." + i); //$NON-NLS-1$
if (repositoryArgs != null) {
// lookup repository implementation
String repositoryImpl = conf.getProperty("repository." + i +
".implementation");
String repositoryImpl = conf.getProperty("repository." + i + //$NON-NLS-1$
".implementation"); //$NON-NLS-1$
if (repositoryImpl == null) {
// implementation not set manually, have to guess it
if (repositoryArgs.endsWith(".zip")) {
if (repositoryArgs.endsWith(".zip")) { //$NON-NLS-1$
repositoryArgs = findResource(repositoryArgs);
repositoryImpl = "helma.framework.repository.ZipRepository";
} else if (repositoryArgs.endsWith(".js")) {
repositoryImpl = "helma.framework.repository.ZipRepository"; //$NON-NLS-1$
} else if (repositoryArgs.endsWith(".js")) { //$NON-NLS-1$
repositoryArgs = findResource(repositoryArgs);
repositoryImpl = "helma.framework.repository.SingleFileRepository";
repositoryImpl = "helma.framework.repository.SingleFileRepository"; //$NON-NLS-1$
} else {
repositoryArgs = findResource(repositoryArgs);
repositoryImpl = "helma.framework.repository.FileRepository";
repositoryImpl = "helma.framework.repository.FileRepository"; //$NON-NLS-1$
}
}
@ -408,17 +405,17 @@ public class ApplicationManager implements XmlRpcHandler {
}
}
if (appDir != null) {
FileRepository appRep = new FileRepository(appDir);
if (this.appDir != null) {
FileRepository appRep = new FileRepository(this.appDir);
if (!repositoryList.contains(appRep)) {
repositoryList.add(appRep);
}
} else if (repositoryList.isEmpty()) {
repositoryList.add(new FileRepository(
new File(server.getAppsHome(), appName)));
new File(ApplicationManager.this.server.getAppsHome(), this.appName)));
}
repositories = new Repository[repositoryList.size()];
repositories = (Repository[]) repositoryList.toArray(repositories);
this.repositories = (Repository[]) repositoryList.toArray(new Repository[repositoryList.size()]);
}
@ -427,21 +424,21 @@ public class ApplicationManager implements XmlRpcHandler {
try {
// create the application instance
app = new Application(appName, server, repositories, appDir, dbDir);
this.app = new Application(this.appName, ApplicationManager.this.server, this.repositories, this.appDir, this.dbDir);
// register ourselves
descriptors.put(appName, this);
applications.put(appName, app);
ApplicationManager.this.descriptors.put(this.appName, this);
ApplicationManager.this.applications.put(this.appName, this.app);
// the application is started later in the register method, when it's bound
app.init(ignoreDirs);
this.app.init(this.ignoreDirs);
// set application URL prefix if it isn't set in app.properties
if (!app.hasExplicitBaseURI()) {
app.setBaseURI(mountpoint);
if (!this.app.hasExplicitBaseURI()) {
this.app.setBaseURI(this.mountpoint);
}
app.start();
this.app.start();
} catch (Exception x) {
getLogger().error("Error creating application " + appName, x);
x.printStackTrace();
@ -462,8 +459,8 @@ public class ApplicationManager implements XmlRpcHandler {
getLogger().error("Couldn't stop app", x);
}
descriptors.remove(appName);
applications.remove(appName);
ApplicationManager.this.descriptors.remove(this.appName);
ApplicationManager.this.applications.remove(this.appName);
}
void bind() {
@ -471,21 +468,21 @@ public class ApplicationManager implements XmlRpcHandler {
getLogger().info("Binding application " + appName + " :: " + app.hashCode() + " :: " + this.hashCode());
// set application URL prefix if it isn't set in app.properties
if (!app.hasExplicitBaseURI()) {
app.setBaseURI(mountpoint);
if (!this.app.hasExplicitBaseURI()) {
this.app.setBaseURI(this.mountpoint);
}
// bind to Jetty HTTP server
if (jetty != null) {
if (context == null) {
context = new ContextHandlerCollection();
jetty.getHttpServer().setHandler(context);
if (ApplicationManager.this.jetty != null) {
if(ApplicationManager.this.context == null) {
ApplicationManager.this.context = new ContextHandlerCollection();
ApplicationManager.this.jetty.getHttpServer().setHandler(ApplicationManager.this.context);
}
// if there is a static direcory specified, mount it
if (staticDir != null) {
if (this.staticDir != null) {
File staticContent = getAbsoluteFile(staticDir);
File staticContent = getAbsoluteFile(this.staticDir);
getLogger().info("Serving static from " + staticContent.getPath());
getLogger().info("Mounting static at " + staticMountpoint);
@ -494,7 +491,7 @@ public class ApplicationManager implements XmlRpcHandler {
rhandler.setResourceBase(staticContent.getPath());
rhandler.setWelcomeFiles(staticHome);
staticContext = context.addContext(staticMountpoint, "");
staticContext = ApplicationManager.this.context.addContext(staticMountpoint, ""); //$NON-NLS-1$
staticContext.setHandler(rhandler);
staticContext.start();
@ -504,48 +501,49 @@ public class ApplicationManager implements XmlRpcHandler {
Class servletClass = servletClassName == null ?
EmbeddedServletClient.class : Class.forName(servletClassName);
ServletHolder holder = new ServletHolder(servletClass);
holder.setInitParameter("application", appName);
appContext.addServlet(holder, "/*");
appContext.addServlet(holder, "/*"); //$NON-NLS-1$
if (cookieDomain != null) {
holder.setInitParameter("cookieDomain", cookieDomain);
holder.setInitParameter("application", appName); //$NON-NLS-1$
if (this.cookieDomain != null) {
holder.setInitParameter("cookieDomain", this.cookieDomain); //$NON-NLS-1$
}
if (sessionCookieName != null) {
holder.setInitParameter("sessionCookieName", sessionCookieName);
if (this.sessionCookieName != null) {
holder.setInitParameter("sessionCookieName", this.sessionCookieName); //$NON-NLS-1$
}
if (protectedSessionCookie != null) {
holder.setInitParameter("protectedSessionCookie", protectedSessionCookie);
if (this.protectedSessionCookie != null) {
holder.setInitParameter("protectedSessionCookie", this.protectedSessionCookie); //$NON-NLS-1$
}
if (uploadLimit != null) {
holder.setInitParameter("uploadLimit", uploadLimit);
if (this.uploadLimit != null) {
holder.setInitParameter("uploadLimit", this.uploadLimit); //$NON-NLS-1$
}
if (uploadSoftfail != null) {
holder.setInitParameter("uploadSoftfail", uploadSoftfail);
if (this.uploadSoftfail != null) {
holder.setInitParameter("uploadSoftfail", this.uploadSoftfail); //$NON-NLS-1$
}
if (debug != null) {
holder.setInitParameter("debug", debug);
if (this.debug != null) {
holder.setInitParameter("debug", this.debug); //$NON-NLS-1$
}
if (protectedStaticDir != null) {
File protectedContent = getAbsoluteFile(protectedStaticDir);
appContext.setResourceBase(protectedContent.getPath());
if (this.protectedStaticDir != null) {
File protectedContent = getAbsoluteFile(this.protectedStaticDir);
this.appContext.setResourceBase(protectedContent.getPath());
getLogger().info("Serving protected static from " +
protectedContent.getPath());
}
// Remap the context paths and start
context.mapContexts();
appContext.start();
ApplicationManager.this.context.mapContexts();
this.appContext.start();
}
// register as XML-RPC handler
xmlrpcHandlerName = app.getXmlRpcHandlerName();
xmlrpcHandlers.put(xmlrpcHandlerName, app);
this.xmlrpcHandlerName = this.app.getXmlRpcHandlerName();
ApplicationManager.this.xmlrpcHandlers.put(this.xmlrpcHandlerName, this.app);
} catch (Exception x) {
getLogger().error("Couldn't bind app", x);
x.printStackTrace();
@ -557,26 +555,26 @@ public class ApplicationManager implements XmlRpcHandler {
try {
// unbind from Jetty HTTP server
if (jetty != null) {
if (appContext != null) {
context.removeHandler(appContext);
appContext.stop();
appContext.destroy();
appContext = null;
if (ApplicationManager.this.jetty != null) {
if (this.appContext != null) {
ApplicationManager.this.context.removeHandler(this.appContext);
this.appContext.stop();
this.appContext.destroy();
this.appContext = null;
}
if (staticContext != null) {
context.removeHandler(staticContext);
staticContext.stop();
staticContext.destroy();
staticContext = null;
if (this.staticContext != null) {
ApplicationManager.this.context.removeHandler(this.staticContext);
this.staticContext.stop();
this.staticContext.destroy();
this.staticContext = null;
}
context.mapContexts();
ApplicationManager.this.context.mapContexts();
}
// unregister as XML-RPC handler
if (xmlrpcHandlerName != null) {
xmlrpcHandlers.remove(xmlrpcHandlerName);
if (this.xmlrpcHandlerName != null) {
ApplicationManager.this.xmlrpcHandlers.remove(this.xmlrpcHandlerName);
}
} catch (Exception x) {
getLogger().error("Couldn't unbind app", x);
@ -584,8 +582,9 @@ public class ApplicationManager implements XmlRpcHandler {
}
@Override
public String toString() {
return "[AppDescriptor "+app+"]";
return "[AppDescriptor "+this.app+"]"; //$NON-NLS-1$ //$NON-NLS-2$
}
}
}

View file

@ -216,15 +216,6 @@ public class HelmaSecurityManager extends SecurityManager {
public void checkMulticast(InetAddress addr) {
}
/**
*
*
* @param addr ...
* @param ttl ...
*/
public void checkMulticast(InetAddress addr, byte ttl) {
}
/**
*
*/

View file

@ -145,11 +145,13 @@ public class Server implements Runnable {
public static void checkJavaVersion() {
String javaVersion = System.getProperty("java.version");
if ((javaVersion == null) || javaVersion.startsWith("1.3")
if ((javaVersion == null) || javaVersion.startsWith("1.5")
|| javaVersion.startsWith("1.4")
|| javaVersion.startsWith("1.3")
|| javaVersion.startsWith("1.2")
|| javaVersion.startsWith("1.1")
|| javaVersion.startsWith("1.0")) {
System.err.println("This version of Helma requires Java 1.4 or greater.");
System.err.println("This version of Helma requires Java 1.6 or greater.");
if (javaVersion == null) { // don't think this will ever happen, but you never know
System.err.println("Your Java Runtime did not provide a version number. Please update to a more recent version.");

View file

@ -22,6 +22,8 @@ package helma.objectmodel;
* will normally catch this and try again after a period of time.
*/
public class ConcurrencyException extends Error {
private static final long serialVersionUID = 4031542073544406467L;
/**
* Creates a new ConcurrencyException object.
*

View file

@ -21,6 +21,8 @@ package helma.objectmodel;
* Thrown on any kind of Database-Error
*/
public class DatabaseException extends RuntimeException {
private static final long serialVersionUID = -5715728591015640819L;
/**
* Creates a new DatabaseException object.
*

View file

@ -22,6 +22,8 @@ import java.io.*;
* This is passed to NodeListeners when a node is modified.
*/
public class NodeEvent implements Serializable {
private static final long serialVersionUID = 4322426080131107600L;
public static final int CONTENT_CHANGED = 0;
public static final int PROPERTIES_CHANGED = 1;
public static final int NODE_REMOVED = 2;

View file

@ -22,6 +22,8 @@ package helma.objectmodel;
* it was expected.
*/
public class ObjectNotFoundException extends Exception {
private static final long serialVersionUID = -5368941052804232094L;
/**
* Creates a new ObjectNotFoundException object.
*

View file

@ -36,6 +36,8 @@ import java.util.Vector;
* object, class helma.objectmodel.db.Node has to be used.
*/
public class TransientNode implements INode, Serializable {
private static final long serialVersionUID = -4599844796152072979L;
private static long idgen = 0;
protected Hashtable propMap;
protected Hashtable nodeMap;

View file

@ -24,6 +24,8 @@ import java.util.Date;
* A property implementation for Nodes stored inside a database.
*/
public final class TransientProperty implements IProperty, Serializable {
private static final long serialVersionUID = 3128899239601365229L;
protected String propname;
protected TransientNode node;
public String svalue;

View file

@ -15,6 +15,8 @@ import java.util.*;
public class SegmentedSubnodeList extends SubnodeList {
private static final long serialVersionUID = -4947752577517584610L;
transient Segment[] segments = null;
static int SEGLENGTH = 1000;

View file

@ -25,6 +25,8 @@ import java.io.Serializable;
*/
public class SubnodeList implements Serializable {
private static final long serialVersionUID = 711208015232333566L;
protected Node node;
protected List list;

View file

@ -495,6 +495,7 @@ public class Transactor {
/**
* Kill this transaction thread. Used as last measure only.
*/
@SuppressWarnings("deprecation")
public synchronized void kill() {
killed = true;

View file

@ -27,6 +27,8 @@ import java.io.*;
*/
public class ScriptingException extends Exception {
private static final long serialVersionUID = -7191341724784015678L;
String scriptStack = null;
/**

View file

@ -0,0 +1,73 @@
/*
* 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 2017 Daniel Ruthardt. All rights reserved.
*/
package helma.scripting.rhino;
import java.net.URI;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.EvaluatorException;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.commonjs.module.ModuleScript;
import org.mozilla.javascript.commonjs.module.provider.ModuleSourceProvider;
import org.mozilla.javascript.commonjs.module.provider.StrongCachingModuleScriptProvider;
/**
* Provides module scripts without compiling, should compiling not be possible for whatever reason.
* The main reason being targeted though, is the "generated bytecode for method exceeds 64K limit" issue.
*/
public class CompiledOrInterpretedModuleScriptProvider extends StrongCachingModuleScriptProvider {
/**
* Define the serialization UID.
*/
private static final long serialVersionUID = 1170789670529274963L;
/**
* Delegates to the super constructor.
*/
public CompiledOrInterpretedModuleScriptProvider(ModuleSourceProvider moduleSourceProvider) {
// do what would have been done anyways
super(moduleSourceProvider);
}
@Override
public ModuleScript getModuleScript(Context cx, String moduleId, URI moduleUri, URI baseUri, Scriptable paths) throws Exception {
try {
// try to load the module script with whatever optimization level is set for the application
return super.getModuleScript(cx, moduleId, moduleUri, baseUri, paths);
} catch (EvaluatorException ignore) {
// unlikely, but possible exception during loading the module script without compilation
Exception exception;
// get the application's optimization level
int optimizationLevel = cx.getOptimizationLevel();
try {
// set the optimization level to not compile, but interpret
cx.setOptimizationLevel(-1);
// load the module script with the newly set optimization level
ModuleScript moduleScript = super.getModuleScript(cx, moduleId, moduleUri, baseUri, paths);
// return the module script
return moduleScript;
} catch (Exception e) {
// remember the exception
exception = e;
} finally {
// re-set the optimization
cx.setOptimizationLevel(optimizationLevel);
}
// re-throw the exception catched when trying to load the module script without compilation
throw exception;
}
}
}

View file

@ -37,6 +37,8 @@ import java.io.*;
* Helma global object defines a number of custom global functions.
*/
public class GlobalObject extends ImporterTopLevel implements PropertyRecorder {
private static final long serialVersionUID = -5058912338247265290L;
Application app;
RhinoCore core;
boolean isThreadScope = false;
@ -68,8 +70,7 @@ public class GlobalObject extends ImporterTopLevel implements PropertyRecorder {
public void init() {
String[] globalFuncs = {
"renderSkin", "renderSkinAsString", "getProperty",
"authenticate", "createSkin", "format", "encode",
"encodeXml", "encodeForm", "stripTags", "formatParagraphs",
"authenticate", "createSkin", "format", "formatParagraphs",
"getXmlDocument", "getHtmlDocument", "seal",
"getDBConnection", "getURL", "write", "writeln",
"serialize", "deserialize", "defineLibraryScope",
@ -152,7 +153,7 @@ public class GlobalObject extends ImporterTopLevel implements PropertyRecorder {
Skin skin = engine.toSkin(skinobj, "global");
if (skin != null) {
skin.render(engine.reval, null,
skin.render(engine.reval, null,
(paramobj == Undefined.instance) ? null : paramobj);
}
@ -379,6 +380,7 @@ public class GlobalObject extends ImporterTopLevel implements PropertyRecorder {
* @param name the name of the libary namespace
* @deprecated should be implemented in JavaScript instead
*/
@Deprecated
public void defineLibraryScope(final String name) {
Object obj = get(name, this);
if (obj != NOT_FOUND) {
@ -388,6 +390,8 @@ public class GlobalObject extends ImporterTopLevel implements PropertyRecorder {
return;
}
ScriptableObject scope = new NativeObject() {
private static final long serialVersionUID = 9205558066617631601L;
public String getClassName() {
return name;
}
@ -453,39 +457,6 @@ public class GlobalObject extends ImporterTopLevel implements PropertyRecorder {
return new NativeJavaObject(this, obj, null);
}
/**
*
*
* @param obj ...
*
* @return ...
*/
public String encode(Object obj) {
return HtmlEncoder.encodeAll(toString(obj));
}
/**
*
*
* @param obj ...
*
* @return ...
*/
public String encodeXml(Object obj) {
return HtmlEncoder.encodeXml(toString(obj));
}
/**
*
*
* @param obj ...
*
* @return ...
*/
public String encodeForm(Object obj) {
return HtmlEncoder.encodeFormValue(toString(obj));
}
/**
*
*
@ -568,47 +539,6 @@ public class GlobalObject extends ImporterTopLevel implements PropertyRecorder {
}
}
/**
* (Try to) strip all HTML/XML style tags from the given string argument
*
* @param str a string
* @return the string with tags removed
*/
public String stripTags(String str) {
if (str == null) {
return null;
}
char[] c = str.toCharArray();
boolean inTag = false;
int i;
int j = 0;
for (i = 0; i < c.length; i++) {
if (c[i] == '<') {
inTag = true;
}
if (!inTag) {
if (i > j) {
c[j] = c[i];
}
j++;
}
if (c[i] == '>') {
inTag = false;
}
}
if (i > j) {
return new String(c, 0, j);
}
return str;
}
/**
* Serialize a JavaScript object to a file.
*/
@ -658,10 +588,10 @@ public class GlobalObject extends ImporterTopLevel implements PropertyRecorder {
}
/**
* Set DONTENUM attrubutes on the given properties in this object.
* Set DONTENUM attrubutes on the given properties in this object.
* This is set on the JavaScript Object prototype.
*/
public static Object dontEnum (Context cx, Scriptable thisObj,
public static Object dontEnum (Context cx, Scriptable thisObj,
Object[] args, Function funObj) {
if (!(thisObj instanceof ScriptableObject)) {
throw new EvaluatorException("dontEnum() called on non-ScriptableObject");

View file

@ -66,9 +66,9 @@ public class HacHspConverter {
f.append(" (");
if (args != null)
f.append(args);
f.append(") {\n");
f.append(") {");
f.append(body);
f.append("\n}");
f.append("}");
return f.toString();
}

View file

@ -33,6 +33,8 @@ import java.io.IOException;
*/
public class HopObject extends ScriptableObject implements Wrapper, PropertyRecorder {
private static final long serialVersionUID = 1329862822101428427L;
String className;
final NodeProxy proxy;
final RhinoCore core;
@ -705,6 +707,7 @@ public class HopObject extends ScriptableObject implements Wrapper, PropertyReco
* Return its index position if it is, and -1 otherwise.
* @deprecated use indexOf(Object) instead.
*/
@Deprecated
public int jsFunction_contains(Object obj) {
return jsFunction_indexOf(obj);
}

View file

@ -29,6 +29,8 @@ import org.mozilla.javascript.*;
public class HopObjectCtor extends FunctionObject {
private static final long serialVersionUID = 3787907922712636030L;
// init flag to trigger prototype compilation on
// static constructor property access
boolean initialized;
@ -144,6 +146,8 @@ public class HopObjectCtor extends FunctionObject {
class GetById extends BaseFunction {
private static final long serialVersionUID = -8041352998956882647L;
public GetById(Scriptable scope) {
ScriptRuntime.setFunctionProtoAndParent(this, scope);
}
@ -187,6 +191,8 @@ public class HopObjectCtor extends FunctionObject {
class HopCollection extends BaseFunction {
private static final long serialVersionUID = -4046933261468527204L;
public HopCollection(Scriptable scope) {
ScriptRuntime.setFunctionProtoAndParent(this, scope);
}

View file

@ -0,0 +1,35 @@
package helma.scripting.rhino;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.net.URI;
import org.apache.commons.io.IOUtils;
import org.mozilla.javascript.commonjs.module.provider.ModuleSource;
public class JSONModuleSource extends ModuleSource {
private static final long serialVersionUID = 4446798833357540398L;
public JSONModuleSource(Object securityDomain, URI uri, URI base, Object validator) {
super(null, securityDomain, uri, base, validator);
}
@Override
public Reader getReader() {
StringBuffer content = new StringBuffer();
content.append("module.exports = "); //$NON-NLS-1$
try {
content.append(IOUtils.toString(this.getUri().toURL().openStream()));
} catch (IOException e) {
content.append("null"); //$NON-NLS-1$
}
content.append(";"); //$NON-NLS-1$
return new StringReader(content.toString());
}
}

View file

@ -32,6 +32,8 @@ import java.io.IOException;
*/
public class JavaObject extends NativeJavaObject {
private static final long serialVersionUID = 6348440950512377606L;
RhinoCore core;
String protoName;
NativeJavaObject unscriptedJavaObj;

View file

@ -30,6 +30,8 @@ import java.util.Map;
* and helma.util.WrappedMap.
*/
public class MapWrapper extends ScriptableObject implements Wrapper {
private static final long serialVersionUID = -8802538795495729410L;
Map map;
RhinoCore core;

View file

@ -0,0 +1,212 @@
/*
* 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 2017 Daniel Ruthardt. All rights reserved.
*/
package helma.scripting.rhino;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.file.Files;
import org.apache.commons.io.FilenameUtils;
import org.mozilla.javascript.commonjs.module.provider.ModuleSource;
import org.mozilla.javascript.commonjs.module.provider.UrlModuleSourceProvider;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.JsonSyntaxException;
/**
* Bridges the gap between CommonJS-style module loading and Node.js-style module loading.
*/
public class NodeModulesProvider extends UrlModuleSourceProvider {
/**
* Define the serialization UID.
*/
private static final long serialVersionUID = 6858072487233136717L;
/**
* Delegates to the super constructor.
*/
public NodeModulesProvider(Iterable<URI> privilegedUris, Iterable<URI> fallbackUris) {
// do what would have been done anyways
super(privilegedUris, fallbackUris);
}
/**
* Do what Node.js's LOAD_AS_FILE(X) would do.
* Case 4 ("If X.node is a file, load X.node as binary addon. STOP") is currently not supported (for
* quite obvious reasons). We might want to load JAR files in the future.
*
* @see https://nodejs.org/dist/latest-v9.x/docs/api/modules.html#modules_file_modules
*
* @param uri
* The file to load. FILE, FILE.js and FILE.json will be tried in this order.
* @param base
* Not used, only forwarded to
* {@link UrlModuleSourceProvider#loadSource(URI, URI, Object)}.
* @param validator
* Not used, only forwarded to
* {@link UrlModuleSourceProvider#loadSource(URI, URI, Object)}.
* @return
* The module source or null, if the module was not found.
*
* @throws IOException
* See {@link UrlModuleSourceProvider#loadSource(URI, URI, Object)}.
* @throws URISyntaxException
* See {@link UrlModuleSourceProvider#loadSource(URI, URI, Object)}.
*/
private ModuleSource loadAsFile(URI uri, URI base, Object validator)
throws IOException, URISyntaxException {
// lets assume the module is a file
File file = new File(uri);
// check if the file exists and is a file
if (file.exists() && file.isFile()) {
// check if the file is a JSON file
if (file.getAbsolutePath().toLowerCase().endsWith(".json")) { //$NON-NLS-1$
// return a JSON module source
return new JSONModuleSource(null, file.toURI(), base, validator);
} else {
// do what would have been done anyways
return super.loadFromUri(uri, base, validator);
}
}
// lets assume the module is a JS file
file = new File(new File(uri).getPath() + ".js"); //$NON-NLS-1$
// check if a file.js exists and is a file
if (file.exists() && file.isFile()) {
// do what would have been done anyways
return super.loadFromUri(uri, base, validator);
}
// lets assume the module is a JSON file
file = new File(new File(uri).getPath() + ".json"); //$NON-NLS-1$
// check if a file.json exists and is a file
if (file.exists() && file.isFile()) {
// return a JSON module source
return new JSONModuleSource(null, file.toURI(), base, validator);
}
// module not found
return null;
}
/**
* Do what Node.js's LOAD_AS_DIRECTORY(X) would do.
*
* @see https://nodejs.org/dist/latest-v9.x/docs/api/modules.html#modules_file_modules
*
* @param uri
* The directory to load.
* @param base
* Not used, only forwarded to
* {@link UrlModuleSourceProvider#loadSource(URI, URI, Object)}.
* @param validator
* Not used, only forwarded to
* {@link UrlModuleSourceProvider#loadSource(URI, URI, Object)}.
* @return
* The module source or null, if the module was not found.
*
* @throws JsonSyntaxException
* Thrown for problems accessing the module's "package.json" file.
* @throws IOException
* See {@link UrlModuleSourceProvider#loadSource(URI, URI, Object)}.
* @throws URISyntaxException
* See {@link UrlModuleSourceProvider#loadSource(URI, URI, Object)}.
*/
private ModuleSource loadAsDirectory(URI uri, URI base, Object validator)
throws JsonSyntaxException, IOException, URISyntaxException {
// lets assume the module is a directory
File directory = new File(uri);
// check if the directory exists and is a directory
if (directory.exists() && directory.isDirectory()) {
// the module source
ModuleSource moduleSource;
// lets assume that there is a "package.json" file in the directory
File packageFile = new File(directory, "package.json"); //$NON-NLS-1$
// check if the there is a "package.json" file in the directory
if (packageFile.exists() && packageFile.isFile()) {
// parse the JSON file
JsonObject json = new JsonParser()
.parse(new String(Files.readAllBytes(packageFile.toPath()))).getAsJsonObject();
// check if the JSON file defines a main JS file
if (json.has("main")) { //$NON-NLS-1$
// get the main JS file, removing the filename extension
String main = FilenameUtils.removeExtension(json.get("main").getAsString()); //$NON-NLS-1$
// load as file
moduleSource = this.loadAsFile(new File(directory, main).toURI(), base, validator);
// check if something was loaded
if (moduleSource != null) {
// return the loaded module source
return moduleSource;
}
}
}
// load as index
moduleSource = this.loadAsFile(new File(directory, "index").toURI(), base, validator); //$NON-NLS-1$
// check if something was loaded
if (moduleSource != null) {
// return the loaded module source
return moduleSource;
}
}
// module not found
return null;
}
/**
* Do what Node.js's require(X) would do.
*
* Case 1 is not supported, you will have to use modules from npmjs.org, re-implementing the core
* core module's functionality. We might want to use Nodeschnaps in the future.
* Case 2 is not supported, paths are always treated as relative paths within the application's
* "commonjs" directory.
* Case 5 additionally tries {@link UrlModuleSourceProvider#loadSource(URI, URI, Object)}, even if it is
* very unlikely that something, which hasn't been tried yet, will be done. One could say we are just
* delegating throwing the error.
*
* @see https://nodejs.org/dist/latest-v9.x/docs/api/modules.html#modules_file_modules
* @see https://github.com/killmag10/nodeschnaps
*/
protected ModuleSource loadFromUri(URI uri, URI base, Object validator)
throws IOException, URISyntaxException {
// the module source
ModuleSource moduleSource;
// load as file
moduleSource = this.loadAsFile(uri, base, validator);
// check if something was loaded
if (moduleSource != null) {
// return the loaded module source
return moduleSource;
}
// load as directory
moduleSource = this.loadAsDirectory(uri, base, validator);
// check if something was loaded
if (moduleSource != null) {
// return the loaded module source
return moduleSource;
}
// do what would have been done anyways
return super.loadFromUri(uri, base, validator);
}
}

View file

@ -29,6 +29,8 @@ import java.io.UnsupportedEncodingException;
*/
public class PathWrapper extends ScriptableObject {
private static final long serialVersionUID = 514381479839863014L;
RequestPath path;
RhinoCore core;
@ -44,7 +46,7 @@ public class PathWrapper extends ScriptableObject {
setParentScope(core.getScope());
setPrototype(null);
defineProperty("length", PathWrapper.class, DONTENUM | READONLY | PERMANENT);
defineFunctionProperties(new String[] {"href", "contains"},
defineFunctionProperties(new String[] {"href", "contains"},
PathWrapper.class, DONTENUM | PERMANENT);
}
@ -127,7 +129,7 @@ public class PathWrapper extends ScriptableObject {
return path.href(null);
}
/**
* Checks if the given object is contained in the request path
*
@ -137,7 +139,7 @@ public class PathWrapper extends ScriptableObject {
public int contains(Object obj) {
if (obj instanceof Wrapper)
obj = ((Wrapper) obj).unwrap();
return path.contains(obj);
return path.indexOf(obj);
}
public String getClassName() {
@ -147,7 +149,7 @@ public class PathWrapper extends ScriptableObject {
public String toString() {
return "PathWrapper["+path.toString()+"]";
}
/**
* Return a primitive representation for this object.
* FIXME: We always return a string representation.
@ -158,4 +160,4 @@ public class PathWrapper extends ScriptableObject {
public Object getDefaultValue(Class hint) {
return toString();
}
}
}

View file

@ -44,7 +44,7 @@ import org.mozilla.javascript.Undefined;
import org.mozilla.javascript.WrapFactory;
import org.mozilla.javascript.Wrapper;
import org.mozilla.javascript.commonjs.module.RequireBuilder;
import org.mozilla.javascript.commonjs.module.provider.*;
import org.mozilla.javascript.commonjs.module.provider.StrongCachingModuleScriptProvider;
import org.mozilla.javascript.tools.debugger.ScopeProvider;
import java.io.*;
@ -175,9 +175,11 @@ public final class RhinoCore implements ScopeProvider {
}
}
// install the global require() function using our custom modules provider, so that
// CommonJS-style as well as NodeJS-style modules can be required
new RequireBuilder()
.setModuleScriptProvider(new StrongCachingModuleScriptProvider(
new UrlModuleSourceProvider(commonJsPaths, null)))
.setModuleScriptProvider(new CompiledOrInterpretedModuleScriptProvider(
new NodeModulesProvider(commonJsPaths, null)))
.setSandboxed(true)
.createRequire(context, global)
.install(global);
@ -1177,6 +1179,8 @@ public final class RhinoCore implements ScopeProvider {
}
class StringTrim extends BaseFunction {
private static final long serialVersionUID = -1515630068911501925L;
public Object call(Context cx, Scriptable scope, Scriptable thisObj, Object[] args) {
String str = thisObj.toString();
return str.trim();
@ -1184,6 +1188,8 @@ public final class RhinoCore implements ScopeProvider {
}
class DateFormat extends BaseFunction {
private static final long serialVersionUID = 4694440247686532087L;
public Object call(Context cx, Scriptable scope, Scriptable thisObj, Object[] args) {
Date date = new Date((long) ScriptRuntime.toNumber(thisObj));
SimpleDateFormat df;
@ -1208,6 +1214,8 @@ public final class RhinoCore implements ScopeProvider {
}
class NumberFormat extends BaseFunction {
private static final long serialVersionUID = -6999409297243210875L;
public Object call(Context cx, Scriptable scope, Scriptable thisObj, Object[] args) {
DecimalFormat df;
if (args.length > 0 && args[0] != Undefined.instance) {

View file

@ -568,6 +568,8 @@ public class RhinoEngine implements ScriptingEngine {
return new GlobalProxy((GlobalObject) obj);
if (obj instanceof ApplicationBean)
return new ScriptBeanProxy("app");
if (obj instanceof Application)
return new ApplicationProxy();
if (obj instanceof RequestBean)
return new ScriptBeanProxy("req");
if (obj instanceof ResponseBean)

View file

@ -35,6 +35,8 @@ public interface SerializationProxy extends Serializable {
* Serialization proxy for app, req, res, path objects.
*/
class ScriptBeanProxy implements SerializationProxy {
private static final long serialVersionUID = -1002489933060844917L;
String name;
ScriptBeanProxy(String name) {
@ -47,15 +49,38 @@ class ScriptBeanProxy implements SerializationProxy {
* @return the object represented by this proxy
*/
public Object getObject(RhinoEngine engine) {
try {
Object object = engine.global.get(name, engine.global);
} catch (Exception e) {
System.out.println(name);
}
return engine.global.get(name, engine.global);
}
}
/**
* Serialization proxy for the application object.
*
* @author Daniel Ruthardt
* @since 20170918
*/
class ApplicationProxy implements SerializationProxy {
private static final long serialVersionUID = -3635418002212260600L;
@Override
public Object getObject(RhinoEngine engine) {
// return the application
return engine.app;
}
}
/**
* Serialization proxy for global scope
*/
class GlobalProxy implements SerializationProxy {
private static final long serialVersionUID = -3200125667487274257L;
boolean shared;
GlobalProxy(GlobalObject scope) {
@ -76,6 +101,8 @@ class GlobalProxy implements SerializationProxy {
* Serialization proxy for various flavors of HopObjects/Nodes
*/
class HopObjectProxy implements SerializationProxy {
private static final long serialVersionUID = -4808579296683836009L;
Object ref;
boolean wrapped = false;

View file

@ -123,6 +123,8 @@ public class HelmaDebugger extends Dim implements TreeSelectionListener {
class DebuggerTreeNode extends DefaultMutableTreeNode {
private static final long serialVersionUID = -5881442554351749706L;
public DebuggerTreeNode(Object obj) {
super(obj);
}
@ -156,6 +158,8 @@ public class HelmaDebugger extends Dim implements TreeSelectionListener {
class DebugGui extends SwingGui {
private static final long serialVersionUID = 8930558796272502640L;
String currentSourceUrl;
public DebugGui(Dim dim, String title) {

View file

@ -40,6 +40,8 @@ import java.lang.reflect.Method;
* An EcmaScript FileIO 'File' object
*/
public class FileObject extends ScriptableObject {
private static final long serialVersionUID = -9098307162306984764L;
File file = null;
Object readerWriter = null;
boolean atEOF = false;

View file

@ -35,6 +35,8 @@ import java.lang.reflect.Method;
* This uses the NetComponent classes from savarese.org (ex oroinc.com).
*/
public class FtpObject extends ScriptableObject {
private static final long serialVersionUID = 3470670009973887555L;
private FTPClient ftpclient;
private String server;
private Exception lastError = null;

View file

@ -150,6 +150,8 @@ public class ImageObject {
}
static class GetInfo extends BaseFunction {
private static final long serialVersionUID = 109556119036857349L;
public Object call(Context cx, Scriptable scope,
Scriptable thisObj, Object[] args) {
if (args.length != 1) {

View file

@ -41,6 +41,8 @@ import javax.mail.internet.MimeUtility;
*/
public class MailObject extends ScriptableObject implements Serializable {
private static final long serialVersionUID = -4834981850233741039L;
public static final int OK = 0;
public static final int SUBJECT = 10;
public static final int TEXT = 11;

View file

@ -43,6 +43,8 @@ import java.util.Vector;
*/
public class XmlRpcObject extends BaseFunction {
private static final long serialVersionUID = 1479373761583135438L;
String url = null;
String method = null;

View file

@ -29,6 +29,7 @@ import java.security.NoSuchAlgorithmException;
import javax.servlet.*;
import javax.servlet.http.*;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.*;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
@ -40,6 +41,8 @@ import org.apache.commons.fileupload.servlet.ServletRequestContext;
*/
public abstract class AbstractServletClient extends HttpServlet {
private static final long serialVersionUID = -6096445259839663680L;
// limit to HTTP uploads per file in kB
int uploadLimit = 1024;
@ -514,9 +517,9 @@ public abstract class AbstractServletClient extends HttpServlet {
checksum[i] = (byte) (n);
n >>>= 8;
}
String etag = "\"" + new String(helma.util.Base64.encode(checksum)) + "\"";
res.setHeader("ETag", etag);
String etagHeader = req.getHeader("If-None-Match");
String etag = "\"" + new String(Base64.encodeBase64(checksum)) + "\""; //$NON-NLS-1$//$NON-NLS-2$
res.setHeader("ETag", etag); //$NON-NLS-1$
String etagHeader = req.getHeader("If-None-Match"); //$NON-NLS-1$
if (etagHeader != null) {
StringTokenizer st = new StringTokenizer(etagHeader, ", \r\n");
while (st.hasMoreTokens()) {

View file

@ -26,6 +26,8 @@ import javax.servlet.*;
* web server
*/
public final class EmbeddedServletClient extends AbstractServletClient {
private static final long serialVersionUID = -1716809853688477356L;
private Application app = null;
private String appName;

View file

@ -39,6 +39,8 @@ import java.util.*;
* </ul>
*/
public final class StandaloneServletClient extends AbstractServletClient {
private static final long serialVersionUID = 6515895361950250466L;
private Application app = null;
private String appName;
private String appDir;

View file

@ -1,286 +0,0 @@
//////////////////////license & copyright header/////////////////////////
// //
// Base64 - encode/decode data using the Base64 encoding scheme //
// //
// Copyright (c) 1998 by Kevin Kelley //
// //
// 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., 59 Temple Place - Suite 330, Boston, MA //
// 02111-1307, USA, or contact the author: //
// //
// Kevin Kelley <kelley@ruralnet.net> - 30718 Rd. 28, La Junta, CO, //
// 81050 USA. //
// //
////////////////////end license & copyright header///////////////////////
package helma.util;
import java.io.*; // needed only for main() method.
/**
* Provides encoding of raw bytes to base64-encoded characters, and
* decoding of base64 characters to raw bytes.
*
* @author Kevin Kelley (kelley@ruralnet.net)
* @version 1.3
* date 06 August 1998
* modified 14 February 2000
* modified 22 September 2000
*/
public class Base64 {
/**
* returns an array of base64-encoded characters to represent the
* passed data array.
*
* @param data the array of bytes to encode
* @return base64-coded character array.
*/
static public char[] encode(byte[] data)
{
char[] out = new char[((data.length + 2) / 3) * 4];
//
// 3 bytes encode to 4 chars. Output is always an even
// multiple of 4 characters.
//
for (int i=0, index=0; i<data.length; i+=3, index+=4) {
boolean quad = false;
boolean trip = false;
int val = (0xFF & (int) data[i]);
val <<= 8;
if ((i+1) < data.length) {
val |= (0xFF & (int) data[i+1]);
trip = true;
}
val <<= 8;
if ((i+2) < data.length) {
val |= (0xFF & (int) data[i+2]);
quad = true;
}
out[index+3] = alphabet[(quad? (val & 0x3F): 64)];
val >>= 6;
out[index+2] = alphabet[(trip? (val & 0x3F): 64)];
val >>= 6;
out[index+1] = alphabet[val & 0x3F];
val >>= 6;
out[index+0] = alphabet[val & 0x3F];
}
return out;
}
/**
* Decodes a BASE-64 encoded stream to recover the original
* data. White space before and after will be trimmed away,
* but no other manipulation of the input will be performed.
*
* As of version 1.2 this method will properly handle input
* containing junk characters (newlines and the like) rather
* than throwing an error. It does this by pre-parsing the
* input and generating from that a count of VALID input
* characters.
**/
static public byte[] decode(char[] data)
{
// as our input could contain non-BASE64 data (newlines,
// whitespace of any sort, whatever) we must first adjust
// our count of USABLE data so that...
// (a) we don't misallocate the output array, and
// (b) think that we miscalculated our data length
// just because of extraneous throw-away junk
int tempLen = data.length;
for( int ix=0; ix<data.length; ix++ )
{
if( (data[ix] > 255) || codes[ data[ix] ] < 0 )
--tempLen; // ignore non-valid chars and padding
}
// calculate required length:
// -- 3 bytes for every 4 valid base64 chars
// -- plus 2 bytes if there are 3 extra base64 chars,
// or plus 1 byte if there are 2 extra.
int len = (tempLen / 4) * 3;
if ((tempLen % 4) == 3) len += 2;
if ((tempLen % 4) == 2) len += 1;
byte[] out = new byte[len];
int shift = 0; // # of excess bits stored in accum
int accum = 0; // excess bits
int index = 0;
// we now go through the entire array (NOT using the 'tempLen' value)
for (int ix=0; ix<data.length; ix++)
{
int value = (data[ix]>255)? -1: codes[ data[ix] ];
if ( value >= 0 ) // skip over non-code
{
accum <<= 6; // bits shift up by 6 each time thru
shift += 6; // loop, with new bits being put in
accum |= value; // at the bottom.
if ( shift >= 8 ) // whenever there are 8 or more shifted in,
{
shift -= 8; // write them out (from the top, leaving any
out[index++] = // excess at the bottom for next iteration.
(byte) ((accum >> shift) & 0xff);
}
}
// we will also have skipped processing a padding null byte ('=') here;
// these are used ONLY for padding to an even length and do not legally
// occur as encoded data. for this reason we can ignore the fact that
// no index++ operation occurs in that special case: the out[] array is
// initialized to all-zero bytes to start with and that works to our
// advantage in this combination.
}
// if there is STILL something wrong we just have to throw up now!
if( index != out.length)
{
throw new Error("Miscalculated data length (wrote " + index + " instead of " + out.length + ")");
}
return out;
}
//
// code characters for values 0..63
//
static private char[] alphabet =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
.toCharArray();
//
// lookup table for converting base64 characters to value in range 0..63
//
static private byte[] codes = new byte[256];
static {
for (int i=0; i<256; i++) codes[i] = -1;
for (int i = 'A'; i <= 'Z'; i++) codes[i] = (byte)( i - 'A');
for (int i = 'a'; i <= 'z'; i++) codes[i] = (byte)(26 + i - 'a');
for (int i = '0'; i <= '9'; i++) codes[i] = (byte)(52 + i - '0');
codes['+'] = 62;
codes['/'] = 63;
}
///////////////////////////////////////////////////
// remainder (main method and helper functions) is
// for testing purposes only, feel free to clip it.
///////////////////////////////////////////////////
public static void main(String[] args)
{
boolean decode = false;
if (args.length == 0) {
System.out.println("usage: java Base64 [-d[ecode]] filename");
System.exit(0);
}
for (int i=0; i<args.length; i++) {
if ("-decode".equalsIgnoreCase(args[i])) decode = true;
else if ("-d".equalsIgnoreCase(args[i])) decode = true;
}
String filename = args[args.length-1];
File file = new File(filename);
if (!file.exists()) {
System.out.println("Error: file '" + filename + "' doesn't exist!");
System.exit(0);
}
if (decode)
{
char[] encoded = readChars(file);
byte[] decoded = decode(encoded);
writeBytes(file, decoded);
}
else
{
byte[] decoded = readBytes(file);
char[] encoded = encode(decoded);
writeChars(file, encoded);
}
}
private static byte[] readBytes(File file)
{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try
{
InputStream fis = new FileInputStream(file);
InputStream is = new BufferedInputStream(fis);
int count = 0;
byte[] buf = new byte[16384];
while ((count=is.read(buf)) != -1) {
if (count > 0) baos.write(buf, 0, count);
}
is.close();
}
catch (Exception e) { e.printStackTrace(); }
return baos.toByteArray();
}
private static char[] readChars(File file)
{
CharArrayWriter caw = new CharArrayWriter();
try
{
Reader fr = new FileReader(file);
Reader in = new BufferedReader(fr);
int count = 0;
char[] buf = new char[16384];
while ((count=in.read(buf)) != -1) {
if (count > 0) caw.write(buf, 0, count);
}
in.close();
}
catch (Exception e) { e.printStackTrace(); }
return caw.toCharArray();
}
private static void writeBytes(File file, byte[] data) {
try {
OutputStream fos = new FileOutputStream(file);
OutputStream os = new BufferedOutputStream(fos);
os.write(data);
os.close();
}
catch (Exception e) { e.printStackTrace(); }
}
private static void writeChars(File file, char[] data) {
try {
Writer fos = new FileWriter(file);
Writer os = new BufferedWriter(fos);
os.write(data);
os.close();
}
catch (Exception e) { e.printStackTrace(); }
}
///////////////////////////////////////////////////
// end of test code.
///////////////////////////////////////////////////
}

View file

@ -1,128 +0,0 @@
/*
* 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-2003 Helma Software. All Rights Reserved.
*
* $RCSfile$
* $Author$
* $Revision$
* $Date$
*/
package helma.util;
import java.io.*;
import java.util.*;
/**
* This file authenticates against a passwd file
*/
public class CryptFile {
private Properties users;
private CryptFile parentFile;
private File file;
private long lastRead = 0;
/**
* Creates a new CryptFile object.
*
* @param file ...
* @param parentFile ...
*/
public CryptFile(File file, CryptFile parentFile) {
this.file = file;
this.parentFile = parentFile;
users = new Properties();
}
/**
*
*
* @param username ...
* @param pw ...
*
* @return ...
*/
public boolean authenticate(String username, String pw) {
if (file.exists() && (file.lastModified() > lastRead)) {
readFile();
} else if (!file.exists() && (users.size() > 0)) {
users.clear();
}
String realpw = users.getProperty(username);
if (realpw != null) {
try {
// check if password matches
// first we try with unix crypt algorithm
String cryptpw = Crypt.crypt(realpw, pw);
if (realpw.equals(cryptpw)) {
return true;
}
// then try MD5
if (realpw.equals(MD5Encoder.encode(pw))) {
return true;
}
} catch (Exception x) {
return false;
}
} else {
if (parentFile != null) {
return parentFile.authenticate(username, pw);
}
}
return false;
}
private synchronized void readFile() {
BufferedReader reader = null;
users = new Properties();
try {
reader = new BufferedReader(new FileReader(file));
String line = reader.readLine();
while (line != null) {
StringTokenizer st = new StringTokenizer(line, ":");
if (st.countTokens() > 1) {
users.put(st.nextToken(), st.nextToken());
}
line = reader.readLine();
}
} catch (Exception ignore) {
} finally {
if (reader != null) {
try {
reader.close();
} catch (Exception x) {
}
}
lastRead = System.currentTimeMillis();
}
}
/**
*
*
* @param args ...
*/
public static void main(String[] args) {
CryptFile cf = new CryptFile(new File("passwd"), null);
System.err.println(cf.authenticate("hns", "asdf"));
}
}

View file

@ -20,6 +20,9 @@ import java.io.BufferedReader;
import java.io.StringReader;
import java.util.Properties;
import java.util.StringTokenizer;
import org.apache.commons.codec.digest.DigestUtils;
import helma.framework.repository.Resource;
import helma.framework.repository.Resource;
@ -73,7 +76,7 @@ public class CryptResource {
}
// then try MD5
if (realpw.equals(MD5Encoder.encode(pw))) {
if (realpw.equals(DigestUtils.md5(pw))) {
return true;
}
} catch (Exception x) {

View file

@ -1,107 +0,0 @@
/*
* 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-2003 Helma Software. All Rights Reserved.
*
* $RCSfile$
* $Author$
* $Revision$
* $Date$
*/
package helma.util;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
/**
*
*/
public class MD5Encoder {
private static MessageDigest md;
/** used by commandline script to create admin username & password */
public static void main(String[] args) throws Exception {
if (args.length < 2) {
System.out.println("\n\nUsage: helma.util.MD5Encoder <username> <password>");
System.out.println("Output:");
System.out.println("adminUsername=<encoded username>");
System.out.println("adminPassword=<encoded password>\n");
System.exit(0);
}
System.out.println("adminUsername=" + encode(args[0]));
System.out.println("adminPassword=" + encode(args[1]));
}
/**
*
*
* @param str ...
*
* @return ...
*
* @throws NoSuchAlgorithmException ...
*/
public static String encode(String str) throws NoSuchAlgorithmException {
return encode(str.getBytes());
}
/**
*
*
* @param message ...
*
* @return ...
*
* @throws NoSuchAlgorithmException ...
*/
public static String encode(byte[] message) throws NoSuchAlgorithmException {
md = MessageDigest.getInstance("MD5");
byte[] b = md.digest(message);
StringBuffer buf = new StringBuffer(b.length * 2);
for (int i = 0; i < b.length; i++) {
int j = (b[i] < 0) ? (256 + b[i]) : b[i];
if (j < 16) {
buf.append("0");
}
buf.append(Integer.toHexString(j));
}
return buf.toString();
}
/**
* Convert a long to a byte array.
*/
public static byte[] toBytes(long n) {
byte[] b = new byte[8];
b[0] = (byte) (n);
n >>>= 8;
b[1] = (byte) (n);
n >>>= 8;
b[2] = (byte) (n);
n >>>= 8;
b[3] = (byte) (n);
n >>>= 8;
b[4] = (byte) (n);
n >>>= 8;
b[5] = (byte) (n);
n >>>= 8;
b[6] = (byte) (n);
n >>>= 8;
b[7] = (byte) (n);
return b;
}
}

View file

@ -26,6 +26,8 @@ import java.util.StringTokenizer;
* This represents a MIME part of a HTTP file upload
*/
public class MimePart implements Serializable {
private static final long serialVersionUID = 7800159441938112415L;
private final String name;
private int contentLength;
private String contentType;

View file

@ -28,6 +28,8 @@ import helma.framework.repository.Repository;
*/
public class ResourceProperties extends Properties {
private static final long serialVersionUID = -2258056784572269727L;
// Delay between checks
private final long CACHE_TIME = 1500L;
@ -142,7 +144,7 @@ public class ResourceProperties extends Properties {
this.parentProperties = parentProperties;
this.prefix = prefix;
resources = new LinkedHashSet();
setIgnoreCase(parentProperties.ignoreCase);
setIgnoreCase(parentProperties.ignoreCase);
forceUpdate();
}
@ -481,7 +483,7 @@ public class ResourceProperties extends Properties {
* @param value value
* @return the old value, if an old value got replaced
*/
public Object put(Object key, Object value) {
public synchronized Object put(Object key, Object value) {
if (value instanceof String) {
value = ((String) value).trim();
}
@ -497,7 +499,7 @@ public class ResourceProperties extends Properties {
* @param key key
* @return the old value
*/
public Object remove(Object key) {
public synchronized Object remove(Object key) {
String strkey = key.toString();
if (ignoreCase) {
strkey = (String) keyMap.remove(strkey.toLowerCase());

View file

@ -27,6 +27,8 @@ import java.util.*;
public class SystemMap extends HashMap {
private static final long serialVersionUID = 2926260006469380544L;
/**
* Construct an empty SystemMap.
*/

View file

@ -25,6 +25,8 @@ import java.util.*;
*/
public final class SystemProperties extends Properties {
private static final long serialVersionUID = -6994562125444162183L;
final static long cacheTime = 1500L;
private SystemProperties defaultProps; // the default/fallback properties.
private File file; // the underlying properties file from which we read.
@ -197,7 +199,7 @@ public final class SystemProperties extends Properties {
* This should not be used directly if properties are read from file,
* otherwise changes will be lost whe the file is next modified.
*/
public Object put(Object key, Object value) {
public synchronized Object put(Object key, Object value) {
// cut off trailing whitespace
if (value != null) {
value = value.toString().trim();
@ -209,7 +211,7 @@ public final class SystemProperties extends Properties {
/**
* Overrides method to act on the wrapped properties object.
*/
public Object get(Object key) {
public synchronized Object get(Object key) {
if ((System.currentTimeMillis() - lastcheck) > cacheTime) {
checkFile();
}
@ -220,14 +222,14 @@ public final class SystemProperties extends Properties {
/**
* Overrides method to act on the wrapped properties object.
*/
public Object remove(Object key) {
public synchronized Object remove(Object key) {
return super.remove(ignoreCase ? key.toString().toLowerCase() : key);
}
/**
* Overrides method to act on the wrapped properties object.
*/
public boolean contains(Object obj) {
public synchronized boolean contains(Object obj) {
if ((System.currentTimeMillis() - lastcheck) > cacheTime) {
checkFile();
}
@ -238,7 +240,7 @@ public final class SystemProperties extends Properties {
/**
* Overrides method to act on the wrapped properties object.
*/
public boolean containsKey(Object key) {
public synchronized boolean containsKey(Object key) {
if ((System.currentTimeMillis() - lastcheck) > cacheTime) {
checkFile();
}
@ -249,7 +251,7 @@ public final class SystemProperties extends Properties {
/**
* Overrides method to act on the wrapped properties object.
*/
public boolean isEmpty() {
public synchronized boolean isEmpty() {
if ((System.currentTimeMillis() - lastcheck) > cacheTime) {
checkFile();
}
@ -283,7 +285,7 @@ public final class SystemProperties extends Properties {
/**
* Overrides method to act on the wrapped properties object.
*/
public Enumeration keys() {
public synchronized Enumeration keys() {
if ((System.currentTimeMillis() - lastcheck) > cacheTime) {
checkFile();
}
@ -305,7 +307,7 @@ public final class SystemProperties extends Properties {
/**
* Overrides method to act on the wrapped properties object.
*/
public Enumeration elements() {
public synchronized Enumeration elements() {
if ((System.currentTimeMillis() - lastcheck) > cacheTime) {
checkFile();
}
@ -316,7 +318,7 @@ public final class SystemProperties extends Properties {
/**
* Overrides method to act on the wrapped properties object.
*/
public int size() {
public synchronized int size() {
if ((System.currentTimeMillis() - lastcheck) > cacheTime) {
checkFile();
}
@ -327,7 +329,7 @@ public final class SystemProperties extends Properties {
/**
* Overrides method to act on the wrapped properties object.
*/
public String toString() {
public synchronized String toString() {
return super.toString();
}