Merge from helma_1_2_4
This commit is contained in:
parent
df40e73b63
commit
66663c8b20
177 changed files with 28899 additions and 18112 deletions
|
@ -1,98 +1,197 @@
|
|||
/*
|
||||
* 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 {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class DocApplication extends DocDirElement {
|
||||
HashSet excluded;
|
||||
|
||||
public static void main (String args[]) {
|
||||
// DocApplication app;
|
||||
// app = new DocApplication (args[0], args[1]);
|
||||
// app.readApplication ();
|
||||
/**
|
||||
* Creates a new DocApplication object.
|
||||
*
|
||||
* @param name ...
|
||||
* @param location ...
|
||||
*
|
||||
* @throws DocException ...
|
||||
*/
|
||||
public DocApplication(String name, File location) throws DocException {
|
||||
super(name, location, APPLICATION);
|
||||
readProps();
|
||||
}
|
||||
|
||||
// DocPrototype el = DocPrototype.newInstance (new File(args[0]));
|
||||
// el.readFiles ();
|
||||
/**
|
||||
* 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();
|
||||
}
|
||||
|
||||
// DocFunction func = DocFunction.newTemplate (new File(args[0]));
|
||||
// DocFunction func = DocFunction.newAction (new File(args[0]));
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @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]));
|
||||
|
||||
DocFunction[] func = DocFunction.newFunctions (new File (args[0]));
|
||||
// DocSkin skin = DocSkin.newInstance (new File (args[0]));
|
||||
// System.out.println (func.getContent ());
|
||||
// System.out.println ("\n\n\ncomment = " + func.getComment ());
|
||||
}
|
||||
|
||||
// DocSkin skin = DocSkin.newInstance (new File (args[0]));
|
||||
// System.out.println (func.getContent ());
|
||||
// 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);
|
||||
|
||||
excluded = new HashSet();
|
||||
addExclude("cvs");
|
||||
addExclude(".docs");
|
||||
|
||||
public DocApplication (String name, File location) throws DocException {
|
||||
super (name, location, APPLICATION);
|
||||
}
|
||||
String excludeProps = appProps.getProperty("helma.excludeDocs");
|
||||
|
||||
public DocApplication (String name, String appDir) throws DocException {
|
||||
super (name, new File (appDir), APPLICATION);
|
||||
}
|
||||
if (excludeProps != null) {
|
||||
StringTokenizer tok = new StringTokenizer(excludeProps, ",");
|
||||
|
||||
while (tok.hasMoreTokens()) {
|
||||
String str = tok.nextToken().trim();
|
||||
|
||||
/**
|
||||
* reads all prototypes and files of the application
|
||||
*/
|
||||
public void readApplication () {
|
||||
String arr[] = location.list ();
|
||||
children.clear ();
|
||||
for (int i=0; i<arr.length; i++) {
|
||||
if (Util.isExcluded (arr[i]))
|
||||
continue;
|
||||
File f = new File (location.getAbsolutePath (), arr[i]);
|
||||
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 ();
|
||||
}
|
||||
}
|
||||
addExclude(str);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 ()]);
|
||||
}
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param str ...
|
||||
*/
|
||||
public void addExclude(String str) {
|
||||
excluded.add(str.toLowerCase());
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param str ...
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public boolean isExcluded(String str) {
|
||||
return (excluded.contains(str.toLowerCase()));
|
||||
}
|
||||
|
||||
/**
|
||||
* from helma.framework.IPathElement, overridden with "api"
|
||||
* to work in manage-application
|
||||
*/
|
||||
public String getElementName() {
|
||||
return "api";
|
||||
}
|
||||
/**
|
||||
* reads all prototypes and files of the application
|
||||
*/
|
||||
public void readApplication() {
|
||||
readProps();
|
||||
|
||||
String[] arr = location.list();
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
children.clear();
|
||||
|
||||
for (int i = 0; i < arr.length; i++) {
|
||||
if (isExcluded(arr[i])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
File f = new File(location.getAbsolutePath(), arr[i]);
|
||||
|
||||
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
|
||||
*/
|
||||
public String getElementName() {
|
||||
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;
|
||||
|
||||
public static final int BY_TYPE = 0;
|
||||
public static final int BY_NAME = 1;
|
||||
/**
|
||||
* Creates a new DocComparator object.
|
||||
*
|
||||
* @param mode ...
|
||||
* @param docEl ...
|
||||
*/
|
||||
public DocComparator(int mode, DocElement docEl) {
|
||||
this.mode = mode;
|
||||
this.docEl = docEl;
|
||||
}
|
||||
|
||||
int mode;
|
||||
DocElement docEl;
|
||||
/**
|
||||
* Creates a new DocComparator object.
|
||||
*
|
||||
* @param docEl ...
|
||||
*/
|
||||
public DocComparator(DocElement docEl) {
|
||||
this.mode = 0;
|
||||
this.docEl = docEl;
|
||||
}
|
||||
|
||||
public DocComparator(int mode, DocElement docEl) {
|
||||
this.mode = mode;
|
||||
this.docEl = docEl;
|
||||
}
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param obj1 ...
|
||||
* @param obj2 ...
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public int compare(Object obj1, Object obj2) {
|
||||
DocElement e1 = (DocElement) obj1;
|
||||
DocElement e2 = (DocElement) obj2;
|
||||
|
||||
public DocComparator(DocElement docEl) {
|
||||
this.mode = 0;
|
||||
this.docEl = docEl;
|
||||
}
|
||||
if ((mode == BY_TYPE) && (e1.getType() > e2.getType())) {
|
||||
return 1;
|
||||
} else if ((mode == BY_TYPE) && (e1.getType() < e2.getType())) {
|
||||
return -1;
|
||||
} else {
|
||||
return e1.name.compareTo(e2.name);
|
||||
}
|
||||
}
|
||||
|
||||
public int compare(Object obj1, Object obj2) {
|
||||
DocElement e1 = (DocElement)obj1;
|
||||
DocElement e2 = (DocElement)obj2;
|
||||
if (mode==BY_TYPE && e1.getType()>e2.getType())
|
||||
return 1;
|
||||
else if (mode==BY_TYPE && e1.getType()<e2.getType())
|
||||
return -1;
|
||||
else {
|
||||
return e1.name.compareTo(e2.name);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
DocElement el = (DocElement) obj;
|
||||
if (el.name.equals(docEl.name) && el.getType()==docEl.getType()) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param obj ...
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public boolean equals(Object obj) {
|
||||
DocElement el = (DocElement) obj;
|
||||
|
||||
if (el.name.equals(docEl.name) && (el.getType() == docEl.getType())) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,36 +1,53 @@
|
|||
/*
|
||||
* 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"
|
||||
};
|
||||
|
||||
// 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"
|
||||
};
|
||||
protected DocDirElement(String name, File location, int type) {
|
||||
super(name, location, type);
|
||||
checkCommentFiles();
|
||||
}
|
||||
|
||||
protected DocDirElement (String name, File location, int type) {
|
||||
super (name, location, type);
|
||||
checkCommentFiles ();
|
||||
}
|
||||
private void checkCommentFiles() throws DocException {
|
||||
for (int i = 0; i < DOCFILES.length; i++) {
|
||||
File f = new File(location, DOCFILES[i]);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (f.exists()) {
|
||||
String rawComment = readFile(f);
|
||||
|
||||
parseComment(rawComment);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,304 +1,403 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
public abstract class DocElement implements IPathElement {
|
||||
// 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;
|
||||
int type;
|
||||
File location;
|
||||
DocElement parent = null;
|
||||
Map children = new HashMap ();
|
||||
// identifiers of this element
|
||||
String name;
|
||||
int type;
|
||||
File location;
|
||||
DocElement parent = null;
|
||||
Map children = new HashMap();
|
||||
|
||||
// content
|
||||
String content = "";
|
||||
String comment = "";
|
||||
List tags = new Vector ();
|
||||
List parameters = new Vector ();
|
||||
// content
|
||||
String content = "";
|
||||
String comment = "";
|
||||
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;
|
||||
protected DocElement(String name, String location, int type)
|
||||
throws DocException {
|
||||
this(name, new File(location), type);
|
||||
}
|
||||
|
||||
// above constants are used as array indices
|
||||
public static final String[] typeNames = {
|
||||
"Application",
|
||||
"Prototype",
|
||||
"Action",
|
||||
"Template",
|
||||
"Function",
|
||||
"Macro",
|
||||
"Skin",
|
||||
"Properties"
|
||||
};
|
||||
protected DocElement(String name, File location, int type)
|
||||
throws DocException {
|
||||
if (location.exists() == false) {
|
||||
throw new DocException(name + " not found in " + location.toString());
|
||||
}
|
||||
|
||||
protected DocElement (String name, String location, int type) throws DocException {
|
||||
this (name, new File (location), type);
|
||||
}
|
||||
this.name = name;
|
||||
this.location = location;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
/**
|
||||
* the simple name of the element
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* the simple name of the element
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
/**
|
||||
* @return absolute path to location of element
|
||||
* (directory for apps and prototypes, file for
|
||||
* methods and properties files)
|
||||
*/
|
||||
public File getLocation() {
|
||||
return location;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return absolute path to location of element
|
||||
* (directory for apps and prototypes, file for
|
||||
* methods and properties files)
|
||||
*/
|
||||
public File getLocation() {
|
||||
return location;
|
||||
}
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public int getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public int getType() {
|
||||
return type;
|
||||
}
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getTypeName() {
|
||||
return typeNames[type];
|
||||
}
|
||||
|
||||
public String getTypeName () {
|
||||
return typeNames [type];
|
||||
}
|
||||
/**
|
||||
* returns the comment string, empty string if no comment is set.
|
||||
*/
|
||||
public String getComment() {
|
||||
return comment;
|
||||
}
|
||||
|
||||
/**
|
||||
* the actual content of the doc element (the function body, the properties
|
||||
* list, the file list etc.
|
||||
*/
|
||||
public String getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the comment string, empty string if no comment is set.
|
||||
*/
|
||||
public String getComment () {
|
||||
return comment;
|
||||
}
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param rawContent ...
|
||||
*/
|
||||
public void addTag(String rawContent) {
|
||||
if (tags == null) {
|
||||
tags = new Vector();
|
||||
}
|
||||
|
||||
try {
|
||||
DocTag tag = DocTag.parse(rawContent);
|
||||
|
||||
/**
|
||||
* the actual content of the doc element (the function body, the properties
|
||||
* list, the file list etc.
|
||||
*/
|
||||
public String getContent () {
|
||||
return content;
|
||||
}
|
||||
tags.add(tag);
|
||||
} catch (DocException doc) {
|
||||
debug(doc.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* list all tags
|
||||
*/
|
||||
public DocTag[] listTags() {
|
||||
return (DocTag[]) tags.toArray(new DocTag[0]);
|
||||
}
|
||||
|
||||
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 ());
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 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) {
|
||||
retval.add(tags.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* list all tags
|
||||
*/
|
||||
public DocTag[] listTags () {
|
||||
return (DocTag[]) tags.toArray (new DocTag[0]);
|
||||
}
|
||||
return (DocTag[]) retval.toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param param ...
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public boolean hasParameter(String param) {
|
||||
return parameters.contains(param);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
retval.add (tags.get (i));
|
||||
}
|
||||
return (DocTag[]) retval.toArray ();
|
||||
}
|
||||
/**
|
||||
* the list of parameters
|
||||
*/
|
||||
public String[] listParameters() {
|
||||
return (String[]) parameters.toArray(new String[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* add a string to the parameters-list
|
||||
*/
|
||||
protected void addParameter(String param) {
|
||||
parameters.add(param);
|
||||
}
|
||||
|
||||
public boolean hasParameter (String param) {
|
||||
return parameters.contains (param);
|
||||
}
|
||||
/**
|
||||
* parse rawComment, render DocTags
|
||||
*/
|
||||
void parseComment(String rawComment) {
|
||||
try {
|
||||
StringTokenizer tok = new StringTokenizer(rawComment, "\n", true);
|
||||
int BLANK = 0;
|
||||
int TEXT = 1;
|
||||
int TAGS = 2;
|
||||
boolean lastEmpty = false;
|
||||
int mode = BLANK;
|
||||
StringBuffer buf = new StringBuffer();
|
||||
|
||||
/**
|
||||
* the list of parameters
|
||||
*/
|
||||
public String[] listParameters () {
|
||||
return (String[]) parameters.toArray (new String[0]);
|
||||
}
|
||||
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;
|
||||
|
||||
/**
|
||||
* add a string to the parameters-list
|
||||
*/
|
||||
protected void addParameter (String param) {
|
||||
parameters.add (param);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// if we come here the first time, start with TEXT mode
|
||||
mode = (mode == BLANK) ? TEXT : mode;
|
||||
|
||||
/**
|
||||
* parse rawComment, render DocTags
|
||||
*/
|
||||
void parseComment (String rawComment) {
|
||||
try {
|
||||
StringTokenizer tok = new StringTokenizer (rawComment, "\n", true);
|
||||
int BLANK = 0;
|
||||
int TEXT = 1;
|
||||
int TAGS = 2;
|
||||
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)
|
||||
comment = buf.toString ();
|
||||
// if we appended to a tag, store that ...
|
||||
if (mode==TAGS)
|
||||
addTag (buf.toString ());
|
||||
// reset buffer
|
||||
buf = new StringBuffer ();
|
||||
mode = TAGS;
|
||||
}
|
||||
// append to current buffer
|
||||
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)
|
||||
comment = buf.toString ();
|
||||
else if (mode==TAGS)
|
||||
addTag (buf.toString ());
|
||||
} catch (RuntimeException rt) {
|
||||
debug ("parse error in " + location + ": " + rt.getMessage());
|
||||
}
|
||||
}
|
||||
// check if we have a new tag
|
||||
if (DocTag.isTagStart(line)) {
|
||||
// if we appended to comment text until now, store that ...
|
||||
if (mode == TEXT) {
|
||||
comment = buf.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* utility: read a complete file into a string
|
||||
*/
|
||||
protected static String readFile (File file) {
|
||||
try {
|
||||
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 ("");
|
||||
}
|
||||
}
|
||||
// if we appended to a tag, store that ...
|
||||
if (mode == TAGS) {
|
||||
addTag(buf.toString());
|
||||
}
|
||||
|
||||
// reset buffer
|
||||
buf = new StringBuffer();
|
||||
mode = TAGS;
|
||||
}
|
||||
|
||||
public void setParent (DocElement parent) {
|
||||
this.parent = parent;
|
||||
}
|
||||
// append to current buffer
|
||||
if (lastEmpty == true) {
|
||||
buf.append("\n");
|
||||
}
|
||||
|
||||
public void addChild (DocElement child) {
|
||||
if (child==null)
|
||||
return;
|
||||
children.put (child.getElementName (), child);
|
||||
}
|
||||
buf.append(line);
|
||||
buf.append(" ");
|
||||
lastEmpty = false;
|
||||
}
|
||||
|
||||
public int countChildren () {
|
||||
return children.size ();
|
||||
}
|
||||
// store the last element, if there was at least one element ...
|
||||
if (mode == TEXT) {
|
||||
comment = buf.toString();
|
||||
} else if (mode == TAGS) {
|
||||
addTag(buf.toString());
|
||||
}
|
||||
} catch (RuntimeException rt) {
|
||||
debug("parse error in " + location + ": " + rt.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public Map getChildren () {
|
||||
return children;
|
||||
}
|
||||
/**
|
||||
* utility: read a complete file into a string
|
||||
*/
|
||||
protected static String readFile(File file) {
|
||||
try {
|
||||
StringBuffer buf = new StringBuffer();
|
||||
BufferedReader in = new BufferedReader(new FileReader(file));
|
||||
String line = in.readLine();
|
||||
|
||||
/**
|
||||
* returns an array of doc elements, sorted by their name
|
||||
*/
|
||||
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;
|
||||
}
|
||||
while (line != null) {
|
||||
buf.append(line + "\n");
|
||||
line = in.readLine();
|
||||
}
|
||||
|
||||
/**
|
||||
* from helma.framework.IPathElement. Elements are named
|
||||
* like this: typename_name
|
||||
*/
|
||||
public String getElementName() {
|
||||
return typeNames[type].toLowerCase() + "_" + name;
|
||||
}
|
||||
in.close();
|
||||
|
||||
return buf.toString();
|
||||
} catch (IOException e) {
|
||||
return ("");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* from helma.framework.IPathElement. Retrieves a child from the
|
||||
* children map.
|
||||
*/
|
||||
public IPathElement getChildElement (String name) {
|
||||
try {
|
||||
return (IPathElement) children.get (name);
|
||||
} catch (ClassCastException cce) {
|
||||
debug (cce.toString ());
|
||||
cce.printStackTrace ();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param parent ...
|
||||
*/
|
||||
public void setParent(DocElement parent) {
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param child ...
|
||||
*/
|
||||
public void addChild(DocElement child) {
|
||||
if (child == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* from helma.framework.IPathElement. Returns the parent object
|
||||
* of this instance if assigned.
|
||||
*/
|
||||
public IPathElement getParentElement () {
|
||||
return parent;
|
||||
}
|
||||
children.put(child.getElementName(), child);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public int countChildren() {
|
||||
return children.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* from helma.framework.IPathElement. Prototypes are assigned like
|
||||
* this: "doc" + typename (e.g. docapplication, docprototype etc)
|
||||
*/
|
||||
public java.lang.String getPrototype () {
|
||||
return "doc" + typeNames[type].toLowerCase ();
|
||||
}
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public Map getChildren() {
|
||||
return children;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns an array of doc elements, sorted by their name
|
||||
*/
|
||||
public DocElement[] listChildren() {
|
||||
String[] keys = (String[]) children.keySet().toArray(new String[0]);
|
||||
|
||||
public String toString () {
|
||||
return "[" + typeNames [type] + " " + name + "]";
|
||||
}
|
||||
Arrays.sort(keys);
|
||||
|
||||
public static void debug (String msg) {
|
||||
System.out.println(msg);
|
||||
}
|
||||
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
|
||||
*/
|
||||
public String getElementName() {
|
||||
return typeNames[type].toLowerCase() + "_" + name;
|
||||
}
|
||||
|
||||
/**
|
||||
* from helma.framework.IPathElement. Retrieves a child from the
|
||||
* children map.
|
||||
*/
|
||||
public IPathElement getChildElement(String name) {
|
||||
try {
|
||||
return (IPathElement) children.get(name);
|
||||
} catch (ClassCastException cce) {
|
||||
debug(cce.toString());
|
||||
cce.printStackTrace();
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* from helma.framework.IPathElement. Returns the parent object
|
||||
* of this instance if assigned.
|
||||
*/
|
||||
public IPathElement getParentElement() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* from helma.framework.IPathElement. Prototypes are assigned like
|
||||
* this: "doc" + typename (e.g. docapplication, docprototype etc)
|
||||
*/
|
||||
public java.lang.String getPrototype() {
|
||||
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;
|
||||
|
||||
public DocException (String str) {
|
||||
super (str);
|
||||
this.str = str;
|
||||
/**
|
||||
* Creates a new DocException object.
|
||||
*
|
||||
* @param str ...
|
||||
*/
|
||||
public DocException(String str) {
|
||||
super(str);
|
||||
this.str = str;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getMessage() {
|
||||
return str;
|
||||
return str;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,84 +1,112 @@
|
|||
/*
|
||||
* Helma License Notice
|
||||
*
|
||||
* The contents of this file are subject to the Helma License
|
||||
* Version 2.0 (the "License"). You may not use this file except in
|
||||
* compliance with the License. A copy of the License is available at
|
||||
* http://adele.helma.org/download/helma/license.txt
|
||||
*
|
||||
* Copyright 1998-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 {
|
||||
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));
|
||||
}
|
||||
/**
|
||||
* 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 {
|
||||
String filename = f.getName();
|
||||
|
||||
if (!filename.endsWith(suffix)) {
|
||||
throw new DocException("file doesn't have suffix " + suffix + ": " +
|
||||
f.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* creates fesi token manager for a given file.
|
||||
*/
|
||||
static protected EcmaScriptTokenManager createTokenManager (File f) {
|
||||
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 ();
|
||||
throw new DocException (fnfe.toString ());
|
||||
}
|
||||
}
|
||||
return filename.substring(0, filename.lastIndexOf(suffix));
|
||||
}
|
||||
|
||||
/**
|
||||
* creates fesi token manager for a given file.
|
||||
*/
|
||||
static protected EcmaScriptTokenManager createTokenManager(File f) {
|
||||
try {
|
||||
ASCII_CharStream is = new ASCII_CharStream(new FileReader(f), 1, 1);
|
||||
EcmaScriptTokenManager mgr = new EcmaScriptTokenManager(is, 0);
|
||||
|
||||
protected DocFileElement (String name, File location, int type) {
|
||||
super (name, location, type);
|
||||
}
|
||||
return mgr;
|
||||
} catch (FileNotFoundException fnfe) {
|
||||
fnfe.printStackTrace();
|
||||
throw new DocException(fnfe.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
StringBuffer buf = new StringBuffer();
|
||||
int ct = 0;
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
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;
|
||||
ct++;
|
||||
if (ct==beginLine)
|
||||
buf.append (line.substring(beginColumn-1, line.length())+"\n");
|
||||
else if ( ct>beginLine && ct<endLine )
|
||||
buf.append (line+"\n");
|
||||
else if (ct==endLine)
|
||||
buf.append (line.substring(0,endColumn));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
debug (e.getMessage ());
|
||||
}
|
||||
content = buf.toString ();
|
||||
}
|
||||
try {
|
||||
BufferedReader in = new BufferedReader(new FileReader(sourceFile));
|
||||
String line = "";
|
||||
|
||||
while (line != null) {
|
||||
line = in.readLine();
|
||||
|
||||
/**
|
||||
* 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());
|
||||
}
|
||||
if (line == null) {
|
||||
break;
|
||||
}
|
||||
|
||||
ct++;
|
||||
|
||||
if (ct == beginLine) {
|
||||
buf.append(line.substring(beginColumn - 1, line.length()) + "\n");
|
||||
} else if ((ct > beginLine) && (ct < endLine)) {
|
||||
buf.append(line + "\n");
|
||||
} 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,154 +1,185 @@
|
|||
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
|
||||
*/
|
||||
public static DocFunction newAction (File location) {
|
||||
return newAction (location, null);
|
||||
}
|
||||
/**
|
||||
* creates a new independent DocFunction object of type ACTION
|
||||
*/
|
||||
public static DocFunction newAction(File location) {
|
||||
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);
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
func.parseActionFile();
|
||||
|
||||
/**
|
||||
* creates a new independent DocFunction object of type TEMPLATE
|
||||
*/
|
||||
public static DocFunction newTemplate (File location) {
|
||||
return newTemplate (location, null);
|
||||
}
|
||||
return func;
|
||||
}
|
||||
|
||||
/**
|
||||
* creates a new independent DocFunction object of type TEMPLATE
|
||||
*/
|
||||
public static DocFunction newTemplate(File location) {
|
||||
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;
|
||||
}
|
||||
/**
|
||||
* 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();
|
||||
|
||||
/**
|
||||
* reads a function file and creates independent DocFunction objects of type FUNCTION
|
||||
*/
|
||||
public static DocFunction[] newFunctions (File location) {
|
||||
return newFunctions (location, null);
|
||||
}
|
||||
return func;
|
||||
}
|
||||
|
||||
/**
|
||||
* reads a function file and creates independent DocFunction objects of type FUNCTION
|
||||
*/
|
||||
public static DocFunction[] newFunctions(File location) {
|
||||
return newFunctions(location, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* reads a function file and creates DocFunction objects of type FUNCTION
|
||||
* connected to another DocElement.
|
||||
*/
|
||||
public static DocFunction[] newFunctions (File location, DocElement parent) {
|
||||
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"))
|
||||
func = new DocFunction (funcName, location, parent, ACTION);
|
||||
else if (funcName.endsWith("_macro"))
|
||||
func = new DocFunction (funcName, location, parent, MACRO);
|
||||
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) {
|
||||
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) {
|
||||
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]);
|
||||
}
|
||||
/**
|
||||
* reads a function file and creates DocFunction objects of type FUNCTION
|
||||
* connected to another DocElement.
|
||||
*/
|
||||
public static DocFunction[] newFunctions(File location, DocElement parent) {
|
||||
Vector vec = new Vector();
|
||||
EcmaScriptTokenManager mgr = createTokenManager(location);
|
||||
Token tok = mgr.getNextToken();
|
||||
|
||||
protected DocFunction (String name, File location, DocElement parent, int type) {
|
||||
super (name, location, type);
|
||||
this.parent = parent;
|
||||
}
|
||||
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();
|
||||
|
||||
/**
|
||||
* reads the content of a .hac file and parses the comment before the first
|
||||
* javascript element
|
||||
*/
|
||||
private void parseActionFile () {
|
||||
EcmaScriptTokenManager mgr = createTokenManager(location);
|
||||
Token tok = mgr.getNextToken();
|
||||
parseCommentFromToken (tok);
|
||||
content = readFile (location);
|
||||
}
|
||||
// create the function object
|
||||
DocFunction func;
|
||||
|
||||
if (funcName.endsWith("_action")) {
|
||||
func = new DocFunction(funcName, location, parent, ACTION);
|
||||
} else if (funcName.endsWith("_macro")) {
|
||||
func = new DocFunction(funcName, location, parent, MACRO);
|
||||
} else {
|
||||
func = new DocFunction(funcName, location, parent, FUNCTION);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 ("%>")));
|
||||
ASCII_CharStream ascii = new ASCII_CharStream (str,1,1);
|
||||
EcmaScriptTokenManager mgr = new EcmaScriptTokenManager (ascii);
|
||||
Token tok = mgr.getNextToken();
|
||||
parseCommentFromToken (tok);
|
||||
}
|
||||
// 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)) {
|
||||
if (tok.kind == EcmaScriptConstants.IDENTIFIER) {
|
||||
func.addParameter(tok.image);
|
||||
}
|
||||
|
||||
/**
|
||||
* from helma.framework.IPathElement. All macros, templates, actions etc
|
||||
* have the same prototype.
|
||||
*/
|
||||
public java.lang.String getPrototype () {
|
||||
return "docfunction";
|
||||
}
|
||||
tok = mgr.getNextToken();
|
||||
}
|
||||
} else {
|
||||
tok = mgr.getNextToken();
|
||||
}
|
||||
|
||||
// now find the end of the 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]);
|
||||
}
|
||||
|
||||
/**
|
||||
* reads the content of a .hac file and parses the comment before the first
|
||||
* javascript element
|
||||
*/
|
||||
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("%>")));
|
||||
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.
|
||||
*/
|
||||
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,59 +21,76 @@ import helma.util.SystemProperties;
|
|||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
public class DocProperties extends DocFileElement {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class DocProperties extends DocFileElement {
|
||||
Properties props = null;
|
||||
|
||||
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();
|
||||
|
||||
/**
|
||||
* creates a new independent DocProperties object
|
||||
*/
|
||||
public static DocProperties newInstance (File location) {
|
||||
return newInstance (location, null);
|
||||
}
|
||||
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 DocProperties object connected to another DocElement
|
||||
*/
|
||||
public static DocProperties newInstance (File location, DocElement parent) {
|
||||
try {
|
||||
return new DocProperties (location, parent);
|
||||
} catch (DocException doc) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* creates a new independent DocProperties object
|
||||
*/
|
||||
public static DocProperties newInstance(File location) {
|
||||
return newInstance(location, 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 DocProperties object connected to another DocElement
|
||||
*/
|
||||
public static DocProperties newInstance(File location, DocElement parent) {
|
||||
try {
|
||||
return new DocProperties(location, parent);
|
||||
} catch (DocException doc) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public Properties getProperties () {
|
||||
return props;
|
||||
}
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public Properties getProperties() {
|
||||
return props;
|
||||
}
|
||||
|
||||
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 ();
|
||||
childProps.setProperty (key, prototype);
|
||||
}
|
||||
|
||||
}
|
||||
return childProps;
|
||||
}
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @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();
|
||||
|
||||
childProps.setProperty(key, prototype);
|
||||
}
|
||||
}
|
||||
|
||||
return childProps;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,110 +1,150 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
public class DocPrototype extends DocDirElement {
|
||||
private DocPrototype(String name, File location, DocElement parent) {
|
||||
super(name, location, PROTOTYPE);
|
||||
this.parent = parent;
|
||||
typeProperties = DocProperties.newInstance(new File(location, "type.properties"));
|
||||
}
|
||||
|
||||
private DocProperties typeProperties = null;
|
||||
private DocPrototype parentPrototype = null;
|
||||
/**
|
||||
* creates a prototype that is independent of an
|
||||
* application object
|
||||
* @param homedirectory
|
||||
*/
|
||||
public static DocPrototype newInstance(File location) {
|
||||
return newInstance(location, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* creates a prototype that is independent of an
|
||||
* application object
|
||||
* @param homedirectory
|
||||
*/
|
||||
public static DocPrototype newInstance (File location) {
|
||||
return newInstance (location, null);
|
||||
}
|
||||
/**
|
||||
* creates a prototype that is connected to an
|
||||
* application object and resides in app's home dir.
|
||||
* @param application
|
||||
* @param name
|
||||
*/
|
||||
public static DocPrototype newInstance(File location, DocElement parent) {
|
||||
DocPrototype pt = new DocPrototype(location.getName(), location, parent);
|
||||
|
||||
/**
|
||||
* creates a prototype that is connected to an
|
||||
* application object and resides in app's home dir.
|
||||
* @param application
|
||||
* @param name
|
||||
*/
|
||||
public static DocPrototype newInstance (File location, DocElement parent) {
|
||||
DocPrototype pt = new DocPrototype (location.getName (), location, parent);
|
||||
return pt;
|
||||
}
|
||||
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
|
||||
* time but only -after- all prototypes are parsed and attached to a parent
|
||||
* DocApplication object.
|
||||
*/
|
||||
public void checkInheritance() {
|
||||
// hopobject is the top prototype:
|
||||
if (name.equals("hopobject")) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeProperties != null) {
|
||||
// check for "_extends" in the the type.properties
|
||||
String ext = typeProperties.getProperties().getProperty("_extends");
|
||||
|
||||
/**
|
||||
* checks the type.properites for _extend values and connected a possible
|
||||
* parent prototype with this prototype. this can't be successfull at construction
|
||||
* time but only -after- all prototypes are parsed and attached to a parent
|
||||
* DocApplication object.
|
||||
*/
|
||||
public void checkInheritance () {
|
||||
// hopobject is the top prototype:
|
||||
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) {
|
||||
// try to get the prototype if available
|
||||
parentPrototype = (DocPrototype) parent.getChildElement ("prototype_" + ext);
|
||||
}
|
||||
}
|
||||
if (parentPrototype==null && parent!=null && !name.equals("global")) {
|
||||
// if no _extend was set, get the hopobject prototype
|
||||
parentPrototype = (DocPrototype) parent.getChildElement ("prototype_hopobject");
|
||||
}
|
||||
}
|
||||
if ((ext != null) && (parent != null)) {
|
||||
// try to get the prototype if available
|
||||
parentPrototype = (DocPrototype) parent.getChildElement("prototype_" +
|
||||
ext);
|
||||
}
|
||||
}
|
||||
|
||||
public DocPrototype getParentPrototype () {
|
||||
return parentPrototype;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
public DocProperties getTypeProperties () {
|
||||
return typeProperties;
|
||||
}
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public DocProperties getTypeProperties() {
|
||||
return typeProperties;
|
||||
}
|
||||
|
||||
/**
|
||||
* runs through the prototype directory and parses all helma files
|
||||
*/
|
||||
public void readFiles() {
|
||||
children.clear();
|
||||
|
||||
/**
|
||||
* runs through the prototype directory and parses all helma files
|
||||
*/
|
||||
public void readFiles () {
|
||||
children.clear ();
|
||||
String arr[] = location.list ();
|
||||
for (int i=0; i<arr.length; i++) {
|
||||
if (Util.isExcluded (arr[i]))
|
||||
continue;
|
||||
File f = new File (location.getAbsolutePath (), arr[i]);
|
||||
if (f.isDirectory ())
|
||||
continue;
|
||||
try {
|
||||
if (arr[i].endsWith (".skin")) {
|
||||
addChild (DocSkin.newInstance (f, this));
|
||||
} else if (arr[i].endsWith (".properties")) {
|
||||
continue;
|
||||
} else if (arr[i].endsWith (".hac")) {
|
||||
addChild (DocFunction.newAction (f, this));
|
||||
} else if (arr[i].endsWith (".hsp")) {
|
||||
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 ());
|
||||
ex.printStackTrace ();
|
||||
}
|
||||
}
|
||||
}
|
||||
String[] arr = location.list();
|
||||
|
||||
for (int i = 0; i < arr.length; i++) {
|
||||
if (getDocApplication().isExcluded(arr[i])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
File f = new File(location.getAbsolutePath(), arr[i]);
|
||||
|
||||
if (f.isDirectory()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
if (arr[i].endsWith(".skin")) {
|
||||
addChild(DocSkin.newInstance(f, this));
|
||||
} else if (arr[i].endsWith(".properties")) {
|
||||
continue;
|
||||
} else if (arr[i].endsWith(".hac")) {
|
||||
addChild(DocFunction.newAction(f, this));
|
||||
} else if (arr[i].endsWith(".hsp")) {
|
||||
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());
|
||||
ex.printStackTrace();
|
||||
} catch (FESI.Parser.TokenMgrError err) {
|
||||
System.out.println("couldn't parse file " + f.getAbsolutePath() + ": " +
|
||||
err.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,87 +1,118 @@
|
|||
/*
|
||||
* 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 {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
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
|
||||
*/
|
||||
public static DocSkin newInstance (File location) {
|
||||
return newInstance (location, null);
|
||||
}
|
||||
/**
|
||||
* creates a new independent DocSkin object
|
||||
*/
|
||||
public static DocSkin newInstance(File location) {
|
||||
return newInstance(location, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* creates a new DocSkin object connected to another DocElement
|
||||
*/
|
||||
public static DocSkin newInstance (File location, DocElement parent) {
|
||||
String skinname = nameFromFile (location, ".skin");
|
||||
DocSkin skin = new DocSkin (skinname, location, parent);
|
||||
return skin;
|
||||
}
|
||||
/**
|
||||
* creates a new DocSkin object connected to another DocElement
|
||||
*/
|
||||
public static DocSkin newInstance(File location, DocElement parent) {
|
||||
String skinname = nameFromFile(location, ".skin");
|
||||
DocSkin skin = new DocSkin(skinname, location, parent);
|
||||
|
||||
protected DocSkin (String name, File location, DocElement parent) {
|
||||
super (name, location, SKIN);
|
||||
this.parent = parent;
|
||||
content = readFile (location);
|
||||
parseHandlers ();
|
||||
}
|
||||
return skin;
|
||||
}
|
||||
|
||||
/**
|
||||
* parses the source code of the skin and
|
||||
* extracts all included macros. code taken
|
||||
* from helma.framework.core.Skin
|
||||
* @see helma.framework.core.Skin
|
||||
*/
|
||||
private void parseHandlers() {
|
||||
ArrayList partBuffer = new ArrayList();
|
||||
char[] source = content.toCharArray();
|
||||
int sourceLength = source.length;
|
||||
int start = 0;
|
||||
|
||||
/**
|
||||
* parses the source code of the skin and
|
||||
* extracts all included macros. code taken
|
||||
* from helma.framework.core.Skin
|
||||
* @see helma.framework.core.Skin
|
||||
*/
|
||||
private void parseHandlers () {
|
||||
ArrayList partBuffer = new ArrayList ();
|
||||
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] == '%') {
|
||||
// found macro start tag
|
||||
int j = i+2;
|
||||
// search macro end tag
|
||||
while (j < sourceLength-1 && (source[j] != '%' || source[j+1] != '>')) {
|
||||
j++;
|
||||
}
|
||||
if (j > i+2) {
|
||||
String str = (new String (source, i+2, j-i)).trim ();
|
||||
if (str.endsWith("%>"))
|
||||
str = str.substring (0, str.length()-2);
|
||||
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)) {
|
||||
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]);
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < (sourceLength - 1); i++) {
|
||||
if ((source[i] == '<') && (source[i + 1] == '%')) {
|
||||
// found macro start tag
|
||||
int j = i + 2;
|
||||
|
||||
/**
|
||||
* from helma.framework.IPathElement. Use the same prototype as functions etc.
|
||||
*/
|
||||
public java.lang.String getPrototype () {
|
||||
return "docfunction";
|
||||
}
|
||||
// search macro end tag
|
||||
while ((j < (sourceLength - 1)) &&
|
||||
((source[j] != '%') || (source[j + 1] != '>'))) {
|
||||
j++;
|
||||
}
|
||||
|
||||
if (j > (i + 2)) {
|
||||
String str = (new String(source, i + 2, j - i)).trim();
|
||||
|
||||
if (str.endsWith("%>")) {
|
||||
str = str.substring(0, str.length() - 2);
|
||||
}
|
||||
|
||||
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)) {
|
||||
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]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* from helma.framework.IPathElement. Use the same prototype as functions etc.
|
||||
*/
|
||||
public java.lang.String getPrototype() {
|
||||
return "docfunction";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,108 +1,176 @@
|
|||
/*
|
||||
* 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 {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public final class DocTag {
|
||||
// for public use we have less types than
|
||||
// internally. eg, we're combining "return" and "returns"
|
||||
// or "arg" and "param".
|
||||
// the values here have to match the index of
|
||||
// the tags-array!
|
||||
public static final int PARAMETER = 0;
|
||||
public static final int RETURN = 2;
|
||||
public static final int AUTHOR = 4;
|
||||
public static final int VERSION = 5;
|
||||
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" },
|
||||
{ "@return", "Returns" },
|
||||
{ "@returns", "Returns" },
|
||||
{ "@author", "Author" },
|
||||
{ "@version", "Version" },
|
||||
{ "@see", "See also" },
|
||||
{ "@deprecated", "Deprecated" },
|
||||
{ "@overrides", "Overrides" }
|
||||
};
|
||||
private String name;
|
||||
|
||||
// for public use we have less types than
|
||||
// internally. eg, we're combining "return" and "returns"
|
||||
// or "arg" and "param".
|
||||
// the values here have to match the index of
|
||||
// the tags-array!
|
||||
public static final int PARAMETER = 0;
|
||||
public static final int RETURN = 2;
|
||||
public static final int AUTHOR = 4;
|
||||
public static final int VERSION = 5;
|
||||
public static final int SEE = 6;
|
||||
public static final int DEPRECATED = 7;
|
||||
public static final int OVERRIDES = 8;
|
||||
// "kind" is for internal use, "type" is external
|
||||
private int kind;
|
||||
private String text;
|
||||
|
||||
public static final String[][] tags = {
|
||||
{"@arg","Argument"},
|
||||
{"@param","Parameter"},
|
||||
{"@return","Returns"},
|
||||
{"@returns","Returns"},
|
||||
{"@author","Author"},
|
||||
{"@version","Version"},
|
||||
{"@see","See also"},
|
||||
{"@deprecated", "Deprecated"},
|
||||
{"@overrides", "Overrides"}
|
||||
};
|
||||
private DocTag(int kind, String name, String text) {
|
||||
this.kind = kind;
|
||||
this.name = (name != null) ? name : "";
|
||||
this.text = (text != null) ? text : "";
|
||||
}
|
||||
|
||||
private String name;
|
||||
// "kind" is for internal use, "type" is external
|
||||
private int kind;
|
||||
private String text;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param rawTag ...
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public static boolean isTagStart(String rawTag) {
|
||||
if (getTagNumber(rawTag) > -1) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
public static DocTag parse (String rawTag) throws DocException {
|
||||
int kind = getTagNumber (rawTag);
|
||||
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) {
|
||||
StringTokenizer tok = new StringTokenizer (content);
|
||||
String name = "";
|
||||
if (tok.hasMoreTokens ())
|
||||
name = tok.nextToken ();
|
||||
String comment = "";
|
||||
try {
|
||||
comment = content.substring (name.length ()+1).trim ();
|
||||
} catch (StringIndexOutOfBoundsException e) { }
|
||||
return new DocTag (kind, name, comment);
|
||||
} else {
|
||||
return new DocTag (kind, "", content);
|
||||
}
|
||||
}
|
||||
if (kind == -1) {
|
||||
throw new DocException("unsupported tag type: " + rawTag);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
String content = rawTag.substring(tags[kind][0].length() + 1).trim();
|
||||
|
||||
if ((kind == 0) || (kind == 1)) {
|
||||
StringTokenizer tok = new StringTokenizer(content);
|
||||
String name = "";
|
||||
|
||||
private DocTag (int kind, String name, String text) {
|
||||
this.kind = kind;
|
||||
this.name = (name!=null) ? name : "";
|
||||
this.text = (text!=null) ? text : "";
|
||||
}
|
||||
if (tok.hasMoreTokens()) {
|
||||
name = tok.nextToken();
|
||||
}
|
||||
|
||||
public String getName () {
|
||||
return name;
|
||||
}
|
||||
String comment = "";
|
||||
|
||||
public int getType () {
|
||||
if (kind==0 || kind==1)
|
||||
return PARAMETER;
|
||||
else if (kind==2 || kind==3)
|
||||
return RETURN;
|
||||
else
|
||||
return kind;
|
||||
}
|
||||
try {
|
||||
comment = content.substring(name.length() + 1).trim();
|
||||
} catch (StringIndexOutOfBoundsException e) {
|
||||
}
|
||||
|
||||
return new DocTag(kind, name, comment);
|
||||
} else {
|
||||
return new DocTag(kind, "", content);
|
||||
}
|
||||
}
|
||||
|
||||
public String getTag () {
|
||||
return tags[kind][0];
|
||||
}
|
||||
private static int getTagNumber(String rawTag) {
|
||||
rawTag = rawTag.trim().toLowerCase();
|
||||
|
||||
public String getText () {
|
||||
return text;
|
||||
}
|
||||
for (int i = 0; i < tags.length; i++) {
|
||||
if (rawTag.startsWith(tags[i][0])) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return tags [kind][1] + ": " + name + " " + text;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public int getType() {
|
||||
if ((kind == 0) || (kind == 1)) {
|
||||
return PARAMETER;
|
||||
} else if ((kind == 2) || (kind == 3)) {
|
||||
return RETURN;
|
||||
} 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 ()));
|
||||
}
|
||||
|
||||
public static String chopDelimiters (String line) {
|
||||
if (line==null)
|
||||
return null;
|
||||
else if (line.startsWith("/**"))
|
||||
return line.substring (3).trim ();
|
||||
else if (line.startsWith("/*"))
|
||||
return line.substring (2).trim ();
|
||||
else if (line.endsWith ("*/"))
|
||||
return line.substring (0, line.length ()-2);
|
||||
else if (line.startsWith("*"))
|
||||
return line.substring (1).trim ();
|
||||
else if (line.startsWith("//"))
|
||||
return line.substring (2).trim ();
|
||||
else
|
||||
return line;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param line ...
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public static String chopDelimiters(String line) {
|
||||
if (line == null) {
|
||||
return null;
|
||||
} else if (line.startsWith("/**")) {
|
||||
return line.substring(3).trim();
|
||||
} else if (line.startsWith("/*")) {
|
||||
return line.substring(2).trim();
|
||||
} else if (line.endsWith("*/")) {
|
||||
return line.substring(0, line.length() - 2);
|
||||
} else if (line.startsWith("*")) {
|
||||
return line.substring(1).trim();
|
||||
} else if (line.startsWith("//")) {
|
||||
return line.substring(2).trim();
|
||||
} 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 {
|
||||
|
||||
public ConfigurationException (String msg) {
|
||||
super (msg);
|
||||
/**
|
||||
* Creates a new ConfigurationException object.
|
||||
*
|
||||
* @param msg ...
|
||||
*/
|
||||
public ConfigurationException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,53 +1,71 @@
|
|||
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>.
|
||||
*/
|
||||
|
||||
* 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.
|
||||
*/
|
||||
public abstract void init(Server server) throws ConfigurationException;
|
||||
|
||||
/**
|
||||
* called by the Server at startup time. should check wheter the needed classes
|
||||
* are present and throw a ConfigurationException if not.
|
||||
*/
|
||||
public abstract void init (Server server) throws ConfigurationException;
|
||||
/**
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
/**
|
||||
* called when an Application is stopped.
|
||||
* This should be <b>synchronized</b> when any self-destruction is performed.
|
||||
*/
|
||||
public abstract void applicationStopped(Application app);
|
||||
|
||||
/**
|
||||
* called when an Application is stopped.
|
||||
* This should be <b>synchronized</b> when any self-destruction is performed.
|
||||
*/
|
||||
public abstract void applicationStopped (Application app);
|
||||
/**
|
||||
* called when an Application's properties are have been updated.
|
||||
* note that this will be called at startup once *before* applicationStarted().
|
||||
*/
|
||||
public abstract void applicationUpdated(Application app);
|
||||
|
||||
/**
|
||||
* called when an Application's properties are have been updated.
|
||||
* note that this will be called at startup once *before* applicationStarted().
|
||||
*/
|
||||
public abstract void applicationUpdated (Application app);
|
||||
|
||||
/**
|
||||
* called by the ScriptingEngine when it is initizalized. Throws a ConfigurationException
|
||||
* when this type of ScriptingEngine is not supported. New methods and prototypes can be
|
||||
* added to the scripting environment. New global vars should be returned in a HashMap
|
||||
* 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 String getName ();
|
||||
/**
|
||||
* called by the ScriptingEngine when it is initizalized. Throws a ConfigurationException
|
||||
* when this type of ScriptingEngine is not supported. New methods and prototypes can be
|
||||
* added to the scripting environment. New global vars should be returned in a HashMap
|
||||
* 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;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @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,55 +23,104 @@ 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 =
|
||||
* helma.extensions.demo.DemoExtensions</code> to your <code>server.properties</code>.
|
||||
* a new global object <code>demo</code> that wraps helma.main.Server
|
||||
* will be added to the scripting environment.
|
||||
*/
|
||||
|
||||
* a demo extension implementation, to activate this add <code>extensions =
|
||||
* helma.extensions.demo.DemoExtensions</code> to your <code>server.properties</code>.
|
||||
* 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)
|
||||
Class check = Class.forName("helma.main.Server");
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new ConfigurationException("helma-library not present in classpath. make sure helma.jar is included. get it from http://www.helma.org/");
|
||||
}
|
||||
}
|
||||
|
||||
public void init (Server server) throws ConfigurationException {
|
||||
try {
|
||||
// just a demo with the server class itself (which is always there, obviously)
|
||||
Class check = Class.forName("helma.main.Server");
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new ConfigurationException("helma-library not present in classpath. make sure helma.jar is included. get it from http://www.helma.org/");
|
||||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param app ...
|
||||
*
|
||||
* @throws ConfigurationException ...
|
||||
*/
|
||||
public void applicationStarted(Application app) throws ConfigurationException {
|
||||
app.logEvent("DemoExtension init with app " + app.getName());
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
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 void applicationUpdated (Application app) {
|
||||
app.logEvent ("DemoExtension updated on app " + app.getName () );
|
||||
}
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @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");
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
app.logEvent("initScripting DemoExtension with " + app.getName() + " and " +
|
||||
engine.toString());
|
||||
|
||||
public String getName () {
|
||||
return "DemoExtension";
|
||||
}
|
||||
// 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 {
|
||||
|
||||
|
||||
public ApplicationStoppedException () {
|
||||
super ("The application has been stopped");
|
||||
/**
|
||||
* 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;
|
||||
|
||||
|
@ -7,68 +21,110 @@ import java.util.HashMap;
|
|||
import javax.servlet.http.Cookie;
|
||||
|
||||
/**
|
||||
* Cookie Transmitter. A simple, serializable representation
|
||||
* Cookie Transmitter. A simple, serializable representation
|
||||
* 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) {
|
||||
this.name = name;
|
||||
this.value = value;
|
||||
CookieTrans(String name, String value) {
|
||||
this.name = name;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
void setValue (String value) {
|
||||
this.value = value;
|
||||
void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
void setDays (int days) {
|
||||
this.days = days;
|
||||
void setDays(int days) {
|
||||
this.days = days;
|
||||
}
|
||||
|
||||
void setPath (String path) {
|
||||
this.path = path;
|
||||
void setPath(String path) {
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
void setDomain (String domain) {
|
||||
this.domain = domain;
|
||||
void setDomain(String domain) {
|
||||
this.domain = domain;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getValue() {
|
||||
return value;
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public int getDays() {
|
||||
return days;
|
||||
return days;
|
||||
}
|
||||
|
||||
public String getPath () {
|
||||
return path;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
public String getDomain () {
|
||||
return domain;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getDomain() {
|
||||
return domain;
|
||||
}
|
||||
|
||||
public Cookie getCookie (String defaultPath, String defaultDomain) {
|
||||
Cookie c = new Cookie (name, value);
|
||||
if (days > 0)
|
||||
// Cookie time to live, days -> seconds
|
||||
c.setMaxAge (days*60*60*24);
|
||||
if (path != null)
|
||||
c.setPath (path);
|
||||
else if (defaultPath != null)
|
||||
c.setPath (defaultPath);
|
||||
if (domain != null)
|
||||
c.setDomain (domain);
|
||||
else if (defaultDomain != null)
|
||||
c.setDomain (defaultDomain);
|
||||
return c;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param defaultPath ...
|
||||
* @param defaultDomain ...
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public Cookie getCookie(String defaultPath, String defaultDomain) {
|
||||
Cookie c = new Cookie(name, value);
|
||||
|
||||
if (days > 0) {
|
||||
// Cookie time to live, days -> seconds
|
||||
c.setMaxAge(days * 60 * 60 * 24);
|
||||
}
|
||||
|
||||
if (path != null) {
|
||||
c.setPath(path);
|
||||
} else if (defaultPath != null) {
|
||||
c.setPath(defaultPath);
|
||||
}
|
||||
|
||||
if (domain != null) {
|
||||
c.setDomain(domain);
|
||||
} 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
|
||||
* The basic exception class used to tell when certain things go
|
||||
* wrong in evaluation of requests.
|
||||
*/
|
||||
|
||||
public class FrameworkException extends RuntimeException {
|
||||
|
||||
public FrameworkException (String msg) {
|
||||
super (msg);
|
||||
/**
|
||||
* Creates a new FrameworkException object.
|
||||
*
|
||||
* @param msg ...
|
||||
*/
|
||||
public FrameworkException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,6 +1,19 @@
|
|||
// 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,34 +27,26 @@ package helma.framework;
|
|||
* parent element. <p>
|
||||
*
|
||||
*/
|
||||
|
||||
public interface IPathElement {
|
||||
|
||||
/**
|
||||
* Return the name to be used to get this element from its parent
|
||||
*/
|
||||
public String getElementName ();
|
||||
public String getElementName();
|
||||
|
||||
/**
|
||||
* Retrieve a child element of this object by name.
|
||||
*/
|
||||
public IPathElement getChildElement (String name);
|
||||
public IPathElement getChildElement(String name);
|
||||
|
||||
/**
|
||||
* Return the parent element of this object.
|
||||
*/
|
||||
public IPathElement getParentElement ();
|
||||
|
||||
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 ();
|
||||
|
||||
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;
|
||||
|
||||
public ResponseTrans execute (RequestTrans param) throws RemoteException;
|
||||
|
||||
public void ping () 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;
|
||||
|
||||
public RedirectException (String url) {
|
||||
super ("Redirection Request to "+url);
|
||||
this.url = url;
|
||||
/**
|
||||
* Creates a new RedirectException object.
|
||||
*
|
||||
* @param url ...
|
||||
*/
|
||||
public RedirectException(String url) {
|
||||
super("Redirection Request to " + url);
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public String getMessage () {
|
||||
return url;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getMessage() {
|
||||
return url;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param s ...
|
||||
*/
|
||||
public void printStackTrace(java.io.PrintStream s) {
|
||||
// do nothing
|
||||
// do nothing
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param w ...
|
||||
*/
|
||||
public void printStackTrace(java.io.PrintWriter w) {
|
||||
// do nothing
|
||||
// do nothing
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,74 +1,138 @@
|
|||
/*
|
||||
* Helma License Notice
|
||||
*
|
||||
* The contents of this file are subject to the Helma License
|
||||
* Version 2.0 (the "License"). You may not use this file except in
|
||||
* compliance with the License. A copy of the License is available at
|
||||
* http://adele.helma.org/download/helma/license.txt
|
||||
*
|
||||
* Copyright 1998-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;
|
||||
|
||||
RequestTrans req;
|
||||
/**
|
||||
* Creates a new RequestBean object.
|
||||
*
|
||||
* @param req ...
|
||||
*/
|
||||
public RequestBean(RequestTrans req) {
|
||||
this.req = req;
|
||||
}
|
||||
|
||||
public RequestBean(RequestTrans req) {
|
||||
this.req = req;
|
||||
}
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param name ...
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public Object get(String name) {
|
||||
return req.get(name);
|
||||
}
|
||||
|
||||
public Object get (String name) {
|
||||
return req.get (name);
|
||||
}
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public boolean isGet() {
|
||||
return req.isGet();
|
||||
}
|
||||
|
||||
public boolean isGet () {
|
||||
return req.isGet ();
|
||||
}
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public boolean isPost() {
|
||||
return req.isPost();
|
||||
}
|
||||
|
||||
public boolean isPost () {
|
||||
return req.isPost ();
|
||||
}
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String toString() {
|
||||
return "[Request]";
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "[Request]";
|
||||
}
|
||||
// property related methods:
|
||||
public String getaction() {
|
||||
return req.action;
|
||||
}
|
||||
|
||||
// property related methods:
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public Map getdata() {
|
||||
return req.getRequestData();
|
||||
}
|
||||
|
||||
public String getaction () {
|
||||
return req.action;
|
||||
}
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public long getruntime() {
|
||||
return (System.currentTimeMillis() - req.startTime);
|
||||
}
|
||||
|
||||
public Map getdata () {
|
||||
return req.getRequestData ();
|
||||
}
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getpassword() {
|
||||
return req.getPassword();
|
||||
}
|
||||
|
||||
public long getruntime () {
|
||||
return (System.currentTimeMillis() - req.startTime);
|
||||
}
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getpath() {
|
||||
return req.path;
|
||||
}
|
||||
|
||||
public String getpassword () {
|
||||
return req.getPassword ();
|
||||
}
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getusername() {
|
||||
return req.getUsername();
|
||||
}
|
||||
|
||||
public String getpath () {
|
||||
return req.path;
|
||||
}
|
||||
|
||||
public String getusername () {
|
||||
return req.getUsername ();
|
||||
}
|
||||
|
||||
/* public Date getLastModified () {
|
||||
long since = req.getIfModifiedSince ();
|
||||
if (since < 0)
|
||||
return null;
|
||||
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.");
|
||||
} */
|
||||
/* public Date getLastModified () {
|
||||
long since = req.getIfModifiedSince ();
|
||||
if (since < 0)
|
||||
return null;
|
||||
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.
|
||||
* 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,185 +51,237 @@ 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.
|
||||
*/
|
||||
public RequestTrans () {
|
||||
httpMethod = 0;
|
||||
values = new HashMap ();
|
||||
public RequestTrans() {
|
||||
httpMethod = 0;
|
||||
values = new HashMap();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new request transmitter with the given data map.
|
||||
*/
|
||||
public RequestTrans (byte method) {
|
||||
httpMethod = method;
|
||||
values = new HashMap ();
|
||||
* Create a new request transmitter with the given data map.
|
||||
*/
|
||||
public RequestTrans(byte method) {
|
||||
httpMethod = method;
|
||||
values = new HashMap();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a parameter value in this request transmitter.
|
||||
*/
|
||||
public void set (String name, Object value) {
|
||||
values.put (name, value);
|
||||
public void set(String name, Object value) {
|
||||
values.put(name, value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a value from the requests map by key.
|
||||
*/
|
||||
public Object get (String name) {
|
||||
try {
|
||||
return values.get (name);
|
||||
} catch (Exception x) {
|
||||
return null;
|
||||
}
|
||||
public Object get(String name) {
|
||||
try {
|
||||
return values.get(name);
|
||||
} catch (Exception x) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the data map for this request transmitter.
|
||||
*/
|
||||
public Map getRequestData () {
|
||||
return values;
|
||||
public Map getRequestData() {
|
||||
return values;
|
||||
}
|
||||
|
||||
/**
|
||||
* The hash code is computed from the session id if available. This is used to
|
||||
* detect multiple identic requests.
|
||||
*/
|
||||
public int hashCode () {
|
||||
return session == null ? super.hashCode () : session.hashCode ();
|
||||
public int 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
|
||||
*/
|
||||
public boolean equals (Object what) {
|
||||
try {
|
||||
RequestTrans other = (RequestTrans) what;
|
||||
return (session.equals (other.session) &&
|
||||
path.equalsIgnoreCase (other.path) &&
|
||||
values.equals (other.getRequestData ()));
|
||||
} catch (Exception x) {
|
||||
return false;
|
||||
}
|
||||
public boolean equals(Object what) {
|
||||
try {
|
||||
RequestTrans other = (RequestTrans) what;
|
||||
|
||||
return (session.equals(other.session) && path.equalsIgnoreCase(other.path) &&
|
||||
values.equals(other.getRequestData()));
|
||||
} catch (Exception x) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if this object represents a HTTP GET Request.
|
||||
*/
|
||||
public boolean isGet () {
|
||||
return httpMethod == 0;
|
||||
public boolean isGet() {
|
||||
return httpMethod == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if this object represents a HTTP GET Request.
|
||||
*/
|
||||
public boolean isPost () {
|
||||
return httpMethod == 1;
|
||||
public boolean isPost() {
|
||||
return httpMethod == 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom externalization code for quicker serialization.
|
||||
*/
|
||||
public void readExternal (ObjectInput s) throws ClassNotFoundException, IOException {
|
||||
path = s.readUTF ();
|
||||
session = s.readUTF ();
|
||||
values = (Map) s.readObject ();
|
||||
httpMethod = s.readByte ();
|
||||
ifModifiedSince = s.readLong ();
|
||||
etags = (Set) s.readObject ();
|
||||
public void readExternal(ObjectInput s) throws ClassNotFoundException, IOException {
|
||||
path = s.readUTF();
|
||||
session = s.readUTF();
|
||||
values = (Map) s.readObject();
|
||||
httpMethod = s.readByte();
|
||||
ifModifiedSince = s.readLong();
|
||||
etags = (Set) s.readObject();
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom externalization code for quicker serialization.
|
||||
*/
|
||||
public void writeExternal (ObjectOutput s) throws IOException {
|
||||
s.writeUTF (path);
|
||||
s.writeUTF (session);
|
||||
s.writeObject (values);
|
||||
s.writeByte (httpMethod);
|
||||
s.writeLong (ifModifiedSince);
|
||||
s.writeObject (etags);
|
||||
public void writeExternal(ObjectOutput s) throws IOException {
|
||||
s.writeUTF(path);
|
||||
s.writeUTF(session);
|
||||
s.writeObject(values);
|
||||
s.writeByte(httpMethod);
|
||||
s.writeLong(ifModifiedSince);
|
||||
s.writeObject(etags);
|
||||
}
|
||||
|
||||
public void setIfModifiedSince (long since) {
|
||||
ifModifiedSince = since;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param since ...
|
||||
*/
|
||||
public void setIfModifiedSince(long since) {
|
||||
ifModifiedSince = since;
|
||||
}
|
||||
|
||||
public long getIfModifiedSince () {
|
||||
return ifModifiedSince;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public long getIfModifiedSince() {
|
||||
return ifModifiedSince;
|
||||
}
|
||||
|
||||
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 {
|
||||
etags.add (etagHeader);
|
||||
}
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @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 {
|
||||
etags.add(etagHeader);
|
||||
}
|
||||
}
|
||||
|
||||
public Set getETags () {
|
||||
return etags;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public Set getETags() {
|
||||
return etags;
|
||||
}
|
||||
|
||||
public boolean hasETag (String etag) {
|
||||
if (etags == null || etag == null)
|
||||
return false;
|
||||
return etags.contains (etag);
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param etag ...
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public boolean hasETag(String etag) {
|
||||
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);
|
||||
return httpUsername;
|
||||
if (httpUsername != null) {
|
||||
return httpUsername;
|
||||
}
|
||||
|
||||
String auth = (String) get("authorization");
|
||||
|
||||
if ((auth == null) || "".equals(auth)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
decodeHttpAuth(auth);
|
||||
|
||||
return httpUsername;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
if ( httpPassword!=null )
|
||||
return httpPassword;
|
||||
String auth = (String)get("authorization");
|
||||
if ( auth==null || "".equals(auth) ) {
|
||||
return null;
|
||||
}
|
||||
decodeHttpAuth(auth);
|
||||
return httpPassword;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @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 )
|
||||
return;
|
||||
StringTokenizer tok;
|
||||
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;
|
||||
}
|
||||
}
|
||||
private void decodeHttpAuth(String auth) {
|
||||
if (auth == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
StringTokenizer tok;
|
||||
|
||||
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,175 +1,386 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
public ResponseBean(ResponseTrans res) {
|
||||
this.res = res;
|
||||
/**
|
||||
* Creates a new ResponseBean object.
|
||||
*
|
||||
* @param res ...
|
||||
*/
|
||||
public ResponseBean(ResponseTrans res) {
|
||||
this.res = res;
|
||||
}
|
||||
|
||||
public void encode (Object what) {
|
||||
res.encode (what);
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param what ...
|
||||
*/
|
||||
public void encode(Object what) {
|
||||
res.encode(what);
|
||||
}
|
||||
|
||||
public void encodeXml (Object what) {
|
||||
res.encodeXml (what);
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param what ...
|
||||
*/
|
||||
public void encodeXml(Object what) {
|
||||
res.encodeXml(what);
|
||||
}
|
||||
|
||||
public void format (Object what) {
|
||||
res.format (what);
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param what ...
|
||||
*/
|
||||
public void format(Object what) {
|
||||
res.format(what);
|
||||
}
|
||||
|
||||
public void redirect (String url) throws RedirectException {
|
||||
res.redirect (url);
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param url ...
|
||||
*
|
||||
* @throws RedirectException ...
|
||||
*/
|
||||
public void redirect(String url) throws RedirectException {
|
||||
res.redirect(url);
|
||||
}
|
||||
|
||||
public void reset () {
|
||||
res.reset ();
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void reset() {
|
||||
res.reset();
|
||||
}
|
||||
|
||||
public void setCookie (String key, String value) {
|
||||
res.setCookie (key, value, -1, null, null);
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param key ...
|
||||
* @param value ...
|
||||
*/
|
||||
public void setCookie(String key, String value) {
|
||||
res.setCookie(key, value, -1, null, null);
|
||||
}
|
||||
|
||||
public void setCookie (String key, String value, int days) {
|
||||
res.setCookie (key, value, days, null, null);
|
||||
}
|
||||
|
||||
public void setCookie (String key, String value, int days, String path) {
|
||||
res.setCookie (key, value, days, path, null);
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param key ...
|
||||
* @param value ...
|
||||
* @param days ...
|
||||
*/
|
||||
public void setCookie(String key, String value, int days) {
|
||||
res.setCookie(key, value, days, null, null);
|
||||
}
|
||||
|
||||
public void setCookie (String key, String value, int days, String path, String domain) {
|
||||
res.setCookie (key, value, days, path, domain);
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @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);
|
||||
}
|
||||
|
||||
public void write (Object what) {
|
||||
res.write (what);
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @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);
|
||||
}
|
||||
|
||||
public void writeln (Object what) {
|
||||
res.writeln (what);
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param what ...
|
||||
*/
|
||||
public void write(Object what) {
|
||||
res.write(what);
|
||||
}
|
||||
|
||||
public void writeBinary (byte[] what) {
|
||||
res.writeBinary (what);
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param what ...
|
||||
*/
|
||||
public void writeln(Object what) {
|
||||
res.writeln(what);
|
||||
}
|
||||
|
||||
public void debug (Object message) {
|
||||
res.debug (message);
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @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]";
|
||||
return "[Response]";
|
||||
}
|
||||
|
||||
|
||||
// property-related methods:
|
||||
|
||||
public boolean getcache () {
|
||||
return res.cache;
|
||||
// property-related methods:
|
||||
public boolean getcache() {
|
||||
return res.cache;
|
||||
}
|
||||
|
||||
public void setcache (boolean cache) {
|
||||
res.cache = cache;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param cache ...
|
||||
*/
|
||||
public void setcache(boolean cache) {
|
||||
res.cache = cache;
|
||||
}
|
||||
|
||||
public String getcharset () {
|
||||
return res.charset;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getcharset() {
|
||||
return res.charset;
|
||||
}
|
||||
|
||||
public void setcharset (String charset) {
|
||||
res.charset = charset;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param charset ...
|
||||
*/
|
||||
public void setcharset(String charset) {
|
||||
res.charset = charset;
|
||||
}
|
||||
|
||||
public String getcontentType () {
|
||||
return res.contentType;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getcontentType() {
|
||||
return res.contentType;
|
||||
}
|
||||
|
||||
public void setcontentType (String contentType) {
|
||||
res.contentType = contentType;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param contentType ...
|
||||
*/
|
||||
public void setcontentType(String contentType) {
|
||||
res.contentType = contentType;
|
||||
}
|
||||
|
||||
public Map getdata () {
|
||||
return res.getResponseData ();
|
||||
}
|
||||
|
||||
public Map gethandlers () {
|
||||
return res.getMacroHandlers ();
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public Map getdata() {
|
||||
return res.getResponseData();
|
||||
}
|
||||
|
||||
public String geterror () {
|
||||
return res.error;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public Map gethandlers() {
|
||||
return res.getMacroHandlers();
|
||||
}
|
||||
|
||||
public String getmessage () {
|
||||
return res.message;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String geterror() {
|
||||
return res.error;
|
||||
}
|
||||
|
||||
public void setmessage (String message) {
|
||||
res.message = message;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getmessage() {
|
||||
return res.message;
|
||||
}
|
||||
|
||||
public String getrealm () {
|
||||
return res.realm;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param message ...
|
||||
*/
|
||||
public void setmessage(String message) {
|
||||
res.message = message;
|
||||
}
|
||||
|
||||
public void setrealm (String realm) {
|
||||
res.realm = realm;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getrealm() {
|
||||
return res.realm;
|
||||
}
|
||||
|
||||
public void setskinpath (Object[] arr) {
|
||||
res.setSkinpath (arr);
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param realm ...
|
||||
*/
|
||||
public void setrealm(String realm) {
|
||||
res.realm = realm;
|
||||
}
|
||||
|
||||
public Object[] getskinpath () {
|
||||
return res.getSkinpath ();
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param arr ...
|
||||
*/
|
||||
public void setskinpath(Object[] arr) {
|
||||
res.setSkinpath(arr);
|
||||
}
|
||||
|
||||
public int getstatus () {
|
||||
return res.status;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public Object[] getskinpath() {
|
||||
return res.getSkinpath();
|
||||
}
|
||||
|
||||
public void setstatus (int status) {
|
||||
res.status = status;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public int getstatus() {
|
||||
return res.status;
|
||||
}
|
||||
|
||||
public Date getLastModified () {
|
||||
long modified = res.getLastModified ();
|
||||
if (modified > -1)
|
||||
return new Date (modified);
|
||||
else
|
||||
return null;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param status ...
|
||||
*/
|
||||
public void setstatus(int status) {
|
||||
res.status = status;
|
||||
}
|
||||
|
||||
public void setLastModified (Date date) {
|
||||
if (date == null)
|
||||
res.setLastModified (-1);
|
||||
else
|
||||
res.setLastModified (date.getTime());
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public Date getLastModified() {
|
||||
long modified = res.getLastModified();
|
||||
|
||||
if (modified > -1) {
|
||||
return new Date(modified);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public String getETag () {
|
||||
return res.getETag ();
|
||||
}
|
||||
|
||||
public void setETag (String etag) {
|
||||
res.setETag (etag);
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param date ...
|
||||
*/
|
||||
public void setLastModified(Date date) {
|
||||
if (date == null) {
|
||||
res.setLastModified(-1);
|
||||
} else {
|
||||
res.setLastModified(date.getTime());
|
||||
}
|
||||
}
|
||||
|
||||
public void dependsOn (Object what) {
|
||||
res.dependsOn (what);
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getETag() {
|
||||
return res.getETag();
|
||||
}
|
||||
|
||||
public void digest () {
|
||||
res.digestDependencies ();
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @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 ();
|
||||
public void pushStringBuffer() {
|
||||
res.pushStringBuffer();
|
||||
}
|
||||
|
||||
public String popStringBuffer () {
|
||||
return res.popStringBuffer ();
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String popStringBuffer() {
|
||||
return res.popStringBuffer();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -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.
|
||||
* 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 {
|
||||
public TimeoutException () {
|
||||
super ("Request timed out");
|
||||
/**
|
||||
* Creates a new TimeoutException object.
|
||||
*/
|
||||
public TimeoutException() {
|
||||
super("Request timed out");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,37 +1,53 @@
|
|||
// 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;
|
||||
|
||||
/**
|
||||
* Create a HelmaClassLoader with the given application name and the given URLs
|
||||
*/
|
||||
/**
|
||||
* Create a HelmaClassLoader with the given application name and the given URLs
|
||||
*/
|
||||
public AppClassLoader(String appname, URL[] urls) {
|
||||
super ( urls, AppClassLoader.class.getClassLoader());
|
||||
this.appname = appname;
|
||||
super(urls, AppClassLoader.class.getClassLoader());
|
||||
this.appname = appname;
|
||||
}
|
||||
|
||||
protected void addURL (URL url) {
|
||||
super.addURL (url);
|
||||
protected void addURL(URL url) {
|
||||
super.addURL(url);
|
||||
}
|
||||
|
||||
public String getAppName () {
|
||||
return appname;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @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;
|
||||
this.app = app;
|
||||
}
|
||||
|
||||
public void clearCache () {
|
||||
app.clearCache ();
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void clearCache() {
|
||||
app.clearCache();
|
||||
}
|
||||
|
||||
public void log (Object msg) {
|
||||
String str = msg == null ? "null" : msg.toString();
|
||||
app.logEvent (str);
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param msg ...
|
||||
*/
|
||||
public void log(Object msg) {
|
||||
String str = (msg == null) ? "null" : msg.toString();
|
||||
|
||||
app.logEvent(str);
|
||||
}
|
||||
|
||||
public void log (String logname, Object msg) {
|
||||
String str = msg == null ? "null" : msg.toString();
|
||||
app.getLogger (logname).log (str);
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param logname ...
|
||||
* @param msg ...
|
||||
*/
|
||||
public void log(String logname, Object msg) {
|
||||
String str = (msg == null) ? "null" : msg.toString();
|
||||
|
||||
app.getLogger(logname).log(str);
|
||||
}
|
||||
|
||||
public void debug (Object msg) {
|
||||
if (app.debug()) {
|
||||
String str = msg == null ? "null" : msg.toString();
|
||||
app.logEvent (str);
|
||||
}
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param msg ...
|
||||
*/
|
||||
public void debug(Object msg) {
|
||||
if (app.debug()) {
|
||||
String str = (msg == null) ? "null" : msg.toString();
|
||||
|
||||
app.logEvent(str);
|
||||
}
|
||||
}
|
||||
|
||||
public void debug (String logname, Object msg) {
|
||||
if (app.debug()) {
|
||||
String str = msg == null ? "null" : msg.toString();
|
||||
app.getLogger (logname).log (str);
|
||||
}
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param logname ...
|
||||
* @param msg ...
|
||||
*/
|
||||
public void debug(String logname, Object msg) {
|
||||
if (app.debug()) {
|
||||
String str = (msg == null) ? "null" : msg.toString();
|
||||
|
||||
app.getLogger(logname).log(str);
|
||||
}
|
||||
}
|
||||
|
||||
public int countSessions () {
|
||||
return app.sessions.size();
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public int countSessions() {
|
||||
return app.sessions.size();
|
||||
}
|
||||
|
||||
public SessionBean getSession (String sessionID) {
|
||||
if (sessionID==null)
|
||||
return null;
|
||||
Session session = app.getSession (sessionID.trim ());
|
||||
if (session == null)
|
||||
return null;
|
||||
return new SessionBean (session);
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param sessionID ...
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public SessionBean getSession(String sessionID) {
|
||||
if (sessionID == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Session session = app.getSession(sessionID.trim());
|
||||
|
||||
if (session == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new SessionBean(session);
|
||||
}
|
||||
|
||||
public SessionBean createSession (String sessionID) {
|
||||
if (sessionID==null)
|
||||
return null;
|
||||
Session session = session = app.checkSession (sessionID.trim ());
|
||||
if (session == null)
|
||||
return null;
|
||||
return new SessionBean (session);
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param sessionID ...
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public SessionBean createSession(String sessionID) {
|
||||
if (sessionID == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Session session = session = app.checkSession(sessionID.trim());
|
||||
|
||||
if (session == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new SessionBean(session);
|
||||
}
|
||||
|
||||
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;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @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;
|
||||
}
|
||||
|
||||
public INode registerUser (String username, String password) {
|
||||
if (username==null || password==null || "".equals (username.trim ()) || "".equals (password.trim ()) )
|
||||
return null;
|
||||
else
|
||||
return app.registerUser (username, password);
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param username ...
|
||||
* @param password ...
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public INode registerUser(String username, String password) {
|
||||
if ((username == null) || (password == null) || "".equals(username.trim()) ||
|
||||
"".equals(password.trim())) {
|
||||
return null;
|
||||
} else {
|
||||
return app.registerUser(username, password);
|
||||
}
|
||||
}
|
||||
|
||||
public INode getUser (String username) {
|
||||
if (username==null || "".equals (username.trim()) )
|
||||
return null;
|
||||
return app.getUserNode (username);
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param username ...
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public INode getUser(String username) {
|
||||
if ((username == null) || "".equals(username.trim())) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return app.getUserNode(username);
|
||||
}
|
||||
|
||||
public INode[] getActiveUsers () {
|
||||
List activeUsers = app.getActiveUsers ();
|
||||
return (INode[]) activeUsers.toArray (new INode[0]);
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public INode[] getActiveUsers() {
|
||||
List activeUsers = app.getActiveUsers();
|
||||
|
||||
return (INode[]) activeUsers.toArray(new INode[0]);
|
||||
}
|
||||
|
||||
public INode[] getRegisteredUsers () {
|
||||
List registeredUsers = app.getRegisteredUsers ();
|
||||
return (INode[]) registeredUsers.toArray (new INode[0]);
|
||||
}
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public INode[] getRegisteredUsers() {
|
||||
List registeredUsers = app.getRegisteredUsers();
|
||||
|
||||
public SessionBean[] getSessionsForUser (INode usernode) {
|
||||
if (usernode==null)
|
||||
return new SessionBean[0];
|
||||
else
|
||||
return getSessionsForUser(usernode.getName());
|
||||
return (INode[]) registeredUsers.toArray(new INode[0]);
|
||||
}
|
||||
|
||||
public SessionBean[] getSessionsForUser (String username) {
|
||||
if (username==null || "".equals (username.trim ()) )
|
||||
return new SessionBean[0];
|
||||
List userSessions = app.getSessionsForUsername (username);
|
||||
return (SessionBean[]) userSessions.toArray (new SessionBean[0]);
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param usernode ...
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public SessionBean[] getSessionsForUser(INode usernode) {
|
||||
if (usernode == null) {
|
||||
return new SessionBean[0];
|
||||
} else {
|
||||
return getSessionsForUser(usernode.getName());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param username ...
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public SessionBean[] getSessionsForUser(String username) {
|
||||
if ((username == null) || "".equals(username.trim())) {
|
||||
return new SessionBean[0];
|
||||
}
|
||||
|
||||
List userSessions = app.getSessionsForUsername(username);
|
||||
|
||||
return (SessionBean[]) userSessions.toArray(new SessionBean[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @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 ();
|
||||
public int getcacheusage() {
|
||||
return app.getCacheUsage();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public INode getdata() {
|
||||
return app.getCacheNode ();
|
||||
return app.getCacheNode();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public Map getmodules() {
|
||||
return app.modules;
|
||||
return app.modules;
|
||||
}
|
||||
|
||||
public String getdir () {
|
||||
return app.getAppDir ().getAbsolutePath ();
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getdir() {
|
||||
return app.getAppDir().getAbsolutePath();
|
||||
}
|
||||
|
||||
public Date getupSince () {
|
||||
return new Date (app.starttime);
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getname() {
|
||||
return app.getName();
|
||||
}
|
||||
|
||||
public long getrequestCount () {
|
||||
return app.getRequestCount ();
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public Date getupSince() {
|
||||
return new Date(app.starttime);
|
||||
}
|
||||
|
||||
public long getxmlrpcCount () {
|
||||
return app.getXmlrpcCount ();
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public long getrequestCount() {
|
||||
return app.getRequestCount();
|
||||
}
|
||||
|
||||
public long geterrorCount () {
|
||||
return app.getErrorCount ();
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public long getxmlrpcCount() {
|
||||
return app.getXmlrpcCount();
|
||||
}
|
||||
|
||||
public Application get__app__ () {
|
||||
return app;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public long geterrorCount() {
|
||||
return app.getErrorCount();
|
||||
}
|
||||
|
||||
public Map getproperties () {
|
||||
return app.getProperties ();
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public Application get__app__() {
|
||||
return app;
|
||||
}
|
||||
|
||||
public int getfreeThreads () {
|
||||
return app.countFreeEvaluators ();
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public Map getproperties() {
|
||||
return app.getProperties();
|
||||
}
|
||||
|
||||
public int getactiveThreads () {
|
||||
return app.countActiveEvaluators ();
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public int getfreeThreads() {
|
||||
return app.countFreeEvaluators();
|
||||
}
|
||||
|
||||
public int getmaxThreads () {
|
||||
return app.countEvaluators ();
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public int getactiveThreads() {
|
||||
return app.countActiveEvaluators();
|
||||
}
|
||||
|
||||
public void setmaxThreads (int n) {
|
||||
// add one to the number to compensate for the internal scheduler.
|
||||
app.setNumberOfEvaluators (n+1);
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public int getmaxThreads() {
|
||||
return app.countEvaluators();
|
||||
}
|
||||
|
||||
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 n ...
|
||||
*/
|
||||
public void setmaxThreads(int n) {
|
||||
// add one to the number to compensate for the internal scheduler.
|
||||
app.setNumberOfEvaluators(n + 1);
|
||||
}
|
||||
|
||||
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 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;
|
||||
}
|
||||
|
||||
public String getAppDir () {
|
||||
return app.getAppDir().getAbsolutePath();
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @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;
|
||||
}
|
||||
|
||||
public String getServerDir () {
|
||||
File f = app.getServerDir();
|
||||
if (f == null)
|
||||
f = app.getAppDir();
|
||||
return f.getAbsolutePath();
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getAppDir() {
|
||||
return app.getAppDir().getAbsolutePath();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getServerDir() {
|
||||
File f = app.getServerDir();
|
||||
|
||||
if (f == null) {
|
||||
f = app.getAppDir();
|
||||
}
|
||||
|
||||
return f.getAbsolutePath();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String toString() {
|
||||
return "[Application " + app.getName() + "]";
|
||||
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,161 +30,195 @@ 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;
|
||||
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;
|
||||
|
||||
public Prototype (String name, File dir, Application app) {
|
||||
// app.logEvent ("Constructing Prototype "+app.getName()+"/"+name);
|
||||
this.app = app;
|
||||
this.name = name;
|
||||
this.directory = dir;
|
||||
/**
|
||||
* 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;
|
||||
this.name = name;
|
||||
this.directory = dir;
|
||||
|
||||
code = new HashMap ();
|
||||
zippedCode = new HashMap ();
|
||||
skins = new HashMap ();
|
||||
zippedSkins = new HashMap ();
|
||||
updatables = new HashMap ();
|
||||
code = new HashMap();
|
||||
zippedCode = new HashMap();
|
||||
skins = new HashMap();
|
||||
zippedSkins = new HashMap();
|
||||
updatables = new HashMap();
|
||||
|
||||
skinMap = new SkinMap ();
|
||||
skinMap = new SkinMap();
|
||||
|
||||
isJavaPrototype = app.isJavaPrototype (name);
|
||||
lastUpdate = lastChecksum = 0;
|
||||
isJavaPrototype = app.isJavaPrototype(name);
|
||||
lastUpdate = lastChecksum = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the application this prototype is a part of
|
||||
*/
|
||||
public Application getApplication () {
|
||||
return app;
|
||||
public Application getApplication() {
|
||||
return app;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return this prototype's directory.
|
||||
*/
|
||||
public File getDirectory () {
|
||||
return directory;
|
||||
public File getDirectory() {
|
||||
return directory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of files in this prototype's directory
|
||||
*/
|
||||
public File[] getFiles () {
|
||||
if (files == null || directory.lastModified() != lastDirectoryListing) {
|
||||
lastDirectoryListing = directory.lastModified ();
|
||||
files = directory.listFiles();
|
||||
if (files == null)
|
||||
files = new File[0];
|
||||
}
|
||||
return files;
|
||||
public File[] getFiles() {
|
||||
if ((files == null) || (directory.lastModified() != lastDirectoryListing)) {
|
||||
lastDirectoryListing = directory.lastModified();
|
||||
files = directory.listFiles();
|
||||
|
||||
if (files == null) {
|
||||
files = new File[0];
|
||||
}
|
||||
}
|
||||
|
||||
return files;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a checksum over the files in this prototype's directory
|
||||
*/
|
||||
public long getChecksum () {
|
||||
// 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;
|
||||
public long getChecksum() {
|
||||
// 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;
|
||||
}
|
||||
|
||||
public boolean isUpToDate () {
|
||||
return checksum == lastChecksum;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public boolean isUpToDate() {
|
||||
return checksum == lastChecksum;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the parent prototype of this prototype, i.e. the prototype this
|
||||
* prototype inherits from.
|
||||
*/
|
||||
public void setParentPrototype (Prototype parent) {
|
||||
// this is not allowed for the hopobject and global prototypes
|
||||
if ("hopobject".equalsIgnoreCase (name) || "global".equalsIgnoreCase (name))
|
||||
return;
|
||||
this.parent = parent;
|
||||
public void setParentPrototype(Prototype parent) {
|
||||
// this is not allowed for the hopobject and global prototypes
|
||||
if ("hopobject".equalsIgnoreCase(name) || "global".equalsIgnoreCase(name)) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the parent prototype from which we inherit, or null
|
||||
* if we are top of the line.
|
||||
*/
|
||||
public Prototype getParentPrototype () {
|
||||
return parent;
|
||||
public Prototype getParentPrototype() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if the given prototype is within this prototype's parent chain.
|
||||
*/
|
||||
public final boolean isInstanceOf (String pname) {
|
||||
if (name.equals (pname))
|
||||
return true;
|
||||
if (parent != null && !"hopobject".equalsIgnoreCase (parent.getName()))
|
||||
return parent.isInstanceOf (pname);
|
||||
return false;
|
||||
public final boolean isInstanceOf(String pname) {
|
||||
if (name.equals(pname)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((parent != null) && !"hopobject".equalsIgnoreCase(parent.getName())) {
|
||||
return parent.isInstanceOf(pname);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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()))
|
||||
parent.addToHandlerMap (handlers, obj);
|
||||
handlers.put (name, obj);
|
||||
public final void addToHandlerMap(Map handlers, Object obj) {
|
||||
if ((parent != null) && !"hopobject".equalsIgnoreCase(parent.getName())) {
|
||||
parent.addToHandlerMap(handlers, obj);
|
||||
}
|
||||
|
||||
handlers.put(name, obj);
|
||||
}
|
||||
|
||||
public void setDbMapping (DbMapping dbmap) {
|
||||
this.dbmap = dbmap;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param dbmap ...
|
||||
*/
|
||||
public void setDbMapping(DbMapping dbmap) {
|
||||
this.dbmap = dbmap;
|
||||
}
|
||||
|
||||
public DbMapping getDbMapping () {
|
||||
return 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
|
||||
* other locations or database stored skins.
|
||||
*/
|
||||
public SkinFile getSkinFile (String sfname) {
|
||||
SkinFile sf = (SkinFile) skins.get (sfname);
|
||||
if (sf == null)
|
||||
sf = (SkinFile) zippedSkins.get (sfname);
|
||||
return sf;
|
||||
public SkinFile getSkinFile(String sfname) {
|
||||
SkinFile sf = (SkinFile) skins.get(sfname);
|
||||
|
||||
if (sf == null) {
|
||||
sf = (SkinFile) zippedSkins.get(sfname);
|
||||
}
|
||||
|
||||
return sf;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -180,25 +226,30 @@ public final class Prototype {
|
|||
* residing in the prototype directory, not for skins files in
|
||||
* other locations or database stored skins.
|
||||
*/
|
||||
public Skin getSkin (String sfname) {
|
||||
SkinFile sf = getSkinFile (sfname);
|
||||
if (sf != null)
|
||||
return sf.getSkin ();
|
||||
else
|
||||
return null;
|
||||
public Skin getSkin(String sfname) {
|
||||
SkinFile sf = getSkinFile(sfname);
|
||||
|
||||
if (sf != null) {
|
||||
return sf.getSkin();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public String getName () {
|
||||
return name;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the last time any script has been re-read for this prototype.
|
||||
*/
|
||||
public long getLastUpdate () {
|
||||
return lastUpdate;
|
||||
public long getLastUpdate() {
|
||||
return lastUpdate;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -206,35 +257,35 @@ public final class Prototype {
|
|||
* re-read from disk and needs to be re-compiled by
|
||||
* the evaluators.
|
||||
*/
|
||||
public void markUpdated () {
|
||||
lastUpdate = System.currentTimeMillis ();
|
||||
public void markUpdated() {
|
||||
lastUpdate = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the time at which this prototype's scripts were checked
|
||||
* for changes for the last time.
|
||||
*/
|
||||
|
||||
/* public long getLastCheck () {
|
||||
return lastCheck;
|
||||
} */
|
||||
return lastCheck;
|
||||
} */
|
||||
|
||||
/**
|
||||
* Signal that the prototype's scripts have been checked for
|
||||
* changes.
|
||||
*/
|
||||
public void markChecked () {
|
||||
// lastCheck = System.currentTimeMillis ();
|
||||
lastChecksum = checksum;
|
||||
public void markChecked() {
|
||||
// lastCheck = System.currentTimeMillis ();
|
||||
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
|
||||
* updated by the type manager.
|
||||
*/
|
||||
public synchronized Map getCode () {
|
||||
return (Map) code.clone();
|
||||
public synchronized Map getCode() {
|
||||
return (Map) code.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -242,232 +293,304 @@ public final class Prototype {
|
|||
* to not return a map in a transient state where it is just being
|
||||
* updated by the type manager.
|
||||
*/
|
||||
public synchronized Map getZippedCode () {
|
||||
return (Map) zippedCode.clone();
|
||||
public synchronized Map getZippedCode() {
|
||||
return (Map) zippedCode.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param action ...
|
||||
*/
|
||||
public synchronized void addActionFile(ActionFile action) {
|
||||
File f = action.getFile();
|
||||
|
||||
public synchronized void addActionFile (ActionFile action) {
|
||||
File f = action.getFile ();
|
||||
if (f != null) {
|
||||
code.put (action.getSourceName(), action);
|
||||
updatables.put (f.getName(), action);
|
||||
} else {
|
||||
zippedCode.put (action.getSourceName(), action);
|
||||
}
|
||||
if (f != null) {
|
||||
code.put(action.getSourceName(), action);
|
||||
updatables.put(f.getName(), action);
|
||||
} else {
|
||||
zippedCode.put(action.getSourceName(), action);
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void addTemplate (Template template) {
|
||||
File f = template.getFile ();
|
||||
if (f != null) {
|
||||
code.put (template.getSourceName(), template);
|
||||
updatables.put (f.getName(), template);
|
||||
} else {
|
||||
zippedCode.put (template.getSourceName(), template);
|
||||
}
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @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);
|
||||
} else {
|
||||
zippedCode.put(template.getSourceName(), template);
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void addFunctionFile (FunctionFile funcfile) {
|
||||
File f = funcfile.getFile ();
|
||||
if (f != null) {
|
||||
code.put (funcfile.getSourceName(), funcfile);
|
||||
updatables.put (f.getName(), funcfile);
|
||||
} else {
|
||||
zippedCode.put (funcfile.getSourceName(), funcfile);
|
||||
}
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @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);
|
||||
} else {
|
||||
zippedCode.put(funcfile.getSourceName(), funcfile);
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void addSkinFile (SkinFile skinfile) {
|
||||
File f = skinfile.getFile ();
|
||||
if (f != null) {
|
||||
skins.put (skinfile.getName(), skinfile);
|
||||
updatables.put (f.getName(), skinfile);
|
||||
} else {
|
||||
zippedSkins.put (skinfile.getName(), skinfile);
|
||||
}
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @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);
|
||||
} else {
|
||||
zippedSkins.put(skinfile.getName(), skinfile);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param action ...
|
||||
*/
|
||||
public synchronized void removeActionFile(ActionFile action) {
|
||||
File f = action.getFile();
|
||||
|
||||
public synchronized void removeActionFile (ActionFile action) {
|
||||
File f = action.getFile ();
|
||||
if (f != null) {
|
||||
code.remove (action.getSourceName());
|
||||
updatables.remove (f.getName());
|
||||
} else {
|
||||
zippedCode.remove (action.getSourceName());
|
||||
}
|
||||
if (f != null) {
|
||||
code.remove(action.getSourceName());
|
||||
updatables.remove(f.getName());
|
||||
} else {
|
||||
zippedCode.remove(action.getSourceName());
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void removeFunctionFile (FunctionFile funcfile) {
|
||||
File f = funcfile.getFile ();
|
||||
if (f != null) {
|
||||
code.remove (funcfile.getSourceName());
|
||||
updatables.remove (f.getName());
|
||||
} else {
|
||||
zippedCode.remove (funcfile.getSourceName());
|
||||
}
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param funcfile ...
|
||||
*/
|
||||
public synchronized void removeFunctionFile(FunctionFile funcfile) {
|
||||
File f = funcfile.getFile();
|
||||
|
||||
if (f != null) {
|
||||
code.remove(funcfile.getSourceName());
|
||||
updatables.remove(f.getName());
|
||||
} else {
|
||||
zippedCode.remove(funcfile.getSourceName());
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void removeTemplate (Template template) {
|
||||
File f = template.getFile ();
|
||||
if (f != null) {
|
||||
code.remove (template.getSourceName());
|
||||
updatables.remove (f.getName());
|
||||
} else {
|
||||
zippedCode.remove (template.getSourceName());
|
||||
}
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param template ...
|
||||
*/
|
||||
public synchronized void removeTemplate(Template template) {
|
||||
File f = template.getFile();
|
||||
|
||||
if (f != null) {
|
||||
code.remove(template.getSourceName());
|
||||
updatables.remove(f.getName());
|
||||
} else {
|
||||
zippedCode.remove(template.getSourceName());
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void removeSkinFile (SkinFile skinfile) {
|
||||
File f = skinfile.getFile ();
|
||||
if (f != null) {
|
||||
skins.remove (skinfile.getName());
|
||||
updatables.remove (f.getName());
|
||||
} else {
|
||||
zippedSkins.remove (skinfile.getName());
|
||||
}
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param skinfile ...
|
||||
*/
|
||||
public synchronized void removeSkinFile(SkinFile skinfile) {
|
||||
File f = skinfile.getFile();
|
||||
|
||||
if (f != null) {
|
||||
skins.remove(skinfile.getName());
|
||||
updatables.remove(f.getName());
|
||||
} else {
|
||||
zippedSkins.remove(skinfile.getName());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return a string representing this prototype.
|
||||
*/
|
||||
public String toString () {
|
||||
return "[Prototype "+ app.getName()+"/"+name+"]";
|
||||
/**
|
||||
* Return a string representing this prototype.
|
||||
*/
|
||||
public String toString() {
|
||||
return "[Prototype " + app.getName() + "/" + name + "]";
|
||||
}
|
||||
|
||||
|
||||
public SkinMap getSkinMap () {
|
||||
return skinMap;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public SkinMap getSkinMap() {
|
||||
return skinMap;
|
||||
}
|
||||
|
||||
// not yet implemented
|
||||
public SkinMap getSkinMap (Object[] skinpath) {
|
||||
return new SkinMap (skinpath);
|
||||
public SkinMap getSkinMap(Object[] skinpath) {
|
||||
return new SkinMap(skinpath);
|
||||
}
|
||||
|
||||
// a map that dynamically expands to all skins in this prototype
|
||||
final class SkinMap extends HashMap {
|
||||
long lastSkinmapLoad = 0;
|
||||
Object[] skinpath;
|
||||
|
||||
long lastSkinmapLoad = 0;
|
||||
SkinMap() {
|
||||
super();
|
||||
skinpath = null;
|
||||
}
|
||||
|
||||
Object[] skinpath;
|
||||
SkinMap(Object[] path) {
|
||||
super();
|
||||
skinpath = path;
|
||||
}
|
||||
|
||||
SkinMap () {
|
||||
super ();
|
||||
skinpath = null;
|
||||
}
|
||||
public boolean containsKey(Object key) {
|
||||
checkForUpdates();
|
||||
|
||||
SkinMap (Object[] path) {
|
||||
super ();
|
||||
skinpath = path;
|
||||
}
|
||||
return super.containsKey(key);
|
||||
}
|
||||
|
||||
public boolean containsKey (Object key) {
|
||||
checkForUpdates ();
|
||||
return super.containsKey (key);
|
||||
}
|
||||
public boolean containsValue(Object value) {
|
||||
checkForUpdates();
|
||||
|
||||
public boolean containsValue (Object value) {
|
||||
checkForUpdates ();
|
||||
return super.containsValue (value);
|
||||
}
|
||||
return super.containsValue(value);
|
||||
}
|
||||
|
||||
public Set entrySet () {
|
||||
checkForUpdates ();
|
||||
return super.entrySet ();
|
||||
}
|
||||
public Set entrySet() {
|
||||
checkForUpdates();
|
||||
|
||||
public boolean equals (Object obj) {
|
||||
checkForUpdates ();
|
||||
return super.equals (obj);
|
||||
}
|
||||
return super.entrySet();
|
||||
}
|
||||
|
||||
public Object get (Object key) {
|
||||
if (key == null)
|
||||
return null;
|
||||
checkForUpdates ();
|
||||
SkinFile sf = (SkinFile) super.get (key);
|
||||
if (sf == null)
|
||||
return null;
|
||||
return sf.getSkin().getSource ();
|
||||
}
|
||||
public boolean equals(Object obj) {
|
||||
checkForUpdates();
|
||||
|
||||
public int hashCode () {
|
||||
checkForUpdates ();
|
||||
return super.hashCode ();
|
||||
}
|
||||
return super.equals(obj);
|
||||
}
|
||||
|
||||
public boolean isEmpty () {
|
||||
checkForUpdates ();
|
||||
return super.isEmpty ();
|
||||
}
|
||||
public Object get(Object key) {
|
||||
if (key == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Set keySet () {
|
||||
checkForUpdates ();
|
||||
return super.keySet ();
|
||||
}
|
||||
checkForUpdates();
|
||||
|
||||
public Object put (Object key, Object value) {
|
||||
// checkForUpdates ();
|
||||
return super.put (key, value);
|
||||
}
|
||||
SkinFile sf = (SkinFile) super.get(key);
|
||||
|
||||
public void putAll (Map t) {
|
||||
// checkForUpdates ();
|
||||
super.putAll (t);
|
||||
}
|
||||
if (sf == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Object remove (Object key) {
|
||||
checkForUpdates ();
|
||||
return super.remove (key);
|
||||
}
|
||||
return sf.getSkin().getSource();
|
||||
}
|
||||
|
||||
public int size () {
|
||||
checkForUpdates ();
|
||||
return super.size ();
|
||||
}
|
||||
public int hashCode() {
|
||||
checkForUpdates();
|
||||
|
||||
public Collection values () {
|
||||
checkForUpdates ();
|
||||
return super.values ();
|
||||
}
|
||||
return super.hashCode();
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
checkForUpdates();
|
||||
|
||||
private void checkForUpdates () {
|
||||
if (/* lastCheck < System.currentTimeMillis()- 2000l*/ !isUpToDate())
|
||||
app.typemgr.updatePrototype (Prototype.this);
|
||||
if (lastUpdate > lastSkinmapLoad)
|
||||
load ();
|
||||
}
|
||||
return super.isEmpty();
|
||||
}
|
||||
|
||||
private synchronized void load () {
|
||||
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)
|
||||
super.putAll (m);
|
||||
}
|
||||
}
|
||||
}
|
||||
lastSkinmapLoad = lastUpdate;
|
||||
}
|
||||
|
||||
public String toString () {
|
||||
return "[SkinMap "+name+"]";
|
||||
}
|
||||
public Set keySet() {
|
||||
checkForUpdates();
|
||||
|
||||
return super.keySet();
|
||||
}
|
||||
|
||||
public Object put(Object key, Object value) {
|
||||
// checkForUpdates ();
|
||||
return super.put(key, value);
|
||||
}
|
||||
|
||||
public void putAll(Map t) {
|
||||
// checkForUpdates ();
|
||||
super.putAll(t);
|
||||
}
|
||||
|
||||
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()) {
|
||||
app.typemgr.updatePrototype(Prototype.this);
|
||||
}
|
||||
|
||||
if (lastUpdate > lastSkinmapLoad) {
|
||||
load();
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized void load() {
|
||||
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) {
|
||||
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,43 +25,45 @@ 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;
|
||||
|
||||
|
||||
public RemoteApplication (Application app) throws RemoteException {
|
||||
this.app = 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
|
||||
*/
|
||||
public void ping () {
|
||||
// do nothing
|
||||
public void ping() {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a request coming in from a web client.
|
||||
*/
|
||||
public ResponseTrans execute (RequestTrans req) {
|
||||
return app.execute (req);
|
||||
public ResponseTrans execute(RequestTrans req) {
|
||||
return app.execute(req);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Update HopObjects in this application's cache. This is used to replicate
|
||||
* application caches in a distributed app environment
|
||||
*/
|
||||
public void replicateCache (Vector add, Vector delete) {
|
||||
if (!"true".equalsIgnoreCase (app.getProperty ("allowReplication"))) {
|
||||
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);
|
||||
public void replicateCache(Vector add, Vector delete) {
|
||||
if (!"true".equalsIgnoreCase(app.getProperty("allowReplication"))) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -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,118 +41,175 @@ 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;
|
||||
|
||||
public Session (String sessionID, Application app) {
|
||||
this.sessionID = sessionID;
|
||||
this.app = app;
|
||||
this.uid = null;
|
||||
this.userHandle = null;
|
||||
cacheNode = new TransientNode ("session");
|
||||
onSince = System.currentTimeMillis ();
|
||||
lastTouched = lastModified = onSince;
|
||||
/**
|
||||
* Creates a new Session object.
|
||||
*
|
||||
* @param sessionID ...
|
||||
* @param app ...
|
||||
*/
|
||||
public Session(String sessionID, Application app) {
|
||||
this.sessionID = sessionID;
|
||||
this.app = app;
|
||||
this.uid = null;
|
||||
this.userHandle = null;
|
||||
cacheNode = new TransientNode("session");
|
||||
onSince = System.currentTimeMillis();
|
||||
lastTouched = lastModified = onSince;
|
||||
}
|
||||
|
||||
/**
|
||||
* attach the given user node to this session.
|
||||
*/
|
||||
public void login (INode usernode) {
|
||||
if (usernode==null) {
|
||||
userHandle = null;
|
||||
uid = null;
|
||||
} else {
|
||||
userHandle = ((Node)usernode).getHandle();
|
||||
uid = usernode.getElementName();
|
||||
}
|
||||
lastModified = System.currentTimeMillis ();
|
||||
public void login(INode usernode) {
|
||||
if (usernode == null) {
|
||||
userHandle = null;
|
||||
uid = null;
|
||||
} else {
|
||||
userHandle = ((Node) usernode).getHandle();
|
||||
uid = usernode.getElementName();
|
||||
}
|
||||
|
||||
lastModified = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
/**
|
||||
* remove this sessions's user node.
|
||||
*/
|
||||
public void logout() {
|
||||
userHandle = null;
|
||||
uid = null;
|
||||
lastModified = System.currentTimeMillis ();
|
||||
userHandle = null;
|
||||
uid = null;
|
||||
lastModified = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public boolean isLoggedIn() {
|
||||
if (userHandle!=null && uid!=null) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
if ((userHandle != null) && (uid != null)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the user Node from this Application's NodeManager.
|
||||
*/
|
||||
public INode getUserNode() {
|
||||
if (userHandle!=null)
|
||||
return userHandle.getNode (app.getWrappedNodeManager());
|
||||
else
|
||||
return null;
|
||||
if (userHandle != null) {
|
||||
return userHandle.getNode(app.getWrappedNodeManager());
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the transient cache node.
|
||||
*/
|
||||
public INode getCacheNode () {
|
||||
return cacheNode;
|
||||
public INode getCacheNode() {
|
||||
return cacheNode;
|
||||
}
|
||||
|
||||
public Application getApp () {
|
||||
return app;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public Application getApp() {
|
||||
return app;
|
||||
}
|
||||
|
||||
public void setApp (Application app) {
|
||||
this.app = app;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param app ...
|
||||
*/
|
||||
public void setApp(Application app) {
|
||||
this.app = app;
|
||||
}
|
||||
|
||||
public String getSessionID () {
|
||||
return sessionID;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getSessionID() {
|
||||
return sessionID;
|
||||
}
|
||||
|
||||
public void touch () {
|
||||
lastTouched = System.currentTimeMillis ();
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void touch() {
|
||||
lastTouched = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
public long lastTouched () {
|
||||
return lastTouched;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public long lastTouched() {
|
||||
return lastTouched;
|
||||
}
|
||||
|
||||
public long lastModified () {
|
||||
return lastModified;
|
||||
}
|
||||
|
||||
public void setLastModified (Date date) {
|
||||
if (date != null)
|
||||
lastModified = date.getTime ();
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public long lastModified() {
|
||||
return lastModified;
|
||||
}
|
||||
|
||||
public long onSince () {
|
||||
return onSince;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param date ...
|
||||
*/
|
||||
public void setLastModified(Date date) {
|
||||
if (date != null) {
|
||||
lastModified = date.getTime();
|
||||
}
|
||||
}
|
||||
|
||||
public String toString () {
|
||||
if ( uid!=null )
|
||||
return "[Session for user " + uid + "]";
|
||||
else
|
||||
return "[Anonymous Session]";
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public long onSince() {
|
||||
return onSince;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String toString() {
|
||||
if (uid != null) {
|
||||
return "[Session for user " + uid + "]";
|
||||
} else {
|
||||
return "[Anonymous Session]";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the persistent user id of a registered user. This is usually the user name, or
|
||||
* null if the user is not logged in.
|
||||
*/
|
||||
public String getUID () {
|
||||
return uid;
|
||||
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;
|
||||
|
||||
public SessionBean(Session session) {
|
||||
this.session = session;
|
||||
/**
|
||||
* Creates a new SessionBean object.
|
||||
*
|
||||
* @param session ...
|
||||
*/
|
||||
public SessionBean(Session session) {
|
||||
this.session = session;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return session.toString ();
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String toString() {
|
||||
return session.toString();
|
||||
}
|
||||
|
||||
public boolean login (String username, String password) {
|
||||
boolean success = session.getApp().loginSession (username, password, session);
|
||||
return success;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @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 logout() {
|
||||
session.getApp().logoutSession(session);
|
||||
}
|
||||
|
||||
public void touch () {
|
||||
session.touch ();
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void touch() {
|
||||
session.touch();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public Date lastActive() {
|
||||
return new Date (session.lastTouched ());
|
||||
return new Date(session.lastTouched());
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public Date onSince() {
|
||||
return new Date (session.onSince ());
|
||||
return new Date(session.onSince());
|
||||
}
|
||||
|
||||
// property-related methods:
|
||||
|
||||
public INode getdata() {
|
||||
return session.getCacheNode ();
|
||||
return session.getCacheNode();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public INode getuser() {
|
||||
return session.getUserNode();
|
||||
return session.getUserNode();
|
||||
}
|
||||
|
||||
public String get_id () {
|
||||
return session.getSessionID ();
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String get_id() {
|
||||
return session.getSessionID();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getcookie() {
|
||||
return session.getSessionID ();
|
||||
return session.getSessionID();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public Date getlastActive() {
|
||||
return new Date (session.lastTouched ());
|
||||
return new Date(session.lastTouched());
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public Date getonSince() {
|
||||
return new Date (session.onSince ());
|
||||
}
|
||||
|
||||
public Date getLastModified () {
|
||||
return new Date (session.lastModified ());
|
||||
return new Date(session.onSince());
|
||||
}
|
||||
|
||||
public void setLastModified (Date date) {
|
||||
session.setLastModified (date);
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public Date getLastModified() {
|
||||
return new Date(session.lastModified());
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param date ...
|
||||
*/
|
||||
public void setLastModified(Date date) {
|
||||
session.setLastModified(date);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -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,12 +31,19 @@ public final class SkinFile implements Updatable {
|
|||
Skin skin;
|
||||
long lastmod = 0;
|
||||
|
||||
public SkinFile (File file, String name, Prototype proto) {
|
||||
this.prototype = proto;
|
||||
this.file = file;
|
||||
this.name = name;
|
||||
this.app = proto.app;
|
||||
skin = null;
|
||||
/**
|
||||
* 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;
|
||||
this.name = name;
|
||||
this.app = proto.app;
|
||||
skin = null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -35,88 +51,113 @@ public final class SkinFile implements Updatable {
|
|||
* Skins contained in zipped applications. The whole update mechanism is bypassed
|
||||
* by immediately setting the skin member.
|
||||
*/
|
||||
public SkinFile (String body, String name, Prototype proto) {
|
||||
this.prototype = proto;
|
||||
this.app = proto.app;
|
||||
this.name = name;
|
||||
this.file = null;
|
||||
skin = new Skin (body, app);
|
||||
public SkinFile(String body, String name, Prototype proto) {
|
||||
this.prototype = proto;
|
||||
this.app = proto.app;
|
||||
this.name = name;
|
||||
this.file = null;
|
||||
skin = new Skin(body, app);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a skinfile that doesn't belong to a prototype, or at
|
||||
* least it doesn't know about its prototype and isn't managed by the prototype.
|
||||
*/
|
||||
public SkinFile (File file, String name, Application app) {
|
||||
this.app = app;
|
||||
this.file = file;
|
||||
this.name = name;
|
||||
this.prototype = null;
|
||||
skin = null;
|
||||
public SkinFile(File file, String name, Application app) {
|
||||
this.app = app;
|
||||
this.file = file;
|
||||
this.name = name;
|
||||
this.prototype = null;
|
||||
skin = null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
/**
|
||||
* Tell the type manager whether we need an update. this is the case when
|
||||
* the file has been modified or deleted.
|
||||
*/
|
||||
public boolean needsUpdate () {
|
||||
// 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 ();
|
||||
public boolean needsUpdate() {
|
||||
// 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());
|
||||
}
|
||||
|
||||
|
||||
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)
|
||||
read ();
|
||||
}
|
||||
/**
|
||||
*
|
||||
*/
|
||||
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) {
|
||||
read();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void read () {
|
||||
try {
|
||||
FileReader reader = new FileReader (file);
|
||||
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 ();
|
||||
private void read() {
|
||||
try {
|
||||
FileReader reader = new FileReader(file);
|
||||
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);
|
||||
}
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void remove() {
|
||||
if (prototype != null) {
|
||||
prototype.removeSkinFile(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public File getFile () {
|
||||
return file;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public File getFile() {
|
||||
return file;
|
||||
}
|
||||
|
||||
public Skin getSkin () {
|
||||
if (skin == null)
|
||||
read ();
|
||||
return skin;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public Skin getSkin() {
|
||||
if (skin == null) {
|
||||
read();
|
||||
}
|
||||
|
||||
return skin;
|
||||
}
|
||||
|
||||
public String getName () {
|
||||
return name;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String toString () {
|
||||
return prototype.getName()+"/"+file.getName();
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String toString() {
|
||||
return prototype.getName() + "/" + file.getName();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,107 +1,140 @@
|
|||
// 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;
|
||||
|
||||
public SkinManager (Application app) {
|
||||
this.app = 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) {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected Skin getSkin (Prototype proto, String skinname, Object[] skinpath) {
|
||||
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;
|
||||
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)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected Skin getSkinInternal (Object skinset, String prototype, String skinname) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 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;
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 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);
|
||||
|
||||
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)
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Implements java.io.FilenameFilter.accept()
|
||||
*/
|
||||
public boolean accept (File d, String n) {
|
||||
return n.endsWith (".skin");
|
||||
public boolean accept(File d, String n) {
|
||||
return n.endsWith(".skin");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,230 +1,300 @@
|
|||
// 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;
|
||||
|
||||
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
|
||||
* 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
|
||||
HashMap zipfiles; // map of zipped script files
|
||||
HashSet jarfiles; // set of Java archives
|
||||
HashMap prototypes; // map of prototypes
|
||||
HashMap zipfiles; // map of zipped script files
|
||||
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";
|
||||
|
||||
public TypeManager (Application app) throws MalformedURLException {
|
||||
/**
|
||||
* 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.");
|
||||
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.");
|
||||
}
|
||||
}
|
||||
}
|
||||
prototypes = new HashMap ();
|
||||
zipfiles = new HashMap ();
|
||||
jarfiles = new HashSet ();
|
||||
|
||||
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++) {
|
||||
|
||||
for (int i = 0; i < urls.length; i++) {
|
||||
String url = urls[i].toString().toLowerCase();
|
||||
if (url.endsWith ("helma.jar")) {
|
||||
|
||||
if (url.endsWith("helma.jar")) {
|
||||
helmajar = urls[i];
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (helmajar == null)
|
||||
throw new RuntimeException ("helma.jar not found in embedding classpath");
|
||||
|
||||
if (helmajar == null) {
|
||||
throw new RuntimeException("helma.jar not found in embedding classpath");
|
||||
}
|
||||
|
||||
loader = new AppClassLoader(app.getName(), new URL[] { helmajar });
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Run through application's prototype directories and create prototypes, but don't
|
||||
* compile or evaluate any scripts.
|
||||
*/
|
||||
public void createPrototypes () {
|
||||
public void createPrototypes() {
|
||||
// create standard prototypes.
|
||||
createPrototype ("root");
|
||||
createPrototype ("user");
|
||||
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 ();
|
||||
}
|
||||
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)
|
||||
return;
|
||||
try {
|
||||
checkFiles ();
|
||||
} catch (Exception ignore) {}
|
||||
lastCheck = System.currentTimeMillis ();
|
||||
public synchronized void checkPrototypes() {
|
||||
if ((System.currentTimeMillis() - lastCheck) < 1000L) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
checkFiles();
|
||||
} catch (Exception ignore) {
|
||||
}
|
||||
|
||||
lastCheck = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Run through application's prototype directories and check if
|
||||
* there are any prototypes to be created.
|
||||
*/
|
||||
public void checkFiles () {
|
||||
// check if any files have been created/removed since last time we
|
||||
// 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");
|
||||
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) {}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (list[i].indexOf ('.') > -1)
|
||||
continue;
|
||||
Prototype proto = getPrototype (list[i]);
|
||||
// if prototype doesn't exist, create it
|
||||
if (proto == null && isValidTypeName (list[i])) {
|
||||
File f = new File (appDir, list[i]);
|
||||
if (f.isDirectory ()) {
|
||||
// create new prototype
|
||||
createPrototype (list[i], f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public void checkFiles() {
|
||||
// check if any files have been created/removed since last time we
|
||||
// checked...
|
||||
if (appDir.lastModified() > appDirMod) {
|
||||
appDirMod = appDir.lastModified();
|
||||
|
||||
// calculate this app's checksum by adding all checksums from all prototypes
|
||||
long newChecksum = 0;
|
||||
String[] list = appDir.list();
|
||||
|
||||
// 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;
|
||||
}
|
||||
if (list == null) {
|
||||
throw new RuntimeException("Can't read app directory " + appDir +
|
||||
" - check permissions");
|
||||
}
|
||||
|
||||
// loop through prototypes and check if type.properties needs updates
|
||||
// it's important that we do this _after_ potentially new prototypes
|
||||
// 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 ()) {
|
||||
dbmap.update ();
|
||||
if (proto != hopobjectProto && proto != globalProto) {
|
||||
// set parent prototype, in case it has changed.
|
||||
String parentName = dbmap.getExtends ();
|
||||
if (parentName != null)
|
||||
proto.setParentPrototype (getPrototype (parentName));
|
||||
else if (!app.isJavaPrototype (proto.getName()))
|
||||
proto.setParentPrototype (hopobjectProto);
|
||||
}
|
||||
}
|
||||
}
|
||||
checksum = newChecksum;
|
||||
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) {
|
||||
}
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (list[i].indexOf('.') > -1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Prototype proto = getPrototype(list[i]);
|
||||
|
||||
// if prototype doesn't exist, create it
|
||||
if ((proto == null) && isValidTypeName(list[i])) {
|
||||
File f = new File(appDir, list[i]);
|
||||
|
||||
if (f.isDirectory()) {
|
||||
// create new prototype
|
||||
createPrototype(list[i], f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// calculate this app's checksum by adding all checksums from all prototypes
|
||||
long newChecksum = 0;
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
// loop through prototypes and check if type.properties needs updates
|
||||
// it's important that we do this _after_ potentially new prototypes
|
||||
// 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()) {
|
||||
dbmap.update();
|
||||
|
||||
if ((proto != hopobjectProto) && (proto != globalProto)) {
|
||||
// set parent prototype, in case it has changed.
|
||||
String parentName = dbmap.getExtends();
|
||||
|
||||
if (parentName != null) {
|
||||
proto.setParentPrototype(getPrototype(parentName));
|
||||
} 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);
|
||||
}
|
||||
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) {
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isValidTypeName (String str) {
|
||||
if (str == null)
|
||||
return false;
|
||||
char[] c = str.toCharArray ();
|
||||
for (int i=0; i<c.length; i++)
|
||||
if (!Character.isJavaIdentifierPart (c[i]))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
char[] c = str.toCharArray();
|
||||
|
||||
/**
|
||||
* Return a checksum over all files in all prototypes in this application.
|
||||
* The checksum can be used to find out quickly if any file has changed.
|
||||
*/
|
||||
public long getChecksum () {
|
||||
return checksum;
|
||||
for (int i = 0; i < c.length; i++)
|
||||
if (!Character.isJavaIdentifierPart(c[i])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a prototype defined for this application
|
||||
*/
|
||||
public Prototype getPrototype (String typename) {
|
||||
return (Prototype) prototypes.get (typename);
|
||||
* Return a checksum over all files in all prototypes in this application.
|
||||
* The checksum can be used to find out quickly if any file has changed.
|
||||
*/
|
||||
public long getChecksum() {
|
||||
return checksum;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a prototype defined for this application
|
||||
*/
|
||||
public Prototype getPrototype(String typename) {
|
||||
return (Prototype) prototypes.get(typename);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -232,152 +302,167 @@ public final class TypeManager {
|
|||
* that it doesn't create a DbMapping - this is left to the
|
||||
* caller (e.g. ZippedAppFile).
|
||||
*/
|
||||
public Prototype createPrototype (String typename) {
|
||||
return createPrototype (typename, new File (appDir, typename));
|
||||
public Prototype createPrototype(String typename) {
|
||||
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;
|
||||
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) {
|
||||
* 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);
|
||||
Prototype proto = getPrototype(name);
|
||||
|
||||
updatePrototype(proto);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a prototype to the files in the prototype directory.
|
||||
*/
|
||||
public void updatePrototype (Prototype proto) {
|
||||
if (proto == null || proto.isUpToDate())
|
||||
* Update a prototype to the files in the prototype directory.
|
||||
*/
|
||||
public void updatePrototype(Prototype proto) {
|
||||
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 ();
|
||||
/* if (System.currentTimeMillis() - proto.getLastCheck() < 1000)
|
||||
return; */
|
||||
File dir = proto.getDirectory();
|
||||
HashSet updateSet = null;
|
||||
HashSet createSet = null;
|
||||
|
||||
// our plan is to do as little as possible, so first check if
|
||||
// anything the prototype knows about has changed on disk
|
||||
for (Iterator i = proto.updatables.values().iterator(); i.hasNext(); ) {
|
||||
for (Iterator i = proto.updatables.values().iterator(); i.hasNext();) {
|
||||
Updatable upd = (Updatable) i.next();
|
||||
if (upd.needsUpdate ()) {
|
||||
if (updateSet == null)
|
||||
updateSet = new HashSet ();
|
||||
updateSet.add (upd);
|
||||
|
||||
if (upd.needsUpdate()) {
|
||||
if (updateSet == null) {
|
||||
updateSet = new HashSet();
|
||||
}
|
||||
|
||||
updateSet.add(upd);
|
||||
}
|
||||
}
|
||||
|
||||
// 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)
|
||||
createSet = new HashSet ();
|
||||
createSet.add (list[i]);
|
||||
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) {
|
||||
createSet = new HashSet();
|
||||
}
|
||||
|
||||
createSet.add(list[i]);
|
||||
}
|
||||
}
|
||||
// }
|
||||
}
|
||||
|
||||
// }
|
||||
// if nothing needs to be updated, mark prototype as checked and return
|
||||
if (updateSet == null && createSet == null) {
|
||||
proto.markChecked ();
|
||||
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++) {
|
||||
Object[] newFiles = createSet.toArray();
|
||||
|
||||
for (int i = 0; i < newFiles.length; i++) {
|
||||
File file = (File) newFiles[i];
|
||||
String filename = file.getName ();
|
||||
int dot = filename.lastIndexOf (".");
|
||||
String filename = file.getName();
|
||||
int dot = filename.lastIndexOf(".");
|
||||
String tmpname = filename.substring(0, dot);
|
||||
|
||||
if (filename.endsWith (templateExtension)) {
|
||||
if (filename.endsWith(templateExtension)) {
|
||||
try {
|
||||
Template t = new Template (file, tmpname, proto);
|
||||
proto.addTemplate (t);
|
||||
Template t = new Template(file, tmpname, proto);
|
||||
|
||||
proto.addTemplate(t);
|
||||
} catch (Throwable x) {
|
||||
app.logEvent ("Error updating prototype: "+x);
|
||||
app.logEvent("Error updating prototype: " + x);
|
||||
}
|
||||
} else if (filename.endsWith (scriptExtension)) {
|
||||
} else if (filename.endsWith(scriptExtension)) {
|
||||
try {
|
||||
FunctionFile ff = new FunctionFile (file, proto);
|
||||
proto.addFunctionFile (ff);
|
||||
FunctionFile ff = new FunctionFile(file, proto);
|
||||
|
||||
proto.addFunctionFile(ff);
|
||||
} catch (Throwable x) {
|
||||
app.logEvent ("Error updating prototype: "+x);
|
||||
app.logEvent("Error updating prototype: " + x);
|
||||
}
|
||||
} else if (filename.endsWith (actionExtension)) {
|
||||
} else if (filename.endsWith(actionExtension)) {
|
||||
try {
|
||||
ActionFile af = new ActionFile (file, tmpname, proto);
|
||||
proto.addActionFile (af);
|
||||
ActionFile af = new ActionFile(file, tmpname, proto);
|
||||
|
||||
proto.addActionFile(af);
|
||||
} catch (Throwable x) {
|
||||
app.logEvent ("Error updating prototype: "+x);
|
||||
app.logEvent("Error updating prototype: " + x);
|
||||
}
|
||||
} else if (filename.endsWith (skinExtension)) {
|
||||
SkinFile sf = new SkinFile (file, tmpname, proto);
|
||||
proto.addSkinFile (sf);
|
||||
} else if (filename.endsWith(skinExtension)) {
|
||||
SkinFile sf = new SkinFile(file, tmpname, proto);
|
||||
|
||||
proto.addSkinFile(sf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// next go through existing updatables
|
||||
if (updateSet != null) {
|
||||
for (Iterator i = updateSet.iterator(); i.hasNext(); ) {
|
||||
for (Iterator i = updateSet.iterator(); i.hasNext();) {
|
||||
Updatable upd = (Updatable) i.next();
|
||||
|
||||
try {
|
||||
upd.update ();
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// mark prototype as checked and updated.
|
||||
proto.markChecked ();
|
||||
proto.markChecked();
|
||||
proto.markUpdated();
|
||||
|
||||
} // end of synchronized (proto)
|
||||
|
||||
}
|
||||
// end of synchronized (proto)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -1,160 +1,208 @@
|
|||
// 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;
|
||||
|
||||
public ZippedAppFile (File file, Application app) {
|
||||
this.app = app;
|
||||
this.file = file;
|
||||
// System.err.println ("CREATING ZIP FILE "+this);
|
||||
// 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 ();
|
||||
public boolean needsUpdate() {
|
||||
return !file.exists() || (lastmod != file.lastModified());
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void update() {
|
||||
if (!file.exists()) {
|
||||
remove();
|
||||
} else {
|
||||
ZipFile zip = null;
|
||||
|
||||
public void update () {
|
||||
// collect created protos - we need this to check DbMappings for each created
|
||||
// prototype afterwards
|
||||
HashSet newPrototypes = new HashSet();
|
||||
|
||||
if (!file.exists ()) {
|
||||
remove ();
|
||||
try {
|
||||
lastmod = file.lastModified();
|
||||
|
||||
} else {
|
||||
// System.err.println ("UPDATING ZIP FILE "+this);
|
||||
zip = new ZipFile(file);
|
||||
updatables = new HashSet();
|
||||
|
||||
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);
|
||||
proto.addActionFile (act);
|
||||
updatables.add (act);
|
||||
// mark prototype as updated
|
||||
proto.markUpdated ();
|
||||
}
|
||||
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")) {
|
||||
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")) {
|
||||
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)) {
|
||||
DbMapping dbmap = proto.getDbMapping ();
|
||||
SystemProperties props = dbmap.getProperties ();
|
||||
props.addProps (file.getName(), zip.getInputStream (entry));
|
||||
// mark prototype as updated
|
||||
proto.markUpdated ();
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Throwable x) {
|
||||
System.err.println ("Error updating ZipFile: "+x);
|
||||
} finally {
|
||||
try {
|
||||
zip.close ();
|
||||
} catch (Exception ignore) {}
|
||||
}
|
||||
}
|
||||
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);
|
||||
|
||||
proto.addActionFile(act);
|
||||
updatables.add(act);
|
||||
|
||||
// mark prototype as updated
|
||||
proto.markUpdated();
|
||||
} 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")) {
|
||||
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")) {
|
||||
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)) {
|
||||
DbMapping dbmap = proto.getDbMapping();
|
||||
SystemProperties props = dbmap.getProperties();
|
||||
|
||||
props.addProps(file.getName(), zip.getInputStream(entry));
|
||||
|
||||
// mark prototype as updated
|
||||
proto.markUpdated();
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Throwable x) {
|
||||
System.err.println("Error updating ZipFile: " + x);
|
||||
} finally {
|
||||
try {
|
||||
zip.close();
|
||||
} 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 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);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @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));
|
||||
|
||||
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);
|
||||
reader.read(c);
|
||||
|
||||
return new String(c);
|
||||
}
|
||||
|
||||
|
||||
public String toString () {
|
||||
return file.getName();
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String toString() {
|
||||
return file.getName();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,198 +1,295 @@
|
|||
// 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 {
|
||||
|
||||
public ImageGenerator () {
|
||||
// nothing to do
|
||||
/**
|
||||
* Creates a new ImageGenerator object.
|
||||
*/
|
||||
public ImageGenerator() {
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
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;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @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[]) {
|
||||
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;
|
||||
}
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param src ...
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public ImageWrapper createPaintableImage(byte[] src) {
|
||||
ImageWrapper rimg = null;
|
||||
Image img1 = Toolkit.getDefaultToolkit().createImage(src);
|
||||
ImageLoader loader = new ImageLoader(img1);
|
||||
|
||||
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;
|
||||
}
|
||||
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();
|
||||
|
||||
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 {
|
||||
g.drawImage(img1, 0, 0, null);
|
||||
rimg = new SunImageWrapper(img, g, w, h, this);
|
||||
} finally {
|
||||
loader.done();
|
||||
}
|
||||
return rimg;
|
||||
|
||||
return rimg;
|
||||
}
|
||||
|
||||
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 {
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @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;
|
||||
|
||||
return rimg;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @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);
|
||||
|
||||
public Image createImage (String filename) {
|
||||
Image img = null;
|
||||
img = Toolkit.getDefaultToolkit ().createImage (filename);
|
||||
ImageLoader loader = new ImageLoader (img);
|
||||
loader.getDimensions ();
|
||||
loader.done();
|
||||
return img;
|
||||
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 Image createImage (ImageProducer producer) {
|
||||
Image img = null;
|
||||
img = Toolkit.getDefaultToolkit ().createImage (producer);
|
||||
ImageLoader loader = new ImageLoader (img);
|
||||
loader.getDimensions ();
|
||||
loader.done();
|
||||
return img;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @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;
|
||||
int h;
|
||||
boolean waiting;
|
||||
boolean firstFrameLoaded;
|
||||
|
||||
Image img;
|
||||
int w, h;
|
||||
boolean waiting;
|
||||
boolean firstFrameLoaded;
|
||||
ImageLoader(Image img) {
|
||||
this.img = img;
|
||||
waiting = true;
|
||||
firstFrameLoaded = false;
|
||||
}
|
||||
|
||||
ImageLoader (Image img) {
|
||||
this.img = img;
|
||||
waiting = true;
|
||||
firstFrameLoaded = false;
|
||||
}
|
||||
synchronized void getDimensions() {
|
||||
w = img.getWidth(this);
|
||||
h = img.getHeight(this);
|
||||
|
||||
synchronized void getDimensions () {
|
||||
w = img.getWidth(this);
|
||||
h = img.getHeight (this);
|
||||
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) {
|
||||
throw new RuntimeException ("Error loading image");
|
||||
}
|
||||
}
|
||||
if ((w == -1) || (h == -1)) {
|
||||
try {
|
||||
wait(45000);
|
||||
} catch (InterruptedException x) {
|
||||
waiting = false;
|
||||
|
||||
synchronized void done () {
|
||||
waiting = false;
|
||||
notifyAll ();
|
||||
}
|
||||
return;
|
||||
} finally {
|
||||
waiting = false;
|
||||
}
|
||||
}
|
||||
|
||||
int getWidth () {
|
||||
return w;
|
||||
}
|
||||
// if width and height haven't been set, throw tantrum
|
||||
if ((w == -1) || (h == -1)) {
|
||||
throw new RuntimeException("Error loading image");
|
||||
}
|
||||
}
|
||||
|
||||
int getHeight () {
|
||||
return h;
|
||||
}
|
||||
synchronized void done() {
|
||||
waiting = false;
|
||||
notifyAll();
|
||||
}
|
||||
|
||||
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) {
|
||||
// we either timed out or there was an error.
|
||||
notifyAll ();
|
||||
return false;
|
||||
}
|
||||
if ((infoflags & WIDTH) > 0 || (infoflags & HEIGHT) > 0) {
|
||||
if ((infoflags & WIDTH) > 0)
|
||||
w = width;
|
||||
if ((infoflags & HEIGHT) > 0)
|
||||
h = height;
|
||||
if (w > -1 && h > -1 && firstFrameLoaded) {
|
||||
notifyAll ();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if ((infoflags & ALLBITS) > 0 || (infoflags & FRAMEBITS) > 0) {
|
||||
firstFrameLoaded = true;
|
||||
notifyAll ();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
int getWidth() {
|
||||
return w;
|
||||
}
|
||||
|
||||
int getHeight() {
|
||||
return h;
|
||||
}
|
||||
|
||||
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)) {
|
||||
// we either timed out or there was an error.
|
||||
notifyAll();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (((infoflags & WIDTH) > 0) || ((infoflags & HEIGHT) > 0)) {
|
||||
if ((infoflags & WIDTH) > 0) {
|
||||
w = width;
|
||||
}
|
||||
|
||||
if ((infoflags & HEIGHT) > 0) {
|
||||
h = height;
|
||||
}
|
||||
|
||||
if ((w > -1) && (h > -1) && firstFrameLoaded) {
|
||||
notifyAll();
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (((infoflags & ALLBITS) > 0) || ((infoflags & FRAMEBITS) > 0)) {
|
||||
firstFrameLoaded = true;
|
||||
notifyAll();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,247 +1,396 @@
|
|||
// 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) {
|
||||
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 ();
|
||||
}
|
||||
/**
|
||||
* 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();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* image manipulation methods
|
||||
*/
|
||||
|
||||
public void setFont (String name, int style, int size) {
|
||||
this.fontname = name;
|
||||
this.fontstyle = style;
|
||||
this.fontsize = size;
|
||||
g.setFont (new Font (name, style, size));
|
||||
}
|
||||
|
||||
public void setColor (int red, int green, int blue) {
|
||||
g.setColor (new Color (red, green, blue));
|
||||
}
|
||||
|
||||
public void setColor (int color) {
|
||||
g.setColor (new Color (color));
|
||||
*/
|
||||
public void setFont(String name, int style, int size) {
|
||||
this.fontname = name;
|
||||
this.fontstyle = style;
|
||||
this.fontsize = size;
|
||||
g.setFont(new Font(name, style, size));
|
||||
}
|
||||
|
||||
public void drawString (String str, int x, int y) {
|
||||
g.drawString (str, x, y);
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param red ...
|
||||
* @param green ...
|
||||
* @param blue ...
|
||||
*/
|
||||
public void setColor(int red, int green, int blue) {
|
||||
g.setColor(new Color(red, green, blue));
|
||||
}
|
||||
|
||||
public void drawLine (int x1, int y1, int x2, int y2) {
|
||||
g.drawLine (x1, y1, x2, y2);
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param color ...
|
||||
*/
|
||||
public void setColor(int color) {
|
||||
g.setColor(new Color(color));
|
||||
}
|
||||
|
||||
public void drawRect (int x, int y, int w, int h) {
|
||||
g.drawRect (x, y, w, h);
|
||||
}
|
||||
|
||||
public void drawImage (String filename, int x, int y) {
|
||||
try {
|
||||
Image i = imggen.createImage (filename);
|
||||
g.drawImage (i, x, y, null);
|
||||
} catch (Exception ignore) {}
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param str ...
|
||||
* @param x ...
|
||||
* @param y ...
|
||||
*/
|
||||
public void drawString(String str, int x, int y) {
|
||||
g.drawString(str, x, y);
|
||||
}
|
||||
|
||||
public void fillRect (int x, int y, int w, int h) {
|
||||
g.fillRect (x, y, w, h);
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @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);
|
||||
}
|
||||
|
||||
public int getWidth () {
|
||||
return width;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @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);
|
||||
}
|
||||
|
||||
public int getHeight () {
|
||||
return height;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @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) {
|
||||
}
|
||||
}
|
||||
|
||||
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));
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @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);
|
||||
}
|
||||
|
||||
public void resize (int w, int h) {
|
||||
img = img.getScaledInstance (w, h, Image.SCALE_SMOOTH);
|
||||
width = w;
|
||||
height = h;
|
||||
}
|
||||
|
||||
public void resizeFast (int w, int h) {
|
||||
img = img.getScaledInstance (w, h, Image.SCALE_FAST);
|
||||
width = w;
|
||||
height = h;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public int getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
public abstract void reduceColors (int colors);
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public int getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
public abstract void saveAs (String filename);
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @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));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @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);
|
||||
|
||||
/**
|
||||
* Get ImageProducer of the wrapped image
|
||||
*/
|
||||
public ImageProducer getSource () {
|
||||
return img.getSource ();
|
||||
public ImageProducer getSource() {
|
||||
return img.getSource();
|
||||
}
|
||||
|
||||
public void fillString (String str) {
|
||||
Filler filler = new Filler (0, 0, width, height);
|
||||
filler.layout (str);
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param str ...
|
||||
*/
|
||||
public void fillString(String str) {
|
||||
Filler filler = new Filler(0, 0, width, height);
|
||||
|
||||
filler.layout(str);
|
||||
}
|
||||
|
||||
public void fillString (String str, int x, int y, int w, int h) {
|
||||
Filler filler = new Filler (x, y, w, h);
|
||||
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;
|
||||
int y;
|
||||
int w;
|
||||
int h;
|
||||
int addedSpace = 0;
|
||||
int xLeft;
|
||||
int yLeft;
|
||||
int realHeight;
|
||||
transient Vector lines;
|
||||
|
||||
int x, y, w, h;
|
||||
int addedSpace = 0;
|
||||
int xLeft, yLeft;
|
||||
int realHeight;
|
||||
transient Vector lines;
|
||||
|
||||
public Filler (int x, int y, int w, int h) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.w = w;
|
||||
this.h = h;
|
||||
public Filler(int x, int y, int w, int h) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.w = w;
|
||||
this.h = h;
|
||||
}
|
||||
|
||||
public void layout(String str) {
|
||||
int size = fontsize;
|
||||
|
||||
lines = new Vector();
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
int heightSoFar = 0;
|
||||
int heightIncrement = (int) (0.84f * metrics.getHeight());
|
||||
StringTokenizer tk = new StringTokenizer(string);
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
int spaceWidth = metrics.stringWidth(" ");
|
||||
int currentLine = 0;
|
||||
int currentWidth = 0;
|
||||
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))) {
|
||||
Line line = new Line(buffer.toString(), x, heightSoFar, metrics);
|
||||
|
||||
lines.addElement(line);
|
||||
|
||||
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)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!"".equals(buffer.toString().trim())) {
|
||||
Line line = new Line(buffer.toString(), x, heightSoFar, metrics);
|
||||
|
||||
lines.addElement(line);
|
||||
|
||||
if (line.textwidth > longestLine) {
|
||||
longestLine = line.textwidth;
|
||||
}
|
||||
|
||||
if ((longestLine > maxWidth) && (fontsize > 10)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
heightSoFar += heightIncrement;
|
||||
}
|
||||
|
||||
xLeft = w - longestLine;
|
||||
yLeft = (addedSpace + h) - heightSoFar;
|
||||
realHeight = heightSoFar;
|
||||
|
||||
return ((1.18 * heightSoFar) <= maxHeight);
|
||||
}
|
||||
}
|
||||
|
||||
public void layout (String str) {
|
||||
int size = fontsize;
|
||||
lines = new Vector ();
|
||||
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);
|
||||
}
|
||||
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;
|
||||
int heightSoFar = 0;
|
||||
int heightIncrement = (int) (0.84f * metrics.getHeight ());
|
||||
StringTokenizer tk = new StringTokenizer (string);
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
int spaceWidth = metrics.stringWidth(" ");
|
||||
int currentLine = 0;
|
||||
int currentWidth = 0;
|
||||
int maxWidth = w - 2, maxHeight = h + addedSpace - 2;
|
||||
while (tk.hasMoreTokens()) {
|
||||
String nextToken = tk.nextToken();
|
||||
int nextWidth = metrics.stringWidth(nextToken);
|
||||
if ((currentWidth + nextWidth >= maxWidth && currentWidth != 0)) {
|
||||
Line line = new Line (buffer.toString(), x, heightSoFar, metrics);
|
||||
lines.addElement (line);
|
||||
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)
|
||||
return false;
|
||||
}
|
||||
if (! "".equals (buffer.toString().trim())) {
|
||||
Line line = new Line (buffer.toString(), x, heightSoFar, metrics);
|
||||
lines.addElement (line);
|
||||
|
||||
if (line.textwidth > longestLine)
|
||||
longestLine = line.textwidth;
|
||||
if (longestLine > maxWidth && fontsize > 10)
|
||||
return false;
|
||||
heightSoFar += heightIncrement;
|
||||
}
|
||||
xLeft = w - longestLine;
|
||||
yLeft = addedSpace + h - heightSoFar;
|
||||
realHeight = heightSoFar;
|
||||
return (1.18*heightSoFar <= maxHeight);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
class Line implements Serializable {
|
||||
String text;
|
||||
int xoff;
|
||||
int yoff;
|
||||
FontMetrics fm;
|
||||
public int textwidth;
|
||||
public int len;
|
||||
int ascent;
|
||||
|
||||
String text;
|
||||
int xoff, yoff;
|
||||
FontMetrics fm;
|
||||
public int textwidth, len;
|
||||
int ascent;
|
||||
public Line(String text, int xoff, int yoff, FontMetrics fm) {
|
||||
this.text = text.trim();
|
||||
len = text.length();
|
||||
this.xoff = xoff;
|
||||
this.yoff = yoff;
|
||||
this.fm = fm;
|
||||
textwidth = (len == 0) ? 0 : fm.stringWidth(this.text);
|
||||
ascent = (int) (0.9f * fm.getAscent());
|
||||
}
|
||||
|
||||
public void paint(Graphics g, int xadd, int yadd) {
|
||||
g.drawString(text, xoff + xadd, yoff + ascent + yadd);
|
||||
}
|
||||
|
||||
public Line (String text, int xoff, int yoff, FontMetrics fm) {
|
||||
this.text = text.trim();
|
||||
len = text.length();
|
||||
this.xoff = xoff;
|
||||
this.yoff = yoff;
|
||||
this.fm = fm;
|
||||
textwidth = (len == 0) ? 0 : fm.stringWidth(this.text);
|
||||
ascent = (int) (0.9f * fm.getAscent());
|
||||
public boolean contains(int y) {
|
||||
return (y < (yoff + fm.getHeight())) ? true : false;
|
||||
}
|
||||
}
|
||||
|
||||
public void paint (Graphics g, int xadd, int yadd) {
|
||||
g.drawString (text, xoff+xadd, yoff+ascent+yadd);
|
||||
}
|
||||
|
||||
|
||||
public boolean contains (int y) {
|
||||
return (y < yoff+fm.getHeight()) ? true : false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,87 +1,121 @@
|
|||
// 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 {
|
||||
|
||||
public SunImageWrapper (Image img, Graphics g, int width, int height,
|
||||
ImageGenerator imggen) {
|
||||
super (img, g, width, height, imggen);
|
||||
}
|
||||
|
||||
|
||||
public void reduceColors (int colors) {
|
||||
try {
|
||||
int pixels[][] = getPixels();
|
||||
int palette[] = Quantize.quantizeImage(pixels, colors);
|
||||
int w = pixels.length;
|
||||
int h = pixels[0].length;
|
||||
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]];
|
||||
}
|
||||
}
|
||||
img = imggen.createImage (new MemoryImageSource(w, h, pix, 0, w));
|
||||
} catch (Exception x) {
|
||||
// throw new RuntimeException (x.getMessage ());
|
||||
}
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Snag the pixels from an image.
|
||||
*
|
||||
*
|
||||
* @param colors ...
|
||||
*/
|
||||
int[][] getPixels () throws IOException {
|
||||
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());
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
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];
|
||||
}
|
||||
}
|
||||
return pixels;
|
||||
public void reduceColors(int colors) {
|
||||
try {
|
||||
int[][] pixels = getPixels();
|
||||
int[] palette = Quantize.quantizeImage(pixels, colors);
|
||||
int w = pixels.length;
|
||||
int h = pixels[0].length;
|
||||
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]];
|
||||
}
|
||||
}
|
||||
|
||||
img = imggen.createImage(new MemoryImageSource(w, h, pix, 0, w));
|
||||
} catch (Exception x) {
|
||||
// throw new RuntimeException (x.getMessage ());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Snag the pixels from an image.
|
||||
*/
|
||||
int[][] getPixels() throws IOException {
|
||||
int[] pix = new int[width * height];
|
||||
PixelGrabber grabber = new PixelGrabber(img, 0, 0, width, height, pix, 0, width);
|
||||
|
||||
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 {
|
||||
Jimi.putImage (img, filename);
|
||||
}
|
||||
} catch (Exception x) {
|
||||
throw new RuntimeException (x.getMessage ());
|
||||
}
|
||||
try {
|
||||
if (grabber.grabPixels() != true) {
|
||||
throw new IOException("Grabber returned false: " + grabber.status());
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
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];
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
Jimi.putImage(img, filename);
|
||||
}
|
||||
} catch (Exception x) {
|
||||
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,258 +47,368 @@ public class ApplicationManager implements XmlRpcHandler {
|
|||
private Server server;
|
||||
private long lastModified;
|
||||
|
||||
public ApplicationManager (int port, File hopHome, SystemProperties props, Server server) {
|
||||
this.port = port;
|
||||
this.hopHome = hopHome;
|
||||
this.props = props;
|
||||
this.server = server;
|
||||
applications = new Hashtable ();
|
||||
xmlrpcHandlers = new Hashtable ();
|
||||
mountpoints = new Properties ();
|
||||
lastModified = 0;
|
||||
/**
|
||||
* 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;
|
||||
this.server = server;
|
||||
applications = new Hashtable();
|
||||
xmlrpcHandlers = new Hashtable();
|
||||
mountpoints = new Properties();
|
||||
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) {
|
||||
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);
|
||||
} else if (server.http != null) {
|
||||
// check if application should be remounted at a
|
||||
// different location on embedded web server
|
||||
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);
|
||||
if (oldContext != null) {
|
||||
// oldContext.setContextPath(pattern);
|
||||
oldContext.stop ();
|
||||
oldContext.destroy ();
|
||||
}
|
||||
Application app = (Application) applications.get (appName);
|
||||
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");
|
||||
holder.setInitParameter ("application", appName);
|
||||
holder.setInitParameter ("mountpoint", mountpoint);
|
||||
if ("true".equalsIgnoreCase (props.getProperty (appName+".responseEncoding")))
|
||||
context.addHandler(new ContentEncodingHandler());
|
||||
String cookieDomain = props.getProperty (appName+".cookieDomain");
|
||||
if (cookieDomain != null)
|
||||
holder.setInitParameter ("cookieDomain", cookieDomain);
|
||||
String uploadLimit = props.getProperty (appName+".uploadLimit");
|
||||
if (uploadLimit != null)
|
||||
holder.setInitParameter ("uploadLimit", uploadLimit);
|
||||
// holder.start ();
|
||||
context.start ();
|
||||
mountpoints.setProperty (appName, pattern);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception mx) {
|
||||
Server.getLogger().log ("Error checking applications: "+mx);
|
||||
}
|
||||
protected void checkForChanges() {
|
||||
if (props.lastModified() > lastModified) {
|
||||
try {
|
||||
for (Enumeration e = props.keys(); e.hasMoreElements();) {
|
||||
String appName = (String) e.nextElement();
|
||||
|
||||
lastModified = System.currentTimeMillis ();
|
||||
}
|
||||
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);
|
||||
} else if (server.http != null) {
|
||||
// check if application should be remounted at a
|
||||
// different location on embedded web server
|
||||
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);
|
||||
|
||||
if (oldContext != null) {
|
||||
// oldContext.setContextPath(pattern);
|
||||
oldContext.stop();
|
||||
oldContext.destroy();
|
||||
}
|
||||
|
||||
Application app = (Application) applications.get(appName);
|
||||
|
||||
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");
|
||||
|
||||
holder.setInitParameter("application", appName);
|
||||
holder.setInitParameter("mountpoint", mountpoint);
|
||||
|
||||
if ("true".equalsIgnoreCase(props.getProperty(appName +
|
||||
".responseEncoding"))) {
|
||||
context.addHandler(new ContentEncodingHandler());
|
||||
}
|
||||
|
||||
String cookieDomain = props.getProperty(appName +
|
||||
".cookieDomain");
|
||||
|
||||
if (cookieDomain != null) {
|
||||
holder.setInitParameter("cookieDomain", cookieDomain);
|
||||
}
|
||||
|
||||
String uploadLimit = props.getProperty(appName +
|
||||
".uploadLimit");
|
||||
|
||||
if (uploadLimit != null) {
|
||||
holder.setInitParameter("uploadLimit", uploadLimit);
|
||||
}
|
||||
|
||||
// holder.start ();
|
||||
context.start();
|
||||
mountpoints.setProperty(appName, pattern);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception mx) {
|
||||
Server.getLogger().log("Error checking applications: " + mx);
|
||||
}
|
||||
|
||||
lastModified = System.currentTimeMillis();
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
String dbDirName = props.getProperty (appName+".dbdir");
|
||||
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) {
|
||||
Server.getLogger().log ("Error creating application "+appName+": "+x);
|
||||
x.printStackTrace ();
|
||||
}
|
||||
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);
|
||||
String dbDirName = props.getProperty(appName + ".dbdir");
|
||||
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) {
|
||||
Server.getLogger().log("Error creating application " + appName + ": " + x);
|
||||
x.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
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 ();
|
||||
Server.getLogger().log ("Unregistered application "+appName);
|
||||
} catch (Exception x) {
|
||||
Server.getLogger().log ("Couldn't unregister app: "+x);
|
||||
}
|
||||
applications.remove (appName);
|
||||
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();
|
||||
Server.getLogger().log("Unregistered application " + appName);
|
||||
} 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 ())
|
||||
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");
|
||||
holder.setInitParameter ("application", appName);
|
||||
holder.setInitParameter ("mountpoint", mountpoint);
|
||||
if ("true".equalsIgnoreCase (props.getProperty (appName+".responseEncoding")))
|
||||
context.addHandler(new ContentEncodingHandler());
|
||||
String cookieDomain = props.getProperty (appName+".cookieDomain");
|
||||
if (cookieDomain != null)
|
||||
holder.setInitParameter ("cookieDomain", cookieDomain);
|
||||
String uploadLimit = props.getProperty (appName+".uploadLimit");
|
||||
if (uploadLimit != null)
|
||||
holder.setInitParameter ("uploadLimit", uploadLimit);
|
||||
String debug = props.getProperty (appName+".debug");
|
||||
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 ();
|
||||
} catch (Exception x) {
|
||||
Server.getLogger().log ("Couldn't register and start app: "+x);
|
||||
x.printStackTrace ();
|
||||
}
|
||||
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()) {
|
||||
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");
|
||||
|
||||
holder.setInitParameter("application", appName);
|
||||
holder.setInitParameter("mountpoint", mountpoint);
|
||||
|
||||
if ("true".equalsIgnoreCase(props.getProperty(appName +
|
||||
".responseEncoding"))) {
|
||||
context.addHandler(new ContentEncodingHandler());
|
||||
}
|
||||
|
||||
String cookieDomain = props.getProperty(appName + ".cookieDomain");
|
||||
|
||||
if (cookieDomain != null) {
|
||||
holder.setInitParameter("cookieDomain", cookieDomain);
|
||||
}
|
||||
|
||||
String uploadLimit = props.getProperty(appName + ".uploadLimit");
|
||||
|
||||
if (uploadLimit != null) {
|
||||
holder.setInitParameter("uploadLimit", uploadLimit);
|
||||
}
|
||||
|
||||
String debug = props.getProperty(appName + ".debug");
|
||||
|
||||
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();
|
||||
} catch (Exception x) {
|
||||
Server.getLogger().log("Couldn't register and start app: " + x);
|
||||
x.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void startAll () {
|
||||
try {
|
||||
for (Enumeration e = props.keys(); e.hasMoreElements (); ) {
|
||||
String appName = (String) e.nextElement ();
|
||||
if (appName.indexOf (".") == -1)
|
||||
start (appName);
|
||||
}
|
||||
for (Enumeration e = props.keys(); e.hasMoreElements (); ) {
|
||||
String appName = (String) e.nextElement ();
|
||||
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());
|
||||
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);
|
||||
mx.printStackTrace ();
|
||||
}
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void startAll() {
|
||||
try {
|
||||
for (Enumeration e = props.keys(); e.hasMoreElements();) {
|
||||
String appName = (String) e.nextElement();
|
||||
|
||||
if (appName.indexOf(".") == -1) {
|
||||
start(appName);
|
||||
}
|
||||
}
|
||||
|
||||
for (Enumeration e = props.keys(); e.hasMoreElements();) {
|
||||
String appName = (String) e.nextElement();
|
||||
|
||||
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());
|
||||
|
||||
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);
|
||||
mx.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void stopAll () {
|
||||
for (Enumeration en=applications.keys(); en.hasMoreElements(); ) {
|
||||
String appName = (String) en.nextElement();
|
||||
stop (appName);
|
||||
}
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void stopAll() {
|
||||
for (Enumeration en = applications.keys(); en.hasMoreElements();) {
|
||||
String appName = (String) en.nextElement();
|
||||
|
||||
stop(appName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an array containing all currently running applications.
|
||||
*/
|
||||
public Object[] getApplications () {
|
||||
return applications.values ().toArray ();
|
||||
public Object[] getApplications() {
|
||||
return applications.values().toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an application by name.
|
||||
*/
|
||||
public Application getApplication(String name) {
|
||||
return (Application)applications.get(name);
|
||||
* Get an application by name.
|
||||
*/
|
||||
public Application getApplication(String name) {
|
||||
return (Application) applications.get(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements org.apache.xmlrpc.XmlRpcHandler.execute()
|
||||
*/
|
||||
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)
|
||||
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)
|
||||
throw new Exception ("Handler \""+handler+"\" not found for "+method);
|
||||
return app.executeXmlRpc (method2, params);
|
||||
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))) {
|
||||
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) {
|
||||
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");
|
||||
|
||||
private String getMountpoint (String appName) {
|
||||
String mountpoint = props.getProperty (appName+".mountpoint");
|
||||
if (mountpoint == null)
|
||||
return "/"+URLEncoder.encode(appName);
|
||||
mountpoint = mountpoint.trim ();
|
||||
if ("".equals (mountpoint))
|
||||
return "/";
|
||||
else if (!mountpoint.startsWith ("/"))
|
||||
return "/"+mountpoint;
|
||||
return mountpoint;
|
||||
if (mountpoint == null) {
|
||||
return "/" + URLEncoder.encode(appName);
|
||||
}
|
||||
|
||||
mountpoint = mountpoint.trim();
|
||||
|
||||
if ("".equals(mountpoint)) {
|
||||
return "/";
|
||||
} else if (!mountpoint.startsWith("/")) {
|
||||
return "/" + mountpoint;
|
||||
}
|
||||
|
||||
return mountpoint;
|
||||
}
|
||||
|
||||
private String getPathPattern (String mountpoint) {
|
||||
if ("/".equals (mountpoint))
|
||||
return "/";
|
||||
if (!mountpoint.endsWith ("/"))
|
||||
return mountpoint+"/*";
|
||||
return mountpoint+"*";
|
||||
}
|
||||
private String getPathPattern(String mountpoint) {
|
||||
if ("/".equals(mountpoint)) {
|
||||
return "/";
|
||||
}
|
||||
|
||||
if (!mountpoint.endsWith("/")) {
|
||||
return mountpoint + "/*";
|
||||
}
|
||||
|
||||
return mountpoint + "*";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,94 +1,327 @@
|
|||
// 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
|
||||
* Liberal security manager for Helma system that makes sure application code
|
||||
* is not allowed to exit the VM and set a security manager.
|
||||
*
|
||||
* This class can be subclassed to implement actual security policies. It contains
|
||||
* a utility method <code>getApplication</code> that can be used to determine
|
||||
* a utility method <code>getApplication</code> that can be used to determine
|
||||
* 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 ();
|
||||
private final static HashSet forbidden = new HashSet();
|
||||
|
||||
static {
|
||||
forbidden.add ("exitVM");
|
||||
forbidden.add ("setSecurityManager");
|
||||
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 (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");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @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 checkExit(int status) {
|
||||
Class[] classes = getClassContext();
|
||||
for (int i=0; i<classes.length; i++) {
|
||||
if (classes[i].getClassLoader() instanceof AppClassLoader)
|
||||
throw new SecurityException ("operation not allowed for application code");
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
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) {
|
||||
throw new SecurityException("operation not allowed for application code");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @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) {
|
||||
}
|
||||
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) {}
|
||||
|
||||
/**
|
||||
* Utility method that returns the name of the application trying
|
||||
* to execute the code in question. Returns null if the current code
|
||||
* to execute the code in question. Returns null if the current code
|
||||
* does not belong to any application.
|
||||
*/
|
||||
protected String getApplication () {
|
||||
Class[] classes = getClassContext();
|
||||
for (int i=0; i<classes.length; i++) {
|
||||
if (classes[i].getClassLoader() instanceof AppClassLoader)
|
||||
return ((AppClassLoader) classes[i].getClassLoader()).getAppName ();
|
||||
}
|
||||
// no application class loader found in stack - return null
|
||||
return null;
|
||||
}
|
||||
protected String getApplication() {
|
||||
Class[] classes = getClassContext();
|
||||
|
||||
for (int i = 0; i < classes.length; i++) {
|
||||
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;
|
||||
|
||||
public HelmaShutdownHook (ApplicationManager appmgr) {
|
||||
this.appmgr = 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)
|
||||
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();
|
||||
}
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void run() {
|
||||
Logger logger = Server.getLogger();
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
public HelmaSocketFactory () {
|
||||
filter = new InetAddressFilter ();
|
||||
/**
|
||||
* Creates a new HelmaSocketFactory object.
|
||||
*/
|
||||
public HelmaSocketFactory() {
|
||||
filter = new InetAddressFilter();
|
||||
}
|
||||
|
||||
public void addAddress (String address) {
|
||||
try {
|
||||
filter.addAddress (address);
|
||||
} catch (IOException x) {
|
||||
Server.getLogger().log ("Could not add "+address+" to Socket Filter: invalid address.");
|
||||
}
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @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.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param host ...
|
||||
* @param port ...
|
||||
*
|
||||
* @return ...
|
||||
*
|
||||
* @throws IOException ...
|
||||
*/
|
||||
public Socket createSocket(String host, int port) throws IOException {
|
||||
return new Socket (host, port);
|
||||
return new Socket(host, port);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param port ...
|
||||
*
|
||||
* @return ...
|
||||
*
|
||||
* @throws IOException ...
|
||||
*/
|
||||
public ServerSocket createServerSocket(int port) throws IOException {
|
||||
return new ParanoidServerSocket (port, filter);
|
||||
return new ParanoidServerSocket(port, filter);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,36 +1,51 @@
|
|||
// 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
|
||||
* class loaders so that special security policies can be applied to them and
|
||||
* so that they can load classes from jar files in the app directories.
|
||||
*/
|
||||
/**
|
||||
* 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
|
||||
* class loaders so that special security policies can be applied to them and
|
||||
* so that they can load classes from jar files in the app directories.
|
||||
*/
|
||||
public FilteredClassLoader(URL[] urls) {
|
||||
super (urls);
|
||||
super(urls);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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))
|
||||
throw new ClassNotFoundException (name);
|
||||
return super.findClass (name);
|
||||
protected Class findClass(String name) throws ClassNotFoundException {
|
||||
if ((name != null) && "helma.scripting.fesi.PhantomEngine".equals(name)) {
|
||||
throw new ClassNotFoundException(name);
|
||||
}
|
||||
|
||||
return super.findClass(name);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,114 +1,145 @@
|
|||
// 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
|
||||
/**
|
||||
* 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;
|
||||
|
||||
public static void main (String[] args) throws Exception {
|
||||
// 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)) {
|
||||
installDir = args[i + 1];
|
||||
}
|
||||
}
|
||||
|
||||
// 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) {
|
||||
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) {
|
||||
// unable to get Helma installation dir from launcher jar
|
||||
System.err.println ("Unable to get Helma installation directory: "+x);
|
||||
System.exit (2);
|
||||
}
|
||||
}
|
||||
URLClassLoader apploader = (URLClassLoader) ClassLoader.getSystemClassLoader();
|
||||
|
||||
// decode installDir in case it is URL-encoded
|
||||
installDir = URLDecoder.decode (installDir);
|
||||
// try to get Helma installation directory
|
||||
if (installDir == null) {
|
||||
try {
|
||||
URL launcherUrl = apploader.findResource("helma/main/launcher/Main.class");
|
||||
|
||||
// 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)
|
||||
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()));
|
||||
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);
|
||||
// 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) {
|
||||
// unable to get Helma installation dir from launcher jar
|
||||
System.err.println("Unable to get Helma installation directory: " + x);
|
||||
System.exit(2);
|
||||
}
|
||||
}
|
||||
|
||||
// decode installDir in case it is URL-encoded
|
||||
installDir = URLDecoder.decode(installDir);
|
||||
|
||||
// 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) {
|
||||
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()));
|
||||
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,51 +1,33 @@
|
|||
// 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;
|
||||
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* 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 {
|
||||
|
||||
public ConcurrencyException (String msg) {
|
||||
super (msg);
|
||||
/**
|
||||
* Creates a new ConcurrencyException object.
|
||||
*
|
||||
* @param msg ...
|
||||
*/
|
||||
public ConcurrencyException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,49 +1,32 @@
|
|||
// 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;
|
||||
|
||||
|
||||
/**
|
||||
* Thrown on any kind of Database-Error
|
||||
*/
|
||||
|
||||
public class DatabaseException extends RuntimeException {
|
||||
|
||||
public DatabaseException (String msg) {
|
||||
super (msg);
|
||||
/**
|
||||
* 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();
|
||||
|
||||
// db-related
|
||||
public void shutdown ();
|
||||
// id-related
|
||||
public String nextID() throws ObjectNotFoundException;
|
||||
|
||||
// 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;
|
||||
|
||||
// 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;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param transaction ...
|
||||
* @param idgen ...
|
||||
*
|
||||
* @throws IOException ...
|
||||
*/
|
||||
public void saveIDGenerator(ITransaction transaction, IDGenerator idgen)
|
||||
throws IOException;
|
||||
|
||||
// transaction-related
|
||||
public ITransaction beginTransaction ();
|
||||
public void commitTransaction (ITransaction transaction) throws DatabaseException;
|
||||
public void abortTransaction (ITransaction transaction) throws DatabaseException;
|
||||
// node-related
|
||||
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();
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @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();
|
||||
|
||||
public String getID ();
|
||||
public String getName ();
|
||||
public void setDbMapping (DbMapping dbmap);
|
||||
public DbMapping getDbMapping ();
|
||||
public int getState ();
|
||||
public void setState (int s);
|
||||
public void setName (String name);
|
||||
public long lastModified ();
|
||||
public long created ();
|
||||
public boolean isAnonymous (); // is this a named node, or an anonymous node in a collection?
|
||||
public String getPrototype ();
|
||||
public void setPrototype (String prototype);
|
||||
public INode getCacheNode ();
|
||||
public void clearCacheNode ();
|
||||
public String getFullName ();
|
||||
public String getFullName (INode root);
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @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();
|
||||
|
||||
public INode getParent ();
|
||||
public void setSubnodeRelation (String rel);
|
||||
public String getSubnodeRelation ();
|
||||
public int numberOfNodes ();
|
||||
public INode addNode (INode node);
|
||||
public INode addNode (INode node, int where);
|
||||
public INode createNode (String name);
|
||||
public INode createNode (String name, int where);
|
||||
public Enumeration getSubnodes ();
|
||||
public INode getSubnode (String name);
|
||||
public INode getSubnodeAt (int index);
|
||||
public int contains (INode node);
|
||||
public boolean remove ();
|
||||
public void removeNode (INode node);
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @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();
|
||||
|
||||
public Enumeration properties ();
|
||||
public IProperty get (String name);
|
||||
public String getString (String name);
|
||||
public boolean getBoolean (String name);
|
||||
public Date getDate (String name);
|
||||
public long getInteger (String name);
|
||||
public double getFloat (String name);
|
||||
public INode getNode (String name);
|
||||
public Object getJavaObject (String name);
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param name ...
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public IProperty get(String name);
|
||||
|
||||
public void setString (String name, String value);
|
||||
public void setBoolean (String name, boolean value);
|
||||
public void setDate (String name, Date value);
|
||||
public void setInteger (String name, long value);
|
||||
public void setFloat (String name, double value);
|
||||
public void setNode (String name, INode value);
|
||||
public void setJavaObject (String name, Object value);
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param name ...
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getString(String name);
|
||||
|
||||
public void unset (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;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,5 +1,18 @@
|
|||
// IProperty.java
|
||||
// Copyright (c) Hannes Wallnöfer 1997-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,9 +21,7 @@ import java.util.Date;
|
|||
/**
|
||||
* Interface that is implemented by node properties.
|
||||
*/
|
||||
|
||||
public interface IProperty {
|
||||
|
||||
public static final int STRING = 1;
|
||||
public static final int BOOLEAN = 2;
|
||||
public static final int DATE = 3;
|
||||
|
@ -19,16 +30,73 @@ public interface IProperty {
|
|||
public static final int NODE = 6;
|
||||
public static final int JAVAOBJECT = 7;
|
||||
|
||||
public String getName ();
|
||||
public int getType ();
|
||||
public Object getValue ();
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getName();
|
||||
|
||||
public INode getNodeValue ();
|
||||
public String getStringValue ();
|
||||
public boolean getBooleanValue ();
|
||||
public long getIntegerValue ();
|
||||
public double getFloatValue ();
|
||||
public Date getDateValue ();
|
||||
public Object getJavaObjectValue ();
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public int getType();
|
||||
|
||||
}
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public Object getValue();
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public INode getNodeValue();
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getStringValue();
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public boolean getBooleanValue();
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public long getIntegerValue();
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public double getFloatValue();
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public Date getDateValue();
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public Object getJavaObjectValue();
|
||||
}
|
||||
|
|
|
@ -1,18 +1,27 @@
|
|||
// ITransaction.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;
|
||||
|
||||
|
||||
/**
|
||||
* This interface is kept for databases that are able
|
||||
* to run transactions. Transactions were used for the
|
||||
* Berkeley database and might be used in other future
|
||||
* databases, so we leave transactions in.
|
||||
*/
|
||||
|
||||
* This interface is kept for databases that are able
|
||||
* to run transactions. Transactions were used for the
|
||||
* Berkeley database and might be used in other future
|
||||
* databases, so we leave transactions in.
|
||||
*/
|
||||
public interface ITransaction {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,59 +1,92 @@
|
|||
// NodeEvent.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.io.*;
|
||||
|
||||
/**
|
||||
/**
|
||||
* This is passed to NodeListeners when a node is modified.
|
||||
*/
|
||||
|
||||
public class NodeEvent implements Serializable {
|
||||
|
||||
public static final int CONTENT_CHANGED = 0;
|
||||
public static final int PROPERTIES_CHANGED = 1;
|
||||
public static final int NODE_REMOVED = 2;
|
||||
public static final int NODE_RENAMED = 3;
|
||||
public static final int SUBNODE_ADDED = 4;
|
||||
public static final int SUBNODE_REMOVED = 5;
|
||||
|
||||
public int type;
|
||||
public String id;
|
||||
public transient INode node;
|
||||
public transient Object arg;
|
||||
|
||||
public NodeEvent (INode node, int type) {
|
||||
super ();
|
||||
this.node = node;
|
||||
this.id = node.getID ();
|
||||
this.type = type;
|
||||
/**
|
||||
* Creates a new NodeEvent object.
|
||||
*
|
||||
* @param node ...
|
||||
* @param type ...
|
||||
*/
|
||||
public NodeEvent(INode node, int type) {
|
||||
super();
|
||||
this.node = node;
|
||||
this.id = node.getID();
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public NodeEvent (INode node, int type, Object arg) {
|
||||
super ();
|
||||
this.node = node;
|
||||
this.id = node.getID ();
|
||||
this.type = type;
|
||||
this.arg = arg;
|
||||
/**
|
||||
* Creates a new NodeEvent object.
|
||||
*
|
||||
* @param node ...
|
||||
* @param type ...
|
||||
* @param arg ...
|
||||
*/
|
||||
public NodeEvent(INode node, int type, Object arg) {
|
||||
super();
|
||||
this.node = node;
|
||||
this.id = node.getID();
|
||||
this.type = type;
|
||||
this.arg = arg;
|
||||
}
|
||||
|
||||
public String toString () {
|
||||
switch (type) {
|
||||
case CONTENT_CHANGED:
|
||||
return "NodeEvent: content changed";
|
||||
case PROPERTIES_CHANGED:
|
||||
return "NodeEvent: properties changed";
|
||||
case NODE_REMOVED:
|
||||
return "NodeEvent: node removed";
|
||||
case NODE_RENAMED:
|
||||
return "NodeEvent: node moved";
|
||||
case SUBNODE_ADDED:
|
||||
return "NodeEvent: subnode added";
|
||||
case SUBNODE_REMOVED:
|
||||
return "NodeEvent: subnode removed";
|
||||
}
|
||||
return "NodeEvent: invalid type";
|
||||
}
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String toString() {
|
||||
switch (type) {
|
||||
case CONTENT_CHANGED:
|
||||
return "NodeEvent: content changed";
|
||||
|
||||
}
|
||||
case PROPERTIES_CHANGED:
|
||||
return "NodeEvent: properties changed";
|
||||
|
||||
case NODE_REMOVED:
|
||||
return "NodeEvent: node removed";
|
||||
|
||||
case NODE_RENAMED:
|
||||
return "NodeEvent: node moved";
|
||||
|
||||
case SUBNODE_ADDED:
|
||||
return "NodeEvent: subnode added";
|
||||
|
||||
case SUBNODE_REMOVED:
|
||||
return "NodeEvent: subnode removed";
|
||||
}
|
||||
|
||||
return "NodeEvent: invalid type";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,19 @@
|
|||
// ObjectNotFoundException.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,42 +21,13 @@ package helma.objectmodel;
|
|||
* Thrown when an object could not found in the database where
|
||||
* it was expected.
|
||||
*/
|
||||
|
||||
public class ObjectNotFoundException extends Exception {
|
||||
|
||||
public ObjectNotFoundException (String msg) {
|
||||
super (msg);
|
||||
/**
|
||||
* Creates a new ObjectNotFoundException object.
|
||||
*
|
||||
* @param msg ...
|
||||
*/
|
||||
public ObjectNotFoundException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,195 +1,350 @@
|
|||
// Property.java
|
||||
// Copyright (c) Hannes Wallnöfer 1997-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 helma.util.*;
|
||||
import java.util.Vector;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Date;
|
||||
import java.util.Enumeration;
|
||||
import java.io.*;
|
||||
import java.text.*;
|
||||
import java.util.Date;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Vector;
|
||||
|
||||
/**
|
||||
* A property implementation for Nodes stored inside a database.
|
||||
* A property implementation for Nodes stored inside a database.
|
||||
*/
|
||||
|
||||
public final class Property implements IProperty, Serializable {
|
||||
|
||||
|
||||
protected String propname;
|
||||
protected TransientNode node;
|
||||
|
||||
public String svalue;
|
||||
public boolean bvalue;
|
||||
public long lvalue;
|
||||
public double dvalue;
|
||||
public INode nvalue;
|
||||
public Object jvalue;
|
||||
|
||||
public int type;
|
||||
|
||||
|
||||
public Property (TransientNode node) {
|
||||
this.node = node;
|
||||
/**
|
||||
* Creates a new Property object.
|
||||
*
|
||||
* @param node ...
|
||||
*/
|
||||
public Property(TransientNode node) {
|
||||
this.node = node;
|
||||
}
|
||||
|
||||
public Property (String propname, TransientNode node) {
|
||||
this.propname = propname;
|
||||
this.node = node;
|
||||
/**
|
||||
* Creates a new Property object.
|
||||
*
|
||||
* @param propname ...
|
||||
* @param node ...
|
||||
*/
|
||||
public Property(String propname, TransientNode node) {
|
||||
this.propname = propname;
|
||||
this.node = node;
|
||||
}
|
||||
|
||||
public String getName () {
|
||||
return propname;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getName() {
|
||||
return propname;
|
||||
}
|
||||
|
||||
public Object getValue () {
|
||||
switch (type) {
|
||||
case STRING:
|
||||
return svalue;
|
||||
case BOOLEAN:
|
||||
return new Boolean (bvalue);
|
||||
case INTEGER:
|
||||
return new Long (lvalue);
|
||||
case FLOAT:
|
||||
return new Double (dvalue);
|
||||
case DATE:
|
||||
return new Date (lvalue);
|
||||
case NODE:
|
||||
return nvalue;
|
||||
case JAVAOBJECT:
|
||||
return jvalue;
|
||||
}
|
||||
return null;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public Object getValue() {
|
||||
switch (type) {
|
||||
case STRING:
|
||||
return svalue;
|
||||
|
||||
case BOOLEAN:
|
||||
return new Boolean(bvalue);
|
||||
|
||||
case INTEGER:
|
||||
return new Long(lvalue);
|
||||
|
||||
case FLOAT:
|
||||
return new Double(dvalue);
|
||||
|
||||
case DATE:
|
||||
return new Date(lvalue);
|
||||
|
||||
case NODE:
|
||||
return nvalue;
|
||||
|
||||
case JAVAOBJECT:
|
||||
return jvalue;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setStringValue (String value) {
|
||||
if (type == NODE)
|
||||
this.nvalue = null;
|
||||
if (type == JAVAOBJECT)
|
||||
this.jvalue = null;
|
||||
type = STRING;
|
||||
this.svalue = value;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param value ...
|
||||
*/
|
||||
public void setStringValue(String value) {
|
||||
if (type == NODE) {
|
||||
this.nvalue = null;
|
||||
}
|
||||
|
||||
if (type == JAVAOBJECT) {
|
||||
this.jvalue = null;
|
||||
}
|
||||
|
||||
type = STRING;
|
||||
this.svalue = value;
|
||||
}
|
||||
|
||||
public void setIntegerValue (long value) {
|
||||
if (type == NODE)
|
||||
this.nvalue = null;
|
||||
if (type == JAVAOBJECT)
|
||||
this.jvalue = null;
|
||||
type = INTEGER;
|
||||
this.lvalue = value;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param value ...
|
||||
*/
|
||||
public void setIntegerValue(long value) {
|
||||
if (type == NODE) {
|
||||
this.nvalue = null;
|
||||
}
|
||||
|
||||
if (type == JAVAOBJECT) {
|
||||
this.jvalue = null;
|
||||
}
|
||||
|
||||
type = INTEGER;
|
||||
this.lvalue = value;
|
||||
}
|
||||
|
||||
public void setFloatValue (double value) {
|
||||
if (type == NODE)
|
||||
this.nvalue = null;
|
||||
if (type == JAVAOBJECT)
|
||||
this.jvalue = null;
|
||||
type = FLOAT;
|
||||
this.dvalue = value;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param value ...
|
||||
*/
|
||||
public void setFloatValue(double value) {
|
||||
if (type == NODE) {
|
||||
this.nvalue = null;
|
||||
}
|
||||
|
||||
if (type == JAVAOBJECT) {
|
||||
this.jvalue = null;
|
||||
}
|
||||
|
||||
type = FLOAT;
|
||||
this.dvalue = value;
|
||||
}
|
||||
|
||||
public void setDateValue (Date value) {
|
||||
if (type == NODE)
|
||||
this.nvalue = null;
|
||||
if (type == JAVAOBJECT)
|
||||
this.jvalue = null;
|
||||
type = DATE;
|
||||
this.lvalue = value.getTime();
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param value ...
|
||||
*/
|
||||
public void setDateValue(Date value) {
|
||||
if (type == NODE) {
|
||||
this.nvalue = null;
|
||||
}
|
||||
|
||||
if (type == JAVAOBJECT) {
|
||||
this.jvalue = null;
|
||||
}
|
||||
|
||||
type = DATE;
|
||||
this.lvalue = value.getTime();
|
||||
}
|
||||
|
||||
public void setBooleanValue (boolean value) {
|
||||
if (type == NODE)
|
||||
this.nvalue = null;
|
||||
if (type == JAVAOBJECT)
|
||||
this.jvalue = null;
|
||||
type = BOOLEAN;
|
||||
this.bvalue = value;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param value ...
|
||||
*/
|
||||
public void setBooleanValue(boolean value) {
|
||||
if (type == NODE) {
|
||||
this.nvalue = null;
|
||||
}
|
||||
|
||||
if (type == JAVAOBJECT) {
|
||||
this.jvalue = null;
|
||||
}
|
||||
|
||||
type = BOOLEAN;
|
||||
this.bvalue = value;
|
||||
}
|
||||
|
||||
public void setNodeValue (INode value) {
|
||||
if (type == JAVAOBJECT)
|
||||
this.jvalue = null;
|
||||
type = NODE;
|
||||
this.nvalue = value;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param value ...
|
||||
*/
|
||||
public void setNodeValue(INode value) {
|
||||
if (type == JAVAOBJECT) {
|
||||
this.jvalue = null;
|
||||
}
|
||||
|
||||
type = NODE;
|
||||
this.nvalue = value;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param value ...
|
||||
*/
|
||||
public void setJavaObjectValue(Object value) {
|
||||
if (type == NODE) {
|
||||
this.nvalue = null;
|
||||
}
|
||||
|
||||
public void setJavaObjectValue (Object value) {
|
||||
if (type == NODE)
|
||||
this.nvalue = null;
|
||||
type = JAVAOBJECT;
|
||||
this.jvalue = value;
|
||||
type = JAVAOBJECT;
|
||||
this.jvalue = value;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getStringValue() {
|
||||
switch (type) {
|
||||
case STRING:
|
||||
return svalue;
|
||||
|
||||
public String getStringValue () {
|
||||
switch (type) {
|
||||
case STRING:
|
||||
return svalue;
|
||||
case BOOLEAN:
|
||||
return "" + bvalue;
|
||||
case DATE:
|
||||
SimpleDateFormat format = new SimpleDateFormat ("dd.MM.yy HH:mm");
|
||||
return format.format (new Date (lvalue));
|
||||
case INTEGER:
|
||||
return Long.toString (lvalue);
|
||||
case FLOAT:
|
||||
return Double.toString (dvalue);
|
||||
case NODE:
|
||||
return nvalue.getName ();
|
||||
case JAVAOBJECT:
|
||||
return jvalue == null ? null : jvalue.toString ();
|
||||
}
|
||||
return "";
|
||||
case BOOLEAN:
|
||||
return "" + bvalue;
|
||||
|
||||
case DATE:
|
||||
|
||||
SimpleDateFormat format = new SimpleDateFormat("dd.MM.yy HH:mm");
|
||||
|
||||
return format.format(new Date(lvalue));
|
||||
|
||||
case INTEGER:
|
||||
return Long.toString(lvalue);
|
||||
|
||||
case FLOAT:
|
||||
return Double.toString(dvalue);
|
||||
|
||||
case NODE:
|
||||
return nvalue.getName();
|
||||
|
||||
case JAVAOBJECT:
|
||||
return (jvalue == null) ? null : jvalue.toString();
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
public String toString () {
|
||||
return getStringValue ();
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String toString() {
|
||||
return getStringValue();
|
||||
}
|
||||
|
||||
public long getIntegerValue () {
|
||||
if (type == INTEGER)
|
||||
return lvalue;
|
||||
return 0;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public long getIntegerValue() {
|
||||
if (type == INTEGER) {
|
||||
return lvalue;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public double getFloatValue () {
|
||||
if (type == FLOAT)
|
||||
return dvalue;
|
||||
return 0.0;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public double getFloatValue() {
|
||||
if (type == FLOAT) {
|
||||
return dvalue;
|
||||
}
|
||||
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public Date getDateValue() {
|
||||
if (type == DATE) {
|
||||
return new Date(lvalue);
|
||||
}
|
||||
|
||||
public Date getDateValue () {
|
||||
if (type == DATE)
|
||||
return new Date (lvalue);
|
||||
return null;
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean getBooleanValue () {
|
||||
if (type == BOOLEAN)
|
||||
return bvalue;
|
||||
return false;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public boolean getBooleanValue() {
|
||||
if (type == BOOLEAN) {
|
||||
return bvalue;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public INode getNodeValue () {
|
||||
if (type == NODE)
|
||||
return nvalue;
|
||||
return null;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public INode getNodeValue() {
|
||||
if (type == NODE) {
|
||||
return nvalue;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public Object getJavaObjectValue () {
|
||||
if (type == JAVAOBJECT)
|
||||
return jvalue;
|
||||
return null;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public Object getJavaObjectValue() {
|
||||
if (type == JAVAOBJECT) {
|
||||
return jvalue;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public int getType () {
|
||||
return type;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public int getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,48 +1,62 @@
|
|||
// DbColumn.java
|
||||
// Copyright 2002 Hannes Wallnoefer, Helma.org
|
||||
/*
|
||||
* 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.db;
|
||||
|
||||
/**
|
||||
* A class that encapsulates the Column name and data type of a
|
||||
|
||||
/**
|
||||
* A class that encapsulates the Column name and data type of a
|
||||
* column in a relational table.
|
||||
*/
|
||||
public final class DbColumn {
|
||||
|
||||
private final String name;
|
||||
private final int type;
|
||||
private final Relation relation;
|
||||
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public DbColumn (String name, int type, Relation rel) {
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
this.relation = rel;
|
||||
if (relation != null)
|
||||
relation.setColumnType (type);
|
||||
public DbColumn(String name, int type, Relation rel) {
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
this.relation = rel;
|
||||
|
||||
if (relation != null) {
|
||||
relation.setColumnType(type);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the column name.
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get this columns SQL data type.
|
||||
*/
|
||||
public int getType() {
|
||||
return type;
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the relation associated with this column. May be null.
|
||||
*/
|
||||
public Relation getRelation() {
|
||||
return relation;
|
||||
return relation;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,22 +1,34 @@
|
|||
// DbKey.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.db;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
|
||||
/**
|
||||
* This is the internal representation of a database key. It is constructed
|
||||
* from the logical table (type) name and the object's primary key
|
||||
* within the table. Currently only single keys are supported.
|
||||
*/
|
||||
public final class DbKey implements Key, Serializable {
|
||||
|
||||
// the name of the prototype which defines the storage of this object.
|
||||
// this is the name of the object's prototype, or one of its ancestors.
|
||||
// If null, the object is stored in the embedded db.
|
||||
private final String storageName;
|
||||
|
||||
// the id that defines this key's object within the above storage space
|
||||
private final String id;
|
||||
|
||||
|
@ -26,50 +38,82 @@ public final class DbKey implements Key, Serializable {
|
|||
/**
|
||||
* make a key for a persistent Object, describing its datasource and id.
|
||||
*/
|
||||
public DbKey (DbMapping dbmap, String id) {
|
||||
this.id = id;
|
||||
this.storageName = dbmap == null ? null : dbmap.getStorageTypeName ();
|
||||
}
|
||||
|
||||
|
||||
|
||||
public boolean equals (Object what) {
|
||||
if (what == this)
|
||||
return true;
|
||||
if (!(what instanceof DbKey))
|
||||
return false;
|
||||
DbKey k = (DbKey) what;
|
||||
// storageName is an interned string (by DbMapping, from where we got it)
|
||||
// so we can compare by using == instead of the equals method.
|
||||
return storageName == k.storageName && (id == k.id || id.equals (k.id));
|
||||
public DbKey(DbMapping dbmap, String id) {
|
||||
this.id = id;
|
||||
this.storageName = (dbmap == null) ? null : dbmap.getStorageTypeName();
|
||||
}
|
||||
|
||||
public int hashCode () {
|
||||
if (hashcode == 0) {
|
||||
hashcode = storageName == null ?
|
||||
17 + 37*id.hashCode () :
|
||||
17 + 37*storageName.hashCode() + +37*id.hashCode ();
|
||||
}
|
||||
return hashcode;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param what ...
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public boolean equals(Object what) {
|
||||
if (what == this) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(what instanceof DbKey)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
DbKey k = (DbKey) what;
|
||||
|
||||
// storageName is an interned string (by DbMapping, from where we got it)
|
||||
// so we can compare by using == instead of the equals method.
|
||||
return (storageName == k.storageName) && ((id == k.id) || id.equals(k.id));
|
||||
}
|
||||
|
||||
public Key getParentKey () {
|
||||
return null;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public int hashCode() {
|
||||
if (hashcode == 0) {
|
||||
hashcode = (storageName == null) ? (17 + (37 * id.hashCode()))
|
||||
: (17 + (37 * storageName.hashCode()) +
|
||||
(+37 * id.hashCode()));
|
||||
}
|
||||
|
||||
return hashcode;
|
||||
}
|
||||
|
||||
public String getStorageName () {
|
||||
return storageName;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public Key getParentKey() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getID () {
|
||||
return id;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getStorageName() {
|
||||
return storageName;
|
||||
}
|
||||
|
||||
public String toString () {
|
||||
return storageName == null ? "["+id+"]" : storageName+"["+id+"]";
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getID() {
|
||||
return id;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String toString() {
|
||||
return (storageName == null) ? ("[" + id + "]") : (storageName + "[" + id + "]");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,120 +1,119 @@
|
|||
// DbSource.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.objectmodel.db;
|
||||
|
||||
import helma.util.SystemProperties;
|
||||
import java.sql.*;
|
||||
import java.util.Hashtable;
|
||||
import helma.util.SystemProperties;
|
||||
|
||||
|
||||
/**
|
||||
* This class describes a releational data source (URL, driver, user and password).
|
||||
*/
|
||||
|
||||
public class DbSource {
|
||||
|
||||
private static SystemProperties defaultProps = null;
|
||||
private String name;
|
||||
private SystemProperties props;
|
||||
private static SystemProperties defaultProps = null;
|
||||
protected String url;
|
||||
private String driver;
|
||||
protected String user;
|
||||
private String password;
|
||||
private long lastRead = 0L;
|
||||
|
||||
private long lastRead = 0l;
|
||||
|
||||
public DbSource (String name, SystemProperties props) throws ClassNotFoundException {
|
||||
this.name = name;
|
||||
this.props = props;
|
||||
init ();
|
||||
/**
|
||||
* Creates a new DbSource object.
|
||||
*
|
||||
* @param name ...
|
||||
* @param props ...
|
||||
*
|
||||
* @throws ClassNotFoundException ...
|
||||
*/
|
||||
public DbSource(String name, SystemProperties props)
|
||||
throws ClassNotFoundException {
|
||||
this.name = name;
|
||||
this.props = props;
|
||||
init();
|
||||
}
|
||||
|
||||
public Connection getConnection () throws ClassNotFoundException, SQLException {
|
||||
Transactor tx = (Transactor) Thread.currentThread ();
|
||||
Connection con = tx.getConnection (this);
|
||||
boolean fileUpdated = props.lastModified () > lastRead;
|
||||
if (!fileUpdated && defaultProps != null)
|
||||
fileUpdated = defaultProps.lastModified () > lastRead;
|
||||
if (con == null || con.isClosed () || fileUpdated) {
|
||||
init ();
|
||||
Class.forName (driver);
|
||||
con = DriverManager.getConnection (url, user, password);
|
||||
// If we wanted to use SQL transactions, we'd set autoCommit to
|
||||
// false here and make commit/rollback invocations in Transactor methods;
|
||||
// System.err.println ("Created new Connection to "+url);
|
||||
tx.registerConnection (this, con);
|
||||
//////////////////////////////////////////////
|
||||
/* DatabaseMetaData meta = con.getMetaData ();
|
||||
ResultSet tables = meta.getCatalogs ();
|
||||
while (tables.next())
|
||||
System.err.println ("********* TABLE: "+ tables.getObject (1));
|
||||
ResultSet types = meta.getTypeInfo ();
|
||||
while (types.next())
|
||||
System.err.println ("******* TYPE: "+types.getObject(1) +" - "+types.getObject(2)+" - "+types.getObject(6));
|
||||
*/
|
||||
}
|
||||
return con;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*
|
||||
* @throws ClassNotFoundException ...
|
||||
* @throws SQLException ...
|
||||
*/
|
||||
public Connection getConnection() throws ClassNotFoundException, SQLException {
|
||||
Transactor tx = (Transactor) Thread.currentThread();
|
||||
Connection con = tx.getConnection(this);
|
||||
boolean fileUpdated = props.lastModified() > lastRead;
|
||||
|
||||
if (!fileUpdated && (defaultProps != null)) {
|
||||
fileUpdated = defaultProps.lastModified() > lastRead;
|
||||
}
|
||||
|
||||
if ((con == null) || con.isClosed() || fileUpdated) {
|
||||
init();
|
||||
Class.forName(driver);
|
||||
con = DriverManager.getConnection(url, user, password);
|
||||
|
||||
// If we wanted to use SQL transactions, we'd set autoCommit to
|
||||
// false here and make commit/rollback invocations in Transactor methods;
|
||||
// System.err.println ("Created new Connection to "+url);
|
||||
tx.registerConnection(this, con);
|
||||
}
|
||||
|
||||
return con;
|
||||
}
|
||||
|
||||
private void init () throws ClassNotFoundException {
|
||||
lastRead = defaultProps == null ? props.lastModified () : Math.max (props.lastModified (), defaultProps.lastModified ());
|
||||
url = props.getProperty (name+".url");
|
||||
driver = props.getProperty (name+".driver");
|
||||
Class.forName (driver);
|
||||
user = props.getProperty (name+".user");
|
||||
password = props.getProperty (name+".password");
|
||||
private void init() throws ClassNotFoundException {
|
||||
lastRead = (defaultProps == null) ? props.lastModified()
|
||||
: Math.max(props.lastModified(),
|
||||
defaultProps.lastModified());
|
||||
url = props.getProperty(name + ".url");
|
||||
driver = props.getProperty(name + ".driver");
|
||||
Class.forName(driver);
|
||||
user = props.getProperty(name + ".user");
|
||||
password = props.getProperty(name + ".password");
|
||||
}
|
||||
|
||||
public String getDriverName () {
|
||||
return driver;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getDriverName() {
|
||||
return driver;
|
||||
}
|
||||
|
||||
public String getName () {
|
||||
return name;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public static void setDefaultProps (SystemProperties props) {
|
||||
defaultProps = props;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param props ...
|
||||
*/
|
||||
public static void setDefaultProps(SystemProperties props) {
|
||||
defaultProps = props;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,5 +1,18 @@
|
|||
// ExternalizableVector.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.objectmodel.db;
|
||||
|
||||
|
@ -7,33 +20,45 @@ import java.io.*;
|
|||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* A subclass of Vector that implements the Externalizable interface in order
|
||||
* A subclass of Vector that implements the Externalizable interface in order
|
||||
* to be able to control how it is serialized and deserialized.
|
||||
*/
|
||||
|
||||
public class ExternalizableVector extends ArrayList implements Externalizable {
|
||||
|
||||
static final long serialVersionUID = 2316243615310540423L;
|
||||
|
||||
public synchronized void readExternal (ObjectInput in) throws IOException {
|
||||
try {
|
||||
int size = in.readInt ();
|
||||
for (int i=0; i<size; i++)
|
||||
add (in.readObject ());
|
||||
} catch (ClassNotFoundException x) {
|
||||
throw new IOException (x.toString ());
|
||||
}
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param in ...
|
||||
*
|
||||
* @throws IOException ...
|
||||
*/
|
||||
public synchronized void readExternal(ObjectInput in)
|
||||
throws IOException {
|
||||
try {
|
||||
int size = in.readInt();
|
||||
|
||||
for (int i = 0; i < size; i++)
|
||||
add(in.readObject());
|
||||
} catch (ClassNotFoundException x) {
|
||||
throw new IOException(x.toString());
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void writeExternal (ObjectOutput out) throws IOException {
|
||||
int size = size ();
|
||||
out.writeInt (size);
|
||||
for (int i=0; i<size; i++)
|
||||
out.writeObject (get (i));
|
||||
}
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param out ...
|
||||
*
|
||||
* @throws IOException ...
|
||||
*/
|
||||
public synchronized void writeExternal(ObjectOutput out)
|
||||
throws IOException {
|
||||
int size = size();
|
||||
|
||||
out.writeInt(size);
|
||||
|
||||
for (int i = 0; i < size; i++)
|
||||
out.writeObject(get(i));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,73 +1,84 @@
|
|||
// IDGenerator.java
|
||||
// Copyright (c) Hannes Wallnöfer 1997-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.db;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* An object that generates IDs (Strings) that are unique across the whole system.
|
||||
* It does this keeping a simple long value which is incremented for each new ID.
|
||||
* This is the key generation for nodes stored in the internal database, but it can
|
||||
* also be used for relational nodes if no other mechanism is available. (Sequences
|
||||
* An object that generates IDs (Strings) that are unique across the whole system.
|
||||
* It does this keeping a simple long value which is incremented for each new ID.
|
||||
* This is the key generation for nodes stored in the internal database, but it can
|
||||
* also be used for relational nodes if no other mechanism is available. (Sequences
|
||||
* in Oracle are supported, while auto-IDs are not, since the HOP has to know
|
||||
* the keys of new objects.)
|
||||
*/
|
||||
|
||||
public final class IDGenerator implements Serializable {
|
||||
|
||||
static final long serialVersionUID = 753408631669789263L;
|
||||
private long counter;
|
||||
transient volatile boolean dirty;
|
||||
|
||||
static final long serialVersionUID = 753408631669789263L;
|
||||
|
||||
|
||||
/**
|
||||
* Builds a new IDGenerator starting with 0.
|
||||
*/
|
||||
public IDGenerator () {
|
||||
this.counter = 0l;
|
||||
dirty = false;
|
||||
*/
|
||||
public IDGenerator() {
|
||||
this.counter = 0L;
|
||||
dirty = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a new IDGenerator starting with value.
|
||||
*/
|
||||
public IDGenerator (long value) {
|
||||
this.counter = value;
|
||||
dirty = false;
|
||||
*/
|
||||
public IDGenerator(long value) {
|
||||
this.counter = value;
|
||||
dirty = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delivers a unique id and increases counter by 1.
|
||||
*/
|
||||
public synchronized String newID () {
|
||||
counter += 1l;
|
||||
dirty = true;
|
||||
return Long.toString (counter);
|
||||
* Delivers a unique id and increases counter by 1.
|
||||
*/
|
||||
public synchronized String newID() {
|
||||
counter += 1L;
|
||||
dirty = true;
|
||||
|
||||
return Long.toString(counter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the counter to a new value
|
||||
*/
|
||||
protected synchronized void setValue (long value) {
|
||||
counter = value;
|
||||
dirty = true;
|
||||
protected synchronized void setValue(long value) {
|
||||
counter = value;
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current counter value
|
||||
*/
|
||||
public long getValue () {
|
||||
return counter;
|
||||
public long getValue() {
|
||||
return counter;
|
||||
}
|
||||
|
||||
|
||||
public String toString () {
|
||||
return "helma.objectmodel.db.IDGenerator[counter="+counter+",dirty="+dirty+"]";
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String toString() {
|
||||
return "helma.objectmodel.db.IDGenerator[counter=" + counter + ",dirty=" + dirty +
|
||||
"]";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,5 +1,18 @@
|
|||
// IReplicationListener.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.objectmodel.db;
|
||||
|
||||
|
@ -9,13 +22,11 @@ import java.util.Vector;
|
|||
/**
|
||||
* RMI interface for an application. Currently only execute is used and supported.
|
||||
*/
|
||||
|
||||
public interface IReplicationListener extends Remote {
|
||||
|
||||
/**
|
||||
* Update HopObjects in this application's cache. This is used to replicate
|
||||
* application caches in a distributed app environment
|
||||
*/
|
||||
public void replicateCache (Vector add, Vector delete) throws RemoteException;
|
||||
|
||||
public void replicateCache(Vector add, Vector delete)
|
||||
throws RemoteException;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,19 @@
|
|||
// Key.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.db;
|
||||
|
||||
|
||||
|
@ -9,66 +22,24 @@ package helma.objectmodel.db;
|
|||
*
|
||||
*/
|
||||
public interface Key {
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public Key getParentKey();
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getID();
|
||||
|
||||
public Key getParentKey ();
|
||||
|
||||
public String getID ();
|
||||
|
||||
public String getStorageName ();
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getStorageName();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,6 +1,19 @@
|
|||
// NodeHandle.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.db;
|
||||
|
||||
import helma.objectmodel.*;
|
||||
|
@ -16,8 +29,8 @@ import java.io.Serializable;
|
|||
* and reinstanciated since being set, NodeHandle will always return an up-to-date
|
||||
* instance of its node.
|
||||
*/
|
||||
|
||||
public final class NodeHandle implements INodeState, Serializable {
|
||||
static final long serialVersionUID = 3067763116576910931L;
|
||||
|
||||
// direct reference to the node
|
||||
private Node node;
|
||||
|
@ -25,20 +38,19 @@ public final class NodeHandle implements INodeState, Serializable {
|
|||
// the node's key
|
||||
private Key key;
|
||||
|
||||
static final long serialVersionUID = 3067763116576910931L;
|
||||
|
||||
/**
|
||||
* Builds a handle for a node
|
||||
*/
|
||||
public NodeHandle (Node node) {
|
||||
int state = node.getState ();
|
||||
if (state == TRANSIENT) {
|
||||
this.node = node;
|
||||
key = null;
|
||||
} else {
|
||||
this.node = null;
|
||||
key = node.getKey ();
|
||||
}
|
||||
public NodeHandle(Node node) {
|
||||
int state = node.getState();
|
||||
|
||||
if (state == TRANSIENT) {
|
||||
this.node = node;
|
||||
key = null;
|
||||
} else {
|
||||
this.node = null;
|
||||
key = node.getKey();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -46,73 +58,90 @@ public final class NodeHandle implements INodeState, Serializable {
|
|||
* the node is ususally not yet created. It will be fetched on demand when accessed by
|
||||
* application code.
|
||||
*/
|
||||
public NodeHandle (Key key) {
|
||||
this.node = null;
|
||||
this.key = key;
|
||||
public NodeHandle(Key key) {
|
||||
this.node = null;
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the node described by this node handle
|
||||
*/
|
||||
public Node getNode (WrappedNodeManager nodemgr) {
|
||||
if (node != null)
|
||||
return node;
|
||||
return nodemgr.getNode (key);
|
||||
public Node getNode(WrappedNodeManager nodemgr) {
|
||||
if (node != null) {
|
||||
return node;
|
||||
}
|
||||
|
||||
return nodemgr.getNode(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the key for the node described by this handle.
|
||||
* Get the key for the node described by this handle.
|
||||
* This may only be called on persistent Nodes.
|
||||
*/
|
||||
public Key getKey () {
|
||||
if (key == null)
|
||||
throw new RuntimeException ("getKey called on transient Node");
|
||||
return key;
|
||||
public Key getKey() {
|
||||
if (key == null) {
|
||||
throw new RuntimeException("getKey called on transient Node");
|
||||
}
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the ID for the node described by this handle.
|
||||
* Get the ID for the node described by this handle.
|
||||
* This may only be called on persistent Nodes.
|
||||
*/
|
||||
public String getID () {
|
||||
if (key == null)
|
||||
return node.getID ();
|
||||
return key.getID ();
|
||||
public String getID() {
|
||||
if (key == null) {
|
||||
return node.getID();
|
||||
}
|
||||
|
||||
return key.getID();
|
||||
}
|
||||
|
||||
private Object getObject () {
|
||||
if (node != null)
|
||||
return node;
|
||||
else
|
||||
return key;
|
||||
private Object getObject() {
|
||||
if (node != null) {
|
||||
return node;
|
||||
} else {
|
||||
return key;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean equals (Object other) {
|
||||
try {
|
||||
return getObject ().equals (((NodeHandle) other).getObject ());
|
||||
} catch (Exception x) {
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param other ...
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public boolean equals(Object other) {
|
||||
try {
|
||||
return getObject().equals(((NodeHandle) other).getObject());
|
||||
} catch (Exception x) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This is to notify the handle that the underlying node is becoming
|
||||
* persistent and we have to refer to it via the key from now on.
|
||||
*/
|
||||
protected void becomePersistent () {
|
||||
if (node != null) {
|
||||
key = node.getKey ();
|
||||
node = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public String toString () {
|
||||
if (node != null)
|
||||
return "NodeHandle[transient:"+node+"]";
|
||||
else
|
||||
return "NodeHandle["+key+"]";
|
||||
protected void becomePersistent() {
|
||||
if (node != null) {
|
||||
key = node.getKey();
|
||||
node = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String toString() {
|
||||
if (node != null) {
|
||||
return "NodeHandle[transient:" + node + "]";
|
||||
} else {
|
||||
return "NodeHandle[" + key + "]";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,5 +1,18 @@
|
|||
// ParentInfo.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.objectmodel.db;
|
||||
|
||||
|
@ -7,35 +20,45 @@ package helma.objectmodel.db;
|
|||
/**
|
||||
* This class describes a parent relation between releational nodes.
|
||||
*/
|
||||
|
||||
public class ParentInfo {
|
||||
|
||||
public final String propname;
|
||||
public final String virtualname;
|
||||
public final boolean named;
|
||||
public final boolean isroot;
|
||||
|
||||
/**
|
||||
* Creates a new ParentInfo object.
|
||||
*
|
||||
* @param desc ...
|
||||
*/
|
||||
public ParentInfo(String desc) {
|
||||
int n = desc.indexOf("[named]");
|
||||
|
||||
public ParentInfo (String desc) {
|
||||
int n = desc.indexOf ("[named]");
|
||||
named = n > -1;
|
||||
String d = named ? desc.substring (0, n) : desc;
|
||||
named = n > -1;
|
||||
|
||||
int dot = d.indexOf (".");
|
||||
if (dot > -1) {
|
||||
propname = d.substring (0, dot).trim();
|
||||
virtualname = d.substring (dot+1).trim();
|
||||
} else {
|
||||
propname = d.trim();
|
||||
virtualname = null;
|
||||
}
|
||||
|
||||
isroot = "root".equals (propname);
|
||||
// System.err.println ("created "+this);
|
||||
}
|
||||
String d = named ? desc.substring(0, n) : desc;
|
||||
|
||||
public String toString () {
|
||||
return "ParentInfo["+propname+","+virtualname+","+named+"]";
|
||||
int dot = d.indexOf(".");
|
||||
|
||||
if (dot > -1) {
|
||||
propname = d.substring(0, dot).trim();
|
||||
virtualname = d.substring(dot + 1).trim();
|
||||
} else {
|
||||
propname = d.trim();
|
||||
virtualname = null;
|
||||
}
|
||||
|
||||
isroot = "root".equals(propname);
|
||||
|
||||
// System.err.println ("created "+this);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String toString() {
|
||||
return "ParentInfo[" + propname + "," + virtualname + "," + named + "]";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,342 +1,558 @@
|
|||
// Property.java
|
||||
// Copyright (c) Hannes Wallnöfer 1997-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.db;
|
||||
|
||||
import helma.util.*;
|
||||
import java.util.*;
|
||||
import java.io.*;
|
||||
import java.text.*;
|
||||
import helma.objectmodel.*;
|
||||
import helma.util.*;
|
||||
import java.io.*;
|
||||
import java.sql.Timestamp;
|
||||
import java.text.*;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* A property implementation for Nodes stored inside a database. Basically
|
||||
* the same as for transient nodes, with a few hooks added.
|
||||
*/
|
||||
public final class Property implements IProperty, Serializable, Cloneable {
|
||||
|
||||
|
||||
static final long serialVersionUID = -1022221688349192379L;
|
||||
private String propname;
|
||||
private Node node;
|
||||
|
||||
private Object value;
|
||||
|
||||
private int type;
|
||||
|
||||
transient boolean dirty;
|
||||
|
||||
static final long serialVersionUID = -1022221688349192379L;
|
||||
|
||||
private void readObject (ObjectInputStream in) throws IOException {
|
||||
try {
|
||||
propname = in.readUTF ();
|
||||
node = (Node) in.readObject ();
|
||||
type = in.readInt ();
|
||||
switch (type) {
|
||||
case STRING:
|
||||
// try to convert from old format
|
||||
if (node.version < 7)
|
||||
value = in.readUTF ();
|
||||
else
|
||||
value = in.readObject ();
|
||||
break;
|
||||
case BOOLEAN:
|
||||
value = in.readBoolean () ? Boolean.TRUE : Boolean.FALSE;
|
||||
break;
|
||||
case INTEGER:
|
||||
value = new Long (in.readLong ());
|
||||
break;
|
||||
case DATE:
|
||||
value = new Date (in.readLong ());
|
||||
break;
|
||||
case FLOAT:
|
||||
value = new Double (in.readDouble ());
|
||||
break;
|
||||
case NODE:
|
||||
// try to convert from old format
|
||||
if (node.version > 4)
|
||||
value = (NodeHandle) in.readObject ();
|
||||
else
|
||||
value = new NodeHandle (new DbKey (null, in.readUTF ()));
|
||||
break;
|
||||
case JAVAOBJECT:
|
||||
value = in.readObject ();
|
||||
break;
|
||||
}
|
||||
} catch (ClassNotFoundException x) {
|
||||
throw new IOException (x.toString ());
|
||||
}
|
||||
/**
|
||||
* Creates a new Property object.
|
||||
*
|
||||
* @param node ...
|
||||
*/
|
||||
public Property(Node node) {
|
||||
this.node = node;
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
private void writeObject (ObjectOutputStream out) throws IOException {
|
||||
out.writeUTF (propname);
|
||||
out.writeObject (node);
|
||||
out.writeInt (type);
|
||||
switch (type) {
|
||||
case STRING:
|
||||
out.writeObject (value);
|
||||
break;
|
||||
case BOOLEAN:
|
||||
out.writeBoolean (((Boolean) value).booleanValue());
|
||||
break;
|
||||
case INTEGER:
|
||||
out.writeLong (((Long) value).longValue());
|
||||
break;
|
||||
case DATE:
|
||||
out.writeLong (((Date) value).getTime());
|
||||
break;
|
||||
case FLOAT:
|
||||
out.writeDouble (((Double) value).doubleValue());
|
||||
break;
|
||||
case NODE:
|
||||
out.writeObject (value);
|
||||
break;
|
||||
case JAVAOBJECT:
|
||||
if (value != null && !(value instanceof Serializable))
|
||||
out.writeObject (null);
|
||||
else
|
||||
out.writeObject (value);
|
||||
break;
|
||||
}
|
||||
/**
|
||||
* Creates a new Property object.
|
||||
*
|
||||
* @param propname ...
|
||||
* @param node ...
|
||||
*/
|
||||
public Property(String propname, Node node) {
|
||||
this.propname = propname;
|
||||
this.node = node;
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
|
||||
public Property (Node node) {
|
||||
this.node = node;
|
||||
dirty = true;
|
||||
/**
|
||||
* Creates a new Property object.
|
||||
*
|
||||
* @param propname ...
|
||||
* @param node ...
|
||||
* @param valueNode ...
|
||||
*/
|
||||
public Property(String propname, Node node, Node valueNode) {
|
||||
this(propname, node);
|
||||
type = NODE;
|
||||
value = (valueNode == null) ? null : valueNode.getHandle();
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
public Property (String propname, Node node) {
|
||||
this.propname = propname;
|
||||
this.node = node;
|
||||
dirty = true;
|
||||
private void readObject(ObjectInputStream in) throws IOException {
|
||||
try {
|
||||
propname = in.readUTF();
|
||||
node = (Node) in.readObject();
|
||||
type = in.readInt();
|
||||
|
||||
switch (type) {
|
||||
case STRING:
|
||||
|
||||
// try to convert from old format
|
||||
if (node.version < 7) {
|
||||
value = in.readUTF();
|
||||
} else {
|
||||
value = in.readObject();
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case BOOLEAN:
|
||||
value = in.readBoolean() ? Boolean.TRUE : Boolean.FALSE;
|
||||
|
||||
break;
|
||||
|
||||
case INTEGER:
|
||||
value = new Long(in.readLong());
|
||||
|
||||
break;
|
||||
|
||||
case DATE:
|
||||
value = new Date(in.readLong());
|
||||
|
||||
break;
|
||||
|
||||
case FLOAT:
|
||||
value = new Double(in.readDouble());
|
||||
|
||||
break;
|
||||
|
||||
case NODE:
|
||||
|
||||
// try to convert from old format
|
||||
if (node.version > 4) {
|
||||
value = (NodeHandle) in.readObject();
|
||||
} else {
|
||||
value = new NodeHandle(new DbKey(null, in.readUTF()));
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case JAVAOBJECT:
|
||||
value = in.readObject();
|
||||
|
||||
break;
|
||||
}
|
||||
} catch (ClassNotFoundException x) {
|
||||
throw new IOException(x.toString());
|
||||
}
|
||||
}
|
||||
|
||||
public Property (String propname, Node node, Node valueNode) {
|
||||
this (propname, node);
|
||||
type = NODE;
|
||||
value = valueNode == null ? null : valueNode.getHandle ();
|
||||
dirty = true;
|
||||
private void writeObject(ObjectOutputStream out) throws IOException {
|
||||
out.writeUTF(propname);
|
||||
out.writeObject(node);
|
||||
out.writeInt(type);
|
||||
|
||||
switch (type) {
|
||||
case STRING:
|
||||
out.writeObject(value);
|
||||
|
||||
break;
|
||||
|
||||
case BOOLEAN:
|
||||
out.writeBoolean(((Boolean) value).booleanValue());
|
||||
|
||||
break;
|
||||
|
||||
case INTEGER:
|
||||
out.writeLong(((Long) value).longValue());
|
||||
|
||||
break;
|
||||
|
||||
case DATE:
|
||||
out.writeLong(((Date) value).getTime());
|
||||
|
||||
break;
|
||||
|
||||
case FLOAT:
|
||||
out.writeDouble(((Double) value).doubleValue());
|
||||
|
||||
break;
|
||||
|
||||
case NODE:
|
||||
out.writeObject(value);
|
||||
|
||||
break;
|
||||
|
||||
case JAVAOBJECT:
|
||||
|
||||
if ((value != null) && !(value instanceof Serializable)) {
|
||||
out.writeObject(null);
|
||||
} else {
|
||||
out.writeObject(value);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public String getName () {
|
||||
return propname;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getName() {
|
||||
return propname;
|
||||
}
|
||||
|
||||
public Object getValue () {
|
||||
return value;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public Object getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public int getType () {
|
||||
return type;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public int getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setStringValue (String str) {
|
||||
if (type == NODE)
|
||||
unregisterNode ();
|
||||
type = STRING;
|
||||
value = str;
|
||||
dirty = true;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param str ...
|
||||
*/
|
||||
public void setStringValue(String str) {
|
||||
if (type == NODE) {
|
||||
unregisterNode();
|
||||
}
|
||||
|
||||
type = STRING;
|
||||
value = str;
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param l ...
|
||||
*/
|
||||
public void setIntegerValue(long l) {
|
||||
if (type == NODE) {
|
||||
unregisterNode();
|
||||
}
|
||||
|
||||
public void setIntegerValue (long l) {
|
||||
if (type == NODE)
|
||||
unregisterNode ();
|
||||
type = INTEGER;
|
||||
value = new Long(l);
|
||||
dirty = true;
|
||||
type = INTEGER;
|
||||
value = new Long(l);
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
public void setFloatValue (double d) {
|
||||
if (type == NODE)
|
||||
unregisterNode ();
|
||||
type = FLOAT;
|
||||
value = new Double(d);
|
||||
dirty = true;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param d ...
|
||||
*/
|
||||
public void setFloatValue(double d) {
|
||||
if (type == NODE) {
|
||||
unregisterNode();
|
||||
}
|
||||
|
||||
type = FLOAT;
|
||||
value = new Double(d);
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
public void setDateValue (Date date) {
|
||||
if (type == NODE)
|
||||
unregisterNode ();
|
||||
type = DATE;
|
||||
value = date;
|
||||
dirty = true;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param date ...
|
||||
*/
|
||||
public void setDateValue(Date date) {
|
||||
if (type == NODE) {
|
||||
unregisterNode();
|
||||
}
|
||||
|
||||
type = DATE;
|
||||
value = date;
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
public void setBooleanValue (boolean bool) {
|
||||
if (type == NODE)
|
||||
unregisterNode ();
|
||||
type = BOOLEAN;
|
||||
value = bool ? Boolean.TRUE : Boolean.FALSE;
|
||||
dirty = true;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param bool ...
|
||||
*/
|
||||
public void setBooleanValue(boolean bool) {
|
||||
if (type == NODE) {
|
||||
unregisterNode();
|
||||
}
|
||||
|
||||
type = BOOLEAN;
|
||||
value = bool ? Boolean.TRUE : Boolean.FALSE;
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
public void setNodeValue (Node node) {
|
||||
// value.checkWriteLock ();
|
||||
if (type == NODE)
|
||||
unregisterNode ();
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param node ...
|
||||
*/
|
||||
public void setNodeValue(Node node) {
|
||||
// value.checkWriteLock ();
|
||||
if (type == NODE) {
|
||||
unregisterNode();
|
||||
}
|
||||
|
||||
// registerNode (value);
|
||||
type = NODE;
|
||||
// registerNode (value);
|
||||
type = NODE;
|
||||
|
||||
value = node == null ? null : node.getHandle ();
|
||||
dirty = true;
|
||||
value = (node == null) ? null : node.getHandle();
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
public void setNodeHandle (NodeHandle handle) {
|
||||
if (type == NODE)
|
||||
unregisterNode ();
|
||||
// registerNode (value);
|
||||
type = NODE;
|
||||
value = handle;
|
||||
dirty = true;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param handle ...
|
||||
*/
|
||||
public void setNodeHandle(NodeHandle handle) {
|
||||
if (type == NODE) {
|
||||
unregisterNode();
|
||||
}
|
||||
|
||||
// registerNode (value);
|
||||
type = NODE;
|
||||
value = handle;
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
public NodeHandle getNodeHandle () {
|
||||
if (type == NODE)
|
||||
return (NodeHandle) value;
|
||||
return null;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public NodeHandle getNodeHandle() {
|
||||
if (type == NODE) {
|
||||
return (NodeHandle) value;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void convertToNodeReference (DbMapping dbm) {
|
||||
if (value != null && !(value instanceof NodeHandle))
|
||||
value = new NodeHandle (new DbKey (dbm, value.toString ()));
|
||||
type = NODE;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param dbm ...
|
||||
*/
|
||||
public void convertToNodeReference(DbMapping dbm) {
|
||||
if ((value != null) && !(value instanceof NodeHandle)) {
|
||||
value = new NodeHandle(new DbKey(dbm, value.toString()));
|
||||
}
|
||||
|
||||
type = NODE;
|
||||
}
|
||||
|
||||
public void setJavaObjectValue (Object obj) {
|
||||
if (type == NODE)
|
||||
unregisterNode ();
|
||||
type = JAVAOBJECT;
|
||||
value = obj;
|
||||
}
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param obj ...
|
||||
*/
|
||||
public void setJavaObjectValue(Object obj) {
|
||||
if (type == NODE) {
|
||||
unregisterNode();
|
||||
}
|
||||
|
||||
type = JAVAOBJECT;
|
||||
value = obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* tell a the value node that it is no longer used as a property.
|
||||
* If this was the "main" property for the node, also remove all other references.
|
||||
*/
|
||||
protected void unregisterNode () {
|
||||
if (value == null || !(value instanceof NodeHandle))
|
||||
return;
|
||||
NodeHandle nhandle = (NodeHandle) value;
|
||||
Node nvalue = nhandle.getNode (node.nmgr);
|
||||
protected void unregisterNode() {
|
||||
if ((value == null) || !(value instanceof NodeHandle)) {
|
||||
return;
|
||||
}
|
||||
|
||||
DbMapping nvmap = null;
|
||||
Relation nvrel = null;
|
||||
if (node.dbmap != null) {
|
||||
nvmap = node.dbmap.getPropertyMapping (propname);
|
||||
nvrel = node.dbmap.getPropertyRelation (propname);
|
||||
}
|
||||
NodeHandle nhandle = (NodeHandle) value;
|
||||
Node nvalue = nhandle.getNode(node.nmgr);
|
||||
|
||||
if (nvalue == null)
|
||||
return;
|
||||
DbMapping nvmap = null;
|
||||
Relation nvrel = null;
|
||||
|
||||
nvalue.checkWriteLock ();
|
||||
// check if the property node is also a subnode
|
||||
// BUG: this doesn't work because properties for subnode/properties are never stored and therefore
|
||||
// never reused.
|
||||
if (nvrel != null && nvrel.hasAccessName()) {
|
||||
node.removeNode (nvalue);
|
||||
}
|
||||
// only need to call unregisterPropLink if the value node is not stored in a relational db
|
||||
// also, getParent is heuristical/implicit for relational nodes, so we don't do deepRemoveNode
|
||||
// based on that for relational nodes.
|
||||
if (nvmap == null || !nvmap.isRelational()) {
|
||||
if (!nvalue.isAnonymous() && propname.equals (nvalue.getName()) && this.node == nvalue.getParent()) {
|
||||
// this is the "main" property of a named node, so handle this as a cascading delete.
|
||||
nvalue.deepRemoveNode ();
|
||||
}
|
||||
}
|
||||
if (node.dbmap != null) {
|
||||
nvmap = node.dbmap.getPropertyMapping(propname);
|
||||
nvrel = node.dbmap.getPropertyRelation(propname);
|
||||
}
|
||||
|
||||
if (nvalue == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
nvalue.checkWriteLock();
|
||||
|
||||
// check if the property node is also a subnode
|
||||
// BUG: this doesn't work because properties for subnode/properties are never stored and therefore
|
||||
// never reused.
|
||||
if ((nvrel != null) && nvrel.hasAccessName()) {
|
||||
node.removeNode(nvalue);
|
||||
}
|
||||
|
||||
// only need to call unregisterPropLink if the value node is not stored in a relational db
|
||||
// also, getParent is heuristical/implicit for relational nodes, so we don't do deepRemoveNode
|
||||
// based on that for relational nodes.
|
||||
if ((nvmap == null) || !nvmap.isRelational()) {
|
||||
if (!nvalue.isAnonymous() && propname.equals(nvalue.getName()) &&
|
||||
(this.node == nvalue.getParent())) {
|
||||
// this is the "main" property of a named node, so handle this as a cascading delete.
|
||||
nvalue.deepRemoveNode();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getStringValue() {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getStringValue () {
|
||||
if (value == null)
|
||||
return null;
|
||||
switch (type) {
|
||||
case STRING:
|
||||
case BOOLEAN:
|
||||
case INTEGER:
|
||||
case FLOAT:
|
||||
case JAVAOBJECT:
|
||||
return value.toString ();
|
||||
case DATE:
|
||||
SimpleDateFormat format = new SimpleDateFormat ("dd.MM.yy hh:mm:ss");
|
||||
return format.format ((Date) value);
|
||||
case NODE:
|
||||
return ((NodeHandle) value).getID ();
|
||||
}
|
||||
return "";
|
||||
switch (type) {
|
||||
case STRING:
|
||||
case BOOLEAN:
|
||||
case INTEGER:
|
||||
case FLOAT:
|
||||
case JAVAOBJECT:
|
||||
return value.toString();
|
||||
|
||||
case DATE:
|
||||
|
||||
SimpleDateFormat format = new SimpleDateFormat("dd.MM.yy hh:mm:ss");
|
||||
|
||||
return format.format((Date) value);
|
||||
|
||||
case NODE:
|
||||
return ((NodeHandle) value).getID();
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
public String toString () {
|
||||
return getStringValue ();
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String toString() {
|
||||
return getStringValue();
|
||||
}
|
||||
|
||||
public long getIntegerValue () {
|
||||
if (type == INTEGER)
|
||||
return ((Long) value).longValue ();
|
||||
if (type == FLOAT)
|
||||
return ((Double) value).longValue ();
|
||||
if (type == BOOLEAN)
|
||||
return ((Boolean) value).booleanValue() ? 1 : 0;
|
||||
try {
|
||||
return Long.parseLong (getStringValue());
|
||||
} catch (Exception x) {
|
||||
return 0;
|
||||
}
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public long getIntegerValue() {
|
||||
if (type == INTEGER) {
|
||||
return ((Long) value).longValue();
|
||||
}
|
||||
|
||||
if (type == FLOAT) {
|
||||
return ((Double) value).longValue();
|
||||
}
|
||||
|
||||
if (type == BOOLEAN) {
|
||||
return ((Boolean) value).booleanValue() ? 1 : 0;
|
||||
}
|
||||
|
||||
try {
|
||||
return Long.parseLong(getStringValue());
|
||||
} catch (Exception x) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public double getFloatValue () {
|
||||
if (type == FLOAT)
|
||||
return ((Double) value).doubleValue();
|
||||
if (type == INTEGER)
|
||||
return ((Long) value).doubleValue ();
|
||||
try {
|
||||
return Double.parseDouble (getStringValue());
|
||||
} catch (Exception x) {
|
||||
return 0.0;
|
||||
}
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public double getFloatValue() {
|
||||
if (type == FLOAT) {
|
||||
return ((Double) value).doubleValue();
|
||||
}
|
||||
|
||||
if (type == INTEGER) {
|
||||
return ((Long) value).doubleValue();
|
||||
}
|
||||
|
||||
try {
|
||||
return Double.parseDouble(getStringValue());
|
||||
} catch (Exception x) {
|
||||
return 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public Date getDateValue() {
|
||||
if (type == DATE) {
|
||||
return (Date) value;
|
||||
}
|
||||
|
||||
public Date getDateValue () {
|
||||
if (type == DATE)
|
||||
return (Date) value;
|
||||
return null;
|
||||
return null;
|
||||
}
|
||||
|
||||
public Timestamp getTimestampValue () {
|
||||
if (type == DATE && value != null)
|
||||
return new Timestamp (((Date) value).getTime());
|
||||
return null;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public Timestamp getTimestampValue() {
|
||||
if ((type == DATE) && (value != null)) {
|
||||
return new Timestamp(((Date) value).getTime());
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean getBooleanValue () {
|
||||
if (type == BOOLEAN)
|
||||
return ((Boolean) value).booleanValue();
|
||||
if (type == INTEGER)
|
||||
return !(0 == getIntegerValue());
|
||||
return false;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public boolean getBooleanValue() {
|
||||
if (type == BOOLEAN) {
|
||||
return ((Boolean) value).booleanValue();
|
||||
}
|
||||
|
||||
if (type == INTEGER) {
|
||||
return !(0 == getIntegerValue());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public INode getNodeValue () {
|
||||
if (type == NODE && value != null) {
|
||||
NodeHandle nhandle = (NodeHandle) value;
|
||||
return nhandle.getNode (node.nmgr);
|
||||
}
|
||||
return null;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public INode getNodeValue() {
|
||||
if ((type == NODE) && (value != null)) {
|
||||
NodeHandle nhandle = (NodeHandle) value;
|
||||
|
||||
return nhandle.getNode(node.nmgr);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public Object getJavaObjectValue () {
|
||||
if (type == JAVAOBJECT)
|
||||
return value;
|
||||
return null;
|
||||
}
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public Object getJavaObjectValue() {
|
||||
if (type == JAVAOBJECT) {
|
||||
return value;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,6 +1,19 @@
|
|||
// Replicator.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.db;
|
||||
|
||||
import java.rmi.*;
|
||||
|
@ -9,76 +22,113 @@ import java.util.*;
|
|||
/**
|
||||
* This class replicates the updates of transactions to other applications via RMI
|
||||
*/
|
||||
|
||||
public class Replicator implements Runnable {
|
||||
|
||||
Vector urls;
|
||||
Vector add, delete, currentAdd, currentDelete;
|
||||
Vector add;
|
||||
Vector delete;
|
||||
Vector currentAdd;
|
||||
Vector currentDelete;
|
||||
Thread runner;
|
||||
NodeManager nmgr;
|
||||
|
||||
public Replicator (NodeManager nmgr) {
|
||||
urls = new Vector ();
|
||||
add = new Vector ();
|
||||
delete = new Vector ();
|
||||
this.nmgr = nmgr;
|
||||
runner = new Thread (this);
|
||||
runner.start ();
|
||||
/**
|
||||
* Creates a new Replicator object.
|
||||
*
|
||||
* @param nmgr ...
|
||||
*/
|
||||
public Replicator(NodeManager nmgr) {
|
||||
urls = new Vector();
|
||||
add = new Vector();
|
||||
delete = new Vector();
|
||||
this.nmgr = nmgr;
|
||||
runner = new Thread(this);
|
||||
runner.start();
|
||||
}
|
||||
|
||||
public void addUrl (String url) {
|
||||
urls.addElement (url);
|
||||
if (nmgr.logReplication)
|
||||
nmgr.app.logEvent ("Adding replication listener: "+url);
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param url ...
|
||||
*/
|
||||
public void addUrl(String url) {
|
||||
urls.addElement(url);
|
||||
|
||||
if (nmgr.logReplication) {
|
||||
nmgr.app.logEvent("Adding replication listener: " + url);
|
||||
}
|
||||
}
|
||||
|
||||
public void run () {
|
||||
while (Thread.currentThread () == runner) {
|
||||
if (prepareReplication ()) {
|
||||
for (int i=0; i<urls.size(); i++) {
|
||||
try {
|
||||
String url = (String) urls.elementAt (i);
|
||||
IReplicationListener listener = (IReplicationListener) Naming.lookup (url);
|
||||
listener.replicateCache (currentAdd, currentDelete);
|
||||
if (nmgr.logReplication)
|
||||
nmgr.app.logEvent ("Sent cache replication event: "+add.size()+" added, "+delete.size()+" deleted");
|
||||
} catch (Exception x) {
|
||||
nmgr.app.logEvent ("Error sending cache replication event: "+x);
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void run() {
|
||||
while (Thread.currentThread() == runner) {
|
||||
if (prepareReplication()) {
|
||||
for (int i = 0; i < urls.size(); i++) {
|
||||
try {
|
||||
String url = (String) urls.elementAt(i);
|
||||
IReplicationListener listener = (IReplicationListener) Naming.lookup(url);
|
||||
|
||||
try {
|
||||
if (runner != null)
|
||||
runner.sleep (1000l);
|
||||
} catch (InterruptedException ir) {
|
||||
runner = null;
|
||||
}
|
||||
}
|
||||
listener.replicateCache(currentAdd, currentDelete);
|
||||
|
||||
if (nmgr.logReplication) {
|
||||
nmgr.app.logEvent("Sent cache replication event: " +
|
||||
add.size() + " added, " + delete.size() +
|
||||
" deleted");
|
||||
}
|
||||
} catch (Exception x) {
|
||||
nmgr.app.logEvent("Error sending cache replication event: " + x);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
if (runner != null) {
|
||||
runner.sleep(1000L);
|
||||
}
|
||||
} catch (InterruptedException ir) {
|
||||
runner = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void addNewNode (Node n) {
|
||||
add.addElement (n);
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param n ...
|
||||
*/
|
||||
public synchronized void addNewNode(Node n) {
|
||||
add.addElement(n);
|
||||
}
|
||||
|
||||
public synchronized void addModifiedNode (Node n) {
|
||||
add.addElement (n);
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param n ...
|
||||
*/
|
||||
public synchronized void addModifiedNode(Node n) {
|
||||
add.addElement(n);
|
||||
}
|
||||
|
||||
public synchronized void addDeletedNode (Node n) {
|
||||
delete.addElement (n);
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param n ...
|
||||
*/
|
||||
public synchronized void addDeletedNode(Node n) {
|
||||
delete.addElement(n);
|
||||
}
|
||||
|
||||
private synchronized boolean prepareReplication () {
|
||||
if (add.size() == 0 && delete.size() == 0)
|
||||
return false;
|
||||
currentAdd = add;
|
||||
currentDelete = delete;
|
||||
add = new Vector ();
|
||||
delete = new Vector ();
|
||||
return true;
|
||||
}
|
||||
private synchronized boolean prepareReplication() {
|
||||
if ((add.size() == 0) && (delete.size() == 0)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
currentAdd = add;
|
||||
currentDelete = delete;
|
||||
add = new Vector();
|
||||
delete = new Vector();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,19 @@
|
|||
// 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.objectmodel.db;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -9,16 +22,12 @@ import java.io.IOException;
|
|||
* Helma server main class. This moved to the helma.main package but a
|
||||
* simple redirector is kept here for backwards compatibility.
|
||||
*/
|
||||
|
||||
public class Server {
|
||||
|
||||
public class Server {
|
||||
/**
|
||||
* Just invoke the main method in the new Server class.
|
||||
*/
|
||||
public static void main (String args[]) throws IOException {
|
||||
System.err.println ("The Helma main class is now in helma.main.Server. Please update your start script accordingly.");
|
||||
helma.main.Server.main (args);
|
||||
public static void main(String[] args) throws IOException {
|
||||
System.err.println("The Helma main class is now in helma.main.Server. Please update your start script accordingly.");
|
||||
helma.main.Server.main(args);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,19 @@
|
|||
// SyntheticKey.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.db;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
@ -9,59 +22,91 @@ import java.io.Serializable;
|
|||
* This is the internal key for an object that is not - or not directly - fetched from a db,
|
||||
* but derived from another object. This is useful for all kinds of object accessed via a
|
||||
* symbolic name from another object, like objects mounted via a property name column,
|
||||
* virtual nodes and groupby nodes.
|
||||
* virtual nodes and groupby nodes.
|
||||
*/
|
||||
public final class SyntheticKey implements Key, Serializable {
|
||||
|
||||
private final Key parentKey;
|
||||
private final String name;
|
||||
|
||||
// lazily initialized hashcode
|
||||
private transient int hashcode = 0;
|
||||
|
||||
|
||||
/**
|
||||
* make a key for a persistent Object, describing its datasource and id.
|
||||
*/
|
||||
public SyntheticKey (Key key, String name) {
|
||||
this.parentKey = key;
|
||||
this.name = name;
|
||||
public SyntheticKey(Key key, String name) {
|
||||
this.parentKey = key;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param what ...
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public boolean equals(Object what) {
|
||||
if (what == this) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean equals (Object what) {
|
||||
if (what == this)
|
||||
return true;
|
||||
if (!(what instanceof SyntheticKey))
|
||||
return false;
|
||||
SyntheticKey k = (SyntheticKey) what;
|
||||
return parentKey.equals (k.parentKey) &&
|
||||
(name == k.name || name.equals (k.name));
|
||||
if (!(what instanceof SyntheticKey)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SyntheticKey k = (SyntheticKey) what;
|
||||
|
||||
return parentKey.equals(k.parentKey) &&
|
||||
((name == k.name) || name.equals(k.name));
|
||||
}
|
||||
|
||||
public int hashCode () {
|
||||
if (hashcode == 0)
|
||||
hashcode = 17 + 37*name.hashCode () + 37*parentKey.hashCode ();
|
||||
return hashcode;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public int hashCode() {
|
||||
if (hashcode == 0) {
|
||||
hashcode = 17 + (37 * name.hashCode()) + (37 * parentKey.hashCode());
|
||||
}
|
||||
|
||||
return hashcode;
|
||||
}
|
||||
|
||||
|
||||
public Key getParentKey () {
|
||||
return parentKey;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public Key getParentKey() {
|
||||
return parentKey;
|
||||
}
|
||||
|
||||
public String getID () {
|
||||
return name;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getID() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getStorageName () {
|
||||
return null;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getStorageName() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String toString () {
|
||||
return parentKey+"/"+name;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String toString() {
|
||||
return parentKey + "/" + name;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -1,251 +1,377 @@
|
|||
// Transactor.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.db;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.sql.*;
|
||||
import helma.framework.TimeoutException;
|
||||
import helma.objectmodel.*;
|
||||
import helma.util.Timer;
|
||||
import helma.framework.TimeoutException;
|
||||
import java.io.*;
|
||||
import java.sql.*;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* A subclass of thread that keeps track of changed nodes and triggers
|
||||
* A subclass of thread that keeps track of changed nodes and triggers
|
||||
* changes in the database when a transaction is commited.
|
||||
*/
|
||||
|
||||
public class Transactor extends Thread {
|
||||
|
||||
NodeManager nmgr;
|
||||
|
||||
// List of nodes to be updated
|
||||
private HashMap nodes;
|
||||
private ArrayList nodesArray;
|
||||
|
||||
// List of visited clean nodes
|
||||
private HashMap cleannodes;
|
||||
|
||||
// Is a transaction in progress?
|
||||
private volatile boolean active;
|
||||
private volatile boolean killed;
|
||||
|
||||
// Transaction for the embedded database
|
||||
protected ITransaction txn;
|
||||
|
||||
// Transactions for SQL data sources
|
||||
protected HashMap sqlCon;
|
||||
|
||||
public Timer timer;
|
||||
|
||||
// when did the current transaction start?
|
||||
private long tstart;
|
||||
|
||||
// a name to log the transaction. For HTTP transactions this is the rerquest path
|
||||
private String tname;
|
||||
|
||||
|
||||
public Transactor (Runnable runnable, ThreadGroup group, NodeManager nmgr) {
|
||||
super (group, runnable, group.getName ());
|
||||
this.nmgr = nmgr;
|
||||
nodes = new HashMap ();
|
||||
nodesArray = new ArrayList ();
|
||||
cleannodes = new HashMap ();
|
||||
sqlCon = new HashMap ();
|
||||
active = false;
|
||||
killed = false;
|
||||
timer = new Timer();
|
||||
/**
|
||||
* Creates a new Transactor object.
|
||||
*
|
||||
* @param runnable ...
|
||||
* @param group ...
|
||||
* @param nmgr ...
|
||||
*/
|
||||
public Transactor(Runnable runnable, ThreadGroup group, NodeManager nmgr) {
|
||||
super(group, runnable, group.getName());
|
||||
this.nmgr = nmgr;
|
||||
nodes = new HashMap();
|
||||
nodesArray = new ArrayList();
|
||||
cleannodes = new HashMap();
|
||||
sqlCon = new HashMap();
|
||||
active = false;
|
||||
killed = false;
|
||||
timer = new Timer();
|
||||
}
|
||||
|
||||
public void visitNode (Node node) {
|
||||
if (node != null) {
|
||||
Key key = node.getKey ();
|
||||
if (!nodes.containsKey (key)) {
|
||||
nodes.put (key, node);
|
||||
nodesArray.add (node);
|
||||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param node ...
|
||||
*/
|
||||
public void visitNode(Node node) {
|
||||
if (node != null) {
|
||||
Key key = node.getKey();
|
||||
|
||||
if (!nodes.containsKey(key)) {
|
||||
nodes.put(key, node);
|
||||
nodesArray.add(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void dropNode (Node node) {
|
||||
if (node != null) {
|
||||
Key key = node.getKey ();
|
||||
nodes.remove (key);
|
||||
nodesArray.remove (node);
|
||||
}
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param node ...
|
||||
*/
|
||||
public void dropNode(Node node) {
|
||||
if (node != null) {
|
||||
Key key = node.getKey();
|
||||
|
||||
nodes.remove(key);
|
||||
nodesArray.remove(node);
|
||||
}
|
||||
}
|
||||
|
||||
public void visitCleanNode (Node node) {
|
||||
if (node != null) {
|
||||
Key key = node.getKey ();
|
||||
if (!cleannodes.containsKey (key)) {
|
||||
cleannodes.put (key, node);
|
||||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param node ...
|
||||
*/
|
||||
public void visitCleanNode(Node node) {
|
||||
if (node != null) {
|
||||
Key key = node.getKey();
|
||||
|
||||
if (!cleannodes.containsKey(key)) {
|
||||
cleannodes.put(key, node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void visitCleanNode (Key key, Node node) {
|
||||
if (node != null) {
|
||||
if (!cleannodes.containsKey (key)) {
|
||||
cleannodes.put (key, node);
|
||||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param key ...
|
||||
* @param node ...
|
||||
*/
|
||||
public void visitCleanNode(Key key, Node node) {
|
||||
if (node != null) {
|
||||
if (!cleannodes.containsKey(key)) {
|
||||
cleannodes.put(key, node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public Node getVisitedNode (Object key) {
|
||||
return key == null ? null : (Node) cleannodes.get (key);
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param key ...
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public Node getVisitedNode(Object key) {
|
||||
return (key == null) ? null : (Node) cleannodes.get(key);
|
||||
}
|
||||
|
||||
public boolean isActive () {
|
||||
return active;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public boolean isActive() {
|
||||
return active;
|
||||
}
|
||||
|
||||
public void registerConnection (DbSource src, Connection con) {
|
||||
sqlCon.put (src, con);
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param src ...
|
||||
* @param con ...
|
||||
*/
|
||||
public void registerConnection(DbSource src, Connection con) {
|
||||
sqlCon.put(src, con);
|
||||
}
|
||||
|
||||
public Connection getConnection (DbSource src) {
|
||||
return (Connection) sqlCon.get (src);
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param src ...
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public Connection getConnection(DbSource src) {
|
||||
return (Connection) sqlCon.get(src);
|
||||
}
|
||||
|
||||
public synchronized void begin (String tnm) throws Exception {
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param tnm ...
|
||||
*
|
||||
* @throws Exception ...
|
||||
* @throws DatabaseException ...
|
||||
*/
|
||||
public synchronized void begin(String tnm) throws Exception {
|
||||
if (killed) {
|
||||
throw new DatabaseException("Transaction started on killed thread");
|
||||
}
|
||||
|
||||
if (killed)
|
||||
throw new DatabaseException ("Transaction started on killed thread");
|
||||
if (active) {
|
||||
abort();
|
||||
}
|
||||
|
||||
if (active)
|
||||
abort ();
|
||||
|
||||
nodes.clear ();
|
||||
nodesArray.clear ();
|
||||
cleannodes.clear ();
|
||||
txn = nmgr.db.beginTransaction ();
|
||||
active = true;
|
||||
tstart = System.currentTimeMillis ();
|
||||
tname = tnm;
|
||||
nodes.clear();
|
||||
nodesArray.clear();
|
||||
cleannodes.clear();
|
||||
txn = nmgr.db.beginTransaction();
|
||||
active = true;
|
||||
tstart = System.currentTimeMillis();
|
||||
tname = tnm;
|
||||
}
|
||||
|
||||
public synchronized void commit () throws Exception {
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @throws Exception ...
|
||||
*/
|
||||
public synchronized void commit() throws Exception {
|
||||
if (killed) {
|
||||
abort();
|
||||
|
||||
if (killed) {
|
||||
abort ();
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
int ins = 0, upd = 0, dlt = 0;
|
||||
int l = nodesArray.size ();
|
||||
int ins = 0;
|
||||
int upd = 0;
|
||||
int dlt = 0;
|
||||
int l = nodesArray.size();
|
||||
|
||||
Replicator replicator = nmgr.getReplicator ();
|
||||
Replicator replicator = nmgr.getReplicator();
|
||||
|
||||
for (int i=0; i<l; i++) {
|
||||
Node node = (Node) nodesArray.get (i);
|
||||
// update nodes in db
|
||||
int nstate = node.getState ();
|
||||
if (nstate == Node.NEW) {
|
||||
nmgr.registerNode (node); // register node with nodemanager cache
|
||||
nmgr.insertNode (nmgr.db, txn, node);
|
||||
node.setState (Node.CLEAN);
|
||||
if (replicator != null)
|
||||
replicator.addNewNode (node);
|
||||
ins++;
|
||||
nmgr.app.logEvent ("inserted: Node "+node.getPrototype ()+"/"+node.getID ());
|
||||
} else if (nstate == Node.MODIFIED) {
|
||||
nmgr.updateNode (nmgr.db, txn, node);
|
||||
node.setState (Node.CLEAN);
|
||||
if (replicator != null)
|
||||
replicator.addModifiedNode (node);
|
||||
upd++;
|
||||
nmgr.app.logEvent ("updated: Node "+node.getPrototype ()+"/"+node.getID ());
|
||||
} else if (nstate == Node.DELETED) {
|
||||
// nmgr.app.logEvent ("deleted: "+node.getFullName ()+" ("+node.getName ()+")");
|
||||
nmgr.deleteNode (nmgr.db, txn, node);
|
||||
nmgr.evictNode (node);
|
||||
if (replicator != null)
|
||||
replicator.addDeletedNode (node);
|
||||
dlt++;
|
||||
} else {
|
||||
// nmgr.app.logEvent ("noop: "+node.getFullName ());
|
||||
}
|
||||
node.clearWriteLock ();
|
||||
}
|
||||
for (int i = 0; i < l; i++) {
|
||||
Node node = (Node) nodesArray.get(i);
|
||||
|
||||
nodes.clear ();
|
||||
nodesArray.clear ();
|
||||
cleannodes.clear ();
|
||||
// update nodes in db
|
||||
int nstate = node.getState();
|
||||
|
||||
if (nmgr.idgen.dirty) {
|
||||
nmgr.db.saveIDGenerator (txn, nmgr.idgen);
|
||||
nmgr.idgen.dirty = false;
|
||||
}
|
||||
if (nstate == Node.NEW) {
|
||||
nmgr.registerNode(node); // register node with nodemanager cache
|
||||
nmgr.insertNode(nmgr.db, txn, node);
|
||||
node.setState(Node.CLEAN);
|
||||
|
||||
if (active) {
|
||||
active = false;
|
||||
nmgr.db.commitTransaction (txn);
|
||||
txn = null;
|
||||
}
|
||||
if (replicator != null) {
|
||||
replicator.addNewNode(node);
|
||||
}
|
||||
|
||||
nmgr.app.logAccess (tname+" "+l+" marked, "+ins+" inserted, "+upd+" updated, "+dlt+" deleted in "+(System.currentTimeMillis()-tstart)+" millis");
|
||||
ins++;
|
||||
nmgr.app.logEvent("inserted: Node " + node.getPrototype() + "/" +
|
||||
node.getID());
|
||||
} else if (nstate == Node.MODIFIED) {
|
||||
nmgr.updateNode(nmgr.db, txn, node);
|
||||
node.setState(Node.CLEAN);
|
||||
|
||||
if (replicator != null) {
|
||||
replicator.addModifiedNode(node);
|
||||
}
|
||||
|
||||
upd++;
|
||||
nmgr.app.logEvent("updated: Node " + node.getPrototype() + "/" +
|
||||
node.getID());
|
||||
} else if (nstate == Node.DELETED) {
|
||||
// nmgr.app.logEvent ("deleted: "+node.getFullName ()+" ("+node.getName ()+")");
|
||||
nmgr.deleteNode(nmgr.db, txn, node);
|
||||
nmgr.evictNode(node);
|
||||
|
||||
if (replicator != null) {
|
||||
replicator.addDeletedNode(node);
|
||||
}
|
||||
|
||||
dlt++;
|
||||
} else {
|
||||
// nmgr.app.logEvent ("noop: "+node.getFullName ());
|
||||
}
|
||||
|
||||
node.clearWriteLock();
|
||||
}
|
||||
|
||||
nodes.clear();
|
||||
nodesArray.clear();
|
||||
cleannodes.clear();
|
||||
|
||||
if (nmgr.idgen.dirty) {
|
||||
nmgr.db.saveIDGenerator(txn, nmgr.idgen);
|
||||
nmgr.idgen.dirty = false;
|
||||
}
|
||||
|
||||
if (active) {
|
||||
active = false;
|
||||
nmgr.db.commitTransaction(txn);
|
||||
txn = null;
|
||||
}
|
||||
|
||||
nmgr.app.logAccess(tname + " " + l + " marked, " + ins + " inserted, " + upd +
|
||||
" updated, " + dlt + " deleted in " +
|
||||
(System.currentTimeMillis() - tstart) + " millis");
|
||||
}
|
||||
|
||||
public synchronized void abort () throws Exception {
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @throws Exception ...
|
||||
*/
|
||||
public synchronized void abort() throws Exception {
|
||||
int l = nodesArray.size();
|
||||
|
||||
int l = nodesArray.size ();
|
||||
for (int i=0; i<l; i++ ) {
|
||||
Node node = (Node) nodesArray.get (i);
|
||||
// Declare node as invalid, so it won't be used by other threads that want to
|
||||
// write on it and remove it from cache
|
||||
nmgr.evictNode (node);
|
||||
node.clearWriteLock ();
|
||||
}
|
||||
nodes.clear ();
|
||||
nodesArray.clear ();
|
||||
cleannodes.clear ();
|
||||
// close any JDBC connections associated with this transactor thread
|
||||
closeConnections ();
|
||||
for (int i = 0; i < l; i++) {
|
||||
Node node = (Node) nodesArray.get(i);
|
||||
|
||||
if (active) {
|
||||
active = false;
|
||||
if (txn != null) {
|
||||
nmgr.db.abortTransaction (txn);
|
||||
txn = null;
|
||||
}
|
||||
nmgr.app.logAccess (tname+" aborted after "+(System.currentTimeMillis()-tstart)+" millis");
|
||||
}
|
||||
// Declare node as invalid, so it won't be used by other threads that want to
|
||||
// write on it and remove it from cache
|
||||
nmgr.evictNode(node);
|
||||
node.clearWriteLock();
|
||||
}
|
||||
|
||||
nodes.clear();
|
||||
nodesArray.clear();
|
||||
cleannodes.clear();
|
||||
|
||||
// close any JDBC connections associated with this transactor thread
|
||||
closeConnections();
|
||||
|
||||
if (active) {
|
||||
active = false;
|
||||
|
||||
if (txn != null) {
|
||||
nmgr.db.abortTransaction(txn);
|
||||
txn = null;
|
||||
}
|
||||
|
||||
nmgr.app.logAccess(tname + " aborted after " +
|
||||
(System.currentTimeMillis() - tstart) + " millis");
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void kill () {
|
||||
killed = true;
|
||||
// The thread is told to stop by setting the thread flag in the EcmaScript
|
||||
// evaluator, so we can hope that it stops without doing anything else.
|
||||
try {
|
||||
join (500);
|
||||
} catch (InterruptedException ir) {}
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public synchronized void kill() {
|
||||
killed = true;
|
||||
|
||||
// Interrupt the thread if it has not noticed the flag (e.g. because it is busy
|
||||
// reading from a network socket).
|
||||
if (isAlive()) {
|
||||
interrupt ();
|
||||
try {
|
||||
join (1000);
|
||||
} catch (InterruptedException ir) {}
|
||||
}
|
||||
// The thread is told to stop by setting the thread flag in the EcmaScript
|
||||
// evaluator, so we can hope that it stops without doing anything else.
|
||||
try {
|
||||
join(500);
|
||||
} catch (InterruptedException ir) {
|
||||
}
|
||||
|
||||
// Interrupt the thread if it has not noticed the flag (e.g. because it is busy
|
||||
// reading from a network socket).
|
||||
if (isAlive()) {
|
||||
interrupt();
|
||||
|
||||
try {
|
||||
join(1000);
|
||||
} catch (InterruptedException ir) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void closeConnections () {
|
||||
// nmgr.app.logEvent("Cleaning up Transactor thread");
|
||||
if (sqlCon != null) {
|
||||
for (Iterator i=sqlCon.values().iterator(); i.hasNext(); ) {
|
||||
try {
|
||||
Connection con = (Connection) i.next();
|
||||
con.close ();
|
||||
nmgr.app.logEvent ("Closing DB connection: "+con);
|
||||
} catch (Exception ignore) {}
|
||||
}
|
||||
sqlCon.clear ();
|
||||
}
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void closeConnections() {
|
||||
// nmgr.app.logEvent("Cleaning up Transactor thread");
|
||||
if (sqlCon != null) {
|
||||
for (Iterator i = sqlCon.values().iterator(); i.hasNext();) {
|
||||
try {
|
||||
Connection con = (Connection) i.next();
|
||||
|
||||
con.close();
|
||||
nmgr.app.logEvent("Closing DB connection: " + con);
|
||||
} catch (Exception ignore) {
|
||||
}
|
||||
}
|
||||
|
||||
sqlCon.clear();
|
||||
}
|
||||
}
|
||||
|
||||
public String toString () {
|
||||
return "Transactor["+tname+"]";
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String toString() {
|
||||
return "Transactor[" + tname + "]";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,156 +1,303 @@
|
|||
// WrappedNodeManager.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.db;
|
||||
|
||||
import helma.objectmodel.*;
|
||||
import java.util.List;
|
||||
import java.util.Vector;
|
||||
|
||||
|
||||
/**
|
||||
* A wrapper around NodeManager that catches most Exceptions, or rethrows them as RuntimeExceptions.
|
||||
* The idea behind this is that we don't care a lot about Exception classes, since Hop programming is done
|
||||
* in JavaScript which doesn't know about them (except for the exception message).
|
||||
*/
|
||||
|
||||
public final class WrappedNodeManager {
|
||||
|
||||
public final class WrappedNodeManager {
|
||||
NodeManager nmgr;
|
||||
|
||||
public WrappedNodeManager (NodeManager nmgr) {
|
||||
this.nmgr = nmgr;
|
||||
/**
|
||||
* Creates a new WrappedNodeManager object.
|
||||
*
|
||||
* @param nmgr ...
|
||||
*/
|
||||
public WrappedNodeManager(NodeManager nmgr) {
|
||||
this.nmgr = nmgr;
|
||||
}
|
||||
|
||||
public Node getNode (String id, DbMapping dbmap) {
|
||||
return getNode (new DbKey (dbmap, id));
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param id ...
|
||||
* @param dbmap ...
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public Node getNode(String id, DbMapping dbmap) {
|
||||
return getNode(new DbKey(dbmap, id));
|
||||
}
|
||||
|
||||
public Node getNode (Key key) {
|
||||
try {
|
||||
return nmgr.getNode (key);
|
||||
} catch (ObjectNotFoundException x) {
|
||||
return null;
|
||||
} catch (Exception x) {
|
||||
nmgr.app.logEvent ("Error retrieving Node via DbMapping: "+x);
|
||||
if (nmgr.app.debug ())
|
||||
x.printStackTrace();
|
||||
throw new RuntimeException ("Error retrieving Node: "+x);
|
||||
}
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param key ...
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public Node getNode(Key key) {
|
||||
try {
|
||||
return nmgr.getNode(key);
|
||||
} catch (ObjectNotFoundException x) {
|
||||
return null;
|
||||
} catch (Exception x) {
|
||||
nmgr.app.logEvent("Error retrieving Node via DbMapping: " + x);
|
||||
|
||||
if (nmgr.app.debug()) {
|
||||
x.printStackTrace();
|
||||
}
|
||||
|
||||
throw new RuntimeException("Error retrieving Node: " + x);
|
||||
}
|
||||
}
|
||||
|
||||
public Node getNode (Node home, String id, Relation rel) {
|
||||
try {
|
||||
return nmgr.getNode (home, id, rel);
|
||||
} catch (ObjectNotFoundException x) {
|
||||
return null;
|
||||
} catch (Exception x) {
|
||||
nmgr.app.logEvent ("Error retrieving Node \""+id+"\" from "+home+": "+x);
|
||||
if (nmgr.app.debug ())
|
||||
x.printStackTrace();
|
||||
throw new RuntimeException ("Error retrieving Node: "+x);
|
||||
}
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param home ...
|
||||
* @param id ...
|
||||
* @param rel ...
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public Node getNode(Node home, String id, Relation rel) {
|
||||
try {
|
||||
return nmgr.getNode(home, id, rel);
|
||||
} catch (ObjectNotFoundException x) {
|
||||
return null;
|
||||
} catch (Exception x) {
|
||||
nmgr.app.logEvent("Error retrieving Node \"" + id + "\" from " + home + ": " +
|
||||
x);
|
||||
|
||||
if (nmgr.app.debug()) {
|
||||
x.printStackTrace();
|
||||
}
|
||||
|
||||
throw new RuntimeException("Error retrieving Node: " + x);
|
||||
}
|
||||
}
|
||||
|
||||
public List getNodes (Node home, Relation rel) {
|
||||
try {
|
||||
return nmgr.getNodes (home, rel);
|
||||
} catch (Exception x) {
|
||||
if (nmgr.app.debug ())
|
||||
x.printStackTrace();
|
||||
throw new RuntimeException ("Error retrieving Nodes: "+x);
|
||||
}
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param home ...
|
||||
* @param rel ...
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public List getNodes(Node home, Relation rel) {
|
||||
try {
|
||||
return nmgr.getNodes(home, rel);
|
||||
} catch (Exception x) {
|
||||
if (nmgr.app.debug()) {
|
||||
x.printStackTrace();
|
||||
}
|
||||
|
||||
throw new RuntimeException("Error retrieving Nodes: " + x);
|
||||
}
|
||||
}
|
||||
|
||||
public List getNodeIDs (Node home, Relation rel) {
|
||||
try {
|
||||
return nmgr.getNodeIDs (home, rel);
|
||||
} catch (Exception x) {
|
||||
if (nmgr.app.debug ())
|
||||
x.printStackTrace();
|
||||
throw new RuntimeException ("Error retrieving NodeIDs: "+x);
|
||||
}
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param home ...
|
||||
* @param rel ...
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public List getNodeIDs(Node home, Relation rel) {
|
||||
try {
|
||||
return nmgr.getNodeIDs(home, rel);
|
||||
} catch (Exception x) {
|
||||
if (nmgr.app.debug()) {
|
||||
x.printStackTrace();
|
||||
}
|
||||
|
||||
throw new RuntimeException("Error retrieving NodeIDs: " + x);
|
||||
}
|
||||
}
|
||||
|
||||
public int countNodes (Node home, Relation rel) {
|
||||
try {
|
||||
return nmgr.countNodes (home, rel);
|
||||
} catch (Exception x) {
|
||||
if (nmgr.app.debug ())
|
||||
x.printStackTrace();
|
||||
throw new RuntimeException ("Error counting Node: "+x);
|
||||
}
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param home ...
|
||||
* @param rel ...
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public int countNodes(Node home, Relation rel) {
|
||||
try {
|
||||
return nmgr.countNodes(home, rel);
|
||||
} catch (Exception x) {
|
||||
if (nmgr.app.debug()) {
|
||||
x.printStackTrace();
|
||||
}
|
||||
|
||||
throw new RuntimeException("Error counting Node: " + x);
|
||||
}
|
||||
}
|
||||
|
||||
public void deleteNode (Node node) {
|
||||
try {
|
||||
nmgr.deleteNode (node);
|
||||
} catch (Exception x) {
|
||||
if (nmgr.app.debug ())
|
||||
x.printStackTrace();
|
||||
throw new RuntimeException ("Error deleting Node: "+x);
|
||||
}
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param node ...
|
||||
*/
|
||||
public void deleteNode(Node node) {
|
||||
try {
|
||||
nmgr.deleteNode(node);
|
||||
} catch (Exception x) {
|
||||
if (nmgr.app.debug()) {
|
||||
x.printStackTrace();
|
||||
}
|
||||
|
||||
throw new RuntimeException("Error deleting Node: " + x);
|
||||
}
|
||||
}
|
||||
|
||||
public Vector getPropertyNames (Node home, Relation rel) {
|
||||
try {
|
||||
return nmgr.getPropertyNames (home, rel);
|
||||
} catch (Exception x) {
|
||||
if (nmgr.app.debug ())
|
||||
x.printStackTrace();
|
||||
throw new RuntimeException ("Error retrieving property names: "+x);
|
||||
}
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param home ...
|
||||
* @param rel ...
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public Vector getPropertyNames(Node home, Relation rel) {
|
||||
try {
|
||||
return nmgr.getPropertyNames(home, rel);
|
||||
} catch (Exception x) {
|
||||
if (nmgr.app.debug()) {
|
||||
x.printStackTrace();
|
||||
}
|
||||
|
||||
throw new RuntimeException("Error retrieving property names: " + x);
|
||||
}
|
||||
}
|
||||
|
||||
public void registerNode (Node node) {
|
||||
nmgr.registerNode (node);
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param node ...
|
||||
*/
|
||||
public void registerNode(Node node) {
|
||||
nmgr.registerNode(node);
|
||||
}
|
||||
|
||||
public void evictNode (Node node) {
|
||||
nmgr.evictNode (node);
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param node ...
|
||||
*/
|
||||
public void evictNode(Node node) {
|
||||
nmgr.evictNode(node);
|
||||
}
|
||||
|
||||
public void evictNodeByKey (Key key) {
|
||||
nmgr.evictNodeByKey (key);
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param key ...
|
||||
*/
|
||||
public void evictNodeByKey(Key key) {
|
||||
nmgr.evictNodeByKey(key);
|
||||
}
|
||||
|
||||
public void evictKey (Key key) {
|
||||
nmgr.evictKey (key);
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param key ...
|
||||
*/
|
||||
public void evictKey(Key key) {
|
||||
nmgr.evictKey(key);
|
||||
}
|
||||
|
||||
|
||||
public String generateID () {
|
||||
return nmgr.idgen.newID ();
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String generateID() {
|
||||
return nmgr.idgen.newID();
|
||||
}
|
||||
|
||||
public String generateID (DbMapping map) {
|
||||
try {
|
||||
// check if we use internal id generator
|
||||
if (map == null || !map.isRelational () || "[hop]".equalsIgnoreCase (map.getIDgen()))
|
||||
return nmgr.idgen.newID ();
|
||||
// or if we query max key value
|
||||
else if (map.getIDgen() == null || "[max]".equalsIgnoreCase (map.getIDgen()))
|
||||
return nmgr.generateMaxID (map);
|
||||
else
|
||||
return nmgr.generateID (map);
|
||||
// otherwise, we use an oracle sequence
|
||||
} catch (Exception x) {
|
||||
if (nmgr.app.debug ())
|
||||
x.printStackTrace();
|
||||
throw new RuntimeException (x.toString ());
|
||||
}
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param map ...
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String generateID(DbMapping map) {
|
||||
try {
|
||||
// check if we use internal id generator
|
||||
if ((map == null) || !map.isRelational() ||
|
||||
"[hop]".equalsIgnoreCase(map.getIDgen())) {
|
||||
return nmgr.idgen.newID();
|
||||
}
|
||||
// or if we query max key value
|
||||
else if ((map.getIDgen() == null) ||
|
||||
"[max]".equalsIgnoreCase(map.getIDgen())) {
|
||||
return nmgr.generateMaxID(map);
|
||||
} else {
|
||||
return nmgr.generateID(map);
|
||||
}
|
||||
|
||||
// otherwise, we use an oracle sequence
|
||||
} catch (Exception x) {
|
||||
if (nmgr.app.debug()) {
|
||||
x.printStackTrace();
|
||||
}
|
||||
|
||||
throw new RuntimeException(x.toString());
|
||||
}
|
||||
}
|
||||
|
||||
public Object[] getCacheEntries () {
|
||||
return nmgr.getCacheEntries ();
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public Object[] getCacheEntries() {
|
||||
return nmgr.getCacheEntries();
|
||||
}
|
||||
|
||||
public void logEvent (String msg) {
|
||||
nmgr.app.logEvent (msg);
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param msg ...
|
||||
*/
|
||||
public void logEvent(String msg) {
|
||||
nmgr.app.logEvent(msg);
|
||||
}
|
||||
|
||||
public DbMapping getDbMapping (String name) {
|
||||
return nmgr.app.getDbMapping (name);
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param name ...
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public DbMapping getDbMapping(String name) {
|
||||
return nmgr.app.getDbMapping(name);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,97 +1,240 @@
|
|||
package helma.objectmodel.db;
|
||||
/*
|
||||
* 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.Date;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Document;
|
||||
package helma.objectmodel.db;
|
||||
|
||||
import helma.objectmodel.*;
|
||||
import helma.objectmodel.dom.*;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import java.io.*;
|
||||
import java.util.Date;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
/**
|
||||
* A simple XML-database
|
||||
*/
|
||||
|
||||
public final class XmlDatabase implements IDatabase {
|
||||
private String dbHome;
|
||||
private File dbBaseDir;
|
||||
private NodeManager nmgr;
|
||||
private IDGenerator idgen;
|
||||
|
||||
private String dbHome;
|
||||
private File dbBaseDir;
|
||||
private NodeManager nmgr;
|
||||
private IDGenerator idgen;
|
||||
// character encoding to use when writing files.
|
||||
// use standard encoding by default.
|
||||
private String encoding = null;
|
||||
|
||||
// character encoding to use when writing files.
|
||||
// use standard encoding by default.
|
||||
private String encoding = null;
|
||||
|
||||
public XmlDatabase (String dbHome, String dbFilename, NodeManager nmgr) throws DatabaseException {
|
||||
this.dbHome = dbHome;
|
||||
this.nmgr = nmgr;
|
||||
dbBaseDir = new File (dbHome);
|
||||
if (!dbBaseDir.exists() && !dbBaseDir.mkdirs() )
|
||||
throw new RuntimeException("Couldn't create DB-directory");
|
||||
this.encoding = nmgr.app.getCharset ();
|
||||
}
|
||||
/**
|
||||
* Creates a new XmlDatabase object.
|
||||
*
|
||||
* @param dbHome ...
|
||||
* @param dbFilename ...
|
||||
* @param nmgr ...
|
||||
*
|
||||
* @throws DatabaseException ...
|
||||
* @throws RuntimeException ...
|
||||
*/
|
||||
public XmlDatabase(String dbHome, String dbFilename, NodeManager nmgr)
|
||||
throws DatabaseException {
|
||||
this.dbHome = dbHome;
|
||||
this.nmgr = nmgr;
|
||||
dbBaseDir = new File(dbHome);
|
||||
|
||||
public void shutdown () { }
|
||||
public ITransaction beginTransaction () throws DatabaseException { return null; }
|
||||
public void commitTransaction (ITransaction txn) throws DatabaseException { }
|
||||
public void abortTransaction (ITransaction txn) throws DatabaseException { }
|
||||
if (!dbBaseDir.exists() && !dbBaseDir.mkdirs()) {
|
||||
throw new RuntimeException("Couldn't create DB-directory");
|
||||
}
|
||||
|
||||
public String nextID() throws ObjectNotFoundException {
|
||||
if (idgen==null) {
|
||||
getIDGenerator(null);
|
||||
}
|
||||
return idgen.newID();
|
||||
}
|
||||
this.encoding = nmgr.app.getCharset();
|
||||
}
|
||||
|
||||
public IDGenerator getIDGenerator (ITransaction txn) throws ObjectNotFoundException {
|
||||
File file = new File (dbBaseDir, "idgen.xml");
|
||||
this.idgen = IDGenParser.getIDGenerator(file);
|
||||
return idgen;
|
||||
}
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void shutdown() {
|
||||
}
|
||||
|
||||
public void saveIDGenerator (ITransaction txn, IDGenerator idgen) throws Exception {
|
||||
File file = new File (dbBaseDir, "idgen.xml");
|
||||
IDGenParser.saveIDGenerator(idgen,file);
|
||||
this.idgen = idgen;
|
||||
}
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*
|
||||
* @throws DatabaseException ...
|
||||
*/
|
||||
public ITransaction beginTransaction() throws DatabaseException {
|
||||
return null;
|
||||
}
|
||||
|
||||
public INode getNode (ITransaction txn, String kstr) throws Exception {
|
||||
File f = new File (dbBaseDir, kstr+".xml");
|
||||
if ( ! f.exists() )
|
||||
throw new ObjectNotFoundException ("Object not found for key "+kstr+".");
|
||||
try {
|
||||
XmlDatabaseReader reader = new XmlDatabaseReader (nmgr);
|
||||
Node node = reader.read (f);
|
||||
return node;
|
||||
} catch ( RuntimeException x ) {
|
||||
nmgr.app.logEvent("error reading node from XmlDatbase: " + x.toString() );
|
||||
throw new ObjectNotFoundException(x.toString());
|
||||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param txn ...
|
||||
*
|
||||
* @throws DatabaseException ...
|
||||
*/
|
||||
public void commitTransaction(ITransaction txn) throws DatabaseException {
|
||||
}
|
||||
|
||||
public void saveNode (ITransaction txn, String kstr, INode node) throws Exception {
|
||||
XmlWriter writer = null;
|
||||
File file = new File (dbBaseDir,kstr+".xml");
|
||||
if (encoding != null)
|
||||
writer = new XmlWriter (file, encoding);
|
||||
else
|
||||
writer = new XmlWriter (file);
|
||||
writer.setMaxLevels(1);
|
||||
boolean result = writer.write((Node)node);
|
||||
writer.close();
|
||||
}
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param txn ...
|
||||
*
|
||||
* @throws DatabaseException ...
|
||||
*/
|
||||
public void abortTransaction(ITransaction txn) throws DatabaseException {
|
||||
}
|
||||
|
||||
public void deleteNode (ITransaction txn, String kstr) throws Exception {
|
||||
File f = new File (dbBaseDir, kstr+".xml");
|
||||
f.delete();
|
||||
}
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*
|
||||
* @throws ObjectNotFoundException ...
|
||||
*/
|
||||
public String nextID() throws ObjectNotFoundException {
|
||||
if (idgen == null) {
|
||||
getIDGenerator(null);
|
||||
}
|
||||
|
||||
public void setEncoding (String enc) {
|
||||
this.encoding = encoding;
|
||||
}
|
||||
return idgen.newID();
|
||||
}
|
||||
|
||||
public String getEncoding () {
|
||||
return encoding;
|
||||
}
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param txn ...
|
||||
*
|
||||
* @return ...
|
||||
*
|
||||
* @throws ObjectNotFoundException ...
|
||||
*/
|
||||
public IDGenerator getIDGenerator(ITransaction txn)
|
||||
throws ObjectNotFoundException {
|
||||
File file = new File(dbBaseDir, "idgen.xml");
|
||||
|
||||
this.idgen = IDGenParser.getIDGenerator(file);
|
||||
|
||||
return idgen;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param txn ...
|
||||
* @param idgen ...
|
||||
*
|
||||
* @throws Exception ...
|
||||
*/
|
||||
public void saveIDGenerator(ITransaction txn, IDGenerator idgen)
|
||||
throws IOException {
|
||||
File file = new File(dbBaseDir, "idgen.xml");
|
||||
|
||||
IDGenParser.saveIDGenerator(idgen, file);
|
||||
this.idgen = idgen;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param txn ...
|
||||
* @param kstr ...
|
||||
*
|
||||
* @return ...
|
||||
*
|
||||
* @throws Exception ...
|
||||
* @throws ObjectNotFoundException ...
|
||||
*/
|
||||
public INode getNode(ITransaction txn, String kstr)
|
||||
throws IOException, ObjectNotFoundException,
|
||||
ParserConfigurationException, SAXException {
|
||||
File f = new File(dbBaseDir, kstr + ".xml");
|
||||
|
||||
if (!f.exists()) {
|
||||
throw new ObjectNotFoundException("Object not found for key " + kstr + ".");
|
||||
}
|
||||
|
||||
try {
|
||||
XmlDatabaseReader reader = new XmlDatabaseReader(nmgr);
|
||||
Node node = reader.read(f);
|
||||
|
||||
return node;
|
||||
} catch (RuntimeException x) {
|
||||
nmgr.app.logEvent("error reading node from XmlDatbase: " + x.toString());
|
||||
throw new ObjectNotFoundException(x.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param txn ...
|
||||
* @param kstr ...
|
||||
* @param node ...
|
||||
*
|
||||
* @throws Exception ...
|
||||
*/
|
||||
public void saveNode(ITransaction txn, String kstr, INode node)
|
||||
throws IOException {
|
||||
XmlWriter writer = null;
|
||||
File file = new File(dbBaseDir, kstr + ".xml");
|
||||
|
||||
if (encoding != null) {
|
||||
writer = new XmlWriter(file, encoding);
|
||||
} else {
|
||||
writer = new XmlWriter(file);
|
||||
}
|
||||
|
||||
writer.setMaxLevels(1);
|
||||
|
||||
boolean result = writer.write((Node) node);
|
||||
|
||||
writer.close();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param txn ...
|
||||
* @param kstr ...
|
||||
*
|
||||
* @throws Exception ...
|
||||
*/
|
||||
public void deleteNode(ITransaction txn, String kstr)
|
||||
throws IOException {
|
||||
File f = new File(dbBaseDir, kstr + ".xml");
|
||||
|
||||
f.delete();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param enc ...
|
||||
*/
|
||||
public void setEncoding(String enc) {
|
||||
this.encoding = encoding;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getEncoding() {
|
||||
return encoding;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,37 +1,80 @@
|
|||
package helma.objectmodel.dom;
|
||||
/*
|
||||
* 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.Date;
|
||||
import org.w3c.dom.*;
|
||||
package helma.objectmodel.dom;
|
||||
|
||||
import helma.objectmodel.ObjectNotFoundException;
|
||||
import helma.objectmodel.db.IDGenerator;
|
||||
import org.w3c.dom.*;
|
||||
import java.io.*;
|
||||
import java.util.Date;
|
||||
|
||||
public class IDGenParser {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class IDGenParser {
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param file ...
|
||||
*
|
||||
* @return ...
|
||||
*
|
||||
* @throws ObjectNotFoundException ...
|
||||
*/
|
||||
public static IDGenerator getIDGenerator(File file)
|
||||
throws ObjectNotFoundException {
|
||||
if (!file.exists()) {
|
||||
throw new ObjectNotFoundException("IDGenerator not found in idgen.xml");
|
||||
}
|
||||
|
||||
public static IDGenerator getIDGenerator (File file) throws ObjectNotFoundException {
|
||||
if ( ! file.exists() )
|
||||
throw new ObjectNotFoundException ("IDGenerator not found in idgen.xml");
|
||||
try {
|
||||
Document document = XmlUtil.parse(new FileInputStream (file));
|
||||
org.w3c.dom.Element tmp = (Element)document.getDocumentElement().getElementsByTagName("counter").item(0);
|
||||
return new IDGenerator( Long.parseLong (XmlUtil.getTextContent(tmp)) );
|
||||
} catch (Exception e) {
|
||||
throw new ObjectNotFoundException(e.toString());
|
||||
}
|
||||
try {
|
||||
Document document = XmlUtil.parse(new FileInputStream(file));
|
||||
org.w3c.dom.Element tmp = (Element) document.getDocumentElement()
|
||||
.getElementsByTagName("counter")
|
||||
.item(0);
|
||||
|
||||
return new IDGenerator(Long.parseLong(XmlUtil.getTextContent(tmp)));
|
||||
} catch (Exception e) {
|
||||
throw new ObjectNotFoundException(e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
public static IDGenerator saveIDGenerator (IDGenerator idgen, File file) throws Exception {
|
||||
OutputStreamWriter out = new OutputStreamWriter (new FileOutputStream (file));
|
||||
out.write ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
|
||||
out.write ("<!-- printed by helma object publisher -->\n");
|
||||
out.write ("<!-- created " + (new Date()).toString() + " -->\n" );
|
||||
out.write ("<xmlroot>\n");
|
||||
out.write (" <counter>" + idgen.getValue() + "</counter>\n");
|
||||
out.write ("</xmlroot>\n");
|
||||
out.close ();
|
||||
return idgen;
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param idgen ...
|
||||
* @param file ...
|
||||
*
|
||||
* @return ...
|
||||
*
|
||||
* @throws Exception ...
|
||||
*/
|
||||
public static IDGenerator saveIDGenerator(IDGenerator idgen, File file)
|
||||
throws IOException {
|
||||
OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream(file));
|
||||
|
||||
out.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
|
||||
out.write("<!-- printed by helma object publisher -->\n");
|
||||
out.write("<!-- created " + (new Date()).toString() + " -->\n");
|
||||
out.write("<xmlroot>\n");
|
||||
out.write(" <counter>" + idgen.getValue() + "</counter>\n");
|
||||
out.write("</xmlroot>\n");
|
||||
out.close();
|
||||
|
||||
return idgen;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,25 @@
|
|||
/*
|
||||
* 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.dom;
|
||||
|
||||
public interface XmlConstants {
|
||||
|
||||
public final String NAMESPACE = "http://www.helma.org/docs/guide/features/database";
|
||||
public final String DATEFORMAT = "dd.MM.yyyy HH:mm:ss z";
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public interface XmlConstants {
|
||||
public final String NAMESPACE = "http://www.helma.org/docs/guide/features/database";
|
||||
public final String DATEFORMAT = "dd.MM.yyyy HH:mm:ss z";
|
||||
}
|
||||
|
|
|
@ -1,345 +1,536 @@
|
|||
/*
|
||||
* 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.dom;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.*;
|
||||
import java.util.*;
|
||||
|
||||
import javax.xml.parsers.*;
|
||||
import org.w3c.dom.*;
|
||||
import org.xml.sax.InputSource;
|
||||
|
||||
import helma.objectmodel.*;
|
||||
import helma.util.SystemProperties;
|
||||
import org.w3c.dom.*;
|
||||
import org.xml.sax.InputSource;
|
||||
import java.io.*;
|
||||
import java.net.*;
|
||||
import java.util.*;
|
||||
import javax.xml.parsers.*;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class XmlConverter implements XmlConstants {
|
||||
|
||||
private boolean DEBUG = false;
|
||||
|
||||
private boolean sparse = false;
|
||||
|
||||
private Properties props;
|
||||
|
||||
private char defaultSeparator = '_';
|
||||
|
||||
private char defaultSeparator = '_';
|
||||
private int offset = 0;
|
||||
|
||||
/**
|
||||
* Creates a new XmlConverter object.
|
||||
*/
|
||||
public XmlConverter() {
|
||||
props = new SystemProperties();
|
||||
props = new SystemProperties();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new XmlConverter object.
|
||||
*
|
||||
* @param propFile ...
|
||||
*/
|
||||
public XmlConverter(String propFile) {
|
||||
props = new SystemProperties(propFile);
|
||||
extractProperties(props);
|
||||
props = new SystemProperties(propFile);
|
||||
extractProperties(props);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new XmlConverter object.
|
||||
*
|
||||
* @param propFile ...
|
||||
*/
|
||||
public XmlConverter(File propFile) {
|
||||
this ( propFile.getAbsolutePath() );
|
||||
this(propFile.getAbsolutePath());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new XmlConverter object.
|
||||
*
|
||||
* @param props ...
|
||||
*/
|
||||
public XmlConverter(Properties props) {
|
||||
this.props = props;
|
||||
extractProperties(props);
|
||||
this.props = props;
|
||||
extractProperties(props);
|
||||
}
|
||||
|
||||
public INode convert( String desc ) {
|
||||
return convert(desc, new TransientNode() );
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param desc ...
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public INode convert(String desc) {
|
||||
return convert(desc, new TransientNode());
|
||||
}
|
||||
|
||||
public INode convert( String desc, INode helmaNode ) throws RuntimeException {
|
||||
try {
|
||||
return convert( new URL(desc), helmaNode );
|
||||
} catch ( MalformedURLException notanurl ) {
|
||||
try {
|
||||
return convert( new File(desc), helmaNode );
|
||||
} catch ( FileNotFoundException notfound ) {
|
||||
throw new RuntimeException( "couldn't read xml: " + desc );
|
||||
}
|
||||
} catch ( IOException ioerror ) {
|
||||
throw new RuntimeException( "couldn't read xml: " + desc );
|
||||
}
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param desc ...
|
||||
* @param helmaNode ...
|
||||
*
|
||||
* @return ...
|
||||
*
|
||||
* @throws RuntimeException ...
|
||||
*/
|
||||
public INode convert(String desc, INode helmaNode)
|
||||
throws RuntimeException {
|
||||
try {
|
||||
return convert(new URL(desc), helmaNode);
|
||||
} catch (MalformedURLException notanurl) {
|
||||
try {
|
||||
return convert(new File(desc), helmaNode);
|
||||
} catch (FileNotFoundException notfound) {
|
||||
throw new RuntimeException("couldn't read xml: " + desc);
|
||||
}
|
||||
} catch (IOException ioerror) {
|
||||
throw new RuntimeException("couldn't read xml: " + desc);
|
||||
}
|
||||
}
|
||||
|
||||
public INode convert( File file, INode helmaNode ) throws RuntimeException, FileNotFoundException {
|
||||
return convert( new FileInputStream(file), helmaNode );
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param file ...
|
||||
* @param helmaNode ...
|
||||
*
|
||||
* @return ...
|
||||
*
|
||||
* @throws RuntimeException ...
|
||||
* @throws FileNotFoundException ...
|
||||
*/
|
||||
public INode convert(File file, INode helmaNode)
|
||||
throws RuntimeException, FileNotFoundException {
|
||||
return convert(new FileInputStream(file), helmaNode);
|
||||
}
|
||||
|
||||
public INode convert( URL url, INode helmaNode ) throws RuntimeException, IOException, MalformedURLException {
|
||||
return convert( url.openConnection().getInputStream(), helmaNode );
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param url ...
|
||||
* @param helmaNode ...
|
||||
*
|
||||
* @return ...
|
||||
*
|
||||
* @throws RuntimeException ...
|
||||
* @throws IOException ...
|
||||
* @throws MalformedURLException ...
|
||||
*/
|
||||
public INode convert(URL url, INode helmaNode)
|
||||
throws RuntimeException, IOException, MalformedURLException {
|
||||
return convert(url.openConnection().getInputStream(), helmaNode);
|
||||
}
|
||||
|
||||
public INode convert( InputStream in, INode helmaNode ) throws RuntimeException {
|
||||
Document document = XmlUtil.parse (in);
|
||||
if ( document!=null && document.getDocumentElement()!=null ) {
|
||||
return convert( document.getDocumentElement(), helmaNode, new HashMap() );
|
||||
} else {
|
||||
return helmaNode;
|
||||
}
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param in ...
|
||||
* @param helmaNode ...
|
||||
*
|
||||
* @return ...
|
||||
*
|
||||
* @throws RuntimeException ...
|
||||
*/
|
||||
public INode convert(InputStream in, INode helmaNode)
|
||||
throws RuntimeException {
|
||||
Document document = XmlUtil.parse(in);
|
||||
|
||||
if ((document != null) && (document.getDocumentElement() != null)) {
|
||||
return convert(document.getDocumentElement(), helmaNode, new HashMap());
|
||||
} else {
|
||||
return helmaNode;
|
||||
}
|
||||
}
|
||||
|
||||
public INode convertFromString( String xml, INode helmaNode ) throws RuntimeException {
|
||||
Document document = XmlUtil.parse (new InputSource (new StringReader (xml)));
|
||||
if ( document!=null && document.getDocumentElement()!=null ) {
|
||||
return convert( document.getDocumentElement(), helmaNode, new HashMap() );
|
||||
} else {
|
||||
return helmaNode;
|
||||
}
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param xml ...
|
||||
* @param helmaNode ...
|
||||
*
|
||||
* @return ...
|
||||
*
|
||||
* @throws RuntimeException ...
|
||||
*/
|
||||
public INode convertFromString(String xml, INode helmaNode)
|
||||
throws RuntimeException {
|
||||
Document document = XmlUtil.parse(new InputSource(new StringReader(xml)));
|
||||
|
||||
if ((document != null) && (document.getDocumentElement() != null)) {
|
||||
return convert(document.getDocumentElement(), helmaNode, new HashMap());
|
||||
} else {
|
||||
return helmaNode;
|
||||
}
|
||||
}
|
||||
|
||||
public INode convert( Element element, INode helmaNode, Map nodeCache ) {
|
||||
offset++;
|
||||
// previousNode is used to cache previous nodes with the same prototype
|
||||
// so we can reset it in the nodeCache after we've run
|
||||
Object previousNode = null;
|
||||
if (DEBUG)
|
||||
debug("reading " + element.getNodeName() );
|
||||
String prototype = props.getProperty(element.getNodeName()+"._prototype");
|
||||
if ( prototype == null && !sparse )
|
||||
prototype = "HopObject";
|
||||
// if we have a prototype (either explicit or implicit "hopobject"),
|
||||
// set it on the Helma node and store it in the node cache.
|
||||
if ( prototype != null ) {
|
||||
helmaNode.setName( element.getNodeName() );
|
||||
helmaNode.setPrototype( prototype );
|
||||
previousNode = nodeCache.put (prototype, helmaNode);
|
||||
}
|
||||
// check attributes of the current element
|
||||
attributes(element, helmaNode, nodeCache);
|
||||
// check child nodes of the current element
|
||||
if ( element.hasChildNodes() )
|
||||
children(element, helmaNode, nodeCache);
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param element ...
|
||||
* @param helmaNode ...
|
||||
* @param nodeCache ...
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public INode convert(Element element, INode helmaNode, Map nodeCache) {
|
||||
offset++;
|
||||
|
||||
// if it exists, restore the previous node we've replaced in the node cache.
|
||||
if (previousNode != null)
|
||||
nodeCache.put (prototype, previousNode);
|
||||
// previousNode is used to cache previous nodes with the same prototype
|
||||
// so we can reset it in the nodeCache after we've run
|
||||
Object previousNode = null;
|
||||
|
||||
offset--;
|
||||
return helmaNode;
|
||||
if (DEBUG) {
|
||||
debug("reading " + element.getNodeName());
|
||||
}
|
||||
|
||||
String prototype = props.getProperty(element.getNodeName() + "._prototype");
|
||||
|
||||
if ((prototype == null) && !sparse) {
|
||||
prototype = "HopObject";
|
||||
}
|
||||
|
||||
// if we have a prototype (either explicit or implicit "hopobject"),
|
||||
// set it on the Helma node and store it in the node cache.
|
||||
if (prototype != null) {
|
||||
helmaNode.setName(element.getNodeName());
|
||||
helmaNode.setPrototype(prototype);
|
||||
previousNode = nodeCache.put(prototype, helmaNode);
|
||||
}
|
||||
|
||||
// check attributes of the current element
|
||||
attributes(element, helmaNode, nodeCache);
|
||||
|
||||
// check child nodes of the current element
|
||||
if (element.hasChildNodes()) {
|
||||
children(element, helmaNode, nodeCache);
|
||||
}
|
||||
|
||||
// if it exists, restore the previous node we've replaced in the node cache.
|
||||
if (previousNode != null) {
|
||||
nodeCache.put(prototype, previousNode);
|
||||
}
|
||||
|
||||
offset--;
|
||||
|
||||
return helmaNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* parse xml children and create hopobject-children
|
||||
*/
|
||||
private INode children( Element element, helma.objectmodel.INode helmaNode, Map nodeCache ) {
|
||||
NodeList list = element.getChildNodes();
|
||||
int len = list.getLength();
|
||||
boolean nodeIsInitialized = !nodeCache.isEmpty();
|
||||
StringBuffer textcontent = new StringBuffer();
|
||||
String domKey, helmaKey;
|
||||
for ( int i=0; i<len; i++ ) {
|
||||
private INode children(Element element, helma.objectmodel.INode helmaNode,
|
||||
Map nodeCache) {
|
||||
NodeList list = element.getChildNodes();
|
||||
int len = list.getLength();
|
||||
boolean nodeIsInitialized = !nodeCache.isEmpty();
|
||||
StringBuffer textcontent = new StringBuffer();
|
||||
String domKey;
|
||||
String helmaKey;
|
||||
|
||||
// loop through the list of children
|
||||
org.w3c.dom.Node childNode = list.item(i);
|
||||
for (int i = 0; i < len; i++) {
|
||||
// loop through the list of children
|
||||
org.w3c.dom.Node childNode = list.item(i);
|
||||
|
||||
// if the current node hasn't been initialized yet, try if it can
|
||||
// be initialized and converted from one of the child elements.
|
||||
if (!nodeIsInitialized) {
|
||||
if (childNode.getNodeType() == Node.ELEMENT_NODE) {
|
||||
convert ((Element) childNode, helmaNode, nodeCache);
|
||||
if (helmaNode.getPrototype() != null)
|
||||
return helmaNode;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
// if the current node hasn't been initialized yet, try if it can
|
||||
// be initialized and converted from one of the child elements.
|
||||
if (!nodeIsInitialized) {
|
||||
if (childNode.getNodeType() == Node.ELEMENT_NODE) {
|
||||
convert((Element) childNode, helmaNode, nodeCache);
|
||||
|
||||
// if it's text content of this element -> append to StringBuffer
|
||||
if ( childNode.getNodeType() == Node.TEXT_NODE ||
|
||||
childNode.getNodeType() == Node.CDATA_SECTION_NODE ) {
|
||||
textcontent.append( childNode.getNodeValue().trim() );
|
||||
continue;
|
||||
}
|
||||
if (helmaNode.getPrototype() != null) {
|
||||
return helmaNode;
|
||||
}
|
||||
}
|
||||
|
||||
// it's some kind of element (property or child)
|
||||
if ( childNode.getNodeType() == Node.ELEMENT_NODE ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Element childElement = (Element)childNode;
|
||||
// if it's text content of this element -> append to StringBuffer
|
||||
if ((childNode.getNodeType() == Node.TEXT_NODE) ||
|
||||
(childNode.getNodeType() == Node.CDATA_SECTION_NODE)) {
|
||||
textcontent.append(childNode.getNodeValue().trim());
|
||||
|
||||
// get the basic key we have to look for in the properties-table
|
||||
domKey = element.getNodeName()+"."+childElement.getNodeName();
|
||||
continue;
|
||||
}
|
||||
|
||||
// is there a childtext-2-property mapping?
|
||||
if ( props!=null && props.containsKey(domKey+"._text") ) {
|
||||
helmaKey = props.getProperty(domKey+"._text");
|
||||
if( helmaKey.equals("") )
|
||||
// if property is set but without value, read elementname for this mapping
|
||||
helmaKey = childElement.getNodeName().replace(':',defaultSeparator);
|
||||
if (DEBUG)
|
||||
debug("childtext-2-property mapping, helmaKey " + helmaKey + " for domKey " + domKey );
|
||||
// check if helmaKey contains an explicit prototype name in which to
|
||||
// set the property.
|
||||
int dot = helmaKey.indexOf(".");
|
||||
if (dot > -1) {
|
||||
String prototype = helmaKey.substring (0, dot);
|
||||
INode node = (INode) nodeCache.get (prototype);
|
||||
helmaKey = helmaKey.substring (dot+1);
|
||||
if (node != null && node.getString(helmaKey)==null) {
|
||||
node.setString (helmaKey, XmlUtil.getTextContent (childNode));
|
||||
}
|
||||
} else if ( helmaNode.getString(helmaKey)==null ) {
|
||||
helmaNode.setString( helmaKey, XmlUtil.getTextContent(childNode) );
|
||||
if (DEBUG)
|
||||
debug("childtext-2-property mapping, setting " + helmaKey + " as string" );
|
||||
}
|
||||
continue;
|
||||
}
|
||||
// it's some kind of element (property or child)
|
||||
if (childNode.getNodeType() == Node.ELEMENT_NODE) {
|
||||
Element childElement = (Element) childNode;
|
||||
|
||||
// is there a simple child-2-property mapping?
|
||||
// (lets the user define to use only one element and make this a property
|
||||
// and simply ignore other elements of the same name)
|
||||
if ( props!=null && props.containsKey(domKey+"._property") ) {
|
||||
helmaKey = props.getProperty(domKey+"._property");
|
||||
// if property is set but without value, read elementname for this mapping:
|
||||
if ( helmaKey.equals("") )
|
||||
helmaKey = childElement.getNodeName().replace(':',defaultSeparator);
|
||||
if (DEBUG)
|
||||
debug("child-2-property mapping, helmaKey " + helmaKey + " for domKey " + domKey);
|
||||
// get the node on which to opererate, depending on the helmaKey
|
||||
// value from the properties file.
|
||||
INode node = helmaNode;
|
||||
int dot = helmaKey.indexOf(".");
|
||||
if (dot > -1) {
|
||||
String prototype = helmaKey.substring (0, dot);
|
||||
if (!prototype.equalsIgnoreCase (node.getPrototype()))
|
||||
node = (INode) nodeCache.get (prototype);
|
||||
helmaKey = helmaKey.substring (dot+1);
|
||||
}
|
||||
if (node == null)
|
||||
continue;
|
||||
// get the basic key we have to look for in the properties-table
|
||||
domKey = element.getNodeName() + "." + childElement.getNodeName();
|
||||
|
||||
if ( node.getNode(helmaKey)==null ) {
|
||||
convert( childElement, node.createNode(helmaKey), nodeCache );
|
||||
if (DEBUG)
|
||||
debug( "read " + childElement.toString() + node.getNode(helmaKey).toString() );
|
||||
}
|
||||
continue;
|
||||
}
|
||||
// is there a childtext-2-property mapping?
|
||||
if ((props != null) && props.containsKey(domKey + "._text")) {
|
||||
helmaKey = props.getProperty(domKey + "._text");
|
||||
|
||||
if (helmaKey.equals("")) {
|
||||
// if property is set but without value, read elementname for this mapping
|
||||
helmaKey = childElement.getNodeName().replace(':',
|
||||
defaultSeparator);
|
||||
}
|
||||
|
||||
// map it to one of the children-lists
|
||||
helma.objectmodel.INode newHelmaNode = null;
|
||||
String childrenMapping = props.getProperty(element.getNodeName()+"._children");
|
||||
// do we need a mapping directly among _children of helmaNode?
|
||||
// can either be through property elname._children=_all or elname._children=childname
|
||||
if( childrenMapping!=null && ( childrenMapping.equals("_all") || childrenMapping.equals(childElement.getNodeName()) ) ) {
|
||||
newHelmaNode = convert(childElement, helmaNode.createNode(null), nodeCache );
|
||||
}
|
||||
// in which virtual subnode collection should objects of this type be stored?
|
||||
helmaKey = props.getProperty(domKey);
|
||||
if ( helmaKey==null && !sparse ) {
|
||||
helmaKey = childElement.getNodeName().replace(':',defaultSeparator);
|
||||
}
|
||||
if (helmaKey == null) {
|
||||
// we don't map this child element itself since we do
|
||||
// sparse parsing, but there may be something of interest
|
||||
// in the child's attributes and child elements.
|
||||
attributes (childElement, helmaNode, nodeCache);
|
||||
children (childElement, helmaNode, nodeCache);
|
||||
continue;
|
||||
}
|
||||
if (DEBUG) {
|
||||
debug("childtext-2-property mapping, helmaKey " + helmaKey +
|
||||
" for domKey " + domKey);
|
||||
}
|
||||
|
||||
// get the node on which to opererate, depending on the helmaKey
|
||||
// value from the properties file.
|
||||
INode node = helmaNode;
|
||||
int dot = helmaKey.indexOf(".");
|
||||
if (dot > -1) {
|
||||
String prototype = helmaKey.substring (0, dot);
|
||||
if (!prototype.equalsIgnoreCase (node.getPrototype()))
|
||||
node = (INode) nodeCache.get (prototype);
|
||||
helmaKey = helmaKey.substring (dot+1);
|
||||
}
|
||||
if (node == null)
|
||||
continue;
|
||||
// check if helmaKey contains an explicit prototype name in which to
|
||||
// set the property.
|
||||
int dot = helmaKey.indexOf(".");
|
||||
|
||||
// try to get the virtual node
|
||||
INode worknode = null;
|
||||
if ("_children".equals (helmaKey)) {
|
||||
worknode = node;
|
||||
} else {
|
||||
worknode = node.getNode( helmaKey );
|
||||
if ( worknode==null ) {
|
||||
// if virtual node doesn't exist, create it
|
||||
worknode = helmaNode.createNode( helmaKey );
|
||||
}
|
||||
}
|
||||
if (DEBUG)
|
||||
debug( "mounting child "+ childElement.getNodeName() + " at worknode " + worknode.toString() );
|
||||
// now mount it, possibly re-using the helmaNode that's been created before
|
||||
if ( newHelmaNode!=null ) {
|
||||
worknode.addNode(newHelmaNode);
|
||||
} else {
|
||||
convert( childElement, worknode.createNode( null ), nodeCache );
|
||||
}
|
||||
}
|
||||
// forget about other types (comments etc)
|
||||
continue;
|
||||
}
|
||||
if (dot > -1) {
|
||||
String prototype = helmaKey.substring(0, dot);
|
||||
INode node = (INode) nodeCache.get(prototype);
|
||||
|
||||
// if there's some text content for this element, map it:
|
||||
if ( textcontent.length()>0 && !sparse ) {
|
||||
helmaKey = props.getProperty(element.getNodeName()+"._text");
|
||||
if ( helmaKey==null )
|
||||
helmaKey = "text";
|
||||
if (DEBUG)
|
||||
debug ("setting text "+textcontent+" to property "+helmaKey+" of object "+helmaNode);
|
||||
helmaNode.setString(helmaKey, textcontent.toString().trim() );
|
||||
}
|
||||
helmaKey = helmaKey.substring(dot + 1);
|
||||
|
||||
return helmaNode;
|
||||
if ((node != null) && (node.getString(helmaKey) == null)) {
|
||||
node.setString(helmaKey, XmlUtil.getTextContent(childNode));
|
||||
}
|
||||
} else if (helmaNode.getString(helmaKey) == null) {
|
||||
helmaNode.setString(helmaKey, XmlUtil.getTextContent(childNode));
|
||||
|
||||
if (DEBUG) {
|
||||
debug("childtext-2-property mapping, setting " + helmaKey +
|
||||
" as string");
|
||||
}
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// is there a simple child-2-property mapping?
|
||||
// (lets the user define to use only one element and make this a property
|
||||
// and simply ignore other elements of the same name)
|
||||
if ((props != null) && props.containsKey(domKey + "._property")) {
|
||||
helmaKey = props.getProperty(domKey + "._property");
|
||||
|
||||
// if property is set but without value, read elementname for this mapping:
|
||||
if (helmaKey.equals("")) {
|
||||
helmaKey = childElement.getNodeName().replace(':',
|
||||
defaultSeparator);
|
||||
}
|
||||
|
||||
if (DEBUG) {
|
||||
debug("child-2-property mapping, helmaKey " + helmaKey +
|
||||
" for domKey " + domKey);
|
||||
}
|
||||
|
||||
// get the node on which to opererate, depending on the helmaKey
|
||||
// value from the properties file.
|
||||
INode node = helmaNode;
|
||||
int dot = helmaKey.indexOf(".");
|
||||
|
||||
if (dot > -1) {
|
||||
String prototype = helmaKey.substring(0, dot);
|
||||
|
||||
if (!prototype.equalsIgnoreCase(node.getPrototype())) {
|
||||
node = (INode) nodeCache.get(prototype);
|
||||
}
|
||||
|
||||
helmaKey = helmaKey.substring(dot + 1);
|
||||
}
|
||||
|
||||
if (node == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (node.getNode(helmaKey) == null) {
|
||||
convert(childElement, node.createNode(helmaKey), nodeCache);
|
||||
|
||||
if (DEBUG) {
|
||||
debug("read " + childElement.toString() +
|
||||
node.getNode(helmaKey).toString());
|
||||
}
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// map it to one of the children-lists
|
||||
helma.objectmodel.INode newHelmaNode = null;
|
||||
String childrenMapping = props.getProperty(element.getNodeName() +
|
||||
"._children");
|
||||
|
||||
// do we need a mapping directly among _children of helmaNode?
|
||||
// can either be through property elname._children=_all or elname._children=childname
|
||||
if ((childrenMapping != null) &&
|
||||
(childrenMapping.equals("_all") ||
|
||||
childrenMapping.equals(childElement.getNodeName()))) {
|
||||
newHelmaNode = convert(childElement, helmaNode.createNode(null),
|
||||
nodeCache);
|
||||
}
|
||||
|
||||
// in which virtual subnode collection should objects of this type be stored?
|
||||
helmaKey = props.getProperty(domKey);
|
||||
|
||||
if ((helmaKey == null) && !sparse) {
|
||||
helmaKey = childElement.getNodeName().replace(':', defaultSeparator);
|
||||
}
|
||||
|
||||
if (helmaKey == null) {
|
||||
// we don't map this child element itself since we do
|
||||
// sparse parsing, but there may be something of interest
|
||||
// in the child's attributes and child elements.
|
||||
attributes(childElement, helmaNode, nodeCache);
|
||||
children(childElement, helmaNode, nodeCache);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// get the node on which to opererate, depending on the helmaKey
|
||||
// value from the properties file.
|
||||
INode node = helmaNode;
|
||||
int dot = helmaKey.indexOf(".");
|
||||
|
||||
if (dot > -1) {
|
||||
String prototype = helmaKey.substring(0, dot);
|
||||
|
||||
if (!prototype.equalsIgnoreCase(node.getPrototype())) {
|
||||
node = (INode) nodeCache.get(prototype);
|
||||
}
|
||||
|
||||
helmaKey = helmaKey.substring(dot + 1);
|
||||
}
|
||||
|
||||
if (node == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// try to get the virtual node
|
||||
INode worknode = null;
|
||||
|
||||
if ("_children".equals(helmaKey)) {
|
||||
worknode = node;
|
||||
} else {
|
||||
worknode = node.getNode(helmaKey);
|
||||
|
||||
if (worknode == null) {
|
||||
// if virtual node doesn't exist, create it
|
||||
worknode = helmaNode.createNode(helmaKey);
|
||||
}
|
||||
}
|
||||
|
||||
if (DEBUG) {
|
||||
debug("mounting child " + childElement.getNodeName() +
|
||||
" at worknode " + worknode.toString());
|
||||
}
|
||||
|
||||
// now mount it, possibly re-using the helmaNode that's been created before
|
||||
if (newHelmaNode != null) {
|
||||
worknode.addNode(newHelmaNode);
|
||||
} else {
|
||||
convert(childElement, worknode.createNode(null), nodeCache);
|
||||
}
|
||||
}
|
||||
|
||||
// forget about other types (comments etc)
|
||||
continue;
|
||||
}
|
||||
|
||||
// if there's some text content for this element, map it:
|
||||
if ((textcontent.length() > 0) && !sparse) {
|
||||
helmaKey = props.getProperty(element.getNodeName() + "._text");
|
||||
|
||||
if (helmaKey == null) {
|
||||
helmaKey = "text";
|
||||
}
|
||||
|
||||
if (DEBUG) {
|
||||
debug("setting text " + textcontent + " to property " + helmaKey +
|
||||
" of object " + helmaNode);
|
||||
}
|
||||
|
||||
helmaNode.setString(helmaKey, textcontent.toString().trim());
|
||||
}
|
||||
|
||||
return helmaNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* set element's attributes as properties of helmaNode
|
||||
*/
|
||||
private INode attributes( Element element, INode helmaNode, Map nodeCache ) {
|
||||
NamedNodeMap nnm = element.getAttributes();
|
||||
int len = nnm.getLength();
|
||||
for ( int i=0; i<len; i++ ) {
|
||||
org.w3c.dom.Node attr = nnm.item(i);
|
||||
String helmaKey = props.getProperty(element.getNodeName()+"._attribute."+attr.getNodeName());
|
||||
// unless we only map explicit attributes, use attribute name as property name
|
||||
// in case no property name was defined.
|
||||
if ( helmaKey==null && !sparse)
|
||||
helmaKey = attr.getNodeName().replace(':',defaultSeparator);
|
||||
if (helmaKey != null) {
|
||||
// check if the mapping contains the prototype to which
|
||||
// the property should be applied
|
||||
int dot = helmaKey.indexOf (".");
|
||||
if (dot > -1) {
|
||||
String prototype = helmaKey.substring (0, dot);
|
||||
INode node = (INode) nodeCache.get (prototype);
|
||||
if (node != null) {
|
||||
node.setString (helmaKey.substring(dot+1), attr.getNodeValue());
|
||||
}
|
||||
} else if (helmaNode.getPrototype() != null) {
|
||||
helmaNode.setString( helmaKey, attr.getNodeValue() );
|
||||
}
|
||||
}
|
||||
}
|
||||
return helmaNode;
|
||||
private INode attributes(Element element, INode helmaNode, Map nodeCache) {
|
||||
NamedNodeMap nnm = element.getAttributes();
|
||||
int len = nnm.getLength();
|
||||
|
||||
for (int i = 0; i < len; i++) {
|
||||
org.w3c.dom.Node attr = nnm.item(i);
|
||||
String helmaKey = props.getProperty(element.getNodeName() + "._attribute." +
|
||||
attr.getNodeName());
|
||||
|
||||
// unless we only map explicit attributes, use attribute name as property name
|
||||
// in case no property name was defined.
|
||||
if ((helmaKey == null) && !sparse) {
|
||||
helmaKey = attr.getNodeName().replace(':', defaultSeparator);
|
||||
}
|
||||
|
||||
if (helmaKey != null) {
|
||||
// check if the mapping contains the prototype to which
|
||||
// the property should be applied
|
||||
int dot = helmaKey.indexOf(".");
|
||||
|
||||
if (dot > -1) {
|
||||
String prototype = helmaKey.substring(0, dot);
|
||||
INode node = (INode) nodeCache.get(prototype);
|
||||
|
||||
if (node != null) {
|
||||
node.setString(helmaKey.substring(dot + 1), attr.getNodeValue());
|
||||
}
|
||||
} else if (helmaNode.getPrototype() != null) {
|
||||
helmaNode.setString(helmaKey, attr.getNodeValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return helmaNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* utility function
|
||||
*/
|
||||
private void extractProperties( Properties props ) {
|
||||
if ( props.containsKey("separator") ) {
|
||||
defaultSeparator = props.getProperty("separator").charAt(0);
|
||||
}
|
||||
sparse = "sparse".equalsIgnoreCase (props.getProperty("_mode"));
|
||||
}
|
||||
private void extractProperties(Properties props) {
|
||||
if (props.containsKey("separator")) {
|
||||
defaultSeparator = props.getProperty("separator").charAt(0);
|
||||
}
|
||||
|
||||
sparse = "sparse".equalsIgnoreCase(props.getProperty("_mode"));
|
||||
}
|
||||
|
||||
/** for testing */
|
||||
void debug(Object msg) {
|
||||
for ( int i=0; i<offset; i++ ) {
|
||||
System.out.print(" ");
|
||||
}
|
||||
System.out.println(msg.toString());
|
||||
for (int i = 0; i < offset; i++) {
|
||||
System.out.print(" ");
|
||||
}
|
||||
|
||||
System.out.println(msg.toString());
|
||||
}
|
||||
|
||||
|
||||
public static void main ( String args[] ) {
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param args ...
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -1,189 +1,263 @@
|
|||
/*
|
||||
* 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.dom;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.text.ParseException;
|
||||
import java.util.Date;
|
||||
// import java.util.HashMap;
|
||||
import java.util.Hashtable;
|
||||
import java.util.List;
|
||||
|
||||
import javax.xml.parsers.*;
|
||||
|
||||
import org.xml.sax.*;
|
||||
import org.xml.sax.helpers.DefaultHandler;
|
||||
|
||||
import helma.objectmodel.INode;
|
||||
import helma.objectmodel.db.DbKey;
|
||||
import helma.objectmodel.db.DbMapping;
|
||||
import helma.objectmodel.db.ExternalizableVector;
|
||||
import helma.objectmodel.db.Node;
|
||||
import helma.objectmodel.db.NodeHandle;
|
||||
import helma.objectmodel.db.NodeManager;
|
||||
import helma.objectmodel.db.Property;
|
||||
import helma.objectmodel.db.DbMapping;
|
||||
import org.xml.sax.*;
|
||||
import org.xml.sax.helpers.DefaultHandler;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
// import java.util.HashMap;
|
||||
import java.util.Hashtable;
|
||||
import java.util.List;
|
||||
import javax.xml.parsers.*;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public final class XmlDatabaseReader extends DefaultHandler implements XmlConstants {
|
||||
|
||||
static SAXParserFactory factory = SAXParserFactory.newInstance();
|
||||
private NodeManager nmgr = null;
|
||||
private Node currentNode;
|
||||
|
||||
private String elementType = null;
|
||||
private String elementName = null;
|
||||
private StringBuffer charBuffer = null;
|
||||
|
||||
Hashtable propMap = null;
|
||||
List subnodes = null;
|
||||
|
||||
static SAXParserFactory factory = SAXParserFactory.newInstance ();
|
||||
|
||||
|
||||
public XmlDatabaseReader (NodeManager nmgr) {
|
||||
this.nmgr = nmgr;
|
||||
/**
|
||||
* Creates a new XmlDatabaseReader object.
|
||||
*
|
||||
* @param nmgr ...
|
||||
*/
|
||||
public XmlDatabaseReader(NodeManager nmgr) {
|
||||
this.nmgr = nmgr;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* read an InputSource with xml-content.
|
||||
*/
|
||||
public Node read (File file)
|
||||
throws ParserConfigurationException, SAXException, IOException {
|
||||
if (nmgr==null)
|
||||
throw new RuntimeException ("can't create a new Node without a NodeManager");
|
||||
public Node read(File file)
|
||||
throws ParserConfigurationException, SAXException, IOException {
|
||||
if (nmgr == null) {
|
||||
throw new RuntimeException("can't create a new Node without a NodeManager");
|
||||
}
|
||||
|
||||
SAXParser parser = factory.newSAXParser ();
|
||||
SAXParser parser = factory.newSAXParser();
|
||||
|
||||
currentNode = null;
|
||||
currentNode = null;
|
||||
|
||||
parser.parse (file, this);
|
||||
return currentNode;
|
||||
parser.parse(file, this);
|
||||
|
||||
return currentNode;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param namespaceURI ...
|
||||
* @param localName ...
|
||||
* @param qName ...
|
||||
* @param atts ...
|
||||
*/
|
||||
public void startElement(String namespaceURI, String localName, String qName,
|
||||
Attributes atts) {
|
||||
// System.err.println ("XML-READ: startElement "+namespaceURI+", "+localName+", "+qName+", "+atts.getValue("id"));
|
||||
// discard the first element called xmlroot
|
||||
if ("xmlroot".equals(qName) && (currentNode == null)) {
|
||||
return;
|
||||
}
|
||||
|
||||
public void startElement(String namespaceURI, String localName, String qName, Attributes atts) {
|
||||
// System.err.println ("XML-READ: startElement "+namespaceURI+", "+localName+", "+qName+", "+atts.getValue("id"));
|
||||
// discard the first element called xmlroot
|
||||
if ("xmlroot".equals (qName) && currentNode == null)
|
||||
return;
|
||||
// if currentNode is null, this must be the hopobject node
|
||||
if ("hopobject".equals (qName) && currentNode == null) {
|
||||
String id = atts.getValue ("id");
|
||||
String name = atts.getValue ("name");
|
||||
String prototype = atts.getValue ("prototype");
|
||||
if ( "".equals(prototype) )
|
||||
prototype = "hopobject";
|
||||
// if currentNode is null, this must be the hopobject node
|
||||
if ("hopobject".equals(qName) && (currentNode == null)) {
|
||||
String id = atts.getValue("id");
|
||||
String name = atts.getValue("name");
|
||||
String prototype = atts.getValue("prototype");
|
||||
|
||||
try {
|
||||
long created = Long.parseLong (atts.getValue ("created"));
|
||||
long lastmodified = Long.parseLong (atts.getValue ("lastModified"));
|
||||
currentNode = new Node (name,id,prototype,nmgr.safe,created,lastmodified);
|
||||
} catch ( NumberFormatException e ) {
|
||||
currentNode = new Node (name,id,prototype,nmgr.safe);
|
||||
}
|
||||
return;
|
||||
}
|
||||
// find out what kind of element this is by looking at
|
||||
// the number and names of attributes.
|
||||
String idref = atts.getValue ("idref");
|
||||
if (idref != null) {
|
||||
// a hopobject reference.
|
||||
NodeHandle handle = makeNodeHandle (atts);
|
||||
if ("hop:child".equals (qName)) {
|
||||
if (subnodes == null) {
|
||||
subnodes = new ExternalizableVector ();
|
||||
currentNode.setSubnodes (subnodes);
|
||||
}
|
||||
subnodes.add (handle);
|
||||
} else if ("hop:parent".equals (qName)) {
|
||||
currentNode.setParentHandle (handle);
|
||||
} else {
|
||||
// property name may be encoded as "propertyname" attribute,
|
||||
// otherwise it is the element name
|
||||
String propName = atts.getValue ("propertyname");
|
||||
if (propName == null)
|
||||
propName = qName;
|
||||
Property prop = new Property (propName, currentNode);
|
||||
prop.setNodeHandle (handle);
|
||||
if (propMap == null) {
|
||||
propMap = new Hashtable ();
|
||||
currentNode.setPropMap (propMap);
|
||||
}
|
||||
propMap.put (propName.toLowerCase(), prop);
|
||||
}
|
||||
} else {
|
||||
// a primitive property
|
||||
elementType = atts.getValue ("type");
|
||||
if (elementType == null)
|
||||
elementType = "string";
|
||||
// property name may be encoded as "propertyname" attribute,
|
||||
// otherwise it is the element name
|
||||
elementName = atts.getValue ("propertyname");
|
||||
if (elementName == null)
|
||||
elementName = qName;
|
||||
if (charBuffer == null)
|
||||
charBuffer = new StringBuffer();
|
||||
else
|
||||
charBuffer.setLength (0);
|
||||
}
|
||||
if ("".equals(prototype)) {
|
||||
prototype = "hopobject";
|
||||
}
|
||||
|
||||
try {
|
||||
long created = Long.parseLong(atts.getValue("created"));
|
||||
long lastmodified = Long.parseLong(atts.getValue("lastModified"));
|
||||
|
||||
currentNode = new Node(name, id, prototype, nmgr.safe, created,
|
||||
lastmodified);
|
||||
} catch (NumberFormatException e) {
|
||||
currentNode = new Node(name, id, prototype, nmgr.safe);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// find out what kind of element this is by looking at
|
||||
// the number and names of attributes.
|
||||
String idref = atts.getValue("idref");
|
||||
|
||||
if (idref != null) {
|
||||
// a hopobject reference.
|
||||
NodeHandle handle = makeNodeHandle(atts);
|
||||
|
||||
if ("hop:child".equals(qName)) {
|
||||
if (subnodes == null) {
|
||||
subnodes = new ExternalizableVector();
|
||||
currentNode.setSubnodes(subnodes);
|
||||
}
|
||||
|
||||
subnodes.add(handle);
|
||||
} else if ("hop:parent".equals(qName)) {
|
||||
currentNode.setParentHandle(handle);
|
||||
} else {
|
||||
// property name may be encoded as "propertyname" attribute,
|
||||
// otherwise it is the element name
|
||||
String propName = atts.getValue("propertyname");
|
||||
|
||||
if (propName == null) {
|
||||
propName = qName;
|
||||
}
|
||||
|
||||
Property prop = new Property(propName, currentNode);
|
||||
|
||||
prop.setNodeHandle(handle);
|
||||
|
||||
if (propMap == null) {
|
||||
propMap = new Hashtable();
|
||||
currentNode.setPropMap(propMap);
|
||||
}
|
||||
|
||||
propMap.put(propName.toLowerCase(), prop);
|
||||
}
|
||||
} else {
|
||||
// a primitive property
|
||||
elementType = atts.getValue("type");
|
||||
|
||||
if (elementType == null) {
|
||||
elementType = "string";
|
||||
}
|
||||
|
||||
// property name may be encoded as "propertyname" attribute,
|
||||
// otherwise it is the element name
|
||||
elementName = atts.getValue("propertyname");
|
||||
|
||||
if (elementName == null) {
|
||||
elementName = qName;
|
||||
}
|
||||
|
||||
if (charBuffer == null) {
|
||||
charBuffer = new StringBuffer();
|
||||
} else {
|
||||
charBuffer.setLength(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void characters (char[] ch, int start, int length)
|
||||
throws SAXException {
|
||||
// append chars to char buffer
|
||||
if (elementType != null)
|
||||
charBuffer.append (ch, start, length);
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param ch ...
|
||||
* @param start ...
|
||||
* @param length ...
|
||||
*
|
||||
* @throws SAXException ...
|
||||
*/
|
||||
public void characters(char[] ch, int start, int length)
|
||||
throws SAXException {
|
||||
// append chars to char buffer
|
||||
if (elementType != null) {
|
||||
charBuffer.append(ch, start, length);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param namespaceURI ...
|
||||
* @param localName ...
|
||||
* @param qName ...
|
||||
*
|
||||
* @throws SAXException ...
|
||||
*/
|
||||
public void endElement(String namespaceURI, String localName, String qName)
|
||||
throws SAXException {
|
||||
if (elementType != null) {
|
||||
Property prop = new Property (elementName, currentNode);
|
||||
String charValue = charBuffer.toString ();
|
||||
charBuffer.setLength (0);
|
||||
if ( "boolean".equals (elementType) ) {
|
||||
if ( "true".equals(charValue) ) {
|
||||
prop.setBooleanValue(true);
|
||||
} else {
|
||||
prop.setBooleanValue(false);
|
||||
}
|
||||
} else if ( "date".equals(elementType) ) {
|
||||
SimpleDateFormat format = new SimpleDateFormat ( DATEFORMAT );
|
||||
try {
|
||||
Date date = format.parse(charValue);
|
||||
prop.setDateValue (date);
|
||||
} catch ( ParseException e ) {
|
||||
prop.setStringValue (charValue);
|
||||
}
|
||||
} else if ( "float".equals(elementType) ) {
|
||||
prop.setFloatValue ((new Double(charValue)).doubleValue());
|
||||
} else if ( "integer".equals(elementType) ) {
|
||||
prop.setIntegerValue ((new Long(charValue)).longValue());
|
||||
} else {
|
||||
prop.setStringValue (charValue);
|
||||
}
|
||||
if (propMap == null) {
|
||||
propMap = new Hashtable ();
|
||||
currentNode.setPropMap (propMap);
|
||||
}
|
||||
propMap.put (elementName.toLowerCase(), prop);
|
||||
elementName = null;
|
||||
elementType = null;
|
||||
charValue = null;
|
||||
}
|
||||
}
|
||||
throws SAXException {
|
||||
if (elementType != null) {
|
||||
Property prop = new Property(elementName, currentNode);
|
||||
String charValue = charBuffer.toString();
|
||||
|
||||
charBuffer.setLength(0);
|
||||
|
||||
if ("boolean".equals(elementType)) {
|
||||
if ("true".equals(charValue)) {
|
||||
prop.setBooleanValue(true);
|
||||
} else {
|
||||
prop.setBooleanValue(false);
|
||||
}
|
||||
} else if ("date".equals(elementType)) {
|
||||
SimpleDateFormat format = new SimpleDateFormat(DATEFORMAT);
|
||||
|
||||
try {
|
||||
Date date = format.parse(charValue);
|
||||
|
||||
prop.setDateValue(date);
|
||||
} catch (ParseException e) {
|
||||
prop.setStringValue(charValue);
|
||||
}
|
||||
} else if ("float".equals(elementType)) {
|
||||
prop.setFloatValue((new Double(charValue)).doubleValue());
|
||||
} else if ("integer".equals(elementType)) {
|
||||
prop.setIntegerValue((new Long(charValue)).longValue());
|
||||
} else {
|
||||
prop.setStringValue(charValue);
|
||||
}
|
||||
|
||||
if (propMap == null) {
|
||||
propMap = new Hashtable();
|
||||
currentNode.setPropMap(propMap);
|
||||
}
|
||||
|
||||
propMap.put(elementName.toLowerCase(), prop);
|
||||
elementName = null;
|
||||
elementType = null;
|
||||
charValue = null;
|
||||
}
|
||||
}
|
||||
|
||||
// create a node handle from a node reference DOM element
|
||||
private NodeHandle makeNodeHandle (Attributes atts) {
|
||||
String idref = atts.getValue ("idref");
|
||||
String protoref = atts.getValue ("prototyperef");
|
||||
DbMapping dbmap = null;
|
||||
if (protoref != null)
|
||||
dbmap = nmgr.getDbMapping(protoref);
|
||||
return new NodeHandle (new DbKey (dbmap, idref));
|
||||
private NodeHandle makeNodeHandle(Attributes atts) {
|
||||
String idref = atts.getValue("idref");
|
||||
String protoref = atts.getValue("prototyperef");
|
||||
DbMapping dbmap = null;
|
||||
|
||||
if (protoref != null) {
|
||||
dbmap = nmgr.getDbMapping(protoref);
|
||||
}
|
||||
|
||||
return new NodeHandle(new DbKey(dbmap, idref));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -1,226 +1,305 @@
|
|||
/*
|
||||
* 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.dom;
|
||||
|
||||
import helma.objectmodel.INode;
|
||||
import org.xml.sax.*;
|
||||
import org.xml.sax.helpers.DefaultHandler;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.Reader;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Stack;
|
||||
|
||||
import javax.xml.parsers.*;
|
||||
|
||||
import org.xml.sax.*;
|
||||
import org.xml.sax.helpers.DefaultHandler;
|
||||
|
||||
import helma.objectmodel.INode;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public final class XmlReader extends DefaultHandler implements XmlConstants {
|
||||
|
||||
private INode rootNode, currentNode;
|
||||
static SAXParserFactory factory = SAXParserFactory.newInstance();
|
||||
private INode rootNode;
|
||||
private INode currentNode;
|
||||
private Stack nodeStack;
|
||||
private HashMap convertedNodes;
|
||||
|
||||
private String elementType = null;
|
||||
private String elementName = null;
|
||||
private StringBuffer charBuffer = null;
|
||||
|
||||
static SAXParserFactory factory = SAXParserFactory.newInstance ();
|
||||
|
||||
boolean parsingHopObject;
|
||||
|
||||
public XmlReader () {
|
||||
/**
|
||||
* Creates a new XmlReader object.
|
||||
*/
|
||||
public XmlReader() {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* main entry to read an xml-file.
|
||||
*/
|
||||
public INode read (File file, INode helmaNode)
|
||||
throws ParserConfigurationException, SAXException, IOException {
|
||||
try {
|
||||
return read (new FileInputStream(file), helmaNode);
|
||||
} catch (FileNotFoundException notfound) {
|
||||
System.err.println ("couldn't find xml-file: " + file.getAbsolutePath ());
|
||||
return helmaNode;
|
||||
}
|
||||
public INode read(File file, INode helmaNode)
|
||||
throws ParserConfigurationException, SAXException, IOException {
|
||||
try {
|
||||
return read(new FileInputStream(file), helmaNode);
|
||||
} catch (FileNotFoundException notfound) {
|
||||
System.err.println("couldn't find xml-file: " + file.getAbsolutePath());
|
||||
|
||||
return helmaNode;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* read an InputStream with xml-content.
|
||||
*/
|
||||
public INode read (InputStream in, INode helmaNode)
|
||||
throws ParserConfigurationException, SAXException, IOException {
|
||||
return read (new InputSource (in), helmaNode);
|
||||
public INode read(InputStream in, INode helmaNode)
|
||||
throws ParserConfigurationException, SAXException, IOException {
|
||||
return read(new InputSource(in), helmaNode);
|
||||
}
|
||||
|
||||
/**
|
||||
* read an character reader with xml-content.
|
||||
*/
|
||||
public INode read (Reader in, INode helmaNode)
|
||||
throws ParserConfigurationException, SAXException, IOException {
|
||||
return read (new InputSource (in), helmaNode);
|
||||
public INode read(Reader in, INode helmaNode)
|
||||
throws ParserConfigurationException, SAXException, IOException {
|
||||
return read(new InputSource(in), helmaNode);
|
||||
}
|
||||
|
||||
/**
|
||||
* read an InputSource with xml-content.
|
||||
*/
|
||||
public INode read (InputSource in, INode helmaNode)
|
||||
throws ParserConfigurationException, SAXException, IOException {
|
||||
if (helmaNode==null)
|
||||
throw new RuntimeException ("Can't create a new Node without a root Node");
|
||||
public INode read(InputSource in, INode helmaNode)
|
||||
throws ParserConfigurationException, SAXException, IOException {
|
||||
if (helmaNode == null) {
|
||||
throw new RuntimeException("Can't create a new Node without a root Node");
|
||||
}
|
||||
|
||||
SAXParser parser = factory.newSAXParser ();
|
||||
SAXParser parser = factory.newSAXParser();
|
||||
|
||||
rootNode = helmaNode;
|
||||
currentNode = null;
|
||||
convertedNodes = new HashMap ();
|
||||
nodeStack = new Stack ();
|
||||
parsingHopObject = true;
|
||||
rootNode = helmaNode;
|
||||
currentNode = null;
|
||||
convertedNodes = new HashMap();
|
||||
nodeStack = new Stack();
|
||||
parsingHopObject = true;
|
||||
|
||||
parser.parse (in, this);
|
||||
return rootNode;
|
||||
parser.parse(in, this);
|
||||
|
||||
return rootNode;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param namespaceURI ...
|
||||
* @param localName ...
|
||||
* @param qName ...
|
||||
* @param atts ...
|
||||
*
|
||||
* @throws SAXException ...
|
||||
*/
|
||||
public void startElement(String namespaceURI, String localName, String qName,
|
||||
Attributes atts) throws SAXException {
|
||||
// System.err.println ("XML-READ: startElement "+namespaceURI+", "+localName+", "+qName+", "+atts.getValue("id"));
|
||||
// discard the first element called xmlroot
|
||||
if ("xmlroot".equals(qName) && (currentNode == null)) {
|
||||
return;
|
||||
}
|
||||
|
||||
public void startElement(String namespaceURI, String localName, String qName, Attributes atts)
|
||||
throws SAXException {
|
||||
// System.err.println ("XML-READ: startElement "+namespaceURI+", "+localName+", "+qName+", "+atts.getValue("id"));
|
||||
// discard the first element called xmlroot
|
||||
if ("xmlroot".equals (qName) && currentNode == null)
|
||||
return;
|
||||
// if currentNode is null, this must be the hopobject node
|
||||
String id = atts.getValue ("id");
|
||||
if (id != null) {
|
||||
// check if there is a current node.
|
||||
if (currentNode == null) {
|
||||
// If currentNode is null, this is the root node we're parsing.
|
||||
currentNode = rootNode;
|
||||
} else if ("hop:child".equals (qName)) {
|
||||
// it's an anonymous child node
|
||||
nodeStack.push (currentNode);
|
||||
currentNode = currentNode.createNode (null);
|
||||
} else {
|
||||
// it's a named node property
|
||||
nodeStack.push (currentNode);
|
||||
// property name may be encoded as "propertyname" attribute,
|
||||
// otherwise it is the element name
|
||||
String propName = atts.getValue ("propertyname");
|
||||
if (propName == null)
|
||||
propName = qName;
|
||||
currentNode = currentNode.createNode (propName);
|
||||
}
|
||||
// set the prototype on the current node and
|
||||
// add it to the map of parsed nodes.
|
||||
String prototype = atts.getValue ("prototype");
|
||||
if ( !"".equals(prototype) && !"hopobject".equals(prototype) )
|
||||
currentNode.setPrototype (prototype);
|
||||
String key = id + "-" + prototype;
|
||||
convertedNodes.put( key, currentNode );
|
||||
return;
|
||||
}
|
||||
// if currentNode is null, this must be the hopobject node
|
||||
String id = atts.getValue("id");
|
||||
|
||||
// check if we have a currentNode to set properties on,
|
||||
// otherwise throw exception.
|
||||
if (currentNode == null)
|
||||
throw new SAXException ("Invalid XML: No valid root HopObject found");
|
||||
// check if we are inside a HopObject - otherwise throw an exception
|
||||
if (!parsingHopObject)
|
||||
throw new SAXException ("Invalid XML: Found nested non-HobObject elements");
|
||||
if (id != null) {
|
||||
// check if there is a current node.
|
||||
if (currentNode == null) {
|
||||
// If currentNode is null, this is the root node we're parsing.
|
||||
currentNode = rootNode;
|
||||
} else if ("hop:child".equals(qName)) {
|
||||
// it's an anonymous child node
|
||||
nodeStack.push(currentNode);
|
||||
currentNode = currentNode.createNode(null);
|
||||
} else {
|
||||
// it's a named node property
|
||||
nodeStack.push(currentNode);
|
||||
|
||||
// if we got so far, the element is not a hopobject. Set flag to prevent
|
||||
// the hopobject stack to be popped when the element
|
||||
// is closed.
|
||||
parsingHopObject = false;
|
||||
// property name may be encoded as "propertyname" attribute,
|
||||
// otherwise it is the element name
|
||||
String propName = atts.getValue("propertyname");
|
||||
|
||||
// Is it a reference to an already parsed node?
|
||||
String idref = atts.getValue ("idref");
|
||||
if (idref != null) {
|
||||
// a reference to a node that should have been parsed
|
||||
// and lying in our cache of parsed nodes.
|
||||
String prototyperef = atts.getValue ("prototyperef");
|
||||
String key = idref + "-" + prototyperef;
|
||||
INode n = (INode) convertedNodes.get (key);
|
||||
if (n != null) {
|
||||
if ("hop:child".equals (qName)) {
|
||||
// add an already parsed node as child to current node
|
||||
currentNode.addNode (n);
|
||||
} else {
|
||||
// set an already parsed node as node property to current node
|
||||
// property name may be encoded as "propertyname" attribute,
|
||||
// otherwise it is the element name
|
||||
String propName = atts.getValue ("propertyname");
|
||||
if (propName == null)
|
||||
propName = qName;
|
||||
currentNode.setNode (propName, n);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// It's a primitive property. Remember the property name and type
|
||||
// so we can properly parse/interpret the character data when we
|
||||
// get it later on.
|
||||
elementType = atts.getValue ("type");
|
||||
if (elementType == null)
|
||||
elementType = "string";
|
||||
// property name may be encoded as "propertyname" attribute,
|
||||
// otherwise it is the element name
|
||||
elementName = atts.getValue ("propertyname");
|
||||
if (elementName == null)
|
||||
elementName = qName;
|
||||
if (charBuffer == null)
|
||||
charBuffer = new StringBuffer();
|
||||
else
|
||||
charBuffer.setLength (0);
|
||||
}
|
||||
if (propName == null) {
|
||||
propName = qName;
|
||||
}
|
||||
|
||||
currentNode = currentNode.createNode(propName);
|
||||
}
|
||||
|
||||
// set the prototype on the current node and
|
||||
// add it to the map of parsed nodes.
|
||||
String prototype = atts.getValue("prototype");
|
||||
|
||||
if (!"".equals(prototype) && !"hopobject".equals(prototype)) {
|
||||
currentNode.setPrototype(prototype);
|
||||
}
|
||||
|
||||
String key = id + "-" + prototype;
|
||||
|
||||
convertedNodes.put(key, currentNode);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// check if we have a currentNode to set properties on,
|
||||
// otherwise throw exception.
|
||||
if (currentNode == null) {
|
||||
throw new SAXException("Invalid XML: No valid root HopObject found");
|
||||
}
|
||||
|
||||
// check if we are inside a HopObject - otherwise throw an exception
|
||||
if (!parsingHopObject) {
|
||||
throw new SAXException("Invalid XML: Found nested non-HobObject elements");
|
||||
}
|
||||
|
||||
// if we got so far, the element is not a hopobject. Set flag to prevent
|
||||
// the hopobject stack to be popped when the element
|
||||
// is closed.
|
||||
parsingHopObject = false;
|
||||
|
||||
// Is it a reference to an already parsed node?
|
||||
String idref = atts.getValue("idref");
|
||||
|
||||
if (idref != null) {
|
||||
// a reference to a node that should have been parsed
|
||||
// and lying in our cache of parsed nodes.
|
||||
String prototyperef = atts.getValue("prototyperef");
|
||||
String key = idref + "-" + prototyperef;
|
||||
INode n = (INode) convertedNodes.get(key);
|
||||
|
||||
if (n != null) {
|
||||
if ("hop:child".equals(qName)) {
|
||||
// add an already parsed node as child to current node
|
||||
currentNode.addNode(n);
|
||||
} else {
|
||||
// set an already parsed node as node property to current node
|
||||
// property name may be encoded as "propertyname" attribute,
|
||||
// otherwise it is the element name
|
||||
String propName = atts.getValue("propertyname");
|
||||
|
||||
if (propName == null) {
|
||||
propName = qName;
|
||||
}
|
||||
|
||||
currentNode.setNode(propName, n);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// It's a primitive property. Remember the property name and type
|
||||
// so we can properly parse/interpret the character data when we
|
||||
// get it later on.
|
||||
elementType = atts.getValue("type");
|
||||
|
||||
if (elementType == null) {
|
||||
elementType = "string";
|
||||
}
|
||||
|
||||
// property name may be encoded as "propertyname" attribute,
|
||||
// otherwise it is the element name
|
||||
elementName = atts.getValue("propertyname");
|
||||
|
||||
if (elementName == null) {
|
||||
elementName = qName;
|
||||
}
|
||||
|
||||
if (charBuffer == null) {
|
||||
charBuffer = new StringBuffer();
|
||||
} else {
|
||||
charBuffer.setLength(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void characters (char[] ch, int start, int length) throws SAXException {
|
||||
// System.err.println ("CHARACTERS: "+new String (ch, start, length));
|
||||
// append chars to char buffer
|
||||
if (elementType != null)
|
||||
charBuffer.append (ch, start, length);
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param ch ...
|
||||
* @param start ...
|
||||
* @param length ...
|
||||
*
|
||||
* @throws SAXException ...
|
||||
*/
|
||||
public void characters(char[] ch, int start, int length)
|
||||
throws SAXException {
|
||||
// System.err.println ("CHARACTERS: "+new String (ch, start, length));
|
||||
// append chars to char buffer
|
||||
if (elementType != null) {
|
||||
charBuffer.append(ch, start, length);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param namespaceURI ...
|
||||
* @param localName ...
|
||||
* @param qName ...
|
||||
*
|
||||
* @throws SAXException ...
|
||||
*/
|
||||
public void endElement(String namespaceURI, String localName, String qName)
|
||||
throws SAXException {
|
||||
if (elementType != null) {
|
||||
String charValue = charBuffer.toString ();
|
||||
charBuffer.setLength (0);
|
||||
if ( "boolean".equals (elementType) ) {
|
||||
if ( "true".equals(charValue) ) {
|
||||
currentNode.setBoolean(elementName, true);
|
||||
} else {
|
||||
currentNode.setBoolean(elementName, false);
|
||||
}
|
||||
} else if ( "date".equals(elementType) ) {
|
||||
SimpleDateFormat format = new SimpleDateFormat ( DATEFORMAT );
|
||||
try {
|
||||
Date date = format.parse(charValue);
|
||||
currentNode.setDate (elementName, date);
|
||||
} catch ( ParseException e ) {
|
||||
currentNode.setString (elementName, charValue);
|
||||
}
|
||||
} else if ( "float".equals(elementType) ) {
|
||||
currentNode.setFloat (elementName, (new Double(charValue)).doubleValue());
|
||||
} else if ( "integer".equals(elementType) ) {
|
||||
currentNode.setInteger (elementName, (new Long(charValue)).longValue());
|
||||
} else {
|
||||
currentNode.setString (elementName, charValue);
|
||||
}
|
||||
elementName = null;
|
||||
elementType = null;
|
||||
charValue = null;
|
||||
}
|
||||
if (parsingHopObject && !nodeStack.isEmpty ())
|
||||
currentNode = (INode) nodeStack.pop ();
|
||||
else
|
||||
parsingHopObject = true; // the next element end tag closes a hopobject again
|
||||
throws SAXException {
|
||||
if (elementType != null) {
|
||||
String charValue = charBuffer.toString();
|
||||
|
||||
charBuffer.setLength(0);
|
||||
|
||||
if ("boolean".equals(elementType)) {
|
||||
if ("true".equals(charValue)) {
|
||||
currentNode.setBoolean(elementName, true);
|
||||
} else {
|
||||
currentNode.setBoolean(elementName, false);
|
||||
}
|
||||
} else if ("date".equals(elementType)) {
|
||||
SimpleDateFormat format = new SimpleDateFormat(DATEFORMAT);
|
||||
|
||||
try {
|
||||
Date date = format.parse(charValue);
|
||||
|
||||
currentNode.setDate(elementName, date);
|
||||
} catch (ParseException e) {
|
||||
currentNode.setString(elementName, charValue);
|
||||
}
|
||||
} else if ("float".equals(elementType)) {
|
||||
currentNode.setFloat(elementName, (new Double(charValue)).doubleValue());
|
||||
} else if ("integer".equals(elementType)) {
|
||||
currentNode.setInteger(elementName, (new Long(charValue)).longValue());
|
||||
} else {
|
||||
currentNode.setString(elementName, charValue);
|
||||
}
|
||||
|
||||
elementName = null;
|
||||
elementType = null;
|
||||
charValue = null;
|
||||
}
|
||||
|
||||
if (parsingHopObject && !nodeStack.isEmpty()) {
|
||||
currentNode = (INode) nodeStack.pop();
|
||||
} else {
|
||||
parsingHopObject = true; // the next element end tag closes a hopobject again
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -1,109 +1,161 @@
|
|||
/*
|
||||
* 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.dom;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
|
||||
import helma.objectmodel.INode;
|
||||
import helma.objectmodel.TransientNode;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.InputSource;
|
||||
import org.xml.sax.SAXException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.WeakHashMap;
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
|
||||
import helma.objectmodel.INode;
|
||||
import helma.objectmodel.TransientNode;
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class XmlUtil {
|
||||
private static final DocumentBuilderFactory domBuilderFactory = javax.xml.parsers.DocumentBuilderFactory.newInstance();
|
||||
private static final WeakHashMap domBuilders = new WeakHashMap();
|
||||
|
||||
public class XmlUtil {
|
||||
private static synchronized DocumentBuilder getDocumentBuilder() {
|
||||
DocumentBuilder domBuilder = (DocumentBuilder) domBuilders.get(Thread.currentThread());
|
||||
|
||||
private static final DocumentBuilderFactory domBuilderFactory = javax.xml.parsers.DocumentBuilderFactory.newInstance();
|
||||
private static final WeakHashMap domBuilders = new WeakHashMap();
|
||||
if (domBuilder != null) {
|
||||
return domBuilder;
|
||||
} else {
|
||||
try {
|
||||
domBuilder = domBuilderFactory.newDocumentBuilder();
|
||||
domBuilders.put(Thread.currentThread(), domBuilder);
|
||||
|
||||
private static synchronized DocumentBuilder getDocumentBuilder() {
|
||||
DocumentBuilder domBuilder = (DocumentBuilder) domBuilders.get (Thread.currentThread());
|
||||
if (domBuilder != null) {
|
||||
return domBuilder;
|
||||
} else {
|
||||
try {
|
||||
domBuilder = domBuilderFactory.newDocumentBuilder();
|
||||
domBuilders.put (Thread.currentThread(), domBuilder);
|
||||
return domBuilder;
|
||||
} catch ( ParserConfigurationException e ) {
|
||||
throw new RuntimeException ("Cannot build parser: "+e.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
return domBuilder;
|
||||
} catch (ParserConfigurationException e) {
|
||||
throw new RuntimeException("Cannot build parser: " + e.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Document newDocument() {
|
||||
DocumentBuilder d = getDocumentBuilder();
|
||||
return d.newDocument();
|
||||
}
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public static Document newDocument() {
|
||||
DocumentBuilder d = getDocumentBuilder();
|
||||
|
||||
public static Document parse (InputStream in) throws RuntimeException {
|
||||
DocumentBuilder d = getDocumentBuilder();
|
||||
try {
|
||||
Document doc = d.parse (in);
|
||||
doc.normalize();
|
||||
return doc;
|
||||
} catch (SAXException e) {
|
||||
throw new RuntimeException ("Bad xml-code: "+e.toString());
|
||||
} catch (IOException f) {
|
||||
throw new RuntimeException ("Could not read Xml: "+f.toString());
|
||||
}
|
||||
}
|
||||
return d.newDocument();
|
||||
}
|
||||
|
||||
public static Document parse (InputSource in) throws RuntimeException {
|
||||
DocumentBuilder d = getDocumentBuilder();
|
||||
try {
|
||||
Document doc = d.parse (in);
|
||||
doc.normalize();
|
||||
return doc;
|
||||
} catch (SAXException e) {
|
||||
throw new RuntimeException ("Bad xml-code: "+e.toString());
|
||||
} catch (IOException f) {
|
||||
throw new RuntimeException ("Could not read Xml: "+f.toString());
|
||||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param in ...
|
||||
*
|
||||
* @return ...
|
||||
*
|
||||
* @throws RuntimeException ...
|
||||
*/
|
||||
public static Document parse(InputStream in) throws RuntimeException {
|
||||
DocumentBuilder d = getDocumentBuilder();
|
||||
|
||||
/**
|
||||
* get first "real" element (ie not the document-rootelement, but the next one
|
||||
*/
|
||||
public static Element getFirstElement (Document document) {
|
||||
Element workelement = null;
|
||||
if ( document.getDocumentElement()!=null ) {
|
||||
org.w3c.dom.Node tmp = document.getDocumentElement().getFirstChild();
|
||||
while( tmp!=null ) {
|
||||
tmp = tmp.getNextSibling();
|
||||
if ( tmp.getNodeType()==org.w3c.dom.Node.ELEMENT_NODE ) {
|
||||
workelement = (Element) tmp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return workelement;
|
||||
}
|
||||
try {
|
||||
Document doc = d.parse(in);
|
||||
|
||||
/**
|
||||
* return the text content of an element
|
||||
*/
|
||||
public static String getTextContent( org.w3c.dom.Node element ) {
|
||||
StringBuffer childtext = new StringBuffer();
|
||||
NodeList childlist = element.getChildNodes();
|
||||
int ct = childlist.getLength();
|
||||
for ( int j=0; j<ct; j++ ) {
|
||||
org.w3c.dom.Node childNode = childlist.item(j);
|
||||
if ( childNode.getNodeType() == Node.TEXT_NODE ||
|
||||
childNode.getNodeType() == Node.CDATA_SECTION_NODE) {
|
||||
childtext.append(childNode.getNodeValue().trim() );
|
||||
}
|
||||
}
|
||||
return childtext.toString();
|
||||
}
|
||||
doc.normalize();
|
||||
|
||||
return doc;
|
||||
} catch (SAXException e) {
|
||||
throw new RuntimeException("Bad xml-code: " + e.toString());
|
||||
} catch (IOException f) {
|
||||
throw new RuntimeException("Could not read Xml: " + f.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param in ...
|
||||
*
|
||||
* @return ...
|
||||
*
|
||||
* @throws RuntimeException ...
|
||||
*/
|
||||
public static Document parse(InputSource in) throws RuntimeException {
|
||||
DocumentBuilder d = getDocumentBuilder();
|
||||
|
||||
try {
|
||||
Document doc = d.parse(in);
|
||||
|
||||
doc.normalize();
|
||||
|
||||
return doc;
|
||||
} catch (SAXException e) {
|
||||
throw new RuntimeException("Bad xml-code: " + e.toString());
|
||||
} catch (IOException f) {
|
||||
throw new RuntimeException("Could not read Xml: " + f.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get first "real" element (ie not the document-rootelement, but the next one
|
||||
*/
|
||||
public static Element getFirstElement(Document document) {
|
||||
Element workelement = null;
|
||||
|
||||
if (document.getDocumentElement() != null) {
|
||||
org.w3c.dom.Node tmp = document.getDocumentElement().getFirstChild();
|
||||
|
||||
while (tmp != null) {
|
||||
tmp = tmp.getNextSibling();
|
||||
|
||||
if (tmp.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE) {
|
||||
workelement = (Element) tmp;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return workelement;
|
||||
}
|
||||
|
||||
/**
|
||||
* return the text content of an element
|
||||
*/
|
||||
public static String getTextContent(org.w3c.dom.Node element) {
|
||||
StringBuffer childtext = new StringBuffer();
|
||||
NodeList childlist = element.getChildNodes();
|
||||
int ct = childlist.getLength();
|
||||
|
||||
for (int j = 0; j < ct; j++) {
|
||||
org.w3c.dom.Node childNode = childlist.item(j);
|
||||
|
||||
if ((childNode.getNodeType() == Node.TEXT_NODE) ||
|
||||
(childNode.getNodeType() == Node.CDATA_SECTION_NODE)) {
|
||||
childtext.append(childNode.getNodeValue().trim());
|
||||
}
|
||||
}
|
||||
|
||||
return childtext.toString();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,30 @@
|
|||
/*
|
||||
* 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.dom;
|
||||
|
||||
|
||||
// import java.util.Set;
|
||||
import helma.objectmodel.*;
|
||||
import helma.objectmodel.INode;
|
||||
import helma.objectmodel.IProperty;
|
||||
import helma.objectmodel.TransientNode;
|
||||
import helma.objectmodel.db.DbMapping;
|
||||
import helma.objectmodel.db.Node;
|
||||
import helma.util.HtmlEncoder;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
|
@ -12,385 +37,498 @@ import java.util.Date;
|
|||
import java.util.Enumeration;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Vector;
|
||||
// import java.util.Set;
|
||||
|
||||
import helma.objectmodel.*;
|
||||
import helma.objectmodel.INode;
|
||||
import helma.objectmodel.IProperty;
|
||||
import helma.objectmodel.TransientNode;
|
||||
import helma.objectmodel.db.Node;
|
||||
import helma.objectmodel.db.DbMapping;
|
||||
import helma.util.HtmlEncoder;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class XmlWriter extends OutputStreamWriter implements XmlConstants {
|
||||
private final static String LINESEPARATOR = System.getProperty("line.separator");
|
||||
private static int fileid;
|
||||
private Vector convertedNodes;
|
||||
private int maxLevels = 3;
|
||||
private String indent = " ";
|
||||
private StringBuffer prefix = new StringBuffer();
|
||||
private SimpleDateFormat format = new SimpleDateFormat(DATEFORMAT);
|
||||
private boolean dbmode = true;
|
||||
|
||||
private final static String LINESEPARATOR = System.getProperty("line.separator");
|
||||
// Only add encoding to XML declaration if it was explicitly set, not when we're using
|
||||
// the platform's standard encoding.
|
||||
private String explicitEncoding;
|
||||
|
||||
private Vector convertedNodes;
|
||||
private int maxLevels = 3;
|
||||
/**
|
||||
* empty constructor, will use System.out as outputstream.
|
||||
*/
|
||||
public XmlWriter() {
|
||||
super(System.out);
|
||||
}
|
||||
|
||||
private String indent = " ";
|
||||
private StringBuffer prefix = new StringBuffer();
|
||||
/**
|
||||
* Creates a new XmlWriter object.
|
||||
*
|
||||
* @param out ...
|
||||
*/
|
||||
public XmlWriter(OutputStream out) {
|
||||
super(out);
|
||||
}
|
||||
|
||||
private static int fileid;
|
||||
private SimpleDateFormat format = new SimpleDateFormat ( DATEFORMAT );
|
||||
/**
|
||||
* Creates a new XmlWriter object.
|
||||
*
|
||||
* @param out ...
|
||||
* @param enc ...
|
||||
*
|
||||
* @throws UnsupportedEncodingException ...
|
||||
*/
|
||||
public XmlWriter(OutputStream out, String enc) throws UnsupportedEncodingException {
|
||||
super(out, enc);
|
||||
explicitEncoding = enc;
|
||||
}
|
||||
|
||||
private boolean dbmode = true;
|
||||
|
||||
// Only add encoding to XML declaration if it was explicitly set, not when we're using
|
||||
// the platform's standard encoding.
|
||||
private String explicitEncoding;
|
||||
|
||||
// Set of prototypes at which to stop writing.
|
||||
// private Set stopTypes = null;
|
||||
/**
|
||||
* Creates a new XmlWriter object.
|
||||
*
|
||||
* @param desc ...
|
||||
*
|
||||
* @throws FileNotFoundException ...
|
||||
*/
|
||||
public XmlWriter(String desc) throws FileNotFoundException {
|
||||
super(new FileOutputStream(desc));
|
||||
}
|
||||
|
||||
/**
|
||||
* create ids that can be used for temporary files.
|
||||
*/
|
||||
public static int generateID() {
|
||||
return fileid++;
|
||||
}
|
||||
/**
|
||||
* Creates a new XmlWriter object.
|
||||
*
|
||||
* @param desc ...
|
||||
* @param enc ...
|
||||
*
|
||||
* @throws FileNotFoundException ...
|
||||
* @throws UnsupportedEncodingException ...
|
||||
*/
|
||||
public XmlWriter(String desc, String enc)
|
||||
throws FileNotFoundException, UnsupportedEncodingException {
|
||||
super(new FileOutputStream(desc), enc);
|
||||
explicitEncoding = enc;
|
||||
}
|
||||
|
||||
/**
|
||||
* empty constructor, will use System.out as outputstream.
|
||||
*/
|
||||
public XmlWriter () {
|
||||
super(System.out);
|
||||
}
|
||||
/**
|
||||
* Creates a new XmlWriter object.
|
||||
*
|
||||
* @param file ...
|
||||
*
|
||||
* @throws FileNotFoundException ...
|
||||
*/
|
||||
public XmlWriter(File file) throws FileNotFoundException {
|
||||
super(new FileOutputStream(file));
|
||||
}
|
||||
|
||||
public XmlWriter (OutputStream out) {
|
||||
super(out);
|
||||
}
|
||||
/**
|
||||
* Creates a new XmlWriter object.
|
||||
*
|
||||
* @param file ...
|
||||
* @param enc ...
|
||||
*
|
||||
* @throws FileNotFoundException ...
|
||||
* @throws UnsupportedEncodingException ...
|
||||
*/
|
||||
public XmlWriter(File file, String enc)
|
||||
throws FileNotFoundException, UnsupportedEncodingException {
|
||||
super(new FileOutputStream(file), enc);
|
||||
explicitEncoding = enc;
|
||||
}
|
||||
|
||||
public XmlWriter (OutputStream out, String enc) throws UnsupportedEncodingException {
|
||||
super(out, enc);
|
||||
explicitEncoding = enc;
|
||||
}
|
||||
// Set of prototypes at which to stop writing.
|
||||
// private Set stopTypes = null;
|
||||
|
||||
public XmlWriter (String desc) throws FileNotFoundException {
|
||||
super (new FileOutputStream (desc));
|
||||
}
|
||||
/**
|
||||
* create ids that can be used for temporary files.
|
||||
*/
|
||||
public static int generateID() {
|
||||
return fileid++;
|
||||
}
|
||||
|
||||
public XmlWriter (String desc, String enc) throws FileNotFoundException, UnsupportedEncodingException {
|
||||
super (new FileOutputStream (desc), enc);
|
||||
explicitEncoding = enc;
|
||||
}
|
||||
/**
|
||||
* by default writing only descends 50 levels into the node tree to prevent
|
||||
* infite loops. number can be changed here.
|
||||
*/
|
||||
public void setMaxLevels(int levels) {
|
||||
maxLevels = levels;
|
||||
}
|
||||
|
||||
public XmlWriter (File file) throws FileNotFoundException {
|
||||
super (new FileOutputStream (file));
|
||||
}
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param dbmode ...
|
||||
*/
|
||||
public void setDatabaseMode(boolean dbmode) {
|
||||
this.dbmode = dbmode;
|
||||
}
|
||||
|
||||
public XmlWriter (File file, String enc) throws FileNotFoundException, UnsupportedEncodingException {
|
||||
super (new FileOutputStream (file), enc);
|
||||
explicitEncoding = enc;
|
||||
}
|
||||
/**
|
||||
* Set a group of prototypes at which to stop XML serialization.
|
||||
*/
|
||||
|
||||
/**
|
||||
* by default writing only descends 50 levels into the node tree to prevent
|
||||
* infite loops. number can be changed here.
|
||||
*/
|
||||
public void setMaxLevels (int levels) {
|
||||
maxLevels = levels;
|
||||
}
|
||||
/* public void setStopTypes (Set set) {
|
||||
this.stopTypes = set;
|
||||
} */
|
||||
|
||||
public void setDatabaseMode (boolean dbmode) {
|
||||
this.dbmode = dbmode;
|
||||
}
|
||||
/**
|
||||
* set the number of space chars
|
||||
*/
|
||||
public void setIndent(int ct) {
|
||||
StringBuffer tmp = new StringBuffer();
|
||||
|
||||
/**
|
||||
* Set a group of prototypes at which to stop XML serialization.
|
||||
*/
|
||||
/* public void setStopTypes (Set set) {
|
||||
this.stopTypes = set;
|
||||
} */
|
||||
for (int i = 0; i < ct; i++) {
|
||||
tmp.append(" ");
|
||||
}
|
||||
|
||||
/**
|
||||
* set the number of space chars
|
||||
*/
|
||||
public void setIndent (int ct) {
|
||||
StringBuffer tmp = new StringBuffer ();
|
||||
for ( int i=0; i<ct; i++ ) {
|
||||
tmp.append(" ");
|
||||
}
|
||||
indent = tmp.toString();
|
||||
}
|
||||
indent = tmp.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* starting point for printing a node tree.
|
||||
* creates document header too and initializes
|
||||
* the cache of already converted nodes.
|
||||
*/
|
||||
public boolean write( INode node ) throws IOException {
|
||||
convertedNodes = new Vector();
|
||||
if (explicitEncoding == null)
|
||||
writeln ("<?xml version=\"1.0\"?>");
|
||||
else
|
||||
writeln ("<?xml version=\"1.0\" encoding=\""+explicitEncoding+"\"?>");
|
||||
// writeln ("<!-- printed by helma object publisher -->");
|
||||
// writeln ("<!-- created " + (new Date()).toString() + " -->" );
|
||||
write ("<xmlroot xmlns:hop=\"");
|
||||
write (NAMESPACE);
|
||||
writeln ("\">");
|
||||
write (node, null, null, 0);
|
||||
writeln ("</xmlroot>");
|
||||
convertedNodes = null;
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* starting point for printing a node tree.
|
||||
* creates document header too and initializes
|
||||
* the cache of already converted nodes.
|
||||
*/
|
||||
public boolean write(INode node) throws IOException {
|
||||
convertedNodes = new Vector();
|
||||
|
||||
/**
|
||||
* write a hopobject and print all its properties and children.
|
||||
* references are made here if a node already has been fully printed
|
||||
* or if this is the last level that's going to be dumped
|
||||
*/
|
||||
public void write (INode node, String elementName, String propName, int level) throws IOException {
|
||||
if (node==null)
|
||||
return;
|
||||
// if (stopTypes != null && stopTypes.contains (node.getPrototype()))
|
||||
// return;
|
||||
int previousLength = prefix.length();
|
||||
prefix.append(indent);
|
||||
if ( ++level>maxLevels ) {
|
||||
writeReferenceTag (node, elementName, propName);
|
||||
prefix.setLength( previousLength );
|
||||
return;
|
||||
}
|
||||
if ( convertedNodes.contains(node) ) {
|
||||
writeReferenceTag (node, elementName, propName);
|
||||
} else {
|
||||
convertedNodes.addElement (node);
|
||||
writeTagOpen (node, elementName, propName);
|
||||
INode parent = node.getParent ();
|
||||
if ( parent!=null ) {
|
||||
writeReferenceTag (parent, "hop:parent", null);
|
||||
}
|
||||
writeProperties (node, level);
|
||||
writeChildren (node, level);
|
||||
writeTagClose (elementName);
|
||||
}
|
||||
prefix.setLength( previousLength );
|
||||
}
|
||||
if (explicitEncoding == null) {
|
||||
writeln("<?xml version=\"1.0\"?>");
|
||||
} else {
|
||||
writeln("<?xml version=\"1.0\" encoding=\"" + explicitEncoding + "\"?>");
|
||||
}
|
||||
|
||||
// writeln ("<!-- printed by helma object publisher -->");
|
||||
// writeln ("<!-- created " + (new Date()).toString() + " -->" );
|
||||
write("<xmlroot xmlns:hop=\"");
|
||||
write(NAMESPACE);
|
||||
writeln("\">");
|
||||
write(node, null, null, 0);
|
||||
writeln("</xmlroot>");
|
||||
convertedNodes = null;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* loop through properties and print them with their property-name
|
||||
* as elementname
|
||||
*/
|
||||
private void writeProperties (INode node, int level) throws IOException {
|
||||
Enumeration e = null;
|
||||
if ( dbmode==true && node instanceof helma.objectmodel.db.Node ) {
|
||||
// a newly constructed db.Node doesn't have a propMap,
|
||||
// but returns an enumeration of all it's db-mapped properties
|
||||
Hashtable props = ((Node)node).getPropMap();
|
||||
if (props==null)
|
||||
return;
|
||||
e = props.keys();
|
||||
} else {
|
||||
e = node.properties();
|
||||
}
|
||||
while ( e.hasMoreElements() ) {
|
||||
String key = (String)e.nextElement();
|
||||
IProperty prop = node.get(key);
|
||||
if ( prop!=null ) {
|
||||
boolean validName = isValidElementName (key);
|
||||
String elementName, propName;
|
||||
if (validName) {
|
||||
elementName = key;
|
||||
propName = null;
|
||||
} else {
|
||||
elementName = "property";
|
||||
propName = key;
|
||||
}
|
||||
int type = prop.getType();
|
||||
if( type==IProperty.NODE ) {
|
||||
write (prop.getNodeValue(), elementName, propName, level);
|
||||
} else {
|
||||
writeProperty (prop, elementName, propName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* write a hopobject and print all its properties and children.
|
||||
* references are made here if a node already has been fully printed
|
||||
* or if this is the last level that's going to be dumped
|
||||
*/
|
||||
public void write(INode node, String elementName, String propName, int level)
|
||||
throws IOException {
|
||||
if (node == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* public void writeNullProperty (String key) throws IOException {
|
||||
write (prefix.toString());
|
||||
write (indent);
|
||||
write ("<");
|
||||
write (key);
|
||||
write (" type=\"null\"/>");
|
||||
write (LINESEPARATOR);
|
||||
} */
|
||||
// if (stopTypes != null && stopTypes.contains (node.getPrototype()))
|
||||
// return;
|
||||
int previousLength = prefix.length();
|
||||
|
||||
/**
|
||||
* write a single property, set attribute type according to type,
|
||||
* apply xml-encoding.
|
||||
*/
|
||||
public void writeProperty (IProperty property, String elementName, String propName) throws IOException {
|
||||
int propType = property.getType();
|
||||
// we can't encode java objects in XML
|
||||
if (propType == IProperty.JAVAOBJECT)
|
||||
return;
|
||||
write (prefix.toString());
|
||||
write (indent);
|
||||
write ("<");
|
||||
write (elementName);
|
||||
if (propName != null) {
|
||||
write (" propertyname=\"");
|
||||
write (HtmlEncoder.encodeXml (propName));
|
||||
write ("\"");
|
||||
}
|
||||
switch (propType) {
|
||||
case IProperty.BOOLEAN:
|
||||
write (" type=\"boolean\">");
|
||||
write (property.getStringValue());
|
||||
break;
|
||||
case IProperty.FLOAT:
|
||||
write (" type=\"float\">");
|
||||
write (property.getStringValue());
|
||||
break;
|
||||
case IProperty.INTEGER:
|
||||
write (" type=\"integer\">");
|
||||
write (property.getStringValue());
|
||||
break;
|
||||
case IProperty.DATE:
|
||||
write (" type=\"date\">");
|
||||
write ( format.format (property.getDateValue()) );
|
||||
break;
|
||||
case IProperty.STRING:
|
||||
write (">");
|
||||
String str = HtmlEncoder.encodeXml (property.getStringValue());
|
||||
if (str != null)
|
||||
write ( str );
|
||||
}
|
||||
write ("</");
|
||||
write (elementName);
|
||||
write (">");
|
||||
write (LINESEPARATOR);
|
||||
}
|
||||
prefix.append(indent);
|
||||
|
||||
/**
|
||||
* loop through the children-array and print them as <hop:child>
|
||||
*/
|
||||
private void writeChildren (INode node, int level) throws IOException {
|
||||
if ( dbmode==true && node instanceof helma.objectmodel.db.Node ) {
|
||||
Node dbNode = (Node)node;
|
||||
DbMapping smap = dbNode.getDbMapping() == null ? null : dbNode.getDbMapping().getSubnodeMapping ();
|
||||
if (smap != null && smap.isRelational ())
|
||||
return;
|
||||
}
|
||||
Enumeration e = node.getSubnodes();
|
||||
while (e.hasMoreElements()) {
|
||||
INode nextNode = (INode)e.nextElement();
|
||||
write (nextNode, "hop:child", null, level);
|
||||
}
|
||||
}
|
||||
if (++level > maxLevels) {
|
||||
writeReferenceTag(node, elementName, propName);
|
||||
prefix.setLength(previousLength);
|
||||
|
||||
/**
|
||||
* write an opening tag for a node. Include id and prototype, use a
|
||||
* name if parameter is non-empty.
|
||||
*/
|
||||
public void writeTagOpen (INode node, String name, String propName) throws IOException {
|
||||
write (prefix.toString());
|
||||
write ("<");
|
||||
write ( (name==null)?"hopobject" : name);
|
||||
write (" id=\"");
|
||||
write (getNodeIdentifier(node));
|
||||
if (propName != null) {
|
||||
write ("\" propertyname=\"");
|
||||
write (HtmlEncoder.encodeXml (propName));
|
||||
}
|
||||
write ("\" name=\"");
|
||||
write (node.getName());
|
||||
write ("\" prototype=\"");
|
||||
write (getNodePrototype(node));
|
||||
write ("\" created=\"");
|
||||
write (Long.toString(node.created()));
|
||||
write ("\" lastModified=\"");
|
||||
write (Long.toString(node.lastModified()));
|
||||
//FIXME: do we need anonymous-property?
|
||||
write ("\">");
|
||||
write (LINESEPARATOR);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* write a closing tag for a node
|
||||
* e.g. </root>
|
||||
*/
|
||||
public void writeTagClose (String name) throws IOException {
|
||||
write (prefix.toString());
|
||||
write ("</");
|
||||
write ( (name==null)?"hopobject" : name);
|
||||
write (">");
|
||||
write (LINESEPARATOR);
|
||||
}
|
||||
if (convertedNodes.contains(node)) {
|
||||
writeReferenceTag(node, elementName, propName);
|
||||
} else {
|
||||
convertedNodes.addElement(node);
|
||||
writeTagOpen(node, elementName, propName);
|
||||
|
||||
/**
|
||||
* write a tag holding a reference to an element that has
|
||||
* been written out before.
|
||||
* e.g. <parent idref="35" prototyperef="hopobject"/>
|
||||
*/
|
||||
public void writeReferenceTag (INode node, String name, String propName) throws IOException {
|
||||
write (prefix.toString());
|
||||
write ("<");
|
||||
write ( (name==null)?"hopobject" : name);
|
||||
write ( " idref=\"");
|
||||
write (getNodeIdentifier(node));
|
||||
if (propName != null) {
|
||||
write ("\" propertyname=\"");
|
||||
write (HtmlEncoder.encodeXml (propName));
|
||||
}
|
||||
write ("\" prototyperef=\"");
|
||||
write (getNodePrototype(node));
|
||||
write ("\"/>");
|
||||
write (LINESEPARATOR);
|
||||
}
|
||||
INode parent = node.getParent();
|
||||
|
||||
/**
|
||||
* retrieve prototype-string of a node, defaults to "hopobject"
|
||||
*/
|
||||
private String getNodePrototype( INode node ) {
|
||||
if ( node.getPrototype()==null || "".equals(node.getPrototype()) ) {
|
||||
return "hopobject";
|
||||
} else {
|
||||
return node.getPrototype();
|
||||
}
|
||||
}
|
||||
if (parent != null) {
|
||||
writeReferenceTag(parent, "hop:parent", null);
|
||||
}
|
||||
|
||||
/**
|
||||
* TransientNode produces a different ID each time we call the getID()-method
|
||||
* this is a workaround and uses hashCode if INode stands for a TransientNode.
|
||||
*/
|
||||
private String getNodeIdentifier( INode node ) {
|
||||
try {
|
||||
TransientNode tmp = (TransientNode)node;
|
||||
return Integer.toString( tmp.hashCode() );
|
||||
} catch ( ClassCastException e ) {
|
||||
return node.getID();
|
||||
}
|
||||
}
|
||||
writeProperties(node, level);
|
||||
writeChildren(node, level);
|
||||
writeTagClose(elementName);
|
||||
}
|
||||
|
||||
public void writeln(String str) throws IOException {
|
||||
write (str);
|
||||
write (LINESEPARATOR);
|
||||
}
|
||||
prefix.setLength(previousLength);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if a string is usable as XML element name. If not, the name
|
||||
* will be appended as attribute to the XML element. We are
|
||||
* conservative here, preferring to return false rather too often than
|
||||
* not enough.
|
||||
*/
|
||||
private boolean isValidElementName (String str) {
|
||||
char c = str.charAt (0);
|
||||
if (!Character.isLetter(c))
|
||||
return false;
|
||||
int l = str.length();
|
||||
for (int i=1; i<l; i++) {
|
||||
c = str.charAt (i);
|
||||
if (!Character.isLetterOrDigit(c) && c != '-' && c != '_')
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* loop through properties and print them with their property-name
|
||||
* as elementname
|
||||
*/
|
||||
private void writeProperties(INode node, int level)
|
||||
throws IOException {
|
||||
Enumeration e = null;
|
||||
|
||||
if ((dbmode == true) && node instanceof helma.objectmodel.db.Node) {
|
||||
// a newly constructed db.Node doesn't have a propMap,
|
||||
// but returns an enumeration of all it's db-mapped properties
|
||||
Hashtable props = ((Node) node).getPropMap();
|
||||
|
||||
if (props == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
e = props.keys();
|
||||
} else {
|
||||
e = node.properties();
|
||||
}
|
||||
|
||||
while (e.hasMoreElements()) {
|
||||
String key = (String) e.nextElement();
|
||||
IProperty prop = node.get(key);
|
||||
|
||||
if (prop != null) {
|
||||
boolean validName = isValidElementName(key);
|
||||
String elementName;
|
||||
String propName;
|
||||
|
||||
if (validName) {
|
||||
elementName = key;
|
||||
propName = null;
|
||||
} else {
|
||||
elementName = "property";
|
||||
propName = key;
|
||||
}
|
||||
|
||||
int type = prop.getType();
|
||||
|
||||
if (type == IProperty.NODE) {
|
||||
write(prop.getNodeValue(), elementName, propName, level);
|
||||
} else {
|
||||
writeProperty(prop, elementName, propName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* public void writeNullProperty (String key) throws IOException {
|
||||
write (prefix.toString());
|
||||
write (indent);
|
||||
write ("<");
|
||||
write (key);
|
||||
write (" type=\"null\"/>");
|
||||
write (LINESEPARATOR);
|
||||
} */
|
||||
|
||||
/**
|
||||
* write a single property, set attribute type according to type,
|
||||
* apply xml-encoding.
|
||||
*/
|
||||
public void writeProperty(IProperty property, String elementName, String propName)
|
||||
throws IOException {
|
||||
int propType = property.getType();
|
||||
|
||||
// we can't encode java objects in XML
|
||||
if (propType == IProperty.JAVAOBJECT) {
|
||||
return;
|
||||
}
|
||||
|
||||
write(prefix.toString());
|
||||
write(indent);
|
||||
write("<");
|
||||
write(elementName);
|
||||
|
||||
if (propName != null) {
|
||||
write(" propertyname=\"");
|
||||
write(HtmlEncoder.encodeXml(propName));
|
||||
write("\"");
|
||||
}
|
||||
|
||||
switch (propType) {
|
||||
case IProperty.BOOLEAN:
|
||||
write(" type=\"boolean\">");
|
||||
write(property.getStringValue());
|
||||
|
||||
break;
|
||||
|
||||
case IProperty.FLOAT:
|
||||
write(" type=\"float\">");
|
||||
write(property.getStringValue());
|
||||
|
||||
break;
|
||||
|
||||
case IProperty.INTEGER:
|
||||
write(" type=\"integer\">");
|
||||
write(property.getStringValue());
|
||||
|
||||
break;
|
||||
|
||||
case IProperty.DATE:
|
||||
write(" type=\"date\">");
|
||||
write(format.format(property.getDateValue()));
|
||||
|
||||
break;
|
||||
|
||||
case IProperty.STRING:
|
||||
write(">");
|
||||
|
||||
String str = HtmlEncoder.encodeXml(property.getStringValue());
|
||||
|
||||
if (str != null) {
|
||||
write(str);
|
||||
}
|
||||
}
|
||||
|
||||
write("</");
|
||||
write(elementName);
|
||||
write(">");
|
||||
write(LINESEPARATOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* loop through the children-array and print them as <hop:child>
|
||||
*/
|
||||
private void writeChildren(INode node, int level) throws IOException {
|
||||
if ((dbmode == true) && node instanceof helma.objectmodel.db.Node) {
|
||||
Node dbNode = (Node) node;
|
||||
DbMapping smap = (dbNode.getDbMapping() == null) ? null
|
||||
: dbNode.getDbMapping()
|
||||
.getSubnodeMapping();
|
||||
|
||||
if ((smap != null) && smap.isRelational()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Enumeration e = node.getSubnodes();
|
||||
|
||||
while (e.hasMoreElements()) {
|
||||
INode nextNode = (INode) e.nextElement();
|
||||
|
||||
write(nextNode, "hop:child", null, level);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* write an opening tag for a node. Include id and prototype, use a
|
||||
* name if parameter is non-empty.
|
||||
*/
|
||||
public void writeTagOpen(INode node, String name, String propName)
|
||||
throws IOException {
|
||||
write(prefix.toString());
|
||||
write("<");
|
||||
write((name == null) ? "hopobject" : name);
|
||||
write(" id=\"");
|
||||
write(getNodeIdentifier(node));
|
||||
|
||||
if (propName != null) {
|
||||
write("\" propertyname=\"");
|
||||
write(HtmlEncoder.encodeXml(propName));
|
||||
}
|
||||
|
||||
write("\" name=\"");
|
||||
write(node.getName());
|
||||
write("\" prototype=\"");
|
||||
write(getNodePrototype(node));
|
||||
write("\" created=\"");
|
||||
write(Long.toString(node.created()));
|
||||
write("\" lastModified=\"");
|
||||
write(Long.toString(node.lastModified()));
|
||||
|
||||
//FIXME: do we need anonymous-property?
|
||||
write("\">");
|
||||
write(LINESEPARATOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* write a closing tag for a node
|
||||
* e.g. </root>
|
||||
*/
|
||||
public void writeTagClose(String name) throws IOException {
|
||||
write(prefix.toString());
|
||||
write("</");
|
||||
write((name == null) ? "hopobject" : name);
|
||||
write(">");
|
||||
write(LINESEPARATOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* write a tag holding a reference to an element that has
|
||||
* been written out before.
|
||||
* e.g. <parent idref="35" prototyperef="hopobject"/>
|
||||
*/
|
||||
public void writeReferenceTag(INode node, String name, String propName)
|
||||
throws IOException {
|
||||
write(prefix.toString());
|
||||
write("<");
|
||||
write((name == null) ? "hopobject" : name);
|
||||
write(" idref=\"");
|
||||
write(getNodeIdentifier(node));
|
||||
|
||||
if (propName != null) {
|
||||
write("\" propertyname=\"");
|
||||
write(HtmlEncoder.encodeXml(propName));
|
||||
}
|
||||
|
||||
write("\" prototyperef=\"");
|
||||
write(getNodePrototype(node));
|
||||
write("\"/>");
|
||||
write(LINESEPARATOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* retrieve prototype-string of a node, defaults to "hopobject"
|
||||
*/
|
||||
private String getNodePrototype(INode node) {
|
||||
if ((node.getPrototype() == null) || "".equals(node.getPrototype())) {
|
||||
return "hopobject";
|
||||
} else {
|
||||
return node.getPrototype();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TransientNode produces a different ID each time we call the getID()-method
|
||||
* this is a workaround and uses hashCode if INode stands for a TransientNode.
|
||||
*/
|
||||
private String getNodeIdentifier(INode node) {
|
||||
try {
|
||||
TransientNode tmp = (TransientNode) node;
|
||||
|
||||
return Integer.toString(tmp.hashCode());
|
||||
} catch (ClassCastException e) {
|
||||
return node.getID();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param str ...
|
||||
*
|
||||
* @throws IOException ...
|
||||
*/
|
||||
public void writeln(String str) throws IOException {
|
||||
write(str);
|
||||
write(LINESEPARATOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a string is usable as XML element name. If not, the name
|
||||
* will be appended as attribute to the XML element. We are
|
||||
* conservative here, preferring to return false rather too often than
|
||||
* not enough.
|
||||
*/
|
||||
private boolean isValidElementName(String str) {
|
||||
char c = str.charAt(0);
|
||||
|
||||
if (!Character.isLetter(c)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int l = str.length();
|
||||
|
||||
for (int i = 1; i < l; i++) {
|
||||
c = str.charAt(i);
|
||||
|
||||
if (!Character.isLetterOrDigit(c) && (c != '-') && (c != '_')) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,15 +1,27 @@
|
|||
// ActionFile.java
|
||||
// Copyright (c) Helma.org 1998-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.scripting;
|
||||
|
||||
import java.util.Vector;
|
||||
import java.util.Iterator;
|
||||
import java.io.*;
|
||||
import helma.framework.*;
|
||||
import helma.framework.core.*;
|
||||
import helma.util.Updatable;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.Iterator;
|
||||
import java.util.Vector;
|
||||
|
||||
/**
|
||||
* An ActionFile is a file containing function code that is exposed as a URI
|
||||
|
@ -17,114 +29,178 @@ import helma.util.Updatable;
|
|||
* usually represented by a file with extension .hac (hop action file)
|
||||
* that contains the raw body of the function.
|
||||
*/
|
||||
|
||||
|
||||
public class ActionFile implements Updatable {
|
||||
|
||||
String name, sourceName;
|
||||
String name;
|
||||
String sourceName;
|
||||
Prototype prototype;
|
||||
Application app;
|
||||
File file;
|
||||
String content;
|
||||
long lastmod;
|
||||
|
||||
|
||||
public ActionFile (File file, String name, Prototype proto) {
|
||||
this.prototype = proto;
|
||||
this.app = proto.getApplication ();
|
||||
this.name = name;
|
||||
this.sourceName = file.getParentFile().getName()+"/"+file.getName();
|
||||
this.file = file;
|
||||
this.lastmod = file.lastModified ();
|
||||
this.content = null;
|
||||
/**
|
||||
* Creates a new ActionFile object.
|
||||
*
|
||||
* @param file ...
|
||||
* @param name ...
|
||||
* @param proto ...
|
||||
*/
|
||||
public ActionFile(File file, String name, Prototype proto) {
|
||||
this.prototype = proto;
|
||||
this.app = proto.getApplication();
|
||||
this.name = name;
|
||||
this.sourceName = file.getParentFile().getName() + "/" + file.getName();
|
||||
this.file = file;
|
||||
this.lastmod = file.lastModified();
|
||||
this.content = null;
|
||||
}
|
||||
|
||||
public ActionFile (String content, String name, String sourceName, Prototype proto) {
|
||||
this.prototype = proto;
|
||||
this.app = proto.getApplication ();
|
||||
this.name = name;
|
||||
this.sourceName = sourceName;
|
||||
this.file = null;
|
||||
this.content = content;
|
||||
/**
|
||||
* Creates a new ActionFile object.
|
||||
*
|
||||
* @param content ...
|
||||
* @param name ...
|
||||
* @param sourceName ...
|
||||
* @param proto ...
|
||||
*/
|
||||
public ActionFile(String content, String name, String sourceName, Prototype proto) {
|
||||
this.prototype = proto;
|
||||
this.app = proto.getApplication();
|
||||
this.name = name;
|
||||
this.sourceName = sourceName;
|
||||
this.file = null;
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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 lastmod != file.lastModified ();
|
||||
public boolean needsUpdate() {
|
||||
return lastmod != file.lastModified();
|
||||
}
|
||||
|
||||
|
||||
public void update () {
|
||||
if (!file.exists ()) {
|
||||
// remove functions declared by this from all object prototypes
|
||||
remove ();
|
||||
} else {
|
||||
lastmod = file.lastModified ();
|
||||
}
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void update() {
|
||||
if (!file.exists()) {
|
||||
// remove functions declared by this from all object prototypes
|
||||
remove();
|
||||
} else {
|
||||
lastmod = file.lastModified();
|
||||
}
|
||||
}
|
||||
|
||||
public void remove () {
|
||||
prototype.removeActionFile (this);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void remove() {
|
||||
prototype.removeActionFile(this);
|
||||
}
|
||||
|
||||
public File getFile () {
|
||||
return file;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public File getFile() {
|
||||
return file;
|
||||
}
|
||||
|
||||
public String getName () {
|
||||
return name;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getSourceName () {
|
||||
return sourceName;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getSourceName() {
|
||||
return sourceName;
|
||||
}
|
||||
|
||||
public Reader getReader () throws FileNotFoundException {
|
||||
if (content != null)
|
||||
return new StringReader (content);
|
||||
else if (file.length() == 0)
|
||||
return new StringReader(";");
|
||||
else
|
||||
return new FileReader (file);
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*
|
||||
* @throws FileNotFoundException ...
|
||||
*/
|
||||
public Reader getReader() throws FileNotFoundException {
|
||||
if (content != null) {
|
||||
return new StringReader(content);
|
||||
} else if (file.length() == 0) {
|
||||
return new StringReader(";");
|
||||
} else {
|
||||
return new FileReader(file);
|
||||
}
|
||||
}
|
||||
|
||||
public String getContent () {
|
||||
if (content != null)
|
||||
return content;
|
||||
else {
|
||||
try {
|
||||
FileReader reader = new FileReader (file);
|
||||
char cbuf[] = new char[(int) file.length ()];
|
||||
reader.read (cbuf);
|
||||
reader.close ();
|
||||
return new String (cbuf);
|
||||
} catch (Exception filex) {
|
||||
app.logEvent ("Error reading "+this+": "+filex);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getContent() {
|
||||
if (content != null) {
|
||||
return content;
|
||||
} else {
|
||||
try {
|
||||
FileReader reader = new FileReader(file);
|
||||
char[] cbuf = new char[(int) file.length()];
|
||||
|
||||
reader.read(cbuf);
|
||||
reader.close();
|
||||
|
||||
return new String(cbuf);
|
||||
} catch (Exception filex) {
|
||||
app.logEvent("Error reading " + this + ": " + filex);
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String getFunctionName () {
|
||||
return name + "_action";
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getFunctionName() {
|
||||
return name + "_action";
|
||||
}
|
||||
|
||||
public Prototype getPrototype () {
|
||||
return prototype;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public Prototype getPrototype() {
|
||||
return prototype;
|
||||
}
|
||||
|
||||
public Application getApplication () {
|
||||
return app;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public Application getApplication() {
|
||||
return app;
|
||||
}
|
||||
|
||||
public String toString () {
|
||||
return "ActionFile["+sourceName+"]";
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String toString() {
|
||||
return "ActionFile[" + sourceName + "]";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,25 +1,34 @@
|
|||
// FunctionFile.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.scripting;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.HashSet;
|
||||
import java.util.Enumeration;
|
||||
import java.io.*;
|
||||
import helma.framework.*;
|
||||
import helma.framework.core.*;
|
||||
import helma.util.Updatable;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* This represents a File containing script functions for a given class/prototype.
|
||||
*/
|
||||
|
||||
|
||||
public class FunctionFile implements Updatable {
|
||||
|
||||
Prototype prototype;
|
||||
Application app;
|
||||
File file;
|
||||
|
@ -27,13 +36,18 @@ public class FunctionFile implements Updatable {
|
|||
String content;
|
||||
long lastmod;
|
||||
|
||||
|
||||
public FunctionFile (File file, Prototype proto) {
|
||||
this.prototype = proto;
|
||||
this.app = proto.getApplication ();
|
||||
this.sourceName = file.getParentFile().getName()+"/"+file.getName();
|
||||
this.file = file;
|
||||
update ();
|
||||
/**
|
||||
* Creates a new FunctionFile object.
|
||||
*
|
||||
* @param file ...
|
||||
* @param proto ...
|
||||
*/
|
||||
public FunctionFile(File file, Prototype proto) {
|
||||
this.prototype = proto;
|
||||
this.app = proto.getApplication();
|
||||
this.sourceName = file.getParentFile().getName() + "/" + file.getName();
|
||||
this.file = file;
|
||||
update();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -41,55 +55,75 @@ public class FunctionFile implements Updatable {
|
|||
* files contained in zipped applications. The whole update mechanism is bypassed
|
||||
* by immediately parsing the code.
|
||||
*/
|
||||
public FunctionFile (String body, String sourceName, Prototype proto) {
|
||||
this.prototype = proto;
|
||||
this.app = proto.getApplication ();
|
||||
this.sourceName = sourceName;
|
||||
this.file = null;
|
||||
this.content = body;
|
||||
public FunctionFile(String body, String sourceName, Prototype proto) {
|
||||
this.prototype = proto;
|
||||
this.app = proto.getApplication();
|
||||
this.sourceName = sourceName;
|
||||
this.file = null;
|
||||
this.content = body;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 != null && lastmod != file.lastModified ();
|
||||
public boolean needsUpdate() {
|
||||
return (file != null) && (lastmod != file.lastModified());
|
||||
}
|
||||
|
||||
|
||||
public void update () {
|
||||
if (file != null) {
|
||||
if (!file.exists ()) {
|
||||
remove ();
|
||||
} else {
|
||||
lastmod = file.lastModified ();
|
||||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void update() {
|
||||
if (file != null) {
|
||||
if (!file.exists()) {
|
||||
remove();
|
||||
} else {
|
||||
lastmod = file.lastModified();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public File getFile () {
|
||||
return file;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public File getFile() {
|
||||
return file;
|
||||
}
|
||||
|
||||
public String getContent () {
|
||||
return content;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
public String getSourceName () {
|
||||
return sourceName;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getSourceName() {
|
||||
return sourceName;
|
||||
}
|
||||
|
||||
public void remove () {
|
||||
prototype.removeFunctionFile (this);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void remove() {
|
||||
prototype.removeFunctionFile(this);
|
||||
}
|
||||
|
||||
|
||||
public String toString () {
|
||||
return sourceName;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String toString() {
|
||||
return sourceName;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,5 +1,18 @@
|
|||
// ScriptingEngine.java
|
||||
// Copyright (c) Hannes Wallnöfer 1998-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.scripting;
|
||||
|
||||
|
@ -7,73 +20,69 @@ import helma.framework.IPathElement;
|
|||
import helma.framework.core.Application;
|
||||
import helma.framework.core.Prototype;
|
||||
import helma.framework.core.RequestEvaluator;
|
||||
import java.util.*;
|
||||
import java.io.File;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* This is the interface that must be implemented to make a scripting environment
|
||||
* usable by the Helma application server.
|
||||
*
|
||||
* Implementations of this interface must have a public zero-argument constructor
|
||||
* Implementations of this interface must have a public zero-argument constructor
|
||||
* to be usable by the Helma framework.
|
||||
*/
|
||||
public interface ScriptingEngine {
|
||||
|
||||
/**
|
||||
/**
|
||||
* Init the scripting engine with an application and a request evaluator
|
||||
*/
|
||||
public void init (Application app, RequestEvaluator reval);
|
||||
public void init(Application app, RequestEvaluator reval);
|
||||
|
||||
/**
|
||||
* This method is called before an execution context for a request
|
||||
* evaluation is entered to let the Engine know it should update
|
||||
* evaluation is entered to let the Engine know it should update
|
||||
* its prototype information
|
||||
*/
|
||||
public void updatePrototypes ();
|
||||
public void updatePrototypes();
|
||||
|
||||
/**
|
||||
* This method is called when an execution context for a request
|
||||
* evaluation is entered. The globals parameter contains the global values
|
||||
* to be applied during this execution context.
|
||||
*/
|
||||
public void enterContext (HashMap globals) throws ScriptingException;
|
||||
public void enterContext(HashMap globals) throws ScriptingException;
|
||||
|
||||
/**
|
||||
* This method is called to let the scripting engine know that the current
|
||||
* execution context has terminated.
|
||||
*/
|
||||
public void exitContext ();
|
||||
|
||||
public void exitContext();
|
||||
|
||||
/**
|
||||
* Invoke a function on some object, using the given arguments and global vars.
|
||||
* Invoke a function on some object, using the given arguments and global vars.
|
||||
* XML-RPC calls require special input and output parameter conversion.
|
||||
*/
|
||||
public Object invoke (Object thisObject, String functionName, Object[] args, boolean xmlrpc)
|
||||
throws ScriptingException;
|
||||
public Object invoke(Object thisObject, String functionName, Object[] args,
|
||||
boolean xmlrpc) throws ScriptingException;
|
||||
|
||||
/**
|
||||
* Let the evaluator know that the current evaluation has been aborted.
|
||||
*/
|
||||
public void abort ();
|
||||
public void abort();
|
||||
|
||||
/**
|
||||
* Get a property on an object
|
||||
*/
|
||||
public Object get (Object thisObject, String key);
|
||||
public Object get(Object thisObject, String key);
|
||||
|
||||
/**
|
||||
* Return true if a function by that name is defined for that object.
|
||||
*/
|
||||
public boolean hasFunction (Object thisObject, String functionName);
|
||||
public boolean hasFunction(Object thisObject, String functionName);
|
||||
|
||||
/**
|
||||
* Get an IPathElement that offers introspection services into the application.
|
||||
* If this method returns null, no introspection is available for this kind of engine.
|
||||
* In order to be compatible with the standard Helma management application, this
|
||||
* In order to be compatible with the standard Helma management application, this
|
||||
* class should be compatible with helma.doc.DocApplication.
|
||||
*/
|
||||
public IPathElement getIntrospector ();
|
||||
|
||||
public IPathElement getIntrospector();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,67 +1,105 @@
|
|||
// ScriptingException.java
|
||||
// Copyright (c) Hannes Wallnöfer 1998-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.scripting;
|
||||
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.io.PrintStream;
|
||||
import java.io.PrintWriter;
|
||||
|
||||
/**
|
||||
* The base class for exceptions thrown by Helma scripting package
|
||||
*/
|
||||
public class ScriptingException extends Exception {
|
||||
|
||||
Exception wrapped;
|
||||
|
||||
/**
|
||||
* Construct a ScriptingException given an error message
|
||||
*/
|
||||
public ScriptingException (String msg) {
|
||||
super (msg);
|
||||
wrapped = null;
|
||||
public ScriptingException(String msg) {
|
||||
super(msg);
|
||||
wrapped = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a ScriptingException given an error message
|
||||
*/
|
||||
public ScriptingException (Exception w) {
|
||||
wrapped = w;
|
||||
public ScriptingException(Exception w) {
|
||||
wrapped = w;
|
||||
}
|
||||
|
||||
public String toString () {
|
||||
if (wrapped == null)
|
||||
return super.toString ();
|
||||
else
|
||||
return wrapped.toString ();
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String toString() {
|
||||
if (wrapped == null) {
|
||||
return super.toString();
|
||||
} else {
|
||||
return wrapped.toString();
|
||||
}
|
||||
}
|
||||
|
||||
public String getMessage () {
|
||||
if (wrapped == null)
|
||||
return super.getMessage ();
|
||||
else
|
||||
return wrapped.getMessage ();
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getMessage() {
|
||||
if (wrapped == null) {
|
||||
return super.getMessage();
|
||||
} else {
|
||||
return wrapped.getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
public void printStackTrace () {
|
||||
if (wrapped == null)
|
||||
super.printStackTrace ();
|
||||
else
|
||||
wrapped.printStackTrace ();
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void printStackTrace() {
|
||||
if (wrapped == null) {
|
||||
super.printStackTrace();
|
||||
} else {
|
||||
wrapped.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void printStackTrace (PrintStream stream) {
|
||||
if (wrapped == null)
|
||||
super.printStackTrace (stream);
|
||||
else
|
||||
wrapped.printStackTrace (stream);
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param stream ...
|
||||
*/
|
||||
public void printStackTrace(PrintStream stream) {
|
||||
if (wrapped == null) {
|
||||
super.printStackTrace(stream);
|
||||
} else {
|
||||
wrapped.printStackTrace(stream);
|
||||
}
|
||||
}
|
||||
|
||||
public void printStackTrace (PrintWriter writer) {
|
||||
if (wrapped == null)
|
||||
super.printStackTrace (writer);
|
||||
else
|
||||
wrapped.printStackTrace (writer);
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param writer ...
|
||||
*/
|
||||
public void printStackTrace(PrintWriter writer) {
|
||||
if (wrapped == null) {
|
||||
super.printStackTrace(writer);
|
||||
} else {
|
||||
wrapped.printStackTrace(writer);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,187 +1,239 @@
|
|||
// Template.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.scripting;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.Vector;
|
||||
import java.util.Iterator;
|
||||
import java.util.StringTokenizer;
|
||||
import helma.framework.*;
|
||||
import helma.framework.core.*;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.Iterator;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.Vector;
|
||||
|
||||
/**
|
||||
* This represents a Helma template, i.e. a file with the extension .hsp
|
||||
* (Helma server page) that contains both parts that are to be evaluated
|
||||
* as EcmaScript and parts that are to be delivered to the client as-is.
|
||||
* Internally, templates are regular functions.
|
||||
* Internally, templates are regular functions.
|
||||
* Helma templates are callable via URL, but this is just a leftover from the
|
||||
* days when there were no .hac (action) files. The recommended way
|
||||
* now is to have a .hac file with all the logic which in turn calls one or more
|
||||
* template files to do the formatting.
|
||||
*/
|
||||
|
||||
public class Template extends ActionFile {
|
||||
|
||||
|
||||
public Template (File file, String name, Prototype proto) {
|
||||
super (file, name, proto);
|
||||
/**
|
||||
* Creates a new Template object.
|
||||
*
|
||||
* @param file ...
|
||||
* @param name ...
|
||||
* @param proto ...
|
||||
*/
|
||||
public Template(File file, String name, Prototype proto) {
|
||||
super(file, name, proto);
|
||||
}
|
||||
|
||||
public Template (String content, String name, String sourceName, Prototype proto) {
|
||||
super (content, name, sourceName, proto);
|
||||
/**
|
||||
* Creates a new Template object.
|
||||
*
|
||||
* @param content ...
|
||||
* @param name ...
|
||||
* @param sourceName ...
|
||||
* @param proto ...
|
||||
*/
|
||||
public Template(String content, String name, String sourceName, Prototype proto) {
|
||||
super(content, name, sourceName, proto);
|
||||
}
|
||||
|
||||
public String getFunctionName () {
|
||||
return name;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getFunctionName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public Reader getReader () {
|
||||
return new StringReader(getContent());
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public Reader getReader() {
|
||||
return new StringReader(getContent());
|
||||
}
|
||||
|
||||
public String getContent () {
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getContent() {
|
||||
Vector partBuffer = new Vector();
|
||||
String cstring = super.getContent();
|
||||
char[] cnt = cstring.toCharArray();
|
||||
int l = cnt.length;
|
||||
|
||||
Vector partBuffer = new Vector ();
|
||||
String cstring = super.getContent();
|
||||
char[] cnt = cstring.toCharArray ();
|
||||
int l = cnt.length;
|
||||
if (l == 0)
|
||||
return "";
|
||||
if (l == 0) {
|
||||
return "";
|
||||
}
|
||||
|
||||
// if last charackter is whitespace, swallow it. this is necessary for some inner templates to look ok.
|
||||
if (Character.isWhitespace (cnt[l-1]))
|
||||
l -= 1;
|
||||
// if last charackter is whitespace, swallow it. this is necessary for some inner templates to look ok.
|
||||
if (Character.isWhitespace(cnt[l - 1])) {
|
||||
l -= 1;
|
||||
}
|
||||
|
||||
int lastIdx = 0;
|
||||
for (int i = 0; i < l-1; i++) {
|
||||
if (cnt[i] == '<' && cnt[i+1] == '%') {
|
||||
int j = i+2;
|
||||
while (j < l-1 && (cnt[j] != '%' || cnt[j+1] != '>')) {
|
||||
j++;
|
||||
}
|
||||
if (j > i+2) {
|
||||
if (i - lastIdx > 0)
|
||||
partBuffer.addElement (new Part (this, new String (cnt, lastIdx, i - lastIdx), true));
|
||||
String script = new String (cnt, i+2, (j-i)-2);
|
||||
partBuffer.addElement (new Part (this, script, false));
|
||||
lastIdx = j+2;
|
||||
}
|
||||
i = j+1;
|
||||
}
|
||||
}
|
||||
if (lastIdx < l)
|
||||
partBuffer.addElement (new Part (this, new String (cnt, lastIdx, l - lastIdx), true));
|
||||
int lastIdx = 0;
|
||||
|
||||
StringBuffer templateBody = new StringBuffer ();
|
||||
int nparts = partBuffer.size();
|
||||
for (int i = 0; i < (l - 1); i++) {
|
||||
if ((cnt[i] == '<') && (cnt[i + 1] == '%')) {
|
||||
int j = i + 2;
|
||||
|
||||
for (int k = 0; k < nparts; k++) {
|
||||
Part nextPart = (Part) partBuffer.elementAt (k);
|
||||
while ((j < (l - 1)) && ((cnt[j] != '%') || (cnt[j + 1] != '>'))) {
|
||||
j++;
|
||||
}
|
||||
|
||||
if (nextPart.isStatic || nextPart.content.trim ().startsWith ("=")) {
|
||||
// check for <%= ... %> statements
|
||||
if (!nextPart.isStatic) {
|
||||
nextPart.content = nextPart.content.trim ().substring (1).trim ();
|
||||
// cut trailing ";"
|
||||
while (nextPart.content.endsWith (";"))
|
||||
nextPart.content = nextPart.content.substring (0, nextPart.content.length()-1);
|
||||
}
|
||||
if (j > (i + 2)) {
|
||||
if ((i - lastIdx) > 0) {
|
||||
partBuffer.addElement(new Part(this,
|
||||
new String(cnt, lastIdx,
|
||||
i - lastIdx), true));
|
||||
}
|
||||
|
||||
StringTokenizer st = new StringTokenizer (nextPart.content, "\r\n", true);
|
||||
String nextLine = st.hasMoreTokens () ? st.nextToken () : null;
|
||||
String script = new String(cnt, i + 2, (j - i) - 2);
|
||||
|
||||
// count newLines we "swallow", see explanation below
|
||||
int newLineCount = 0;
|
||||
partBuffer.addElement(new Part(this, script, false));
|
||||
lastIdx = j + 2;
|
||||
}
|
||||
|
||||
templateBody.append ("res.write (");
|
||||
if (nextPart.isStatic) {
|
||||
templateBody.append ("\"");
|
||||
}
|
||||
i = j + 1;
|
||||
}
|
||||
}
|
||||
|
||||
while (nextLine != null) {
|
||||
if (lastIdx < l) {
|
||||
partBuffer.addElement(new Part(this, new String(cnt, lastIdx, l - lastIdx),
|
||||
true));
|
||||
}
|
||||
|
||||
if ("\n".equals (nextLine)) {
|
||||
// append a CRLF
|
||||
newLineCount++;
|
||||
templateBody.append ("\\r\\n");
|
||||
} else if (!"\r".equals (nextLine)) try {
|
||||
StringReader lineReader = new StringReader (nextLine);
|
||||
int c = lineReader.read ();
|
||||
while (c > -1) {
|
||||
if (nextPart.isStatic && ((char)c == '"' || (char)c == '\\')) {
|
||||
templateBody.append ('\\');
|
||||
}
|
||||
templateBody.append ((char) c);
|
||||
c = lineReader.read ();
|
||||
}
|
||||
} catch (IOException srx) {}
|
||||
StringBuffer templateBody = new StringBuffer();
|
||||
int nparts = partBuffer.size();
|
||||
|
||||
nextLine = st.hasMoreTokens () ? st.nextToken () : null;
|
||||
for (int k = 0; k < nparts; k++) {
|
||||
Part nextPart = (Part) partBuffer.elementAt(k);
|
||||
|
||||
}
|
||||
if (nextPart.isStatic || nextPart.content.trim().startsWith("=")) {
|
||||
// check for <%= ... %> statements
|
||||
if (!nextPart.isStatic) {
|
||||
nextPart.content = nextPart.content.trim().substring(1).trim();
|
||||
|
||||
if (nextPart.isStatic) {
|
||||
templateBody.append ("\"");
|
||||
}
|
||||
// cut trailing ";"
|
||||
while (nextPart.content.endsWith(";"))
|
||||
nextPart.content = nextPart.content.substring(0,
|
||||
nextPart.content.length() -
|
||||
1);
|
||||
}
|
||||
|
||||
templateBody.append ("); ");
|
||||
StringTokenizer st = new StringTokenizer(nextPart.content, "\r\n", true);
|
||||
String nextLine = st.hasMoreTokens() ? st.nextToken() : null;
|
||||
|
||||
// append the number of lines we have "swallowed" into
|
||||
// one write statement, so error messages will *approximately*
|
||||
// give correct line numbers.
|
||||
for (int i=0; i<newLineCount; i++) {
|
||||
templateBody.append ("\r\n");
|
||||
}
|
||||
// count newLines we "swallow", see explanation below
|
||||
int newLineCount = 0;
|
||||
|
||||
} else {
|
||||
templateBody.append (nextPart.content);
|
||||
if (!nextPart.content.trim ().endsWith (";")) {
|
||||
templateBody.append (";");
|
||||
}
|
||||
}
|
||||
}
|
||||
// templateBody.append ("\r\nreturn null;\r\n");
|
||||
templateBody.append("res.write (");
|
||||
|
||||
return templateBody.toString ();
|
||||
if (nextPart.isStatic) {
|
||||
templateBody.append("\"");
|
||||
}
|
||||
|
||||
while (nextLine != null) {
|
||||
if ("\n".equals(nextLine)) {
|
||||
// append a CRLF
|
||||
newLineCount++;
|
||||
templateBody.append("\\r\\n");
|
||||
} else if (!"\r".equals(nextLine)) {
|
||||
try {
|
||||
StringReader lineReader = new StringReader(nextLine);
|
||||
int c = lineReader.read();
|
||||
|
||||
while (c > -1) {
|
||||
if (nextPart.isStatic &&
|
||||
(((char) c == '"') || ((char) c == '\\'))) {
|
||||
templateBody.append('\\');
|
||||
}
|
||||
|
||||
templateBody.append((char) c);
|
||||
c = lineReader.read();
|
||||
}
|
||||
} catch (IOException srx) {
|
||||
}
|
||||
}
|
||||
|
||||
nextLine = st.hasMoreTokens() ? st.nextToken() : null;
|
||||
}
|
||||
|
||||
if (nextPart.isStatic) {
|
||||
templateBody.append("\"");
|
||||
}
|
||||
|
||||
templateBody.append("); ");
|
||||
|
||||
// append the number of lines we have "swallowed" into
|
||||
// one write statement, so error messages will *approximately*
|
||||
// give correct line numbers.
|
||||
for (int i = 0; i < newLineCount; i++) {
|
||||
templateBody.append("\r\n");
|
||||
}
|
||||
} else {
|
||||
templateBody.append(nextPart.content);
|
||||
|
||||
if (!nextPart.content.trim().endsWith(";")) {
|
||||
templateBody.append(";");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// templateBody.append ("\r\nreturn null;\r\n");
|
||||
return templateBody.toString();
|
||||
}
|
||||
|
||||
public void remove () {
|
||||
prototype.removeTemplate (this);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void remove() {
|
||||
prototype.removeTemplate(this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
class Part {
|
||||
String content;
|
||||
Template parent;
|
||||
boolean isPart;
|
||||
boolean isStatic;
|
||||
|
||||
String content;
|
||||
Template parent;
|
||||
boolean isPart;
|
||||
boolean isStatic;
|
||||
public Part(Template parent, String content, boolean isStatic) {
|
||||
isPart = false;
|
||||
this.parent = parent;
|
||||
this.content = content;
|
||||
this.isStatic = isStatic;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return isStatic ? null : content;
|
||||
}
|
||||
|
||||
public Part (Template parent, String content, boolean isStatic) {
|
||||
isPart = false;
|
||||
this.parent = parent;
|
||||
this.content = content;
|
||||
this.isStatic = isStatic;
|
||||
}
|
||||
|
||||
public String getName () {
|
||||
return isStatic ? null : content;
|
||||
}
|
||||
|
||||
|
||||
public String toString () {
|
||||
return "Template.Part ["+content+","+isStatic+"]";
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "Template.Part [" + content + "," + isStatic + "]";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,65 +1,98 @@
|
|||
/*
|
||||
* 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.scripting.fesi;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import helma.framework.core.ApplicationBean;
|
||||
import helma.objectmodel.INode;
|
||||
import helma.util.SystemProperties;
|
||||
|
||||
import FESI.Interpreter.Evaluator;
|
||||
import FESI.Exceptions.EcmaScriptException;
|
||||
import FESI.Data.ESNull;
|
||||
import FESI.Data.ESValue;
|
||||
import FESI.Data.ESWrapper;
|
||||
import FESI.Exceptions.EcmaScriptException;
|
||||
import FESI.Interpreter.Evaluator;
|
||||
import helma.framework.core.ApplicationBean;
|
||||
import helma.objectmodel.INode;
|
||||
import helma.util.SystemProperties;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Wrap a Java Bean for use in EcmaScript.
|
||||
*/
|
||||
|
||||
public class ESBeanWrapper extends ESWrapper {
|
||||
|
||||
FesiEngine engine;
|
||||
|
||||
public ESBeanWrapper (Object object, FesiEngine engine) {
|
||||
super (object, engine.getEvaluator(),true);
|
||||
this.engine = engine;
|
||||
/**
|
||||
* Creates a new ESBeanWrapper object.
|
||||
*
|
||||
* @param object ...
|
||||
* @param engine ...
|
||||
*/
|
||||
public ESBeanWrapper(Object object, FesiEngine engine) {
|
||||
super(object, engine.getEvaluator(), true);
|
||||
this.engine = engine;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap getProperty, return ESNode if INode would be returned,
|
||||
* ESMapWrapper if Map would be returned.
|
||||
*/
|
||||
public ESValue getProperty(String propertyName, int hash) throws EcmaScriptException {
|
||||
try {
|
||||
ESValue val = super.getProperty (propertyName, hash);
|
||||
if (val instanceof ESWrapper) {
|
||||
Object theObject = ((ESWrapper)val).getJavaObject ();
|
||||
if (val instanceof ESWrapper && theObject instanceof INode) {
|
||||
return engine.getNodeWrapper ((INode) theObject);
|
||||
} else if (val instanceof ESWrapper && theObject instanceof Map) {
|
||||
ESMapWrapper wrapper = new ESMapWrapper(engine, (Map) theObject);
|
||||
if (theObject instanceof SystemProperties && super.getJavaObject () instanceof ApplicationBean)
|
||||
wrapper.setReadonly(true);
|
||||
return wrapper;
|
||||
/**
|
||||
* Wrap getProperty, return ESNode if INode would be returned,
|
||||
* ESMapWrapper if Map would be returned.
|
||||
*/
|
||||
public ESValue getProperty(String propertyName, int hash)
|
||||
throws EcmaScriptException {
|
||||
try {
|
||||
ESValue val = super.getProperty(propertyName, hash);
|
||||
|
||||
if (val instanceof ESWrapper) {
|
||||
Object theObject = ((ESWrapper) val).getJavaObject();
|
||||
|
||||
if (val instanceof ESWrapper && theObject instanceof INode) {
|
||||
return engine.getNodeWrapper((INode) theObject);
|
||||
} else if (val instanceof ESWrapper && theObject instanceof Map) {
|
||||
ESMapWrapper wrapper = new ESMapWrapper(engine, (Map) theObject);
|
||||
|
||||
if (theObject instanceof SystemProperties &&
|
||||
super.getJavaObject() instanceof ApplicationBean) {
|
||||
wrapper.setReadonly(true);
|
||||
}
|
||||
|
||||
return wrapper;
|
||||
}
|
||||
}
|
||||
}
|
||||
return val;
|
||||
} catch (Exception rte) {
|
||||
return ESNull.theNull;
|
||||
}
|
||||
}
|
||||
|
||||
public void putProperty(String propertyName, ESValue propertyValue, int hash) throws EcmaScriptException {
|
||||
try {
|
||||
super.putProperty (propertyName, propertyValue, hash);
|
||||
} catch (Exception rte) {
|
||||
// create a nice error message
|
||||
throw new EcmaScriptException("can't set property " + propertyName +
|
||||
" to this value on " + getJavaObject().toString() );
|
||||
}
|
||||
return val;
|
||||
} catch (Exception rte) {
|
||||
return ESNull.theNull;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param propertyName ...
|
||||
* @param propertyValue ...
|
||||
* @param hash ...
|
||||
*
|
||||
* @throws EcmaScriptException ...
|
||||
*/
|
||||
public void putProperty(String propertyName, ESValue propertyValue, int hash)
|
||||
throws EcmaScriptException {
|
||||
try {
|
||||
super.putProperty(propertyName, propertyValue, hash);
|
||||
} catch (Exception rte) {
|
||||
// create a nice error message
|
||||
throw new EcmaScriptException("can't set property " + propertyName +
|
||||
" to this value on " +
|
||||
getJavaObject().toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,109 +1,236 @@
|
|||
// ESGenericObject.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.scripting.fesi;
|
||||
|
||||
import helma.framework.core.*;
|
||||
import helma.framework.IPathElement;
|
||||
import FESI.Interpreter.*;
|
||||
import FESI.Exceptions.*;
|
||||
import FESI.Data.*;
|
||||
import FESI.Exceptions.*;
|
||||
import FESI.Interpreter.*;
|
||||
import helma.framework.IPathElement;
|
||||
import helma.framework.core.*;
|
||||
import java.util.*;
|
||||
|
||||
|
||||
/**
|
||||
* A wrapper for a Java object that may or may not implement the IPathElement interface.
|
||||
*/
|
||||
|
||||
* A wrapper for a Java object that may or may not implement the IPathElement interface.
|
||||
*/
|
||||
public class ESGenericObject extends ObjectPrototype {
|
||||
|
||||
ESWrapper wrapper;
|
||||
Object wrappedObject;
|
||||
|
||||
public ESGenericObject (ESObject prototype, Evaluator evaluator, Object obj) {
|
||||
super (prototype, evaluator);
|
||||
wrappedObject = obj;
|
||||
wrapper = new ESWrapper (obj, evaluator);
|
||||
}
|
||||
|
||||
|
||||
public String getESClassName () {
|
||||
return "GenericObject";
|
||||
}
|
||||
|
||||
public String toString () {
|
||||
return wrappedObject.toString ();
|
||||
}
|
||||
|
||||
public String toDetailString () {
|
||||
return wrapper.toDetailString ();
|
||||
}
|
||||
|
||||
|
||||
public void putProperty(String propertyName, ESValue propertyValue, int hash) throws EcmaScriptException {
|
||||
wrapper.putProperty (propertyName, propertyValue, hash);
|
||||
}
|
||||
|
||||
public boolean hasProperty(String propertyName, int hash) throws EcmaScriptException {
|
||||
return super.hasProperty (propertyName, hash) || wrapper.hasProperty (propertyName, hash);
|
||||
}
|
||||
|
||||
public boolean deleteProperty(String propertyName, int hash) throws EcmaScriptException {
|
||||
return wrapper.deleteProperty (propertyName, hash);
|
||||
}
|
||||
|
||||
public ESValue getProperty (int i) throws EcmaScriptException {
|
||||
return wrapper.getProperty (i);
|
||||
}
|
||||
|
||||
public void putProperty(int index, ESValue propertyValue) throws EcmaScriptException {
|
||||
wrapper.putProperty (index, propertyValue);
|
||||
}
|
||||
|
||||
|
||||
public ESValue getProperty(String propertyName, int hash) throws EcmaScriptException {
|
||||
ESValue val = super.getProperty (propertyName, hash);
|
||||
if (val == null || val == ESUndefined.theUndefined)
|
||||
val = wrapper.getProperty (propertyName, hash);
|
||||
return val;
|
||||
}
|
||||
|
||||
public ESValue doIndirectCall(Evaluator evaluator, ESObject thisObject, String functionName, ESValue[] arguments)
|
||||
throws EcmaScriptException, NoSuchMethodException {
|
||||
if (super.hasProperty (functionName, functionName.hashCode()))
|
||||
return super.doIndirectCall (evaluator, thisObject, functionName, arguments);
|
||||
return wrapper.doIndirectCall (evaluator, thisObject, functionName, arguments);
|
||||
}
|
||||
|
||||
public Enumeration getAllProperties () {
|
||||
return wrapper.getProperties ();
|
||||
}
|
||||
|
||||
public Enumeration getProperties () {
|
||||
return wrapper.getProperties ();
|
||||
}
|
||||
|
||||
public Object toJavaObject () {
|
||||
return wrappedObject;
|
||||
/**
|
||||
* Creates a new ESGenericObject object.
|
||||
*
|
||||
* @param prototype ...
|
||||
* @param evaluator ...
|
||||
* @param obj ...
|
||||
*/
|
||||
public ESGenericObject(ESObject prototype, Evaluator evaluator, Object obj) {
|
||||
super(prototype, evaluator);
|
||||
wrappedObject = obj;
|
||||
wrapper = new ESWrapper(obj, evaluator);
|
||||
}
|
||||
|
||||
/**
|
||||
* An ESNode equals another object if it is an ESNode that wraps the same INode
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String getESClassName() {
|
||||
return "GenericObject";
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String toString() {
|
||||
return wrappedObject.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String toDetailString() {
|
||||
return wrapper.toDetailString();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param propertyName ...
|
||||
* @param propertyValue ...
|
||||
* @param hash ...
|
||||
*
|
||||
* @throws EcmaScriptException ...
|
||||
*/
|
||||
public void putProperty(String propertyName, ESValue propertyValue, int hash)
|
||||
throws EcmaScriptException {
|
||||
wrapper.putProperty(propertyName, propertyValue, hash);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param propertyName ...
|
||||
* @param hash ...
|
||||
*
|
||||
* @return ...
|
||||
*
|
||||
* @throws EcmaScriptException ...
|
||||
*/
|
||||
public boolean hasProperty(String propertyName, int hash)
|
||||
throws EcmaScriptException {
|
||||
return super.hasProperty(propertyName, hash) ||
|
||||
wrapper.hasProperty(propertyName, hash);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param propertyName ...
|
||||
* @param hash ...
|
||||
*
|
||||
* @return ...
|
||||
*
|
||||
* @throws EcmaScriptException ...
|
||||
*/
|
||||
public boolean deleteProperty(String propertyName, int hash)
|
||||
throws EcmaScriptException {
|
||||
return wrapper.deleteProperty(propertyName, hash);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param i ...
|
||||
*
|
||||
* @return ...
|
||||
*
|
||||
* @throws EcmaScriptException ...
|
||||
*/
|
||||
public ESValue getProperty(int i) throws EcmaScriptException {
|
||||
return wrapper.getProperty(i);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param index ...
|
||||
* @param propertyValue ...
|
||||
*
|
||||
* @throws EcmaScriptException ...
|
||||
*/
|
||||
public void putProperty(int index, ESValue propertyValue)
|
||||
throws EcmaScriptException {
|
||||
wrapper.putProperty(index, propertyValue);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param propertyName ...
|
||||
* @param hash ...
|
||||
*
|
||||
* @return ...
|
||||
*
|
||||
* @throws EcmaScriptException ...
|
||||
*/
|
||||
public ESValue getProperty(String propertyName, int hash)
|
||||
throws EcmaScriptException {
|
||||
ESValue val = super.getProperty(propertyName, hash);
|
||||
|
||||
if ((val == null) || (val == ESUndefined.theUndefined)) {
|
||||
val = wrapper.getProperty(propertyName, hash);
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param evaluator ...
|
||||
* @param thisObject ...
|
||||
* @param functionName ...
|
||||
* @param arguments ...
|
||||
*
|
||||
* @return ...
|
||||
*
|
||||
* @throws EcmaScriptException ...
|
||||
* @throws NoSuchMethodException ...
|
||||
*/
|
||||
public ESValue doIndirectCall(Evaluator evaluator, ESObject thisObject,
|
||||
String functionName, ESValue[] arguments)
|
||||
throws EcmaScriptException, NoSuchMethodException {
|
||||
if (super.hasProperty(functionName, functionName.hashCode())) {
|
||||
return super.doIndirectCall(evaluator, thisObject, functionName, arguments);
|
||||
}
|
||||
|
||||
return wrapper.doIndirectCall(evaluator, thisObject, functionName, arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public Enumeration getAllProperties() {
|
||||
return wrapper.getProperties();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public Enumeration getProperties() {
|
||||
return wrapper.getProperties();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public Object toJavaObject() {
|
||||
return wrappedObject;
|
||||
}
|
||||
|
||||
/**
|
||||
* An ESNode equals another object if it is an ESNode that wraps the same INode
|
||||
* or the wrapped INode itself. FIXME: doesen't check dbmapping/type!
|
||||
*/
|
||||
public boolean equals (Object what) {
|
||||
if (what == null)
|
||||
public boolean equals(Object what) {
|
||||
if (what == null) {
|
||||
return false;
|
||||
if (what == this)
|
||||
}
|
||||
|
||||
if (what == this) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (what instanceof ESGenericObject) {
|
||||
ESGenericObject other = (ESGenericObject) what;
|
||||
return (wrappedObject.equals (other.wrappedObject));
|
||||
|
||||
return (wrappedObject.equals(other.wrappedObject));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,171 +1,189 @@
|
|||
// ESMapWrapper.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.scripting.fesi;
|
||||
|
||||
import helma.framework.core.*;
|
||||
import helma.objectmodel.INode;
|
||||
import FESI.Data.*;
|
||||
import FESI.Exceptions.*;
|
||||
import FESI.Interpreter.Evaluator;
|
||||
import helma.framework.core.*;
|
||||
import helma.objectmodel.INode;
|
||||
import java.util.*;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* An EcmaScript object that makes stuff in a hashtable accessible as its properties
|
||||
*/
|
||||
|
||||
* An EcmaScript object that makes stuff in a hashtable accessible as its properties
|
||||
*/
|
||||
public class ESMapWrapper extends ESWrapper {
|
||||
|
||||
private Map data;
|
||||
private FesiEngine engine;
|
||||
private boolean readonly = false;
|
||||
|
||||
public ESMapWrapper (FesiEngine engine) {
|
||||
super (new Object(), engine.getEvaluator ());
|
||||
this.engine = engine;
|
||||
/**
|
||||
* Creates a new ESMapWrapper object.
|
||||
*
|
||||
* @param engine ...
|
||||
*/
|
||||
public ESMapWrapper(FesiEngine engine) {
|
||||
super(new Object(), engine.getEvaluator());
|
||||
this.engine = engine;
|
||||
}
|
||||
|
||||
public ESMapWrapper (FesiEngine engine, Map data) {
|
||||
super (new Object(), engine.getEvaluator ());
|
||||
this.engine = engine;
|
||||
this.data = data;
|
||||
/**
|
||||
* Creates a new ESMapWrapper object.
|
||||
*
|
||||
* @param engine ...
|
||||
* @param data ...
|
||||
*/
|
||||
public ESMapWrapper(FesiEngine engine, Map data) {
|
||||
super(new Object(), engine.getEvaluator());
|
||||
this.engine = engine;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public void setReadonly (boolean readonly) {
|
||||
this.readonly = readonly;
|
||||
}
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param readonly ...
|
||||
*/
|
||||
public void setReadonly(boolean readonly) {
|
||||
this.readonly = readonly;
|
||||
}
|
||||
|
||||
public void setData (Map data) {
|
||||
this.data = data;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param data ...
|
||||
*/
|
||||
public void setData(Map data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overridden to make the object read-only
|
||||
*/
|
||||
public void putProperty(String propertyName, ESValue propertyValue, int hash) throws EcmaScriptException {
|
||||
if (data == null)
|
||||
data = new HashMap ();
|
||||
if (propertyValue == ESNull.theNull)
|
||||
deleteProperty(propertyName, hash);
|
||||
else if (readonly==false)
|
||||
data.put (propertyName, propertyValue.toJavaObject ());
|
||||
else
|
||||
throw new EcmaScriptException ("object is readonly");
|
||||
}
|
||||
|
||||
public boolean deleteProperty(String propertyName, int hash) throws EcmaScriptException {
|
||||
if (readonly==false) {
|
||||
data.remove (propertyName);
|
||||
return true;
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
public ESValue getProperty(String propertyName, int hash) throws EcmaScriptException {
|
||||
if (data == null)
|
||||
return ESNull.theNull;
|
||||
public void putProperty(String propertyName, ESValue propertyValue, int hash)
|
||||
throws EcmaScriptException {
|
||||
if (data == null) {
|
||||
data = new HashMap();
|
||||
}
|
||||
|
||||
Object val = data.get (propertyName);
|
||||
|
||||
if (val == null)
|
||||
return ESNull.theNull;
|
||||
|
||||
if (val instanceof String)
|
||||
return new ESString ((String) val);
|
||||
else if (val instanceof INode)
|
||||
return engine.getNodeWrapper ((INode) val);
|
||||
else if (val instanceof Map)
|
||||
return new ESMapWrapper (engine, (Map)val);
|
||||
else if (val instanceof ESValue)
|
||||
return (ESValue) val;
|
||||
return ESLoader.normalizeValue(val, evaluator);
|
||||
if (propertyValue == ESNull.theNull) {
|
||||
deleteProperty(propertyName, hash);
|
||||
} else if (readonly == false) {
|
||||
data.put(propertyName, propertyValue.toJavaObject());
|
||||
} else {
|
||||
throw new EcmaScriptException("object is readonly");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param propertyName ...
|
||||
* @param hash ...
|
||||
*
|
||||
* @return ...
|
||||
*
|
||||
* @throws EcmaScriptException ...
|
||||
*/
|
||||
public boolean deleteProperty(String propertyName, int hash)
|
||||
throws EcmaScriptException {
|
||||
if (readonly == false) {
|
||||
data.remove(propertyName);
|
||||
|
||||
public Enumeration getAllProperties () {
|
||||
return getProperties ();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public Enumeration getProperties () {
|
||||
Object[] keys = data == null ? null : data.keySet().toArray ();
|
||||
return new Enum (keys);
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param propertyName ...
|
||||
* @param hash ...
|
||||
*
|
||||
* @return ...
|
||||
*
|
||||
* @throws EcmaScriptException ...
|
||||
*/
|
||||
public ESValue getProperty(String propertyName, int hash)
|
||||
throws EcmaScriptException {
|
||||
if (data == null) {
|
||||
return ESNull.theNull;
|
||||
}
|
||||
|
||||
Object val = data.get(propertyName);
|
||||
|
||||
if (val == null) {
|
||||
return ESNull.theNull;
|
||||
}
|
||||
|
||||
if (val instanceof String) {
|
||||
return new ESString((String) val);
|
||||
} else if (val instanceof INode) {
|
||||
return engine.getNodeWrapper((INode) val);
|
||||
} else if (val instanceof Map) {
|
||||
return new ESMapWrapper(engine, (Map) val);
|
||||
} else if (val instanceof ESValue) {
|
||||
return (ESValue) val;
|
||||
}
|
||||
|
||||
return ESLoader.normalizeValue(val, evaluator);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public Enumeration getAllProperties() {
|
||||
return getProperties();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public Enumeration getProperties() {
|
||||
Object[] keys = (data == null) ? null : data.keySet().toArray();
|
||||
|
||||
return new Enum(keys);
|
||||
}
|
||||
|
||||
class Enum implements Enumeration {
|
||||
|
||||
Object[] elements;
|
||||
int pos;
|
||||
|
||||
Enum (Object[] elements) {
|
||||
this.elements = elements;
|
||||
pos = 0;
|
||||
}
|
||||
|
||||
public boolean hasMoreElements () {
|
||||
return elements != null && pos < elements.length;
|
||||
}
|
||||
|
||||
public Object nextElement () {
|
||||
if (elements == null || pos >= elements.length)
|
||||
throw new NoSuchElementException ();
|
||||
return elements[pos++];
|
||||
}
|
||||
Object[] elements;
|
||||
int pos;
|
||||
|
||||
Enum(Object[] elements) {
|
||||
this.elements = elements;
|
||||
pos = 0;
|
||||
}
|
||||
|
||||
public boolean hasMoreElements() {
|
||||
return (elements != null) && (pos < elements.length);
|
||||
}
|
||||
|
||||
public Object nextElement() {
|
||||
if ((elements == null) || (pos >= elements.length)) {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
|
||||
return elements[pos++];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,88 +1,121 @@
|
|||
// ActionFile.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.scripting.fesi;
|
||||
|
||||
import helma.scripting.*;
|
||||
import java.util.Vector;
|
||||
import java.util.Iterator;
|
||||
import java.io.*;
|
||||
import helma.framework.*;
|
||||
import helma.framework.core.*;
|
||||
import helma.util.Updatable;
|
||||
import FESI.Data.*;
|
||||
import FESI.Parser.*;
|
||||
import FESI.AST.ASTFormalParameterList;
|
||||
import FESI.AST.ASTStatementList;
|
||||
import FESI.AST.EcmaScriptTreeConstants;
|
||||
import FESI.Interpreter.*;
|
||||
import FESI.Data.*;
|
||||
import FESI.Exceptions.*;
|
||||
|
||||
|
||||
import FESI.Interpreter.*;
|
||||
import FESI.Parser.*;
|
||||
import helma.framework.*;
|
||||
import helma.framework.core.*;
|
||||
import helma.scripting.*;
|
||||
import helma.util.Updatable;
|
||||
import java.io.*;
|
||||
import java.util.Iterator;
|
||||
import java.util.Vector;
|
||||
|
||||
/**
|
||||
* An class that updates fesi interpreters with actionfiles and templates.
|
||||
*/
|
||||
|
||||
|
||||
public class FesiActionAdapter {
|
||||
|
||||
Prototype prototype;
|
||||
Application app;
|
||||
String functionName;
|
||||
String sourceName;
|
||||
|
||||
// this is the parsed function which can be easily applied to FesiEngine objects
|
||||
TypeUpdater pfunc, pfuncAsString;
|
||||
TypeUpdater pfunc;
|
||||
|
||||
public FesiActionAdapter (ActionFile action) {
|
||||
prototype = action.getPrototype ();
|
||||
app = action.getApplication ();
|
||||
Reader reader = null;
|
||||
functionName = action.getFunctionName ();
|
||||
sourceName = action.getSourceName ();
|
||||
try {
|
||||
reader = action.getReader ();
|
||||
pfunc = parseFunction (functionName,
|
||||
"arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10",
|
||||
reader,
|
||||
sourceName);
|
||||
} catch (Throwable x) {
|
||||
String message = x.getMessage ();
|
||||
pfunc = new ErrorFeedback (functionName, message);
|
||||
} finally {
|
||||
try {
|
||||
reader.close();
|
||||
} catch (Exception ignore) {}
|
||||
}
|
||||
// check if this is a template and we need to generate an "_as_string" variant
|
||||
if (action instanceof Template) {
|
||||
String content = "res.pushStringBuffer(); " +
|
||||
action.getContent () +
|
||||
"\r\nreturn res.popStringBuffer();\r\n";
|
||||
try {
|
||||
pfuncAsString = parseFunction (functionName+"_as_string",
|
||||
"arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10",
|
||||
new StringReader(content),
|
||||
sourceName);
|
||||
} catch (Throwable x) {
|
||||
String message = x.getMessage ();
|
||||
pfunc = new ErrorFeedback (functionName+"_as_string", message);
|
||||
}
|
||||
} else {
|
||||
pfuncAsString = null;
|
||||
}
|
||||
// this is the parsed function which can be easily applied to FesiEngine objects
|
||||
TypeUpdater pfuncAsString;
|
||||
|
||||
/**
|
||||
* Creates a new FesiActionAdapter object.
|
||||
*
|
||||
* @param action ...
|
||||
*/
|
||||
public FesiActionAdapter(ActionFile action) {
|
||||
prototype = action.getPrototype();
|
||||
app = action.getApplication();
|
||||
|
||||
Reader reader = null;
|
||||
|
||||
functionName = action.getFunctionName();
|
||||
sourceName = action.getSourceName();
|
||||
|
||||
try {
|
||||
reader = action.getReader();
|
||||
pfunc = parseFunction(functionName,
|
||||
"arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10",
|
||||
reader, sourceName);
|
||||
} catch (Throwable x) {
|
||||
String message = x.getMessage();
|
||||
|
||||
pfunc = new ErrorFeedback(functionName, message);
|
||||
} finally {
|
||||
try {
|
||||
reader.close();
|
||||
} catch (Exception ignore) {
|
||||
}
|
||||
}
|
||||
|
||||
// check if this is a template and we need to generate an "_as_string" variant
|
||||
if (action instanceof Template) {
|
||||
String content = "res.pushStringBuffer(); " + action.getContent() +
|
||||
"\r\nreturn res.popStringBuffer();\r\n";
|
||||
|
||||
try {
|
||||
pfuncAsString = parseFunction(functionName + "_as_string",
|
||||
"arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10",
|
||||
new StringReader(content), sourceName);
|
||||
} catch (Throwable x) {
|
||||
String message = x.getMessage();
|
||||
|
||||
pfunc = new ErrorFeedback(functionName + "_as_string", message);
|
||||
}
|
||||
} else {
|
||||
pfuncAsString = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param engine ...
|
||||
*
|
||||
* @throws EcmaScriptException ...
|
||||
*/
|
||||
public synchronized void updateEvaluator(FesiEngine engine)
|
||||
throws EcmaScriptException {
|
||||
if (pfunc != null) {
|
||||
pfunc.updateEvaluator(engine);
|
||||
}
|
||||
|
||||
public synchronized void updateEvaluator (FesiEngine engine) throws EcmaScriptException {
|
||||
if (pfunc != null)
|
||||
pfunc.updateEvaluator (engine);
|
||||
if (pfuncAsString != null)
|
||||
pfuncAsString.updateEvaluator (engine);
|
||||
if (pfuncAsString != null) {
|
||||
pfuncAsString.updateEvaluator(engine);
|
||||
}
|
||||
}
|
||||
|
||||
protected TypeUpdater parseFunction (String funcName, String params, Reader body, String sourceName) throws EcmaScriptException {
|
||||
|
||||
protected TypeUpdater parseFunction(String funcName, String params, Reader body,
|
||||
String sourceName)
|
||||
throws EcmaScriptException {
|
||||
// ESObject fp = app.eval.evaluator.getFunctionPrototype();
|
||||
// ConstructedFunctionObject function = null;
|
||||
ASTFormalParameterList fpl = null;
|
||||
|
@ -90,116 +123,138 @@ public class FesiActionAdapter {
|
|||
FunctionEvaluationSource fes = null;
|
||||
|
||||
/* if (body == null || "".equals (body.trim()))
|
||||
body = ";\r\n";
|
||||
else
|
||||
body = body + "\r\n"; */
|
||||
if (params == null) params = "";
|
||||
else params = params.trim ();
|
||||
body = ";\r\n";
|
||||
else
|
||||
body = body + "\r\n"; */
|
||||
if (params == null) {
|
||||
params = "";
|
||||
} else {
|
||||
params = params.trim();
|
||||
}
|
||||
|
||||
EcmaScript parser;
|
||||
StringReader is;
|
||||
|
||||
// Special case for empty parameters
|
||||
if (params.length()==0) {
|
||||
if (params.length() == 0) {
|
||||
fpl = new ASTFormalParameterList(EcmaScriptTreeConstants.JJTFORMALPARAMETERLIST);
|
||||
} else {
|
||||
is = new java.io.StringReader(params);
|
||||
parser = new EcmaScript(is);
|
||||
|
||||
try {
|
||||
fpl = (ASTFormalParameterList) parser.FormalParameterList();
|
||||
is.close();
|
||||
} catch (ParseException x) {
|
||||
throw new EcmaScriptParseException (x, new FileEvaluationSource(sourceName, null));
|
||||
throw new EcmaScriptParseException(x,
|
||||
new FileEvaluationSource(sourceName,
|
||||
null));
|
||||
}
|
||||
}
|
||||
|
||||
// this is very very very strange: without the toString, lots of obscure exceptions
|
||||
// deep inside the parser...
|
||||
// is = new java.io.StringReader(body.toString ());
|
||||
try {
|
||||
parser = new EcmaScript (body);
|
||||
parser = new EcmaScript(body);
|
||||
sl = (ASTStatementList) parser.StatementList();
|
||||
body.close();
|
||||
} catch (ParseException x) {
|
||||
app.logEvent ("Error parsing file "+app.getName()+":"+sourceName+": "+x);
|
||||
throw new EcmaScriptParseException (x, new FileEvaluationSource(sourceName, null));
|
||||
app.logEvent("Error parsing file " + app.getName() + ":" + sourceName + ": " +
|
||||
x);
|
||||
throw new EcmaScriptParseException(x,
|
||||
new FileEvaluationSource(sourceName, null));
|
||||
} catch (Exception x) {
|
||||
app.logEvent ("Error parsing file "+app.getName()+":"+sourceName+": "+x);
|
||||
throw new RuntimeException (x.getMessage ());
|
||||
app.logEvent("Error parsing file " + app.getName() + ":" + sourceName + ": " +
|
||||
x);
|
||||
throw new RuntimeException(x.getMessage());
|
||||
}
|
||||
|
||||
fes = new FunctionEvaluationSource (new FileEvaluationSource(sourceName, null), funcName);
|
||||
return new ParsedFunction (fpl, sl, fes, null, funcName);
|
||||
fes = new FunctionEvaluationSource(new FileEvaluationSource(sourceName, null),
|
||||
funcName);
|
||||
|
||||
return new ParsedFunction(fpl, sl, fes, null, funcName);
|
||||
}
|
||||
|
||||
interface TypeUpdater {
|
||||
public void updateEvaluator(FesiEngine engine)
|
||||
throws EcmaScriptException;
|
||||
}
|
||||
|
||||
class ParsedFunction implements TypeUpdater {
|
||||
|
||||
ASTFormalParameterList fpl = null;
|
||||
ASTStatementList sl = null;
|
||||
FunctionEvaluationSource fes = null;
|
||||
String fullFunctionText = null;
|
||||
String functionName;
|
||||
|
||||
public ParsedFunction (ASTFormalParameterList fpl, ASTStatementList sl, FunctionEvaluationSource fes,
|
||||
String fullFunctionText, String functionName) {
|
||||
this.fpl = fpl;
|
||||
this.sl = sl;
|
||||
this.fes = fes;
|
||||
this.fullFunctionText = fullFunctionText;
|
||||
this.functionName = functionName;
|
||||
public ParsedFunction(ASTFormalParameterList fpl, ASTStatementList sl,
|
||||
FunctionEvaluationSource fes, String fullFunctionText,
|
||||
String functionName) {
|
||||
this.fpl = fpl;
|
||||
this.sl = sl;
|
||||
this.fes = fes;
|
||||
this.fullFunctionText = fullFunctionText;
|
||||
this.functionName = functionName;
|
||||
}
|
||||
|
||||
public void updateEvaluator (FesiEngine engine) throws EcmaScriptException {
|
||||
public void updateEvaluator(FesiEngine engine)
|
||||
throws EcmaScriptException {
|
||||
ObjectPrototype op = engine.getPrototype(prototype.getName());
|
||||
|
||||
ObjectPrototype op = engine.getPrototype (prototype.getName());
|
||||
EcmaScriptVariableVisitor vdvisitor = engine.evaluator.getVarDeclarationVisitor();
|
||||
Vector vnames = vdvisitor.processVariableDeclarations(sl, fes);
|
||||
|
||||
EcmaScriptVariableVisitor vdvisitor = engine.evaluator.getVarDeclarationVisitor();
|
||||
Vector vnames = vdvisitor.processVariableDeclarations(sl, fes);
|
||||
FunctionPrototype fp = ConstructedFunctionObject.makeNewConstructedFunction(engine.evaluator,
|
||||
functionName,
|
||||
fes,
|
||||
fullFunctionText,
|
||||
fpl.getArguments(),
|
||||
vnames,
|
||||
sl);
|
||||
|
||||
FunctionPrototype fp = ConstructedFunctionObject.makeNewConstructedFunction (
|
||||
engine.evaluator, functionName, fes,
|
||||
fullFunctionText, fpl.getArguments(), vnames, sl);
|
||||
op.putHiddenProperty (functionName, fp);
|
||||
op.putHiddenProperty(functionName, fp);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class ErrorFeedback implements TypeUpdater {
|
||||
String functionName;
|
||||
String errorMessage;
|
||||
|
||||
String functionName, errorMessage;
|
||||
|
||||
public ErrorFeedback (String fname, String msg) {
|
||||
public ErrorFeedback(String fname, String msg) {
|
||||
functionName = fname;
|
||||
errorMessage = msg;
|
||||
}
|
||||
|
||||
public void updateEvaluator (FesiEngine engine) throws EcmaScriptException {
|
||||
public void updateEvaluator(FesiEngine engine)
|
||||
throws EcmaScriptException {
|
||||
ObjectPrototype op = engine.getPrototype(prototype.getName());
|
||||
|
||||
ObjectPrototype op = engine.getPrototype (prototype.getName ());
|
||||
|
||||
FunctionPrototype fp = (FunctionPrototype) engine.evaluator.getFunctionPrototype ();
|
||||
FunctionPrototype func = new ThrowException (functionName, engine.evaluator, fp, errorMessage);
|
||||
op.putHiddenProperty (functionName, func);
|
||||
FunctionPrototype fp = (FunctionPrototype) engine.evaluator.getFunctionPrototype();
|
||||
FunctionPrototype func = new ThrowException(functionName, engine.evaluator,
|
||||
fp, errorMessage);
|
||||
|
||||
op.putHiddenProperty(functionName, func);
|
||||
}
|
||||
}
|
||||
|
||||
class ThrowException extends BuiltinFunctionObject {
|
||||
String message;
|
||||
ThrowException (String name, Evaluator evaluator, FunctionPrototype fp, String message) {
|
||||
super (fp, evaluator, name, 1);
|
||||
this.message = message == null ? "No error message available" : message;
|
||||
}
|
||||
public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException {
|
||||
throw new EcmaScriptException (message);
|
||||
}
|
||||
public ESObject doConstruct (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException {
|
||||
throw new EcmaScriptException (message);
|
||||
}
|
||||
}
|
||||
|
||||
interface TypeUpdater {
|
||||
public void updateEvaluator (FesiEngine engine) throws EcmaScriptException;
|
||||
ThrowException(String name, Evaluator evaluator, FunctionPrototype fp,
|
||||
String message) {
|
||||
super(fp, evaluator, name, 1);
|
||||
this.message = (message == null) ? "No error message available" : message;
|
||||
}
|
||||
|
||||
public ESValue callFunction(ESObject thisObject, ESValue[] arguments)
|
||||
throws EcmaScriptException {
|
||||
throw new EcmaScriptException(message);
|
||||
}
|
||||
|
||||
public ESObject doConstruct(ESObject thisObject, ESValue[] arguments)
|
||||
throws EcmaScriptException {
|
||||
throw new EcmaScriptException(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -1,90 +1,164 @@
|
|||
// NodeConstructor.java
|
||||
// Copyright (c) Hannes Wallnöfer 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.scripting.fesi;
|
||||
|
||||
import helma.objectmodel.db.Node;
|
||||
import helma.framework.core.*;
|
||||
import FESI.Data.*;
|
||||
import FESI.Exceptions.*;
|
||||
import FESI.Interpreter.*;
|
||||
import helma.framework.core.*;
|
||||
import helma.objectmodel.db.Node;
|
||||
|
||||
/**
|
||||
* A constructor for user defined data types. This first constructs a node, sets its prototype
|
||||
* and invokes the scripted constructor function on it.
|
||||
*/
|
||||
|
||||
public class NodeConstructor extends BuiltinFunctionObject {
|
||||
FesiEngine engine;
|
||||
String typename;
|
||||
|
||||
FesiEngine engine;
|
||||
String typename;
|
||||
/**
|
||||
* Creates a new NodeConstructor object.
|
||||
*
|
||||
* @param name ...
|
||||
* @param fp ...
|
||||
* @param engine ...
|
||||
*/
|
||||
public NodeConstructor(String name, FunctionPrototype fp, FesiEngine engine) {
|
||||
super(fp, engine.getEvaluator(), name, 1);
|
||||
typename = name;
|
||||
this.engine = engine;
|
||||
}
|
||||
|
||||
public NodeConstructor (String name, FunctionPrototype fp, FesiEngine engine) {
|
||||
super(fp, engine.getEvaluator (), name, 1);
|
||||
typename = name;
|
||||
this.engine = engine;
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param thisObject ...
|
||||
* @param arguments ...
|
||||
*
|
||||
* @return ...
|
||||
*
|
||||
* @throws EcmaScriptException ...
|
||||
*/
|
||||
public ESValue callFunction(ESObject thisObject, ESValue[] arguments)
|
||||
throws EcmaScriptException {
|
||||
return doConstruct(thisObject, arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param thisObject ...
|
||||
* @param arguments ...
|
||||
*
|
||||
* @return ...
|
||||
*
|
||||
* @throws EcmaScriptException ...
|
||||
*/
|
||||
public ESObject doConstruct(ESObject thisObject, ESValue[] arguments)
|
||||
throws EcmaScriptException {
|
||||
ESNode node = null;
|
||||
Application app = engine.getApplication();
|
||||
|
||||
if ("Node".equals(typename) || "hopobject".equalsIgnoreCase(typename)) {
|
||||
String nodeName = null;
|
||||
|
||||
if ((arguments.length > 0) && (arguments[0] != null)) {
|
||||
nodeName = arguments[0].toString();
|
||||
}
|
||||
|
||||
Node n = new Node(nodeName, (String) null, app.getWrappedNodeManager());
|
||||
|
||||
node = new ESNode(engine.getPrototype("hopobject"), this.evaluator, n, engine);
|
||||
engine.putNodeWrapper(node.getNode(), node);
|
||||
} else {
|
||||
// Typed nodes are instantiated as helma.objectmodel.db.Node from the beginning
|
||||
// even if we don't know yet if they are going to be stored in a database. The reason
|
||||
// is that we want to be able to use the specail features like subnode relations even for
|
||||
// transient nodes.
|
||||
ObjectPrototype op = engine.getPrototype(typename);
|
||||
Node n = new Node(typename, typename, app.getWrappedNodeManager());
|
||||
|
||||
node = new ESNode(op, engine.getEvaluator(), n, engine);
|
||||
node.setPrototype(typename);
|
||||
node.getNode().setDbMapping(app.getDbMapping(typename));
|
||||
|
||||
try {
|
||||
// first try calling "constructor", if that doesn't work, try calling a function
|
||||
// with the name of the type.
|
||||
// HACK: There is an incompatibility problem here, because the property
|
||||
// constructor is defined as the constructor of the object by EcmaScript.
|
||||
if (op.getProperty("constructor", "constructor".hashCode()) instanceof ConstructedFunctionObject) {
|
||||
node.doIndirectCall(engine.getEvaluator(), node, "constructor",
|
||||
arguments);
|
||||
} else if (op.getProperty(typename, typename.hashCode()) instanceof ConstructedFunctionObject) {
|
||||
node.doIndirectCall(engine.getEvaluator(), node, typename, arguments);
|
||||
}
|
||||
} catch (Exception x) {
|
||||
throw new EcmaScriptException(x.toString());
|
||||
}
|
||||
}
|
||||
|
||||
public ESValue callFunction(ESObject thisObject, ESValue[] arguments) throws EcmaScriptException {
|
||||
return doConstruct(thisObject, arguments);
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param propertyName ...
|
||||
* @param previousScope ...
|
||||
* @param hash ...
|
||||
*
|
||||
* @return ...
|
||||
*
|
||||
* @throws EcmaScriptException ...
|
||||
*/
|
||||
public ESValue getPropertyInScope(String propertyName, ScopeChain previousScope,
|
||||
int hash) throws EcmaScriptException {
|
||||
return super.getPropertyInScope(propertyName, previousScope, hash);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param propertyName ...
|
||||
* @param hash ...
|
||||
*
|
||||
* @return ...
|
||||
*
|
||||
* @throws EcmaScriptException ...
|
||||
*/
|
||||
public ESValue getProperty(String propertyName, int hash)
|
||||
throws EcmaScriptException {
|
||||
if ("prototype".equals(propertyName)) {
|
||||
return engine.getPrototype(typename);
|
||||
}
|
||||
|
||||
public ESObject doConstruct(ESObject thisObject, ESValue[] arguments) throws EcmaScriptException {
|
||||
ESNode node = null;
|
||||
Application app = engine.getApplication ();
|
||||
if ("Node".equals (typename) || "hopobject".equalsIgnoreCase (typename)) {
|
||||
String nodeName = null;
|
||||
if (arguments.length > 0 && arguments[0] != null)
|
||||
nodeName = arguments[0].toString();
|
||||
Node n = new Node (nodeName, (String) null, app.getWrappedNodeManager ());
|
||||
node = new ESNode (engine.getPrototype ("hopobject"), this.evaluator, n, engine);
|
||||
engine.putNodeWrapper (node.getNode (), node);
|
||||
} else {
|
||||
// Typed nodes are instantiated as helma.objectmodel.db.Node from the beginning
|
||||
// even if we don't know yet if they are going to be stored in a database. The reason
|
||||
// is that we want to be able to use the specail features like subnode relations even for
|
||||
// transient nodes.
|
||||
ObjectPrototype op = engine.getPrototype (typename);
|
||||
Node n = new Node (typename, typename, app.getWrappedNodeManager ());
|
||||
node = new ESNode (op, engine.getEvaluator (), n, engine);
|
||||
node.setPrototype (typename);
|
||||
node.getNode ().setDbMapping (app.getDbMapping (typename));
|
||||
try {
|
||||
// first try calling "constructor", if that doesn't work, try calling a function
|
||||
// with the name of the type.
|
||||
// HACK: There is an incompatibility problem here, because the property
|
||||
// constructor is defined as the constructor of the object by EcmaScript.
|
||||
if (op.getProperty ("constructor",
|
||||
"constructor".hashCode())
|
||||
instanceof ConstructedFunctionObject)
|
||||
node.doIndirectCall (engine.getEvaluator(), node, "constructor", arguments);
|
||||
else if (op.getProperty (typename,
|
||||
typename.hashCode())
|
||||
instanceof ConstructedFunctionObject)
|
||||
node.doIndirectCall (engine.getEvaluator(), node, typename, arguments);
|
||||
} catch (Exception x) {
|
||||
throw new EcmaScriptException (x.toString());
|
||||
}
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
public ESValue getPropertyInScope(String propertyName, ScopeChain previousScope, int hash) throws EcmaScriptException {
|
||||
return super.getPropertyInScope (propertyName, previousScope, hash);
|
||||
}
|
||||
|
||||
public ESValue getProperty(String propertyName, int hash) throws EcmaScriptException {
|
||||
if ("prototype".equals (propertyName))
|
||||
return engine.getPrototype (typename);
|
||||
return super.getProperty(propertyName, hash);
|
||||
}
|
||||
|
||||
public String[] getSpecialPropertyNames() {
|
||||
String ns[] = {};
|
||||
return ns;
|
||||
}
|
||||
|
||||
} // class NodeConstructor
|
||||
|
||||
return super.getProperty(propertyName, hash);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
*/
|
||||
public String[] getSpecialPropertyNames() {
|
||||
String[] ns = { };
|
||||
|
||||
return ns;
|
||||
}
|
||||
}
|
||||
// class NodeConstructor
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue