Merge from helma_1_2_4
This commit is contained in:
parent
df40e73b63
commit
66663c8b20
177 changed files with 28899 additions and 18112 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
build/antclick/data/062SYS_INFO_sUSRSequenceInfo.koi
Normal file
BIN
build/antclick/data/062SYS_INFO_sUSRSequenceInfo.koi
Normal file
Binary file not shown.
BIN
build/antclick/data/063SYS_INFO_sUSRSequence.koi
Normal file
BIN
build/antclick/data/063SYS_INFO_sUSRSequence.koi
Normal file
Binary file not shown.
BIN
build/antclick/data/064SYS_INFO_sUSRPKeyInfo.koi
Normal file
BIN
build/antclick/data/064SYS_INFO_sUSRPKeyInfo.koi
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
build/antclick/data/071SYS_INFO_sUSRSchemaInfo.koi
Normal file
BIN
build/antclick/data/071SYS_INFO_sUSRSchemaInfo.koi
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
build/antclick/data/076SYS_INFO_sUSRGrant.koi
Normal file
BIN
build/antclick/data/076SYS_INFO_sUSRGrant.koi
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
build/antclick/data/079SYS_INFO_sUSRFunction.koi
Normal file
BIN
build/antclick/data/079SYS_INFO_sUSRFunction.koi
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
build/antclick/data/082SYS_INFO_sUSRDataTrigger.koi
Normal file
BIN
build/antclick/data/082SYS_INFO_sUSRDataTrigger.koi
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
build/antclick/data/086APP_AV_IMAGE.koi
Normal file
BIN
build/antclick/data/086APP_AV_IMAGE.koi
Normal file
Binary file not shown.
Binary file not shown.
BIN
build/antclick/data/088APP_AV_POLL.koi
Normal file
BIN
build/antclick/data/088APP_AV_POLL.koi
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
build/antclick/data/096APP_AV_TEXT.koi
Normal file
BIN
build/antclick/data/096APP_AV_TEXT.koi
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
build/antclick/data/DefaultDatabase_sf.koi
Normal file
BIN
build/antclick/data/DefaultDatabase_sf.koi
Normal file
Binary file not shown.
Binary file not shown.
|
@ -8,7 +8,7 @@
|
|||
<target name="init">
|
||||
<property name="Name" value="helma"/>
|
||||
<property name="year" value="1998-${year}"/>
|
||||
<property name="version" value="1.2.3"/>
|
||||
<property name="version" value="1.3cvs"/>
|
||||
<property name="project" value="helma"/>
|
||||
<property name="build.compiler" value="classic"/>
|
||||
|
||||
|
@ -28,8 +28,8 @@
|
|||
|
||||
<property name="jar.name" value="${project}"/>
|
||||
<property name="package.name" value="${project}-${version}"/>
|
||||
<property name="antclick.name" value="antclick-1.0pre5"/>
|
||||
<property name="antville.name" value="antville-1.0pre1"/>
|
||||
<property name="antclick.name" value="antclick-1.0cvs"/>
|
||||
<property name="antville.name" value="antville-1.0cvs"/>
|
||||
|
||||
<property name="debug" value="on"/>
|
||||
<property name="optimize" value="on"/>
|
||||
|
|
Binary file not shown.
|
@ -1,23 +1,72 @@
|
|||
/*
|
||||
* 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.doc;
|
||||
|
||||
import helma.framework.IPathElement;
|
||||
import helma.main.Server;
|
||||
import helma.util.SystemProperties;
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class DocApplication extends DocDirElement {
|
||||
HashSet excluded;
|
||||
|
||||
public static void main (String args[]) {
|
||||
/**
|
||||
* Creates a new DocApplication object.
|
||||
*
|
||||
* @param name ...
|
||||
* @param location ...
|
||||
*
|
||||
* @throws DocException ...
|
||||
*/
|
||||
public DocApplication(String name, File location) throws DocException {
|
||||
super(name, location, APPLICATION);
|
||||
readProps();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new DocApplication object.
|
||||
*
|
||||
* @param name ...
|
||||
* @param appDir ...
|
||||
*
|
||||
* @throws DocException ...
|
||||
*/
|
||||
public DocApplication(String name, String appDir) throws DocException {
|
||||
super(name, new File(appDir), APPLICATION);
|
||||
readProps();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param args ...
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
// DocApplication app;
|
||||
// app = new DocApplication (args[0], args[1]);
|
||||
// app.readApplication ();
|
||||
|
||||
// DocPrototype el = DocPrototype.newInstance (new File(args[0]));
|
||||
// el.readFiles ();
|
||||
|
||||
// DocFunction func = DocFunction.newTemplate (new File(args[0]));
|
||||
// DocFunction func = DocFunction.newAction (new File(args[0]));
|
||||
|
||||
DocFunction[] func = DocFunction.newFunctions(new File(args[0]));
|
||||
|
||||
// DocSkin skin = DocSkin.newInstance (new File (args[0]));
|
||||
|
@ -25,53 +74,109 @@ public class DocApplication extends DocDirElement {
|
|||
// System.out.println ("\n\n\ncomment = " + func.getComment ());
|
||||
}
|
||||
|
||||
/**
|
||||
* reads the app.properties file and parses for helma.excludeDocs
|
||||
*/
|
||||
private void readProps() {
|
||||
File propsFile = new File(location, "app.properties");
|
||||
SystemProperties serverProps = Server.getServer().getProperties();
|
||||
SystemProperties appProps = new SystemProperties(propsFile.getAbsolutePath(),
|
||||
serverProps);
|
||||
|
||||
public DocApplication (String name, File location) throws DocException {
|
||||
super (name, location, APPLICATION);
|
||||
excluded = new HashSet();
|
||||
addExclude("cvs");
|
||||
addExclude(".docs");
|
||||
|
||||
String excludeProps = appProps.getProperty("helma.excludeDocs");
|
||||
|
||||
if (excludeProps != null) {
|
||||
StringTokenizer tok = new StringTokenizer(excludeProps, ",");
|
||||
|
||||
while (tok.hasMoreTokens()) {
|
||||
String str = tok.nextToken().trim();
|
||||
|
||||
addExclude(str);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public DocApplication (String name, String appDir) throws DocException {
|
||||
super (name, new File (appDir), APPLICATION);
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param str ...
|
||||
*/
|
||||
public void addExclude(String str) {
|
||||
excluded.add(str.toLowerCase());
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param str ...
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public boolean isExcluded(String str) {
|
||||
return (excluded.contains(str.toLowerCase()));
|
||||
}
|
||||
|
||||
/**
|
||||
* reads all prototypes and files of the application
|
||||
*/
|
||||
public void readApplication() {
|
||||
String arr[] = location.list ();
|
||||
readProps();
|
||||
|
||||
String[] arr = location.list();
|
||||
|
||||
children.clear();
|
||||
|
||||
for (int i = 0; i < arr.length; i++) {
|
||||
if (Util.isExcluded (arr[i]))
|
||||
if (isExcluded(arr[i])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
File f = new File(location.getAbsolutePath(), arr[i]);
|
||||
if (!f.isDirectory ())
|
||||
|
||||
if (!f.isDirectory()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
DocPrototype pt = DocPrototype.newInstance(f, this);
|
||||
|
||||
addChild(pt);
|
||||
pt.readFiles();
|
||||
} catch (DocException e) {
|
||||
debug("Couldn't read prototype " + arr[i] + ": " + e.getMessage());
|
||||
}
|
||||
|
||||
System.out.println(f);
|
||||
}
|
||||
|
||||
for (Iterator i = children.values().iterator(); i.hasNext();) {
|
||||
((DocPrototype) i.next()).checkInheritance();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public DocElement[] listFunctions() {
|
||||
Vector allFunctions = new Vector();
|
||||
|
||||
for (Iterator i = children.values().iterator(); i.hasNext();) {
|
||||
DocElement proto = (DocElement) i.next();
|
||||
|
||||
allFunctions.addAll(proto.children.values());
|
||||
}
|
||||
|
||||
Collections.sort(allFunctions, new DocComparator(DocComparator.BY_NAME, this));
|
||||
|
||||
return (DocElement[]) allFunctions.toArray(new DocElement[allFunctions.size()]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* from helma.framework.IPathElement, overridden with "api"
|
||||
* to work in manage-application
|
||||
|
@ -80,19 +185,13 @@ public class DocApplication extends DocDirElement {
|
|||
return "api";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* from helma.framework.IPathElement, overridden with
|
||||
* Server.getServer() to work in manage-application
|
||||
*/
|
||||
public IPathElement getParentElement() {
|
||||
Server s = helma.main.Server.getServer();
|
||||
|
||||
return s.getChildElement(this.name);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,44 +1,88 @@
|
|||
/*
|
||||
* 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.doc;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class DocComparator implements Comparator {
|
||||
|
||||
public static final int BY_TYPE = 0;
|
||||
public static final int BY_NAME = 1;
|
||||
|
||||
int mode;
|
||||
DocElement docEl;
|
||||
|
||||
/**
|
||||
* Creates a new DocComparator object.
|
||||
*
|
||||
* @param mode ...
|
||||
* @param docEl ...
|
||||
*/
|
||||
public DocComparator(int mode, DocElement docEl) {
|
||||
this.mode = mode;
|
||||
this.docEl = docEl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new DocComparator object.
|
||||
*
|
||||
* @param docEl ...
|
||||
*/
|
||||
public DocComparator(DocElement docEl) {
|
||||
this.mode = 0;
|
||||
this.docEl = docEl;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param obj1 ...
|
||||
* @param obj2 ...
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public int compare(Object obj1, Object obj2) {
|
||||
DocElement e1 = (DocElement) obj1;
|
||||
DocElement e2 = (DocElement) obj2;
|
||||
if (mode==BY_TYPE && e1.getType()>e2.getType())
|
||||
|
||||
if ((mode == BY_TYPE) && (e1.getType() > e2.getType())) {
|
||||
return 1;
|
||||
else if (mode==BY_TYPE && e1.getType()<e2.getType())
|
||||
} else if ((mode == BY_TYPE) && (e1.getType() < e2.getType())) {
|
||||
return -1;
|
||||
else {
|
||||
} else {
|
||||
return e1.name.compareTo(e2.name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param obj ...
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public boolean equals(Object obj) {
|
||||
DocElement el = (DocElement) obj;
|
||||
if (el.name.equals(docEl.name) && el.getType()==docEl.getType()) {
|
||||
|
||||
if (el.name.equals(docEl.name) && (el.getType() == docEl.getType())) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,19 +1,35 @@
|
|||
/*
|
||||
* 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.doc;
|
||||
|
||||
import FESI.Parser.*;
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
import FESI.Parser.*;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public abstract class DocDirElement extends DocElement {
|
||||
|
||||
// a default file that is read as comment for applications
|
||||
// and prototypes if found in their directories
|
||||
public static final String[] DOCFILES = {
|
||||
"doc.html", "doc.htm",
|
||||
"app.html", "app.htm",
|
||||
"prototype.html", "prototype.htm",
|
||||
"index.html", "index.htm"
|
||||
"doc.html", "doc.htm", "app.html",
|
||||
"app.htm", "prototype.html",
|
||||
"prototype.htm", "index.html", "index.htm"
|
||||
};
|
||||
|
||||
protected DocDirElement(String name, File location, int type) {
|
||||
|
@ -24,13 +40,14 @@ public abstract class DocDirElement extends DocElement {
|
|||
private void checkCommentFiles() throws DocException {
|
||||
for (int i = 0; i < DOCFILES.length; i++) {
|
||||
File f = new File(location, DOCFILES[i]);
|
||||
|
||||
if (f.exists()) {
|
||||
String rawComment = readFile(f);
|
||||
|
||||
parseComment(rawComment);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -1,11 +1,44 @@
|
|||
/*
|
||||
* 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.doc;
|
||||
|
||||
import helma.framework.IPathElement;
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
import helma.framework.IPathElement;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public abstract class DocElement implements IPathElement {
|
||||
public static final int APPLICATION = 0;
|
||||
public static final int PROTOTYPE = 1;
|
||||
public static final int ACTION = 2;
|
||||
public static final int TEMPLATE = 3;
|
||||
public static final int FUNCTION = 4;
|
||||
public static final int MACRO = 5;
|
||||
public static final int SKIN = 6;
|
||||
public static final int PROPERTIES = 7;
|
||||
|
||||
// above constants are used as array indices
|
||||
public static final String[] typeNames = {
|
||||
"Application", "Prototype", "Action",
|
||||
"Template", "Function", "Macro", "Skin",
|
||||
"Properties"
|
||||
};
|
||||
|
||||
// identifiers of this element
|
||||
String name;
|
||||
|
@ -20,34 +53,17 @@ public abstract class DocElement implements IPathElement {
|
|||
List tags = new Vector();
|
||||
List parameters = new Vector();
|
||||
|
||||
public static final int APPLICATION = 0;
|
||||
public static final int PROTOTYPE = 1;
|
||||
public static final int ACTION = 2;
|
||||
public static final int TEMPLATE = 3;
|
||||
public static final int FUNCTION = 4;
|
||||
public static final int MACRO = 5;
|
||||
public static final int SKIN = 6;
|
||||
public static final int PROPERTIES = 7;
|
||||
|
||||
// above constants are used as array indices
|
||||
public static final String[] typeNames = {
|
||||
"Application",
|
||||
"Prototype",
|
||||
"Action",
|
||||
"Template",
|
||||
"Function",
|
||||
"Macro",
|
||||
"Skin",
|
||||
"Properties"
|
||||
};
|
||||
|
||||
protected DocElement (String name, String location, int type) throws DocException {
|
||||
protected DocElement(String name, String location, int type)
|
||||
throws DocException {
|
||||
this(name, new File(location), type);
|
||||
}
|
||||
|
||||
protected DocElement (String name, File location, int type) throws DocException {
|
||||
if (location.exists()==false)
|
||||
protected DocElement(String name, File location, int type)
|
||||
throws DocException {
|
||||
if (location.exists() == false) {
|
||||
throw new DocException(name + " not found in " + location.toString());
|
||||
}
|
||||
|
||||
this.name = name;
|
||||
this.location = location;
|
||||
this.type = type;
|
||||
|
@ -69,15 +85,24 @@ public abstract class DocElement implements IPathElement {
|
|||
return location;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public int getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getTypeName() {
|
||||
return typeNames[type];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* returns the comment string, empty string if no comment is set.
|
||||
*/
|
||||
|
@ -85,7 +110,6 @@ public abstract class DocElement implements IPathElement {
|
|||
return comment;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* the actual content of the doc element (the function body, the properties
|
||||
* list, the file list etc.
|
||||
|
@ -94,20 +118,25 @@ public abstract class DocElement implements IPathElement {
|
|||
return content;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param rawContent ...
|
||||
*/
|
||||
public void addTag(String rawContent) {
|
||||
if (tags == null) {
|
||||
tags = new Vector();
|
||||
}
|
||||
|
||||
try {
|
||||
DocTag tag = DocTag.parse(rawContent);
|
||||
|
||||
tags.add(tag);
|
||||
} catch (DocException doc) {
|
||||
debug(doc.toString());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* list all tags
|
||||
*/
|
||||
|
@ -115,20 +144,28 @@ public abstract class DocElement implements IPathElement {
|
|||
return (DocTag[]) tags.toArray(new DocTag[0]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* filter the tags according to DocTag.TYPE
|
||||
*/
|
||||
public DocTag[] listTags(int type) {
|
||||
Vector retval = new Vector();
|
||||
|
||||
for (int i = 0; i < tags.size(); i++) {
|
||||
if ( ((DocTag) tags.get (i)).getType() == type)
|
||||
if (((DocTag) tags.get(i)).getType() == type) {
|
||||
retval.add(tags.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
return (DocTag[]) retval.toArray();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param param ...
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public boolean hasParameter(String param) {
|
||||
return parameters.contains(param);
|
||||
}
|
||||
|
@ -140,7 +177,6 @@ public abstract class DocElement implements IPathElement {
|
|||
return (String[]) parameters.toArray(new String[0]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* add a string to the parameters-list
|
||||
*/
|
||||
|
@ -148,7 +184,6 @@ public abstract class DocElement implements IPathElement {
|
|||
parameters.add(param);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* parse rawComment, render DocTags
|
||||
*/
|
||||
|
@ -161,39 +196,53 @@ public abstract class DocElement implements IPathElement {
|
|||
boolean lastEmpty = false;
|
||||
int mode = BLANK;
|
||||
StringBuffer buf = new StringBuffer();
|
||||
|
||||
while (tok.hasMoreTokens()) {
|
||||
String line = Util.chopDelimiters(tok.nextToken().trim());
|
||||
|
||||
if ("".equals(line)) {
|
||||
// if we've already had text, store that this line was empty
|
||||
lastEmpty = (mode != BLANK) ? true : false;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// if we come here the first time, start with TEXT mode
|
||||
mode = (mode == BLANK) ? TEXT : mode;
|
||||
|
||||
// check if we have a new tag
|
||||
if (DocTag.isTagStart(line)) {
|
||||
// if we appended to comment text until now, store that ...
|
||||
if (mode==TEXT)
|
||||
if (mode == TEXT) {
|
||||
comment = buf.toString();
|
||||
}
|
||||
|
||||
// if we appended to a tag, store that ...
|
||||
if (mode==TAGS)
|
||||
if (mode == TAGS) {
|
||||
addTag(buf.toString());
|
||||
}
|
||||
|
||||
// reset buffer
|
||||
buf = new StringBuffer();
|
||||
mode = TAGS;
|
||||
}
|
||||
|
||||
// append to current buffer
|
||||
if (lastEmpty==true)
|
||||
if (lastEmpty == true) {
|
||||
buf.append("\n");
|
||||
}
|
||||
|
||||
buf.append(line);
|
||||
buf.append(" ");
|
||||
lastEmpty = false;
|
||||
}
|
||||
|
||||
// store the last element, if there was at least one element ...
|
||||
if (mode==TEXT)
|
||||
if (mode == TEXT) {
|
||||
comment = buf.toString();
|
||||
else if (mode==TAGS)
|
||||
} else if (mode == TAGS) {
|
||||
addTag(buf.toString());
|
||||
}
|
||||
} catch (RuntimeException rt) {
|
||||
debug("parse error in " + location + ": " + rt.getMessage());
|
||||
}
|
||||
|
@ -207,32 +256,56 @@ public abstract class DocElement implements IPathElement {
|
|||
StringBuffer buf = new StringBuffer();
|
||||
BufferedReader in = new BufferedReader(new FileReader(file));
|
||||
String line = in.readLine();
|
||||
|
||||
while (line != null) {
|
||||
buf.append(line + "\n");
|
||||
line = in.readLine();
|
||||
}
|
||||
|
||||
in.close();
|
||||
|
||||
return buf.toString();
|
||||
} catch (IOException e) {
|
||||
return ("");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param parent ...
|
||||
*/
|
||||
public void setParent(DocElement parent) {
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param child ...
|
||||
*/
|
||||
public void addChild(DocElement child) {
|
||||
if (child==null)
|
||||
if (child == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
children.put(child.getElementName(), child);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public int countChildren() {
|
||||
return children.size();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public Map getChildren() {
|
||||
return children;
|
||||
}
|
||||
|
@ -242,14 +315,35 @@ public abstract class DocElement implements IPathElement {
|
|||
*/
|
||||
public DocElement[] listChildren() {
|
||||
String[] keys = (String[]) children.keySet().toArray(new String[0]);
|
||||
|
||||
Arrays.sort(keys);
|
||||
|
||||
DocElement[] arr = new DocElement[keys.length];
|
||||
|
||||
for (int i = 0; i < keys.length; i++) {
|
||||
arr[i] = (DocElement) children.get(keys[i]);
|
||||
}
|
||||
|
||||
return arr;
|
||||
}
|
||||
|
||||
/**
|
||||
* walks up the tree and tries to find a DocApplication object
|
||||
*/
|
||||
public DocApplication getDocApplication() {
|
||||
DocElement el = this;
|
||||
|
||||
while (el != null) {
|
||||
if (el instanceof DocApplication) {
|
||||
return (DocApplication) el;
|
||||
}
|
||||
|
||||
el = (DocElement) el.getParentElement();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* from helma.framework.IPathElement. Elements are named
|
||||
* like this: typename_name
|
||||
|
@ -258,7 +352,6 @@ public abstract class DocElement implements IPathElement {
|
|||
return typeNames[type].toLowerCase() + "_" + name;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* from helma.framework.IPathElement. Retrieves a child from the
|
||||
* children map.
|
||||
|
@ -269,11 +362,11 @@ public abstract class DocElement implements IPathElement {
|
|||
} catch (ClassCastException cce) {
|
||||
debug(cce.toString());
|
||||
cce.printStackTrace();
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* from helma.framework.IPathElement. Returns the parent object
|
||||
* of this instance if assigned.
|
||||
|
@ -282,7 +375,6 @@ public abstract class DocElement implements IPathElement {
|
|||
return parent;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* from helma.framework.IPathElement. Prototypes are assigned like
|
||||
* this: "doc" + typename (e.g. docapplication, docprototype etc)
|
||||
|
@ -291,14 +383,21 @@ public abstract class DocElement implements IPathElement {
|
|||
return "doc" + typeNames[type].toLowerCase();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String toString() {
|
||||
return "[" + typeNames[type] + " " + name + "]";
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param msg ...
|
||||
*/
|
||||
public static void debug(String msg) {
|
||||
System.out.println(msg);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -1,16 +1,43 @@
|
|||
/*
|
||||
* 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.doc;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class DocException extends RuntimeException {
|
||||
|
||||
String str;
|
||||
|
||||
/**
|
||||
* Creates a new DocException object.
|
||||
*
|
||||
* @param str ...
|
||||
*/
|
||||
public DocException(String str) {
|
||||
super(str);
|
||||
this.str = str;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getMessage() {
|
||||
return str;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,23 +1,48 @@
|
|||
/*
|
||||
* 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.doc;
|
||||
|
||||
import FESI.Parser.*;
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
import FESI.Parser.*;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public abstract class DocFileElement extends DocElement {
|
||||
protected DocFileElement(String name, File location, int type) {
|
||||
super(name, location, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* extracts the function name from a file. basically chops the given suffix
|
||||
* and throws an error if the file name doesn't fit.
|
||||
*/
|
||||
static protected String nameFromFile (File f, String suffix) throws DocException {
|
||||
static protected String nameFromFile(File f, String suffix)
|
||||
throws DocException {
|
||||
String filename = f.getName();
|
||||
if (!filename.endsWith (suffix))
|
||||
throw new DocException ("file doesn't have suffix " + suffix + ": " + f.toString());
|
||||
return filename.substring (0, filename.lastIndexOf(suffix));
|
||||
|
||||
if (!filename.endsWith(suffix)) {
|
||||
throw new DocException("file doesn't have suffix " + suffix + ": " +
|
||||
f.toString());
|
||||
}
|
||||
|
||||
return filename.substring(0, filename.lastIndexOf(suffix));
|
||||
}
|
||||
|
||||
/**
|
||||
* creates fesi token manager for a given file.
|
||||
|
@ -26,6 +51,7 @@ public abstract class DocFileElement extends DocElement {
|
|||
try {
|
||||
ASCII_CharStream is = new ASCII_CharStream(new FileReader(f), 1, 1);
|
||||
EcmaScriptTokenManager mgr = new EcmaScriptTokenManager(is, 0);
|
||||
|
||||
return mgr;
|
||||
} catch (FileNotFoundException fnfe) {
|
||||
fnfe.printStackTrace();
|
||||
|
@ -33,52 +59,54 @@ public abstract class DocFileElement extends DocElement {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
protected DocFileElement (String name, File location, int type) {
|
||||
super (name, location, type);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* extracts a part of the source code, used to get the code for a
|
||||
* single function from a function file. sets the field "content".
|
||||
*/
|
||||
protected void parseSource (File sourceFile, int beginLine, int beginColumn, int endLine, int endColumn) {
|
||||
protected void parseSource(File sourceFile, int beginLine, int beginColumn,
|
||||
int endLine, int endColumn) {
|
||||
StringBuffer buf = new StringBuffer();
|
||||
int ct = 0;
|
||||
|
||||
try {
|
||||
BufferedReader in = new BufferedReader(new FileReader(sourceFile));
|
||||
String line = "";
|
||||
|
||||
while (line != null) {
|
||||
line = in.readLine();
|
||||
if (line==null) break;
|
||||
|
||||
if (line == null) {
|
||||
break;
|
||||
}
|
||||
|
||||
ct++;
|
||||
if (ct==beginLine)
|
||||
|
||||
if (ct == beginLine) {
|
||||
buf.append(line.substring(beginColumn - 1, line.length()) + "\n");
|
||||
else if ( ct>beginLine && ct<endLine )
|
||||
} else if ((ct > beginLine) && (ct < endLine)) {
|
||||
buf.append(line + "\n");
|
||||
else if (ct==endLine)
|
||||
} else if (ct == endLine) {
|
||||
buf.append(line.substring(0, endColumn));
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
debug(e.getMessage());
|
||||
}
|
||||
|
||||
content = buf.toString();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* connects all available specialTokens starting at the given token.
|
||||
*/
|
||||
protected void parseCommentFromToken(Token tok) {
|
||||
StringBuffer buf = new StringBuffer();
|
||||
|
||||
while (tok.specialToken != null) {
|
||||
buf.append(tok.specialToken.toString());
|
||||
tok = tok.specialToken;
|
||||
}
|
||||
|
||||
parseComment(buf.toString().trim());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -1,12 +1,34 @@
|
|||
package helma.doc;
|
||||
/*
|
||||
* 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$
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
package helma.doc;
|
||||
|
||||
import FESI.Parser.*;
|
||||
import helma.framework.IPathElement;
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class DocFunction extends DocFileElement {
|
||||
protected DocFunction(String name, File location, DocElement parent, int type) {
|
||||
super(name, location, type);
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* creates a new independent DocFunction object of type ACTION
|
||||
|
@ -15,14 +37,15 @@ public class DocFunction extends DocFileElement {
|
|||
return newAction(location, null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* creates a new DocFunction object of type ACTION connected to another DocElement
|
||||
*/
|
||||
public static DocFunction newAction(File location, DocElement parent) {
|
||||
String name = nameFromFile(location, ".hac");
|
||||
DocFunction func = new DocFunction(name, location, parent, ACTION);
|
||||
|
||||
func.parseActionFile();
|
||||
|
||||
return func;
|
||||
}
|
||||
|
||||
|
@ -33,18 +56,18 @@ public class DocFunction extends DocFileElement {
|
|||
return newTemplate(location, null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* creates a new DocFunction object of type TEMPLATE connected to another DocElement
|
||||
*/
|
||||
public static DocFunction newTemplate(File location, DocElement parent) {
|
||||
String name = nameFromFile(location, ".hsp");
|
||||
DocFunction func = new DocFunction(name, location, parent, TEMPLATE);
|
||||
|
||||
func.parseTemplateFile();
|
||||
|
||||
return func;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* reads a function file and creates independent DocFunction objects of type FUNCTION
|
||||
*/
|
||||
|
@ -52,7 +75,6 @@ public class DocFunction extends DocFileElement {
|
|||
return newFunctions(location, null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* reads a function file and creates DocFunction objects of type FUNCTION
|
||||
* connected to another DocElement.
|
||||
|
@ -61,60 +83,70 @@ public class DocFunction extends DocFileElement {
|
|||
Vector vec = new Vector();
|
||||
EcmaScriptTokenManager mgr = createTokenManager(location);
|
||||
Token tok = mgr.getNextToken();
|
||||
|
||||
while (tok.kind != 0) {
|
||||
if (tok.kind == EcmaScriptConstants.FUNCTION) {
|
||||
// store the start position of the function:
|
||||
int beginLine = tok.beginLine;
|
||||
int beginColumn = tok.beginColumn;
|
||||
|
||||
// the name is stored in the next token:
|
||||
String funcName = mgr.getNextToken().toString();
|
||||
|
||||
// create the function object
|
||||
DocFunction func;
|
||||
if (funcName.endsWith("_action"))
|
||||
|
||||
if (funcName.endsWith("_action")) {
|
||||
func = new DocFunction(funcName, location, parent, ACTION);
|
||||
else if (funcName.endsWith("_macro"))
|
||||
} else if (funcName.endsWith("_macro")) {
|
||||
func = new DocFunction(funcName, location, parent, MACRO);
|
||||
else
|
||||
} else {
|
||||
func = new DocFunction(funcName, location, parent, FUNCTION);
|
||||
}
|
||||
|
||||
// parse the comment from the special token(s) before this token:
|
||||
func.parseCommentFromToken(tok);
|
||||
|
||||
// find the parameters of this function, but only if it's
|
||||
// neither macro nor action:
|
||||
if (func.type == FUNCTION) {
|
||||
while (tok.kind!=0 && tok.kind!=EcmaScriptConstants.RPAREN) {
|
||||
while ((tok.kind != 0) && (tok.kind != EcmaScriptConstants.RPAREN)) {
|
||||
if (tok.kind == EcmaScriptConstants.IDENTIFIER) {
|
||||
func.addParameter(tok.image);
|
||||
}
|
||||
|
||||
tok = mgr.getNextToken();
|
||||
}
|
||||
} else {
|
||||
tok = mgr.getNextToken();
|
||||
}
|
||||
|
||||
// now find the end of the function:
|
||||
int endLine=0, endColumn=0;
|
||||
while (tok.kind!=0 && tok.kind!=EcmaScriptConstants.FUNCTION) {
|
||||
int endLine = 0;
|
||||
|
||||
// now find the end of the function:
|
||||
int endColumn = 0;
|
||||
|
||||
while ((tok.kind != 0) && (tok.kind != EcmaScriptConstants.FUNCTION)) {
|
||||
endLine = tok.endLine;
|
||||
endColumn = tok.endColumn;
|
||||
tok = mgr.getNextToken();
|
||||
}
|
||||
|
||||
// now we know the exact position of the function in the file,
|
||||
// re-read it and extract the source code:
|
||||
func.parseSource(location, beginLine, beginColumn, endLine, endColumn);
|
||||
vec.add(func);
|
||||
}
|
||||
|
||||
if (tok.kind != EcmaScriptConstants.FUNCTION) {
|
||||
tok = mgr.getNextToken();
|
||||
}
|
||||
}
|
||||
|
||||
return (DocFunction[]) vec.toArray(new DocFunction[0]);
|
||||
}
|
||||
|
||||
protected DocFunction (String name, File location, DocElement parent, int type) {
|
||||
super (name, location, type);
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* reads the content of a .hac file and parses the comment before the first
|
||||
* javascript element
|
||||
|
@ -122,25 +154,27 @@ public class DocFunction extends DocFileElement {
|
|||
private void parseActionFile() {
|
||||
EcmaScriptTokenManager mgr = createTokenManager(location);
|
||||
Token tok = mgr.getNextToken();
|
||||
|
||||
parseCommentFromToken(tok);
|
||||
content = readFile(location);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* reads the content of a .hsp file and parses the comment before the first
|
||||
* javascript element (only if file starts with >%-tag!).
|
||||
*/
|
||||
private void parseTemplateFile() {
|
||||
content = readFile(location);
|
||||
StringReader str = new StringReader (content.substring (content.indexOf("<%") + 2, content.indexOf ("%>")));
|
||||
|
||||
StringReader str = new StringReader(content.substring(content.indexOf("<%") + 2,
|
||||
content.indexOf("%>")));
|
||||
ASCII_CharStream ascii = new ASCII_CharStream(str, 1, 1);
|
||||
EcmaScriptTokenManager mgr = new EcmaScriptTokenManager(ascii);
|
||||
Token tok = mgr.getNextToken();
|
||||
|
||||
parseCommentFromToken(tok);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* from helma.framework.IPathElement. All macros, templates, actions etc
|
||||
* have the same prototype.
|
||||
|
@ -148,7 +182,4 @@ public class DocFunction extends DocFileElement {
|
|||
public java.lang.String getPrototype() {
|
||||
return "docfunction";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,19 @@
|
|||
/*
|
||||
* 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.doc;
|
||||
|
||||
import helma.framework.IPathElement;
|
||||
|
@ -5,10 +21,28 @@ import helma.util.SystemProperties;
|
|||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class DocProperties extends DocFileElement {
|
||||
|
||||
Properties props = null;
|
||||
|
||||
protected DocProperties(File location, DocElement parent)
|
||||
throws DocException {
|
||||
super(location.getName(), location, PROPERTIES);
|
||||
this.parent = parent;
|
||||
content = readFile(location);
|
||||
props = new SystemProperties();
|
||||
|
||||
try {
|
||||
props.load(new FileInputStream(location));
|
||||
} catch (IOException e) {
|
||||
debug("couldn't read file: " + e.toString());
|
||||
} catch (Exception e) {
|
||||
throw new DocException(e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* creates a new independent DocProperties object
|
||||
*/
|
||||
|
@ -27,37 +61,36 @@ public class DocProperties extends DocFileElement {
|
|||
}
|
||||
}
|
||||
|
||||
protected DocProperties (File location, DocElement parent) throws DocException {
|
||||
super (location.getName (), location, PROPERTIES);
|
||||
this.parent = parent;
|
||||
content = readFile (location);
|
||||
props = new SystemProperties ();
|
||||
try {
|
||||
props.load (new FileInputStream (location));
|
||||
} catch (IOException e) {
|
||||
debug ("couldn't read file: " + e.toString ());
|
||||
} catch (Exception e) {
|
||||
throw new DocException (e.toString ());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public Properties getProperties() {
|
||||
return props;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public Properties getMappings() {
|
||||
Properties childProps = new Properties();
|
||||
|
||||
for (Enumeration e = props.keys(); e.hasMoreElements();) {
|
||||
String key = (String) e.nextElement();
|
||||
String value = props.getProperty(key);
|
||||
if (value.startsWith ("collection") || value.startsWith ("object") || value.startsWith ("mountpoint")) {
|
||||
String prototype = value.substring (value.indexOf("(")+1, value.indexOf(")")).trim ();
|
||||
|
||||
if (value.startsWith("collection") || value.startsWith("object") ||
|
||||
value.startsWith("mountpoint")) {
|
||||
String prototype = value.substring(value.indexOf("(") + 1,
|
||||
value.indexOf(")")).trim();
|
||||
|
||||
childProps.setProperty(key, prototype);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return childProps;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -1,16 +1,39 @@
|
|||
/*
|
||||
* 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.doc;
|
||||
|
||||
import FESI.Parser.*;
|
||||
import helma.framework.IPathElement;
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import FESI.Parser.*;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class DocPrototype extends DocDirElement {
|
||||
|
||||
private DocProperties typeProperties = null;
|
||||
private DocPrototype parentPrototype = null;
|
||||
|
||||
private DocPrototype(String name, File location, DocElement parent) {
|
||||
super(name, location, PROTOTYPE);
|
||||
this.parent = parent;
|
||||
typeProperties = DocProperties.newInstance(new File(location, "type.properties"));
|
||||
}
|
||||
|
||||
/**
|
||||
* creates a prototype that is independent of an
|
||||
* application object
|
||||
|
@ -28,16 +51,10 @@ public class DocPrototype extends DocDirElement {
|
|||
*/
|
||||
public static DocPrototype newInstance(File location, DocElement parent) {
|
||||
DocPrototype pt = new DocPrototype(location.getName(), location, parent);
|
||||
|
||||
return pt;
|
||||
}
|
||||
|
||||
private DocPrototype (String name, File location, DocElement parent) {
|
||||
super (name, location, PROTOTYPE);
|
||||
this.parent = parent;
|
||||
typeProperties = DocProperties.newInstance (new File (location, "type.properties"));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* checks the type.properites for _extend values and connected a possible
|
||||
* parent prototype with this prototype. this can't be successfull at construction
|
||||
|
@ -46,44 +63,64 @@ public class DocPrototype extends DocDirElement {
|
|||
*/
|
||||
public void checkInheritance() {
|
||||
// hopobject is the top prototype:
|
||||
if (name.equals("hopobject"))
|
||||
if (name.equals("hopobject")) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeProperties != null) {
|
||||
// check for "_extends" in the the type.properties
|
||||
String ext = typeProperties.getProperties().getProperty("_extends");
|
||||
if (ext!=null && parent!=null) {
|
||||
|
||||
if ((ext != null) && (parent != null)) {
|
||||
// try to get the prototype if available
|
||||
parentPrototype = (DocPrototype) parent.getChildElement ("prototype_" + ext);
|
||||
parentPrototype = (DocPrototype) parent.getChildElement("prototype_" +
|
||||
ext);
|
||||
}
|
||||
}
|
||||
if (parentPrototype==null && parent!=null && !name.equals("global")) {
|
||||
|
||||
if ((parentPrototype == null) && (parent != null) && !name.equals("global")) {
|
||||
// if no _extend was set, get the hopobject prototype
|
||||
parentPrototype = (DocPrototype) parent.getChildElement("prototype_hopobject");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public DocPrototype getParentPrototype() {
|
||||
return parentPrototype;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public DocProperties getTypeProperties() {
|
||||
return typeProperties;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* runs through the prototype directory and parses all helma files
|
||||
*/
|
||||
public void readFiles() {
|
||||
children.clear();
|
||||
String arr[] = location.list ();
|
||||
|
||||
String[] arr = location.list();
|
||||
|
||||
for (int i = 0; i < arr.length; i++) {
|
||||
if (Util.isExcluded (arr[i]))
|
||||
if (getDocApplication().isExcluded(arr[i])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
File f = new File(location.getAbsolutePath(), arr[i]);
|
||||
if (f.isDirectory ())
|
||||
|
||||
if (f.isDirectory()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
if (arr[i].endsWith(".skin")) {
|
||||
addChild(DocSkin.newInstance(f, this));
|
||||
|
@ -95,16 +132,19 @@ public class DocPrototype extends DocDirElement {
|
|||
addChild(DocFunction.newTemplate(f, this));
|
||||
} else if (arr[i].endsWith(".js")) {
|
||||
DocElement[] elements = DocFunction.newFunctions(f, this);
|
||||
|
||||
for (int j = 0; j < elements.length; j++) {
|
||||
addChild(elements[j]);
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
System.out.println ("couldn't parse file " + f.getAbsolutePath () + ": " + ex.toString ());
|
||||
System.out.println("couldn't parse file " + f.getAbsolutePath() + ": " +
|
||||
ex.toString());
|
||||
ex.printStackTrace();
|
||||
} catch (FESI.Parser.TokenMgrError err) {
|
||||
System.out.println("couldn't parse file " + f.getAbsolutePath() + ": " +
|
||||
err.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -1,10 +1,35 @@
|
|||
/*
|
||||
* 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.doc;
|
||||
|
||||
import helma.framework.IPathElement;
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class DocSkin extends DocFileElement {
|
||||
protected DocSkin(String name, File location, DocElement parent) {
|
||||
super(name, location, SKIN);
|
||||
this.parent = parent;
|
||||
content = readFile(location);
|
||||
parseHandlers();
|
||||
}
|
||||
|
||||
/**
|
||||
* creates a new independent DocSkin object
|
||||
|
@ -19,17 +44,10 @@ public class DocSkin extends DocFileElement {
|
|||
public static DocSkin newInstance(File location, DocElement parent) {
|
||||
String skinname = nameFromFile(location, ".skin");
|
||||
DocSkin skin = new DocSkin(skinname, location, parent);
|
||||
|
||||
return skin;
|
||||
}
|
||||
|
||||
protected DocSkin (String name, File location, DocElement parent) {
|
||||
super (name, location, SKIN);
|
||||
this.parent = parent;
|
||||
content = readFile (location);
|
||||
parseHandlers ();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* parses the source code of the skin and
|
||||
* extracts all included macros. code taken
|
||||
|
@ -41,35 +59,51 @@ public class DocSkin extends DocFileElement {
|
|||
char[] source = content.toCharArray();
|
||||
int sourceLength = source.length;
|
||||
int start = 0;
|
||||
for (int i = 0; i < sourceLength-1; i++) {
|
||||
if (source[i] == '<' && source[i+1] == '%') {
|
||||
|
||||
for (int i = 0; i < (sourceLength - 1); i++) {
|
||||
if ((source[i] == '<') && (source[i + 1] == '%')) {
|
||||
// found macro start tag
|
||||
int j = i + 2;
|
||||
|
||||
// search macro end tag
|
||||
while (j < sourceLength-1 && (source[j] != '%' || source[j+1] != '>')) {
|
||||
while ((j < (sourceLength - 1)) &&
|
||||
((source[j] != '%') || (source[j + 1] != '>'))) {
|
||||
j++;
|
||||
}
|
||||
if (j > i+2) {
|
||||
|
||||
if (j > (i + 2)) {
|
||||
String str = (new String(source, i + 2, j - i)).trim();
|
||||
if (str.endsWith("%>"))
|
||||
|
||||
if (str.endsWith("%>")) {
|
||||
str = str.substring(0, str.length() - 2);
|
||||
if (str.indexOf (" ")>-1)
|
||||
}
|
||||
|
||||
if (str.startsWith("//")) {
|
||||
parseComment(str);
|
||||
} else {
|
||||
if (str.indexOf(" ") > -1) {
|
||||
str = str.substring(0, str.indexOf(" "));
|
||||
if (str.indexOf(".")>-1 &&
|
||||
(str.startsWith ("param.")
|
||||
|| str.startsWith ("response.")
|
||||
|| str.startsWith("request.")
|
||||
|| str.startsWith ("session.")
|
||||
) && !partBuffer.contains(str)) {
|
||||
}
|
||||
|
||||
if ((str.indexOf(".") > -1) &&
|
||||
(str.startsWith("param.") || str.startsWith("response.") ||
|
||||
str.startsWith("request.") || str.startsWith("session.")) &&
|
||||
!partBuffer.contains(str)) {
|
||||
partBuffer.add(str);
|
||||
}
|
||||
}
|
||||
|
||||
start = j + 2;
|
||||
}
|
||||
|
||||
i = j + 1;
|
||||
}
|
||||
}
|
||||
|
||||
String[] strArr = (String[]) partBuffer.toArray(new String[0]);
|
||||
|
||||
Arrays.sort(strArr);
|
||||
|
||||
for (int i = 0; i < strArr.length; i++) {
|
||||
addParameter(strArr[i]);
|
||||
}
|
||||
|
@ -81,7 +115,4 @@ public class DocSkin extends DocFileElement {
|
|||
public java.lang.String getPrototype() {
|
||||
return "docfunction";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -1,9 +1,27 @@
|
|||
/*
|
||||
* 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.doc;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public final class DocTag {
|
||||
|
||||
// for public use we have less types than
|
||||
// internally. eg, we're combining "return" and "returns"
|
||||
// or "arg" and "param".
|
||||
|
@ -16,7 +34,6 @@ public final class DocTag {
|
|||
public static final int SEE = 6;
|
||||
public static final int DEPRECATED = 7;
|
||||
public static final int OVERRIDES = 8;
|
||||
|
||||
public static final String[][] tags = {
|
||||
{ "@arg", "Argument" },
|
||||
{ "@param", "Parameter" },
|
||||
|
@ -28,33 +45,66 @@ public final class DocTag {
|
|||
{ "@deprecated", "Deprecated" },
|
||||
{ "@overrides", "Overrides" }
|
||||
};
|
||||
|
||||
private String name;
|
||||
|
||||
// "kind" is for internal use, "type" is external
|
||||
private int kind;
|
||||
private String text;
|
||||
|
||||
public static boolean isTagStart (String rawTag) {
|
||||
if (getTagNumber(rawTag) > -1)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
private DocTag(int kind, String name, String text) {
|
||||
this.kind = kind;
|
||||
this.name = (name != null) ? name : "";
|
||||
this.text = (text != null) ? text : "";
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param rawTag ...
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public static boolean isTagStart(String rawTag) {
|
||||
if (getTagNumber(rawTag) > -1) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param rawTag ...
|
||||
*
|
||||
* @return ...
|
||||
*
|
||||
* @throws DocException ...
|
||||
*/
|
||||
public static DocTag parse(String rawTag) throws DocException {
|
||||
int kind = getTagNumber(rawTag);
|
||||
if (kind == -1)
|
||||
|
||||
if (kind == -1) {
|
||||
throw new DocException("unsupported tag type: " + rawTag);
|
||||
}
|
||||
|
||||
String content = rawTag.substring(tags[kind][0].length() + 1).trim();
|
||||
if (kind == 0 || kind==1) {
|
||||
|
||||
if ((kind == 0) || (kind == 1)) {
|
||||
StringTokenizer tok = new StringTokenizer(content);
|
||||
String name = "";
|
||||
if (tok.hasMoreTokens ())
|
||||
|
||||
if (tok.hasMoreTokens()) {
|
||||
name = tok.nextToken();
|
||||
}
|
||||
|
||||
String comment = "";
|
||||
|
||||
try {
|
||||
comment = content.substring(name.length() + 1).trim();
|
||||
} catch (StringIndexOutOfBoundsException e) { }
|
||||
} catch (StringIndexOutOfBoundsException e) {
|
||||
}
|
||||
|
||||
return new DocTag(kind, name, comment);
|
||||
} else {
|
||||
return new DocTag(kind, "", content);
|
||||
|
@ -63,46 +113,64 @@ public final class DocTag {
|
|||
|
||||
private static int getTagNumber(String rawTag) {
|
||||
rawTag = rawTag.trim().toLowerCase();
|
||||
|
||||
for (int i = 0; i < tags.length; i++) {
|
||||
if (rawTag.startsWith(tags[i][0])) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
private DocTag (int kind, String name, String text) {
|
||||
this.kind = kind;
|
||||
this.name = (name!=null) ? name : "";
|
||||
this.text = (text!=null) ? text : "";
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public int getType() {
|
||||
if (kind==0 || kind==1)
|
||||
if ((kind == 0) || (kind == 1)) {
|
||||
return PARAMETER;
|
||||
else if (kind==2 || kind==3)
|
||||
} else if ((kind == 2) || (kind == 3)) {
|
||||
return RETURN;
|
||||
else
|
||||
} else {
|
||||
return kind;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getTag() {
|
||||
return tags[kind][0];
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String toString() {
|
||||
return tags[kind][1] + ": " + name + " " + text;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -1,40 +1,50 @@
|
|||
/*
|
||||
* 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.doc;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public final class Util {
|
||||
|
||||
static Vector excluded = new Vector ();
|
||||
|
||||
public static void addExlude (String str) {
|
||||
excluded.add (str.toLowerCase ());
|
||||
}
|
||||
|
||||
public static boolean isExcluded (String str) {
|
||||
if (excluded.size ()==0) {
|
||||
excluded.add ("cvs");
|
||||
excluded.add (".docs");
|
||||
}
|
||||
return (excluded.contains (str.toLowerCase ()));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param line ...
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public static String chopDelimiters(String line) {
|
||||
if (line==null)
|
||||
if (line == null) {
|
||||
return null;
|
||||
else if (line.startsWith("/**"))
|
||||
} else if (line.startsWith("/**")) {
|
||||
return line.substring(3).trim();
|
||||
else if (line.startsWith("/*"))
|
||||
} else if (line.startsWith("/*")) {
|
||||
return line.substring(2).trim();
|
||||
else if (line.endsWith ("*/"))
|
||||
} else if (line.endsWith("*/")) {
|
||||
return line.substring(0, line.length() - 2);
|
||||
else if (line.startsWith("*"))
|
||||
} else if (line.startsWith("*")) {
|
||||
return line.substring(1).trim();
|
||||
else if (line.startsWith("//"))
|
||||
} else if (line.startsWith("//")) {
|
||||
return line.substring(2).trim();
|
||||
else
|
||||
} else {
|
||||
return line;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,31 @@
|
|||
/*
|
||||
* 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.extensions;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class ConfigurationException extends RuntimeException {
|
||||
|
||||
/**
|
||||
* Creates a new ConfigurationException object.
|
||||
*
|
||||
* @param msg ...
|
||||
*/
|
||||
public ConfigurationException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,19 +1,32 @@
|
|||
package helma.extensions;
|
||||
/*
|
||||
* 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$
|
||||
*/
|
||||
|
||||
import java.util.HashMap;
|
||||
package helma.extensions;
|
||||
|
||||
import helma.framework.core.Application;
|
||||
import helma.main.Server;
|
||||
import helma.scripting.ScriptingEngine;
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* Helma extensions have to subclass this. The extensions to be loaded are
|
||||
* defined in <code>server.properties</code> by setting <code>extensions =
|
||||
* packagename.classname, packagename.classname</code>.
|
||||
*/
|
||||
|
||||
public abstract class HelmaExtension {
|
||||
|
||||
/**
|
||||
* called by the Server at startup time. should check wheter the needed classes
|
||||
* are present and throw a ConfigurationException if not.
|
||||
|
@ -24,7 +37,8 @@ public abstract class HelmaExtension {
|
|||
* called when an Application is started. This should be <b>synchronized</b> when
|
||||
* any self-initialization is performed.
|
||||
*/
|
||||
public abstract void applicationStarted (Application app) throws ConfigurationException;
|
||||
public abstract void applicationStarted(Application app)
|
||||
throws ConfigurationException;
|
||||
|
||||
/**
|
||||
* called when an Application is stopped.
|
||||
|
@ -45,9 +59,13 @@ public abstract class HelmaExtension {
|
|||
* with pairs of varname and ESObjects. This method should be <b>synchronized</b>, if it
|
||||
* performs any other self-initialization outside the scripting environment.
|
||||
*/
|
||||
public abstract HashMap initScripting (Application app, ScriptingEngine engine) throws ConfigurationException;
|
||||
public abstract HashMap initScripting(Application app, ScriptingEngine engine)
|
||||
throws ConfigurationException;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public abstract String getName();
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -1,12 +1,21 @@
|
|||
/*
|
||||
* 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.extensions.demo;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
import helma.extensions.HelmaExtension;
|
||||
import helma.extensions.ConfigurationException;
|
||||
import helma.framework.core.Application;
|
||||
import helma.main.Server;
|
||||
import helma.scripting.ScriptingEngine;
|
||||
|
||||
// fesi-related stuff:
|
||||
import FESI.Data.ESObject;
|
||||
|
@ -14,8 +23,13 @@ import FESI.Data.ESWrapper;
|
|||
import FESI.Data.GlobalObject;
|
||||
import FESI.Exceptions.EcmaScriptException;
|
||||
import FESI.Interpreter.Evaluator;
|
||||
import helma.extensions.ConfigurationException;
|
||||
import helma.extensions.HelmaExtension;
|
||||
import helma.framework.core.Application;
|
||||
import helma.main.Server;
|
||||
import helma.scripting.ScriptingEngine;
|
||||
import helma.scripting.fesi.FesiEngine;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* a demo extension implementation, to activate this add <code>extensions =
|
||||
|
@ -23,9 +37,14 @@ import helma.scripting.fesi.FesiEngine;
|
|||
* a new global object <code>demo</code> that wraps helma.main.Server
|
||||
* will be added to the scripting environment.
|
||||
*/
|
||||
|
||||
public class DemoExtension extends HelmaExtension {
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param server ...
|
||||
*
|
||||
* @throws ConfigurationException ...
|
||||
*/
|
||||
public void init(Server server) throws ConfigurationException {
|
||||
try {
|
||||
// just a demo with the server class itself (which is always there, obviously)
|
||||
|
@ -35,34 +54,73 @@ public class DemoExtension extends HelmaExtension {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param app ...
|
||||
*
|
||||
* @throws ConfigurationException ...
|
||||
*/
|
||||
public void applicationStarted(Application app) throws ConfigurationException {
|
||||
app.logEvent("DemoExtension init with app " + app.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param app ...
|
||||
*/
|
||||
public void applicationStopped(Application app) {
|
||||
app.logEvent("DemoExtension stopped on app " + app.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param app ...
|
||||
*/
|
||||
public void applicationUpdated(Application app) {
|
||||
app.logEvent("DemoExtension updated on app " + app.getName());
|
||||
}
|
||||
|
||||
public HashMap initScripting (Application app, ScriptingEngine engine) throws ConfigurationException {
|
||||
if (!(engine instanceof FesiEngine))
|
||||
throw new ConfigurationException ("scripting engine " + engine.toString () + " not supported in DemoExtension");
|
||||
app.logEvent("initScripting DemoExtension with " + app.getName () + " and " + engine.toString() );
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param app ...
|
||||
* @param engine ...
|
||||
*
|
||||
* @return ...
|
||||
*
|
||||
* @throws ConfigurationException ...
|
||||
*/
|
||||
public HashMap initScripting(Application app, ScriptingEngine engine)
|
||||
throws ConfigurationException {
|
||||
if (!(engine instanceof FesiEngine)) {
|
||||
throw new ConfigurationException("scripting engine " + engine.toString() +
|
||||
" not supported in DemoExtension");
|
||||
}
|
||||
|
||||
app.logEvent("initScripting DemoExtension with " + app.getName() + " and " +
|
||||
engine.toString());
|
||||
|
||||
// fesi-specific code:
|
||||
Evaluator evaluator = ((FesiEngine) engine).getEvaluator();
|
||||
|
||||
// initialize prototypes and global vars here, but don't add them to fesi's global object
|
||||
ESWrapper demo = new ESWrapper(Server.getServer(), evaluator);
|
||||
HashMap globals = new HashMap();
|
||||
|
||||
globals.put("demo", demo);
|
||||
|
||||
return globals;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getName() {
|
||||
return "DemoExtension";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -1,19 +1,31 @@
|
|||
// ApplicationStoppedException.java
|
||||
// Copyright (c) Hannes Wallnöfer 1998-2000
|
||||
/*
|
||||
* 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.framework;
|
||||
|
||||
|
||||
/**
|
||||
* This is thrown when a request is made to a stopped
|
||||
* application
|
||||
*/
|
||||
|
||||
public class ApplicationStoppedException extends RuntimeException {
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new ApplicationStoppedException object.
|
||||
*/
|
||||
public ApplicationStoppedException() {
|
||||
super("The application has been stopped");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -1,4 +1,18 @@
|
|||
// CookieTrans.java
|
||||
/*
|
||||
* 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.framework;
|
||||
|
||||
|
@ -11,8 +25,10 @@ import javax.servlet.http.Cookie;
|
|||
* of an HTTP cookie.
|
||||
*/
|
||||
public final class CookieTrans implements Serializable {
|
||||
|
||||
String name, value, path, domain;
|
||||
String name;
|
||||
String value;
|
||||
String path;
|
||||
String domain;
|
||||
int days;
|
||||
|
||||
CookieTrans(String name, String value) {
|
||||
|
@ -36,39 +52,79 @@ public final class CookieTrans implements Serializable {
|
|||
this.domain = domain;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public int getDays() {
|
||||
return days;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getDomain() {
|
||||
return domain;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param defaultPath ...
|
||||
* @param defaultDomain ...
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public Cookie getCookie(String defaultPath, String defaultDomain) {
|
||||
Cookie c = new Cookie(name, value);
|
||||
if (days > 0)
|
||||
|
||||
if (days > 0) {
|
||||
// Cookie time to live, days -> seconds
|
||||
c.setMaxAge(days * 60 * 60 * 24);
|
||||
if (path != null)
|
||||
}
|
||||
|
||||
if (path != null) {
|
||||
c.setPath(path);
|
||||
else if (defaultPath != null)
|
||||
} else if (defaultPath != null) {
|
||||
c.setPath(defaultPath);
|
||||
if (domain != null)
|
||||
}
|
||||
|
||||
if (domain != null) {
|
||||
c.setDomain(domain);
|
||||
else if (defaultDomain != null)
|
||||
} else if (defaultDomain != null) {
|
||||
c.setDomain(defaultDomain);
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,17 +1,33 @@
|
|||
// FrameworkException.java
|
||||
// Copyright (c) Hannes Wallnöfer 1998-2000
|
||||
/*
|
||||
* 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.framework;
|
||||
|
||||
|
||||
/**
|
||||
* The basic exception class used to tell when certain things go
|
||||
* wrong in evaluation of requests.
|
||||
*/
|
||||
|
||||
public class FrameworkException extends RuntimeException {
|
||||
|
||||
/**
|
||||
* Creates a new FrameworkException object.
|
||||
*
|
||||
* @param msg ...
|
||||
*/
|
||||
public FrameworkException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,18 @@
|
|||
// IPathElement.java
|
||||
// Copyright (c) Hannes Wallnöfer 2001
|
||||
/*
|
||||
* 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.framework;
|
||||
|
||||
|
@ -14,9 +27,7 @@ package helma.framework;
|
|||
* parent element. <p>
|
||||
*
|
||||
*/
|
||||
|
||||
public interface IPathElement {
|
||||
|
||||
/**
|
||||
* Return the name to be used to get this element from its parent
|
||||
*/
|
||||
|
@ -32,16 +43,10 @@ public interface IPathElement {
|
|||
*/
|
||||
public IPathElement getParentElement();
|
||||
|
||||
|
||||
/**
|
||||
* Get the name of the prototype to be used for this object. This will
|
||||
* determine which scripts, actions and skins can be called on it
|
||||
* within the Helma scripting and rendering framework.
|
||||
*/
|
||||
public String getPrototype();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,5 +1,18 @@
|
|||
// IRemoteApp.java
|
||||
// Copyright (c) Hannes Wallnöfer 1998-2000
|
||||
/*
|
||||
* 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.framework;
|
||||
|
||||
|
@ -9,11 +22,22 @@ import java.util.Vector;
|
|||
/**
|
||||
* RMI interface for an application. Currently only execute is used and supported.
|
||||
*/
|
||||
|
||||
public interface IRemoteApp extends Remote {
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param param ...
|
||||
*
|
||||
* @return ...
|
||||
*
|
||||
* @throws RemoteException ...
|
||||
*/
|
||||
public ResponseTrans execute(RequestTrans param) throws RemoteException;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @throws RemoteException ...
|
||||
*/
|
||||
public void ping() throws RemoteException;
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,18 @@
|
|||
// RedirectException.java
|
||||
// Copyright (c) Hannes Wallnöfer 1998-2000
|
||||
/*
|
||||
* 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.framework;
|
||||
|
||||
|
@ -8,26 +21,43 @@ package helma.framework;
|
|||
* RedirectException is thrown internally when a response is redirected to a
|
||||
* new URL.
|
||||
*/
|
||||
|
||||
public class RedirectException extends RuntimeException {
|
||||
|
||||
String url;
|
||||
|
||||
/**
|
||||
* Creates a new RedirectException object.
|
||||
*
|
||||
* @param url ...
|
||||
*/
|
||||
public RedirectException(String url) {
|
||||
super("Redirection Request to " + url);
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getMessage() {
|
||||
return url;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param s ...
|
||||
*/
|
||||
public void printStackTrace(java.io.PrintStream s) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param w ...
|
||||
*/
|
||||
public void printStackTrace(java.io.PrintWriter w) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,57 +1,125 @@
|
|||
/*
|
||||
* 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.framework;
|
||||
|
||||
import helma.framework.core.Application;
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
import helma.framework.core.Application;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class RequestBean implements Serializable {
|
||||
|
||||
RequestTrans req;
|
||||
|
||||
/**
|
||||
* Creates a new RequestBean object.
|
||||
*
|
||||
* @param req ...
|
||||
*/
|
||||
public RequestBean(RequestTrans req) {
|
||||
this.req = req;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param name ...
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public Object get(String name) {
|
||||
return req.get(name);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public boolean isGet() {
|
||||
return req.isGet();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public boolean isPost() {
|
||||
return req.isPost();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String toString() {
|
||||
return "[Request]";
|
||||
}
|
||||
|
||||
// property related methods:
|
||||
|
||||
public String getaction() {
|
||||
return req.action;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public Map getdata() {
|
||||
return req.getRequestData();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public long getruntime() {
|
||||
return (System.currentTimeMillis() - req.startTime);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getpassword() {
|
||||
return req.getPassword();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getpath() {
|
||||
return req.path;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getusername() {
|
||||
return req.getUsername();
|
||||
}
|
||||
|
@ -63,12 +131,8 @@ public class RequestBean implements Serializable {
|
|||
else
|
||||
return new Date (since);
|
||||
}
|
||||
|
||||
public void setLastModified () {
|
||||
throw new RuntimeException ("The lastModified property of the Request object is read-only. "+
|
||||
"Set lastModified on the Response object if you want to mark the last modification date of a resource.");
|
||||
} */
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,31 +1,48 @@
|
|||
// RequestTrans.java
|
||||
// Copyright (c) Hannes Wallnöfer 1998-2000
|
||||
/*
|
||||
* 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.framework;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import helma.objectmodel.*;
|
||||
import helma.util.Base64;
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* A Transmitter for a request from the servlet client. Objects of this
|
||||
* class are directly exposed to JavaScript as global property req.
|
||||
*/
|
||||
|
||||
public class RequestTrans implements Externalizable {
|
||||
static final long serialVersionUID = 5398880083482000580L;
|
||||
|
||||
// the uri path of the request
|
||||
public String path;
|
||||
|
||||
// the request's session id
|
||||
public String session;
|
||||
|
||||
// the map of form and cookie data
|
||||
private Map values;
|
||||
|
||||
// the request method - 0 for GET, 1 for POST
|
||||
private byte httpMethod = 0;
|
||||
|
||||
// timestamp of client-cached version, if present in request
|
||||
private long ifModifiedSince = -1;
|
||||
|
||||
// set of ETags the client sent with If-None-Match header
|
||||
private Set etags;
|
||||
|
||||
|
@ -34,12 +51,9 @@ public class RequestTrans implements Externalizable {
|
|||
|
||||
// the name of the action being invoked
|
||||
public transient String action;
|
||||
|
||||
private transient String httpUsername;
|
||||
private transient String httpPassword;
|
||||
|
||||
static final long serialVersionUID = 5398880083482000580L;
|
||||
|
||||
/**
|
||||
* Create a new Request transmitter with an empty data map.
|
||||
*/
|
||||
|
@ -63,7 +77,6 @@ public class RequestTrans implements Externalizable {
|
|||
values.put(name, value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a value from the requests map by key.
|
||||
*/
|
||||
|
@ -87,10 +100,9 @@ public class RequestTrans implements Externalizable {
|
|||
* detect multiple identic requests.
|
||||
*/
|
||||
public int hashCode() {
|
||||
return session == null ? super.hashCode () : session.hashCode ();
|
||||
return (session == null) ? super.hashCode() : session.hashCode();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A request is considered equal to another one if it has the same user, path,
|
||||
* and request data. This is used to evaluate multiple simultanous requests only once
|
||||
|
@ -98,8 +110,8 @@ public class RequestTrans implements Externalizable {
|
|||
public boolean equals(Object what) {
|
||||
try {
|
||||
RequestTrans other = (RequestTrans) what;
|
||||
return (session.equals (other.session) &&
|
||||
path.equalsIgnoreCase (other.path) &&
|
||||
|
||||
return (session.equals(other.session) && path.equalsIgnoreCase(other.path) &&
|
||||
values.equals(other.getRequestData()));
|
||||
} catch (Exception x) {
|
||||
return false;
|
||||
|
@ -144,18 +156,35 @@ public class RequestTrans implements Externalizable {
|
|||
s.writeObject(etags);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param since ...
|
||||
*/
|
||||
public void setIfModifiedSince(long since) {
|
||||
ifModifiedSince = since;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public long getIfModifiedSince() {
|
||||
return ifModifiedSince;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param etagHeader ...
|
||||
*/
|
||||
public void setETags(String etagHeader) {
|
||||
etags = new HashSet();
|
||||
|
||||
if (etagHeader.indexOf(",") > -1) {
|
||||
StringTokenizer st = new StringTokenizer(etagHeader, ", \r\n");
|
||||
|
||||
while (st.hasMoreTokens())
|
||||
etags.add(st.nextToken());
|
||||
} else {
|
||||
|
@ -163,56 +192,96 @@ public class RequestTrans implements Externalizable {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public Set getETags() {
|
||||
return etags;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param etag ...
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public boolean hasETag(String etag) {
|
||||
if (etags == null || etag == null)
|
||||
if ((etags == null) || (etag == null)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return etags.contains(etag);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getUsername() {
|
||||
if ( httpUsername!=null )
|
||||
return httpUsername;
|
||||
String auth = (String)get("authorization");
|
||||
if ( auth==null || "".equals(auth) ) {
|
||||
return null;
|
||||
}
|
||||
decodeHttpAuth(auth);
|
||||
if (httpUsername != null) {
|
||||
return httpUsername;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
if ( httpPassword!=null )
|
||||
return httpPassword;
|
||||
String auth = (String) get("authorization");
|
||||
if ( auth==null || "".equals(auth) ) {
|
||||
|
||||
if ((auth == null) || "".equals(auth)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
decodeHttpAuth(auth);
|
||||
|
||||
return httpUsername;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getPassword() {
|
||||
if (httpPassword != null) {
|
||||
return httpPassword;
|
||||
}
|
||||
|
||||
String auth = (String) get("authorization");
|
||||
|
||||
if ((auth == null) || "".equals(auth)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
decodeHttpAuth(auth);
|
||||
|
||||
return httpPassword;
|
||||
}
|
||||
|
||||
private void decodeHttpAuth(String auth) {
|
||||
if ( auth==null )
|
||||
if (auth == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
StringTokenizer tok;
|
||||
if( auth.startsWith("Basic ") )
|
||||
tok = new StringTokenizer ( new String( Base64.decode((auth.substring(6)).toCharArray()) ), ":" );
|
||||
else
|
||||
|
||||
if (auth.startsWith("Basic ")) {
|
||||
tok = new StringTokenizer(new String(Base64.decode((auth.substring(6)).toCharArray())),
|
||||
":");
|
||||
} else {
|
||||
tok = new StringTokenizer(new String(Base64.decode(auth.toCharArray())), ":");
|
||||
}
|
||||
|
||||
try {
|
||||
httpUsername = tok.nextToken();
|
||||
} catch (NoSuchElementException e) {
|
||||
httpUsername = null;
|
||||
}
|
||||
|
||||
try {
|
||||
httpPassword = tok.nextToken();
|
||||
} catch (NoSuchElementException e) {
|
||||
httpPassword = null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,173 +1,384 @@
|
|||
/*
|
||||
* 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.framework;
|
||||
|
||||
import helma.framework.core.Application;
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
import helma.framework.core.Application;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class ResponseBean implements Serializable {
|
||||
|
||||
ResponseTrans res;
|
||||
|
||||
/**
|
||||
* Creates a new ResponseBean object.
|
||||
*
|
||||
* @param res ...
|
||||
*/
|
||||
public ResponseBean(ResponseTrans res) {
|
||||
this.res = res;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param what ...
|
||||
*/
|
||||
public void encode(Object what) {
|
||||
res.encode(what);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param what ...
|
||||
*/
|
||||
public void encodeXml(Object what) {
|
||||
res.encodeXml(what);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param what ...
|
||||
*/
|
||||
public void format(Object what) {
|
||||
res.format(what);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param url ...
|
||||
*
|
||||
* @throws RedirectException ...
|
||||
*/
|
||||
public void redirect(String url) throws RedirectException {
|
||||
res.redirect(url);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void reset() {
|
||||
res.reset();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param key ...
|
||||
* @param value ...
|
||||
*/
|
||||
public void setCookie(String key, String value) {
|
||||
res.setCookie(key, value, -1, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param key ...
|
||||
* @param value ...
|
||||
* @param days ...
|
||||
*/
|
||||
public void setCookie(String key, String value, int days) {
|
||||
res.setCookie(key, value, days, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param key ...
|
||||
* @param value ...
|
||||
* @param days ...
|
||||
* @param path ...
|
||||
*/
|
||||
public void setCookie(String key, String value, int days, String path) {
|
||||
res.setCookie(key, value, days, path, null);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param key ...
|
||||
* @param value ...
|
||||
* @param days ...
|
||||
* @param path ...
|
||||
* @param domain ...
|
||||
*/
|
||||
public void setCookie(String key, String value, int days, String path, String domain) {
|
||||
res.setCookie(key, value, days, path, domain);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param what ...
|
||||
*/
|
||||
public void write(Object what) {
|
||||
res.write(what);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param what ...
|
||||
*/
|
||||
public void writeln(Object what) {
|
||||
res.writeln(what);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param what ...
|
||||
*/
|
||||
public void writeBinary(byte[] what) {
|
||||
res.writeBinary(what);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param message ...
|
||||
*/
|
||||
public void debug(Object message) {
|
||||
res.debug(message);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String toString() {
|
||||
return "[Response]";
|
||||
}
|
||||
|
||||
|
||||
// property-related methods:
|
||||
|
||||
public boolean getcache() {
|
||||
return res.cache;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param cache ...
|
||||
*/
|
||||
public void setcache(boolean cache) {
|
||||
res.cache = cache;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getcharset() {
|
||||
return res.charset;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param charset ...
|
||||
*/
|
||||
public void setcharset(String charset) {
|
||||
res.charset = charset;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getcontentType() {
|
||||
return res.contentType;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param contentType ...
|
||||
*/
|
||||
public void setcontentType(String contentType) {
|
||||
res.contentType = contentType;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public Map getdata() {
|
||||
return res.getResponseData();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public Map gethandlers() {
|
||||
return res.getMacroHandlers();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String geterror() {
|
||||
return res.error;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getmessage() {
|
||||
return res.message;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param message ...
|
||||
*/
|
||||
public void setmessage(String message) {
|
||||
res.message = message;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getrealm() {
|
||||
return res.realm;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param realm ...
|
||||
*/
|
||||
public void setrealm(String realm) {
|
||||
res.realm = realm;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param arr ...
|
||||
*/
|
||||
public void setskinpath(Object[] arr) {
|
||||
res.setSkinpath(arr);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public Object[] getskinpath() {
|
||||
return res.getSkinpath();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public int getstatus() {
|
||||
return res.status;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param status ...
|
||||
*/
|
||||
public void setstatus(int status) {
|
||||
res.status = status;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public Date getLastModified() {
|
||||
long modified = res.getLastModified();
|
||||
if (modified > -1)
|
||||
|
||||
if (modified > -1) {
|
||||
return new Date(modified);
|
||||
else
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setLastModified (Date date) {
|
||||
if (date == null)
|
||||
res.setLastModified (-1);
|
||||
else
|
||||
res.setLastModified (date.getTime());
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param date ...
|
||||
*/
|
||||
public void setLastModified(Date date) {
|
||||
if (date == null) {
|
||||
res.setLastModified(-1);
|
||||
} else {
|
||||
res.setLastModified(date.getTime());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getETag() {
|
||||
return res.getETag();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param etag ...
|
||||
*/
|
||||
public void setETag(String etag) {
|
||||
res.setETag(etag);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param what ...
|
||||
*/
|
||||
public void dependsOn(Object what) {
|
||||
res.dependsOn(what);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void digest() {
|
||||
res.digestDependencies();
|
||||
}
|
||||
|
@ -177,14 +388,16 @@ public class ResponseBean implements Serializable {
|
|||
// Helma templates (*.hsp files) and shouldn't
|
||||
// be used otherwise.
|
||||
////////////////////////////////////
|
||||
|
||||
public void pushStringBuffer() {
|
||||
res.pushStringBuffer();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String popStringBuffer() {
|
||||
return res.popStringBuffer();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -1,21 +1,35 @@
|
|||
// ResponseTrans.java
|
||||
// Copyright (c) Hannes Wallnöfer 1998-2000
|
||||
/*
|
||||
* 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.framework;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import helma.framework.core.Skin;
|
||||
import helma.objectmodel.*;
|
||||
import helma.util.*;
|
||||
import java.io.*;
|
||||
import java.security.*;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* A Transmitter for a response to the servlet client. Objects of this
|
||||
* class are directly exposed to JavaScript as global property res.
|
||||
*/
|
||||
|
||||
public final class ResponseTrans implements Externalizable {
|
||||
static final long serialVersionUID = -8627370766119740844L;
|
||||
static final int INITIAL_BUFFER_SIZE = 2048;
|
||||
|
||||
/**
|
||||
* Set the MIME content type of the response.
|
||||
|
@ -53,8 +67,10 @@ public final class ResponseTrans implements Externalizable {
|
|||
|
||||
// the last-modified date, if it should be set in the response
|
||||
private long lastModified = -1;
|
||||
|
||||
// flag to signal that resource has not been modified
|
||||
private boolean notModified = false;
|
||||
|
||||
// Entity Tag for this response, used for conditional GETs
|
||||
private String etag = null;
|
||||
|
||||
|
@ -63,19 +79,19 @@ public final class ResponseTrans implements Externalizable {
|
|||
|
||||
// the buffer used to build the response
|
||||
private transient StringBuffer buffer = null;
|
||||
|
||||
// these are used to implement the _as_string variants for Hop templates.
|
||||
private transient Stack buffers;
|
||||
|
||||
// the path used to tell where to look for skins
|
||||
private transient Object[] skinpath = null;
|
||||
|
||||
// hashmap for skin caching
|
||||
private transient HashMap skincache;
|
||||
|
||||
// buffer for debug messages - will be automatically appended to response
|
||||
private transient StringBuffer debugBuffer;
|
||||
|
||||
static final long serialVersionUID = -8627370766119740844L;
|
||||
|
||||
/**
|
||||
* string fields that hold a user message
|
||||
*/
|
||||
|
@ -86,8 +102,6 @@ public final class ResponseTrans implements Externalizable {
|
|||
*/
|
||||
public transient String error;
|
||||
|
||||
static final int INITIAL_BUFFER_SIZE = 2048;
|
||||
|
||||
// the map of form and cookie data
|
||||
private transient Map values;
|
||||
|
||||
|
@ -103,7 +117,9 @@ public final class ResponseTrans implements Externalizable {
|
|||
// the appliciation checksum to make ETag headers sensitive to app changes
|
||||
long applicationChecksum;
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new ResponseTrans object.
|
||||
*/
|
||||
public ResponseTrans() {
|
||||
super();
|
||||
message = error = null;
|
||||
|
@ -111,12 +127,16 @@ public final class ResponseTrans implements Externalizable {
|
|||
handlers = new HashMap();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new ResponseTrans object.
|
||||
*
|
||||
* @param req ...
|
||||
*/
|
||||
public ResponseTrans(RequestTrans req) {
|
||||
this();
|
||||
reqtrans = req;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a value from the responses map by key.
|
||||
*/
|
||||
|
@ -142,13 +162,14 @@ public final class ResponseTrans implements Externalizable {
|
|||
return handlers;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reset the response object to its initial empty state.
|
||||
*/
|
||||
public void reset() {
|
||||
if (buffer != null)
|
||||
if (buffer != null) {
|
||||
buffer.setLength(0);
|
||||
}
|
||||
|
||||
buffers = null;
|
||||
response = null;
|
||||
redir = null;
|
||||
|
@ -158,20 +179,25 @@ public final class ResponseTrans implements Externalizable {
|
|||
lastModified = -1;
|
||||
notModified = false;
|
||||
etag = null;
|
||||
if (digest != null)
|
||||
|
||||
if (digest != null) {
|
||||
digest.reset();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This is called before a skin is rendered as string (renderSkinAsString) to redirect the output
|
||||
* to a new string buffer.
|
||||
*/
|
||||
public void pushStringBuffer() {
|
||||
if (buffers == null)
|
||||
if (buffers == null) {
|
||||
buffers = new Stack();
|
||||
if (buffer != null)
|
||||
}
|
||||
|
||||
if (buffer != null) {
|
||||
buffers.push(buffer);
|
||||
}
|
||||
|
||||
buffer = new StringBuffer(64);
|
||||
}
|
||||
|
||||
|
@ -180,7 +206,9 @@ public final class ResponseTrans implements Externalizable {
|
|||
*/
|
||||
public String popStringBuffer() {
|
||||
StringBuffer b = buffer;
|
||||
|
||||
buffer = buffers.empty() ? null : (StringBuffer) buffers.pop();
|
||||
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
|
@ -188,11 +216,12 @@ public final class ResponseTrans implements Externalizable {
|
|||
* Get the response buffer, creating it if it doesn't exist
|
||||
*/
|
||||
public StringBuffer getBuffer() {
|
||||
if (buffer == null)
|
||||
if (buffer == null) {
|
||||
buffer = new StringBuffer(INITIAL_BUFFER_SIZE);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Append a string to the response unchanged. This is often called
|
||||
|
@ -202,8 +231,11 @@ public final class ResponseTrans implements Externalizable {
|
|||
public void write(Object what) {
|
||||
if (what != null) {
|
||||
String str = what.toString();
|
||||
if (buffer == null)
|
||||
|
||||
if (buffer == null) {
|
||||
buffer = new StringBuffer(Math.max(str.length() + 100, INITIAL_BUFFER_SIZE));
|
||||
}
|
||||
|
||||
buffer.append(what.toString());
|
||||
}
|
||||
}
|
||||
|
@ -212,10 +244,14 @@ public final class ResponseTrans implements Externalizable {
|
|||
* Utility function that appends a <br> to whatever is written.
|
||||
*/
|
||||
public void writeln(Object what) {
|
||||
if (buffer == null)
|
||||
if (buffer == null) {
|
||||
buffer = new StringBuffer(INITIAL_BUFFER_SIZE);
|
||||
if (what != null)
|
||||
}
|
||||
|
||||
if (what != null) {
|
||||
buffer.append(what.toString());
|
||||
}
|
||||
|
||||
buffer.append("<br />\r\n");
|
||||
}
|
||||
|
||||
|
@ -223,8 +259,10 @@ public final class ResponseTrans implements Externalizable {
|
|||
* Append a part from a char array to the response buffer.
|
||||
*/
|
||||
public void writeCharArray(char[] c, int start, int length) {
|
||||
if (buffer == null)
|
||||
if (buffer == null) {
|
||||
buffer = new StringBuffer(Math.max(length, INITIAL_BUFFER_SIZE));
|
||||
}
|
||||
|
||||
buffer.append(c, start, length);
|
||||
}
|
||||
|
||||
|
@ -234,9 +272,12 @@ public final class ResponseTrans implements Externalizable {
|
|||
* case nothing happens.
|
||||
*/
|
||||
public void debug(Object message) {
|
||||
if (debugBuffer == null)
|
||||
if (debugBuffer == null) {
|
||||
debugBuffer = new StringBuffer();
|
||||
String str = message == null ? "null" : message.toString ();
|
||||
}
|
||||
|
||||
String str = (message == null) ? "null" : message.toString();
|
||||
|
||||
debugBuffer.append("<p><span style=\"background: yellow; color: black\">");
|
||||
debugBuffer.append(str);
|
||||
debugBuffer.append("</span></p>");
|
||||
|
@ -249,8 +290,11 @@ public final class ResponseTrans implements Externalizable {
|
|||
public void encode(Object what) {
|
||||
if (what != null) {
|
||||
String str = what.toString();
|
||||
if (buffer == null)
|
||||
|
||||
if (buffer == null) {
|
||||
buffer = new StringBuffer(Math.max(str.length() + 100, INITIAL_BUFFER_SIZE));
|
||||
}
|
||||
|
||||
HtmlEncoder.encodeAll(str, buffer);
|
||||
}
|
||||
}
|
||||
|
@ -261,13 +305,15 @@ public final class ResponseTrans implements Externalizable {
|
|||
public void format(Object what) {
|
||||
if (what != null) {
|
||||
String str = what.toString();
|
||||
if (buffer == null)
|
||||
|
||||
if (buffer == null) {
|
||||
buffer = new StringBuffer(Math.max(str.length() + 100, INITIAL_BUFFER_SIZE));
|
||||
}
|
||||
|
||||
HtmlEncoder.encode(str, buffer);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Replace special characters with entities, including <, > and ", thus allowing
|
||||
* no HTML tags.
|
||||
|
@ -275,39 +321,62 @@ public final class ResponseTrans implements Externalizable {
|
|||
public void encodeXml(Object what) {
|
||||
if (what != null) {
|
||||
String str = what.toString();
|
||||
if (buffer == null)
|
||||
|
||||
if (buffer == null) {
|
||||
buffer = new StringBuffer(Math.max(str.length() + 100, INITIAL_BUFFER_SIZE));
|
||||
}
|
||||
|
||||
HtmlEncoder.encodeXml(str, buffer);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Encode HTML entities, but leave newlines alone. This is for the content of textarea forms.
|
||||
*/
|
||||
public void encodeForm(Object what) {
|
||||
if (what != null) {
|
||||
String str = what.toString();
|
||||
if (buffer == null)
|
||||
|
||||
if (buffer == null) {
|
||||
buffer = new StringBuffer(Math.max(str.length() + 100, INITIAL_BUFFER_SIZE));
|
||||
}
|
||||
|
||||
HtmlEncoder.encodeAll(str, buffer, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param str ...
|
||||
*/
|
||||
public void append(String str) {
|
||||
if (str != null) {
|
||||
if (buffer == null)
|
||||
if (buffer == null) {
|
||||
buffer = new StringBuffer(Math.max(str.length(), INITIAL_BUFFER_SIZE));
|
||||
}
|
||||
|
||||
buffer.append(str);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param url ...
|
||||
*
|
||||
* @throws RedirectException ...
|
||||
*/
|
||||
public void redirect(String url) throws RedirectException {
|
||||
redir = url;
|
||||
throw new RedirectException(url);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getRedirect() {
|
||||
return redir;
|
||||
}
|
||||
|
@ -321,28 +390,34 @@ public final class ResponseTrans implements Externalizable {
|
|||
response = what;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This has to be called after writing to this response has finished and before it is shipped back to the
|
||||
* web server. Transforms the string buffer into a char array to minimize size.
|
||||
*/
|
||||
public synchronized void close(String cset) throws UnsupportedEncodingException {
|
||||
// only use default charset if not explicitly set for this response.
|
||||
if (charset == null)
|
||||
if (charset == null) {
|
||||
charset = cset;
|
||||
}
|
||||
|
||||
// if charset is not set, use western encoding
|
||||
if (charset == null)
|
||||
if (charset == null) {
|
||||
charset = "ISO-8859-1";
|
||||
}
|
||||
|
||||
boolean encodingError = false;
|
||||
|
||||
// only close if the response hasn't been closed yet
|
||||
if (response == null) {
|
||||
// if debug buffer exists, append it to main buffer
|
||||
if (debugBuffer != null) {
|
||||
if (buffer == null)
|
||||
if (buffer == null) {
|
||||
buffer = debugBuffer;
|
||||
else
|
||||
} else {
|
||||
buffer.append(debugBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
// get the buffer's bytes in the specified encoding
|
||||
if (buffer != null) {
|
||||
try {
|
||||
|
@ -351,31 +426,41 @@ public final class ResponseTrans implements Externalizable {
|
|||
encodingError = true;
|
||||
response = buffer.toString().getBytes();
|
||||
}
|
||||
|
||||
// make sure this is done only once, even with more requsts attached
|
||||
buffer = null;
|
||||
} else {
|
||||
response = new byte[0];
|
||||
}
|
||||
}
|
||||
|
||||
// if etag is not set, calc MD5 digest and check it
|
||||
if (etag == null && lastModified == -1 && redir == null) try {
|
||||
if ((etag == null) && (lastModified == -1) && (redir == null)) {
|
||||
try {
|
||||
digest = MessageDigest.getInstance("MD5");
|
||||
|
||||
// if (contentType != null)
|
||||
// digest.update (contentType.getBytes());
|
||||
byte[] b = digest.digest(response);
|
||||
|
||||
etag = "\"" + new String(Base64.encode(b)) + "\"";
|
||||
if (reqtrans != null && reqtrans.hasETag (etag)) {
|
||||
|
||||
if ((reqtrans != null) && reqtrans.hasETag(etag)) {
|
||||
response = new byte[0];
|
||||
notModified = true;
|
||||
}
|
||||
} catch (Exception ignore) {
|
||||
// Etag creation failed for some reason. Ignore.
|
||||
}
|
||||
}
|
||||
|
||||
notifyAll();
|
||||
|
||||
// if there was a problem with the encoding, let the app know
|
||||
if (encodingError)
|
||||
if (encodingError) {
|
||||
throw new UnsupportedEncodingException(charset);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If we just attached to evaluation we call this instead of close because only the primary thread
|
||||
|
@ -383,63 +468,118 @@ public final class ResponseTrans implements Externalizable {
|
|||
*/
|
||||
public synchronized void waitForClose() {
|
||||
try {
|
||||
if (response == null)
|
||||
wait (10000l);
|
||||
} catch (InterruptedException ix) {}
|
||||
if (response == null) {
|
||||
wait(10000L);
|
||||
}
|
||||
} catch (InterruptedException ix) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public byte[] getContent() {
|
||||
return response == null ? new byte[0] : response;
|
||||
return (response == null) ? new byte[0] : response;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public int getContentLength() {
|
||||
if (response != null)
|
||||
if (response != null) {
|
||||
return response.length;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getContentType() {
|
||||
if (charset != null)
|
||||
if (charset != null) {
|
||||
return contentType + "; charset=" + charset;
|
||||
}
|
||||
|
||||
return contentType;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param modified ...
|
||||
*/
|
||||
public void setLastModified(long modified) {
|
||||
if (modified > -1 && reqtrans != null &&
|
||||
reqtrans.getIfModifiedSince() >= modified)
|
||||
{
|
||||
if ((modified > -1) && (reqtrans != null) &&
|
||||
(reqtrans.getIfModifiedSince() >= modified)) {
|
||||
notModified = true;
|
||||
throw new RedirectException(null);
|
||||
}
|
||||
|
||||
lastModified = modified;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public long getLastModified() {
|
||||
return lastModified;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param value ...
|
||||
*/
|
||||
public void setETag(String value) {
|
||||
etag = value == null ? null : "\""+value+"\"";
|
||||
if (etag != null && reqtrans != null && reqtrans.hasETag (etag)) {
|
||||
etag = (value == null) ? null : ("\"" + value + "\"");
|
||||
|
||||
if ((etag != null) && (reqtrans != null) && reqtrans.hasETag(etag)) {
|
||||
notModified = true;
|
||||
throw new RedirectException(null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getETag() {
|
||||
return etag;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public boolean getNotModified() {
|
||||
return notModified;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param what ...
|
||||
*/
|
||||
public void dependsOn(Object what) {
|
||||
if (digest == null) try {
|
||||
if (digest == null) {
|
||||
try {
|
||||
digest = MessageDigest.getInstance("MD5");
|
||||
} catch (NoSuchAlgorithmException nsa) {
|
||||
// MD5 should always be available
|
||||
}
|
||||
}
|
||||
|
||||
if (what == null) {
|
||||
digest.update(new byte[0]);
|
||||
} else if (what instanceof Date) {
|
||||
|
@ -448,17 +588,25 @@ public final class ResponseTrans implements Externalizable {
|
|||
digest.update((byte[]) what);
|
||||
} else {
|
||||
String str = what.toString();
|
||||
if (str != null)
|
||||
|
||||
if (str != null) {
|
||||
digest.update(str.getBytes());
|
||||
else
|
||||
} else {
|
||||
digest.update(new byte[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void digestDependencies() {
|
||||
if (digest == null)
|
||||
if (digest == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
byte[] b = digest.digest(MD5Encoder.toBytes(applicationChecksum));
|
||||
|
||||
/* 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];
|
||||
|
@ -469,71 +617,144 @@ public final class ResponseTrans implements Externalizable {
|
|||
setETag(new String(Base64.encode(b)));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param n ...
|
||||
*/
|
||||
public void setApplicationChecksum(long n) {
|
||||
applicationChecksum = n;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param arr ...
|
||||
*/
|
||||
public void setSkinpath(Object[] arr) {
|
||||
this.skinpath = arr;
|
||||
skincache = null;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public Object[] getSkinpath() {
|
||||
if (skinpath == null)
|
||||
if (skinpath == null) {
|
||||
skinpath = new Object[0];
|
||||
}
|
||||
|
||||
return skinpath;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param id ...
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public Skin getCachedSkin(String id) {
|
||||
if (skincache == null)
|
||||
if (skincache == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (Skin) skincache.get(id);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param id ...
|
||||
* @param skin ...
|
||||
*/
|
||||
public void cacheSkin(String id, Skin skin) {
|
||||
if (skincache == null)
|
||||
if (skincache == null) {
|
||||
skincache = new HashMap();
|
||||
}
|
||||
|
||||
skincache.put(id, skin);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param key ...
|
||||
* @param value ...
|
||||
* @param days ...
|
||||
* @param path ...
|
||||
* @param domain ...
|
||||
*/
|
||||
public void setCookie(String key, String value, int days, String path, String domain) {
|
||||
CookieTrans c = null;
|
||||
|
||||
if (cookies == null) {
|
||||
cookies = new HashMap();
|
||||
} else {
|
||||
c = (CookieTrans) cookies.get(key);
|
||||
}
|
||||
|
||||
if (c == null) {
|
||||
c = new CookieTrans(key, value);
|
||||
cookies.put(key, c);
|
||||
} else {
|
||||
c.setValue(value);
|
||||
}
|
||||
|
||||
c.setDays(days);
|
||||
c.setPath(path);
|
||||
c.setDomain(domain);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void resetCookies() {
|
||||
if (cookies != null)
|
||||
if (cookies != null) {
|
||||
cookies.clear();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public int countCookies() {
|
||||
if (cookies != null)
|
||||
if (cookies != null) {
|
||||
return cookies.size();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public CookieTrans[] getCookies() {
|
||||
if (cookies == null)
|
||||
if (cookies == null) {
|
||||
return new CookieTrans[0];
|
||||
}
|
||||
|
||||
CookieTrans[] c = new CookieTrans[cookies.size()];
|
||||
|
||||
cookies.values().toArray(c);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param s ...
|
||||
*
|
||||
* @throws ClassNotFoundException ...
|
||||
* @throws IOException ...
|
||||
*/
|
||||
public void readExternal(ObjectInput s) throws ClassNotFoundException, IOException {
|
||||
contentType = (String) s.readObject();
|
||||
response = (byte[]) s.readObject();
|
||||
|
@ -548,6 +769,13 @@ public final class ResponseTrans implements Externalizable {
|
|||
etag = (String) s.readObject();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param s ...
|
||||
*
|
||||
* @throws IOException ...
|
||||
*/
|
||||
public void writeExternal(ObjectOutput s) throws IOException {
|
||||
s.writeObject(contentType);
|
||||
s.writeObject(response);
|
||||
|
@ -561,7 +789,4 @@ public final class ResponseTrans implements Externalizable {
|
|||
s.writeObject(charset);
|
||||
s.writeObject(etag);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,18 +1,31 @@
|
|||
// TimeoutException.java
|
||||
// Copyright (c) Hannes Wallnöfer 1998-2000
|
||||
/*
|
||||
* 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.framework;
|
||||
|
||||
|
||||
/**
|
||||
* TimeoutException is thrown by the request evaluator when a request could
|
||||
* not be serviced within the timeout period specified for an application.
|
||||
*/
|
||||
|
||||
public class TimeoutException extends RuntimeException {
|
||||
/**
|
||||
* Creates a new TimeoutException object.
|
||||
*/
|
||||
public TimeoutException() {
|
||||
super("Request timed out");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,21 +1,33 @@
|
|||
// ApplicationClassLoader.java
|
||||
/*
|
||||
* 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.framework.core;
|
||||
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.Enumeration;
|
||||
import java.security.CodeSource;
|
||||
import java.security.Permission;
|
||||
import java.security.PermissionCollection;
|
||||
import java.security.Permissions;
|
||||
|
||||
import java.util.Enumeration;
|
||||
|
||||
/**
|
||||
* ClassLoader subclass with package accessible addURL method.
|
||||
*/
|
||||
public class AppClassLoader extends URLClassLoader {
|
||||
|
||||
private final String appname;
|
||||
|
||||
/**
|
||||
|
@ -30,8 +42,12 @@ public class AppClassLoader extends URLClassLoader {
|
|||
super.addURL(url);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getAppName() {
|
||||
return appname;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,215 +1,497 @@
|
|||
/*
|
||||
* 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.framework.core;
|
||||
|
||||
import java.io.Serializable;
|
||||
import helma.objectmodel.INode;
|
||||
import helma.util.CronJob;
|
||||
import java.io.File;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import helma.objectmodel.INode;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class ApplicationBean implements Serializable {
|
||||
|
||||
Application app;
|
||||
|
||||
/**
|
||||
* Creates a new ApplicationBean object.
|
||||
*
|
||||
* @param app ...
|
||||
*/
|
||||
public ApplicationBean(Application app) {
|
||||
this.app = app;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void clearCache() {
|
||||
app.clearCache();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param msg ...
|
||||
*/
|
||||
public void log(Object msg) {
|
||||
String str = msg == null ? "null" : msg.toString();
|
||||
String str = (msg == null) ? "null" : msg.toString();
|
||||
|
||||
app.logEvent(str);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param logname ...
|
||||
* @param msg ...
|
||||
*/
|
||||
public void log(String logname, Object msg) {
|
||||
String str = msg == null ? "null" : msg.toString();
|
||||
String str = (msg == null) ? "null" : msg.toString();
|
||||
|
||||
app.getLogger(logname).log(str);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param msg ...
|
||||
*/
|
||||
public void debug(Object msg) {
|
||||
if (app.debug()) {
|
||||
String str = msg == null ? "null" : msg.toString();
|
||||
String str = (msg == null) ? "null" : msg.toString();
|
||||
|
||||
app.logEvent(str);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param logname ...
|
||||
* @param msg ...
|
||||
*/
|
||||
public void debug(String logname, Object msg) {
|
||||
if (app.debug()) {
|
||||
String str = msg == null ? "null" : msg.toString();
|
||||
String str = (msg == null) ? "null" : msg.toString();
|
||||
|
||||
app.getLogger(logname).log(str);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public int countSessions() {
|
||||
return app.sessions.size();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param sessionID ...
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public SessionBean getSession(String sessionID) {
|
||||
if (sessionID==null)
|
||||
if (sessionID == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Session session = app.getSession(sessionID.trim());
|
||||
if (session == null)
|
||||
|
||||
if (session == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new SessionBean(session);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param sessionID ...
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public SessionBean createSession(String sessionID) {
|
||||
if (sessionID==null)
|
||||
if (sessionID == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Session session = session = app.checkSession(sessionID.trim());
|
||||
if (session == null)
|
||||
|
||||
if (session == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new SessionBean(session);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public SessionBean[] getSessions() {
|
||||
SessionBean[] theArray = new SessionBean[app.sessions.size()];
|
||||
int i = 0;
|
||||
|
||||
for (Enumeration e = app.sessions.elements(); e.hasMoreElements();) {
|
||||
SessionBean sb = new SessionBean((Session) e.nextElement());
|
||||
|
||||
theArray[i++] = sb;
|
||||
}
|
||||
|
||||
return theArray;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param username ...
|
||||
* @param password ...
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public INode registerUser(String username, String password) {
|
||||
if (username==null || password==null || "".equals (username.trim ()) || "".equals (password.trim ()) )
|
||||
if ((username == null) || (password == null) || "".equals(username.trim()) ||
|
||||
"".equals(password.trim())) {
|
||||
return null;
|
||||
else
|
||||
} else {
|
||||
return app.registerUser(username, password);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param username ...
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public INode getUser(String username) {
|
||||
if (username==null || "".equals (username.trim()) )
|
||||
if ((username == null) || "".equals(username.trim())) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return app.getUserNode(username);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public INode[] getActiveUsers() {
|
||||
List activeUsers = app.getActiveUsers();
|
||||
|
||||
return (INode[]) activeUsers.toArray(new INode[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public INode[] getRegisteredUsers() {
|
||||
List registeredUsers = app.getRegisteredUsers();
|
||||
|
||||
return (INode[]) registeredUsers.toArray(new INode[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param usernode ...
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public SessionBean[] getSessionsForUser(INode usernode) {
|
||||
if (usernode==null)
|
||||
if (usernode == null) {
|
||||
return new SessionBean[0];
|
||||
else
|
||||
} else {
|
||||
return getSessionsForUser(usernode.getName());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param username ...
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public SessionBean[] getSessionsForUser(String username) {
|
||||
if (username==null || "".equals (username.trim ()) )
|
||||
if ((username == null) || "".equals(username.trim())) {
|
||||
return new SessionBean[0];
|
||||
}
|
||||
|
||||
List userSessions = app.getSessionsForUsername(username);
|
||||
|
||||
return (SessionBean[]) userSessions.toArray(new SessionBean[0]);
|
||||
}
|
||||
|
||||
// getter methods for readonly properties of this application
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param functionName ...
|
||||
*/
|
||||
public void addCronJob(String functionName) {
|
||||
CronJob job = new CronJob(functionName);
|
||||
|
||||
job.setFunction(functionName);
|
||||
app.customCronJobs.put(functionName, job);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param functionName ...
|
||||
* @param year ...
|
||||
* @param month ...
|
||||
* @param day ...
|
||||
* @param weekday ...
|
||||
* @param hour ...
|
||||
* @param minute ...
|
||||
*/
|
||||
public void addCronJob(String functionName, String year, String month, String day,
|
||||
String weekday, String hour, String minute) {
|
||||
CronJob job = CronJob.newJob(functionName, year, month, day, weekday, hour, minute);
|
||||
|
||||
app.customCronJobs.put(functionName, job);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param functionName ...
|
||||
*/
|
||||
public void removeCronJob(String functionName) {
|
||||
app.customCronJobs.remove(functionName);
|
||||
}
|
||||
|
||||
// getter methods for readonly properties of this application
|
||||
public int getcacheusage() {
|
||||
return app.getCacheUsage();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public INode getdata() {
|
||||
return app.getCacheNode();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public Map getmodules() {
|
||||
return app.modules;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getdir() {
|
||||
return app.getAppDir().getAbsolutePath();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getname() {
|
||||
return app.getName();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public Date getupSince() {
|
||||
return new Date(app.starttime);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public long getrequestCount() {
|
||||
return app.getRequestCount();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public long getxmlrpcCount() {
|
||||
return app.getXmlrpcCount();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public long geterrorCount() {
|
||||
return app.getErrorCount();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public Application get__app__() {
|
||||
return app;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public Map getproperties() {
|
||||
return app.getProperties();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public int getfreeThreads() {
|
||||
return app.countFreeEvaluators();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public int getactiveThreads() {
|
||||
return app.countActiveEvaluators();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public int getmaxThreads() {
|
||||
return app.countEvaluators();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param n ...
|
||||
*/
|
||||
public void setmaxThreads(int n) {
|
||||
// add one to the number to compensate for the internal scheduler.
|
||||
app.setNumberOfEvaluators(n + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public Map getSkinfiles() {
|
||||
Map skinz = new HashMap();
|
||||
|
||||
for (Iterator it = app.getPrototypes().iterator(); it.hasNext();) {
|
||||
Prototype p = (Prototype) it.next();
|
||||
|
||||
skinz.put(p.getName(), p.getSkinMap());
|
||||
}
|
||||
|
||||
return skinz;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param skinpath ...
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public Map getSkinfiles(Object[] skinpath) {
|
||||
Map skinz = new HashMap();
|
||||
|
||||
for (Iterator it = app.getPrototypes().iterator(); it.hasNext();) {
|
||||
Prototype p = (Prototype) it.next();
|
||||
|
||||
skinz.put(p.getName(), p.getSkinMap(skinpath));
|
||||
}
|
||||
|
||||
return skinz;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getAppDir() {
|
||||
return app.getAppDir().getAbsolutePath();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getServerDir() {
|
||||
File f = app.getServerDir();
|
||||
if (f == null)
|
||||
|
||||
if (f == null) {
|
||||
f = app.getAppDir();
|
||||
}
|
||||
|
||||
return f.getAbsolutePath();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String toString() {
|
||||
return "[Application " + app.getName() + "]";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,16 +1,28 @@
|
|||
// Prototype.java
|
||||
// Copyright (c) Hannes Wallnöfer 1998-2000
|
||||
/*
|
||||
* 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.framework.core;
|
||||
|
||||
import java.util.*;
|
||||
import java.io.*;
|
||||
import helma.framework.*;
|
||||
import helma.scripting.*;
|
||||
import helma.objectmodel.*;
|
||||
import helma.objectmodel.db.DbMapping;
|
||||
import helma.scripting.*;
|
||||
import helma.util.Updatable;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* The Prototype class represents Script prototypes/type defined in a Helma
|
||||
|
@ -18,40 +30,43 @@ import helma.util.Updatable;
|
|||
* as well as optional information about the mapping of this type to a
|
||||
* relational database table.
|
||||
*/
|
||||
|
||||
|
||||
public final class Prototype {
|
||||
|
||||
String name;
|
||||
Application app;
|
||||
File directory;
|
||||
|
||||
File[] files;
|
||||
long lastDirectoryListing;
|
||||
long checksum;
|
||||
|
||||
HashMap code, zippedCode;
|
||||
HashMap skins, zippedSkins;
|
||||
HashMap code;
|
||||
HashMap zippedCode;
|
||||
HashMap skins;
|
||||
HashMap zippedSkins;
|
||||
HashMap updatables;
|
||||
|
||||
// a map of this prototype's skins as raw strings
|
||||
// used for exposing skins to application (script) code (via app.skinfiles).
|
||||
SkinMap skinMap;
|
||||
|
||||
DbMapping dbmap;
|
||||
|
||||
// lastCheck is the time the prototype's files were last checked
|
||||
private long lastChecksum;
|
||||
|
||||
// lastUpdate is the time at which any of the prototype's files were
|
||||
// found updated the last time
|
||||
private long lastUpdate;
|
||||
|
||||
private Prototype parent;
|
||||
|
||||
// Tells us whether this prototype is used to script a generic Java object,
|
||||
// as opposed to a Helma objectmodel node object.
|
||||
boolean isJavaPrototype;
|
||||
|
||||
/**
|
||||
* Creates a new Prototype object.
|
||||
*
|
||||
* @param name ...
|
||||
* @param dir ...
|
||||
* @param app ...
|
||||
*/
|
||||
public Prototype(String name, File dir, Application app) {
|
||||
// app.logEvent ("Constructing Prototype "+app.getName()+"/"+name);
|
||||
this.app = app;
|
||||
|
@ -88,12 +103,15 @@ public final class Prototype {
|
|||
* Get the list of files in this prototype's directory
|
||||
*/
|
||||
public File[] getFiles() {
|
||||
if (files == null || directory.lastModified() != lastDirectoryListing) {
|
||||
if ((files == null) || (directory.lastModified() != lastDirectoryListing)) {
|
||||
lastDirectoryListing = directory.lastModified();
|
||||
files = directory.listFiles();
|
||||
if (files == null)
|
||||
|
||||
if (files == null) {
|
||||
files = new File[0];
|
||||
}
|
||||
}
|
||||
|
||||
return files;
|
||||
}
|
||||
|
||||
|
@ -104,13 +122,21 @@ public final class Prototype {
|
|||
// long start = System.currentTimeMillis();
|
||||
File[] f = getFiles();
|
||||
long c = 0;
|
||||
|
||||
for (int i = 0; i < f.length; i++)
|
||||
c += f[i].lastModified();
|
||||
|
||||
checksum = c;
|
||||
|
||||
// System.err.println ("CHECKSUM "+name+": "+(System.currentTimeMillis()-start));
|
||||
return checksum;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public boolean isUpToDate() {
|
||||
return checksum == lastChecksum;
|
||||
}
|
||||
|
@ -121,8 +147,10 @@ public final class Prototype {
|
|||
*/
|
||||
public void setParentPrototype(Prototype parent) {
|
||||
// this is not allowed for the hopobject and global prototypes
|
||||
if ("hopobject".equalsIgnoreCase (name) || "global".equalsIgnoreCase (name))
|
||||
if ("hopobject".equalsIgnoreCase(name) || "global".equalsIgnoreCase(name)) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
|
@ -138,10 +166,14 @@ public final class Prototype {
|
|||
* Check if the given prototype is within this prototype's parent chain.
|
||||
*/
|
||||
public final boolean isInstanceOf(String pname) {
|
||||
if (name.equals (pname))
|
||||
if (name.equals(pname)) {
|
||||
return true;
|
||||
if (parent != null && !"hopobject".equalsIgnoreCase (parent.getName()))
|
||||
}
|
||||
|
||||
if ((parent != null) && !"hopobject".equalsIgnoreCase(parent.getName())) {
|
||||
return parent.isInstanceOf(pname);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -149,20 +181,31 @@ public final class Prototype {
|
|||
* Register an object as handler for this prototype and all our parent prototypes.
|
||||
*/
|
||||
public final void addToHandlerMap(Map handlers, Object obj) {
|
||||
if (parent != null && !"hopobject".equalsIgnoreCase (parent.getName()))
|
||||
if ((parent != null) && !"hopobject".equalsIgnoreCase(parent.getName())) {
|
||||
parent.addToHandlerMap(handlers, obj);
|
||||
}
|
||||
|
||||
handlers.put(name, obj);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param dbmap ...
|
||||
*/
|
||||
public void setDbMapping(DbMapping dbmap) {
|
||||
this.dbmap = dbmap;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public DbMapping getDbMapping() {
|
||||
return dbmap;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a Skinfile for this prototype. This only works for skins
|
||||
* residing in the prototype directory, not for skin files in
|
||||
|
@ -170,8 +213,11 @@ public final class Prototype {
|
|||
*/
|
||||
public SkinFile getSkinFile(String sfname) {
|
||||
SkinFile sf = (SkinFile) skins.get(sfname);
|
||||
if (sf == null)
|
||||
|
||||
if (sf == null) {
|
||||
sf = (SkinFile) zippedSkins.get(sfname);
|
||||
}
|
||||
|
||||
return sf;
|
||||
}
|
||||
|
||||
|
@ -182,18 +228,23 @@ public final class Prototype {
|
|||
*/
|
||||
public Skin getSkin(String sfname) {
|
||||
SkinFile sf = getSkinFile(sfname);
|
||||
if (sf != null)
|
||||
|
||||
if (sf != null) {
|
||||
return sf.getSkin();
|
||||
else
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the last time any script has been re-read for this prototype.
|
||||
*/
|
||||
|
@ -214,6 +265,7 @@ public final class Prototype {
|
|||
* Get the time at which this prototype's scripts were checked
|
||||
* for changes for the last time.
|
||||
*/
|
||||
|
||||
/* public long getLastCheck () {
|
||||
return lastCheck;
|
||||
} */
|
||||
|
@ -227,7 +279,6 @@ public final class Prototype {
|
|||
lastChecksum = checksum;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return a clone of this prototype's actions container. Synchronized
|
||||
* to not return a map in a transient state where it is just being
|
||||
|
@ -246,9 +297,14 @@ public final class Prototype {
|
|||
return (Map) zippedCode.clone();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param action ...
|
||||
*/
|
||||
public synchronized void addActionFile(ActionFile action) {
|
||||
File f = action.getFile();
|
||||
|
||||
if (f != null) {
|
||||
code.put(action.getSourceName(), action);
|
||||
updatables.put(f.getName(), action);
|
||||
|
@ -257,8 +313,14 @@ public final class Prototype {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param template ...
|
||||
*/
|
||||
public synchronized void addTemplate(Template template) {
|
||||
File f = template.getFile();
|
||||
|
||||
if (f != null) {
|
||||
code.put(template.getSourceName(), template);
|
||||
updatables.put(f.getName(), template);
|
||||
|
@ -267,8 +329,14 @@ public final class Prototype {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param funcfile ...
|
||||
*/
|
||||
public synchronized void addFunctionFile(FunctionFile funcfile) {
|
||||
File f = funcfile.getFile();
|
||||
|
||||
if (f != null) {
|
||||
code.put(funcfile.getSourceName(), funcfile);
|
||||
updatables.put(f.getName(), funcfile);
|
||||
|
@ -277,8 +345,14 @@ public final class Prototype {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param skinfile ...
|
||||
*/
|
||||
public synchronized void addSkinFile(SkinFile skinfile) {
|
||||
File f = skinfile.getFile();
|
||||
|
||||
if (f != null) {
|
||||
skins.put(skinfile.getName(), skinfile);
|
||||
updatables.put(f.getName(), skinfile);
|
||||
|
@ -287,9 +361,14 @@ public final class Prototype {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param action ...
|
||||
*/
|
||||
public synchronized void removeActionFile(ActionFile action) {
|
||||
File f = action.getFile();
|
||||
|
||||
if (f != null) {
|
||||
code.remove(action.getSourceName());
|
||||
updatables.remove(f.getName());
|
||||
|
@ -298,8 +377,14 @@ public final class Prototype {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param funcfile ...
|
||||
*/
|
||||
public synchronized void removeFunctionFile(FunctionFile funcfile) {
|
||||
File f = funcfile.getFile();
|
||||
|
||||
if (f != null) {
|
||||
code.remove(funcfile.getSourceName());
|
||||
updatables.remove(f.getName());
|
||||
|
@ -308,8 +393,14 @@ public final class Prototype {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param template ...
|
||||
*/
|
||||
public synchronized void removeTemplate(Template template) {
|
||||
File f = template.getFile();
|
||||
|
||||
if (f != null) {
|
||||
code.remove(template.getSourceName());
|
||||
updatables.remove(f.getName());
|
||||
|
@ -318,8 +409,14 @@ public final class Prototype {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param skinfile ...
|
||||
*/
|
||||
public synchronized void removeSkinFile(SkinFile skinfile) {
|
||||
File f = skinfile.getFile();
|
||||
|
||||
if (f != null) {
|
||||
skins.remove(skinfile.getName());
|
||||
updatables.remove(f.getName());
|
||||
|
@ -328,7 +425,6 @@ public final class Prototype {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return a string representing this prototype.
|
||||
*/
|
||||
|
@ -336,7 +432,11 @@ public final class Prototype {
|
|||
return "[Prototype " + app.getName() + "/" + name + "]";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public SkinMap getSkinMap() {
|
||||
return skinMap;
|
||||
}
|
||||
|
@ -348,9 +448,7 @@ public final class Prototype {
|
|||
|
||||
// a map that dynamically expands to all skins in this prototype
|
||||
final class SkinMap extends HashMap {
|
||||
|
||||
long lastSkinmapLoad = 0;
|
||||
|
||||
Object[] skinpath;
|
||||
|
||||
SkinMap() {
|
||||
|
@ -365,46 +463,59 @@ public final class Prototype {
|
|||
|
||||
public boolean containsKey(Object key) {
|
||||
checkForUpdates();
|
||||
|
||||
return super.containsKey(key);
|
||||
}
|
||||
|
||||
public boolean containsValue(Object value) {
|
||||
checkForUpdates();
|
||||
|
||||
return super.containsValue(value);
|
||||
}
|
||||
|
||||
public Set entrySet() {
|
||||
checkForUpdates();
|
||||
|
||||
return super.entrySet();
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
checkForUpdates();
|
||||
|
||||
return super.equals(obj);
|
||||
}
|
||||
|
||||
public Object get(Object key) {
|
||||
if (key == null)
|
||||
if (key == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
checkForUpdates();
|
||||
|
||||
SkinFile sf = (SkinFile) super.get(key);
|
||||
if (sf == null)
|
||||
|
||||
if (sf == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return sf.getSkin().getSource();
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
checkForUpdates();
|
||||
|
||||
return super.hashCode();
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
checkForUpdates();
|
||||
|
||||
return super.isEmpty();
|
||||
}
|
||||
|
||||
public Set keySet() {
|
||||
checkForUpdates();
|
||||
|
||||
return super.keySet();
|
||||
}
|
||||
|
||||
|
@ -420,54 +531,66 @@ public final class Prototype {
|
|||
|
||||
public Object remove(Object key) {
|
||||
checkForUpdates();
|
||||
|
||||
return super.remove(key);
|
||||
}
|
||||
|
||||
public int size() {
|
||||
checkForUpdates();
|
||||
|
||||
return super.size();
|
||||
}
|
||||
|
||||
public Collection values() {
|
||||
checkForUpdates();
|
||||
|
||||
return super.values();
|
||||
}
|
||||
|
||||
|
||||
private void checkForUpdates() {
|
||||
if (/* lastCheck < System.currentTimeMillis()- 2000l*/ !isUpToDate())
|
||||
if ( /* lastCheck < System.currentTimeMillis()- 2000l*/
|
||||
!isUpToDate()) {
|
||||
app.typemgr.updatePrototype(Prototype.this);
|
||||
if (lastUpdate > lastSkinmapLoad)
|
||||
}
|
||||
|
||||
if (lastUpdate > lastSkinmapLoad) {
|
||||
load();
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized void load() {
|
||||
if (lastUpdate == lastSkinmapLoad)
|
||||
if (lastUpdate == lastSkinmapLoad) {
|
||||
return;
|
||||
}
|
||||
|
||||
super.clear();
|
||||
|
||||
// System.err.println ("LOADING SKIN VALUES: "+Prototype.this);
|
||||
for (Iterator i = skins.entrySet().iterator(); i.hasNext();) {
|
||||
Map.Entry e = (Map.Entry) i.next();
|
||||
|
||||
super.put(e.getKey(), e.getValue());
|
||||
}
|
||||
|
||||
// if skinpath is not null, overload/add skins from there
|
||||
if (skinpath != null) {
|
||||
for (int i = skinpath.length - 1; i >= 0; i--) {
|
||||
if (skinpath[i] != null && skinpath[i] instanceof String) {
|
||||
Map m = app.skinmgr.getSkinFiles ((String) skinpath[i], Prototype.this);
|
||||
if (m != null)
|
||||
if ((skinpath[i] != null) && skinpath[i] instanceof String) {
|
||||
Map m = app.skinmgr.getSkinFiles((String) skinpath[i],
|
||||
Prototype.this);
|
||||
|
||||
if (m != null) {
|
||||
super.putAll(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lastSkinmapLoad = lastUpdate;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "[SkinMap " + name + "]";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,18 @@
|
|||
// RemoteApplication.java
|
||||
// Copyright (c) Hannes Wallnöfer 2002
|
||||
/*
|
||||
* 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.framework.core;
|
||||
|
||||
|
@ -12,19 +25,21 @@ import java.util.Vector;
|
|||
/**
|
||||
* Proxy class for Aplication that listens to requests via RMI.
|
||||
*/
|
||||
|
||||
public class RemoteApplication
|
||||
extends UnicastRemoteObject
|
||||
implements IRemoteApp, IReplicationListener {
|
||||
|
||||
public class RemoteApplication extends UnicastRemoteObject implements IRemoteApp,
|
||||
IReplicationListener {
|
||||
Application app;
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new RemoteApplication object.
|
||||
*
|
||||
* @param app ...
|
||||
*
|
||||
* @throws RemoteException ...
|
||||
*/
|
||||
public RemoteApplication(Application app) throws RemoteException {
|
||||
this.app = app;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ping method to let clients know if the server is reachable
|
||||
*/
|
||||
|
@ -39,7 +54,6 @@ public class RemoteApplication
|
|||
return app.execute(req);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Update HopObjects in this application's cache. This is used to replicate
|
||||
* application caches in a distributed app environment
|
||||
|
@ -49,6 +63,7 @@ public class RemoteApplication
|
|||
app.logEvent("Rejecting cache replication event: allowReplication property is not set to true");
|
||||
throw new RuntimeException("Replication event rejected: setup does not allow replication.");
|
||||
}
|
||||
|
||||
app.nmgr.replicateCache(add, delete);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,15 +1,28 @@
|
|||
// RequestEvaluator.java
|
||||
// Copyright (c) Hannes Wallnöfer 1998-2000
|
||||
/*
|
||||
* 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.framework.core;
|
||||
|
||||
import helma.framework.*;
|
||||
import helma.objectmodel.*;
|
||||
import helma.objectmodel.db.*;
|
||||
import helma.framework.*;
|
||||
import helma.scripting.*;
|
||||
import helma.util.*;
|
||||
import java.util.*;
|
||||
import java.lang.reflect.*;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* This class does the work for incoming requests. It holds a transactor thread
|
||||
|
@ -18,17 +31,15 @@ import java.lang.reflect.*;
|
|||
* specified by the application has passed. In the latter case, the evaluator thread
|
||||
* is killed and an error message is returned.
|
||||
*/
|
||||
|
||||
public final class RequestEvaluator implements Runnable {
|
||||
|
||||
|
||||
static final int NONE = 0; // no request
|
||||
static final int HTTP = 1; // via HTTP gateway
|
||||
static final int XMLRPC = 2; // via XML-RPC
|
||||
static final int INTERNAL = 3; // generic function call, e.g. by scheduler
|
||||
public final Application app;
|
||||
|
||||
protected ScriptingEngine scriptingEngine;
|
||||
|
||||
public RequestTrans req;
|
||||
public ResponseTrans res;
|
||||
|
||||
volatile Transactor rtx;
|
||||
|
||||
// the object on which to invoke a function, if specified
|
||||
|
@ -54,11 +65,6 @@ public final class RequestEvaluator implements Runnable {
|
|||
|
||||
// the type of request to be serviced
|
||||
int reqtype;
|
||||
static final int NONE = 0; // no request
|
||||
static final int HTTP = 1; // via HTTP gateway
|
||||
static final int XMLRPC = 2; // via XML-RPC
|
||||
static final int INTERNAL = 3; // generic function call, e.g. by scheduler
|
||||
|
||||
protected int skinDepth;
|
||||
|
||||
/**
|
||||
|
@ -70,17 +76,21 @@ public final class RequestEvaluator implements Runnable {
|
|||
|
||||
protected void initScriptingEngine() {
|
||||
if (scriptingEngine == null) {
|
||||
String engineClassName = app.getProperty (
|
||||
"scriptingEngine",
|
||||
String engineClassName = app.getProperty("scriptingEngine",
|
||||
"helma.scripting.fesi.PhantomEngine");
|
||||
|
||||
try {
|
||||
Class clazz = app.getClassLoader().loadClass(engineClassName);
|
||||
|
||||
scriptingEngine = (ScriptingEngine) clazz.newInstance();
|
||||
scriptingEngine.init(app, this);
|
||||
} catch (Exception x) {
|
||||
Throwable t = x;
|
||||
if (x instanceof InvocationTargetException)
|
||||
|
||||
if (x instanceof InvocationTargetException) {
|
||||
t = ((InvocationTargetException) x).getTargetException();
|
||||
}
|
||||
|
||||
app.logEvent("******************************************");
|
||||
app.logEvent("*** Error creating scripting engine: ");
|
||||
app.logEvent("*** " + t.toString());
|
||||
|
@ -89,43 +99,50 @@ public final class RequestEvaluator implements Runnable {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void run() {
|
||||
|
||||
int txcount = 0;
|
||||
|
||||
// first, set a local variable to the current transactor thread so we know
|
||||
// when it's time to quit because another thread took over.
|
||||
Transactor localrtx = (Transactor) Thread.currentThread();
|
||||
|
||||
try {
|
||||
do {
|
||||
|
||||
// long startCheck = System.currentTimeMillis ();
|
||||
app.typemgr.checkPrototypes();
|
||||
initScriptingEngine();
|
||||
scriptingEngine.updatePrototypes();
|
||||
// System.err.println ("Type check overhead: "+(System.currentTimeMillis ()-startCheck)+" millis");
|
||||
|
||||
// System.err.println ("Type check overhead: "+(System.currentTimeMillis ()-startCheck)+" millis");
|
||||
// object refs to ressolve request path
|
||||
Object root, currentElement;
|
||||
Object root;
|
||||
|
||||
// System.err.println ("Type check overhead: "+(System.currentTimeMillis ()-startCheck)+" millis");
|
||||
// object refs to ressolve request path
|
||||
Object currentElement;
|
||||
|
||||
requestPath = new ArrayList();
|
||||
|
||||
switch (reqtype) {
|
||||
case HTTP:
|
||||
|
||||
int tries = 0;
|
||||
boolean done = false;
|
||||
String error = null;
|
||||
|
||||
while (!done) {
|
||||
|
||||
currentElement = null;
|
||||
|
||||
try {
|
||||
|
||||
// used for logging
|
||||
StringBuffer txname = new StringBuffer(app.getName());
|
||||
|
||||
txname.append("/");
|
||||
txname.append (error == null ? req.path : "error");
|
||||
txname.append((error == null) ? req.path : "error");
|
||||
|
||||
// begin transaction
|
||||
localrtx.begin(txname.toString());
|
||||
|
||||
|
@ -134,6 +151,7 @@ public final class RequestEvaluator implements Runnable {
|
|||
root = app.getDataRoot();
|
||||
|
||||
HashMap globals = new HashMap();
|
||||
|
||||
globals.put("root", root);
|
||||
globals.put("session", new SessionBean(session));
|
||||
globals.put("req", new RequestBean(req));
|
||||
|
@ -141,44 +159,57 @@ public final class RequestEvaluator implements Runnable {
|
|||
globals.put("app", new ApplicationBean(app));
|
||||
globals.put("path", requestPath);
|
||||
req.startTime = System.currentTimeMillis();
|
||||
if (error != null)
|
||||
|
||||
if (error != null) {
|
||||
res.error = error;
|
||||
}
|
||||
|
||||
if (session.message != null) {
|
||||
// bring over the message from a redirect
|
||||
res.message = session.message;
|
||||
session.message = null;
|
||||
}
|
||||
|
||||
Map macroHandlers = res.getMacroHandlers();
|
||||
|
||||
try {
|
||||
|
||||
if (error != null) {
|
||||
// there was an error in the previous loop, call error handler
|
||||
currentElement = root;
|
||||
|
||||
// do not reset the requestPath so error handler can use the original one
|
||||
// get error handler action
|
||||
String errorAction = app.props.getProperty ("error", "error");
|
||||
action = getAction (currentElement, errorAction);
|
||||
if (action == null)
|
||||
throw new RuntimeException (error);
|
||||
String errorAction = app.props.getProperty("error",
|
||||
"error");
|
||||
|
||||
} else if (req.path == null || "".equals (req.path.trim ())) {
|
||||
action = getAction(currentElement, errorAction);
|
||||
|
||||
if (action == null) {
|
||||
throw new RuntimeException(error);
|
||||
}
|
||||
} else if ((req.path == null) ||
|
||||
"".equals(req.path.trim())) {
|
||||
currentElement = root;
|
||||
requestPath.add(currentElement);
|
||||
macroHandlers.put("root", root);
|
||||
action = getAction(currentElement, null);
|
||||
if (action == null)
|
||||
|
||||
if (action == null) {
|
||||
throw new FrameworkException("Action not found");
|
||||
|
||||
}
|
||||
} else {
|
||||
|
||||
// march down request path...
|
||||
StringTokenizer st = new StringTokenizer (req.path, "/");
|
||||
StringTokenizer st = new StringTokenizer(req.path,
|
||||
"/");
|
||||
int ntokens = st.countTokens();
|
||||
|
||||
// limit path to < 50 tokens
|
||||
if (ntokens > 50)
|
||||
if (ntokens > 50) {
|
||||
throw new RuntimeException("Path too long");
|
||||
}
|
||||
|
||||
String[] pathItems = new String[ntokens];
|
||||
|
||||
for (int i = 0; i < ntokens; i++)
|
||||
pathItems[i] = st.nextToken();
|
||||
|
||||
|
@ -187,66 +218,80 @@ public final class RequestEvaluator implements Runnable {
|
|||
macroHandlers.put("root", root);
|
||||
|
||||
for (int i = 0; i < ntokens; i++) {
|
||||
|
||||
if (currentElement == null)
|
||||
if (currentElement == null) {
|
||||
throw new FrameworkException("Object not found.");
|
||||
}
|
||||
|
||||
if (pathItems[i].length () == 0)
|
||||
if (pathItems[i].length() == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// we used to do special processing for /user and /users
|
||||
// here but with the framework cleanup, this stuff has to be
|
||||
// mounted manually.
|
||||
|
||||
// if we're at the last element of the path,
|
||||
// try to interpret it as action name.
|
||||
if (i == ntokens-1) {
|
||||
action = getAction (currentElement, pathItems[i]);
|
||||
if (i == (ntokens - 1)) {
|
||||
action = getAction(currentElement,
|
||||
pathItems[i]);
|
||||
}
|
||||
|
||||
if (action == null) {
|
||||
|
||||
currentElement = app.getChildElement (currentElement, pathItems[i]);
|
||||
currentElement = app.getChildElement(currentElement,
|
||||
pathItems[i]);
|
||||
|
||||
// add object to request path if suitable
|
||||
if (currentElement != null) {
|
||||
// add to requestPath array
|
||||
requestPath.add(currentElement);
|
||||
|
||||
Prototype proto = app.getPrototype(currentElement);
|
||||
if (proto != null)
|
||||
proto.addToHandlerMap (macroHandlers, currentElement);
|
||||
|
||||
if (proto != null) {
|
||||
proto.addToHandlerMap(macroHandlers,
|
||||
currentElement);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (currentElement == null)
|
||||
if (currentElement == null) {
|
||||
throw new FrameworkException("Object not found.");
|
||||
}
|
||||
|
||||
if (action == null)
|
||||
if (action == null) {
|
||||
action = getAction(currentElement, null);
|
||||
}
|
||||
|
||||
if (action == null)
|
||||
if (action == null) {
|
||||
throw new FrameworkException("Action not found");
|
||||
}
|
||||
|
||||
}
|
||||
} catch (FrameworkException notfound) {
|
||||
if (error != null)
|
||||
if (error != null) {
|
||||
|
||||
// we already have an error and the error template wasn't found,
|
||||
// display it instead of notfound message
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
// The path could not be resolved. Check if there is a "not found" action
|
||||
// specified in the property file.
|
||||
res.status = 404;
|
||||
String notFoundAction = app.props.getProperty ("notFound", "notfound");
|
||||
|
||||
String notFoundAction = app.props.getProperty("notFound",
|
||||
"notfound");
|
||||
|
||||
currentElement = root;
|
||||
action = getAction(currentElement, notFoundAction);
|
||||
if (action == null)
|
||||
|
||||
if (action == null) {
|
||||
throw new FrameworkException(notfound.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// end of path resolution section
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// beginning of execution section
|
||||
try {
|
||||
|
@ -255,6 +300,7 @@ public final class RequestEvaluator implements Runnable {
|
|||
|
||||
// set the req.action property, cutting off the _action suffix
|
||||
req.action = action.substring(0, action.length() - 7);
|
||||
|
||||
// set the application checksum in response to make ETag
|
||||
// generation sensitive to changes in the app
|
||||
res.setApplicationChecksum(app.getChecksum());
|
||||
|
@ -265,8 +311,12 @@ public final class RequestEvaluator implements Runnable {
|
|||
// try calling onRequest() function on object before
|
||||
// calling the actual action
|
||||
try {
|
||||
if (scriptingEngine.hasFunction (currentElement, "onRequest"))
|
||||
scriptingEngine.invoke (currentElement, "onRequest", new Object[0], false);
|
||||
if (scriptingEngine.hasFunction(currentElement,
|
||||
"onRequest")) {
|
||||
scriptingEngine.invoke(currentElement,
|
||||
"onRequest",
|
||||
new Object[0], false);
|
||||
}
|
||||
} catch (RedirectException redir) {
|
||||
throw redir;
|
||||
}
|
||||
|
@ -275,48 +325,57 @@ public final class RequestEvaluator implements Runnable {
|
|||
skinDepth = 0;
|
||||
|
||||
// do the actual action invocation
|
||||
scriptingEngine.invoke (currentElement, action, new Object[0], false);
|
||||
|
||||
scriptingEngine.invoke(currentElement, action,
|
||||
new Object[0], false);
|
||||
} catch (RedirectException redirect) {
|
||||
// res.redirect = redirect.getMessage ();
|
||||
// if there is a message set, save it on the user object for the next request
|
||||
if (res.message != null)
|
||||
if (res.message != null) {
|
||||
session.message = res.message;
|
||||
}
|
||||
|
||||
done = true;
|
||||
}
|
||||
|
||||
// check if we're still the one and only or if the waiting thread has given up on us already
|
||||
commitTransaction();
|
||||
done = true;
|
||||
|
||||
} catch (ConcurrencyException x) {
|
||||
|
||||
res.reset();
|
||||
|
||||
if (++tries < 8) {
|
||||
// try again after waiting some period
|
||||
abortTransaction(true);
|
||||
|
||||
try {
|
||||
// wait a bit longer with each try
|
||||
int base = 800 * tries;
|
||||
Thread.currentThread ().sleep ((long) (base + Math.random ()*base*2));
|
||||
} catch (Exception ignore) {}
|
||||
|
||||
Thread.currentThread().sleep((long) (base +
|
||||
(Math.random() * base * 2)));
|
||||
} catch (Exception ignore) {
|
||||
}
|
||||
|
||||
continue;
|
||||
} else {
|
||||
abortTransaction(false);
|
||||
|
||||
if (error == null) {
|
||||
app.errorCount += 1;
|
||||
|
||||
// set done to false so that the error will be processed
|
||||
done = false;
|
||||
error = "Couldn't complete transaction due to heavy object traffic (tried "+tries+" times)";
|
||||
error = "Couldn't complete transaction due to heavy object traffic (tried " +
|
||||
tries + " times)";
|
||||
} else {
|
||||
// error in error action. use traditional minimal error message
|
||||
res.write ("<b>Error in application '"+app.getName()+"':</b> <br><br><pre>"+error+"</pre>");
|
||||
res.write("<b>Error in application '" +
|
||||
app.getName() + "':</b> <br><br><pre>" +
|
||||
error + "</pre>");
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception x) {
|
||||
|
||||
abortTransaction(false);
|
||||
|
||||
// If the transactor thread has been killed by the invoker thread we don't have to
|
||||
|
@ -330,30 +389,41 @@ public final class RequestEvaluator implements Runnable {
|
|||
// check if we tried to process the error already
|
||||
if (error == null) {
|
||||
app.errorCount += 1;
|
||||
app.logEvent ("Exception in "+Thread.currentThread()+": "+x);
|
||||
app.logEvent("Exception in " +
|
||||
Thread.currentThread() + ": " + x);
|
||||
|
||||
// set done to false so that the error will be processed
|
||||
done = false;
|
||||
error = x.getMessage();
|
||||
if (error == null || error.length() == 0)
|
||||
|
||||
if ((error == null) || (error.length() == 0)) {
|
||||
error = x.toString();
|
||||
if (error == null)
|
||||
error = "Unspecified error";
|
||||
} else {
|
||||
// error in error action. use traditional minimal error message
|
||||
res.write ("<b>Error in application '"+app.getName()+"':</b> <br><br><pre>"+error+"</pre>");
|
||||
done = true;
|
||||
}
|
||||
|
||||
if (error == null) {
|
||||
error = "Unspecified error";
|
||||
}
|
||||
} else {
|
||||
// error in error action. use traditional minimal error message
|
||||
res.write("<b>Error in application '" +
|
||||
app.getName() + "':</b> <br><br><pre>" +
|
||||
error + "</pre>");
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case XMLRPC:
|
||||
|
||||
try {
|
||||
localrtx.begin(app.getName() + ":xmlrpc:" + method);
|
||||
|
||||
root = app.getDataRoot();
|
||||
|
||||
HashMap globals = new HashMap();
|
||||
|
||||
globals.put("root", root);
|
||||
globals.put("res", new ResponseBean(res));
|
||||
globals.put("app", new ApplicationBean(app));
|
||||
|
@ -365,30 +435,39 @@ public final class RequestEvaluator implements Runnable {
|
|||
if (method.indexOf(".") > -1) {
|
||||
StringTokenizer st = new StringTokenizer(method, ".");
|
||||
int cnt = st.countTokens();
|
||||
|
||||
for (int i = 1; i < cnt; i++) {
|
||||
String next = st.nextToken();
|
||||
currentElement = app.getChildElement (currentElement, next);
|
||||
|
||||
currentElement = app.getChildElement(currentElement,
|
||||
next);
|
||||
}
|
||||
|
||||
if (currentElement == null) {
|
||||
throw new FrameworkException("Method name \"" +
|
||||
method +
|
||||
"\" could not be resolved.");
|
||||
}
|
||||
|
||||
if (currentElement == null)
|
||||
throw new FrameworkException ("Method name \""+method+"\" could not be resolved.");
|
||||
method = st.nextToken();
|
||||
}
|
||||
|
||||
// check XML-RPC access permissions
|
||||
String proto = app.getPrototypeName(currentElement);
|
||||
|
||||
app.checkXmlRpcAccess(proto, method);
|
||||
|
||||
// reset skin recursion detection counter
|
||||
skinDepth = 0;
|
||||
|
||||
result = scriptingEngine.invoke (currentElement, method, args, true);
|
||||
result = scriptingEngine.invoke(currentElement, method, args,
|
||||
true);
|
||||
commitTransaction();
|
||||
|
||||
} catch (Exception x) {
|
||||
|
||||
abortTransaction(false);
|
||||
|
||||
app.logEvent ("Exception in "+Thread.currentThread()+": "+x);
|
||||
app.logEvent("Exception in " + Thread.currentThread() + ": " +
|
||||
x);
|
||||
|
||||
// If the transactor thread has been killed by the invoker thread we don't have to
|
||||
// bother for the error message, just quit.
|
||||
|
@ -400,49 +479,57 @@ public final class RequestEvaluator implements Runnable {
|
|||
}
|
||||
|
||||
break;
|
||||
|
||||
case INTERNAL:
|
||||
|
||||
// Just a human readable descriptor of this invocation
|
||||
String funcdesc = app.getName() + ":internal:" + method;
|
||||
|
||||
// if thisObject is an instance of NodeHandle, get the node object itself.
|
||||
if (thisObject != null && thisObject instanceof NodeHandle) {
|
||||
if ((thisObject != null) && thisObject instanceof NodeHandle) {
|
||||
thisObject = ((NodeHandle) thisObject).getNode(app.nmgr.safe);
|
||||
|
||||
// see if a valid node was returned
|
||||
if (thisObject == null) {
|
||||
reqtype = NONE;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// avoid going into transaction if called function doesn't exist
|
||||
boolean functionexists = true;
|
||||
|
||||
functionexists = scriptingEngine.hasFunction(thisObject, method);
|
||||
|
||||
if (!functionexists) {
|
||||
// function doesn't exist, nothing to do here.
|
||||
reqtype = NONE;
|
||||
} else try {
|
||||
} else {
|
||||
try {
|
||||
localrtx.begin(funcdesc);
|
||||
|
||||
root = app.getDataRoot();
|
||||
|
||||
HashMap globals = new HashMap();
|
||||
|
||||
globals.put("root", root);
|
||||
globals.put("res", new ResponseBean(res));
|
||||
globals.put("app", new ApplicationBean(app));
|
||||
|
||||
scriptingEngine.enterContext(globals);
|
||||
|
||||
// reset skin recursion detection counter
|
||||
skinDepth = 0;
|
||||
|
||||
result = scriptingEngine.invoke (thisObject, method, args, false);
|
||||
result = scriptingEngine.invoke(thisObject, method, args,
|
||||
false);
|
||||
commitTransaction();
|
||||
|
||||
} catch (Exception x) {
|
||||
|
||||
abortTransaction(false);
|
||||
|
||||
app.logEvent ("Exception in "+Thread.currentThread()+": "+x);
|
||||
app.logEvent("Exception in " + Thread.currentThread() +
|
||||
": " + x);
|
||||
|
||||
// If the transactor thread has been killed by the invoker thread we don't have to
|
||||
// bother for the error message, just quit.
|
||||
|
@ -452,9 +539,9 @@ public final class RequestEvaluator implements Runnable {
|
|||
|
||||
this.exception = x;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
// exit execution context
|
||||
|
@ -464,13 +551,12 @@ public final class RequestEvaluator implements Runnable {
|
|||
// if localrtx != rtx, the current thread has been aborted and there's no need to notify
|
||||
if (localrtx != rtx) {
|
||||
localrtx.closeConnections();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
notifyAndWait();
|
||||
|
||||
} while (localrtx == rtx);
|
||||
|
||||
} finally {
|
||||
localrtx.closeConnections();
|
||||
}
|
||||
|
@ -481,6 +567,7 @@ public final class RequestEvaluator implements Runnable {
|
|||
*/
|
||||
synchronized void commitTransaction() throws Exception {
|
||||
Transactor localrtx = (Transactor) Thread.currentThread();
|
||||
|
||||
if (localrtx == rtx) {
|
||||
reqtype = NONE;
|
||||
localrtx.commit();
|
||||
|
@ -491,11 +578,15 @@ public final class RequestEvaluator implements Runnable {
|
|||
|
||||
synchronized void abortTransaction(boolean retry) {
|
||||
Transactor localrtx = (Transactor) Thread.currentThread();
|
||||
if (!retry && localrtx == rtx)
|
||||
|
||||
if (!retry && (localrtx == rtx)) {
|
||||
reqtype = NONE;
|
||||
}
|
||||
|
||||
try {
|
||||
localrtx.abort();
|
||||
} catch (Exception ignore) {}
|
||||
} catch (Exception ignore) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -503,25 +594,41 @@ public final class RequestEvaluator implements Runnable {
|
|||
*/
|
||||
synchronized void notifyAndWait() {
|
||||
Transactor localrtx = (Transactor) Thread.currentThread();
|
||||
if (reqtype != NONE)
|
||||
|
||||
if (reqtype != NONE) {
|
||||
return; // is there a new request already?
|
||||
}
|
||||
|
||||
notifyAll();
|
||||
|
||||
try {
|
||||
// wait for request, max 10 min
|
||||
wait(1000 * 60 * 10);
|
||||
|
||||
// if no request arrived, release ressources and thread
|
||||
if (reqtype == NONE && rtx == localrtx) {
|
||||
if ((reqtype == NONE) && (rtx == localrtx)) {
|
||||
// comment this in to release not just the thread, but also the scripting engine.
|
||||
// currently we don't do this because of the risk of memory leaks (objects from
|
||||
// framework referencing into the scripting engine)
|
||||
// scriptingEngine = null;
|
||||
rtx = null;
|
||||
}
|
||||
} catch (InterruptedException ir) {}
|
||||
} catch (InterruptedException ir) {
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized ResponseTrans invoke (RequestTrans req, Session session) throws Exception {
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param req ...
|
||||
* @param session ...
|
||||
*
|
||||
* @return ...
|
||||
*
|
||||
* @throws Exception ...
|
||||
*/
|
||||
public synchronized ResponseTrans invoke(RequestTrans req, Session session)
|
||||
throws Exception {
|
||||
this.reqtype = HTTP;
|
||||
this.req = req;
|
||||
this.session = session;
|
||||
|
@ -531,14 +638,15 @@ public final class RequestEvaluator implements Runnable {
|
|||
|
||||
checkThread();
|
||||
wait(app.requestTimeout);
|
||||
|
||||
if (reqtype != NONE) {
|
||||
app.logEvent("Stopping Thread for Request " + app.getName() + "/" + req.path);
|
||||
stopThread();
|
||||
res.reset();
|
||||
res.write ("<b>Error in application '" +
|
||||
app.getName() +
|
||||
res.write("<b>Error in application '" + app.getName() +
|
||||
"':</b> <br><br><pre>Request timed out.</pre>");
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -546,18 +654,34 @@ public final class RequestEvaluator implements Runnable {
|
|||
* This checks if the Evaluator is already executing an equal request. If so, attach to it and
|
||||
* wait for it to complete. Otherwise return null, so the application knows it has to run the request.
|
||||
*/
|
||||
public synchronized ResponseTrans attachRequest (RequestTrans req) throws InterruptedException {
|
||||
if (this.req == null || res == null || !this.req.equals (req))
|
||||
public synchronized ResponseTrans attachRequest(RequestTrans req)
|
||||
throws InterruptedException {
|
||||
if ((this.req == null) || (res == null) || !this.req.equals(req)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// we already know our response object
|
||||
ResponseTrans r = res;
|
||||
if (reqtype != NONE)
|
||||
|
||||
if (reqtype != NONE) {
|
||||
wait(app.requestTimeout);
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
public synchronized Object invokeXmlRpc (String method, Object[] args) throws Exception {
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param method ...
|
||||
* @param args ...
|
||||
*
|
||||
* @return ...
|
||||
*
|
||||
* @throws Exception ...
|
||||
*/
|
||||
public synchronized Object invokeXmlRpc(String method, Object[] args)
|
||||
throws Exception {
|
||||
this.reqtype = XMLRPC;
|
||||
this.session = null;
|
||||
this.method = method;
|
||||
|
@ -568,22 +692,69 @@ public final class RequestEvaluator implements Runnable {
|
|||
|
||||
checkThread();
|
||||
wait(app.requestTimeout);
|
||||
|
||||
if (reqtype != NONE) {
|
||||
stopThread();
|
||||
}
|
||||
|
||||
// reset res for garbage collection (res.data may hold reference to evaluator)
|
||||
res = null;
|
||||
if (exception != null)
|
||||
|
||||
if (exception != null) {
|
||||
throw (exception);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public Object invokeDirectFunction (Object obj, String functionName, Object[] args) throws Exception {
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param obj ...
|
||||
* @param functionName ...
|
||||
* @param args ...
|
||||
*
|
||||
* @return ...
|
||||
*
|
||||
* @throws Exception ...
|
||||
*/
|
||||
public Object invokeDirectFunction(Object obj, String functionName, Object[] args)
|
||||
throws Exception {
|
||||
return scriptingEngine.invoke(obj, functionName, args, false);
|
||||
}
|
||||
|
||||
public synchronized Object invokeFunction (Object object, String functionName, Object[] args)
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param object ...
|
||||
* @param functionName ...
|
||||
* @param args ...
|
||||
*
|
||||
* @return ...
|
||||
*
|
||||
* @throws Exception ...
|
||||
*/
|
||||
public synchronized Object invokeFunction(Object object, String functionName,
|
||||
Object[] args)
|
||||
throws Exception {
|
||||
// give internal call more time (15 minutes) to complete
|
||||
return invokeFunction(object, functionName, args, 60000L * 15);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param object ...
|
||||
* @param functionName ...
|
||||
* @param args ...
|
||||
* @param timeout ...
|
||||
*
|
||||
* @return ...
|
||||
*
|
||||
* @throws Exception ...
|
||||
*/
|
||||
public synchronized Object invokeFunction(Object object, String functionName,
|
||||
Object[] args, long timeout)
|
||||
throws Exception {
|
||||
reqtype = INTERNAL;
|
||||
session = null;
|
||||
|
@ -595,7 +766,7 @@ public final class RequestEvaluator implements Runnable {
|
|||
exception = null;
|
||||
|
||||
checkThread();
|
||||
wait (60000l*15); // give internal call more time (15 minutes) to complete
|
||||
wait(timeout);
|
||||
|
||||
if (reqtype != NONE) {
|
||||
stopThread();
|
||||
|
@ -603,12 +774,27 @@ public final class RequestEvaluator implements Runnable {
|
|||
|
||||
// reset res for garbage collection (res.data may hold reference to evaluator)
|
||||
res = null;
|
||||
if (exception != null)
|
||||
|
||||
if (exception != null) {
|
||||
throw (exception);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public synchronized Object invokeFunction (Session session, String functionName, Object[] args)
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param session ...
|
||||
* @param functionName ...
|
||||
* @param args ...
|
||||
*
|
||||
* @return ...
|
||||
*
|
||||
* @throws Exception ...
|
||||
*/
|
||||
public synchronized Object invokeFunction(Session session, String functionName,
|
||||
Object[] args)
|
||||
throws Exception {
|
||||
reqtype = INTERNAL;
|
||||
this.session = session;
|
||||
|
@ -628,44 +814,53 @@ public final class RequestEvaluator implements Runnable {
|
|||
|
||||
// reset res for garbage collection (res.data may hold reference to evaluator)
|
||||
res = null;
|
||||
if (exception != null)
|
||||
|
||||
if (exception != null) {
|
||||
throw (exception);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Stop this request evaluator's current thread. If currently active kill the request, otherwise just
|
||||
* notify.
|
||||
*/
|
||||
public synchronized void stopThread() {
|
||||
app.logEvent("Stopping Thread " + rtx);
|
||||
|
||||
Transactor t = rtx;
|
||||
|
||||
// let the scripting engine know that the
|
||||
// current transaction is being aborted.
|
||||
if (scriptingEngine != null)
|
||||
if (scriptingEngine != null) {
|
||||
scriptingEngine.abort();
|
||||
}
|
||||
|
||||
rtx = null;
|
||||
|
||||
if (t != null) {
|
||||
if (reqtype != NONE) {
|
||||
reqtype = NONE;
|
||||
t.kill();
|
||||
|
||||
try {
|
||||
t.abort();
|
||||
} catch (Exception ignore) {}
|
||||
} catch (Exception ignore) {
|
||||
}
|
||||
} else {
|
||||
notifyAll();
|
||||
}
|
||||
|
||||
t.closeConnections();
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized void checkThread() throws InterruptedException {
|
||||
|
||||
if (app.stopped)
|
||||
if (app.stopped) {
|
||||
throw new ApplicationStoppedException();
|
||||
}
|
||||
|
||||
if (rtx == null || !rtx.isAlive()) {
|
||||
if ((rtx == null) || !rtx.isAlive()) {
|
||||
// app.logEvent ("Starting Thread");
|
||||
rtx = new Transactor(this, app.threadgroup, app.nmgr);
|
||||
rtx.setContextClassLoader(app.getClassLoader());
|
||||
|
@ -693,13 +888,16 @@ public final class RequestEvaluator implements Runnable {
|
|||
* return the action's function name. Otherwise, return null.
|
||||
*/
|
||||
public String getAction(Object obj, String action) {
|
||||
if (obj == null)
|
||||
if (obj == null) {
|
||||
return null;
|
||||
String act = action == null ? "main_action" : action+"_action";
|
||||
if (scriptingEngine.hasFunction (obj, act))
|
||||
}
|
||||
|
||||
String act = (action == null) ? "main_action" : (action + "_action");
|
||||
|
||||
if (scriptingEngine.hasFunction(obj, act)) {
|
||||
return act;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -1,12 +1,26 @@
|
|||
// Session.java
|
||||
/*
|
||||
* 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.framework.core;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.net.URLEncoder;
|
||||
import helma.objectmodel.*;
|
||||
import helma.objectmodel.db.*;
|
||||
import java.io.*;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* This represents a session currently using the Hop application.
|
||||
|
@ -14,9 +28,7 @@ import helma.objectmodel.db.*;
|
|||
* Depending on whether the user is logged in or not, the user object holds a
|
||||
* persistent user node.
|
||||
*/
|
||||
|
||||
public class Session implements Serializable {
|
||||
|
||||
transient Application app;
|
||||
String sessionID;
|
||||
|
||||
|
@ -29,13 +41,20 @@ public class Session implements Serializable {
|
|||
// the transient cache node that is exposed to javascript
|
||||
// this stays the same across logins and logouts.
|
||||
public TransientNode cacheNode;
|
||||
|
||||
long onSince, lastTouched, lastModified;
|
||||
long onSince;
|
||||
long lastTouched;
|
||||
long lastModified;
|
||||
|
||||
// used to remember messages to the user between requests -
|
||||
// used for redirects.
|
||||
String message;
|
||||
|
||||
/**
|
||||
* Creates a new Session object.
|
||||
*
|
||||
* @param sessionID ...
|
||||
* @param app ...
|
||||
*/
|
||||
public Session(String sessionID, Application app) {
|
||||
this.sessionID = sessionID;
|
||||
this.app = app;
|
||||
|
@ -57,6 +76,7 @@ public class Session implements Serializable {
|
|||
userHandle = ((Node) usernode).getHandle();
|
||||
uid = usernode.getElementName();
|
||||
}
|
||||
|
||||
lastModified = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
|
@ -69,8 +89,13 @@ public class Session implements Serializable {
|
|||
lastModified = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public boolean isLoggedIn() {
|
||||
if (userHandle!=null && uid!=null) {
|
||||
if ((userHandle != null) && (uid != null)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
|
@ -81,11 +106,12 @@ public class Session implements Serializable {
|
|||
* Gets the user Node from this Application's NodeManager.
|
||||
*/
|
||||
public INode getUserNode() {
|
||||
if (userHandle!=null)
|
||||
if (userHandle != null) {
|
||||
return userHandle.getNode(app.getWrappedNodeManager());
|
||||
else
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the transient cache node.
|
||||
|
@ -94,45 +120,90 @@ public class Session implements Serializable {
|
|||
return cacheNode;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public Application getApp() {
|
||||
return app;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param app ...
|
||||
*/
|
||||
public void setApp(Application app) {
|
||||
this.app = app;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getSessionID() {
|
||||
return sessionID;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void touch() {
|
||||
lastTouched = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public long lastTouched() {
|
||||
return lastTouched;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public long lastModified() {
|
||||
return lastModified;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param date ...
|
||||
*/
|
||||
public void setLastModified(Date date) {
|
||||
if (date != null)
|
||||
if (date != null) {
|
||||
lastModified = date.getTime();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public long onSince() {
|
||||
return onSince;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String toString() {
|
||||
if ( uid!=null )
|
||||
if (uid != null) {
|
||||
return "[Session for user " + uid + "]";
|
||||
else
|
||||
} else {
|
||||
return "[Anonymous Session]";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the persistent user id of a registered user. This is usually the user name, or
|
||||
|
@ -141,6 +212,4 @@ public class Session implements Serializable {
|
|||
public String getUID() {
|
||||
return uid;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -1,79 +1,163 @@
|
|||
/*
|
||||
* 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.framework.core;
|
||||
|
||||
import helma.objectmodel.INode;
|
||||
import helma.scripting.fesi.*;
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
|
||||
import helma.objectmodel.INode;
|
||||
import helma.scripting.fesi.*;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class SessionBean implements Serializable {
|
||||
|
||||
// the wrapped session object
|
||||
Session session;
|
||||
|
||||
/**
|
||||
* Creates a new SessionBean object.
|
||||
*
|
||||
* @param session ...
|
||||
*/
|
||||
public SessionBean(Session session) {
|
||||
this.session = session;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String toString() {
|
||||
return session.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param username ...
|
||||
* @param password ...
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public boolean login(String username, String password) {
|
||||
boolean success = session.getApp().loginSession(username, password, session);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void logout() {
|
||||
session.getApp().logoutSession(session);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void touch() {
|
||||
session.touch();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public Date lastActive() {
|
||||
return new Date(session.lastTouched());
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public Date onSince() {
|
||||
return new Date(session.onSince());
|
||||
}
|
||||
|
||||
// property-related methods:
|
||||
|
||||
public INode getdata() {
|
||||
return session.getCacheNode();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public INode getuser() {
|
||||
return session.getUserNode();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String get_id() {
|
||||
return session.getSessionID();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getcookie() {
|
||||
return session.getSessionID();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public Date getlastActive() {
|
||||
return new Date(session.lastTouched());
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public Date getonSince() {
|
||||
return new Date(session.onSince());
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public Date getLastModified() {
|
||||
return new Date(session.lastModified());
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param date ...
|
||||
*/
|
||||
public void setLastModified(Date date) {
|
||||
session.setLastModified(date);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -1,15 +1,28 @@
|
|||
// Skin.java
|
||||
// Copyright (c) Hannes Wallnöfer 2001
|
||||
/*
|
||||
* 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.framework.core;
|
||||
|
||||
import helma.framework.*;
|
||||
import helma.scripting.*;
|
||||
import helma.objectmodel.INode;
|
||||
import helma.objectmodel.ConcurrencyException;
|
||||
import helma.objectmodel.INode;
|
||||
import helma.scripting.*;
|
||||
import helma.util.HtmlEncoder;
|
||||
import java.net.URLEncoder;
|
||||
import java.io.*;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
|
@ -17,16 +30,23 @@ import java.util.*;
|
|||
* that will be dynamically evaluated.. It uses the request path array
|
||||
* from the RequestEvaluator object to resolve Macro handlers by type name.
|
||||
*/
|
||||
|
||||
public final class Skin {
|
||||
|
||||
static final int HANDLER = 0;
|
||||
static final int MACRO = 1;
|
||||
static final int PARAMNAME = 2;
|
||||
static final int PARAMVALUE = 3;
|
||||
static final int ENCODE_NONE = 0;
|
||||
static final int ENCODE_HTML = 1;
|
||||
static final int ENCODE_XML = 2;
|
||||
static final int ENCODE_FORM = 3;
|
||||
static final int ENCODE_URL = 4;
|
||||
static final int ENCODE_ALL = 5;
|
||||
private Macro[] macros;
|
||||
private Application app;
|
||||
private char[] source;
|
||||
private int sourceLength;
|
||||
private HashSet sandbox;
|
||||
|
||||
|
||||
/**
|
||||
* Create a skin without any restrictions on which macros are allowed to be called from it
|
||||
*/
|
||||
|
@ -64,22 +84,26 @@ public final class Skin {
|
|||
* Parse a skin object from source text
|
||||
*/
|
||||
private void parse() {
|
||||
|
||||
ArrayList partBuffer = new ArrayList();
|
||||
|
||||
int start = 0;
|
||||
for (int i = 0; i < sourceLength-1; i++) {
|
||||
if (source[i] == '<' && source[i+1] == '%') {
|
||||
|
||||
for (int i = 0; i < (sourceLength - 1); i++) {
|
||||
if ((source[i] == '<') && (source[i + 1] == '%')) {
|
||||
// found macro start tag
|
||||
int j = i + 2;
|
||||
|
||||
// search macr end tag
|
||||
while (j < sourceLength-1 && (source[j] != '%' || source[j+1] != '>')) {
|
||||
while ((j < (sourceLength - 1)) &&
|
||||
((source[j] != '%') || (source[j + 1] != '>'))) {
|
||||
j++;
|
||||
}
|
||||
if (j > i+2) {
|
||||
|
||||
if (j > (i + 2)) {
|
||||
partBuffer.add(new Macro(i, j + 2));
|
||||
start = j + 2;
|
||||
}
|
||||
|
||||
i = j + 1;
|
||||
}
|
||||
}
|
||||
|
@ -98,32 +122,40 @@ public final class Skin {
|
|||
/**
|
||||
* Render this skin
|
||||
*/
|
||||
public void render (RequestEvaluator reval, Object thisObject, Map paramObject) throws RedirectException {
|
||||
|
||||
public void render(RequestEvaluator reval, Object thisObject, Map paramObject)
|
||||
throws RedirectException {
|
||||
// check for endless skin recursion
|
||||
if (++reval.skinDepth > 50)
|
||||
if (++reval.skinDepth > 50) {
|
||||
throw new RuntimeException("Recursive skin invocation suspected");
|
||||
}
|
||||
|
||||
if (macros == null) {
|
||||
reval.res.writeCharArray(source, 0, sourceLength);
|
||||
reval.skinDepth--;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
int written = 0;
|
||||
Map handlerCache = null;
|
||||
|
||||
if (macros.length > 3) {
|
||||
handlerCache = new HashMap();
|
||||
}
|
||||
|
||||
for (int i = 0; i < macros.length; i++) {
|
||||
if (macros[i].start > written)
|
||||
if (macros[i].start > written) {
|
||||
reval.res.writeCharArray(source, written, macros[i].start - written);
|
||||
}
|
||||
|
||||
macros[i].render(reval, thisObject, paramObject, handlerCache);
|
||||
written = macros[i].end;
|
||||
}
|
||||
if (written < sourceLength)
|
||||
|
||||
if (written < sourceLength) {
|
||||
reval.res.writeCharArray(source, written, sourceLength - written);
|
||||
}
|
||||
} finally {
|
||||
reval.skinDepth--;
|
||||
}
|
||||
|
@ -136,10 +168,13 @@ public final class Skin {
|
|||
for (int i = 0; i < macros.length; i++) {
|
||||
if (macros[i] instanceof Macro) {
|
||||
Macro m = (Macro) macros[i];
|
||||
if (macroname.equals (m.fullName))
|
||||
|
||||
if (macroname.equals(m.fullName)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -150,24 +185,13 @@ public final class Skin {
|
|||
if (sandbox == null) {
|
||||
sandbox = new HashSet();
|
||||
}
|
||||
|
||||
sandbox.add(macroname);
|
||||
}
|
||||
|
||||
static final int HANDLER = 0;
|
||||
static final int MACRO = 1;
|
||||
static final int PARAMNAME = 2;
|
||||
static final int PARAMVALUE = 3;
|
||||
|
||||
static final int ENCODE_NONE = 0;
|
||||
static final int ENCODE_HTML = 1;
|
||||
static final int ENCODE_XML = 2;
|
||||
static final int ENCODE_FORM = 3;
|
||||
static final int ENCODE_URL = 4;
|
||||
static final int ENCODE_ALL = 5;
|
||||
|
||||
class Macro {
|
||||
|
||||
final int start, end;
|
||||
final int start;
|
||||
final int end;
|
||||
String handler;
|
||||
String name;
|
||||
String fullName;
|
||||
|
@ -178,37 +202,50 @@ public final class Skin {
|
|||
Map parameters = null;
|
||||
|
||||
public Macro(int start, int end) {
|
||||
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
|
||||
int state = HANDLER;
|
||||
boolean escape = false;
|
||||
char quotechar = '\u0000';
|
||||
String lastParamName = null;
|
||||
StringBuffer b = new StringBuffer();
|
||||
|
||||
for (int i=start+2; i<end-2; i++) {
|
||||
for (int i = start + 2; i < (end - 2); i++) {
|
||||
switch (source[i]) {
|
||||
case '.':
|
||||
|
||||
if (state == HANDLER) {
|
||||
handler = b.toString().trim();
|
||||
b.setLength(0);
|
||||
state = MACRO;
|
||||
} else
|
||||
} else {
|
||||
b.append(source[i]);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case '\\':
|
||||
if (escape)
|
||||
|
||||
if (escape) {
|
||||
b.append(source[i]);
|
||||
}
|
||||
|
||||
escape = !escape;
|
||||
|
||||
break;
|
||||
|
||||
case '"':
|
||||
case '\'':
|
||||
if (!escape && state == PARAMVALUE) {
|
||||
|
||||
if (!escape && (state == PARAMVALUE)) {
|
||||
if (quotechar == source[i]) {
|
||||
String paramValue = b.toString();
|
||||
if (!setSpecialParameter (lastParamName, paramValue))
|
||||
|
||||
if (!setSpecialParameter(lastParamName, paramValue)) {
|
||||
addGenericParameter(lastParamName, paramValue);
|
||||
}
|
||||
|
||||
lastParamName = null;
|
||||
b.setLength(0);
|
||||
state = PARAMNAME;
|
||||
|
@ -216,119 +253,152 @@ public final class Skin {
|
|||
} else if (quotechar == '\u0000') {
|
||||
quotechar = source[i];
|
||||
b.setLength(0);
|
||||
} else
|
||||
} else {
|
||||
b.append(source[i]);
|
||||
} else
|
||||
}
|
||||
} else {
|
||||
b.append(source[i]);
|
||||
}
|
||||
|
||||
escape = false;
|
||||
|
||||
break;
|
||||
|
||||
case ' ':
|
||||
case '\t':
|
||||
case '\n':
|
||||
case '\r':
|
||||
case '\f':
|
||||
if (state == MACRO || (state == HANDLER && b.length() > 0)) {
|
||||
|
||||
if ((state == MACRO) || ((state == HANDLER) && (b.length() > 0))) {
|
||||
name = b.toString().trim();
|
||||
b.setLength(0);
|
||||
state = PARAMNAME;
|
||||
} else if (state == PARAMVALUE && quotechar == '\u0000') {
|
||||
} else if ((state == PARAMVALUE) && (quotechar == '\u0000')) {
|
||||
String paramValue = b.toString();
|
||||
if (!setSpecialParameter (lastParamName, paramValue))
|
||||
|
||||
if (!setSpecialParameter(lastParamName, paramValue)) {
|
||||
addGenericParameter(lastParamName, paramValue);
|
||||
}
|
||||
|
||||
lastParamName = null;
|
||||
b.setLength(0);
|
||||
state = PARAMNAME;
|
||||
} else if (state == PARAMVALUE)
|
||||
} else if (state == PARAMVALUE) {
|
||||
b.append(source[i]);
|
||||
else
|
||||
} else {
|
||||
b.setLength(0);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case '=':
|
||||
|
||||
if (state == PARAMNAME) {
|
||||
lastParamName = b.toString().trim();
|
||||
b.setLength(0);
|
||||
state = PARAMVALUE;
|
||||
} else
|
||||
} else {
|
||||
b.append(source[i]);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
b.append(source[i]);
|
||||
escape = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (b.length() > 0) {
|
||||
if (lastParamName != null && b.length() > 0) {
|
||||
if ((lastParamName != null) && (b.length() > 0)) {
|
||||
String paramValue = b.toString();
|
||||
if (!setSpecialParameter (lastParamName, paramValue))
|
||||
|
||||
if (!setSpecialParameter(lastParamName, paramValue)) {
|
||||
addGenericParameter(lastParamName, paramValue);
|
||||
} else if (state <= MACRO)
|
||||
}
|
||||
} else if (state <= MACRO) {
|
||||
name = b.toString().trim();
|
||||
}
|
||||
if (handler == null)
|
||||
fullName = name;
|
||||
else
|
||||
fullName = handler+"."+name;
|
||||
|
||||
}
|
||||
|
||||
if (handler == null) {
|
||||
fullName = name;
|
||||
} else {
|
||||
fullName = handler + "." + name;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean setSpecialParameter(String name, String value) {
|
||||
if ("prefix".equals(name)) {
|
||||
prefix = value;
|
||||
|
||||
return true;
|
||||
} else if ("suffix".equals(name)) {
|
||||
suffix = value;
|
||||
|
||||
return true;
|
||||
} else if ("encoding".equals(name)) {
|
||||
if ("html".equalsIgnoreCase (value))
|
||||
if ("html".equalsIgnoreCase(value)) {
|
||||
encoding = ENCODE_HTML;
|
||||
else if ("xml".equalsIgnoreCase (value))
|
||||
} else if ("xml".equalsIgnoreCase(value)) {
|
||||
encoding = ENCODE_XML;
|
||||
else if ("form".equalsIgnoreCase (value))
|
||||
} else if ("form".equalsIgnoreCase(value)) {
|
||||
encoding = ENCODE_FORM;
|
||||
else if ("url".equalsIgnoreCase (value))
|
||||
} else if ("url".equalsIgnoreCase(value)) {
|
||||
encoding = ENCODE_URL;
|
||||
else if ("all".equalsIgnoreCase (value))
|
||||
} else if ("all".equalsIgnoreCase(value)) {
|
||||
encoding = ENCODE_ALL;
|
||||
}
|
||||
|
||||
return true;
|
||||
} else if ("default".equals(name)) {
|
||||
defaultValue = value;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void addGenericParameter(String name, String value) {
|
||||
if (parameters == null)
|
||||
if (parameters == null) {
|
||||
parameters = new HashMap();
|
||||
}
|
||||
|
||||
parameters.put(name, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the macro given a handler object
|
||||
*/
|
||||
public void render (RequestEvaluator reval, Object thisObject, Map paramObject, Map handlerCache) throws RedirectException {
|
||||
public void render(RequestEvaluator reval, Object thisObject, Map paramObject,
|
||||
Map handlerCache) throws RedirectException {
|
||||
if ((sandbox != null) && !sandbox.contains(fullName)) {
|
||||
String h = (handler == null) ? "global" : handler;
|
||||
|
||||
if (sandbox != null && !sandbox.contains (fullName)) {
|
||||
String h = handler == null ? "global" : handler;
|
||||
reval.res.write("[Macro " + fullName + " not allowed in sandbox]");
|
||||
|
||||
return;
|
||||
} else if ("response".equalsIgnoreCase(handler)) {
|
||||
renderFromResponse(reval);
|
||||
|
||||
return;
|
||||
} else if ("request".equalsIgnoreCase(handler)) {
|
||||
renderFromRequest(reval);
|
||||
|
||||
return;
|
||||
} else if ("param".equalsIgnoreCase(handler)) {
|
||||
renderFromParam(reval, paramObject);
|
||||
|
||||
return;
|
||||
} else if ("session".equalsIgnoreCase(handler)) {
|
||||
renderFromSession(reval);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
Object handlerObject = null;
|
||||
|
||||
// flag to tell whether we found our invocation target object
|
||||
|
@ -336,25 +406,30 @@ public final class Skin {
|
|||
|
||||
if (handler != null) {
|
||||
// try to get handler from handlerCache first
|
||||
if (handlerCache != null)
|
||||
if (handlerCache != null) {
|
||||
handlerObject = handlerCache.get(handler);
|
||||
}
|
||||
|
||||
if (handlerObject == null) {
|
||||
|
||||
// if handler object wasn't found in cache retrieve it
|
||||
if (handlerObject == null && thisObject != null) {
|
||||
if ((handlerObject == null) && (thisObject != null)) {
|
||||
// not a global macro - need to find handler object
|
||||
// was called with this object - check it or its parents for matching prototype
|
||||
if (!handler.equals ("this") && !handler.equals (app.getPrototypeName (thisObject))) {
|
||||
if (!handler.equals("this") &&
|
||||
!handler.equals(app.getPrototypeName(thisObject))) {
|
||||
// the handler object is not what we want
|
||||
Object n = thisObject;
|
||||
|
||||
// walk down parent chain to find handler object
|
||||
while (n != null) {
|
||||
Prototype proto = app.getPrototype(n);
|
||||
if (proto != null && proto.isInstanceOf (handler)) {
|
||||
|
||||
if ((proto != null) && proto.isInstanceOf(handler)) {
|
||||
handlerObject = n;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
n = app.getParentElement(n);
|
||||
}
|
||||
} else {
|
||||
|
@ -371,13 +446,14 @@ public final class Skin {
|
|||
}
|
||||
|
||||
// the macro handler object couldn't be found
|
||||
if (handlerObject == null)
|
||||
if (handlerObject == null) {
|
||||
objectFound = false;
|
||||
}
|
||||
// else put the found handler object into the cache so we don't have to look again
|
||||
else if (handlerCache != null)
|
||||
else if (handlerCache != null) {
|
||||
handlerCache.put(handler, handlerObject);
|
||||
}
|
||||
|
||||
}
|
||||
} else {
|
||||
// this is a global macro with no handler specified
|
||||
handlerObject = null;
|
||||
|
@ -387,15 +463,17 @@ public final class Skin {
|
|||
// check if a function called name_macro is defined.
|
||||
// if so, the macro evaluates to the function. Otherwise,
|
||||
// a property/field with the name is used, if defined.
|
||||
|
||||
String funcName = name + "_macro";
|
||||
if (reval.scriptingEngine.hasFunction (handlerObject, funcName)) {
|
||||
|
||||
if (reval.scriptingEngine.hasFunction(handlerObject, funcName)) {
|
||||
StringBuffer buffer = reval.res.getBuffer();
|
||||
|
||||
// remember length of response buffer before calling macro
|
||||
int bufLength = buffer.length();
|
||||
|
||||
// remember length of buffer with prefix written out
|
||||
int preLength = 0;
|
||||
|
||||
if (prefix != null) {
|
||||
buffer.append(prefix);
|
||||
preLength = prefix.length();
|
||||
|
@ -406,41 +484,50 @@ public final class Skin {
|
|||
// Map param = ;
|
||||
// if (parameters == null)
|
||||
// parameters = new HashMap ();
|
||||
Object[] arguments = { parameters == null ?
|
||||
new HashMap () :
|
||||
new HashMap (parameters)
|
||||
Object[] arguments = {
|
||||
(parameters == null) ? new HashMap()
|
||||
: new HashMap(parameters)
|
||||
};
|
||||
|
||||
Object value = reval.scriptingEngine.invoke (handlerObject, funcName, arguments, false);
|
||||
Object value = reval.scriptingEngine.invoke(handlerObject,
|
||||
funcName, arguments,
|
||||
false);
|
||||
|
||||
// check if macro wrote out to response buffer
|
||||
if (buffer.length () == bufLength + preLength) {
|
||||
if (buffer.length() == (bufLength + preLength)) {
|
||||
// function didn't write out anything itself.
|
||||
// erase previously written prefix
|
||||
if (preLength > 0)
|
||||
if (preLength > 0) {
|
||||
buffer.setLength(bufLength);
|
||||
}
|
||||
|
||||
// write out macro's return value
|
||||
writeResponse(value, buffer, true);
|
||||
} else {
|
||||
if (encoding != ENCODE_NONE) {
|
||||
// if an encoding is specified, re-encode the macro's output
|
||||
String output = buffer.substring(bufLength + preLength);
|
||||
|
||||
buffer.setLength(bufLength);
|
||||
writeResponse(output, buffer, false);
|
||||
} else {
|
||||
// no re-encoding needed, just append suffix
|
||||
if (suffix != null)
|
||||
if (suffix != null) {
|
||||
buffer.append(suffix);
|
||||
}
|
||||
}
|
||||
|
||||
writeResponse(value, buffer, false);
|
||||
}
|
||||
} else {
|
||||
// System.err.println ("Getting macro from property");
|
||||
Object value = reval.scriptingEngine.get(handlerObject, name);
|
||||
|
||||
writeResponse(value, reval.res.getBuffer(), true);
|
||||
}
|
||||
} else {
|
||||
String msg = "[HopMacro unhandled: " + fullName + "]";
|
||||
|
||||
reval.res.write(" " + msg + " ");
|
||||
app.logEvent(msg);
|
||||
}
|
||||
|
@ -453,8 +540,11 @@ public final class Skin {
|
|||
} catch (Exception x) {
|
||||
// x.printStackTrace();
|
||||
String msg = x.getMessage();
|
||||
if (msg == null || msg.length() < 10)
|
||||
|
||||
if ((msg == null) || (msg.length() < 10)) {
|
||||
msg = x.toString();
|
||||
}
|
||||
|
||||
msg = "[HopMacro error in " + fullName + ": " + msg + "]";
|
||||
reval.res.write(" " + msg + " ");
|
||||
app.logEvent(msg);
|
||||
|
@ -463,34 +553,46 @@ public final class Skin {
|
|||
|
||||
private void renderFromResponse(RequestEvaluator reval) {
|
||||
Object value = null;
|
||||
if ("message".equals (name))
|
||||
|
||||
if ("message".equals(name)) {
|
||||
value = reval.res.message;
|
||||
else if ("error".equals (name))
|
||||
} else if ("error".equals(name)) {
|
||||
value = reval.res.error;
|
||||
if (value == null)
|
||||
}
|
||||
|
||||
if (value == null) {
|
||||
value = reval.res.get(name);
|
||||
}
|
||||
|
||||
writeResponse(value, reval.res.getBuffer(), true);
|
||||
}
|
||||
|
||||
private void renderFromRequest(RequestEvaluator reval) {
|
||||
if (reval.req == null)
|
||||
if (reval.req == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Object value = reval.req.get(name);
|
||||
|
||||
writeResponse(value, reval.res.getBuffer(), true);
|
||||
}
|
||||
|
||||
private void renderFromSession(RequestEvaluator reval) {
|
||||
if (reval.session == null)
|
||||
if (reval.session == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Object value = reval.session.getCacheNode().getString(name);
|
||||
|
||||
writeResponse(value, reval.res.getBuffer(), true);
|
||||
}
|
||||
|
||||
private void renderFromParam(RequestEvaluator reval, Map paramObject) {
|
||||
if (paramObject == null)
|
||||
if (paramObject == null) {
|
||||
reval.res.write("[HopMacro error: Skin requires a parameter object]");
|
||||
else {
|
||||
} else {
|
||||
Object value = paramObject.get(name);
|
||||
|
||||
writeResponse(value, reval.res.getBuffer(), true);
|
||||
}
|
||||
}
|
||||
|
@ -500,57 +602,69 @@ public final class Skin {
|
|||
*/
|
||||
void writeResponse(Object value, StringBuffer buffer, boolean useDefault) {
|
||||
String text;
|
||||
|
||||
if (value == null) {
|
||||
if (useDefault)
|
||||
if (useDefault) {
|
||||
text = defaultValue;
|
||||
else
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
text = value.toString();
|
||||
}
|
||||
if (text != null && text.length() > 0) {
|
||||
if (prefix != null)
|
||||
|
||||
if ((text != null) && (text.length() > 0)) {
|
||||
if (prefix != null) {
|
||||
buffer.append(prefix);
|
||||
}
|
||||
|
||||
switch (encoding) {
|
||||
case ENCODE_NONE:
|
||||
buffer.append(text);
|
||||
|
||||
break;
|
||||
|
||||
case ENCODE_HTML:
|
||||
HtmlEncoder.encode(text, buffer);
|
||||
|
||||
break;
|
||||
|
||||
case ENCODE_XML:
|
||||
HtmlEncoder.encodeXml(text, buffer);
|
||||
|
||||
break;
|
||||
|
||||
case ENCODE_FORM:
|
||||
HtmlEncoder.encodeFormValue(text, buffer);
|
||||
|
||||
break;
|
||||
|
||||
case ENCODE_URL:
|
||||
buffer.append(URLEncoder.encode(text));
|
||||
|
||||
break;
|
||||
|
||||
case ENCODE_ALL:
|
||||
HtmlEncoder.encodeAll(text, buffer);
|
||||
|
||||
break;
|
||||
}
|
||||
if (suffix != null)
|
||||
|
||||
if (suffix != null) {
|
||||
buffer.append(suffix);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "[HopMacro: " + fullName + "]";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the full name of the macro in handler.name notation
|
||||
*/
|
||||
public String getFullName() {
|
||||
return fullName;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,20 +1,29 @@
|
|||
// SkinFile.java
|
||||
// Copyright (c) Hannes Wallnöfer 2001
|
||||
/*
|
||||
* 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.framework.core;
|
||||
|
||||
import java.util.*;
|
||||
import java.io.*;
|
||||
import helma.util.Updatable;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* This represents a File containing a Hop skin
|
||||
*/
|
||||
|
||||
|
||||
public final class SkinFile implements Updatable {
|
||||
|
||||
String name;
|
||||
Prototype prototype;
|
||||
Application app;
|
||||
|
@ -22,6 +31,13 @@ public final class SkinFile implements Updatable {
|
|||
Skin skin;
|
||||
long lastmod = 0;
|
||||
|
||||
/**
|
||||
* Creates a new SkinFile object.
|
||||
*
|
||||
* @param file ...
|
||||
* @param name ...
|
||||
* @param proto ...
|
||||
*/
|
||||
public SkinFile(File file, String name, Prototype proto) {
|
||||
this.prototype = proto;
|
||||
this.file = file;
|
||||
|
@ -55,7 +71,6 @@ public final class SkinFile implements Updatable {
|
|||
skin = null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Tell the type manager whether we need an update. this is the case when
|
||||
* the file has been modified or deleted.
|
||||
|
@ -64,59 +79,85 @@ public final class SkinFile implements Updatable {
|
|||
// if skin object is null we only need to call update if the file doesn't
|
||||
// exist anymore, while if the skin is initialized, we'll catch both
|
||||
// cases (file deleted and file changed) by just calling lastModified().
|
||||
return skin != null ? lastmod != file.lastModified () : !file.exists ();
|
||||
return (skin != null) ? (lastmod != file.lastModified()) : (!file.exists());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void update() {
|
||||
if (!file.exists()) {
|
||||
// remove skin from prototype
|
||||
remove();
|
||||
} else {
|
||||
// we only need to update if the skin has already been initialized
|
||||
if (skin != null)
|
||||
if (skin != null) {
|
||||
read();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void read() {
|
||||
try {
|
||||
FileReader reader = new FileReader(file);
|
||||
char c[] = new char[(int) file.length()];
|
||||
char[] c = new char[(int) file.length()];
|
||||
int length = reader.read(c);
|
||||
|
||||
reader.close();
|
||||
skin = new Skin(c, length, app);
|
||||
} catch (IOException x) {
|
||||
app.logEvent("Error reading Skin " + file + ": " + x);
|
||||
}
|
||||
|
||||
lastmod = file.lastModified();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void remove() {
|
||||
if (prototype != null) {
|
||||
prototype.removeSkinFile(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public File getFile() {
|
||||
return file;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public Skin getSkin() {
|
||||
if (skin == null)
|
||||
if (skin == null) {
|
||||
read();
|
||||
}
|
||||
|
||||
return skin;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String toString() {
|
||||
return prototype.getName() + "/" + file.getName();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,67 +1,92 @@
|
|||
// SkinManager.java
|
||||
// Copyright (c) Hannes Wallnöfer 2002
|
||||
/*
|
||||
* 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.framework.core;
|
||||
|
||||
import java.util.*;
|
||||
import helma.objectmodel.INode;
|
||||
import java.io.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Manages skins for a Helma application
|
||||
*/
|
||||
|
||||
|
||||
public final class SkinManager implements FilenameFilter {
|
||||
|
||||
Application app;
|
||||
|
||||
/**
|
||||
* Creates a new SkinManager object.
|
||||
*
|
||||
* @param app ...
|
||||
*/
|
||||
public SkinManager(Application app) {
|
||||
this.app = app;
|
||||
}
|
||||
|
||||
|
||||
protected Skin getSkin(Prototype proto, String skinname, Object[] skinpath) {
|
||||
if (proto == null)
|
||||
if (proto == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Skin skin = null;
|
||||
|
||||
// First check if the skin has been already used within the execution of this request
|
||||
// check for skinsets set via res.skinpath property
|
||||
do {
|
||||
if (skinpath != null) {
|
||||
for (int i = 0; i < skinpath.length; i++) {
|
||||
skin = getSkinInternal(skinpath[i], proto.getName(), skinname);
|
||||
|
||||
if (skin != null) {
|
||||
return skin;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// skin for this prototype wasn't found in the skinsets.
|
||||
// the next step is to look if it is defined as skin file in the application directory
|
||||
skin = proto.getSkin(skinname);
|
||||
|
||||
if (skin != null) {
|
||||
return skin;
|
||||
}
|
||||
|
||||
// still not found. See if there is a parent prototype which might define the skin.
|
||||
proto = proto.getParentPrototype();
|
||||
} while (proto != null);
|
||||
|
||||
// looked every where, nothing to be found
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
protected Skin getSkinInternal(Object skinset, String prototype, String skinname) {
|
||||
if (prototype == null || skinset == null)
|
||||
if ((prototype == null) || (skinset == null)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// check if the skinset object is a HopObject (db based skin)
|
||||
// or a String (file based skin)
|
||||
if (skinset instanceof INode) {
|
||||
INode n = ((INode) skinset).getNode(prototype);
|
||||
|
||||
if (n != null) {
|
||||
n = n.getNode(skinname);
|
||||
|
||||
if (n != null) {
|
||||
String skin = n.getString("skin");
|
||||
|
||||
if (skin != null) {
|
||||
return new Skin(skin, app);
|
||||
}
|
||||
|
@ -71,29 +96,38 @@ public final class SkinManager implements FilenameFilter {
|
|||
// Skinset is interpreted as directory name from which to
|
||||
// retrieve the skin
|
||||
File f = new File(skinset.toString(), prototype);
|
||||
|
||||
f = new File(f, skinname + ".skin");
|
||||
|
||||
if (f.exists() && f.canRead()) {
|
||||
SkinFile sf = new SkinFile(f, skinname, app);
|
||||
|
||||
return sf.getSkin();
|
||||
}
|
||||
}
|
||||
|
||||
// Inheritance is taken care of in the above getSkin method.
|
||||
// the sequence is prototype.skin-from-db, prototype.skin-from-file, parent.from-db, parent.from-file etc.
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
protected Map getSkinFiles(String skinDir, Prototype proto) {
|
||||
File dir = new File(skinDir.toString(), proto.getName());
|
||||
String[] skinNames = dir.list(this);
|
||||
if (skinNames == null || skinNames.length == 0)
|
||||
|
||||
if ((skinNames == null) || (skinNames.length == 0)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
HashMap map = new HashMap();
|
||||
|
||||
for (int i = 0; i < skinNames.length; i++) {
|
||||
String name = skinNames[i].substring(0, skinNames[i].length() - 5);
|
||||
File file = new File(dir, skinNames[i]);
|
||||
|
||||
map.put(name, new SkinFile(file, name, proto));
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
|
@ -103,5 +137,4 @@ public final class SkinManager implements FilenameFilter {
|
|||
public boolean accept(File d, String n) {
|
||||
return n.endsWith(".skin");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,18 @@
|
|||
// TypeManager.java
|
||||
// Copyright (c) Hannes Wallnöfer 1998-2000
|
||||
/*
|
||||
* 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.framework.core;
|
||||
|
||||
|
@ -7,19 +20,22 @@ import helma.objectmodel.*;
|
|||
import helma.objectmodel.db.DbMapping;
|
||||
import helma.scripting.*;
|
||||
import helma.util.*;
|
||||
import java.util.*;
|
||||
import java.io.*;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.net.MalformedURLException;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* The type manager periodically checks the prototype definitions for its
|
||||
* applications and updates the evaluators if anything has changed.
|
||||
*/
|
||||
|
||||
public final class TypeManager {
|
||||
|
||||
final static String[] standardTypes = { "user", "global", "root", "hopobject" };
|
||||
final static String templateExtension = ".hsp";
|
||||
final static String scriptExtension = ".js";
|
||||
final static String actionExtension = ".hac";
|
||||
final static String skinExtension = ".skin";
|
||||
Application app;
|
||||
File appDir;
|
||||
HashMap prototypes; // map of prototypes
|
||||
|
@ -27,54 +43,69 @@ public final class TypeManager {
|
|||
HashSet jarfiles; // set of Java archives
|
||||
long lastCheck = 0;
|
||||
long appDirMod = 0;
|
||||
|
||||
// a checksum that changes whenever something in the application files changes.
|
||||
long checksum;
|
||||
|
||||
// the hopobject prototype
|
||||
Prototype hopobjectProto;
|
||||
|
||||
// the global prototype
|
||||
Prototype globalProto;
|
||||
|
||||
// app specific class loader, includes jar files in the app directory
|
||||
AppClassLoader loader;
|
||||
|
||||
final static String[] standardTypes = {"user", "global", "root", "hopobject"};
|
||||
|
||||
final static String templateExtension = ".hsp";
|
||||
final static String scriptExtension = ".js";
|
||||
final static String actionExtension = ".hac";
|
||||
final static String skinExtension = ".skin";
|
||||
|
||||
/**
|
||||
* Creates a new TypeManager object.
|
||||
*
|
||||
* @param app ...
|
||||
*
|
||||
* @throws MalformedURLException ...
|
||||
* @throws RuntimeException ...
|
||||
*/
|
||||
public TypeManager(Application app) throws MalformedURLException {
|
||||
this.app = app;
|
||||
appDir = app.appDir;
|
||||
|
||||
// make sure the directories for the standard prototypes exist, and lament otherwise
|
||||
if (appDir.list().length == 0) {
|
||||
for (int i = 0; i < standardTypes.length; i++) {
|
||||
File f = new File(appDir, standardTypes[i]);
|
||||
if (!f.exists() && !f.mkdir ())
|
||||
app.logEvent ("Warning: directory "+f.getAbsolutePath ()+" could not be created.");
|
||||
else if (!f.isDirectory ())
|
||||
app.logEvent ("Warning: "+f.getAbsolutePath ()+" is not a directory.");
|
||||
|
||||
if (!f.exists() && !f.mkdir()) {
|
||||
app.logEvent("Warning: directory " + f.getAbsolutePath() +
|
||||
" could not be created.");
|
||||
} else if (!f.isDirectory()) {
|
||||
app.logEvent("Warning: " + f.getAbsolutePath() +
|
||||
" is not a directory.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
prototypes = new HashMap();
|
||||
zipfiles = new HashMap();
|
||||
jarfiles = new HashSet();
|
||||
|
||||
URL[] urls = ((URLClassLoader) TypeManager.class.getClassLoader()).getURLs();
|
||||
URL helmajar = null;
|
||||
|
||||
for (int i = 0; i < urls.length; i++) {
|
||||
String url = urls[i].toString().toLowerCase();
|
||||
|
||||
if (url.endsWith("helma.jar")) {
|
||||
helmajar = urls[i];
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (helmajar == null)
|
||||
|
||||
if (helmajar == null) {
|
||||
throw new RuntimeException("helma.jar not found in embedding classpath");
|
||||
loader = new AppClassLoader(app.getName(), new URL[] { helmajar });
|
||||
}
|
||||
|
||||
loader = new AppClassLoader(app.getName(), new URL[] { helmajar });
|
||||
}
|
||||
|
||||
/**
|
||||
* Run through application's prototype directories and create prototypes, but don't
|
||||
|
@ -84,25 +115,30 @@ public final class TypeManager {
|
|||
// create standard prototypes.
|
||||
createPrototype("root");
|
||||
createPrototype("user");
|
||||
|
||||
// get references to hopobject and global protos,
|
||||
// since we need it regularly when setting parent prototypes.
|
||||
hopobjectProto = createPrototype("hopobject");
|
||||
globalProto = createPrototype("global");
|
||||
|
||||
// loop through directories and create prototypes
|
||||
checkFiles();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Run through application's prototype directories and check if anything has been updated.
|
||||
* If so, update prototypes and scripts.
|
||||
*/
|
||||
public synchronized void checkPrototypes() {
|
||||
if (System.currentTimeMillis () - lastCheck < 1000l)
|
||||
if ((System.currentTimeMillis() - lastCheck) < 1000L) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
checkFiles();
|
||||
} catch (Exception ignore) {}
|
||||
} catch (Exception ignore) {
|
||||
}
|
||||
|
||||
lastCheck = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
|
@ -115,37 +151,55 @@ public final class TypeManager {
|
|||
// checked...
|
||||
if (appDir.lastModified() > appDirMod) {
|
||||
appDirMod = appDir.lastModified();
|
||||
|
||||
String[] list = appDir.list();
|
||||
if (list == null)
|
||||
throw new RuntimeException ("Can't read app directory "+appDir+" - check permissions");
|
||||
|
||||
if (list == null) {
|
||||
throw new RuntimeException("Can't read app directory " + appDir +
|
||||
" - check permissions");
|
||||
}
|
||||
|
||||
for (int i = 0; i < list.length; i++) {
|
||||
if (list[i].endsWith(".zip")) {
|
||||
ZippedAppFile zipped = (ZippedAppFile) zipfiles.get(list[i]);
|
||||
|
||||
if (zipped == null) {
|
||||
File f = new File(appDir, list[i]);
|
||||
|
||||
if (!f.isDirectory()) {
|
||||
zipped = new ZippedAppFile(f, app);
|
||||
zipfiles.put(list[i], zipped);
|
||||
}
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (list[i].endsWith(".jar")) {
|
||||
if (!jarfiles.contains(list[i])) {
|
||||
jarfiles.add(list[i]);
|
||||
|
||||
File f = new File(appDir, list[i]);
|
||||
|
||||
try {
|
||||
loader.addURL(new URL("file:" + f.getAbsolutePath()));
|
||||
} catch (MalformedURLException ignore) {}
|
||||
} catch (MalformedURLException ignore) {
|
||||
}
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
if (list[i].indexOf ('.') > -1)
|
||||
|
||||
if (list[i].indexOf('.') > -1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Prototype proto = getPrototype(list[i]);
|
||||
|
||||
// if prototype doesn't exist, create it
|
||||
if (proto == null && isValidTypeName (list[i])) {
|
||||
if ((proto == null) && isValidTypeName(list[i])) {
|
||||
File f = new File(appDir, list[i]);
|
||||
|
||||
if (f.isDirectory()) {
|
||||
// create new prototype
|
||||
createPrototype(list[i], f);
|
||||
|
@ -160,9 +214,11 @@ public final class TypeManager {
|
|||
// loop through zip files to check for updates
|
||||
for (Iterator it = zipfiles.values().iterator(); it.hasNext();) {
|
||||
ZippedAppFile zipped = (ZippedAppFile) it.next();
|
||||
|
||||
if (zipped.needsUpdate()) {
|
||||
zipped.update();
|
||||
}
|
||||
|
||||
newChecksum += zipped.lastmod;
|
||||
}
|
||||
|
||||
|
@ -171,44 +227,58 @@ public final class TypeManager {
|
|||
// have been created in the previous loop.
|
||||
for (Iterator i = prototypes.values().iterator(); i.hasNext();) {
|
||||
Prototype proto = (Prototype) i.next();
|
||||
|
||||
// calculate this app's type checksum
|
||||
newChecksum += proto.getChecksum();
|
||||
|
||||
// update prototype's type mapping
|
||||
DbMapping dbmap = proto.getDbMapping();
|
||||
if (dbmap != null && dbmap.needsUpdate ()) {
|
||||
|
||||
if ((dbmap != null) && dbmap.needsUpdate()) {
|
||||
dbmap.update();
|
||||
if (proto != hopobjectProto && proto != globalProto) {
|
||||
|
||||
if ((proto != hopobjectProto) && (proto != globalProto)) {
|
||||
// set parent prototype, in case it has changed.
|
||||
String parentName = dbmap.getExtends();
|
||||
if (parentName != null)
|
||||
|
||||
if (parentName != null) {
|
||||
proto.setParentPrototype(getPrototype(parentName));
|
||||
else if (!app.isJavaPrototype (proto.getName()))
|
||||
} else if (!app.isJavaPrototype(proto.getName())) {
|
||||
proto.setParentPrototype(hopobjectProto);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
checksum = newChecksum;
|
||||
}
|
||||
|
||||
protected void removeZipFile(String zipname) {
|
||||
zipfiles.remove(zipname);
|
||||
|
||||
for (Iterator i = prototypes.values().iterator(); i.hasNext();) {
|
||||
Prototype proto = (Prototype) i.next();
|
||||
|
||||
// update prototype's type mapping
|
||||
DbMapping dbmap = proto.getDbMapping();
|
||||
SystemProperties props = dbmap.getProperties();
|
||||
|
||||
props.removeProps(zipname);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private boolean isValidTypeName(String str) {
|
||||
if (str == null)
|
||||
if (str == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
char[] c = str.toCharArray();
|
||||
|
||||
for (int i = 0; i < c.length; i++)
|
||||
if (!Character.isJavaIdentifierPart (c[i]))
|
||||
if (!Character.isJavaIdentifierPart(c[i])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -236,32 +306,35 @@ public final class TypeManager {
|
|||
return createPrototype(typename, new File(appDir, typename));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a prototype from a directory containing scripts and other stuff
|
||||
*/
|
||||
public Prototype createPrototype(String typename, File dir) {
|
||||
Prototype proto = new Prototype(typename, dir, app);
|
||||
|
||||
// Create and register type properties file
|
||||
File propfile = new File(dir, "type.properties");
|
||||
SystemProperties props = new SystemProperties(propfile.getAbsolutePath());
|
||||
DbMapping dbmap = new DbMapping(app, typename, props);
|
||||
|
||||
// we don't need to put the DbMapping into proto.updatables, because
|
||||
// dbmappings are checked separately in checkFiles for each request
|
||||
// proto.updatables.put ("type.properties", dbmap);
|
||||
proto.setDbMapping(dbmap);
|
||||
|
||||
// put the prototype into our map
|
||||
prototypes.put(typename, proto);
|
||||
|
||||
return proto;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Update a prototype to the files in the prototype directory.
|
||||
*/
|
||||
public void updatePrototype(String name) {
|
||||
// System.err.println ("UPDATE PROTO: "+app.getName()+"/"+name);
|
||||
Prototype proto = getPrototype(name);
|
||||
|
||||
updatePrototype(proto);
|
||||
}
|
||||
|
||||
|
@ -269,15 +342,16 @@ public final class TypeManager {
|
|||
* Update a prototype to the files in the prototype directory.
|
||||
*/
|
||||
public void updatePrototype(Prototype proto) {
|
||||
if (proto == null || proto.isUpToDate())
|
||||
if ((proto == null) || proto.isUpToDate()) {
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized (proto) {
|
||||
// check again because another thread may have checked the
|
||||
// prototype while we were waiting for access to the synchronized section
|
||||
|
||||
/* if (System.currentTimeMillis() - proto.getLastCheck() < 1000)
|
||||
return; */
|
||||
|
||||
File dir = proto.getDirectory();
|
||||
HashSet updateSet = null;
|
||||
HashSet createSet = null;
|
||||
|
@ -286,9 +360,12 @@ public final class TypeManager {
|
|||
// anything the prototype knows about has changed on disk
|
||||
for (Iterator i = proto.updatables.values().iterator(); i.hasNext();) {
|
||||
Updatable upd = (Updatable) i.next();
|
||||
|
||||
if (upd.needsUpdate()) {
|
||||
if (updateSet == null)
|
||||
if (updateSet == null) {
|
||||
updateSet = new HashSet();
|
||||
}
|
||||
|
||||
updateSet.add(upd);
|
||||
}
|
||||
}
|
||||
|
@ -296,32 +373,35 @@ public final class TypeManager {
|
|||
// next we check if files have been created or removed since last update
|
||||
// if (proto.getLastCheck() < dir.lastModified ()) {
|
||||
File[] list = proto.getFiles();
|
||||
|
||||
for (int i = 0; i < list.length; i++) {
|
||||
String fn = list[i].getName();
|
||||
|
||||
if (!proto.updatables.containsKey(fn)) {
|
||||
if (fn.endsWith (templateExtension) ||
|
||||
fn.endsWith (scriptExtension) ||
|
||||
fn.endsWith (actionExtension) ||
|
||||
fn.endsWith (skinExtension) ||
|
||||
"type.properties".equalsIgnoreCase (fn))
|
||||
{
|
||||
if (createSet == null)
|
||||
if (fn.endsWith(templateExtension) || fn.endsWith(scriptExtension) ||
|
||||
fn.endsWith(actionExtension) || fn.endsWith(skinExtension) ||
|
||||
"type.properties".equalsIgnoreCase(fn)) {
|
||||
if (createSet == null) {
|
||||
createSet = new HashSet();
|
||||
}
|
||||
|
||||
createSet.add(list[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
// }
|
||||
|
||||
// }
|
||||
// if nothing needs to be updated, mark prototype as checked and return
|
||||
if (updateSet == null && createSet == null) {
|
||||
if ((updateSet == null) && (createSet == null)) {
|
||||
proto.markChecked();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// first go through new files and create new items
|
||||
if (createSet != null) {
|
||||
Object[] newFiles = createSet.toArray();
|
||||
|
||||
for (int i = 0; i < newFiles.length; i++) {
|
||||
File file = (File) newFiles[i];
|
||||
String filename = file.getName();
|
||||
|
@ -331,6 +411,7 @@ public final class TypeManager {
|
|||
if (filename.endsWith(templateExtension)) {
|
||||
try {
|
||||
Template t = new Template(file, tmpname, proto);
|
||||
|
||||
proto.addTemplate(t);
|
||||
} catch (Throwable x) {
|
||||
app.logEvent("Error updating prototype: " + x);
|
||||
|
@ -338,6 +419,7 @@ public final class TypeManager {
|
|||
} else if (filename.endsWith(scriptExtension)) {
|
||||
try {
|
||||
FunctionFile ff = new FunctionFile(file, proto);
|
||||
|
||||
proto.addFunctionFile(ff);
|
||||
} catch (Throwable x) {
|
||||
app.logEvent("Error updating prototype: " + x);
|
||||
|
@ -345,12 +427,14 @@ public final class TypeManager {
|
|||
} else if (filename.endsWith(actionExtension)) {
|
||||
try {
|
||||
ActionFile af = new ActionFile(file, tmpname, proto);
|
||||
|
||||
proto.addActionFile(af);
|
||||
} catch (Throwable x) {
|
||||
app.logEvent("Error updating prototype: " + x);
|
||||
}
|
||||
} else if (filename.endsWith(skinExtension)) {
|
||||
SkinFile sf = new SkinFile(file, tmpname, proto);
|
||||
|
||||
proto.addSkinFile(sf);
|
||||
}
|
||||
}
|
||||
|
@ -360,13 +444,17 @@ public final class TypeManager {
|
|||
if (updateSet != null) {
|
||||
for (Iterator i = updateSet.iterator(); i.hasNext();) {
|
||||
Updatable upd = (Updatable) i.next();
|
||||
|
||||
try {
|
||||
upd.update();
|
||||
} catch (Exception x) {
|
||||
if (upd instanceof DbMapping)
|
||||
app.logEvent ("Error updating db mapping for type "+proto.getName()+": "+x);
|
||||
else
|
||||
app.logEvent ("Error updating "+upd+" of prototye type "+proto.getName()+": "+x);
|
||||
if (upd instanceof DbMapping) {
|
||||
app.logEvent("Error updating db mapping for type " +
|
||||
proto.getName() + ": " + x);
|
||||
} else {
|
||||
app.logEvent("Error updating " + upd + " of prototye type " +
|
||||
proto.getName() + ": " + x);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -374,10 +462,7 @@ public final class TypeManager {
|
|||
// mark prototype as checked and updated.
|
||||
proto.markChecked();
|
||||
proto.markUpdated();
|
||||
|
||||
} // end of synchronized (proto)
|
||||
|
||||
}
|
||||
|
||||
// end of synchronized (proto)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,119 +1,151 @@
|
|||
// ZippedFile.java
|
||||
// Copyright (c) Hannes Wallnöfer 2001
|
||||
/*
|
||||
* 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.framework.core;
|
||||
|
||||
import helma.framework.*;
|
||||
import helma.objectmodel.db.DbMapping;
|
||||
import helma.scripting.*;
|
||||
import helma.util.SystemProperties;
|
||||
import helma.util.Updatable;
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.util.zip.*;
|
||||
import java.io.*;
|
||||
import helma.framework.*;
|
||||
import helma.scripting.*;
|
||||
import helma.util.Updatable;
|
||||
import helma.util.SystemProperties;
|
||||
import helma.objectmodel.db.DbMapping;
|
||||
|
||||
/**
|
||||
* This represents a Zip-File which may contain other Updatables for one or more prototypes.
|
||||
*/
|
||||
|
||||
|
||||
public class ZippedAppFile implements Updatable {
|
||||
|
||||
Application app;
|
||||
File file;
|
||||
long lastmod;
|
||||
Set updatables;
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new ZippedAppFile object.
|
||||
*
|
||||
* @param file ...
|
||||
* @param app ...
|
||||
*/
|
||||
public ZippedAppFile(File file, Application app) {
|
||||
this.app = app;
|
||||
this.file = file;
|
||||
|
||||
// System.err.println ("CREATING ZIP FILE "+this);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Tell the type manager whether we need an update. this is the case when
|
||||
* the file has been modified or deleted.
|
||||
*/
|
||||
public boolean needsUpdate() {
|
||||
return !file.exists () || lastmod != file.lastModified ();
|
||||
return !file.exists() || (lastmod != file.lastModified());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void update() {
|
||||
|
||||
if (!file.exists()) {
|
||||
remove();
|
||||
|
||||
} else {
|
||||
|
||||
ZipFile zip = null;
|
||||
|
||||
// collect created protos - we need this to check DbMappings for each created
|
||||
// prototype afterwards
|
||||
HashSet newPrototypes = new HashSet();
|
||||
|
||||
try {
|
||||
lastmod = file.lastModified();
|
||||
|
||||
// System.err.println ("UPDATING ZIP FILE "+this);
|
||||
zip = new ZipFile(file);
|
||||
updatables = new HashSet();
|
||||
|
||||
for (Enumeration en = zip.entries(); en.hasMoreElements();) {
|
||||
ZipEntry entry = (ZipEntry) en.nextElement();
|
||||
String ename = entry.getName();
|
||||
StringTokenizer st = new StringTokenizer(ename, "/");
|
||||
|
||||
if (st.countTokens() == 2) {
|
||||
String dir = st.nextToken();
|
||||
String fname = st.nextToken();
|
||||
|
||||
// System.err.println ("ZIPENTRY: "+ dir +" ~ "+fname);
|
||||
Prototype proto = app.typemgr.getPrototype(dir);
|
||||
|
||||
if (proto == null) {
|
||||
proto = app.typemgr.createPrototype(dir);
|
||||
newPrototypes.add(proto);
|
||||
}
|
||||
|
||||
if (fname.endsWith(".hac")) {
|
||||
String name = fname.substring(0, fname.lastIndexOf("."));
|
||||
String sourceName = file.getName() + "/" + ename;
|
||||
String content = getZipEntryContent(zip, entry);
|
||||
|
||||
// System.err.println ("["+content+"]");
|
||||
ActionFile act = new ActionFile (content, name, sourceName, proto);
|
||||
ActionFile act = new ActionFile(content, name, sourceName,
|
||||
proto);
|
||||
|
||||
proto.addActionFile(act);
|
||||
updatables.add(act);
|
||||
|
||||
// mark prototype as updated
|
||||
proto.markUpdated();
|
||||
}
|
||||
else if (fname.endsWith (".hsp")) {
|
||||
} else if (fname.endsWith(".hsp")) {
|
||||
String name = fname.substring(0, fname.lastIndexOf("."));
|
||||
String sourceName = file.getName() + "/" + ename;
|
||||
String content = getZipEntryContent(zip, entry);
|
||||
|
||||
// System.err.println ("["+content+"]");
|
||||
Template tmp = new Template(content, name, sourceName, proto);
|
||||
|
||||
proto.addTemplate(tmp);
|
||||
updatables.add(tmp);
|
||||
|
||||
// mark prototype as updated
|
||||
proto.markUpdated();
|
||||
}
|
||||
else if (fname.endsWith (".skin")) {
|
||||
} else if (fname.endsWith(".skin")) {
|
||||
String name = fname.substring(0, fname.lastIndexOf("."));
|
||||
String content = getZipEntryContent(zip, entry);
|
||||
|
||||
// System.err.println ("["+content+"]");
|
||||
SkinFile skin = new SkinFile(content, name, proto);
|
||||
|
||||
proto.addSkinFile(skin);
|
||||
updatables.add(skin);
|
||||
}
|
||||
else if (fname.endsWith (".js")) {
|
||||
} else if (fname.endsWith(".js")) {
|
||||
String sourceName = file.getName() + "/" + ename;
|
||||
String content = getZipEntryContent(zip, entry);
|
||||
|
||||
// System.err.println ("["+content+"]");
|
||||
FunctionFile ff = new FunctionFile(content, sourceName, proto);
|
||||
|
||||
proto.addFunctionFile(ff);
|
||||
updatables.add(ff);
|
||||
|
||||
// mark prototype as updated
|
||||
proto.markUpdated();
|
||||
}
|
||||
else if ("type.properties".equalsIgnoreCase (fname)) {
|
||||
} else if ("type.properties".equalsIgnoreCase(fname)) {
|
||||
DbMapping dbmap = proto.getDbMapping();
|
||||
SystemProperties props = dbmap.getProperties();
|
||||
|
||||
props.addProps(file.getName(), zip.getInputStream(entry));
|
||||
|
||||
// mark prototype as updated
|
||||
proto.markUpdated();
|
||||
}
|
||||
|
@ -124,37 +156,53 @@ public class ZippedAppFile implements Updatable {
|
|||
} finally {
|
||||
try {
|
||||
zip.close();
|
||||
} catch (Exception ignore) {}
|
||||
} catch (Exception ignore) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void remove() {
|
||||
if (updatables != null) {
|
||||
for (Iterator it = updatables.iterator(); it.hasNext();)
|
||||
((Updatable) it.next()).remove();
|
||||
}
|
||||
|
||||
app.typemgr.removeZipFile(file.getName());
|
||||
|
||||
// System.err.println ("REMOVING ZIP FILE "+this);
|
||||
}
|
||||
|
||||
|
||||
public String getZipEntryContent (ZipFile zip, ZipEntry entry) throws IOException {
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param zip ...
|
||||
* @param entry ...
|
||||
*
|
||||
* @return ...
|
||||
*
|
||||
* @throws IOException ...
|
||||
*/
|
||||
public String getZipEntryContent(ZipFile zip, ZipEntry entry)
|
||||
throws IOException {
|
||||
int size = (int) entry.getSize();
|
||||
char[] c = new char[size];
|
||||
InputStreamReader reader = new InputStreamReader(zip.getInputStream(entry));
|
||||
|
||||
reader.read(c);
|
||||
|
||||
return new String(c);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String toString() {
|
||||
return file.getName();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,126 +1,217 @@
|
|||
// ImageGenerator.java
|
||||
// Copyright (c) Hannes Wallnöfer 1999-2000
|
||||
/*
|
||||
* 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.image;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.image.*;
|
||||
import java.net.URL;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
|
||||
/**
|
||||
* Factory class for generating Image objects from various sources.
|
||||
*
|
||||
*/
|
||||
|
||||
public class ImageGenerator {
|
||||
|
||||
/**
|
||||
* Creates a new ImageGenerator object.
|
||||
*/
|
||||
public ImageGenerator() {
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param w ...
|
||||
* @param h ...
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public ImageWrapper createPaintableImage(int w, int h) {
|
||||
BufferedImage img = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
|
||||
Graphics g = img.getGraphics();
|
||||
ImageWrapper rimg = new SunImageWrapper(img, g, w, h, this);
|
||||
|
||||
return rimg;
|
||||
}
|
||||
|
||||
public ImageWrapper createPaintableImage (byte src[]) {
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param src ...
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public ImageWrapper createPaintableImage(byte[] src) {
|
||||
ImageWrapper rimg = null;
|
||||
Image img1 = Toolkit.getDefaultToolkit().createImage(src);
|
||||
ImageLoader loader = new ImageLoader(img1);
|
||||
|
||||
try {
|
||||
loader.getDimensions();
|
||||
|
||||
int w = loader.getWidth();
|
||||
int h = loader.getHeight();
|
||||
Image img = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
|
||||
Graphics g = img.getGraphics();
|
||||
|
||||
g.drawImage(img1, 0, 0, null);
|
||||
rimg = new SunImageWrapper(img, g, w, h, this);
|
||||
} finally {
|
||||
loader.done();
|
||||
}
|
||||
|
||||
return rimg;
|
||||
}
|
||||
|
||||
public ImageWrapper createImage (byte src[]) {
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param src ...
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public ImageWrapper createImage(byte[] src) {
|
||||
ImageWrapper rimg = null;
|
||||
Image img = Toolkit.getDefaultToolkit().createImage(src);
|
||||
ImageLoader loader = new ImageLoader(img);
|
||||
|
||||
try {
|
||||
loader.getDimensions();
|
||||
|
||||
int w = loader.getWidth();
|
||||
int h = loader.getHeight();
|
||||
|
||||
rimg = new SunImageWrapper(img, null, w, h, this);
|
||||
} finally {
|
||||
loader.done();
|
||||
}
|
||||
|
||||
return rimg;
|
||||
}
|
||||
|
||||
|
||||
public ImageWrapper createPaintableImage (String urlstring) throws MalformedURLException {
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param urlstring ...
|
||||
*
|
||||
* @return ...
|
||||
*
|
||||
* @throws MalformedURLException ...
|
||||
*/
|
||||
public ImageWrapper createPaintableImage(String urlstring)
|
||||
throws MalformedURLException {
|
||||
ImageWrapper rimg = null;
|
||||
URL url = new URL(urlstring);
|
||||
Image img1 = Toolkit.getDefaultToolkit().createImage(url);
|
||||
ImageLoader loader = new ImageLoader(img1);
|
||||
|
||||
try {
|
||||
loader.getDimensions();
|
||||
|
||||
int w = loader.getWidth();
|
||||
int h = loader.getHeight();
|
||||
Image img = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
|
||||
Graphics g = img.getGraphics();
|
||||
|
||||
g.drawImage(img1, 0, 0, null);
|
||||
rimg = new SunImageWrapper(img, g, w, h, this);
|
||||
} finally {
|
||||
loader.done();
|
||||
}
|
||||
|
||||
return rimg;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param iw ...
|
||||
* @param filter ...
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public ImageWrapper createPaintableImage(ImageWrapper iw, ImageFilter filter) {
|
||||
ImageWrapper rimg = null;
|
||||
FilteredImageSource fis = new FilteredImageSource(iw.getSource(), filter);
|
||||
Image img1 = Toolkit.getDefaultToolkit().createImage(fis);
|
||||
ImageLoader loader = new ImageLoader(img1);
|
||||
|
||||
try {
|
||||
loader.getDimensions();
|
||||
|
||||
int w = loader.getWidth();
|
||||
int h = loader.getHeight();
|
||||
Image img = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
|
||||
Graphics g = img.getGraphics();
|
||||
|
||||
g.drawImage(img1, 0, 0, null);
|
||||
rimg = new SunImageWrapper(img, g, w, h, this);
|
||||
} finally {
|
||||
loader.done();
|
||||
}
|
||||
|
||||
return rimg;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param filename ...
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public Image createImage(String filename) {
|
||||
Image img = null;
|
||||
|
||||
img = Toolkit.getDefaultToolkit().createImage(filename);
|
||||
|
||||
ImageLoader loader = new ImageLoader(img);
|
||||
|
||||
loader.getDimensions();
|
||||
loader.done();
|
||||
|
||||
return img;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param producer ...
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public Image createImage(ImageProducer producer) {
|
||||
Image img = null;
|
||||
|
||||
img = Toolkit.getDefaultToolkit().createImage(producer);
|
||||
|
||||
ImageLoader loader = new ImageLoader(img);
|
||||
|
||||
loader.getDimensions();
|
||||
loader.done();
|
||||
|
||||
return img;
|
||||
}
|
||||
|
||||
class ImageLoader implements ImageObserver {
|
||||
|
||||
Image img;
|
||||
int w, h;
|
||||
int w;
|
||||
int h;
|
||||
boolean waiting;
|
||||
boolean firstFrameLoaded;
|
||||
|
||||
|
@ -133,18 +224,21 @@ public class ImageGenerator {
|
|||
synchronized void getDimensions() {
|
||||
w = img.getWidth(this);
|
||||
h = img.getHeight(this);
|
||||
if (w == -1 || h == -1) {
|
||||
|
||||
if ((w == -1) || (h == -1)) {
|
||||
try {
|
||||
wait(45000);
|
||||
} catch (InterruptedException x) {
|
||||
waiting = false;
|
||||
|
||||
return;
|
||||
} finally {
|
||||
waiting = false;
|
||||
}
|
||||
}
|
||||
|
||||
// if width and height haven't been set, throw tantrum
|
||||
if (w == -1 || h == -1) {
|
||||
if ((w == -1) || (h == -1)) {
|
||||
throw new RuntimeException("Error loading image");
|
||||
}
|
||||
}
|
||||
|
@ -162,37 +256,40 @@ public class ImageGenerator {
|
|||
return h;
|
||||
}
|
||||
|
||||
public synchronized boolean imageUpdate(Image img,
|
||||
int infoflags,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height) {
|
||||
public synchronized boolean imageUpdate(Image img, int infoflags, int x, int y,
|
||||
int width, int height) {
|
||||
// check if there was an error
|
||||
if (!waiting || (infoflags & ERROR) > 0 || (infoflags & ABORT) > 0) {
|
||||
if (!waiting || ((infoflags & ERROR) > 0) || ((infoflags & ABORT) > 0)) {
|
||||
// we either timed out or there was an error.
|
||||
notifyAll();
|
||||
|
||||
return false;
|
||||
}
|
||||
if ((infoflags & WIDTH) > 0 || (infoflags & HEIGHT) > 0) {
|
||||
if ((infoflags & WIDTH) > 0)
|
||||
|
||||
if (((infoflags & WIDTH) > 0) || ((infoflags & HEIGHT) > 0)) {
|
||||
if ((infoflags & WIDTH) > 0) {
|
||||
w = width;
|
||||
if ((infoflags & HEIGHT) > 0)
|
||||
}
|
||||
|
||||
if ((infoflags & HEIGHT) > 0) {
|
||||
h = height;
|
||||
if (w > -1 && h > -1 && firstFrameLoaded) {
|
||||
}
|
||||
|
||||
if ((w > -1) && (h > -1) && firstFrameLoaded) {
|
||||
notifyAll();
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if ((infoflags & ALLBITS) > 0 || (infoflags & FRAMEBITS) > 0) {
|
||||
|
||||
if (((infoflags & ALLBITS) > 0) || ((infoflags & FRAMEBITS) > 0)) {
|
||||
firstFrameLoaded = true;
|
||||
notifyAll();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,36 +1,61 @@
|
|||
// ImageWrapper.java
|
||||
// Copyright (c) Hannes Wallnöfer 1999-2000
|
||||
/*
|
||||
* 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.image;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.image.*;
|
||||
import java.util.*;
|
||||
import java.io.*;
|
||||
import java.rmi.*;
|
||||
import java.rmi.server.*;
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Abstract base class for Image Wrappers.
|
||||
*/
|
||||
|
||||
public abstract class ImageWrapper {
|
||||
|
||||
Image img;
|
||||
Graphics g;
|
||||
int width, height;
|
||||
int fontstyle, fontsize;
|
||||
int width;
|
||||
int height;
|
||||
int fontstyle;
|
||||
int fontsize;
|
||||
String fontname;
|
||||
ImageGenerator imggen;
|
||||
|
||||
public ImageWrapper (Image img, Graphics g, int width, int height, ImageGenerator imggen) {
|
||||
/**
|
||||
* Creates a new ImageWrapper object.
|
||||
*
|
||||
* @param img ...
|
||||
* @param g ...
|
||||
* @param width ...
|
||||
* @param height ...
|
||||
* @param imggen ...
|
||||
*/
|
||||
public ImageWrapper(Image img, Graphics g, int width, int height,
|
||||
ImageGenerator imggen) {
|
||||
this.img = img;
|
||||
this.g = g;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.imggen = imggen;
|
||||
|
||||
if (g != null) {
|
||||
Font f = g.getFont();
|
||||
|
||||
fontname = f.getName();
|
||||
fontstyle = f.getStyle();
|
||||
fontsize = f.getSize();
|
||||
|
@ -40,7 +65,6 @@ public abstract class ImageWrapper {
|
|||
/**
|
||||
* image manipulation methods
|
||||
*/
|
||||
|
||||
public void setFont(String name, int style, int size) {
|
||||
this.fontname = name;
|
||||
this.fontstyle = style;
|
||||
|
@ -48,65 +72,158 @@ public abstract class ImageWrapper {
|
|||
g.setFont(new Font(name, style, size));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param red ...
|
||||
* @param green ...
|
||||
* @param blue ...
|
||||
*/
|
||||
public void setColor(int red, int green, int blue) {
|
||||
g.setColor(new Color(red, green, blue));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param color ...
|
||||
*/
|
||||
public void setColor(int color) {
|
||||
g.setColor(new Color(color));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param str ...
|
||||
* @param x ...
|
||||
* @param y ...
|
||||
*/
|
||||
public void drawString(String str, int x, int y) {
|
||||
g.drawString(str, x, y);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param x1 ...
|
||||
* @param y1 ...
|
||||
* @param x2 ...
|
||||
* @param y2 ...
|
||||
*/
|
||||
public void drawLine(int x1, int y1, int x2, int y2) {
|
||||
g.drawLine(x1, y1, x2, y2);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param x ...
|
||||
* @param y ...
|
||||
* @param w ...
|
||||
* @param h ...
|
||||
*/
|
||||
public void drawRect(int x, int y, int w, int h) {
|
||||
g.drawRect(x, y, w, h);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param filename ...
|
||||
* @param x ...
|
||||
* @param y ...
|
||||
*/
|
||||
public void drawImage(String filename, int x, int y) {
|
||||
try {
|
||||
Image i = imggen.createImage(filename);
|
||||
|
||||
g.drawImage(i, x, y, null);
|
||||
} catch (Exception ignore) {}
|
||||
} catch (Exception ignore) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param x ...
|
||||
* @param y ...
|
||||
* @param w ...
|
||||
* @param h ...
|
||||
*/
|
||||
public void fillRect(int x, int y, int w, int h) {
|
||||
g.fillRect(x, y, w, h);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public int getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public int getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param x ...
|
||||
* @param y ...
|
||||
* @param w ...
|
||||
* @param h ...
|
||||
*/
|
||||
public void crop(int x, int y, int w, int h) {
|
||||
ImageFilter filter = new CropImageFilter(x, y, w, h);
|
||||
img = Toolkit.getDefaultToolkit ().createImage(new FilteredImageSource(img.getSource(), filter));
|
||||
|
||||
img = Toolkit.getDefaultToolkit().createImage(new FilteredImageSource(img.getSource(),
|
||||
filter));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param w ...
|
||||
* @param h ...
|
||||
*/
|
||||
public void resize(int w, int h) {
|
||||
img = img.getScaledInstance(w, h, Image.SCALE_SMOOTH);
|
||||
width = w;
|
||||
height = h;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param w ...
|
||||
* @param h ...
|
||||
*/
|
||||
public void resizeFast(int w, int h) {
|
||||
img = img.getScaledInstance(w, h, Image.SCALE_FAST);
|
||||
width = w;
|
||||
height = h;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param colors ...
|
||||
*/
|
||||
public abstract void reduceColors(int colors);
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param filename ...
|
||||
*/
|
||||
public abstract void saveAs(String filename);
|
||||
|
||||
/**
|
||||
|
@ -116,21 +233,40 @@ public abstract class ImageWrapper {
|
|||
return img.getSource();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param str ...
|
||||
*/
|
||||
public void fillString(String str) {
|
||||
Filler filler = new Filler(0, 0, width, height);
|
||||
|
||||
filler.layout(str);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param str ...
|
||||
* @param x ...
|
||||
* @param y ...
|
||||
* @param w ...
|
||||
* @param h ...
|
||||
*/
|
||||
public void fillString(String str, int x, int y, int w, int h) {
|
||||
Filler filler = new Filler(x, y, w, h);
|
||||
|
||||
filler.layout(str);
|
||||
}
|
||||
|
||||
class Filler {
|
||||
|
||||
int x, y, w, h;
|
||||
int x;
|
||||
int y;
|
||||
int w;
|
||||
int h;
|
||||
int addedSpace = 0;
|
||||
int xLeft, yLeft;
|
||||
int xLeft;
|
||||
int yLeft;
|
||||
int realHeight;
|
||||
transient Vector lines;
|
||||
|
||||
|
@ -143,22 +279,28 @@ public abstract class ImageWrapper {
|
|||
|
||||
public void layout(String str) {
|
||||
int size = fontsize;
|
||||
|
||||
lines = new Vector();
|
||||
while (!splitMessage (str, size) && size > 10) {
|
||||
|
||||
while (!splitMessage(str, size) && (size > 10)) {
|
||||
lines.setSize(0);
|
||||
size = Math.max(2, size - 1);
|
||||
}
|
||||
|
||||
Font oldfont = g.getFont();
|
||||
|
||||
g.setFont(new Font(fontname, fontstyle, size));
|
||||
|
||||
int l = lines.size();
|
||||
|
||||
for (int i = 0; i < l; i++) {
|
||||
((Line) lines.elementAt (i)).paint (g, xLeft/2, yLeft/2 + y);
|
||||
((Line) lines.elementAt(i)).paint(g, xLeft / 2, (yLeft / 2) + y);
|
||||
}
|
||||
|
||||
g.setFont(oldfont);
|
||||
}
|
||||
|
||||
private boolean splitMessage(String string, int size) {
|
||||
|
||||
Font font = new Font(fontname, fontstyle, size);
|
||||
FontMetrics metrics = Toolkit.getDefaultToolkit().getFontMetrics(font);
|
||||
int longestLine = 0;
|
||||
|
@ -169,54 +311,70 @@ public abstract class ImageWrapper {
|
|||
int spaceWidth = metrics.stringWidth(" ");
|
||||
int currentLine = 0;
|
||||
int currentWidth = 0;
|
||||
int maxWidth = w - 2, maxHeight = h + addedSpace - 2;
|
||||
int maxWidth = w - 2;
|
||||
int maxHeight = (h + addedSpace) - 2;
|
||||
|
||||
while (tk.hasMoreTokens()) {
|
||||
String nextToken = tk.nextToken();
|
||||
int nextWidth = metrics.stringWidth(nextToken);
|
||||
if ((currentWidth + nextWidth >= maxWidth && currentWidth != 0)) {
|
||||
|
||||
if ((((currentWidth + nextWidth) >= maxWidth) && (currentWidth != 0))) {
|
||||
Line line = new Line(buffer.toString(), x, heightSoFar, metrics);
|
||||
|
||||
lines.addElement(line);
|
||||
if (line.textwidth > longestLine)
|
||||
|
||||
if (line.textwidth > longestLine) {
|
||||
longestLine = line.textwidth;
|
||||
}
|
||||
|
||||
buffer = new StringBuffer();
|
||||
|
||||
currentWidth = 0;
|
||||
heightSoFar += heightIncrement;
|
||||
}
|
||||
|
||||
buffer.append(nextToken);
|
||||
buffer.append(" ");
|
||||
currentWidth += (nextWidth + spaceWidth);
|
||||
if (1.18*heightSoFar > maxHeight && fontsize > 10)
|
||||
|
||||
if (((1.18 * heightSoFar) > maxHeight) && (fontsize > 10)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!"".equals(buffer.toString().trim())) {
|
||||
Line line = new Line(buffer.toString(), x, heightSoFar, metrics);
|
||||
|
||||
lines.addElement(line);
|
||||
|
||||
if (line.textwidth > longestLine)
|
||||
if (line.textwidth > longestLine) {
|
||||
longestLine = line.textwidth;
|
||||
if (longestLine > maxWidth && fontsize > 10)
|
||||
}
|
||||
|
||||
if ((longestLine > maxWidth) && (fontsize > 10)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
heightSoFar += heightIncrement;
|
||||
}
|
||||
|
||||
xLeft = w - longestLine;
|
||||
yLeft = addedSpace + h - heightSoFar;
|
||||
yLeft = (addedSpace + h) - heightSoFar;
|
||||
realHeight = heightSoFar;
|
||||
return (1.18*heightSoFar <= maxHeight);
|
||||
}
|
||||
|
||||
return ((1.18 * heightSoFar) <= maxHeight);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class Line implements Serializable {
|
||||
|
||||
String text;
|
||||
int xoff, yoff;
|
||||
int xoff;
|
||||
int yoff;
|
||||
FontMetrics fm;
|
||||
public int textwidth, len;
|
||||
public int textwidth;
|
||||
public int len;
|
||||
int ascent;
|
||||
|
||||
|
||||
public Line(String text, int xoff, int yoff, FontMetrics fm) {
|
||||
this.text = text.trim();
|
||||
len = text.length();
|
||||
|
@ -231,17 +389,8 @@ public abstract class ImageWrapper {
|
|||
g.drawString(text, xoff + xadd, yoff + ascent + yadd);
|
||||
}
|
||||
|
||||
|
||||
public boolean contains(int y) {
|
||||
return (y < yoff+fm.getHeight()) ? true : false;
|
||||
return (y < (yoff + fm.getHeight())) ? true : false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,42 +1,68 @@
|
|||
// ActivatedImageWrapper.java
|
||||
// Copyright (c) Hannes Wallnöfer 1999-2000
|
||||
/*
|
||||
* 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.image;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.image.*;
|
||||
import Acme.JPM.Encoders.GifEncoder;
|
||||
import com.sun.jimi.core.*;
|
||||
import com.sun.jimi.core.util.*;
|
||||
import Acme.JPM.Encoders.GifEncoder;
|
||||
import java.io.IOException;
|
||||
import java.awt.*;
|
||||
import java.awt.image.*;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* A wrapper for an image that uses the Sun version of JIMI available at
|
||||
* http://java.sun.com/products/jimi.
|
||||
*/
|
||||
|
||||
public class SunImageWrapper extends ImageWrapper {
|
||||
|
||||
/**
|
||||
* Creates a new SunImageWrapper object.
|
||||
*
|
||||
* @param img ...
|
||||
* @param g ...
|
||||
* @param width ...
|
||||
* @param height ...
|
||||
* @param imggen ...
|
||||
*/
|
||||
public SunImageWrapper(Image img, Graphics g, int width, int height,
|
||||
ImageGenerator imggen) {
|
||||
super(img, g, width, height, imggen);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param colors ...
|
||||
*/
|
||||
public void reduceColors(int colors) {
|
||||
try {
|
||||
int pixels[][] = getPixels();
|
||||
int palette[] = Quantize.quantizeImage(pixels, colors);
|
||||
int[][] pixels = getPixels();
|
||||
int[] palette = Quantize.quantizeImage(pixels, colors);
|
||||
int w = pixels.length;
|
||||
int h = pixels[0].length;
|
||||
int pix[] = new int[w * h];
|
||||
int[] pix = new int[w * h];
|
||||
|
||||
// convert to RGB
|
||||
for (int x = w; x-- > 0;) {
|
||||
for (int y = h; y-- > 0;) {
|
||||
pix[y * w + x] = palette[pixels[x][y]];
|
||||
pix[(y * w) + x] = palette[pixels[x][y]];
|
||||
}
|
||||
}
|
||||
|
||||
img = imggen.createImage(new MemoryImageSource(w, h, pix, 0, w));
|
||||
} catch (Exception x) {
|
||||
// throw new RuntimeException (x.getMessage ());
|
||||
|
@ -47,8 +73,9 @@ public class SunImageWrapper extends ImageWrapper {
|
|||
* Snag the pixels from an image.
|
||||
*/
|
||||
int[][] getPixels() throws IOException {
|
||||
int pix[] = new int[width * height];
|
||||
int[] pix = new int[width * height];
|
||||
PixelGrabber grabber = new PixelGrabber(img, 0, 0, width, height, pix, 0, width);
|
||||
|
||||
try {
|
||||
if (grabber.grabPixels() != true) {
|
||||
throw new IOException("Grabber returned false: " + grabber.status());
|
||||
|
@ -56,23 +83,32 @@ public class SunImageWrapper extends ImageWrapper {
|
|||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
int pixels[][] = new int[width][height];
|
||||
|
||||
int[][] pixels = new int[width][height];
|
||||
|
||||
for (int x = width; x-- > 0;) {
|
||||
for (int y = height; y-- > 0;) {
|
||||
pixels[x][y] = pix[y * width + x];
|
||||
pixels[x][y] = pix[(y * width) + x];
|
||||
}
|
||||
}
|
||||
|
||||
return pixels;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param filename ...
|
||||
*/
|
||||
public void saveAs(String filename) {
|
||||
try {
|
||||
if (filename.toLowerCase().endsWith(".gif")) {
|
||||
// sun's jimi package doesn't encode gifs, use Acme encoder
|
||||
FileOutputStream fout = new FileOutputStream(filename);
|
||||
|
||||
// Acme gif encoder
|
||||
GifEncoder enc = new GifEncoder(img, fout);
|
||||
|
||||
enc.encode();
|
||||
fout.close();
|
||||
} else {
|
||||
|
@ -82,6 +118,4 @@ public class SunImageWrapper extends ImageWrapper {
|
|||
throw new RuntimeException(x.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -1,33 +1,43 @@
|
|||
// ApplicationManager.java
|
||||
// Copyright (c) Hannes Wallnöfer 1998-2000
|
||||
/*
|
||||
* 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.main;
|
||||
|
||||
import java.util.*;
|
||||
import java.io.*;
|
||||
import java.lang.reflect.*;
|
||||
import java.rmi.*;
|
||||
import java.rmi.server.*;
|
||||
import java.net.URLEncoder;
|
||||
import helma.framework.*;
|
||||
import helma.framework.core.*;
|
||||
import helma.objectmodel.*;
|
||||
import helma.servlet.*;
|
||||
import helma.util.SystemProperties;
|
||||
import org.apache.xmlrpc.XmlRpcHandler;
|
||||
import org.mortbay.http.*;
|
||||
import org.mortbay.http.handler.*;
|
||||
import org.mortbay.jetty.servlet.*;
|
||||
import org.mortbay.util.*;
|
||||
import java.io.*;
|
||||
import java.lang.reflect.*;
|
||||
import java.net.URLEncoder;
|
||||
import java.rmi.*;
|
||||
import java.rmi.server.*;
|
||||
import java.util.*;
|
||||
import javax.servlet.Servlet;
|
||||
import org.apache.xmlrpc.XmlRpcHandler;
|
||||
|
||||
|
||||
/**
|
||||
* This class is responsible for starting and stopping Helma applications.
|
||||
*/
|
||||
|
||||
public class ApplicationManager implements XmlRpcHandler {
|
||||
|
||||
private Hashtable applications;
|
||||
private Hashtable xmlrpcHandlers;
|
||||
private Properties mountpoints;
|
||||
|
@ -37,7 +47,16 @@ public class ApplicationManager implements XmlRpcHandler {
|
|||
private Server server;
|
||||
private long lastModified;
|
||||
|
||||
public ApplicationManager (int port, File hopHome, SystemProperties props, Server server) {
|
||||
/**
|
||||
* Creates a new ApplicationManager object.
|
||||
*
|
||||
* @param port ...
|
||||
* @param hopHome ...
|
||||
* @param props ...
|
||||
* @param server ...
|
||||
*/
|
||||
public ApplicationManager(int port, File hopHome, SystemProperties props,
|
||||
Server server) {
|
||||
this.port = port;
|
||||
this.hopHome = hopHome;
|
||||
this.props = props;
|
||||
|
@ -48,21 +67,24 @@ public class ApplicationManager implements XmlRpcHandler {
|
|||
lastModified = 0;
|
||||
}
|
||||
|
||||
|
||||
// regularely check applications property file to create and start new applications
|
||||
protected void checkForChanges() {
|
||||
if (props.lastModified() > lastModified) {
|
||||
try {
|
||||
for (Enumeration e = props.keys(); e.hasMoreElements();) {
|
||||
String appName = (String) e.nextElement();
|
||||
if (appName.indexOf (".") == -1 && applications.get (appName) == null) {
|
||||
|
||||
if ((appName.indexOf(".") == -1) &&
|
||||
(applications.get(appName) == null)) {
|
||||
start(appName);
|
||||
register(appName);
|
||||
}
|
||||
}
|
||||
|
||||
// then stop deleted ones
|
||||
for (Enumeration e = applications.keys(); e.hasMoreElements();) {
|
||||
String appName = (String) e.nextElement();
|
||||
|
||||
// check if application has been removed and should be stopped
|
||||
if (!props.containsKey(appName)) {
|
||||
stop(appName);
|
||||
|
@ -72,31 +94,57 @@ public class ApplicationManager implements XmlRpcHandler {
|
|||
String oldMountpoint = mountpoints.getProperty(appName);
|
||||
String mountpoint = getMountpoint(appName);
|
||||
String pattern = getPathPattern(mountpoint);
|
||||
|
||||
if (!pattern.equals(oldMountpoint)) {
|
||||
Server.getLogger().log("Moving application "+appName+" from "+oldMountpoint+" to "+pattern);
|
||||
HttpContext oldContext = server.http.getContext (null, oldMountpoint);
|
||||
Server.getLogger().log("Moving application " + appName +
|
||||
" from " + oldMountpoint + " to " +
|
||||
pattern);
|
||||
|
||||
HttpContext oldContext = server.http.getContext(null,
|
||||
oldMountpoint);
|
||||
|
||||
if (oldContext != null) {
|
||||
// oldContext.setContextPath(pattern);
|
||||
oldContext.stop();
|
||||
oldContext.destroy();
|
||||
}
|
||||
|
||||
Application app = (Application) applications.get(appName);
|
||||
if (!app.hasExplicitBaseURI())
|
||||
|
||||
if (!app.hasExplicitBaseURI()) {
|
||||
app.setBaseURI(mountpoint);
|
||||
}
|
||||
|
||||
ServletHttpContext context = new ServletHttpContext();
|
||||
|
||||
context.setContextPath(pattern);
|
||||
server.http.addContext(context);
|
||||
ServletHolder holder = context.addServlet (appName, "/*", "helma.servlet.EmbeddedServletClient");
|
||||
|
||||
ServletHolder holder = context.addServlet(appName, "/*",
|
||||
"helma.servlet.EmbeddedServletClient");
|
||||
|
||||
holder.setInitParameter("application", appName);
|
||||
holder.setInitParameter("mountpoint", mountpoint);
|
||||
if ("true".equalsIgnoreCase (props.getProperty (appName+".responseEncoding")))
|
||||
|
||||
if ("true".equalsIgnoreCase(props.getProperty(appName +
|
||||
".responseEncoding"))) {
|
||||
context.addHandler(new ContentEncodingHandler());
|
||||
String cookieDomain = props.getProperty (appName+".cookieDomain");
|
||||
if (cookieDomain != null)
|
||||
}
|
||||
|
||||
String cookieDomain = props.getProperty(appName +
|
||||
".cookieDomain");
|
||||
|
||||
if (cookieDomain != null) {
|
||||
holder.setInitParameter("cookieDomain", cookieDomain);
|
||||
String uploadLimit = props.getProperty (appName+".uploadLimit");
|
||||
if (uploadLimit != null)
|
||||
}
|
||||
|
||||
String uploadLimit = props.getProperty(appName +
|
||||
".uploadLimit");
|
||||
|
||||
if (uploadLimit != null) {
|
||||
holder.setInitParameter("uploadLimit", uploadLimit);
|
||||
}
|
||||
|
||||
// holder.start ();
|
||||
context.start();
|
||||
mountpoints.setProperty(appName, pattern);
|
||||
|
@ -113,16 +161,20 @@ public class ApplicationManager implements XmlRpcHandler {
|
|||
|
||||
void start(String appName) {
|
||||
Server.getLogger().log("Building application " + appName);
|
||||
|
||||
try {
|
||||
// check if application and db dirs are set, otherwise go with
|
||||
// the defaults, passing null dirs to the constructor.
|
||||
String appDirName = props.getProperty(appName + ".appdir");
|
||||
File appDir = appDirName == null ? null : new File (appDirName);
|
||||
File appDir = (appDirName == null) ? null : new File(appDirName);
|
||||
String dbDirName = props.getProperty(appName + ".dbdir");
|
||||
File dbDir = dbDirName == null ? null : new File (dbDirName);
|
||||
File dbDir = (dbDirName == null) ? null : new File(dbDirName);
|
||||
|
||||
// create the application instance
|
||||
Application app = new Application(appName, server, appDir, dbDir);
|
||||
|
||||
applications.put(appName, app);
|
||||
|
||||
// the application is started later in the register method, when it's bound
|
||||
app.init();
|
||||
} catch (Exception x) {
|
||||
|
@ -133,21 +185,26 @@ public class ApplicationManager implements XmlRpcHandler {
|
|||
|
||||
void stop(String appName) {
|
||||
Server.getLogger().log("Stopping application " + appName);
|
||||
|
||||
try {
|
||||
Application app = (Application) applications.get(appName);
|
||||
|
||||
// unbind from RMI server
|
||||
if (port > 0) {
|
||||
Naming.unbind("//:" + port + "/" + appName);
|
||||
}
|
||||
|
||||
// unbind from Jetty HTTP server
|
||||
if (server.http != null) {
|
||||
String mountpoint = mountpoints.getProperty(appName);
|
||||
HttpContext context = server.http.getContext(null, mountpoint);
|
||||
|
||||
if (context != null) {
|
||||
context.stop();
|
||||
context.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
// unregister as XML-RPC handler
|
||||
xmlrpcHandlers.remove(app.getXmlRpcHandlerName());
|
||||
app.stop();
|
||||
|
@ -155,45 +212,70 @@ public class ApplicationManager implements XmlRpcHandler {
|
|||
} catch (Exception x) {
|
||||
Server.getLogger().log("Couldn't unregister app: " + x);
|
||||
}
|
||||
|
||||
applications.remove(appName);
|
||||
}
|
||||
|
||||
void register(String appName) {
|
||||
try {
|
||||
Server.getLogger().log("Binding application " + appName);
|
||||
|
||||
Application app = (Application) applications.get(appName);
|
||||
|
||||
// bind to RMI server
|
||||
if (port > 0) {
|
||||
Naming.rebind("//:" + port + "/" + appName, new RemoteApplication(app));
|
||||
}
|
||||
|
||||
// bind to Jetty HTTP server
|
||||
if (server.http != null) {
|
||||
String mountpoint = getMountpoint(appName);
|
||||
|
||||
// if using embedded webserver (not AJP) set application URL prefix
|
||||
if (!app.hasExplicitBaseURI ())
|
||||
if (!app.hasExplicitBaseURI()) {
|
||||
app.setBaseURI(mountpoint);
|
||||
}
|
||||
|
||||
String pattern = getPathPattern(mountpoint);
|
||||
ServletHttpContext context = new ServletHttpContext();
|
||||
|
||||
context.setContextPath(pattern);
|
||||
server.http.addContext(context);
|
||||
ServletHolder holder = context.addServlet (appName, "/*", "helma.servlet.EmbeddedServletClient");
|
||||
|
||||
ServletHolder holder = context.addServlet(appName, "/*",
|
||||
"helma.servlet.EmbeddedServletClient");
|
||||
|
||||
holder.setInitParameter("application", appName);
|
||||
holder.setInitParameter("mountpoint", mountpoint);
|
||||
if ("true".equalsIgnoreCase (props.getProperty (appName+".responseEncoding")))
|
||||
|
||||
if ("true".equalsIgnoreCase(props.getProperty(appName +
|
||||
".responseEncoding"))) {
|
||||
context.addHandler(new ContentEncodingHandler());
|
||||
}
|
||||
|
||||
String cookieDomain = props.getProperty(appName + ".cookieDomain");
|
||||
if (cookieDomain != null)
|
||||
|
||||
if (cookieDomain != null) {
|
||||
holder.setInitParameter("cookieDomain", cookieDomain);
|
||||
}
|
||||
|
||||
String uploadLimit = props.getProperty(appName + ".uploadLimit");
|
||||
if (uploadLimit != null)
|
||||
|
||||
if (uploadLimit != null) {
|
||||
holder.setInitParameter("uploadLimit", uploadLimit);
|
||||
}
|
||||
|
||||
String debug = props.getProperty(appName + ".debug");
|
||||
if (debug != null)
|
||||
|
||||
if (debug != null) {
|
||||
holder.setInitParameter("debug", debug);
|
||||
}
|
||||
|
||||
// holder.start ();
|
||||
context.start();
|
||||
mountpoints.setProperty(appName, pattern);
|
||||
}
|
||||
|
||||
// register as XML-RPC handler
|
||||
xmlrpcHandlers.put(app.getXmlRpcHandlerName(), app);
|
||||
app.start();
|
||||
|
@ -203,28 +285,44 @@ public class ApplicationManager implements XmlRpcHandler {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void startAll() {
|
||||
try {
|
||||
for (Enumeration e = props.keys(); e.hasMoreElements();) {
|
||||
String appName = (String) e.nextElement();
|
||||
if (appName.indexOf (".") == -1)
|
||||
|
||||
if (appName.indexOf(".") == -1) {
|
||||
start(appName);
|
||||
}
|
||||
}
|
||||
|
||||
for (Enumeration e = props.keys(); e.hasMoreElements();) {
|
||||
String appName = (String) e.nextElement();
|
||||
if (appName.indexOf (".") == -1)
|
||||
|
||||
if (appName.indexOf(".") == -1) {
|
||||
register(appName);
|
||||
}
|
||||
}
|
||||
|
||||
if (server.http != null) {
|
||||
// add handler for static files.
|
||||
File staticContent = new File(server.getHopHome(), "static");
|
||||
Server.getLogger().log("Serving static content from "+staticContent.getAbsolutePath());
|
||||
|
||||
Server.getLogger().log("Serving static content from " +
|
||||
staticContent.getAbsolutePath());
|
||||
|
||||
HttpContext context = server.http.addContext("/static/*");
|
||||
|
||||
context.setResourceBase(staticContent.getAbsolutePath());
|
||||
|
||||
ResourceHandler handler = new ResourceHandler();
|
||||
|
||||
context.addHandler(handler);
|
||||
context.start();
|
||||
}
|
||||
|
||||
lastModified = System.currentTimeMillis();
|
||||
} catch (Exception mx) {
|
||||
Server.getLogger().log("Error starting applications: " + mx);
|
||||
|
@ -232,9 +330,13 @@ public class ApplicationManager implements XmlRpcHandler {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void stopAll() {
|
||||
for (Enumeration en = applications.keys(); en.hasMoreElements();) {
|
||||
String appName = (String) en.nextElement();
|
||||
|
||||
stop(appName);
|
||||
}
|
||||
}
|
||||
|
@ -256,39 +358,57 @@ public class ApplicationManager implements XmlRpcHandler {
|
|||
/**
|
||||
* Implements org.apache.xmlrpc.XmlRpcHandler.execute()
|
||||
*/
|
||||
public Object execute (String method, Vector params) throws Exception {
|
||||
public Object execute(String method, Vector params)
|
||||
throws Exception {
|
||||
int dot = method.indexOf(".");
|
||||
if (dot == -1)
|
||||
throw new Exception ("Method name \""+method+"\" does not specify a handler application");
|
||||
if (dot == 0 || dot == method.length()-1)
|
||||
|
||||
if (dot == -1) {
|
||||
throw new Exception("Method name \"" + method +
|
||||
"\" does not specify a handler application");
|
||||
}
|
||||
|
||||
if ((dot == 0) || (dot == (method.length() - 1))) {
|
||||
throw new Exception("\"" + method + "\" is not a valid XML-RPC method name");
|
||||
}
|
||||
|
||||
String handler = method.substring(0, dot);
|
||||
String method2 = method.substring(dot + 1);
|
||||
Application app = (Application) xmlrpcHandlers.get(handler);
|
||||
if (app == null)
|
||||
|
||||
if (app == null) {
|
||||
throw new Exception("Handler \"" + handler + "\" not found for " + method);
|
||||
}
|
||||
|
||||
return app.executeXmlRpc(method2, params);
|
||||
}
|
||||
|
||||
|
||||
private String getMountpoint(String appName) {
|
||||
String mountpoint = props.getProperty(appName + ".mountpoint");
|
||||
if (mountpoint == null)
|
||||
|
||||
if (mountpoint == null) {
|
||||
return "/" + URLEncoder.encode(appName);
|
||||
}
|
||||
|
||||
mountpoint = mountpoint.trim();
|
||||
if ("".equals (mountpoint))
|
||||
|
||||
if ("".equals(mountpoint)) {
|
||||
return "/";
|
||||
else if (!mountpoint.startsWith ("/"))
|
||||
} else if (!mountpoint.startsWith("/")) {
|
||||
return "/" + mountpoint;
|
||||
}
|
||||
|
||||
return mountpoint;
|
||||
}
|
||||
|
||||
private String getPathPattern(String mountpoint) {
|
||||
if ("/".equals (mountpoint))
|
||||
if ("/".equals(mountpoint)) {
|
||||
return "/";
|
||||
if (!mountpoint.endsWith ("/"))
|
||||
return mountpoint+"/*";
|
||||
return mountpoint+"*";
|
||||
}
|
||||
|
||||
if (!mountpoint.endsWith("/")) {
|
||||
return mountpoint + "/*";
|
||||
}
|
||||
|
||||
return mountpoint + "*";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,26 @@
|
|||
// HelmaSecurityManager.java
|
||||
/*
|
||||
* 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.main;
|
||||
|
||||
import java.security.Permission;
|
||||
import helma.framework.core.AppClassLoader;
|
||||
import java.io.FileDescriptor;
|
||||
import java.net.InetAddress;
|
||||
import java.security.Permission;
|
||||
import java.util.HashSet;
|
||||
import helma.framework.core.AppClassLoader;
|
||||
|
||||
/**
|
||||
* Liberal security manager for Helma system that makes sure application code
|
||||
|
@ -17,64 +31,281 @@ import helma.framework.core.AppClassLoader;
|
|||
* the name of the application trying to execute the action in question, if any.
|
||||
*/
|
||||
public class HelmaSecurityManager extends SecurityManager {
|
||||
|
||||
// The set of actions forbidden to application code.
|
||||
// We are pretty permissive, forbidding only System.exit()
|
||||
// and setting the security manager.
|
||||
private final static HashSet forbidden = new HashSet();
|
||||
|
||||
static {
|
||||
forbidden.add("exitVM");
|
||||
forbidden.add("setSecurityManager");
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param p ...
|
||||
*/
|
||||
public void checkPermission(Permission p) {
|
||||
if (p instanceof RuntimePermission) {
|
||||
if (forbidden.contains(p.getName())) {
|
||||
Class[] classes = getClassContext();
|
||||
|
||||
for (int i = 0; i < classes.length; i++) {
|
||||
if (classes[i].getClassLoader() instanceof AppClassLoader)
|
||||
throw new SecurityException (p.getName()+" not allowed for application code");
|
||||
if (classes[i].getClassLoader() instanceof AppClassLoader) {
|
||||
throw new SecurityException(p.getName() +
|
||||
" not allowed for application code");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param p ...
|
||||
* @param context ...
|
||||
*/
|
||||
public void checkPermission(Permission p, Object context) {
|
||||
}
|
||||
public void checkCreateClassLoader() {}
|
||||
public void checkAccess(Thread thread) {}
|
||||
public void checkAccess(ThreadGroup group) {}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void checkCreateClassLoader() {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param thread ...
|
||||
*/
|
||||
public void checkAccess(Thread thread) {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param group ...
|
||||
*/
|
||||
public void checkAccess(ThreadGroup group) {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param status ...
|
||||
*/
|
||||
public void checkExit(int status) {
|
||||
Class[] classes = getClassContext();
|
||||
|
||||
for (int i = 0; i < classes.length; i++) {
|
||||
if (classes[i].getClassLoader() instanceof AppClassLoader)
|
||||
if (classes[i].getClassLoader() instanceof AppClassLoader) {
|
||||
throw new SecurityException("operation not allowed for application code");
|
||||
}
|
||||
}
|
||||
public void checkExec(String cmd) {}
|
||||
public void checkLink(String lib) {}
|
||||
public void checkRead(FileDescriptor fdesc) {}
|
||||
public void checkRead(String file) {}
|
||||
public void checkRead(String file, Object context) {}
|
||||
public void checkWrite(FileDescriptor fdesc) {}
|
||||
public void checkWrite(String file) {}
|
||||
public void checkDelete(String file) {}
|
||||
public void checkConnect(String host, int port) {}
|
||||
public void checkConnect(String host, int port, Object context) {}
|
||||
public void checkListen(int port) {}
|
||||
public void checkAccept(String host, int port) {}
|
||||
public void checkMulticast(InetAddress addr) {}
|
||||
public void checkMulticast(InetAddress addr, byte ttl) {}
|
||||
public void checkPropertiesAccess() {}
|
||||
public void checkPropertyAccess(String key) {}
|
||||
public boolean checkTopLevelWindow(Object window) { return true; }
|
||||
public void checkPrintJobAccess() {}
|
||||
public void checkSystemClipboardAccess() {}
|
||||
public void checkAwtEventQueueAccess() {}
|
||||
public void checkPackageAccess(String pkg) {}
|
||||
public void checkPackageDefinition(String pkg) {}
|
||||
public void checkSetFactory() {}
|
||||
public void checkMemberAccess(Class clazz, int which) {}
|
||||
public void checkSecurityAccess(String target) {}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param cmd ...
|
||||
*/
|
||||
public void checkExec(String cmd) {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param lib ...
|
||||
*/
|
||||
public void checkLink(String lib) {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param fdesc ...
|
||||
*/
|
||||
public void checkRead(FileDescriptor fdesc) {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param file ...
|
||||
*/
|
||||
public void checkRead(String file) {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param file ...
|
||||
* @param context ...
|
||||
*/
|
||||
public void checkRead(String file, Object context) {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param fdesc ...
|
||||
*/
|
||||
public void checkWrite(FileDescriptor fdesc) {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param file ...
|
||||
*/
|
||||
public void checkWrite(String file) {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param file ...
|
||||
*/
|
||||
public void checkDelete(String file) {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param host ...
|
||||
* @param port ...
|
||||
*/
|
||||
public void checkConnect(String host, int port) {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param host ...
|
||||
* @param port ...
|
||||
* @param context ...
|
||||
*/
|
||||
public void checkConnect(String host, int port, Object context) {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param port ...
|
||||
*/
|
||||
public void checkListen(int port) {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param host ...
|
||||
* @param port ...
|
||||
*/
|
||||
public void checkAccept(String host, int port) {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param addr ...
|
||||
*/
|
||||
public void checkMulticast(InetAddress addr) {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param addr ...
|
||||
* @param ttl ...
|
||||
*/
|
||||
public void checkMulticast(InetAddress addr, byte ttl) {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void checkPropertiesAccess() {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param key ...
|
||||
*/
|
||||
public void checkPropertyAccess(String key) {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param window ...
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public boolean checkTopLevelWindow(Object window) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void checkPrintJobAccess() {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void checkSystemClipboardAccess() {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void checkAwtEventQueueAccess() {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param pkg ...
|
||||
*/
|
||||
public void checkPackageAccess(String pkg) {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param pkg ...
|
||||
*/
|
||||
public void checkPackageDefinition(String pkg) {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void checkSetFactory() {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param clazz ...
|
||||
* @param which ...
|
||||
*/
|
||||
public void checkMemberAccess(Class clazz, int which) {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param target ...
|
||||
*/
|
||||
public void checkSecurityAccess(String target) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method that returns the name of the application trying
|
||||
|
@ -83,12 +314,14 @@ public class HelmaSecurityManager extends SecurityManager {
|
|||
*/
|
||||
protected String getApplication() {
|
||||
Class[] classes = getClassContext();
|
||||
|
||||
for (int i = 0; i < classes.length; i++) {
|
||||
if (classes[i].getClassLoader() instanceof AppClassLoader)
|
||||
if (classes[i].getClassLoader() instanceof AppClassLoader) {
|
||||
return ((AppClassLoader) classes[i].getClassLoader()).getAppName();
|
||||
}
|
||||
}
|
||||
|
||||
// no application class loader found in stack - return null
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,4 +1,19 @@
|
|||
// HelmaShutdownHook.java
|
||||
/*
|
||||
* 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.main;
|
||||
|
||||
import helma.util.Logger;
|
||||
|
@ -8,23 +23,35 @@ import java.util.List;
|
|||
* ShutdownHook that shuts down all running Helma applications on exit.
|
||||
*/
|
||||
public class HelmaShutdownHook extends Thread {
|
||||
|
||||
ApplicationManager appmgr;
|
||||
|
||||
/**
|
||||
* Creates a new HelmaShutdownHook object.
|
||||
*
|
||||
* @param appmgr ...
|
||||
*/
|
||||
public HelmaShutdownHook(ApplicationManager appmgr) {
|
||||
this.appmgr = appmgr;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void run() {
|
||||
Logger logger = Server.getLogger();
|
||||
if (logger != null)
|
||||
|
||||
if (logger != null) {
|
||||
logger.log("Shutting down Helma");
|
||||
appmgr.stopAll ();
|
||||
List loggers = Logger.getLoggers();
|
||||
int l = loggers.size();
|
||||
for (int i=0; i<l; i++)
|
||||
((Logger) loggers.get(i)).close();
|
||||
Logger.wakeup();
|
||||
}
|
||||
|
||||
appmgr.stopAll();
|
||||
|
||||
List loggers = Logger.getLoggers();
|
||||
int l = loggers.size();
|
||||
|
||||
for (int i = 0; i < l; i++)
|
||||
((Logger) loggers.get(i)).close();
|
||||
|
||||
Logger.wakeup();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,42 +1,79 @@
|
|||
// HopSocketFactory.java
|
||||
// Copyright (c) Hannes Wallnöfer 1999-2000
|
||||
|
||||
/*
|
||||
* 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.main;
|
||||
|
||||
import helma.util.*;
|
||||
import java.io.IOException;
|
||||
import java.net.*;
|
||||
import java.rmi.server.*;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* An RMI socket factory that has a "paranoid" option to filter clients.
|
||||
* We only do direct connections, no HTTP proxy stuff, since this is
|
||||
* server-to-server.
|
||||
*/
|
||||
|
||||
public class HelmaSocketFactory extends RMISocketFactory {
|
||||
|
||||
private InetAddressFilter filter;
|
||||
|
||||
/**
|
||||
* Creates a new HelmaSocketFactory object.
|
||||
*/
|
||||
public HelmaSocketFactory() {
|
||||
filter = new InetAddressFilter();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param address ...
|
||||
*/
|
||||
public void addAddress(String address) {
|
||||
try {
|
||||
filter.addAddress(address);
|
||||
} catch (IOException x) {
|
||||
Server.getLogger().log ("Could not add "+address+" to Socket Filter: invalid address.");
|
||||
Server.getLogger().log("Could not add " + address +
|
||||
" to Socket Filter: invalid address.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param host ...
|
||||
* @param port ...
|
||||
*
|
||||
* @return ...
|
||||
*
|
||||
* @throws IOException ...
|
||||
*/
|
||||
public Socket createSocket(String host, int port) throws IOException {
|
||||
return new Socket(host, port);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param port ...
|
||||
*
|
||||
* @return ...
|
||||
*
|
||||
* @throws IOException ...
|
||||
*/
|
||||
public ServerSocket createServerSocket(int port) throws IOException {
|
||||
return new ParanoidServerSocket(port, filter);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,48 +1,63 @@
|
|||
// Server.java
|
||||
// Copyright (c) Hannes Wallnöfer 1998-2000
|
||||
/*
|
||||
* 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.main;
|
||||
|
||||
import java.io.*;
|
||||
import java.rmi.*;
|
||||
import java.rmi.server.*;
|
||||
import java.rmi.registry.*;
|
||||
import java.net.*;
|
||||
import java.util.*;
|
||||
import helma.extensions.HelmaExtension;
|
||||
import helma.objectmodel.db.DbSource;
|
||||
import helma.framework.*;
|
||||
import helma.framework.core.*;
|
||||
import helma.objectmodel.db.DbSource;
|
||||
import helma.util.*;
|
||||
import org.mortbay.http.*;
|
||||
import org.mortbay.util.*;
|
||||
import org.mortbay.http.ajp.*;
|
||||
import org.apache.xmlrpc.*;
|
||||
import org.mortbay.http.*;
|
||||
import org.mortbay.http.ajp.*;
|
||||
import org.mortbay.util.*;
|
||||
import java.io.*;
|
||||
import java.net.*;
|
||||
import java.rmi.*;
|
||||
import java.rmi.registry.*;
|
||||
import java.rmi.server.*;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Helma server main class.
|
||||
*/
|
||||
|
||||
public class Server implements IPathElement, Runnable {
|
||||
|
||||
public static final String version = "1.2.3 RC1 (2003/03/05)";
|
||||
public final long starttime;
|
||||
|
||||
// if true we only accept RMI and XML-RPC connections from
|
||||
// explicitly listed hosts.
|
||||
public boolean paranoid;
|
||||
|
||||
private ApplicationManager appManager;
|
||||
|
||||
private Vector extensions;
|
||||
|
||||
private Thread mainThread;
|
||||
public static final String version = "1.2.4 (2003/04/16)";
|
||||
|
||||
// server-wide properties
|
||||
static SystemProperties appsProps;
|
||||
static SystemProperties dbProps;
|
||||
static SystemProperties sysProps;
|
||||
|
||||
// static server instance
|
||||
private static Server server;
|
||||
protected static File hopHome = null;
|
||||
|
||||
// our logger
|
||||
private static Logger logger;
|
||||
public final long starttime;
|
||||
|
||||
// if true we only accept RMI and XML-RPC connections from
|
||||
// explicitly listed hosts.
|
||||
public boolean paranoid;
|
||||
private ApplicationManager appManager;
|
||||
private Vector extensions;
|
||||
private Thread mainThread;
|
||||
|
||||
// server ports
|
||||
int rmiPort = 0;
|
||||
int xmlrpcPort = 0;
|
||||
|
@ -52,14 +67,6 @@ import org.apache.xmlrpc.*;
|
|||
// map of server-wide database sources
|
||||
Hashtable dbSources;
|
||||
|
||||
// static server instance
|
||||
private static Server server;
|
||||
|
||||
protected static File hopHome = null;
|
||||
|
||||
// our logger
|
||||
private static Logger logger;
|
||||
|
||||
// the embedded web server
|
||||
// protected Serve websrv;
|
||||
protected HttpServer http;
|
||||
|
@ -70,37 +77,12 @@ import org.apache.xmlrpc.*;
|
|||
// the XML-RPC server
|
||||
protected WebServer xmlrpc;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* static main entry point.
|
||||
*/
|
||||
public static void main (String args[]) throws IOException {
|
||||
|
||||
// check if we are running on a Java 2 VM - otherwise exit with an error message
|
||||
String javaVersion = System.getProperty ("java.version");
|
||||
if (javaVersion == null || javaVersion.startsWith ("1.1") || javaVersion.startsWith ("1.0")) {
|
||||
System.err.println ("This version of Helma requires Java 1.2 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.");
|
||||
else
|
||||
System.err.println ("Your Java Runtime is version "+javaVersion+". Please update to a more recent version.");
|
||||
System.exit (1);
|
||||
}
|
||||
|
||||
// create new server instance
|
||||
server = new Server (args);
|
||||
|
||||
// start the server main thread
|
||||
server.start ();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new Server instance with an array of command line options.
|
||||
*/
|
||||
public Server(String[] args) {
|
||||
|
||||
starttime = System.currentTimeMillis();
|
||||
|
||||
String homeDir = null;
|
||||
|
||||
boolean usageError = false;
|
||||
|
@ -112,35 +94,35 @@ import org.apache.xmlrpc.*;
|
|||
|
||||
// parse arguments
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
if (args[i].equals ("-h") && i+1<args.length)
|
||||
if (args[i].equals("-h") && ((i + 1) < args.length)) {
|
||||
homeDir = args[++i];
|
||||
else if (args[i].equals ("-f") && i+1<args.length)
|
||||
} else if (args[i].equals("-f") && ((i + 1) < args.length)) {
|
||||
propfile = args[++i];
|
||||
else if (args[i].equals ("-p") && i+1<args.length) {
|
||||
} else if (args[i].equals("-p") && ((i + 1) < args.length)) {
|
||||
try {
|
||||
rmiPort = Integer.parseInt(args[++i]);
|
||||
} catch (Exception portx) {
|
||||
usageError = true;
|
||||
}
|
||||
} else if (args[i].equals ("-x") && i+1<args.length) {
|
||||
} else if (args[i].equals("-x") && ((i + 1) < args.length)) {
|
||||
try {
|
||||
xmlrpcPort = Integer.parseInt(args[++i]);
|
||||
} catch (Exception portx) {
|
||||
usageError = true;
|
||||
}
|
||||
} else if (args[i].equals ("-w") && i+1<args.length) {
|
||||
} else if (args[i].equals("-w") && ((i + 1) < args.length)) {
|
||||
try {
|
||||
websrvPort = Integer.parseInt(args[++i]);
|
||||
} catch (Exception portx) {
|
||||
usageError = true;
|
||||
}
|
||||
} else if (args[i].equals ("-jk") && i+1<args.length) {
|
||||
} else if (args[i].equals("-jk") && ((i + 1) < args.length)) {
|
||||
try {
|
||||
ajp13Port = Integer.parseInt(args[++i]);
|
||||
} catch (Exception portx) {
|
||||
usageError = true;
|
||||
}
|
||||
} else if (args[i].equals ("-i") && i+1<args.length) {
|
||||
} else if (args[i].equals("-i") && ((i + 1) < args.length)) {
|
||||
// eat away the -i parameter which is meant for helma.main.launcher.Main
|
||||
i++;
|
||||
} else {
|
||||
|
@ -152,38 +134,51 @@ import org.apache.xmlrpc.*;
|
|||
// get main property file from home dir or vice versa, depending on what we have.
|
||||
// get property file from hopHome
|
||||
if (propfile == null) {
|
||||
if (homeDir != null)
|
||||
if (homeDir != null) {
|
||||
propfile = new File(homeDir, "server.properties").getAbsolutePath();
|
||||
else
|
||||
} else {
|
||||
propfile = new File("server.properties").getAbsolutePath();
|
||||
}
|
||||
}
|
||||
|
||||
// create system properties
|
||||
sysProps = new SystemProperties(propfile);
|
||||
|
||||
// check if there's a property setting for those ports not specified via command line
|
||||
if (websrvPort == 0 && sysProps.getProperty ("webPort") != null) try {
|
||||
if ((websrvPort == 0) && (sysProps.getProperty("webPort") != null)) {
|
||||
try {
|
||||
websrvPort = Integer.parseInt(sysProps.getProperty("webPort"));
|
||||
} catch (NumberFormatException fmt) {
|
||||
System.err.println("Error parsing web server port property: " + fmt);
|
||||
}
|
||||
if (ajp13Port == 0 && sysProps.getProperty ("ajp13Port") != null) try {
|
||||
}
|
||||
|
||||
if ((ajp13Port == 0) && (sysProps.getProperty("ajp13Port") != null)) {
|
||||
try {
|
||||
ajp13Port = Integer.parseInt(sysProps.getProperty("ajp13Port"));
|
||||
} catch (NumberFormatException fmt) {
|
||||
System.err.println("Error parsing AJP1.3 server port property: " + fmt);
|
||||
}
|
||||
if (rmiPort == 0 && sysProps.getProperty ("rmiPort") != null) try {
|
||||
}
|
||||
|
||||
if ((rmiPort == 0) && (sysProps.getProperty("rmiPort") != null)) {
|
||||
try {
|
||||
rmiPort = Integer.parseInt(sysProps.getProperty("rmiPort"));
|
||||
} catch (NumberFormatException fmt) {
|
||||
System.err.println("Error parsing RMI server port property: " + fmt);
|
||||
}
|
||||
if (xmlrpcPort == 0 && sysProps.getProperty ("xmlrpcPort") != null) try {
|
||||
}
|
||||
|
||||
if ((xmlrpcPort == 0) && (sysProps.getProperty("xmlrpcPort") != null)) {
|
||||
try {
|
||||
xmlrpcPort = Integer.parseInt(sysProps.getProperty("xmlrpcPort"));
|
||||
} catch (NumberFormatException fmt) {
|
||||
System.err.println("Error parsing XML-RPC server port property: " + fmt);
|
||||
}
|
||||
}
|
||||
|
||||
// check server ports. If no port is set, issue a warning and exit.
|
||||
if (!usageError && (websrvPort | ajp13Port | rmiPort | xmlrpcPort) == 0) {
|
||||
if (!usageError && ((websrvPort | ajp13Port | rmiPort | xmlrpcPort) == 0)) {
|
||||
System.out.println(" Error: No server port specified.");
|
||||
usageError = true;
|
||||
}
|
||||
|
@ -203,27 +198,38 @@ import org.apache.xmlrpc.*;
|
|||
|
||||
// check if any of the specified server ports is in use already
|
||||
try {
|
||||
if (websrvPort > 0)
|
||||
if (websrvPort > 0) {
|
||||
checkRunning(websrvPort);
|
||||
if (rmiPort > 0)
|
||||
}
|
||||
|
||||
if (rmiPort > 0) {
|
||||
checkRunning(rmiPort);
|
||||
if (xmlrpcPort > 0)
|
||||
}
|
||||
|
||||
if (xmlrpcPort > 0) {
|
||||
checkRunning(xmlrpcPort);
|
||||
if (ajp13Port > 0)
|
||||
}
|
||||
|
||||
if (ajp13Port > 0) {
|
||||
checkRunning(ajp13Port);
|
||||
}
|
||||
} catch (Exception running) {
|
||||
System.out.println(running.getMessage());
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
// get hopHome from property file
|
||||
if (homeDir == null)
|
||||
if (homeDir == null) {
|
||||
homeDir = sysProps.getProperty("hophome");
|
||||
if (homeDir == null)
|
||||
}
|
||||
|
||||
if (homeDir == null) {
|
||||
homeDir = new File(propfile).getParent();
|
||||
}
|
||||
|
||||
// create hopHome File object
|
||||
hopHome = new File(homeDir);
|
||||
|
||||
// try to transform hopHome directory to its cononical representation
|
||||
try {
|
||||
hopHome = hopHome.getCanonicalFile();
|
||||
|
@ -239,28 +245,32 @@ import org.apache.xmlrpc.*;
|
|||
System.setProperty("user.dir", hopHome.getPath());
|
||||
|
||||
// from now on it's safe to call getLogger() because hopHome is set up
|
||||
String startMessage = "Starting Helma " + version + " on Java " +
|
||||
System.getProperty("java.version");
|
||||
|
||||
String startMessage = "Starting Helma "+version+
|
||||
" on Java "+System.getProperty ("java.version");
|
||||
getLogger().log(startMessage);
|
||||
|
||||
// also print a msg to System.out
|
||||
System.out.println(startMessage);
|
||||
|
||||
getLogger().log("propfile = " + propfile);
|
||||
getLogger().log("hopHome = " + hopHome);
|
||||
|
||||
|
||||
File helper = new File(hopHome, "db.properties");
|
||||
|
||||
dbPropfile = helper.getAbsolutePath();
|
||||
dbProps = new SystemProperties(dbPropfile);
|
||||
DbSource.setDefaultProps(dbProps);
|
||||
getLogger().log("dbPropfile = " + dbPropfile);
|
||||
|
||||
appsPropfile = sysProps.getProperty("appsPropFile");
|
||||
if (appsPropfile != null && !"".equals (appsPropfile.trim()))
|
||||
|
||||
if ((appsPropfile != null) && !"".equals(appsPropfile.trim())) {
|
||||
helper = new File(appsPropfile);
|
||||
else
|
||||
} else {
|
||||
helper = new File(hopHome, "apps.properties");
|
||||
}
|
||||
|
||||
appsPropfile = helper.getAbsolutePath();
|
||||
appsProps = new SystemProperties(appsPropfile);
|
||||
getLogger().log("appsPropfile = " + appsPropfile);
|
||||
|
@ -271,34 +281,71 @@ import org.apache.xmlrpc.*;
|
|||
String country = sysProps.getProperty("country");
|
||||
String timezone = sysProps.getProperty("timezone");
|
||||
|
||||
if (language != null && country != null)
|
||||
if ((language != null) && (country != null)) {
|
||||
Locale.setDefault(new Locale(language, country));
|
||||
if (timezone != null)
|
||||
}
|
||||
|
||||
if (timezone != null) {
|
||||
TimeZone.setDefault(TimeZone.getTimeZone(timezone));
|
||||
}
|
||||
|
||||
getLogger().log("Locale = " + Locale.getDefault());
|
||||
getLogger().log ("TimeZone = "+TimeZone.getDefault().getDisplayName (Locale.getDefault ()));
|
||||
getLogger().log("TimeZone = " +
|
||||
TimeZone.getDefault().getDisplayName(Locale.getDefault()));
|
||||
|
||||
dbSources = new Hashtable();
|
||||
|
||||
// try to load the extensions
|
||||
extensions = new Vector();
|
||||
|
||||
if (sysProps.getProperty("extensions") != null) {
|
||||
StringTokenizer tok=new StringTokenizer (sysProps.getProperty ("extensions"),",");
|
||||
StringTokenizer tok = new StringTokenizer(sysProps.getProperty("extensions"),
|
||||
",");
|
||||
|
||||
while (tok.hasMoreTokens()) {
|
||||
String extClassName = tok.nextToken().trim();
|
||||
|
||||
try {
|
||||
Class extClass = Class.forName(extClassName);
|
||||
HelmaExtension ext = (HelmaExtension) extClass.newInstance();
|
||||
|
||||
ext.init(this);
|
||||
extensions.add(ext);
|
||||
getLogger().log("loaded: " + extClassName);
|
||||
} catch (Exception e) {
|
||||
getLogger ().log ("error: " + extClassName + " (" + e.toString () + ")");
|
||||
getLogger().log("error: " + extClassName + " (" + e.toString() +
|
||||
")");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* static main entry point.
|
||||
*/
|
||||
public static void main(String[] args) throws IOException {
|
||||
// check if we are running on a Java 2 VM - otherwise exit with an error message
|
||||
String javaVersion = System.getProperty("java.version");
|
||||
|
||||
if ((javaVersion == null) || javaVersion.startsWith("1.1") ||
|
||||
javaVersion.startsWith("1.0")) {
|
||||
System.err.println("This version of Helma requires Java 1.2 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.");
|
||||
} else {
|
||||
System.err.println("Your Java Runtime is version " + javaVersion +
|
||||
". Please update to a more recent version.");
|
||||
}
|
||||
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
// create new server instance
|
||||
server = new Server(args);
|
||||
|
||||
// start the server main thread
|
||||
server.start();
|
||||
}
|
||||
|
||||
protected void start() {
|
||||
|
@ -318,25 +365,37 @@ import org.apache.xmlrpc.*;
|
|||
* apps or starting new ones.
|
||||
*/
|
||||
public void run() {
|
||||
|
||||
try {
|
||||
|
||||
if (websrvPort > 0 || ajp13Port > 0) {
|
||||
if ((websrvPort > 0) || (ajp13Port > 0)) {
|
||||
http = new HttpServer();
|
||||
|
||||
// disable Jetty logging FIXME: seems to be a jetty bug; as soon
|
||||
// as the logging is disabled, the more is logged
|
||||
Log.instance().disableLog();
|
||||
Log.instance().add (new LogSink ()
|
||||
{
|
||||
public String getOptions () { return null; }
|
||||
public void log (String formattedLog) {}
|
||||
public void log (String tag, Object msg, Frame frame, long time) {}
|
||||
public void setOptions (String options) {}
|
||||
public boolean isStarted () { return true; }
|
||||
public void start () {}
|
||||
public void stop () {}
|
||||
Log.instance().add(new LogSink() {
|
||||
public String getOptions() {
|
||||
return null;
|
||||
}
|
||||
);
|
||||
|
||||
public void log(String formattedLog) {
|
||||
}
|
||||
|
||||
public void log(String tag, Object msg, Frame frame, long time) {
|
||||
}
|
||||
|
||||
public void setOptions(String options) {
|
||||
}
|
||||
|
||||
public boolean isStarted() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void start() {
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// start embedded web server if port is specified
|
||||
|
@ -349,66 +408,84 @@ import org.apache.xmlrpc.*;
|
|||
// create AJP13Listener
|
||||
ajp13 = new AJP13Listener(new InetAddrPort(ajp13Port));
|
||||
ajp13.setHttpServer(http);
|
||||
|
||||
String jkallow = sysProps.getProperty("allowAJP13");
|
||||
|
||||
// by default the AJP13-connection just accepts requests from 127.0.0.1
|
||||
if (jkallow == null)
|
||||
if (jkallow == null) {
|
||||
jkallow = "127.0.0.1";
|
||||
}
|
||||
|
||||
StringTokenizer st = new StringTokenizer(jkallow, " ,;");
|
||||
String[] jkallowarr = new String[st.countTokens()];
|
||||
int cnt = 0;
|
||||
|
||||
while (st.hasMoreTokens()) {
|
||||
jkallowarr[cnt] = st.nextToken();
|
||||
cnt++;
|
||||
}
|
||||
|
||||
ajp13.setRemoteServers(jkallowarr);
|
||||
getLogger().log("Starting AJP13-Listener on port " + (ajp13Port));
|
||||
}
|
||||
|
||||
if (xmlrpcPort > 0) {
|
||||
String xmlparser = sysProps.getProperty("xmlparser");
|
||||
if (xmlparser != null)
|
||||
|
||||
if (xmlparser != null) {
|
||||
XmlRpc.setDriver(xmlparser);
|
||||
}
|
||||
|
||||
xmlrpc = new WebServer(xmlrpcPort);
|
||||
|
||||
if (paranoid) {
|
||||
xmlrpc.setParanoid(true);
|
||||
|
||||
String xallow = sysProps.getProperty("allowXmlRpc");
|
||||
|
||||
if (xallow != null) {
|
||||
StringTokenizer st = new StringTokenizer(xallow, " ,;");
|
||||
|
||||
while (st.hasMoreTokens())
|
||||
xmlrpc.acceptClient(st.nextToken());
|
||||
}
|
||||
}
|
||||
|
||||
getLogger().log("Starting XML-RPC server on port " + (xmlrpcPort));
|
||||
}
|
||||
|
||||
|
||||
if (rmiPort > 0) {
|
||||
if (paranoid) {
|
||||
HelmaSocketFactory factory = new HelmaSocketFactory();
|
||||
String rallow = sysProps.getProperty("allowWeb");
|
||||
|
||||
if (rallow != null) {
|
||||
StringTokenizer st = new StringTokenizer(rallow, " ,;");
|
||||
|
||||
while (st.hasMoreTokens())
|
||||
factory.addAddress(st.nextToken());
|
||||
}
|
||||
|
||||
RMISocketFactory.setSocketFactory(factory);
|
||||
}
|
||||
|
||||
getLogger().log("Starting RMI server on port " + rmiPort);
|
||||
LocateRegistry.createRegistry(rmiPort);
|
||||
}
|
||||
|
||||
// create application manager
|
||||
appManager = new ApplicationManager(rmiPort, hopHome, appsProps, this);
|
||||
if (xmlrpc != null)
|
||||
|
||||
if (xmlrpc != null) {
|
||||
xmlrpc.addHandler("$default", appManager);
|
||||
}
|
||||
|
||||
// add shutdown hook to close running apps and servers on exit
|
||||
Runtime.getRuntime().addShutdownHook(new HelmaShutdownHook(appManager));
|
||||
|
||||
} catch (Exception gx) {
|
||||
getLogger().log("Error initializing embedded database: " + gx);
|
||||
gx.printStackTrace();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -416,8 +493,11 @@ import org.apache.xmlrpc.*;
|
|||
// the default implementation is helma.main.HelmaSecurityManager.
|
||||
try {
|
||||
String secManClass = sysProps.getProperty("securityManager");
|
||||
|
||||
if (secManClass != null) {
|
||||
SecurityManager secMan = (SecurityManager) Class.forName(secManClass).newInstance ();
|
||||
SecurityManager secMan = (SecurityManager) Class.forName(secManClass)
|
||||
.newInstance();
|
||||
|
||||
System.setSecurityManager(secMan);
|
||||
getLogger().log("Setting security manager to " + secManClass);
|
||||
}
|
||||
|
@ -429,23 +509,30 @@ import org.apache.xmlrpc.*;
|
|||
appManager.startAll();
|
||||
|
||||
// start embedded web server
|
||||
if (http != null) try {
|
||||
if (http != null) {
|
||||
try {
|
||||
http.start();
|
||||
} catch (MultiException m) {
|
||||
getLogger().log("Error starting embedded web server: " + m);
|
||||
}
|
||||
}
|
||||
|
||||
if (ajp13 != null) try {
|
||||
if (ajp13 != null) {
|
||||
try {
|
||||
ajp13.start();
|
||||
} catch (Exception m) {
|
||||
getLogger().log("Error starting AJP13 listener: " + m);
|
||||
}
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
|
||||
while (Thread.currentThread() == mainThread) {
|
||||
try {
|
||||
mainThread.sleep (3000l);
|
||||
} catch (InterruptedException ie) {}
|
||||
mainThread.sleep(3000L);
|
||||
} catch (InterruptedException ie) {
|
||||
}
|
||||
|
||||
try {
|
||||
appManager.checkForChanges();
|
||||
} catch (Exception x) {
|
||||
|
@ -474,16 +561,21 @@ import org.apache.xmlrpc.*;
|
|||
public static Logger getLogger() {
|
||||
if (logger == null) {
|
||||
String logDir = sysProps.getProperty("logdir", "log");
|
||||
|
||||
if ("console".equalsIgnoreCase(logDir)) {
|
||||
logger = new Logger(System.out);
|
||||
} else {
|
||||
File helper = new File(logDir);
|
||||
if (hopHome != null && !helper.isAbsolute ())
|
||||
|
||||
if ((hopHome != null) && !helper.isAbsolute()) {
|
||||
helper = new File(hopHome, logDir);
|
||||
}
|
||||
|
||||
logDir = helper.getAbsolutePath();
|
||||
logger = Logger.getLogger(logDir, "hop");
|
||||
}
|
||||
}
|
||||
|
||||
return logger;
|
||||
}
|
||||
|
||||
|
@ -517,39 +609,79 @@ import org.apache.xmlrpc.*;
|
|||
} catch (Exception x) {
|
||||
return;
|
||||
}
|
||||
|
||||
// if we got so far, another server is already running on this port and db
|
||||
throw new Exception("Error: Server already running on this port: " + portNumber);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param key ...
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getProperty(String key) {
|
||||
return (String) sysProps.get(key);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public SystemProperties getProperties() {
|
||||
return sysProps;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public SystemProperties getDbProperties() {
|
||||
return dbProps;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public File getAppsHome() {
|
||||
String appHome = sysProps.getProperty("appHome");
|
||||
if (appHome != null && !"".equals (appHome.trim()))
|
||||
|
||||
if ((appHome != null) && !"".equals(appHome.trim())) {
|
||||
return new File(appHome);
|
||||
else
|
||||
} else {
|
||||
return new File(hopHome, "apps");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public Vector getExtensions() {
|
||||
return extensions;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param name ...
|
||||
*/
|
||||
public void startApplication(String name) {
|
||||
appManager.start(name);
|
||||
appManager.register(name);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param name ...
|
||||
*/
|
||||
public void stopApplication(String name) {
|
||||
appManager.stop(name);
|
||||
}
|
||||
|
@ -582,6 +714,4 @@ import org.apache.xmlrpc.*;
|
|||
public String getPrototype() {
|
||||
return "root";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -1,20 +1,33 @@
|
|||
// FilteredClassLoader.java
|
||||
/*
|
||||
* 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.main.launcher;
|
||||
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.Hashtable;
|
||||
import java.security.CodeSource;
|
||||
import java.security.PermissionCollection;
|
||||
import java.security.Permissions;
|
||||
import java.security.Policy;
|
||||
import java.security.CodeSource;
|
||||
import java.util.Hashtable;
|
||||
|
||||
/**
|
||||
* ClassLoader that is able to exclude certain packages from loading.
|
||||
*/
|
||||
public class FilteredClassLoader extends URLClassLoader {
|
||||
|
||||
/**
|
||||
* Create a server wide class loader that doesn't see the scripting engine(s)
|
||||
* embedded in helma.jar. These files should be loaded by the per-application
|
||||
|
@ -29,8 +42,10 @@ public class FilteredClassLoader extends URLClassLoader {
|
|||
* Mask classes that implement the scripting engine(s) contained in helma.jar
|
||||
*/
|
||||
protected Class findClass(String name) throws ClassNotFoundException {
|
||||
if (name != null && "helma.scripting.fesi.PhantomEngine".equals (name))
|
||||
if ((name != null) && "helma.scripting.fesi.PhantomEngine".equals(name)) {
|
||||
throw new ClassNotFoundException(name);
|
||||
}
|
||||
|
||||
return super.findClass(name);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,65 +1,84 @@
|
|||
// helma.main.Main
|
||||
/*
|
||||
* 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.main.launcher;
|
||||
|
||||
import java.net.URLClassLoader;
|
||||
import java.net.URL;
|
||||
import java.net.URLDecoder;
|
||||
import java.io.File;
|
||||
import java.io.FilenameFilter;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.net.URLDecoder;
|
||||
import java.security.Policy;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Helma bootstrap class. Figures out Helma home directory, sets up class path and
|
||||
* lauchnes main class.
|
||||
*/
|
||||
public class Main {
|
||||
|
||||
public static final String[] jars = {
|
||||
"helma.jar",
|
||||
"jetty.jar",
|
||||
"crimson.jar",
|
||||
"xmlrpc.jar",
|
||||
"servlet.jar",
|
||||
"regexp.jar",
|
||||
"mail.jar",
|
||||
"activation.jar",
|
||||
"netcomponents.jar",
|
||||
"jimi.jar",
|
||||
"apache-dom.jar",
|
||||
"jdom.jar"
|
||||
"helma.jar", "jetty.jar", "crimson.jar",
|
||||
"xmlrpc.jar", "servlet.jar", "regexp.jar",
|
||||
"mail.jar", "activation.jar",
|
||||
"netcomponents.jar", "jimi.jar",
|
||||
"apache-dom.jar", "jdom.jar"
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param args ...
|
||||
*
|
||||
* @throws Exception ...
|
||||
*/
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
// check if home directory is set via command line arg. If not,
|
||||
// we'll get it from the location of the jar file this class
|
||||
// has been loaded from.
|
||||
String installDir = null;
|
||||
|
||||
// first, try to get helma home dir from command line options
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
if (args[i].equals ("-i") && i+1<args.length) {
|
||||
if (args[i].equals("-i") && ((i + 1) < args.length)) {
|
||||
installDir = args[i + 1];
|
||||
}
|
||||
}
|
||||
|
||||
URLClassLoader apploader = (URLClassLoader) ClassLoader.getSystemClassLoader();
|
||||
|
||||
// try to get Helma installation directory
|
||||
if (installDir == null) {
|
||||
try {
|
||||
URL launcherUrl = apploader.findResource("helma/main/launcher/Main.class");
|
||||
|
||||
// this is a JAR URL of the form
|
||||
// jar:<url>!/{entry}
|
||||
// we strip away the jar: prefix and the !/{entry} suffix
|
||||
// to get the original jar file URL
|
||||
installDir = launcherUrl.toString().substring(4);
|
||||
|
||||
int excl = installDir.indexOf("!");
|
||||
|
||||
if (excl > -1) {
|
||||
installDir = installDir.substring(0, excl);
|
||||
launcherUrl = new URL(installDir);
|
||||
|
||||
File f = new File(launcherUrl.getPath());
|
||||
|
||||
installDir = f.getParentFile().getCanonicalPath();
|
||||
}
|
||||
} catch (Exception x) {
|
||||
|
@ -75,40 +94,52 @@ public class Main {
|
|||
// set up the class path
|
||||
File libdir = new File(installDir, "lib");
|
||||
ArrayList jarlist = new ArrayList();
|
||||
|
||||
for (int i = 0; i < jars.length; i++) {
|
||||
File jar = new File(libdir, jars[i]);
|
||||
|
||||
jarlist.add(new URL("file:" + jar.getAbsolutePath()));
|
||||
}
|
||||
|
||||
// add all jar files from the lib/ext directory
|
||||
File extdir = new File(libdir, "ext");
|
||||
File[] files = extdir.listFiles(new FilenameFilter() {
|
||||
public boolean accept(File dir, String name) {
|
||||
String n = name.toLowerCase();
|
||||
|
||||
return n.endsWith(".jar") || n.endsWith(".zip");
|
||||
}
|
||||
});
|
||||
if (files != null)
|
||||
|
||||
if (files != null) {
|
||||
for (int i = 0; i < files.length; i++) {
|
||||
// WORKAROUND: add the files in lib/ext before
|
||||
// lib/apache-dom.jar, since otherwise putting a full version
|
||||
// of Xerces in lib/ext would cause a version conflict with the
|
||||
// xerces classes in lib/apache-dom.jar. Generally, having some pieces
|
||||
// of Xerces in lib/apache-dom.jar is kind of problematic.
|
||||
jarlist.add (jars.length-3, new URL ("file:" + files[i].getAbsolutePath()));
|
||||
jarlist.add(jars.length - 3, new URL("file:" +
|
||||
files[i].getAbsolutePath()));
|
||||
System.err.println("Adding to classpath: " + files[i].getAbsolutePath());
|
||||
}
|
||||
}
|
||||
|
||||
URL[] urls = new URL[jarlist.size()];
|
||||
|
||||
jarlist.toArray(urls);
|
||||
|
||||
FilteredClassLoader loader = new FilteredClassLoader(urls);
|
||||
|
||||
// set the new class loader as context class loader
|
||||
Thread.currentThread().setContextClassLoader(loader);
|
||||
|
||||
// get the main server class
|
||||
Class clazz = loader.loadClass("helma.main.Server");
|
||||
Class[] cargs = new Class[] { args.getClass() };
|
||||
Method main = clazz.getMethod("main", cargs);
|
||||
Object[] nargs = new Object[] { args };
|
||||
|
||||
// run
|
||||
main.invoke(null, nargs);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,18 @@
|
|||
// ConcurrencyException.java
|
||||
// Copyright (c) Hannes Wallnöfer 1998-2000
|
||||
/*
|
||||
* 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.objectmodel;
|
||||
|
||||
|
@ -8,44 +21,13 @@ package helma.objectmodel;
|
|||
* Thrown when more than one thrad tries to modify a Node. The evaluator
|
||||
* will normally catch this and try again after a period of time.
|
||||
*/
|
||||
|
||||
public class ConcurrencyException extends RuntimeException {
|
||||
|
||||
/**
|
||||
* Creates a new ConcurrencyException object.
|
||||
*
|
||||
* @param msg ...
|
||||
*/
|
||||
public ConcurrencyException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,4 +1,18 @@
|
|||
// DatabaseException.java
|
||||
/*
|
||||
* 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.objectmodel;
|
||||
|
||||
|
@ -6,44 +20,13 @@ package helma.objectmodel;
|
|||
/**
|
||||
* Thrown on any kind of Database-Error
|
||||
*/
|
||||
|
||||
public class DatabaseException extends RuntimeException {
|
||||
|
||||
/**
|
||||
* Creates a new DatabaseException object.
|
||||
*
|
||||
* @param msg ...
|
||||
*/
|
||||
public DatabaseException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,35 +1,108 @@
|
|||
// IDatabase.java
|
||||
/*
|
||||
* 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.objectmodel;
|
||||
|
||||
import helma.objectmodel.db.IDGenerator;
|
||||
import helma.objectmodel.INode;
|
||||
import helma.objectmodel.db.IDGenerator;
|
||||
import java.io.IOException;
|
||||
import org.xml.sax.SAXException;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
|
||||
/**
|
||||
* Interface that is implemented by Database wrappers
|
||||
*/
|
||||
|
||||
public interface IDatabase {
|
||||
|
||||
// db-related
|
||||
public void shutdown();
|
||||
|
||||
// id-related
|
||||
public String nextID() throws ObjectNotFoundException;
|
||||
public IDGenerator getIDGenerator (ITransaction transaction) throws Exception;
|
||||
public void saveIDGenerator (ITransaction transaction, IDGenerator idgen) throws Exception;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param transaction ...
|
||||
*
|
||||
* @return ...
|
||||
*
|
||||
* @throws IOException ...
|
||||
*/
|
||||
public IDGenerator getIDGenerator(ITransaction transaction)
|
||||
throws IOException, ObjectNotFoundException;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param transaction ...
|
||||
* @param idgen ...
|
||||
*
|
||||
* @throws IOException ...
|
||||
*/
|
||||
public void saveIDGenerator(ITransaction transaction, IDGenerator idgen)
|
||||
throws IOException;
|
||||
|
||||
// node-related
|
||||
public INode getNode (ITransaction transaction, String key) throws Exception;
|
||||
public void saveNode (ITransaction transaction, String key, INode node) throws Exception;
|
||||
public void deleteNode (ITransaction transaction, String key) throws Exception;
|
||||
public INode getNode(ITransaction transaction, String key)
|
||||
throws IOException, ObjectNotFoundException,
|
||||
SAXException, ParserConfigurationException;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param transaction ...
|
||||
* @param key ...
|
||||
* @param node ...
|
||||
*
|
||||
* @throws IOException ...
|
||||
*/
|
||||
public void saveNode(ITransaction transaction, String key, INode node)
|
||||
throws IOException;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param transaction ...
|
||||
* @param key ...
|
||||
*
|
||||
* @throws IOException ...
|
||||
*/
|
||||
public void deleteNode(ITransaction transaction, String key)
|
||||
throws IOException;
|
||||
|
||||
// transaction-related
|
||||
public ITransaction beginTransaction();
|
||||
public void commitTransaction (ITransaction transaction) throws DatabaseException;
|
||||
public void abortTransaction (ITransaction transaction) throws DatabaseException;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param transaction ...
|
||||
*
|
||||
* @throws DatabaseException ...
|
||||
*/
|
||||
public void commitTransaction(ITransaction transaction)
|
||||
throws DatabaseException;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param transaction ...
|
||||
*
|
||||
* @throws DatabaseException ...
|
||||
*/
|
||||
public void abortTransaction(ITransaction transaction)
|
||||
throws DatabaseException;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,88 +1,391 @@
|
|||
// INode.java
|
||||
// Copyright (c) Hannes Wallnöfer 1998-2000
|
||||
/*
|
||||
* 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.objectmodel;
|
||||
|
||||
import java.util.*;
|
||||
import java.io.*;
|
||||
import helma.framework.IPathElement;
|
||||
import helma.objectmodel.db.DbMapping;
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Interface that all Nodes implement. Currently, there are two implementations:
|
||||
* Transient nodes which only exist in memory, and persistent Nodes, which are
|
||||
* stored in a database (either the internal Object DB or an external relational DB).
|
||||
*/
|
||||
|
||||
public interface INode extends INodeState, IPathElement {
|
||||
|
||||
|
||||
/**
|
||||
* id-related methods
|
||||
*/
|
||||
|
||||
public String getID();
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getName();
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param dbmap ...
|
||||
*/
|
||||
public void setDbMapping(DbMapping dbmap);
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public DbMapping getDbMapping();
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public int getState();
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param s ...
|
||||
*/
|
||||
public void setState(int s);
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param name ...
|
||||
*/
|
||||
public void setName(String name);
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public long lastModified();
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public long created();
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public boolean isAnonymous(); // is this a named node, or an anonymous node in a collection?
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getPrototype();
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param prototype ...
|
||||
*/
|
||||
public void setPrototype(String prototype);
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public INode getCacheNode();
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void clearCacheNode();
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getFullName();
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param root ...
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getFullName(INode root);
|
||||
|
||||
/**
|
||||
* node-related methods
|
||||
*/
|
||||
|
||||
public INode getParent();
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param rel ...
|
||||
*/
|
||||
public void setSubnodeRelation(String rel);
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getSubnodeRelation();
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public int numberOfNodes();
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param node ...
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public INode addNode(INode node);
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param node ...
|
||||
* @param where ...
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public INode addNode(INode node, int where);
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param name ...
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public INode createNode(String name);
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param name ...
|
||||
* @param where ...
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public INode createNode(String name, int where);
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public Enumeration getSubnodes();
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param name ...
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public INode getSubnode(String name);
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param index ...
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public INode getSubnodeAt(int index);
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param node ...
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public int contains(INode node);
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public boolean remove();
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param node ...
|
||||
*/
|
||||
public void removeNode(INode node);
|
||||
|
||||
/**
|
||||
* property-related methods
|
||||
*/
|
||||
|
||||
public Enumeration properties();
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param name ...
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public IProperty get(String name);
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param name ...
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getString(String name);
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param name ...
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public boolean getBoolean(String name);
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param name ...
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public Date getDate(String name);
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param name ...
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public long getInteger(String name);
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param name ...
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public double getFloat(String name);
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param name ...
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public INode getNode(String name);
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param name ...
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public Object getJavaObject(String name);
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param name ...
|
||||
* @param value ...
|
||||
*/
|
||||
public void setString(String name, String value);
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param name ...
|
||||
* @param value ...
|
||||
*/
|
||||
public void setBoolean(String name, boolean value);
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param name ...
|
||||
* @param value ...
|
||||
*/
|
||||
public void setDate(String name, Date value);
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param name ...
|
||||
* @param value ...
|
||||
*/
|
||||
public void setInteger(String name, long value);
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param name ...
|
||||
* @param value ...
|
||||
*/
|
||||
public void setFloat(String name, double value);
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param name ...
|
||||
* @param value ...
|
||||
*/
|
||||
public void setNode(String name, INode value);
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param name ...
|
||||
* @param value ...
|
||||
*/
|
||||
public void setJavaObject(String name, Object value);
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param name ...
|
||||
*/
|
||||
public void unset(String name);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,17 +1,28 @@
|
|||
// INodeState.java
|
||||
// Copyright (c) Hannes Wallnöfer 2001
|
||||
/*
|
||||
* 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.objectmodel;
|
||||
|
||||
import java.util.*;
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Interface that defines states of nodes
|
||||
*/
|
||||
|
||||
public interface INodeState {
|
||||
|
||||
public final static int TRANSIENT = -3;
|
||||
public final static int VIRTUAL = -2;
|
||||
public final static int INVALID = -1;
|
||||
|
@ -19,9 +30,4 @@ public interface INodeState {
|
|||
public final static int NEW = 1;
|
||||
public final static int MODIFIED = 2;
|
||||
public final static int DELETED = 3;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue