Reference

This is a growing collection of Helma documentation categorized by functionality.

Application Object

app represents the Application object in Hop. By adding variables to this object it is possible to store temporary global variables, which are independent from request evaluator threads, i.e. they are shared by all threads. But be aware that they are not persistent and lost as soon as you restart the application.

errorCount

Syntax
app.errorCount

Description
Returns the number of Errors which occured due to User Requests since the application has been started.

Note: "File Not Found" Errors are not counted.

Example
res.write(app.errorCount);
8

getActiveThreads()

Syntax
app.getActiveThreads()

Description
This function returns the number of currently working Request Evaluator Threads.

If this number reaches the maximum allowed Treads Hop returns a "maximum thread count reached" error page.

Example
res.write(app.getMaxThreads());
12

getFreeThreads()

Syntax
app.getFreeThreads()

Description
This function returns the number of additional of Request Evaluator Threads, which could be created at the current moment.

This is equivalent to the number of current Threads deducted from the number of maximum THreads.

Example
res.write(app.getActiveThreads());
2

res.write(app.getMaxThreads());
12

res.write(app.getFreeThreads());
10

getMaxActiveThreads()

Syntax
app.getMaxActiveThreads()

Description
This function returns the historic maximum number of Request Evaluator Threads, which occured at some point since the application has been started.

Example
res.write(app.getMaxActiveThreads());
6

getMaxThreads()

Syntax
app.getMaxActiveThreads()

Description
This function returns the historic maximum number of Request Evaluator Threads, which occured at some point since the application has been started.

Example
res.write(app.getMaxActiveThreads());
6

requestCount

Syntax
app.requestCount

Description
Returns the number of HTTP-Requests since the application has been started.

Example
res.write(app.requestCount);
231

setMaxThreads()

Syntax
app.setMaxThreads(Number)

Description
This function enables the programmer to adjust the number of maximum allowed Request Evaluator Threads without having to restart the application.

Example
app.setMaxThreads(10);
res.write(app.getMaxThreads());
10

skinfiles

Array containing the skins of an application.

Syntax
app.skinfiles

Description
To access the actual content of a skin file in the inner loop you'd say app.skinfiles[a][b]. To access a skin file by name, you'd say something like app.skinfiles.root.test.

Example
for (var a in app.skinfiles) {
  res.write(a + "<br>");
  for (var b in app.skinfiles[a]) {
    res.write("&nbsp;&nbsp;&nbsp;&nbsp;" + b + "<br>");
  }
}

upSince

Syntax
app.upSince

Description
Returns the createtime of the Application object, i.e. the time when the application was started.

Example
res.write(app.upSince.format("dd.MMM yyyy HH:mm"));
06.Sep 2001 13:09

xmlrpcCount

Syntax
app.xmlrpcCount

Description
Returns the number of XML-RPC-Requests since the application has been started.

Example
res.write(app.xmlrpcCount);
12

Date Object

format()

Formatting a date string for custom output.

Syntax
Date.format(String)

Description
Formats the date string of a date object for custom output. The function's string parameter is used as a pattern to describe the desired format. Most common are the following pattern letters:

Symbol Meaning              Presentation   Example
------ -------              ------------   -------
y      year                 (Number)       1996
M      month in year        (Text, Number) July, 07
d      day in month         (Number)       10
h      hour in am/pm (1~12) (Number)       12
H      hour in day (0~23)   (Number)       0
m      minute in hour       (Number)       30
s      second in minute     (Number)       55
E      day in week          (Text)         Tuesday
a      am/pm marker         (Text)         PM
Please note that the output is depending on the locale settings of the Helma server. For further reference refer to the examples below or directly to the documentation of the Java SimpleDateFormat class.

Example
var d = new Date();
res.write(d.format("EEE d.M.y, HH:mm'h'"));
Thu 9.8.01, 15:15h

res.write(d.format("dd. MMM. yyyy, hh:mm:ss aa"));
09. Aug. 2001, 03:15:44 PM

res.write(d.format("hh:mm:ss,SS"));
03:15:44,609

res.write(d.format("EEEEE d MMMMM yyyy"));
Thursday 9 August 2001

res.write(d.format("EEE, d MMM yyyy HH:mm:ss z"));
Thu, 9 Aug 2001 15:15:44 CET

Direct Database Interface

The Direct Db interface allows the developer to directly access relational databases defined in the db.properties file without going through the Helma objectmodel layer.

var con = getDBConnection("db_source_name");

This returns a Connection object from the Helma connection pool that can be used as specified by the Fesi DbAccess protocol, except that it is not necessary to call the connect() and disconnect() functions.

var rows = con.executeRetrieval("select title from dummy");
while (rows.next())
  res.write(rows.getColumnItem("title")+"<br>");

FESI Extensions

FESI (pronounced like fuzzy) is a full implementation of the ECMAScript language as defined in the ECMA technical standard specification ECMA-262 (June 97 edition).

ECMAScript is largely equivalent to the JavaScript language version 1.1 or to the core part of JScript, but without the extensions specific to Netscape Navigator. Instead, FESI comes with its own extensions as listed below.

These parts of the documentation are adapted from the FESI Homepage courtesy by Jean-Marc Lugrin.

throwError()

Syntax
throwError(stringOrException)

Description
This function throws an exception, ie. the script interpreter aborts, the stringOrException parameter is converted to a string and immediately written to the response object for output.

Example
throwError("Aborting without any reason");
Runtime error Aborting without any reason
detected at line 1 of function 'main_action' in string starting with: 'function main_action (arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10) {'...

tryEval()

Syntax
tryEval(functionString, defaultValue)

Description
tryEval() evaluates the functionString parameter just like the standard ECMAScript function eval() does, but returns an object with two properties, value and error.

If the evaluation is successful, the value property contains the result of the evaluation and the error property equals to null (which tests as false).

If the evaluation results in an error, the value property has either the value of the optional defaultValue parameter (if specified) or undefined, and the error property contains an object describing the error, which is guaranteed to test as true.

The error object string representation is some description of the error. In the future more detailed error information may be available.

Example
var trial = tryEval("undefinedFunction()", -1)
if (trial.error)
   res.writeln(trial.error);
res.writeln(trial.value);

FESI.Exceptions.EcmaScriptException: Runtime error no global function named 'undefinedFunction' detected at line 1 in string: 'undefinedFunction()'
-1

FTP Client

This object represents an Ftp client object for sending and receiving files from an Ftp server. The constructor is called FtpServer and invoked as follows:

var ftp = new FtpClient("ftp.mydomain.com");

The Ftp client needs Daniel Savarese's NetComponents library in the classpath in order to work.

Functions and Properties

ascii()

Syntax
FtpObject.ascii();

Description
Set transfermodus to Ascii for transmitting text.

Example
var ftp = new FtpClient("ftp.host.dom");
ftp.login("user", "pass");
ftp.ascii();

binary()

Syntax
FtpObject.binary();

Description
Set transfer mode to binary for transmitting images and other non-text files.

Example
var ftp = new FtpClient("ftp.host.dom");
ftp.login("user", "pass");
ftp.binary();

cd()

Syntax
FtpObject.cd(Path);

Description
Change the current path on the FTP server.

Example
var ftp = new FtpClient("ftp.host.dom");
ftp.login("user", "pass");

// use absolute pathname
ftp.cd("/home/users/fred/www");

// change to parent directory
ftp.cd("..");

// use relative pathname
ftp.cd("images");

getFile()

Syntax
FtpObject.getFile(RemoteFile, LocalFile);

Description
Transfer a file from the server to the local file system.

Example
var ftp = new FtpClient("ftp.host.dom");
ftp.login("user", "pass");
ftp.getFile(".htaccess", "htaccess.txt");

getString()

Syntax
FtpObject.getString(RemoteFile);

Description
Retrieves a file from the remote server and returns it as string.

Example
var ftp = new FtpClient("ftp.host.dom");
ftp.login("user", "pass");
var str = ftp.getString("messages.txt");

lcd()

Syntax
FtpObject.lcd(LocalPath);

Description
Change the local path of the FTP client.

Example
var ftp = new FtpClient("ftp.host.dom");
ftp.login("user", "pass");

// use absolute pathname
ftp.lcd("/home/users/fred/www");

// change to parent directory
ftp.lcd("..");

// use relative pathname
ftp.lcd("images");

login()

Syntax
FtpObject.login(UserName, Password);

Description
Log in to the FTP server. The function returns true if successful, false otherwise.

Example
var ftp = new FtpClient("ftp.host.dom");
if (ftp.login("user", "pass"))
   res.write("User logged in.");
else
   res.write("Unable to log in.");

User logged in.

logout()

Syntax
FtpObject.logout();

Description
Terminate the current FTP session.

Example
var ftp = new FtpClient("ftp.host.dom");
ftp.login("user", "pass");
ftp.putFile("htaccess.txt", ".htaccess");
ftp.logout();

mkdir()

Syntax
FtpObject.mkdir(String);

Description
Creates a new directory on the server. The name of the directory is determined as the function's string parameter. Returns false when an error occured (e.g. due to access restrictions, directory already exists etc.), otherwise true.

Example
var ftp = new FtpClient("ftp.host.dom");
ftp.login("user", "pass");
if (ftp.mkdir("testdir"))
   ftp.cd("testdir")
else
   ftp.logout();

putFile()

Syntax
FtpObject.putFile(LocalFile, RemoteFile);

Description
Transfers a file from the local file system to the remote server. Returns true if the transmission was successful, otherwise false.

Example
var ftp = new FtpClient("ftp.host.dom");
ftp.login("user", "pass");
if (ftp.putFile("testfile"))
   res.write("File transfered successfully.");
else
   res.write("Transfer error.");

File transfered successfully.

putString()

Syntax
FtpObject.putString(String, RemoteFile);

Description
Transfer text from a string to a file on the remote server.

Example
var ftp = new FtpClient("ftp.host.dom");
ftp.login("user", "pass");
ftp.putString("Hello, World!", "message.txt");

Global Functions

These are the global functions that are added to the Hop interpreter in addition to the standard global functions found in a JavaScript interpreter.

authenticate()

Syntax
authenticate(UserNameString, PasswordString)

Description
This function authenticates against a standard Unix password file, which is both secure (encrypted using CRYPT) and can be managed using the htpasswd utility which is included in the Apache web server distribution.

The function just returns true or false, so you have to make sure yourself you remember the result in the user object by setting some cache flag.

The function compares the two arguments with the data in the file called "passwd", stored in the Helma installation directory. This can be overridden by a file with the same name in the application directory.

Please note that this function is currently not working under Windows because the Windows version of Apache's htpasswd can use a special type of MD5 encryption only.

Example
var login = authenticate("user", "pass");
if (login)
   res.write("Welcome back!");
else
   res.write("Oops, please try again...");

Welcome back!

countActiveUsers()

Syntax
countActiveUsers()

Description
Returns the number of currently active users.

Example
var nr = countActiveUsers();
res.write(nr);
18

createSkin()

Syntax
createSkin(String)

Description
Turns a string into a Skin object ready for rendering with renderSkin() and renderSkinAsString().

Example
var str = "Hello, <% response.body %>!";
var skin = createSkin(str);
res.body = "World";
renderSkin(skin);

Hello, World!

encode()

Preparing a string for smooth html output.

Syntax
encode(string)

Description
Encodes a string by replacing linebreaks with <br> tags and diacritical characters as well as html tags with their equivalent html entities.

Example
var str = encode("<b>Bananer växer\n minsann inte på träd.<b>");
res.write(str);
&lt;b&gt;Bananer v&auml;xer
<br> minsann inte p&aring; tr&auml;d.&lt;/b&gt;

encodeForm()

Syntax
encodeForm(String)

Description
Similar to encode() this functions substitutes html entities but leaves newlines untouched. This is what you usually want to do for encoding form content (esp. with textarea values).

Example
var str = encodeForm("<b>Bananer växer\n minsann inte på träd.<b>");
res.write(str);
&lt;b&gt;Bananer v&auml;xer
minsann inte p&aring; tr&auml;d.&lt;/b&gt;

encodeXml()

Preparing a string for smooth xml output.

Syntax
encodeXml(string)

Description
Encodes a string by replacing < and > with &lt; and &gt; as well as & with its html entity &amp;.

Example
var str = encodeXml("<title>Smørebrød</title>");
res.write(str);
&lt;title&gt;Sm&amp;oslash;rebr&amp;oslash;d&lt;/title&gt;

format()

Preparing a string for smooth html output.

Syntax
format(string)

Description
Encodes a string similar to encode() but keeping the markup tags and trying to avoid <br> tags where possible (e.g. in table structures).

Example
var str = encode("<b>Bananer växer\n minsann inte på träd.<b>");
res.write(str);
<b>Bananer v&auml;xer
<br> minsann inte p&aring; tr&auml;d.</b>

getActiveUsers()

Retrieving active Users.

Syntax
getActiveUsers()

Description
Returns an array that contains all User Objects of users who are currently browsing the Hop application. This includes users who are logged in as well as anonymous users.

Example
var myUsers = getActiveUsers();
res.write(myUsers);
UserNode 6df1869674117400@e4042e487b, UserNode Snoopy, UserNode Woodstock

getAllUsers()

Retrieving the names of all registered users.

Syntax
getAllUsers()

Description
Returns an array that contains the names of all registered users. Use the getUser() function to retrieve the actual user object. This is to be used with caution with large amounts of users.

Example
var myUsers = getAllUsers();
res.write(myUsers);
Snoopy, Lucy, Linux, Woodstock

res.write(getUser(myUsers[1]));
UserObject Lucy

getProperty()

Retrieving a global Property.

Syntax
getProperty(string)

Description
Returns a Property named string stored in one of the files app.properties or server.properties. If the Property exists in both of the files, app.properties overwrites server.properties. This way server.properties defines Properties for all applications which app.properties can refine for a particular application. app.properties is located in the top directory of a Hop application. server.properties is located in the Hop installation directory.

There is a complete list of Hop's System Properties

Example
var smtp = getProperty("smtp");
res.write(smtp);
mail.helma.org

getURL()

Retrieving the content behind a URL.

Syntax
getURL(url)

Description
Allocates and retrieves a remote file from a url.

Example
var url = getURL("http://helma.org/");
res.write(url);

...see helma.org :->

var url = getURL("ftp://user:pass@ftp.server.dom/welcome.txt");
res.write(url);
Welcome on the FTP server of server.dom!


var url = getURL("file:///home/snoopy/www/title.txt");
res.write(url);
The Nudist on the Late Shift

getUser()

Retrieving a User Object.

Syntax
getUser(string)

Description
Returns a Hop Object describing the user referred to with string.

Example
var myUser = getUser("Snoopy");
res.write(myUser.email);
atomicdog@helma.org

getUserBySession()

Retrieving a User Object.

Syntax
getUserBySession(sessionId)

Description
Returns a user object with a certain session id (= Helma session cookie).

Example

var id = user.sessionID;
var user = getUserBySession(id);
res.write(user.name);
Snoopy

(quite recursive, isn't it?)

isActive()

Determining whether a user is logged in.

Syntax
isActive(userObject)

Description
Returns true if the user referred to by the user object is logged in.

Example
var user = getUser("Snoopy");
res.write(isActive(user));
false

renderSkin()

Syntax
renderSkin(String, ParameterObject)

Description
Renders a global skin (ie. a skin file inside the global directory). The name of the skin is defined by the string parameter.

A skin is a file that only contains markup (e.g. Html or Xml) and macros. Macros are references to Helma functions wrapped in special tags (<% and %>). For more information about skin and macro techniques please refer to the section about Helma Skins.

Optionally, a JavaScript object can be assigned to the function call as second argument. This object's properties later can be accessed from the skin via pseudo-macro calls of the kind <% param.PropertyName %>

If a param property is not set but referred to in the skin file, it will be replaced with an empty string. Please note that this behaviour is different from generic macro calls.

Example
Contents of the file global/example.skin:
<html>
<head>
   <title>Hello, <% param.title %>!</title>
</head>
<body bgcolor="<% param.bgcolor %>">
I greet you <% param.amount %> times.
</body>
</html>


Rendering the skin:
var param = new Object();
param.bgcolor = "#ffcc00";
param.title = "World";
param.amount = "12345";
renderSkin("example", param);

<html>
<head>
   <title>Hello, World!</title>
</head>
<body bgcolor="#ffcc00">
I greet you 12345 times.
</body>

renderSkinAsString()

Syntax
renderSkinAsString(String, ParameterObject)

Description
Renders a global skin just the same way as renderSkin() does. The only difference is though, that this function returns the result as string instead of immediately writing it to the response object.

Example
var str = renderSkinAsString("example", param);
res.write(str);


which is equivalent to

renderSkin("example", param);

stripTags()

Removing markup tags from a string.

Syntax
stripTags(string)

Description
Removes any < and > as well as everyhing between both of these two characters. In other words: extracts the essence of the text from a string without anything that looks like markup.

Example
var str = "<html><b>The Nudist on the Late Shift</b></html>";
res.write(str);
The Nudist on the Late Shift

write()

Syntax
write(String)

Description
This function echoes the string parameter on the console display. Very useful for debugging purposes.

Example
write("Hello, Console!");
Hello, Console!

writeln()

Syntax
writeln(String)

Description
This function echoes the string parameter on the console display and additionally a newline character. Very useful for debugging purposes.

Example
writeln("Hello,");
writeln("Console!");
Hello,
Console!

Hop Object

The HopObject is the basic building block of a Hop applications. The website root object, the user object, as well as any custom type defined by the application are HopObjects and inherit all functionality described below.

In addition to defining and scripting special types of HopObjects it is possible to extend all HopObjects at once by defining a prototype called hopobject.

Functions and Properties

add()

Adding a Subnode to a Hop Object.

Syntax
hopObject.add(hopObject)

Description
Adds a Hop Object as new Subnode to another Hop Object. The new Subnode is added after the last Subnode already contained in the Hop Object.

Example
res.write(root.size());
0
var myStory= new story();
root.add(myStory);
res.write(root.size());
1


It is also possible to add a bunch of Subnodes with only one function call:
var myAuthor= new author();
var myTitle= "The Nudist On The Late Shift";
var myStory= new story();
root.add(myAuthor, myTitle, myStory);
res.write(root.size());
3

addAt()

Adding a Subnode to a Hop Object.

Syntax
hopObject.addAt(number, hopObject)

Description
Adds a Subnode to a Hop Object. Unlike add() the position of the Subnode is determined by a number as first parameter in the function call.

Using addAt() instead of add() usually only has an effect with the embedded database, since the order of objects stored in a relational database depends on the value of some column. Thus when adding objects stored in a relational database, one may as well use add().

Example
res.write(root.get(23));
null
var myStory= new story();
root.addAt(23, myStory);
res.write(root.get(23));
hopObject story

cache

Syntax
HopObject.cache

Description
Each HopObject contains a cache object to store temporary properties (e.g. strings, numbers or other objects) in. These properties can be accessed in any thread until the application is restarted or the HopObject is invalidated, either manually using the invalidate() function or whenever Helma is fetching the HopObject's data from a remote database.

There is no way to make the cache object persistent.

Example
user.cache.message = "This is a temporary message."

contains()

Determining if a Hop Object contains a certain Subnode.

Syntax
hopObject.contains(hopObject)

Description
Returns the index position of a Subnode contained by a Hop Object (as usual for JavaScript starting with 0 referring to the first position). The index position is a relative value inside a Hop Object (not to be confused with a Hop ID which is unique for each Hop Object). If there is no appropriate Subnode inside the Hop Object the returned value equals -1

Example
var obj = root.get("myObject");
res.write(root.contains(obj));
23

obj = root.get("blobject");
res.write(root.contains(obj));
-1

count()

Counting Subnodes.

Syntax
hopObject.count()

Description
Returns the amount of Subnodes contained in a Hop Object.

Example
res.write(root.count());
5

editor()

Syntax
hopObject.editor(string, width, height)

Description
Returns an input element for the object's property defined by the string parameter. The result can be used inside an Html form. The property's value is set to the form elements value. If the optional height parameter is set, a text area is used instead of a one-line text field.

Example
var editor = this.editor("title", 20);
res.write("<form>" + editor + "</form>");

<form><input type="text" name="title" size="20" value="Hello, World"></form>

var editor = this.editor("bodytext", 20, 5);
res.write("<form>" + editor + "</form>");

<form><textarea name="bodytext" cols="20" rows="5" wrap="virtual">When the going gets tough, the tough goes shopping.</textarea></form>

get()

Retrieving Properties and Subnodes.

Syntax
hopObject.get(stringOrNumber)

Description
Retrieves a Property or a Subnode of a known Hop Object. The type of the result depends on the type of the submitted parameter: a number will retrieve the Subnode of the Hop Object at the corresponding index position, a string the corresponding Property of the Hop Object. Finally, a number as string retrieves the subnode with the corresponding Hop ID.

Example
root.get(0);
HopObject author
root.get(1);
HopObject story

root.get("date");
Wed Oct 18 02:01:41 GMT+01:00 1971
root.get("title");
The Nudist On The Late Shift

root.get("1");
HopObject author

href()

Getting a Hop Object's url-compatible reference.

Syntax
hopObject.href()
hopObject.href(string)

Description
Returns the absoulte url path of a Hop Object relative to the application's root. Any string parameter is simply appended to the return value. Useful to refer to a Hop Object in a markup tag (e.g. with a href parameter in an html <a> tag).

Example
var obj = root.get(0);

res.write("<a href=\"" + obj.href() + "\">");
<a href="/main/">

res.write("<a href=\"" + obj.href("edit") + "\">");
<a href="/main/edit">

invalidate()

Delete a Hop Object from the cache.

Syntax
hopObject.invalidate()

Description
Marks a HopObject as invalid so that it is fetched again from the database the next time it's accessed. In other words, use this function to kick an object out of Helma's database cache.

Example
var obj = this.get(0);
obj.invalidate();

list()

Listing Hop Objects.

Syntax
hopObject.list()

Description
Returns an array including all Subnodes of a Hop Object. Useful if array data is required, however general use should be avoided in favor of the method described below.

Example
var objectList = root.list();
for (var i=0; i<objectList.length; i++){
 var myObject = objectList[i];
 res.write(myObject.created + "<br>");
}
Wed Oct 18 02:01:41 GMT+01:00 1971
Fri Nov 03 13:25:15 GMT+01:00 2000
Mon May 29 07:43:09 GMT+01:00 1999


With increasing amounts of Subnodes tied to a Hop Object the use of list() becomes seriously inefficient – as long as not all Subnodes really need to be read out. This is due to the creation of a JavaScript Array containing the whole bunch of Subnodes each time the list() function is called. Instead, it is recommended to determine the amount of Subnodes using the count() function and looping through them using get():

var amount = root.size();
for (var i=0; i<amount; i++){
 var myObject = root.get(i);
 res.write(myObject.created + "<br>");
}
Wed Oct 18 02:01:41 GMT+01:00 1971
Fri Nov 03 13:25:15 GMT+01:00 2000
Mon May 29 07:43:09 GMT+01:00 1999

remove()

Removing a Subnode.

Syntax
hopObject.remove()

Description
Removes a known Subnode from a Hop Object. The subnode can be determined e.g. via the get() function.

Example
res.write(root.size());
24
var myObject = root.get(5);
root.remove(myObject);
res.write(root.size());
23

renderSkin()

Syntax
HopObject.renderSkin(String, ParameterObject)

Description
Renders a skin of this object. The name of the skin is defined by the string parameter.

A skin is a file that only contains markup (e.g. Html or Xml) and macros. Macros are references to Helma functions wrapped in special tags (<% and %>). For more information about skin and macro techniques please refer to the section about Helma Skins.

Optionally, a JavaScript object can be assigned to the function call as second argument. This object's properties later can be accessed from the skin via pseudo-macro calls of the kind <% param.PropertyName %>

If a param property is not set but referred to in the skin file, it will be replaced with an empty string. Please note that this behaviour is different from generic macro calls.

Example
Contents of the file root/example.skin:
<html>
<head>
   <title>Hello, <% param.title %>!</title>
</head>
<body bgcolor="<% param.bgcolor %>">
I greet you <% param.amount %> times.
</body>
</html>


Rendering the skin:
var param = new Object();
param.bgcolor = "#ffcc00";
param.title = "World";
param.amount = "12345";
root.renderSkin("example", param);

<html>
<head>
   <title>Hello, World!</title>
</head>
<body bgcolor="#ffcc00">
I greet you 12345 times.
</body>

renderSkinAsString()

Syntax
HopObject.renderSkinAsString(String, ParameterObject)

Description
Renders a skin of this object just the same way as renderSkin() does. The only difference is though, that this function returns the result as string instead of immediately writing it to the response object.

Example
var str = root.renderSkinAsString("example", param);
res.write(str);


which is equivalent to

root.renderSkin("example", param);

set()

Changing Properties and Subnodes.

Syntax
hopObject.set(stringOrNumber, value)

Description
Replaces the value of a Property or Subnode with a new value.

Example
res.write(root.get(23));
null
var myAuthor = new author();
root.set(23, myAuthor);
res.write(root.get(23));
hopObject author

res.write(root.title);
null
var myTitle = "The Nudist On The Late Shift";
root.set("title", myTitle);
res.write(root.title);
The Nudist On The Late Shift

setParent()

Defining a Hop Object as parent for a Subnode.

Syntax
hopObject.setParent(hopObject)

Description
Sometimes it is necessary to set a Subnode's parent to a certain Hop Object. This is caused by the way Hop caches Subnodes. Especially if you are retrieving a Subnode from a relational database through different ways (e.g. by using subnoderelation) and you want to remove this Subnode or apply the href() function on it.

Example
var trash = user.stories.get(23);
trash.setParent(root);
root.remove(trash);

size()

Counting Subnodes.

Please refer to count().

_id

Syntax
hopObject._id

Description
Returns the internal id of the object. This property is assigned by Helma and cannot be set.

Example
var obj = root.get(0);
res.write(obj._id);
43

_parent

Syntax
hopObject._parent

Description
Returns the parent object of this object.

Example
var obj = root.get(0);
res.write(obj._parent);
HopObject root

Image Processing

The image object allows you to read, manipulate, and save images. An image object is created using the Image() constructor.

var img = new Image(imageUrl);
var img = new Image(imageUrl, imageFilter);


For this to work, you must have Sun's Jimi library in your classpath.

Example:
var img = new Image("http://helma.org/image.gif");
var img = new Image("file:///home/images/image.jpg");

var filter = new Packages.com.sun.jimi.core.filters.Rotate(90);
var img = new Image("http://helma.org/image.gif", filter);
.

Please refer to the getSource() function for details and examples of the imageFilter parameter.

crop()

Cutting out a rectangular area of an image.

Syntax
imageObject.crop(x, y, width, height)

Description
Cuts out (crops) a rectanglular area of an image. The dimensions of the area are calculated from the x- and y-offset from the top left corner of the image as upper left reference point to x + width and y + height as lower right reference point.

Example
var img = new Image("http://helma.org/images/original.gif");
res.write("<img src=\"/images/original.gif\">");



img.crop(58,9,48,21);
img.saveAs("/www/images/processed.gif");
res.write("<img src=\"/images/processed.gif\">");

drawLine()

Adding a drawn line to an image.

Syntax
imageObject.drawLine(x1, x2, y1, y2)

Description
Draws a line onto an image. The line starts at the reference point defined by the offsets x1 and y1 from the top left corner of the image and ends at the reference point defined by the offsets x2 and y2.

Example
var img = new Image("http://helma.org/images/originalgif");
res.write("<img src=\"/images/original.gif\">");



img.setColor(204,0,0);
img.drawLine(58,26,100,26);
img.saveAs("/www/images/processed.gif");
res.write("<img src=\"/images/processed.gif\">");

drawRect()

Adding a drawn rectangle to an image.

Syntax
imageObject.drawRect(x, y, width, height)

Description
Draws a rectangle onto an image. The rectangle's dimensions are calculated from the x- and y-offset from the top left corner of the image as upper left reference point to x + width and y + height as lower right reference point.

Example
var img = new Image("http://helma.org/images/originalgif");
res.write("<img src=\"/images/original.gif\">");



img.setColor(204,0,0);
img.drawRect(57,8,46,20);
img.saveAs("/www/images/processed.gif");
res.write("<img src=\"/images/processed.gif\">");

drawString()

Adding text to an image.

Syntax
imageObject.drawString(string, x, y)

Description
Draws a string onto an image. The string will be drawn starting at the x- and y-offset from the top left corner of the imaget.

Example
var img = new Image("http://helma.org/images/original.gif");
res.write("<img src=\"/images/original.gif\">");



img.setColor(204,0,0);
img.drawString("rocks!",82,35);
img.saveAs("/www/images/processed.gif");
res.write("<img src=\"/images/processed.gif\">");

fillRect()

Adding a filled rectangle to an image.

Syntax
imageObject.fillRect(x, y, width, height)

Description
Draws a filled rectangle onto an image. The rectangle's dimensions are calculated from the x- and y-offset from the top left corner of the image as upper left reference point to (x + width) and (y + height) as lower right reference point.

Example
var img = new Image("http://helma.org/images/original.gif");
res.write("<img src=\"/images/original.gif\">");



img.setColor(204,0,0);
img.fillRect(58,27,43,29);
img.saveAs("/www/images/processed.gif");
res.write("<img src=\"/images/processed.gif\">");

getHeight()

Determining the height of an image.

Syntax
imageObject.getHeight()

Description
Returns the height of an image measured in pixels.

Example
var img = new Image("http://helma.org/images/hop.gif");
res.write("<img src=\"/images/hop.gif\">");



var height = img.getHeight();
res.write(height);
35

getSource()

Syntax
Image.getSource()

Description
To use the image filters provided by the Jimi java image processing package Packages.com.sun.jimi.core.filters, a specific class of image objects is needed. Helma wraps the sun.awt.image objects into a custom class. To use Helma image objects with Jimi's filters these have to be "unwrapped" using the getSource() function.

The following filter functions have been successfully applied the way as described in the examples above:

Please take into account that the quality might suffer depending on the type and amount of filters applied to the image.

Example
var img = new Image("http://helma.org/static/original.jpg");
var rotator = new Packages.com.sun.jimi.core.filters.Rotate(45);
var processed = new Image(img, rotator);
processed.saveAs("/path/to/static/processed.jpg");
res.write("&lt;img src=\"/static/processed.jpg\&gt;");



var img = new Image("http://helma.org/static/original.jpg");
var filter = Packages.com.sun.jimi.core.filters;
var oil = new filter.Oil(img.getSource(), 3);
var processed = new Image(img, oil);
processed.saveAs("/path/to/static/processed.jpg");
res.write("&lt;img src=\"/static/processed.jpg\&gt;");

getWidth()

Determining the width of an image.

Syntax
imageObject.getWidth()

Description
Returns the width of an image measured in pixels.

Example
var img = new Image("http://helma.org/images/hop.gif");
res.write("<img src=\"/images/hop.gif\">");



var width = img.getWidth();
res.write(width);
174

reduceColors()

Setting the color depth of an image.

Syntax
imageObject.reduceColors(number)

Description
Reduces the number of colors used in an image to the amount specified with number. Use with caution, generally. Gif images need a color depth of max. 256 colors maximum.

Example
var img = new Image("http://helma.org/images/original.jpg");
res.write("<img src=\"/images/original.jpg\">");



img.reduceColors(8);
img.saveAs("/www/images/processed.jpg");
res.write("<img src=\"/images/processed.jpg\">");

resize()

Setting the dimensions of an image.

Syntax
imageObject.resize(width, heigth)

Description
Sets the height and width of an image to new values. The new width and height have to be integers, so be careful to round the new values eventually. In case of a gif image be sure to reduce the image to 256 colors after resizing by using the reduceColors() function.

Example
var img = new Image("http://helma.org/images/original.jpg");
res.write("<img src=\"/images/original.jpg\">");



var factor = 0.66;
var wd = Math.round(img.getWidth() * factor);
var ht = Math.round(img.getHeight() * factor);
img.resize(wd, ht);
img.saveAs("/www/images/processed.jpg");

res.write("<img src=\"/images/processed.jpg\">");

saveAs()

Storing an image on the hard disk.

Syntax
imageObject.saveAs(path)

Description
Stores the binary data of an image on the hard disk. Before the image is converted into the appropriate image format determined by the file extension (please refer to the JIMI documentation for a detailed overview of the available formats).

Example
var img = new Image("http://helma.org/images/original.jpg");
res.write("<img src=\"/images/original.jpg\">");



img.saveAs("/www/images/processed.png");
res.write("<img src=\"/images/processed.png\">");

setColor()

Selecting a drawing color.

Syntax
imageObject.setColor(colorOrRgbValues)

Description
Determines the color of the following drawing actions either by a 24-bit integer (0–16777215) or by an rgb-tuple (each element ranging from 0 to 255).

Example
var img = new Image("http://helma.org/images/original.jpg");
res.write("<img src=\"/images/original.jpg\">");



img.setColor(16777215);
img.fillRect(80, 50, 30, 30);
img.setColor(255, 255, 0);
img.fillRect(65, 15, 30, 30);
img.saveAs("/www/images/processed.png");
res.write("<img src=\"/images/processed.png\">");

setFont()

Selecting a typeface for font setting.

Syntax
imageObject.setFont(name, style, size)

Description
Determines the font face, style and size of a font to be used in following drawString() actions. name specifies the font face as string (e.g. "sansserif", "dialog").

The integer style sets the font to normal (0), bold (1), italic (2) or bold and italic (3). size, also an integer, refers to the font size in pixels.

Please take a look at this description about adding fonts to the Java Runtime for a detailed look onto Java's font mechanics.

Example
var img = new Image("http://helma.org/images/original.jpg");
res.write("<img src=\"/images/original.jpg\">");



img.setColor(255, 255, 255);
img.setFont("serif", 0, 12);
img.drawString("I shot the serif.", 50, 15);
img.setFont("sansserif", 1, 14);
img.drawString("But I didn't shoot", 10, 100);
img.setFont("monospaced", 2, 16);
img.drawString("the monotype.", 15, 115);
img.saveAs("/www/images/processed.png");
res.write("<img src=\"/images/processed.png\">");

Java Object Access

See the Fesi documentation for Java object access.

For starters, objects from the core Java Api (in the java.* packages) can be instantiated directly, while other Java classes need the Packages prefix.

var buffer = new java.lang.StringBuffer();
var foo = new Packages.com.bar.util.Foo();


Use Sun's Api Specification to find out more about Java objects.

Example
/**
* This function returns a date string
* from a Date object formatted
* according to a custom locale.
*/
function getLocaleDate(date) {
   // Here the locale is set (english / Ireland):
   var locale = new java.util.Locale("en", "IE");
   // Creating the date formatter:
   var dateFormat = new java.text.SimpleDateFormat("EEEE d MMMM yyyy, HH:mm", locale);
   // Formatting the Date object as date string:
   var dateString = dateFormat.format(date);
   return(dateString);
}

Mail Client

Mail objects are used to send email via Smtp and are created by using the Mail() constructor:

var mail = new Mail();

The mail object can than be manipulated and sent using the functions listed below.

You'll need the JavaMail library installed for this to work. Also, don't forget to set your mail server via the smtp property.

Note: Make sure that the Smtp server itself is well-configured, so that it accepts Mails coming from your server and does not deny relaying.
Best and fastest configuration is of course if you run your own Smtp server (e.g. sendmail), but which might be a bit tricky to set up.

addBCC()

Syntax
mailObject.addBCC(EmailString, NameString)

Description
Adds a recipient to the list of addresses to get a "blind carbon copy" of the message. The first argument specifies the receipient's e-mail address. The second argument is optional and specifies the name of the recipient.

Example
var mail = new Mail();
mail.addBCC("hop@helma.at");
mail.addBCC("tobi@helma.at", "Tobi Schaefer");

addCC()

Syntax
mailObject.addCC(EmailString, NameString)

Description
Adds an address to the list of carbon copy recipients. The first argument specifies the receipient's e-mail address. The second argument is optional and specifies the name of the recipient.

Example
var mail = new Mail();
mail.addCC("hop@helma.at");
mail.addCC("tobi@helma.at", "Tobi Schaefer");

addPart()

Syntax
mailObject.addPart(Object)

Description
Adds a mime-part to the message. The mime-part (e.g. a gif image or an rtf document) has to be wrapped into a java.io.File object.

Example
var file = new java.io.File("/home/snoopy/woodstock.jpg");
var mail = new Mail();
mail.setFrom("snoopy@doghouse.com");
mail.setTo("woodstock@birdcage.com");
mail.setSubject("Look at this!");
mail.addPart("I took a photograph from you. Neat, isn't it? -Snoop");
mail.addPart(file);
mail.send();

addText()

Syntax
mailObject.addText(String)

Description
Appends a string to the body text of the message. Note that this method will overwrite any multi-mime-parts already added to the message.

Example
var mail = new Mail();
mail.addText("Hello, World!");

addTo()

Syntax
mailObject.addTo(EmailString, NameString)

Description
Adds a receipient to the address list of the message. The first argument specifies the receipient's e-mail address. The second argument is optional and specifies the name of the recipient.

Example
var mail = new Mail();
mail.addTo("hop@helma.at");
mail.addTo("tobi@helma.at", "Tobi Schaefer");

send()

Syntax
mailObject.send()

Description
This function actually sends the message created with the mail object using the smtp server as specified in an appropriate property file.

Example
var mail = new Mail();
mail.addTo("watching@michi.tv", "michi");
mail.addCC("franzi@home.at", "franzi");
mail.addBCC("monie@home.at");
mail.setFrom("chef@frischfleisch.at", "Hannes");
mail.setSubject("Registration Conformation");
mail.addText("Thanks for your Registration...");
mail.send();

setFrom()

Syntax
mailObject.setFrom(EmailString, NameString)

Description
Sets the sender of the message. The first argument specifies the sender's e-mail address. The second argument is optional and specifies the name of the sender.

Example
var mail = new Mail();
mail.setFrom("tobi@helma.at", "Tobi Schaefer");

setSubject()

Syntax
mailObject.setSubject(String)

Description
Sets the subject of the message.

Example
var mail = new Mail();
mail.setSubject("Hello, World!");

status

Syntax
mailObject.status

Description
Returns the current status of the message. If an error has occured the status is greater than zero. Here are the error codes:

nr   error description
--   -----------------
 0   no error
10   error with setSubject()
11   error with addText()
12   error with addPart()
20   error with addTo()
21   error with addCC()
22   error with addBCC()
30   error while trying to send the Message

Example
var mail = new Mail();
mail.addTo("idont@know@myemail.com");
res.write(mail.status);
20

Number Object

format()

Syntax
Number.format(PatternString)

Description
Formats a number as string for custom output. The function's string parameter is used as a pattern to describe the desired format. In the pattern string you can use the following pattern letters:

Symbol   Meaning
------   -------
  0      a digit
  #      a digit, zero shows as absent
  .      placeholder for decimal separator
  ,      placeholder for grouping separator.
  E      separates mantissa and exponent for
         exponential formats.
  ;      separates formats.
  -      default negative prefix.
  %      multiply by 100 and show as percentage
  ?      multiply by 1000 and show as per mille
  ¤      currency sign; replaced by currency symbol;
         if doubled, replaced by international currency
         symbol. If present in a pattern, the monetary
         decimal separator is used instead of the decimal
         separator.
  X      any other characters can be used in the prefix
         or suffix.
  '      used to quote special characters in a prefix
         or suffix.
Please note that the output is depending on the locale settings of the Helma server. For further reference refer to the examples below or directly to the documentation of the Java DecimalFormat class

Example
var nr = 12345.67890;
res.write(nr.format("#.00 ¤"));
12345,68 öS

res.write(nr.format("###,####.00 ¤¤"));
1.2345,68 ATS

var nr = 0.0987654321;
res.write(nr.format("0.###%"));
9,877%

var nr = 7.9E-5
res.write(nr.format("0.######"));
0,000079

Object-Relational Mapping

The Hop comes with the ability to store Hop objects natively in its embedded object database. However, for many purposes it is advisable to use an external relational database product for object storage for reasons including features, accessability and reliability.

A prototype can specify how its data properties are stored in relational database tables by providing a types.properties file. This file is located in the prototype's directory along with the prototype code. It is basically a Java properties file that maps JavaScript properties to database columns. Unfortunately, the mapping rules have gone from clean and simple to rather obscure as features were added to the Hop.

A basic type.properties file might look like this:

_datasource = my_data_source
_tablename = my_table

_subnodes = <child.db_parent_id
_id = id

title = db_title
createdate = db_createdate
owner = db_owner_id>user.id
The first thing we notice is that some properties begin with an underscore ("_") while others don't. This is a simple convention to separate those properties which are needed by Hop internally from those that specify script-accessible properties of this prototype.

In the following, we describe the different kinds of entries that can be used in type.properties files.

Path Object

Description
The objects in the uri path of a request are not only accessible as array members of the global path object, but also as named properties of path via the name of their prototype. For instance, if an object in the uri path has a prototype called "story", it will be accessible as path.story.

Example
Assumed the request path of an application is
/h_files/myDocument/storyTitle/23

for (var i=0; i<path.length; i++)
   res.writeln(path[i]);

HopObject file
HopObject document
HopObject story
HopObject note


var obj = path.story;
res.write(obj);

HopObject story

Property Files

Helma's property files are simple text files containing information e.g. about which applications to start, about the database connection, server configuration etc.

There is no general syntax of the various properties, however most of the time each line represents a property's assignment the way

propertyName = propertyValue(s)

A line starting with a hash character # will be handled as comment:

# This is a comment.
This is no comment. # This is no comment, either.

app.properties

Description
This file is located in an application's directory (e.g. apps/myApp/). A wide variety of properties can be defined here. Generally, any imaginable name can be used as a property and assigned a string value the way

propertyName = propertyValue

Properties defined in such a way can be evaluated from inside Helma's scripting environment by using the getProperty() function.

However, there is a bunch of pre-defined properties that are used internally by Helma. Be careful not to accidentally bend these special properties for your custom purposes or your application eventually could behave unexpectedly.

Many of those pre-defined properties also can be defined server-wide in server.properties. However, any property that is set there will be overwritten by an appropriate setting in app.properties.

Example
# Setting some properties:
backgroundColor = #3333ff
title = "Hello, World!"


Accessing the properties e.g. from root/main.hac:
var bgColor = getProperty("backgroundColor");
res.write(bgColor);
#3333ff

var title = getProperty("title");
res.write(title);
Hello, World!

apps.properties

Description
This file is located in Helma's installation directory. It contains a list of applications that helma will handle (ie. start up, execute, update). The name of an application refers to a directory with the same name in helma's apps directory.

Example
hopblog
antville
gong
kolin

Special case: appname = self

Using this syntax enables the application appname to script Helma herself. Currently, there can be only one application set-up this way:

Example
hopblog
antville
base = self
gong

db.properties

Description
This file is located in Helma's installation directory. It contains a list of data sources and data source properties setting up the basic connection between Helma and relational databases.

To define data sources, the property sources is assigned a comma-separated list of names (certainly, the list can contain only one element):

sources = dataSourceName

In consequence the following properties of the data source(s) must be set:

dataSourceName.url
dataSourceName.driver
dataSourceName.user
dataSourceName.password


Example
sources = mySqlDB, oracleDB, hsqlDB

mySqlDB.url = jdbc:mysql://db.domain.com/mysql
mySqlDB.driver = org.gjt.mm.mysql.Driver
mySqlDB.user = username
mySqlDB.password = secretPassword

oracleDB.url = jdbc:oracle://db.domain.com/oracle
oracleDB.driver = oracle.jdbc.driver.OracleDriver
oracleDB.user = username2
oracleDB.password = secretPassword2

hsqlDB.url = jdbc:hsqldb:dbData
hsqlDB.driver=org.hsqldb.jdbcDriver
hsqlDB.user=sa
hsqlDB.password=

server.properties

Description
This file is located in Helma's installation directory. It contains pre-defined properties that are used internally by Helma for configuring the server.

Many of these properties also can be defined in an app.properties file. Any property that is set there will overwrite the appropriate setting in server.properties.

Example
# Setting a custom locale:
country = AT
language = de

# Defining a mail server:
smtp = mail.domain.dom

type.properties

This file is located in a prototype's directory (e.g. apps/myApp/myProto). It contains definitions that specify the way Helma maps the relational database tables to hierarchical objects.

Basic Mappings

The _db entry describes the database to use for storing objects of this type. dbname is the name of a database as defined in the db.properties file.

_db = dbname

The _table entry tells Helma which table to use for objects of this type within the database.

_table = TABLENAME

The _id entry defines the column to use as primary key. Helma requires a single primary key with no other functionality.

_id = ID_COLUMN

The optional _name entry tells Helma which database column to use as object name. This is important for the user prototype, since it defines which column constitutes the user name.

_name = NAME_COLUMN

The _parent entry contains a list of properties of objects of this type to be used as parent. Objects must know their parent in order to generate correct URLs in their href() function.

_parent = property1, property2

Simple Property Mappings

The mappings for simple (non-object) properties simple map a property name of the specified object type to a column of the relational database table. The type of the property or column need not be specified. Helma does all necessary conversion when reading or writing a property value.

prop1 = DB_COLUMN_1
prop2 = DB_COLUMN_2


To prevent a property from being overwritten by the application it can be made readonly.

prop1.readonly = true

Mountpoint Mappings

Mountpoints provide a simple way to directly attach a prototype to the URL path. If the path contains the name of a mountpoint the prototype's objects are accessible simply by adding their id (or a property defined by ._accessname) to the URL string.

myMountpoint = mountpoint(myProto)

In the example above, the path /myMountpoint/23/test refers to the action test.hac of the object with id 23, which is derived from the myProto prototype.

Object Property Mappings

Properties that contain other objects are defined by the object keyword and the prototype name of the referenced object in brackets. The object reference is resolved via two entries:

prop3 = object (protoype)
prop3.local = LOCAL_DB_COLUMN
prop3.foreign = FOREIGN_DB_COLUMN


prop3.local specifies the part of the reference in the local database-table, prop3.foreign the column in the table where objects of the referenced prototype are stored. By executing the assignment obj.prop3 = someObject, the database-column specified by prop3.local will be set to the value of FOREIGN_DB_COLUMN, or null if someObject == null.

Collection Mappings

The following section describes the entries used to define collections of objects. There are two kinds of collections: First, every object can itself act as a collection, and second, it can define additional properties to be used as collections. Direct descendents are defined with entries starting with _children, while additional collections are defined using their property name. Otherwise the syntax for the two is the same.

The following are examples for simple collection mappings for both the direct descendants and those contained in a collection-property called prop4. The .foreign entry is used in both cases to specify a column in the foreign table used to collect the objects. Exactly those objects will be collected whose FOREIGN_DB_COLUMN value equals the LOCAL_DB_COLUMN value of the object holding the collection. Leaving away .local and .foreign creates a collection of all available objects of the specified prototype.

_children = collection (protoype)
_children.local = LOCAL_DB_COLUMN
_children.foreign = FOREIGN_DB_COLUMN

prop4 = collection (protoype)
prop4.local = LOCAL_DB_COLUMN
prop4.foreign = FOREIGN_DB_COLUMN


By executing obj.add(otherObj) resp. obj.prop4.add(otherObj), the FOREIGN_DB_COLUMN will be set to the value of LOCAL_DB_COLUMN.

By default, child objects can be accessed from the containing parent object through their index-position or ID value. Additionally the entry .accessname can be used to specify a database column in the child table. The value of this column will be used as name of the objects contained in this collection.

prop4.accessname = DB_COLUMN

With the above mapping, an object contained in the prop4 collection with a DB_COLUMN value of "xyz" would be reachable as this.prop4.xyz from the containing object.

filter can be used to add an additional condition for the selection of objects which is not dependent on the object holding the collection. order contains the sorting to be applied to the child objects. group tells Helma to group the objects in the collection according to the value in DB_GROUPCOLUMN.

prop4.filter = DB_FILTERCOLUMN is not null
prop4.order = DB_ORDERCOLUMN desc
prop4.group = DB_GROUPCOLUMN
prop4.group.order = DB_GROUPORDERCOLUMN


Notice the two appearences of order above. The first one, prop4.order sorts the objects, the second, prop4.group.order sorts the grouped objects, that Helma will create as a result of the group entry. With this it's also possible to sort the grouped objects ascending, but the contents of the grouped objects descending.

Additional Join Conditions

For both object and collection mappings, it is possible to provide any number of additional restraints used to join the local with the other table to further limit the selected objects.

prop4.local.1 = FIRST_LOCAL_COLUMN
prop4.foreign.1 = FIRST_FOREIGN_COLUMN
prop4.local.2 = SECOND_LOCAL_COLUMN
prop4.foreign.2 = SECOND_FOREIGN_COLUMN


Whenever one specifies more than one restraint, the use of .[Number] is mandatory.

List of All Properties

This is a list of all pre-defined properties that can be set in one of the files server.properties, db.properties and app.properties (type.properties coming soon). Which property is available in which file is displayed in the "Range" column.

Property Range Description
actionExtension server, app Sets the extension for Helma action files. Default setting is actionExtension = .hac. Changing this setting is not recommended. Use with caution and at your own risk.
allowWeb server Specifies ip adresses (or networks) that are allowed to connect to the Helma rmi servlet server (port 5055). For more than one ip adress put a comma between the entries, subnets should be written as i.e. 192.168.0.*.
allowXmlRpc server, app Same as allowWeb, but for the xml-rpc server (port 5056).
appHome server Defines the path to the location of Helma applications. If not specified, [hopHome]/apps will be used.
appsPropFile server Sets the location of the apps.properties file (i.e. for security reasons). The default is the root directory of your Helma installation.
baseURI server, app Specifies the prefix to add to urls generated by a Helma application. For example, if your application is "mounted" at /myapp in the server's document tree, you'd set baseURI = /myapp.
cachesize server Defines the size of the node cache in bytes.
charset server Defines the character encoding. The default is ISO-8859-1 (Western) encoding. You can use any of the encodings supported by Java.
country server Like language, this is used to set the country for proper localisation. For details you can refer to this list of country codes.
dbHome server Defines the path to the location of the embedded database files. If not specified, [hopHome]/db will be used
debug server, app Switches between "normal" logging output (debug = false) and the extensive "debug" output (debug = true) which may be useful when developing. Default setting is false.
exposeTemplates server, app To directly call a .hsp (instead of a .hac) file via the http interface it is necessary to set exposeTemplates = true. Default setting is false.
hopHome server This property defines the Helma working directory, e.g. hopHome = /hop/apps. If not specified, the current directory is used.
hrefSkin app The name of the skin that is assigned to this property is used to extend the href() function. E.g. setting hrefSkin = customLink will cause Helma to set param.path to the result of href() and to render the skinfile customLink.skin as if the function renderSkin("customLink", param) was invoked. Take a look at the hrefSkin example for the whole picture.
idBaseValue server, app Used to set the current value of the internal ID generator. This is useful when starting a new internal db (where the id value would normally start at 1), but relational dbs are used that already contain data. Only applied if the current counter value is smaller than idBaseValue.
language server Used to set the language on systems where the Java runtime doesn't recognize it by itself (e.g. Linux), which may be important for date formatting and the like. Refer to this list of language codes for details.
linkMethod server, app linkMethod = query | path
Deprecated.
logDir server, app
logSQL server, app With this option set to "true", Helma writes out all sql select statements to the logging device (and just those, so you won't find any insert, update or delete statements in there).
maxThreads server Sets the maximum number of Helma's Java threads, e.g. maxThreads = 12. This is one of the parameters you should adjust for each server depending on the applications you run. If you see an error like "maximum thread count reached" you should increase the value of this property.
paranoid server If set to true, switches Helma to "paranoid" mode, which means that it won't accept connections from servers with unknown ip adresses >you can specify allowed ip adresses with the allowWeb and allowXmlRpc properties. Default setting is paranoid = false.
requestTimeout server Defines the time in seconds after which a request receives a timeout. Normally there is no need to change this value, but if you have tasks in your Helma application that take a longer time, you should increase this value.
scriptExtension server, app Used to change the extension of script files. Default setting is scriptingExtension = .js. Changing this setting is not recommended. Use with caution and at your own risk.
sessionTimeout server, app This determines the time (in minutes) after which an inactive session becomes invalid.
skinPath app
smtp server, app Specifies an smtp server, e.g. smtp = mail.server.dom. If you want Helma to send e-mail you should define this property.
sources db Defines the name of one or more data sources to be used in an application, e.g. sources = mySqlDB, oracleDB. Each data source has then to be specified in detail by assigning values to its properties url, driver, user and password. Refer to the description of db.properties for further information.
templateExtension server, app Used to change the extension of Helma template files. Changing this setting is not recommended. Use with caution and at your own risk.
timezone server It might be necessary to explicitly set the timezone for Helma. If new Date() puts out the wrong date, check if this option was set correctly. For details, refer to this list of timezones
xmlparser server, app Can be used to specify a different Xml parser, e.g. xmlparser = minml. The default value is openxml.
XmlRpcAccess server, app Functions which should be callable via Xml-Rpc need to be listed in this property on a per-application basis. The list contains entries of the kind prototype.function for each exposed function separated by commata, e.g. XmlRpcAccess = weblog.getStory, weblog.showStatus.
xmlRpcHandlerName app Setting this property makes it possible to change the name under which an application is registered with the XML-RPC server. This means that the functions exposed via XML-RPC will have a "blogger" prefix. For instance a function called "newPost" will be XML-RPC callable as blogger.newPost instead of antville.newPost.

Example Files

server.properties
# Setting the extension for Helma action files:
actionExtension = .hac

# Allowing some ip addreses for web access:
allowWeb = 192.168.0.*, 194.152.169.160

# Allowing some ip addreses for xml-rpc access:
allowXmlRpc = 192.168.0.*

# Setting the directory where Helma applications reside:
appHome = /helma-1.2/apps

# Setting the location of apps.properties:
appsPropFile = /helma-1.2/propFiles

# Setting the application's base uri:
baseURI = /apps/testApp

# Setting the size of Helma's cache memory:
cachesize = 1000

# Setting the character encoding:
charset = UTF8

# Setting the country code:
country = AT

# Setting the location of database files:
dbHome = /etc/db/helma

# Enabling debugging:
debug = true

# Enabling web access to .hsp templates:
exposeTemplates = true

# Setting the Helma working directory
hopHome = /helma-1.2

# Setting the base value to create id numbers from:
idBaseValue = 5000

# Setting the language code:
language = de

# Enabling database logging
logSQL = true

# Setting the maximum number of server threads:
maxThreads = 12

# Enabling restricted web access to the Helma server:
paranoid = true

# Setting the duration after a request times out:
requestTimeout = 60

# Setting the extension of JavaScript files:
scriptExtension = .js

# Setting the duration after an inactive session times out:
sessionTimeout = 10

# Setting a smtp server:
smtp = mail.server.dom

# Setting a relational data source:
sources = mySqlDB

# Setting the extension of Helma templates:
templateExtension = .hsp

# Setting the server's timezone:
timezone = GMT

# Enabling the MinML xml parser:
xmlparser = minml

# Defining which application functions should be accessible via xml-rpc:
XmlRpcAccess = weblog.getStory, weblog.showStatus

Request Object

The request object represents the request coming from the client. It is accessible as a global variable called req.

data

Syntax
req.data.String;

Description
Retrieves the corresponding value from the http request. The value can either come from a cookie, or from a "post" or "get" http request. Hop does not make any difference here.

The following variables are automatically set by Helma if they are available:

req.get() provides exactly the same functionality in a what we think not as comfortable way (gotta type brackets and quotes). But it's just a matter of taste which one to use.

Example
Here we see all three methods of setting a name, value pair:
res.write("<form action=" + root.href("showValues") + " method="post"><input name="city"><input type="submit"></form>");

res.write("<form action=" + root.href("showValues") + " method="get"><input name="district"><input type="submit"></form>");

res.setCookie("street", "Lindengasse");


root/showValues.hac:
res.write(req.data.city);
res.write(req.data.district);
res.write(req.data.street);


Note: If you have got a cookie and a form element with the same name sent by "get" or "post", the cookie value will be overridden by the form value.

If you are very curious and want to see all the values sent by the http request, you can use the getReqData() function.

get()

Syntax
req.get(String)

Description
Retrieves the corresponding value from the http request. The value can either come from a cookie, or from a "post" or "get" http request. Hop does not make any difference here.

This is an alternative way of accessing request data to the req.data object. Please see the req.data documentation for more information.

Example
res.write(req.get("http_remotehost"));
127.0.0.1

path

Syntax
req.path

Description
returns the path of the current request

Example
res.write(req.path);
docs/reference/req/path

session

Syntax
req.session

Description
returns the Session ID of the current user

Example
res.write(req.session);
717163f187abf800@e4b40a0e88

Response Object

The response object represents the response to be sent back to the client. It is accessible as a global variable called res.

body

Deprectated property.

This property is deprecated and will not be supported in future releases of Helma.

Use res.data instead, by attaching the appropriate property to it.

cache

Syntax
res.cache = Boolean

Description
Specifies on a per-response base whether to allow client-side caching of the response or not. The default value is set to true, but can be changed globally by passing caching=false to the initial Helma java call. Please refer to the section about servlet properties for more details.

Example
res.cache = true;

charset

Setting character encoding.

Syntax
res.charset = CharsetString

Description
Sets Helma's character encoding according to the list of supported encodings. By default, Helma uses ISO-8859-1 (western) encoding. It is also possible to set the encoding server or application wide using the charset property in the appropriate file.

Example
res.charset = "UTF8";
res.write("ÄÖÜäöüß");
// this is displayed if the brower's encoding is set to "Western"
ÄÖÜäöüß

contentType

Syntax
res.contentType = ContentTypeString

Description
The contentType of the http response can be set manually by changing the value of this Property. The default value is "text/html".

Example
res.contentType="text/plain";
res.contentType="text/xml";

data

res.data can be used to attach any property propertyName onto it to make it available in a skin via <% response.propertyName %>.

Example

== root/main.hac
res.data.title = "Test";
res.data.body = "Hello, World!";
root.renderSkin("main");


== root/main.skin
<html>
<head>
  <title><% response.title %></title>
</head>
<body>

<% response.body %>

</body>
</html>

encode()

Syntax
res.encode(String)

Description
Works similar to the global function encode() but writes the result directly to the response string buffer. Encodes a string by replacing linebreaks with <br> tags and diacritical characters as well as html tags with their equivalent html entities.

Example
res.encode("<b>Bananer växer\n minsann inte på träd.<b>");
&lt;b&gt;Bananer v&auml;xer
<br> minsann inte p&aring; tr&auml;d.&lt;/b&gt;

encodeXml()

Syntax
res.encodeXml(String)

Description
Works the same way as the global Function encodeXml(), but writes the result directly to the response string buffer.

Example
res.encodeXml("<title>Smørebrød</title>");
&lt;title&gt;Sm&amp;oslash;rebr&amp;oslash;d&lt;/title&gt;

error

Contains an internal Helma error message.

Syntax
res.error

Description
Contains a string describing an error if one should occur. If no error was detected, res.error contains an empty string. A good place for this function is a custom error page to display errors in a pretty layout.

Example
res.write(res.error);
Runtime error Syntax error detected near line 1, column 24, after in string starting with: 'function main_action (arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10) {'...

format()

Syntax
res.format(String);

Description
Encodes a string similar to encode() but keeping the markup tags and trying to avoid <br> tags where possible (e.g. in table structures).

Example
res.encode("<b>Bananer växer\n minsann inte på träd.<b>");
<b>Bananer v&auml;xer
<br> minsann inte p&aring; tr&auml;d.</b>

head

Deprectated property.

This property is deprecated and will not be supported in future releases of Helma.

Use res.data instead, by attaching the appropriate property to it.

message

Buffer a string for output.

When this property is set, its value can be retrieved either by res.message from within an action or a JavaScript file or by <% response.message %> from within a skin file.

Additionally, it will survive an HTTP redirect which can be necessary to display warnings or error messages to the user. The property's value will be cleared at latest after a redirected response was output.

redirect()

Syntax
res.redirect(UrlString);

Description
Redirects the user to the specified url immediately. The JavaScript code following this command will not be processed anymore.

Example
Here is a simple check using a hypothetic isAdmin() function to grant access to authorized people only:

if (!user.isAdmin())
   res.redirect("/main");

reset()

Syntax
res.reset();

Description
Resets the current Response StringBuffer.

Example
res.write("Writing something to the response");
// changing my mind (e.g. an error occured somewhere)
res.reset();
res.write("Actually this is what I wanted to tell you: ...");

Actually this is what I wanted to tell you: ...

setCookie()

Syntax
res.setCookie(KeyString, ValueString, NumberOfDays);

Description
Sets a Cookie on the client machine. The third number argument is optional and specifies the number of days until the cookie expires.

Example
The following can be used to "remember" users, and automatically log them in, when they return to your site.

res.setCookie("username", "michi", 10);
res.setCookie("password", "strenggeheim", 10);

title

Deprectated property.

This property is deprecated and will not be supported in future releases of Helma.

Use res.data instead, by attaching the appropriate property to it.

write()

Writes to the Response StringBuffer

Syntax
res.write(String);

Description
Transforms the passed argument to a string (only if necessary) and appends the result to the response string buffer. Throws an error if no argument or an undefined argument is passed.

Example
var now = new Date();
res.write("current time: " + now);

current time: Thu Feb 15 23:34:29 GMT+01:00 2001

writeBinary()

Syntax
res.writeBinary(javaByteArray);

Description
This function takes one argument, which must be a Java byte array. Useful when handling binary data retrieved via http file upload.

Example
var upload = req.data.fileUpload;
res.writeBinary(upload);

writeln()

Syntax
res.writeln(string)

Description
Transforms the passed argument to a string (only if necessary), appends an Html break <br> and appends the result to the response string buffer. Throws an error if no argument or an undefined argument is passed. Useful for debugging tasks.

Example
res.writeln("Hello,");
res.write("World!");
Hello,<br>
World!

Skin Object

allowMacro()

Syntax
allowMacro(String)

Description
This function is necessary to limit the range of allowed macros to be rendered to an explicit set. This is useful when text entered by non-trusted users is interpreted as skins to provide macro functions on a user-level.

Example
Two macro functions defined in a JavaScript file:
function isAllowed_macro() {
  return("Hello");
}

function isForbidden_macro() {
  return("World");
}


The action that enables one of the macros:
var str = "<% root.isAllowed %>, <% root.isForbidden %>!";
var skin = createSkin(str);
// as soon as we call allowMacro() on a skin, only those
// macros explicitely set are allowed to be evaluated.
// all others will result in an error msg.
skin.allowMacro("root.isAllowed");
renderSkin(skin);

Hello, [Macro root.isForbidden not allowed in sandbox]!

containsMacro()

Syntax
containsMacro(String)

Description
This function checks whether a skin does contain the macro specified by the string parameter. This is thus useful to make sure a user-edited skin does not contain any macro with which the application would break.

Example
var skin1 = createSkin("myMacro");
var skin2 = createSkin("<% myMacro %>");
res.writeln(skin1.containsMacro("myMacro"));
false

res.writeln(skin2.containsMacro("myMacro"));
true

User Object

lastActive()

Determine the last time of a certain user being logged in.

Syntax
user.lastActive()

Description
Returns a Date Object of the timestamp the current user was logged in the last time. Please note that you can use this function with the user prototype only, not with any user HopObject.

Example
res.write(user.lastActive())
Thu Nov 02 16:12:13 GMT+01:00 2000

login()

Syntax
UserObject.login(UserNameString, PasswordString)

Description
Returns true if the user name / password pair match the stored values in the database. Otherwise it returns false.

Example
var login = user.login("user", "pass");
if (login)
   res.write("Welcome back!");
else
   res.write("Oops, please try again...");

Welcome back!

onSince()

Syntax
userObject.onSince()

Description
Returns the date string of the time the user's session was started.

Example
var usr = getUser("Tobi");
res.write(usr.onSince());
Fri Aug 10 16:36:36 GMT+02:00 2001

register()

Syntax
userObject.register(usernameString, passwordString)

Description
Stores this user in the database using two arguments as user name and password phrase. Returns a valid user HopObject if the transaction was successful, false otherwise (e.g. if a user HopObject with the same name already exists). Additional properties can be attached to the user HopObject the usual way, then.

Example
var newUser = user.register("snoopy", "woodstock");
res.write(newUser);
HopObject snoopy

newUser.email = "snoopy@peanuts.com";
newUser.fullname = "Snoop Doggy Dogg";

touch()

Syntax
UserObject.touch()

Description
Refreshes the user's session, moving its expiration date to now plus session timeout unless it is "touched" again either by the user requesting a page or calling touch().

Example
var usr = getUser("tobi");
usr.touch();

uid

Syntax
UserObject.uid

Description
Returns the database-internal id of the current user. If the user is logged into the application uid is set, otherwise it is null.

Example
res.writeln(user);
res.writeln(user.uid);
TransientNode [session cache]
null


res.writeln(user);
res.writeln(user.uid);
HopObject tobi
tobi

XML and HTML Parsing

Syntax
getXmlDocument(XmlString)
getXmlDocument(UrlString)
getXmlDocument(java.io.InputStream)
getXmlDocument(java.io.Reader)

getHtmlDocument(HtmlString)
getHtmlDocument(UrlString)
getHtmlDocument(java.io.InputStream)
getHtmlDocument(java.io.Reader)

jdomize(DomDocument)

Description
The Xml and Html parsing functions take one parameter and try to parse it into a Dom document object. If the document could not be retrieved or contains invalid markup, the functions return null.

The Dom object can be processed according to the Java language binding for Dom Level 1.

Be sure to update your Helma 1.x installation with the patched openxml.jar file for this to work.

As an alternative to the W3C Dom Api, Dom documents may be transformed into JDOM documents using the global jdomize() function. JDom documents are far easier to handle than Dom documents. Be sure to have the jdom.jar file in your classpath for this to work.

Example
This .hac file fetches an Xml document containing news headlines and generates some simple Html output.

var xmltext = getXmlDocument("http://www.salon.at/news/lxml");
if (xmltext == null)
 res.write("Error retrieving Xml document!");
else {
 var newslist = xmltext.firstChild.childNodes;
 for (var i=0; i<newslist.length; i++) {
  var newsitem = newslist.item(i);
  // make sure we only look at <headline> elements,
  // ignoring whitespace CDATA
  if (newsitem.nodeName == "headline") {
   // get the <title> element
   var titleElem = newsitem.getElementsByTagName("title").item(0);
   // get the character data contained in it
   var title = titleElem.firstChild.nodeValue;
   // get the <url> element
   var urlElem = newsitem.getElementsByTagName("url").item(0);
   // get the actual url character data
   var url = urlElem.firstChild.nodeValue
   res.write ("<a href='"+url+"'>"+encode(title)+"</a><br>");
  }
 }
}

XML-RPC

Remote procedure calls via Xml-Rpc are very straightforward with the Hop for both client and server side.

XML-RPC Client

Description
Xml-Rpc calls are performed using a Remote object. Remote objects are created with the Url of the Xml-Rpc service. Functions of the remote Xml-Rpc service can then be called just like local functions.

To compensate for the missing exception handling, Remote objects return result wrappers which contain either the result of the remote function, or a description of the error if one occurred.

Example
var xr = new Remote("http://helma.domain.tld:5056/");
var msg1 = xr.helmaorg.getXmlRpcMessage();
if (msg1.error)
   res.write(msg1.error);
else
   res.write(msg1.result);

Hello, Xml-Rpc World!

var msg2 = xr.hotelGuide.hotels.grandimperial.getXmlRpcMessage();
if (!msg2.error)
   res.write(msg2.result);

Welcome to the Grand Imperial Hotel, Vienna!

var msg3 = xr.kolin.document.comments["23"].getXmlRpcMessage();
if (!msg3.error)
   res.write(msg3.result);

Here you can write your comments.

var xr = new Remote("http://betty.userland.com/RPC2");
var state = xr.examples.getStateName(23);
if (!state.error)
   res.write(state.result);

Minnesota

XML-RPC Server

Description
The Helma Xml-Rpc server is running on port 5056 by default, or port+1 if the -p command line parameter is specified.

You can make any Helma function callable via Xml-Rpc. To do so, the function needs to be added to the XmlRpcAccess property in the app.properties file.

For example, if you have two functions, listThings() and addThing(), in the root prototype you want to call via Xml-Rpc, add the following line to the app.properties file of your application:

XmlRpcAccess = root.listThings, myprototype.addThing

Xml-Rpc function names have the application name as first element followed by an optional object path within the application and the actual function name. Thus, a function called sayHello() in the root directory of an application called myapp would result in an Xml-Rpc function name of myapp.sayHello.

There are a few things to consider when working with server side Xml-Rpc: