Merged changes from helma_1_2 (between helma_1_2_5 and helma_1_2_5_merge_1)
This commit is contained in:
parent
61b8a4a35a
commit
fd2882e21d
7 changed files with 130 additions and 38 deletions
|
@ -140,9 +140,9 @@ public final class Application implements IPathElement, Runnable {
|
|||
// the name under which this app serves XML-RPC requests. Defaults to the app name
|
||||
private String xmlrpcHandlerName;
|
||||
|
||||
// the list of cron jobs
|
||||
// the list of currently active cron jobs
|
||||
private Map activeCronJobs = null;
|
||||
private Vector cronJobs = null;
|
||||
// the list of custom cron jobs
|
||||
Hashtable customCronJobs = null;
|
||||
|
||||
/**
|
||||
|
@ -342,7 +342,7 @@ public final class Application implements IPathElement, Runnable {
|
|||
public void start() {
|
||||
starttime = System.currentTimeMillis();
|
||||
worker = new Thread(this, "Worker-" + name);
|
||||
// worker.setPriority(Thread.NORM_PRIORITY + 2);
|
||||
worker.setPriority(Thread.NORM_PRIORITY + 1);
|
||||
worker.start();
|
||||
|
||||
// logEvent ("session cleanup and scheduler thread started");
|
||||
|
@ -1328,6 +1328,10 @@ public final class Application implements IPathElement, Runnable {
|
|||
}
|
||||
}
|
||||
|
||||
// loop-local cron job data
|
||||
List cronJobs = null;
|
||||
long lastCronParse = 0;
|
||||
|
||||
while (Thread.currentThread() == worker) {
|
||||
|
||||
long now = System.currentTimeMillis();
|
||||
|
@ -1374,13 +1378,14 @@ public final class Application implements IPathElement, Runnable {
|
|||
}
|
||||
}
|
||||
|
||||
if ((cronJobs == null) || (props.lastModified() > lastPropertyRead)) {
|
||||
if ((cronJobs == null) || (props.lastModified() > lastCronParse)) {
|
||||
updateProperties();
|
||||
cronJobs = CronJob.parse(props);
|
||||
lastCronParse = props.lastModified();
|
||||
}
|
||||
|
||||
Date d = new Date();
|
||||
List jobs = (List) cronJobs.clone();
|
||||
List jobs = new ArrayList(cronJobs);
|
||||
|
||||
jobs.addAll(customCronJobs.values());
|
||||
CronJob.sort(jobs);
|
||||
|
@ -1559,6 +1564,9 @@ public final class Application implements IPathElement, Runnable {
|
|||
private synchronized void updateProperties() {
|
||||
// if so property file has been updated, re-read props.
|
||||
if (props.lastModified() > lastPropertyRead) {
|
||||
// force property update
|
||||
props.update();
|
||||
|
||||
// character encoding to be used for responses
|
||||
charset = props.getProperty("charset", "ISO-8859-1");
|
||||
|
||||
|
|
|
@ -378,6 +378,11 @@ public final class TypeManager {
|
|||
for (int i = 0; i < list.length; i++) {
|
||||
String fn = list[i].getName();
|
||||
|
||||
// ignore files starting with ".".
|
||||
if (fn.startsWith(".")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!proto.updatables.containsKey(fn)) {
|
||||
if (fn.endsWith(templateExtension) || fn.endsWith(scriptExtension) ||
|
||||
fn.endsWith(actionExtension) || fn.endsWith(skinExtension) ||
|
||||
|
|
|
@ -1646,12 +1646,12 @@ public final class Node implements INode, Serializable {
|
|||
}
|
||||
|
||||
// the property does not exist in our propmap - see if we should create it on the fly,
|
||||
// either because it is mapped to an object from relational database or defined as
|
||||
// either because it is mapped to an object from relational database or defined as
|
||||
// collection aka virtual node
|
||||
if ((prop == null) && (dbmap != null)) {
|
||||
Relation propRel = dbmap.getPropertyRelation(propname);
|
||||
|
||||
// if no property relation is defined for this specific property name,
|
||||
// if no property relation is defined for this specific property name,
|
||||
// use the generic property relation, if one is defined.
|
||||
if (propRel == null) {
|
||||
propRel = dbmap.getPropertyRelation();
|
||||
|
@ -1668,12 +1668,8 @@ public final class Node implements INode, Serializable {
|
|||
|
||||
pn.setDbMapping(propRel.getVirtualMapping());
|
||||
pn.setParent(this);
|
||||
if (propRel.needsPersistence()) {
|
||||
setNode(propname, pn);
|
||||
prop = (Property) propMap.get(propname);
|
||||
} else {
|
||||
prop = new Property(propname, this, pn);
|
||||
}
|
||||
setNode(propname, pn);
|
||||
prop = (Property) propMap.get(propname);
|
||||
}
|
||||
// if this is from relational database only fetch if this node
|
||||
// is itself persistent.
|
||||
|
@ -2408,6 +2404,14 @@ public final class Node implements INode, Serializable {
|
|||
IProperty next = get((String) e.nextElement());
|
||||
|
||||
if ((next != null) && (next.getType() == IProperty.NODE)) {
|
||||
// check if this property actually needs to be persisted.
|
||||
if (dbmap != null) {
|
||||
Relation rel = dbmap.getExactPropertyRelation(next.getName());
|
||||
if (rel != null && !rel.needsPersistence()) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
Node n = (Node) next.getNodeValue();
|
||||
|
||||
if ((n != null) && (n.state == TRANSIENT)) {
|
||||
|
|
|
@ -120,7 +120,6 @@ public abstract class AbstractServletClient extends HttpServlet {
|
|||
protected void execute(HttpServletRequest request, HttpServletResponse response,
|
||||
byte method) {
|
||||
RequestTrans reqtrans = new RequestTrans(method);
|
||||
|
||||
// get app and path from original request path
|
||||
// String pathInfo = request.getPathInfo ();
|
||||
// String appID = getAppID (pathInfo);
|
||||
|
@ -236,23 +235,8 @@ public abstract class AbstractServletClient extends HttpServlet {
|
|||
}
|
||||
}
|
||||
|
||||
// check if we need to create a session id. also handle the
|
||||
// case that the session id doesn't match the remote host address
|
||||
if ((reqtrans.session == null) || !reqtrans.session.startsWith(remotehost)) {
|
||||
reqtrans.session = remotehost + "." +
|
||||
Long.toString(Math.round(Math.random() * Long.MAX_VALUE) -
|
||||
System.currentTimeMillis(), 36);
|
||||
|
||||
Cookie c = new Cookie("HopSession", reqtrans.session);
|
||||
|
||||
c.setPath("/");
|
||||
|
||||
if (resCookieDomain != null) {
|
||||
c.setDomain(resCookieDomain);
|
||||
}
|
||||
|
||||
response.addCookie(c);
|
||||
}
|
||||
// check if session cookie is present and valid, creating it if not.
|
||||
checkSessionCookie(request, response, reqtrans, resCookieDomain);
|
||||
|
||||
String browser = request.getHeader("User-Agent");
|
||||
|
||||
|
@ -448,6 +432,52 @@ public abstract class AbstractServletClient extends HttpServlet {
|
|||
return upload.getParts().get(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the session cookie is set and valid for this request.
|
||||
* If not, create a new one.
|
||||
*/
|
||||
private void checkSessionCookie(HttpServletRequest request, HttpServletResponse response,
|
||||
RequestTrans reqtrans, String resCookieDomain) {
|
||||
// check if we need to create a session id. also handle the
|
||||
// case that the session id doesn't match the remote host address
|
||||
StringBuffer b = new StringBuffer();
|
||||
addIPAddress(b, request.getRemoteAddr());
|
||||
addIPAddress(b, request.getHeader("X-Forwarded-For"));
|
||||
addIPAddress(b, request.getHeader("Client-ip"));
|
||||
if ((reqtrans.session == null) || !reqtrans.session.startsWith(b.toString())) {
|
||||
b.append (Long.toString(Math.round(Math.random() * Long.MAX_VALUE) -
|
||||
System.currentTimeMillis(), 36));
|
||||
|
||||
reqtrans.session = b.toString();
|
||||
Cookie c = new Cookie("HopSession", reqtrans.session);
|
||||
|
||||
c.setPath("/");
|
||||
|
||||
if (resCookieDomain != null) {
|
||||
c.setDomain(resCookieDomain);
|
||||
}
|
||||
|
||||
response.addCookie(c);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an the 3 most significant bytes of an IP address to the
|
||||
* session cookie id.
|
||||
*/
|
||||
private void addIPAddress(StringBuffer b, String addr) {
|
||||
if (addr != null) {
|
||||
int cut = addr.lastIndexOf(".");
|
||||
if (cut == -1) {
|
||||
cut = addr.lastIndexOf(":");
|
||||
}
|
||||
if (cut > -1) {
|
||||
b.append(addr.substring(0, cut+1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Put name value pair in map.
|
||||
*
|
||||
|
|
|
@ -87,7 +87,7 @@ public class CronJob {
|
|||
|
||||
private String name = null;
|
||||
private String function = null;
|
||||
private long timeout = 20000;
|
||||
private long timeout = 600000;
|
||||
|
||||
/** A method for parsing properties. It looks through the properties
|
||||
* file for entries that look like this:
|
||||
|
@ -182,7 +182,7 @@ public class CronJob {
|
|||
}
|
||||
|
||||
|
||||
public static Vector parse(Properties props) {
|
||||
public static List parse(Properties props) {
|
||||
Hashtable jobs = new Hashtable ();
|
||||
Enumeration e = props.keys ();
|
||||
while (e.hasMoreElements ()) {
|
||||
|
@ -222,8 +222,8 @@ public class CronJob {
|
|||
} catch (NoSuchElementException nsee) {
|
||||
}
|
||||
}
|
||||
Vector jobVec = new Vector (jobs.values ());
|
||||
return (Vector) sort (jobVec);
|
||||
List jobVec = new ArrayList (jobs.values ());
|
||||
return sort (jobVec);
|
||||
}
|
||||
|
||||
public static List sort (List list) {
|
||||
|
|
|
@ -342,6 +342,11 @@ public final class HtmlEncoder {
|
|||
emptyTags.add("param");
|
||||
}
|
||||
|
||||
final static byte TAG_NAME = 0;
|
||||
final static byte TAG_SPACE = 1;
|
||||
final static byte TAG_ATT_NAME = 2;
|
||||
final static byte TAG_ATT_VAL = 3;
|
||||
|
||||
|
||||
/**
|
||||
* Do "smart" encodging on a string. This means that valid HTML entities and tags,
|
||||
|
@ -397,6 +402,8 @@ public final class HtmlEncoder {
|
|||
|
||||
// are we inside an HTML tag?
|
||||
boolean insideHtmlTag = false;
|
||||
boolean insideCloseTag = false;
|
||||
byte htmlTagMode = TAG_NAME;
|
||||
|
||||
// if we are inside a <code> tag, we encode everything to make
|
||||
// documentation work easier
|
||||
|
@ -445,7 +452,7 @@ public final class HtmlEncoder {
|
|||
}
|
||||
} else if (!insideTag) {
|
||||
// check if this is a HTML tag.
|
||||
boolean insideCloseTag = ('/' == str.charAt(i + 1));
|
||||
insideCloseTag = ('/' == str.charAt(i + 1));
|
||||
int tagStart = insideCloseTag ? (i + 2) : (i + 1);
|
||||
int j = tagStart;
|
||||
|
||||
|
@ -464,6 +471,7 @@ public final class HtmlEncoder {
|
|||
allTags.contains(tagName) && !insideCodeTag) {
|
||||
insideHtmlTag = insideTag = true;
|
||||
htmlQuoteChar = '\u0000';
|
||||
htmlTagMode = TAG_NAME;
|
||||
|
||||
// set ignoreNewline on some tags, depending on wheather they're
|
||||
// being opened or closed.
|
||||
|
@ -610,6 +618,7 @@ public final class HtmlEncoder {
|
|||
escape = false;
|
||||
} else if (htmlQuoteChar == c) {
|
||||
htmlQuoteChar = '\u0000';
|
||||
htmlTagMode = TAG_SPACE;
|
||||
} else if (htmlQuoteChar == '\u0000') {
|
||||
htmlQuoteChar = c;
|
||||
}
|
||||
|
@ -650,7 +659,11 @@ public final class HtmlEncoder {
|
|||
// Check if this is an empty tag so we don't generate an
|
||||
// additional </close> tag.
|
||||
if (str.charAt(i - 1) == '/') {
|
||||
openTags.pop();
|
||||
// this is to avoid misinterpreting tags like
|
||||
// <a href=http://foo/> as empty
|
||||
if (htmlTagMode != TAG_ATT_VAL && htmlTagMode != TAG_ATT_NAME) {
|
||||
openTags.pop();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ret.append(">");
|
||||
|
@ -663,7 +676,32 @@ public final class HtmlEncoder {
|
|||
|
||||
default:
|
||||
|
||||
// ret.append (c);
|
||||
if (insideHtmlTag && !insideCloseTag) {
|
||||
switch(htmlTagMode) {
|
||||
case TAG_NAME:
|
||||
if (!Character.isLetterOrDigit(c)) {
|
||||
htmlTagMode = TAG_SPACE;
|
||||
}
|
||||
break;
|
||||
case TAG_SPACE:
|
||||
if (Character.isLetterOrDigit(c)) {
|
||||
htmlTagMode = TAG_ATT_NAME;
|
||||
}
|
||||
break;
|
||||
case TAG_ATT_NAME:
|
||||
if (c == '=') {
|
||||
htmlTagMode = TAG_ATT_VAL;
|
||||
} else if (c == ' ') {
|
||||
htmlTagMode = TAG_SPACE;
|
||||
}
|
||||
break;
|
||||
case TAG_ATT_VAL:
|
||||
if (Character.isWhitespace(c) && htmlQuoteChar == '\u0000') {
|
||||
htmlTagMode = TAG_SPACE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (c < 128) {
|
||||
ret.append(c);
|
||||
} else if ((c >= 128) && (c < 256)) {
|
||||
|
|
|
@ -101,6 +101,13 @@ public final class SystemProperties extends Properties {
|
|||
return Math.max(file.lastModified(), lastadd);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update/re-read the properties from file if necessary.
|
||||
*/
|
||||
public void update () {
|
||||
checkFile();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a checksum that changes when something in the properties changes.
|
||||
*/
|
||||
|
|
Loading…
Add table
Reference in a new issue