chg: replaced ant with gradle
This commit is contained in:
parent
cee0be52e0
commit
5cbeb9f01d
609 changed files with 87626 additions and 638 deletions
23
src/dist/apps.properties
vendored
Normal file
23
src/dist/apps.properties
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
# List of applications to start.
|
||||
# More information about this file is available at
|
||||
# http://helma.org/Documentation/Properties+Files/apps.properties/
|
||||
|
||||
|
||||
# Administrative application to manage all other apps on this server,
|
||||
# accessible via its default mountpoint at http://<host>:<port>/manage
|
||||
# and using its default repository at apps/manage
|
||||
|
||||
manage
|
||||
|
||||
|
||||
# More complex example of an application with custom configuration:
|
||||
|
||||
welcome
|
||||
welcome.mountpoint = /
|
||||
welcome.repository.0 = apps/welcome/code/
|
||||
welcome.repository.1 = modules/tools
|
||||
welcome.static = apps/welcome/static
|
||||
welcome.staticMountpoint = /static
|
||||
welcome.staticHome = index.html,default.html
|
||||
welcome.staticIndex = true
|
||||
welcome.uploadLimit = 2048
|
67
src/dist/apps/manage/Application/actions.js
vendored
Normal file
67
src/dist/apps/manage/Application/actions.js
vendored
Normal file
|
@ -0,0 +1,67 @@
|
|||
/**
|
||||
* renders AppManager
|
||||
*/
|
||||
function main_action() {
|
||||
if (checkAddress() == false)
|
||||
return;
|
||||
if (checkAuth(this) == false)
|
||||
return;
|
||||
|
||||
res.data.body = this.renderSkinAsString("main");
|
||||
renderSkin("global");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* prints session- and thread-stats for mrtg-tool
|
||||
* doesn't check username or password, so that we don't have
|
||||
* to write them cleartext in a mrtg-configfile but checks the
|
||||
* remote address.
|
||||
*/
|
||||
function mrtg_action() {
|
||||
if (checkAddress() == false)
|
||||
return;
|
||||
|
||||
if (this.isActive() == false) {
|
||||
res.write("0\n0\n0\n0\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (req.data.action == "sessions") {
|
||||
|
||||
res.write(this.sessions.size());
|
||||
res.write("\n0\n0\n0\n");
|
||||
|
||||
} else if (req.data.action == "threads") {
|
||||
|
||||
res.write(this.countActiveEvaluators() + "\n");
|
||||
res.write(this.countEvaluators() + "\n");
|
||||
res.write("0\n0\n");
|
||||
|
||||
} else if (req.data.action == "cache") {
|
||||
|
||||
res.write(this.getCacheUsage() + "\n");
|
||||
res.write(this.getProperty("cachesize", "1000") + "\n");
|
||||
res.write("0\n0\n");
|
||||
|
||||
} else if (req.data.action == "requests") {
|
||||
|
||||
// res.write (
|
||||
|
||||
} else {
|
||||
res.write("0\n0\n0\n0\n");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* performs a redirect to the public site
|
||||
* (workaround, we can't access application object from docapplication for some reason)
|
||||
* @see application.url_macro
|
||||
*/
|
||||
function redirectpublic_action() {
|
||||
if (checkAddress() == false) return;
|
||||
if (checkAuth(this) == false) return;
|
||||
|
||||
res.redirect(this.url_macro());
|
||||
}
|
42
src/dist/apps/manage/Application/functions.js
vendored
Normal file
42
src/dist/apps/manage/Application/functions.js
vendored
Normal file
|
@ -0,0 +1,42 @@
|
|||
/**
|
||||
* construct an application object so that we can use
|
||||
* skins for non-active applications too
|
||||
* @arg name
|
||||
*/
|
||||
function constructor(name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* return true/false to determine if application is running
|
||||
*/
|
||||
function isActive() {
|
||||
if (root.getApplication(this.name) == null)
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method used by Helma for URL composition.
|
||||
*/
|
||||
function href(action) {
|
||||
var base = root.href() + this.name + "/";
|
||||
return action ? base + action : base;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method used by Helma for URL composition.
|
||||
*/
|
||||
function getParentElement() {
|
||||
return root;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method used by Helma request path resolution.
|
||||
*/
|
||||
function getChildElement(name) {
|
||||
if (name == "api")
|
||||
return this.getDoc();
|
||||
return null;
|
||||
}
|
11
src/dist/apps/manage/Application/head.skin
vendored
Normal file
11
src/dist/apps/manage/Application/head.skin
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
<p><big>AppManager <% this.title %></big>
|
||||
<% this.description prefix="<br/>" %>
|
||||
<br/>
|
||||
->
|
||||
<a href="<% this.href action="api" %>/read">showAPI</a> |
|
||||
<a href="<% this.href action="api" %>/render">renderAPI</a> |
|
||||
<a href="<% this.url %>">public</a> |
|
||||
<a href="<% root.href action="main" %>?app=<% this.title %>&action=flush">flush</a> |
|
||||
<a href="<% root.href action="main" %>?app=<% this.title %>&action=restart">restart</a> |
|
||||
<a href="<% root.href action="main" %>?app=<% this.title %>&action=stop">stop</a>
|
||||
</p>
|
210
src/dist/apps/manage/Application/macros.js
vendored
Normal file
210
src/dist/apps/manage/Application/macros.js
vendored
Normal file
|
@ -0,0 +1,210 @@
|
|||
/**
|
||||
* macro rendering a skin
|
||||
* @param name name of skin
|
||||
*/
|
||||
function skin_macro(par) {
|
||||
if (par && par.name) {
|
||||
this.renderSkin(par.name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* macro-wrapper for href-function
|
||||
* @param action name of action to call on this prototype, default main
|
||||
*/
|
||||
function href_macro(par) {
|
||||
return this.href((par && par.action) ? par.action : "main");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Macro returning the URL of an application.
|
||||
* using absoluteURI if set in app.properties, otherwise we go for the href calculated by
|
||||
* the application (which is using baseURI if set)
|
||||
*/
|
||||
function url_macro() {
|
||||
var str = this.getProperty("absoluteuri");
|
||||
if (str != null && str != "") {
|
||||
return str;
|
||||
} else {
|
||||
return this.getRootHref();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Macro returning the title of an application
|
||||
*/
|
||||
function title_macro() {
|
||||
var title = this.name;
|
||||
return(title);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Macro rendering a description of an application from a
|
||||
* file called description.txt or doc.html located in the
|
||||
* app's root. Limits description to 200 chars.
|
||||
* @param Object Macro parameter object
|
||||
*/
|
||||
function description_macro(param) {
|
||||
var str = "";
|
||||
var appHome = this.getAppDir();
|
||||
var f = new File(this.getAppDir().toString(), "description.txt");
|
||||
if (!f.exists())
|
||||
f = new File(this.getAppDir().toString(), "doc.html");
|
||||
if (f.exists()) {
|
||||
str = f.readAll();
|
||||
if (str.length > 200)
|
||||
str = str.substring(0, 200) + "...";
|
||||
}
|
||||
return(str);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Macro returning the server's uptime nicely formatted
|
||||
*/
|
||||
function uptime_macro() {
|
||||
return formatAge((java.lang.System.currentTimeMillis() - this.starttime) / 1000);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Macro returning the number of active sessions.
|
||||
* parameter used by global.formatCount
|
||||
* @see global.formatCount
|
||||
*/
|
||||
function countSessions_macro(par) {
|
||||
if (this.isActive() == true)
|
||||
return this.sessions.size() + formatCount(this.sessions.size(), par);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Macro returning the number of logged-in users or the list
|
||||
* of logged-in users if http-parameter showusers is set to true.
|
||||
* Makes use of this.countUsers_macro and this.listUsers_macro
|
||||
* @see application.countUsers_macro
|
||||
* @see application.listUsers_macro
|
||||
*/
|
||||
function users_macro(par) {
|
||||
if (req.data.showusers == "true") {
|
||||
this.listUsers_macro(par);
|
||||
} else {
|
||||
this.countUsers_macro(par);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Macro returning the number of logged-in users if application
|
||||
* is active
|
||||
* parameter used by global.formatCount
|
||||
* @see global.formatCount
|
||||
*/
|
||||
function countUsers_macro(par) {
|
||||
if (this.isActive() == true)
|
||||
return this.activeUsers.size() + formatCount(this.activeUsers.size(), par);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Macro rendering the list of logged-in users if application is active
|
||||
* @param separator html-code written between elements
|
||||
*/
|
||||
function listUsers_macro(par) {
|
||||
var separator = (par && par.separator) ? par.separator : ", ";
|
||||
if (this.activeUsers.size() == 0)
|
||||
return "";
|
||||
var users = this.activeUsers.iterator();
|
||||
while (users.hasNext()) {
|
||||
res.write(users.next().__name__);
|
||||
if (users.hasNext()) {
|
||||
res.write(separator);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Macro returning the number of active evaluators (=threads)
|
||||
*/
|
||||
function countActiveEvaluators_macro() {
|
||||
return this.countActiveEvaluators();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Macro returning the number of free evaluators (=threads)
|
||||
*/
|
||||
function countFreeEvaluators_macro() {
|
||||
return this.countFreeEvaluators();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Macro returning the current number of objects in the cache
|
||||
*/
|
||||
function cacheusage_macro(param) {
|
||||
return this.getCacheUsage();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Macro returning the number of objects allowed in the cache
|
||||
*/
|
||||
function cachesize_macro(param) {
|
||||
return this.getProperty("cachesize", "1000");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Macro formatting the number of requests in the last 5 minutes
|
||||
*/
|
||||
function requestCount_macro(par) {
|
||||
if (app.data.stat == null || app.data.stat[this.name] == null)
|
||||
return "not available";
|
||||
if (this.isActive()) {
|
||||
var obj = app.data.stat[this.name];
|
||||
return obj.requestCount + formatCount(obj.requestCount, par);
|
||||
} else {
|
||||
return 0 + formatCount(0, par);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Macro formatting the number of errors in the last 5 minutes
|
||||
*/
|
||||
function errorCount_macro(par) {
|
||||
if (app.data.stat == null || app.data.stat[this.name] == null)
|
||||
return "not available";
|
||||
if (this.isActive()) {
|
||||
var obj = app.data.stat[this.name];
|
||||
return obj.errorCount + formatCount(obj.errorCount, par);
|
||||
} else {
|
||||
return 0 + formatCount(0, par);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Macro formatting app.properties
|
||||
*/
|
||||
function properties_macro(par) {
|
||||
formatProperties(this.getProperties(), par);
|
||||
}
|
||||
|
||||
|
||||
function repositories_macro(param) {
|
||||
var repos = this.getRepositories().iterator();
|
||||
while (repos.hasNext())
|
||||
res.writeln(repos.next().getName());
|
||||
}
|
||||
|
62
src/dist/apps/manage/Application/main.skin
vendored
Normal file
62
src/dist/apps/manage/Application/main.skin
vendored
Normal file
|
@ -0,0 +1,62 @@
|
|||
<% this.skin name="head" %>
|
||||
<table width="100%" border="0" cellspacing="0" cellpadding="3">
|
||||
<tr>
|
||||
<td class="list_separator" colspan="3">application</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<table border="0" cellspacing="0" cellpadding="3">
|
||||
<tr>
|
||||
<td class="list_property" align="left">active sessions</td>
|
||||
<td class="list_property" width="5"> </td>
|
||||
<td class="list_property" align="left"><% this.countSessions %></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="list_property" align="left"><a href="<% this.href action="main" %>?showusers=true">logged-in users</a></td>
|
||||
<td class="list_property" width="5"> </td>
|
||||
<td class="list_property" align="left"><% this.users %> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="list_property" align="left">active evaluators</td>
|
||||
<td class="list_property" width="5"> </td>
|
||||
<td class="list_property" align="left"><% this.countActiveEvaluators %></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="list_property" align="left">free evaluators</td>
|
||||
<td class="list_property" width="5"> </td>
|
||||
<td class="list_property" align="left"><% this.countFreeEvaluators %></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="list_property" align="left">requests / 5 min</td>
|
||||
<td class="list_property" width="5"> </td>
|
||||
<td class="list_property" align="left"><% this.requestCount %></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="list_property" align="left">errors / 5 min</td>
|
||||
<td class="list_property" width="5"> </td>
|
||||
<td class="list_property" align="left"><% this.errorCount %></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="list_property" align="left">cache usage</td>
|
||||
<td class="list_property" width="5"> </td>
|
||||
<td class="list_property" align="left"><% this.cacheusage %> objects of <% this.cachesize %></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="list_property" align="left">uptime</td>
|
||||
<td class="list_property" width="5"> </td>
|
||||
<td class="list_property" align="left"><% this.uptime %></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="list_property" align="left" valign="top">repositories</td>
|
||||
<td class="list_property" width="5"> </td>
|
||||
<td class="list_property" align="left"><% this.repositories %></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<table width="100%" border="0" cellspacing="0" cellpadding="3">
|
||||
<tr>
|
||||
<td class="list_separator" colspan="3">app.properties</td>
|
||||
</tr>
|
||||
<% this.properties itemprefix='<tr><td class="list_property" valign="top">' separator='</td><td class="list_property" width="5"> </td><td class="list_property" valign="top">' itemsuffix='</td></tr>' %>
|
||||
</table>
|
||||
|
18
src/dist/apps/manage/Application/navig_active.skin
vendored
Normal file
18
src/dist/apps/manage/Application/navig_active.skin
vendored
Normal file
|
@ -0,0 +1,18 @@
|
|||
<div class="list_apps">
|
||||
<b><a href="<% this.href action="main" %>"><% this.title %></a></b><br />
|
||||
<small><% this.countSessions singular=" Session" plural=" Sessions" %>,
|
||||
<% this.requestCount singular=" Request" plural=" Requests" %>/5min</small>
|
||||
<div align="right">
|
||||
<table border="0" cellspacing="0" cellpadding="0">
|
||||
<tr>
|
||||
<td align="right" valign="top"><small style="font-size:9px;">
|
||||
<a href="<% this.href action="api" %>/read">showAPI</a> |
|
||||
<a href="<% this.href action="api" %>/render">renderAPI</a> |
|
||||
<a href="<% this.url %>">public</a> |
|
||||
<a href="<% root.href action="main" %>?app=<% this.title %>&action=flush">flush</a> |
|
||||
<a href="<% root.href action="main" %>?app=<% this.title %>&action=restart">restart</a>
|
||||
</small></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
10
src/dist/apps/manage/Application/navig_disabled.skin
vendored
Normal file
10
src/dist/apps/manage/Application/navig_disabled.skin
vendored
Normal file
|
@ -0,0 +1,10 @@
|
|||
<div class="list_apps">
|
||||
<table border="0" cellspacing="0" cellpadding="0" align="right">
|
||||
<tr>
|
||||
<td align="right" valign="top"><small>
|
||||
<a href="<% root.href action="main" %>?app=<% this.title %>&action=start">start</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<b><% this.title %></b>
|
||||
</div>
|
59
src/dist/apps/manage/DocApplication/actions.js
vendored
Normal file
59
src/dist/apps/manage/DocApplication/actions.js
vendored
Normal file
|
@ -0,0 +1,59 @@
|
|||
function read_action() {
|
||||
this.readApplication();
|
||||
res.redirect(this.href("main"));
|
||||
}
|
||||
|
||||
function main_action() {
|
||||
if (checkAddress() == false)
|
||||
return;
|
||||
if (checkAuth(this.getParentElement()) == false)
|
||||
return;
|
||||
this.renderSkin("frameset");
|
||||
}
|
||||
|
||||
|
||||
function prototypes_action() {
|
||||
if (checkAddress() == false)
|
||||
return;
|
||||
if (checkAuth(this.getParentElement()) == false)
|
||||
return;
|
||||
res.data.body = this.renderSkinAsString("prototypes");
|
||||
renderSkin("api");
|
||||
}
|
||||
|
||||
|
||||
function summary_action() {
|
||||
if (checkAddress() == false)
|
||||
return;
|
||||
if (checkAuth(this.getParentElement()) == false)
|
||||
return;
|
||||
res.data.body = this.renderSkinAsString("summary");
|
||||
renderSkin("api");
|
||||
}
|
||||
|
||||
|
||||
function functionindex_action() {
|
||||
if (checkAddress() == false)
|
||||
return;
|
||||
if (checkAuth(this.getParentElement()) == false)
|
||||
return;
|
||||
res.data.body = this.renderSkinAsString("functionindex");
|
||||
renderSkin("api");
|
||||
}
|
||||
|
||||
|
||||
function render_action() {
|
||||
// set res.data.rendering, this will suppress the link back to the manage
|
||||
// console in the apidocs actions
|
||||
res.data.rendering = true;
|
||||
if (checkAddress() == false)
|
||||
return;
|
||||
if (checkAuth(this.getParentElement()) == false)
|
||||
return;
|
||||
var ct = this.renderApi();
|
||||
res.data.body = '<body>rendering API ...<br/>wrote ' + ct + ' files<br/><br/>';
|
||||
res.data.body += '<a href="' + root.href("main") + '">back to manage console</a>';
|
||||
res.data.title = "rendering helma api";
|
||||
res.data.head = renderSkinAsString("head");
|
||||
renderSkin("basic");
|
||||
}
|
31
src/dist/apps/manage/DocApplication/frameset.skin
vendored
Normal file
31
src/dist/apps/manage/DocApplication/frameset.skin
vendored
Normal file
|
@ -0,0 +1,31 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>helma api / <% this.name %></title>
|
||||
<script language="javascript"><!--
|
||||
function changePrototypeList (obj) {
|
||||
if (obj.href.indexOf (".html")>-1)
|
||||
var newhref = obj.href.substring (0, obj.href.length-9) + "list.html";
|
||||
else
|
||||
var newhref = obj.href.substring (0, obj.href.length-4) + "list";
|
||||
functions.location.href = newhref;
|
||||
}
|
||||
//--></script>
|
||||
</head>
|
||||
|
||||
<frameset cols="30%,70%">
|
||||
<frameset rows="40%,60%">
|
||||
<frame src="<% this.href action="prototypes" %>" name="prototypes">
|
||||
<frame src="<% this.hrefRoot action="list" %>" name="functions">
|
||||
</frameset>
|
||||
<frame src="<% this.href action="summary" %>" name="main">
|
||||
</frameset>
|
||||
<noframes>
|
||||
<h2>
|
||||
Frame Alert</h2>
|
||||
|
||||
<p>
|
||||
This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client.
|
||||
</noframes>
|
||||
</html>
|
||||
|
||||
|
24
src/dist/apps/manage/DocApplication/functionindex.skin
vendored
Normal file
24
src/dist/apps/manage/DocApplication/functionindex.skin
vendored
Normal file
|
@ -0,0 +1,24 @@
|
|||
|
||||
|
||||
<table width="90%" border="0" cellspacing="1" cellpadding="5">
|
||||
<tr>
|
||||
<td class="headline">
|
||||
<big class="top">Application <% this.headline %></tt></b></big><br>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<a class="navig" href="<% this.href action="summary"%>">SUMMARY</a> |
|
||||
<a class="navig" href="<% this.href action="functionindex" %>">INDEX</a> |
|
||||
<a class="navig" href="#A">A</a>|<a class="navig" href="#B">B</a>|<a class="navig" href="#C">C</a>|<a class="navig" href="#D">D</a>|<a class="navig" href="#E">E</a>|<a class="navig" href="#F">F</a>|<a class="navig" href="#G">G</a>|<a class="navig" href="#H">H</a>|<a class="navig" href="#I">I</a>|<a class="navig" href="#J">J</a>|<a class="navig" href="#K">K</a>|<a class="navig" href="#L">L</a>|<a class="navig" href="#M">M</a>|<a class="navig" href="#N">N</a>|<a class="navig" href="#O">O</a>|<a class="navig" href="#P">P</a>|<a class="navig" href="#Q">Q</a>|<a class="navig" href="#R">R</a>|<a class="navig" href="#S">S</a>|<a class="navig" href="#T">T</a>|<a class="navig" href="#U">U</a>|<a class="navig" href="#V">V</a>|<a class="navig" href="#W">W</a>|<a class="navig" href="#X">X</a>|<a class="navig" href="#Y">Y</a>|<a class="navig" href="#Z">Z</a>|
|
||||
|
||||
<table width="90%" border="0" cellspacing="1" cellpadding="5">
|
||||
<% this.functions skin="asIndexItem"
|
||||
separator="<tr><td class='mainbox'><img src='' width=0 height=0></td></tr>"
|
||||
%>
|
||||
</table>
|
||||
|
||||
<a class="navig" href="<% this.href action="summary"%>">SUMMARY</a> |
|
||||
<a class="navig" href="<% this.href action="functionindex" %>">INDEX</a> |
|
||||
<a class="navig" href="#A">A</a>|<a class="navig" href="#B">B</a>|<a class="navig" href="#C">C</a>|<a class="navig" href="#D">D</a>|<a class="navig" href="#E">E</a>|<a class="navig" href="#F">F</a>|<a class="navig" href="#G">G</a>|<a class="navig" href="#H">H</a>|<a class="navig" href="#I">I</a>|<a class="navig" href="#J">J</a>|<a class="navig" href="#K">K</a>|<a class="navig" href="#L">L</a>|<a class="navig" href="#M">M</a>|<a class="navig" href="#N">N</a>|<a class="navig" href="#O">O</a>|<a class="navig" href="#P">P</a>|<a class="navig" href="#Q">Q</a>|<a class="navig" href="#R">R</a>|<a class="navig" href="#S">S</a>|<a class="navig" href="#T">T</a>|<a class="navig" href="#U">U</a>|<a class="navig" href="#V">V</a>|<a class="navig" href="#W">W</a>|<a class="navig" href="#X">X</a>|<a class="navig" href="#Y">Y</a>|<a class="navig" href="#Z">Z</a>|
|
||||
|
97
src/dist/apps/manage/DocApplication/functions.js
vendored
Normal file
97
src/dist/apps/manage/DocApplication/functions.js
vendored
Normal file
|
@ -0,0 +1,97 @@
|
|||
/**
|
||||
* Get the prototype of any doc-object (either a prototype, a function or a tag)
|
||||
*/
|
||||
function getDocPrototype(obj) {
|
||||
var tmp = obj;
|
||||
while (tmp != null && tmp.getType() != this.PROTOTYPE) {
|
||||
tmp = tmp.getParentElement();
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a prototype of this docapplication, ie get on of the children of this object
|
||||
*/
|
||||
function getPrototype(name) {
|
||||
return this.getChildElement("prototype_" + name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method used by Helma for URL composition.
|
||||
*/
|
||||
function href(action) {
|
||||
var base = this.getParentElement().href() + "api/";
|
||||
return action ? base + action : base;
|
||||
}
|
||||
|
||||
function getDir(dir, obj) {
|
||||
dir.mkdir();
|
||||
if (obj.getType() == this.APPLICATION) {
|
||||
return dir;
|
||||
} else {
|
||||
var protoObj = this.getDocPrototype(obj);
|
||||
var dir = new File (dir, protoObj.getElementName());
|
||||
dir.mkdir();
|
||||
return dir;
|
||||
}
|
||||
}
|
||||
|
||||
function renderApi() {
|
||||
var prefix = this.href("");
|
||||
this.storePage(this, "main", "", "index.html");
|
||||
this.storePage(this, "prototypes");
|
||||
this.storePage(this, "summary");
|
||||
this.storePage(this, "functionindex");
|
||||
var ct = 4;
|
||||
var arr = this.listChildren();
|
||||
for (var i = 0; i < arr.length; i++) {
|
||||
this.storePage(arr[i], "list", "../");
|
||||
this.storePage(arr[i], "main", "../");
|
||||
ct += 2;
|
||||
var subarr = arr[i].listChildren();
|
||||
for (var j = 0; j < subarr.length; j++) {
|
||||
this.storePage(subarr[j], "main", "../", subarr[j].getElementName() + ".html");
|
||||
ct += 1;
|
||||
}
|
||||
}
|
||||
return ct;
|
||||
}
|
||||
|
||||
|
||||
function storePage(obj, action, backPath, filename) {
|
||||
if (filename == null)
|
||||
var filename = action + ".html";
|
||||
var str = this.getPage(obj, action, backPath);
|
||||
var appObj = this.getParentElement();
|
||||
var dir = new File (appObj.getAppDir().getAbsolutePath(), ".docs");
|
||||
dir = this.getDir(dir, obj);
|
||||
var f = new File (dir, filename);
|
||||
f.remove();
|
||||
f.open();
|
||||
f.write(str);
|
||||
f.close();
|
||||
app.log("wrote file " + f.getAbsolutePath());
|
||||
}
|
||||
|
||||
|
||||
function getPage(obj, action, backPath) {
|
||||
backPath = (backPath == null) ? "" : backPath;
|
||||
res.pushStringBuffer();
|
||||
eval("obj." + action + "_action ();");
|
||||
var str = res.popStringBuffer();
|
||||
// get the baseURI out of the url and replace
|
||||
// it with the given relative prefix
|
||||
// (keep anchors in regex!)
|
||||
var reg = new RegExp ("href=\"" + this.href("") + "([^\"#]+)([^\"]*)\"", "gim");
|
||||
str = str.replace(reg, "href=\"" + backPath + "$1.html$2\"");
|
||||
var reg = new RegExp ("src=\"" + this.href("") + "([^\"#]+)([^\"]*)\"", "gim");
|
||||
str = str.replace(reg, "src=\"" + backPath + "$1.html$2\"");
|
||||
// shorten links, so that function files can move up one directory
|
||||
// in the hierarchy
|
||||
var reg = new RegExp ("(prototype_[^/]+/[^/]+)/main.html", "gim");
|
||||
str = str.replace(reg, "$1.html");
|
||||
return str;
|
||||
}
|
||||
|
||||
|
3
src/dist/apps/manage/DocApplication/indexSeparator.skin
vendored
Normal file
3
src/dist/apps/manage/DocApplication/indexSeparator.skin
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
<tr><td class='headline'><a name="<% param.letter %>"><!-- --></a>
|
||||
<big><% param.letter %></big>
|
||||
</td></tr>
|
106
src/dist/apps/manage/DocApplication/macros.js
vendored
Normal file
106
src/dist/apps/manage/DocApplication/macros.js
vendored
Normal file
|
@ -0,0 +1,106 @@
|
|||
/**
|
||||
* macro rendering a skin
|
||||
* @param name name of skin
|
||||
*/
|
||||
function skin_macro(par) {
|
||||
if (par && par.name) {
|
||||
this.renderSkin(par.name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* macro-wrapper for href-function
|
||||
* @param action name of action to call on this prototype, default main
|
||||
*/
|
||||
function href_macro(param) {
|
||||
return this.href((param && param.action) ? param.action : "main");
|
||||
}
|
||||
|
||||
function comment_macro(param) {
|
||||
return renderComment(this, param);
|
||||
}
|
||||
|
||||
function content_macro(param) {
|
||||
return this.getContent();
|
||||
}
|
||||
|
||||
function tags_macro(param) {
|
||||
return renderTags(this, param);
|
||||
}
|
||||
|
||||
function location_macro(param) {
|
||||
return renderLocation(this, param);
|
||||
}
|
||||
|
||||
function link_macro(param) {
|
||||
return renderLink(this, param);
|
||||
}
|
||||
|
||||
//// END OF COPIED FUNCTIONS
|
||||
|
||||
|
||||
function linkToManage_macro(param) {
|
||||
if (res.data.rendering != true) {
|
||||
return ('<a href="' + root.href("main") + '" target="_top">back to manage console</a>');
|
||||
}
|
||||
}
|
||||
|
||||
function headline_macro(param) {
|
||||
res.write(this.getName());
|
||||
}
|
||||
|
||||
|
||||
function hrefRoot_macro(param) {
|
||||
var obj = this.getChildElement("prototype_root");
|
||||
if (obj == null) {
|
||||
var obj = this.getChildElement("prototype_Root");
|
||||
}
|
||||
if (obj != null) {
|
||||
var action = (param.action) ? param.action : "main";
|
||||
return obj.href(action);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* list all prototypes of this application
|
||||
* @param skin name of skin to render on prototype
|
||||
* @param separator
|
||||
*/
|
||||
function prototypes_macro(param) {
|
||||
var skin = (param.skin) ? param.skin : "asPrototypeList";
|
||||
var separator = (param.separator) ? param.separator : "";
|
||||
var arr = this.listChildren();
|
||||
for (var i = 0; i < arr.length; i++) {
|
||||
arr[i].renderSkin(skin);
|
||||
if (i < arr.length - 1)
|
||||
res.write(separator);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* list all methods of all prototypes, sort them alphabetically
|
||||
* @param skin name of skin to render on each method
|
||||
* @param skinSeparator name of skin to render as separator between each letters
|
||||
*/
|
||||
function functions_macro(param) {
|
||||
var skinname = (param.skin) ? param.skin : "asListItem";
|
||||
var skinIndexSeparator = (param.indexSeparator) ? param.indexSeparator : "indexSeparator";
|
||||
var separator = (param.separator) ? param.separator : "";
|
||||
var arr = this.listFunctions();
|
||||
var lastLetter = "";
|
||||
for (var i = 0; i < arr.length; i++) {
|
||||
if (arr[i].getName().substring(0, 1) != lastLetter) {
|
||||
lastLetter = arr[i].getName().substring(0, 1);
|
||||
var tmp = new Object ();
|
||||
tmp.letter = lastLetter.toUpperCase();
|
||||
this.renderSkin(skinIndexSeparator, tmp);
|
||||
}
|
||||
arr[i].renderSkin(skinname);
|
||||
if (i < arr.length - 1)
|
||||
res.write(separator);
|
||||
}
|
||||
}
|
||||
|
||||
|
10
src/dist/apps/manage/DocApplication/prototypes.skin
vendored
Normal file
10
src/dist/apps/manage/DocApplication/prototypes.skin
vendored
Normal file
|
@ -0,0 +1,10 @@
|
|||
<% this.linkToManage suffix="<br/><br/>" %>
|
||||
|
||||
<big class="top">Application <a href="<% this.href action="summary" %>" target="main"><% this.name %></a></big><br><br>
|
||||
|
||||
<% this.prototypes %>
|
||||
|
||||
|
||||
|
||||
|
||||
|
29
src/dist/apps/manage/DocApplication/summary.skin
vendored
Normal file
29
src/dist/apps/manage/DocApplication/summary.skin
vendored
Normal file
|
@ -0,0 +1,29 @@
|
|||
|
||||
|
||||
<table width="90%" border="0" cellspacing="1" cellpadding="5">
|
||||
<tr>
|
||||
<td class="headline">
|
||||
<big class="top">Application <% this.headline %></tt></b></big><br>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<a class="navig" href="<% this.href action="summary"%>">SUMMARY</a> |
|
||||
<a class="navig" href="<% this.href action="functionindex" %>">INDEX</a> |
|
||||
|
||||
|
||||
|
||||
<% this.comment encoding="html" %>
|
||||
|
||||
<hr>
|
||||
|
||||
<table width="90%" border="0" cellspacing="1" cellpadding="5">
|
||||
<% this.prototypes skin="asSummary"
|
||||
separator="<tr><td class='mainbox'><img src='' width=0 height=0></td></tr>"
|
||||
%>
|
||||
</table>
|
||||
|
||||
|
||||
<a class="navig" href="<% this.href action="summary"%>">SUMMARY</a> |
|
||||
<a class="navig" href="<% this.href action="functionindex" %>">INDEX</a> |
|
||||
|
11
src/dist/apps/manage/DocFunction/actions.js
vendored
Normal file
11
src/dist/apps/manage/DocFunction/actions.js
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
function main_action() {
|
||||
if (checkAddress() == false)
|
||||
return;
|
||||
if (checkAuth() == false)
|
||||
return;
|
||||
res.data.body = this.renderSkinAsString("main");
|
||||
renderSkin("api");
|
||||
}
|
||||
|
||||
|
||||
|
7
src/dist/apps/manage/DocFunction/asIndexItem.skin
vendored
Normal file
7
src/dist/apps/manage/DocFunction/asIndexItem.skin
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
<tr><td>
|
||||
<% this.link handler="false" %>
|
||||
- <% this.type %> in <% docprototype.name %>
|
||||
<br/>
|
||||
<% this.comment length="200" %>
|
||||
</td></tr>
|
||||
|
5
src/dist/apps/manage/DocFunction/asLargeListItem.skin
vendored
Normal file
5
src/dist/apps/manage/DocFunction/asLargeListItem.skin
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
<tr><td>
|
||||
<a href="<% this.href action="main" %>" target="main"><% this.link %></a><br/>
|
||||
<% this.comment length="200" %>
|
||||
</td></tr>
|
||||
|
8
src/dist/apps/manage/DocFunction/asLargeListItemSkin.skin
vendored
Normal file
8
src/dist/apps/manage/DocFunction/asLargeListItemSkin.skin
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
<tr><td>
|
||||
<a href="<% this.href action="main" %>" target="main"><% this.link %></a><br/>
|
||||
<% this.comment length="200" %>
|
||||
<% this.skinparameters separator=", "%>
|
||||
</td></tr>
|
||||
|
||||
|
||||
|
2
src/dist/apps/manage/DocFunction/asListItem.skin
vendored
Normal file
2
src/dist/apps/manage/DocFunction/asListItem.skin
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
<% this.link %><br>
|
||||
|
1
src/dist/apps/manage/DocFunction/asParentListItem.skin
vendored
Normal file
1
src/dist/apps/manage/DocFunction/asParentListItem.skin
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
<% this.link %>
|
10
src/dist/apps/manage/DocFunction/functions.js
vendored
Normal file
10
src/dist/apps/manage/DocFunction/functions.js
vendored
Normal file
|
@ -0,0 +1,10 @@
|
|||
/**
|
||||
* Method used by Helma for URL composition.
|
||||
*/
|
||||
function href(action) {
|
||||
var base = this.getParentElement().href()
|
||||
+ this.getElementName() + "/";
|
||||
return action ? base + action : base;
|
||||
}
|
||||
|
||||
|
150
src/dist/apps/manage/DocFunction/macros.js
vendored
Normal file
150
src/dist/apps/manage/DocFunction/macros.js
vendored
Normal file
|
@ -0,0 +1,150 @@
|
|||
/**
|
||||
* macro rendering a skin
|
||||
* @param name name of skin
|
||||
*/
|
||||
function skin_macro(par) {
|
||||
if (par && par.name) {
|
||||
this.renderSkin(par.name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* macro-wrapper for href-function
|
||||
* @param action name of action to call on this prototype, default main
|
||||
*/
|
||||
function href_macro(param) {
|
||||
return this.href((param && param.action) ? param.action : "main");
|
||||
}
|
||||
|
||||
function comment_macro(param) {
|
||||
return renderComment(this, param);
|
||||
}
|
||||
function content_macro(param) {
|
||||
return this.getContent();
|
||||
}
|
||||
function tags_macro(param) {
|
||||
return renderTags(this, param);
|
||||
}
|
||||
function location_macro(param) {
|
||||
return renderLocation(this, param);
|
||||
}
|
||||
function link_macro(param) {
|
||||
return renderLink(this, param);
|
||||
}
|
||||
|
||||
//// END OF COPIED FUNCTIONS
|
||||
|
||||
|
||||
function headline_macro(param) {
|
||||
var p = this.getParentElement();
|
||||
var handler = (p != null) ? p.getName() : "";
|
||||
if (this.getType() == this.ACTION) {
|
||||
res.write("/" + this.getName());
|
||||
} else if (this.getType() == this.FUNCTION) {
|
||||
if (handler != "" && handler != "global")
|
||||
res.write(handler + ".");
|
||||
res.write(this.getName() + " (");
|
||||
var arr = this.listParameters();
|
||||
for (var i = 0; i < arr.length; i++) {
|
||||
res.write(arr[i]);
|
||||
if (i < arr.length - 1) {
|
||||
res.write(", ");
|
||||
}
|
||||
}
|
||||
res.write(")");
|
||||
} else if (this.getType() == this.MACRO) {
|
||||
res.write("<% ");
|
||||
if (handler != "" && handler != "global")
|
||||
res.write(handler + ".");
|
||||
var name = this.getName();
|
||||
if (name.indexOf("_macro") > -1)
|
||||
name = name.substring(0, name.length - 6);
|
||||
res.write(name);
|
||||
res.write(" %>");
|
||||
} else if (this.getType() == this.SKIN) {
|
||||
if (handler != "" && handler != "global")
|
||||
res.write(handler + "/");
|
||||
res.write(this.getName());
|
||||
res.write(".skin");
|
||||
} else if (this.getType() == this.PROPERTIES) {
|
||||
res.write(this.getName());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function skinparameters_macro(param) {
|
||||
if (this.getType() == this.SKIN) {
|
||||
this.parameters_macro(param);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function parameters_macro(param) {
|
||||
var separator = (param.separator) ? param.separator : ", ";
|
||||
var arr = this.listParameters();
|
||||
for (var i = 0; i < arr.length; i++) {
|
||||
res.write(arr[i]);
|
||||
if (i < arr.length - 1)
|
||||
res.write(separator);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function type_macro(param) {
|
||||
return this.getTypeName();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* macro returning nicely formatted sourcecode of this method.
|
||||
* code is encoded, >% %<-tags are colorcoded, line numbers are added
|
||||
*/
|
||||
function source_macro(param) {
|
||||
var sourcecode = this.getContent();
|
||||
if (param.as == "highlighted") {
|
||||
|
||||
sourcecode = encode(sourcecode);
|
||||
|
||||
// highlight macro tags
|
||||
r = new RegExp("<%", "gim");
|
||||
sourcecode = sourcecode.replace(r, '<font color="#aa3300"><%');
|
||||
|
||||
r = new RegExp("%>", "gim");
|
||||
sourcecode = sourcecode.replace(r, '%></font>');
|
||||
|
||||
// highlight js-comments
|
||||
r = new RegExp("^([ \\t]*//.*)", "gm");
|
||||
sourcecode = sourcecode.replace(r, '<font color="#33aa00">$1</font>');
|
||||
|
||||
// highlight quotation marks, but not for skins
|
||||
if (this.getTypeName() != "Skin") {
|
||||
r = new RegExp("(".*?")", "gm");
|
||||
sourcecode = sourcecode.replace(r, '<font color="#9999aa">$1</font>');
|
||||
r = new RegExp("(\'[\']*\')", "gm");
|
||||
sourcecode = sourcecode.replace(r, '<font color="#9999aa">$1</font>');
|
||||
}
|
||||
|
||||
// remove all CR and LF, just <br> remains
|
||||
var r = new RegExp("[\\r\\n]", "gm");
|
||||
sourcecode = sourcecode.replace(r, "");
|
||||
|
||||
var arr = sourcecode.split("<br />");
|
||||
var line = this.getStartLine ? this.getStartLine() : 1;
|
||||
for (var i = 0; i < arr.length; i++) {
|
||||
res.write('<font color="#aaaaaa">' + (line++) + ':</font> ');
|
||||
if (i < 99) {
|
||||
res.write(' ');
|
||||
}
|
||||
if (i < 9) {
|
||||
res.write(' ');
|
||||
}
|
||||
res.write(arr[i] + "\n");
|
||||
}
|
||||
|
||||
} else {
|
||||
res.write(sourcecode);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
34
src/dist/apps/manage/DocFunction/main.skin
vendored
Normal file
34
src/dist/apps/manage/DocFunction/main.skin
vendored
Normal file
|
@ -0,0 +1,34 @@
|
|||
<table width="90%" border="0" cellspacing="1" cellpadding="5">
|
||||
<tr>
|
||||
<td class="headline">
|
||||
<big><tt><% this.headline %></tt></big><br>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="mainbox">
|
||||
<% this.comment suffix="<br><br>" %>
|
||||
<% this.skinparameters prefix="general parameters used in this skin:<ul><li><code>" separator="</code><li><code>" suffix="</code></ul><br>" %>
|
||||
<ul>
|
||||
<% this.tags type="param" skin="parameter" %>
|
||||
<% this.tags type="return" skin="return" %>
|
||||
<% this.tags type="author" skin="author" %>
|
||||
<% this.tags type="see" skin="see" %>
|
||||
<% this.tags type="deprecated" skin="deprecated" %>
|
||||
<% this.tags type="overrides" skin="overrides" %>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<table width="90%" border="0" cellspacing="1" cellpadding="5">
|
||||
<tr>
|
||||
<td>Sourcecode in <% this.location %>:
|
||||
<pre><% this.source as="highlighted" %></pre>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
|
||||
|
18
src/dist/apps/manage/DocPrototype/actions.js
vendored
Normal file
18
src/dist/apps/manage/DocPrototype/actions.js
vendored
Normal file
|
@ -0,0 +1,18 @@
|
|||
function list_action() {
|
||||
if (checkAddress() == false)
|
||||
return;
|
||||
if (checkAuth() == false)
|
||||
return;
|
||||
res.data.body = this.renderSkinAsString("list");
|
||||
renderSkin("api");
|
||||
}
|
||||
|
||||
function main_action() {
|
||||
if (checkAddress() == false)
|
||||
return;
|
||||
if (checkAuth() == false)
|
||||
return;
|
||||
res.data.body = this.renderSkinAsString("main");
|
||||
renderSkin("api");
|
||||
}
|
||||
|
1
src/dist/apps/manage/DocPrototype/asInheritanceLink.skin
vendored
Normal file
1
src/dist/apps/manage/DocPrototype/asInheritanceLink.skin
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
extends Prototype <a href="<% this.href action="list" %>"><% this.name %></a>
|
16
src/dist/apps/manage/DocPrototype/asParentList.skin
vendored
Normal file
16
src/dist/apps/manage/DocPrototype/asParentList.skin
vendored
Normal file
|
@ -0,0 +1,16 @@
|
|||
|
||||
<tr><td class='headline'><b>Inherited from prototype <% this.link %>:</b><br></td></tr>
|
||||
|
||||
<tr><td>
|
||||
|
||||
<% this.methods separator=", " filter="actions" skin="asParentListItem" prefix="<b>Actions: </b>" suffix="<br/>" %>
|
||||
<% this.methods separator=", " filter="functions" skin="asParentListItem" prefix="<b>Functions: </b>" suffix="<br/>" %>
|
||||
<% this.methods separator=", " filter="macros" skin="asParentListItem" prefix="<b>Macros: </b>" suffix="<br/>" %>
|
||||
<% this.methods separator=", " filter="skins" skin="asParentListItem" prefix="<b>Skins: </b>" suffix="<br/>" %>
|
||||
|
||||
</td></tr>
|
||||
|
||||
|
||||
|
||||
|
||||
|
10
src/dist/apps/manage/DocPrototype/asPrototypeList.skin
vendored
Normal file
10
src/dist/apps/manage/DocPrototype/asPrototypeList.skin
vendored
Normal file
|
@ -0,0 +1,10 @@
|
|||
|
||||
<a href="<% this.href action="main" %>" onClick="parent.changePrototypeList(this);" target="main"><% this.name %></a>
|
||||
|
||||
<%
|
||||
this.inheritance action="main" target="main"
|
||||
onClick="parent.changePrototypeList(this);" hopobject="false"
|
||||
prefix=" (extends " suffix=")"
|
||||
%>
|
||||
|
||||
<br />
|
4
src/dist/apps/manage/DocPrototype/asSummary.skin
vendored
Normal file
4
src/dist/apps/manage/DocPrototype/asSummary.skin
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
<tr><td>
|
||||
<a href="<% this.href action="main" %>"><% this.name %></a><br/>
|
||||
<% this.comment length="200" %>
|
||||
</td></tr>
|
30
src/dist/apps/manage/DocPrototype/functions.js
vendored
Normal file
30
src/dist/apps/manage/DocPrototype/functions.js
vendored
Normal file
|
@ -0,0 +1,30 @@
|
|||
function translateType(filter) {
|
||||
if (filter == "actions")
|
||||
return Packages.helma.doc.DocElement.ACTION;
|
||||
else if (filter == "functions")
|
||||
return Packages.helma.doc.DocElement.FUNCTION;
|
||||
else if (filter == "macros")
|
||||
return Packages.helma.doc.DocElement.MACRO;
|
||||
else if (filter == "skins")
|
||||
return Packages.helma.doc.DocElement.SKIN;
|
||||
else if (filter == "properties")
|
||||
return Packages.helma.doc.DocElement.PROPERTIES;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the application we're part of.
|
||||
*/
|
||||
function getApplication() {
|
||||
return this.getParentElement();
|
||||
}
|
||||
|
||||
/**
|
||||
* Method used by Helma for URL composition.
|
||||
*/
|
||||
function href(action) {
|
||||
var base = this.getParentElement().href()
|
||||
+ this.getElementName() + "/";
|
||||
return action ? base + action : base;
|
||||
}
|
10
src/dist/apps/manage/DocPrototype/list.skin
vendored
Normal file
10
src/dist/apps/manage/DocPrototype/list.skin
vendored
Normal file
|
@ -0,0 +1,10 @@
|
|||
<big>Prototype <a href="<% this.href action="main" %>" target="main"><% this.name %></a></big><br/>
|
||||
<% this.inheritance action="list" %>
|
||||
<% this.inheritance deep="true" hopobject="true" action="main" target="main" onClick="parent.changePrototypeList(this);" separator=", " prefix="extends: " suffix="<br>" %><br>
|
||||
|
||||
|
||||
<% this.methods filter="actions" skin="asListItem" prefix="<p><b>Actions:</b><br/>" suffix="</p>" %>
|
||||
<% this.methods filter="functions" skin="asListItem" prefix="<p><b>Functions:</b><br/>" suffix="</p>" %>
|
||||
<% this.methods filter="macros" skin="asListItem" prefix="<p><b>Macros:</b><br/>" suffix="</p>" %>
|
||||
<% this.methods filter="skins" skin="asListItem" prefix="<p><b>Skins:</b><br/>" suffix="</p>" %>
|
||||
|
165
src/dist/apps/manage/DocPrototype/macros.js
vendored
Normal file
165
src/dist/apps/manage/DocPrototype/macros.js
vendored
Normal file
|
@ -0,0 +1,165 @@
|
|||
/**
|
||||
* macro rendering a skin
|
||||
* @param name name of skin
|
||||
*/
|
||||
function skin_macro(par) {
|
||||
if (par && par.name) {
|
||||
this.renderSkin(par.name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* macro-wrapper for href-function
|
||||
* @param action name of action to call on this prototype, default main
|
||||
*/
|
||||
function href_macro(param) {
|
||||
return this.href((param && param.action) ? param.action : "main");
|
||||
}
|
||||
|
||||
function comment_macro(param) {
|
||||
return renderComment(this, param);
|
||||
}
|
||||
|
||||
function content_macro(param) {
|
||||
return this.getContent();
|
||||
}
|
||||
|
||||
function tags_macro(param) {
|
||||
return renderTags(this, param);
|
||||
}
|
||||
|
||||
function location_macro(param) {
|
||||
return renderLocation(this, param);
|
||||
}
|
||||
|
||||
function link_macro(param) {
|
||||
return renderLink(this, param);
|
||||
}
|
||||
|
||||
//// END OF COPIED FUNCTIONS
|
||||
|
||||
|
||||
function headline_macro(param) {
|
||||
res.write(this.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* macro formatting list of methods of this prototype
|
||||
* @param filter actions | functions | macros | skins
|
||||
* @param skin skin to apply to the docfunction object
|
||||
* @param separator
|
||||
* @param desc Description that is passed on to the called skin
|
||||
*/
|
||||
function methods_macro(param) {
|
||||
var skinname = (param.skin) ? param.skin : "list";
|
||||
var separator = (param.separator) ? param.separator : "";
|
||||
var arr = this.listChildren();
|
||||
var type = this.translateType(param.filter);
|
||||
var sb = new java.lang.StringBuffer ();
|
||||
for (var i = 0; i < arr.length; i++) {
|
||||
if (arr[i].getType() == type) {
|
||||
sb.append(arr[i].renderSkinAsString(skinname, param));
|
||||
sb.append(separator);
|
||||
}
|
||||
}
|
||||
var str = sb.toString();
|
||||
if (str.length > 0)
|
||||
return str.substring(0, str.length - separator.length);
|
||||
else
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
function inheritance_macro(param) {
|
||||
var action = param.action ? param.action : "main";
|
||||
var target = param.target ? ('target="' + param.target + '" ') : '';
|
||||
var obj = this.getParentPrototype();
|
||||
if (obj != null) {
|
||||
obj = this.inheritanceUtil(obj, param);
|
||||
}
|
||||
if (param.deep == "true") {
|
||||
while (obj != null) {
|
||||
obj = this.inheritanceUtil(obj, param);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function inheritanceUtil(obj, param) {
|
||||
if (obj.getName() == "hopobject" && param.hopobject != "true")
|
||||
return null;
|
||||
var tmp = new Object ();
|
||||
for (var i in param)
|
||||
tmp[i] = param[i];
|
||||
tmp.href = obj.href((param.action) ? param.action : "main");
|
||||
delete tmp.hopobject;
|
||||
delete tmp.action;
|
||||
delete tmp.deep;
|
||||
delete tmp.separator;
|
||||
res.write(renderLinkTag(tmp));
|
||||
res.write(obj.getName() + "</a>");
|
||||
if (obj.getParentPrototype())
|
||||
res.write(param.separator);
|
||||
return obj.getParentPrototype();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* loops through the parent prototypes and renders a skin on each
|
||||
* if it has got any functions.
|
||||
* @param skin
|
||||
*/
|
||||
function parentPrototype_macro(param) {
|
||||
var skinname = (param.skin) ? param.skin : "asParentList";
|
||||
var obj = this.getParentPrototype();
|
||||
while (obj != null) {
|
||||
if (obj.listChildren().length > 0) {
|
||||
obj.renderSkin(skinname);
|
||||
}
|
||||
obj = obj.getParentPrototype();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* macro rendering a skin depending on wheter this prototype has got
|
||||
* type-properties or not.
|
||||
* @param skin
|
||||
*/
|
||||
function typeProperties_macro(param) {
|
||||
var props = this.getTypeProperties();
|
||||
var iter = props.getResources();
|
||||
while (iter.hasNext()) {
|
||||
var tmp = this.renderTypePropertiesResource(iter.next(), props);
|
||||
var skinname = (param.skinname) ? param.skinname : "typeproperties";
|
||||
this.renderSkin(skinname, tmp);
|
||||
}
|
||||
}
|
||||
|
||||
function renderTypePropertiesResource(res, props) {
|
||||
if (res.getContent() != "") {
|
||||
var sb = new java.lang.StringBuffer ();
|
||||
// map of all mappings....
|
||||
var mappings = props.getMappings();
|
||||
// parse type.properties linewise:
|
||||
var arr = res.getContent().split("\n");
|
||||
for (var i = 0; i < arr.length; i++) {
|
||||
arr [i] = arr[i].trim();
|
||||
// look up in mappings table if line matches:
|
||||
for (var e = mappings.keys(); e.hasMoreElements();) {
|
||||
var key = e.nextElement();
|
||||
var reg = new RegExp ('^' + key + '\\s');
|
||||
if (arr[i].match(reg)) {
|
||||
// it matched, wrap line in a link to that prototype:
|
||||
var docProtoObj = this.getApplication().getPrototype(mappings.getProperty(key));
|
||||
if (docProtoObj != null) {
|
||||
arr[i] = '<a href="' + docProtoObj.href("main") + '#typeproperties">' + arr[i] + '</a>';
|
||||
}
|
||||
}
|
||||
}
|
||||
sb.append(arr[i] + "\n");
|
||||
}
|
||||
var tmp = new Object ();
|
||||
tmp.content = sb.toString();
|
||||
tmp.source = res.getName();
|
||||
return tmp;
|
||||
}
|
||||
}
|
81
src/dist/apps/manage/DocPrototype/main.skin
vendored
Normal file
81
src/dist/apps/manage/DocPrototype/main.skin
vendored
Normal file
|
@ -0,0 +1,81 @@
|
|||
<table width="90%" border="0" cellspacing="1" cellpadding="5">
|
||||
<tr>
|
||||
<td class="headline">
|
||||
<big><tt>Prototype <% this.headline %></tt></big><br>
|
||||
<% this.inheritance deep="true" hopobject="true" action="main" target="main" onClick="parent.changePrototypeList(this);" separator=", " prefix="extends: " suffix="<br>" %>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<a class="navig" href="#actions">ACTIONS</a> |
|
||||
<a class="navig" href="#functions">FUNCTIONS</a> |
|
||||
<a class="navig" href="#macros">MACROS</a> |
|
||||
<a class="navig" href="#skins">SKINS</a> |
|
||||
<a class="navig" href="#typeproperties">TYPE.PROPERTIES</a>
|
||||
|
||||
<br/><br/>
|
||||
|
||||
|
||||
<table width="90%" border="0" cellspacing="1" cellpadding="5">
|
||||
<tr>
|
||||
<td class="mainbox">
|
||||
<% this.comment suffix="<br><br>" %>
|
||||
<ul>
|
||||
<% this.tags type="author" skin="author" %>
|
||||
<% this.tags type="see" skin="see" %>
|
||||
<% this.tags type="deprecated" skin="deprecated" %>
|
||||
<% this.tags type="overrides" skin="overrides" %>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<table width="90%" border="0" cellspacing="1" cellpadding="3">
|
||||
|
||||
<% this.methods separator="<tr><td class='mainbox'><img src='' width=0 height=0></td></tr>"
|
||||
filter="actions"
|
||||
skin="asLargeListItem"
|
||||
prefix="<tr><td class='headline'>Actions<a name='actions'><!-- --></a></td></tr>"
|
||||
suffix="<tr><td height='8'> </td></tr>"
|
||||
%>
|
||||
|
||||
<% this.methods separator="<tr><td class='mainbox'><img src='' width=0 height=0></td></tr>"
|
||||
filter="functions"
|
||||
skin="asLargeListItem"
|
||||
prefix="<tr><td class='headline'>Functions<a name='functions'><!-- --></a></td></tr>"
|
||||
suffix="<tr><td height='8'> </td></tr>"
|
||||
%>
|
||||
|
||||
<% this.methods separator="<tr><td class='mainbox'><img src='' width=0 height=0></td></tr>"
|
||||
filter="macros"
|
||||
skin="asLargeListItem"
|
||||
prefix="<tr><td class='headline'>Macros<a name='macros'><!-- --></a></td></tr>"
|
||||
suffix="<tr><td height='8'> </td></tr>"
|
||||
%>
|
||||
|
||||
<% this.methods separator="<tr><td class='mainbox'><img src='' width=0 height=0></td></tr>"
|
||||
filter="skins"
|
||||
skin="asLargeListItemSkin"
|
||||
prefix="<tr><td class='headline'>Skins<a name='skins'><!-- --></a></td></tr>"
|
||||
suffix="<tr><td height='8'> </td></tr>"
|
||||
%>
|
||||
|
||||
<% this.methods separator="<tr><td class='mainbox'><img src='' width=0 height=0></td></tr>"
|
||||
filter="properties"
|
||||
skin="asLargeListItemSkin"
|
||||
prefix="<tr><td class='headline'>type.properties<a name='typeproperties'><!-- --></a></td></tr>"
|
||||
suffix="<tr><td height='8'> </td></tr>"
|
||||
%>
|
||||
|
||||
<% this.parentPrototype skin="asParentList" %>
|
||||
</table>
|
||||
|
||||
<br/><br/>
|
||||
|
||||
<!-- % this.typeProperties % -->
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
9
src/dist/apps/manage/DocPrototype/typeproperties.skin
vendored
Normal file
9
src/dist/apps/manage/DocPrototype/typeproperties.skin
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
<a name='typeproperties'><!-- --></a>
|
||||
<table width='90%' border='0' cellspacing='1' cellpadding='5'><tr>
|
||||
<td class="headline">type.properties in <% param.source %></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="mainbox"><pre><% param.content %></pre></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
2
src/dist/apps/manage/DocTag/author.skin
vendored
Normal file
2
src/dist/apps/manage/DocTag/author.skin
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
<li><b>Author</b><br/>
|
||||
<% this.text %>
|
2
src/dist/apps/manage/DocTag/deprecated.skin
vendored
Normal file
2
src/dist/apps/manage/DocTag/deprecated.skin
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
<li><b>Deprecated</b><br/>
|
||||
<% this.text %>
|
1
src/dist/apps/manage/DocTag/main.skin
vendored
Normal file
1
src/dist/apps/manage/DocTag/main.skin
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
<li><% this.text %>
|
3
src/dist/apps/manage/DocTag/overrides.skin
vendored
Normal file
3
src/dist/apps/manage/DocTag/overrides.skin
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
<li><b>Overrides</b><br/>
|
||||
<% param.link %>
|
||||
|
2
src/dist/apps/manage/DocTag/parameter.skin
vendored
Normal file
2
src/dist/apps/manage/DocTag/parameter.skin
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
<li><b>Parameter</b> <code><% this.name %></code>:<br/>
|
||||
<% this.text %>
|
2
src/dist/apps/manage/DocTag/return.skin
vendored
Normal file
2
src/dist/apps/manage/DocTag/return.skin
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
<li><b>Returns</b><br>
|
||||
<% this.text %>
|
2
src/dist/apps/manage/DocTag/see.skin
vendored
Normal file
2
src/dist/apps/manage/DocTag/see.skin
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
<li><b>See also</b><br>
|
||||
<% param.link %>
|
67
src/dist/apps/manage/Global/api.skin
vendored
Normal file
67
src/dist/apps/manage/Global/api.skin
vendored
Normal file
|
@ -0,0 +1,67 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title></title>
|
||||
<style type="text/css">
|
||||
|
||||
body, p, td, th, li {
|
||||
font-family: verdana, sans-serif;
|
||||
font-size: 10pt;
|
||||
}
|
||||
|
||||
big.top {
|
||||
font-size: 18pt;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
big {
|
||||
font-size: 13pt;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
a {
|
||||
font-weight:bold;
|
||||
color: #cc3333;
|
||||
text-decoration:none;
|
||||
}
|
||||
a:hover {
|
||||
text-decoration:underline;
|
||||
}
|
||||
|
||||
.navig {
|
||||
font-size: 9px;
|
||||
text-decoration: none;
|
||||
font-weight:normal;
|
||||
}
|
||||
|
||||
li {
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
|
||||
|
||||
.mainbox {
|
||||
border-color:#999999;
|
||||
padding-top:5px;
|
||||
padding-bottom:5px;
|
||||
border-bottom-width:1px;
|
||||
border-bottom-style:dotted;
|
||||
}
|
||||
|
||||
.headline {
|
||||
font-weight:bold;
|
||||
background:#dfdfdf;
|
||||
border-color:#999999;
|
||||
padding-top:5px;
|
||||
padding-bottom:5px;
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<% response.body %>
|
||||
|
||||
</body>
|
||||
</html>
|
5
src/dist/apps/manage/Global/basic.skin
vendored
Normal file
5
src/dist/apps/manage/Global/basic.skin
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
|
||||
<html>
|
||||
<% response.head %>
|
||||
<% response.body %>
|
||||
</html>
|
262
src/dist/apps/manage/Global/functions.js
vendored
Normal file
262
src/dist/apps/manage/Global/functions.js
vendored
Normal file
|
@ -0,0 +1,262 @@
|
|||
/**
|
||||
* scheduler function, runs global.appStat every minute
|
||||
*/
|
||||
function scheduler() {
|
||||
appStat();
|
||||
return 60000;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* initializes app.data.stat storage on startup,
|
||||
* creates app.data.addressFilter
|
||||
*/
|
||||
function onStart() {
|
||||
app.data.addressFilter = createAddressFilter();
|
||||
app.data.addressString = root.getProperty("allowadmin");
|
||||
}
|
||||
|
||||
/**
|
||||
* initializes addressFilter from app.properties,
|
||||
* hostnames are converted, wildcards are only allowed in ip-addresses
|
||||
* (so, no network-names, sorry)
|
||||
*/
|
||||
function createAddressFilter() {
|
||||
var filter = new Packages.helma.util.InetAddressFilter();
|
||||
var str = root.getProperty("allowadmin");
|
||||
if (str != null && str != "") {
|
||||
var arr = str.split(",");
|
||||
for (var i in arr) {
|
||||
str = new java.lang.String(arr[i]);
|
||||
try {
|
||||
filter.addAddress(str.trim());
|
||||
} catch (a) {
|
||||
try {
|
||||
str = java.net.InetAddress.getByName(str.trim()).getHostAddress();
|
||||
filter.addAddress(str);
|
||||
} catch (b) {
|
||||
app.log("error using address " + arr[i] + ": " + b);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
app.log("no addresses allowed for app manage, all access will be denied");
|
||||
}
|
||||
return filter;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* updates the stats in app.data.stat every 5 minutes
|
||||
*/
|
||||
function appStat() {
|
||||
if (app.data.stat == null)
|
||||
app.data.stat = new HopObject ();
|
||||
if ((new Date() - 300000) < app.data.stat.lastRun)
|
||||
return;
|
||||
var arr = root.getApplications();
|
||||
for (var i = 0; i < arr.length; i++) {
|
||||
var tmp = app.data.stat[arr[i].getName()];
|
||||
if (tmp == null) {
|
||||
tmp = new HopObject();
|
||||
tmp.lastTotalRequestCount = 0;
|
||||
tmp.lastTotalErrorCount = 0;
|
||||
}
|
||||
tmp.requestCount = arr[i].getRequestCount() - tmp.lastTotalRequestCount;
|
||||
tmp.lastTotalRequestCount = arr[i].getRequestCount();
|
||||
tmp.errorCount = arr[i].getErrorCount() - tmp.lastTotalErrorCount;
|
||||
tmp.lastTotalErrorCount = arr[i].getErrorCount();
|
||||
app.data.stat[arr[i].getName()] = tmp;
|
||||
}
|
||||
app.data.stat.lastRun = new Date();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* utility function to sort object-arrays by name
|
||||
*/
|
||||
function sortByName(a, b) {
|
||||
if (a.name > b.name)
|
||||
return 1;
|
||||
else if (a.name == b.name)
|
||||
return 0;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* utility function to sort property-arrays by key
|
||||
*/
|
||||
function sortProps(a, b) {
|
||||
if (a > b)
|
||||
return 1;
|
||||
else if (a == b)
|
||||
return 0;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* check access to an application or the whole server, authenticate against md5-encrypted
|
||||
* properties of base-app or the particular application. if username or password aren't set
|
||||
* go into stealth-mode and return a 404. if username|password are wrong, prepare response-
|
||||
* object for http-auth and return false.
|
||||
* @arg appObj application object to check against (if adminUsername etc are set in app.properties)
|
||||
*/
|
||||
function checkAuth(appObj) {
|
||||
if (res && res.data.noWeb == true) {
|
||||
return true;
|
||||
}
|
||||
var ok = false;
|
||||
|
||||
// check against root
|
||||
var adminAccess = root.getProperty("adminAccess");
|
||||
|
||||
if (adminAccess == null || adminAccess == "") {
|
||||
res.redirect(root.href("makekey"));
|
||||
}
|
||||
|
||||
var uname = req.username;
|
||||
var pwd = req.password;
|
||||
|
||||
if (uname == null || uname == "" || pwd == null || pwd == "")
|
||||
return forceAuth();
|
||||
|
||||
var md5key = Packages.helma.util.MD5Encoder.encode(uname + "-" + pwd);
|
||||
|
||||
if (md5key == adminAccess)
|
||||
return true;
|
||||
|
||||
if (appObj != null && appObj.isActive()) {
|
||||
// check against application
|
||||
adminAccess = appObj.getProperty("adminAccess");
|
||||
if (md5key == adminAccess)
|
||||
return true;
|
||||
}
|
||||
return forceAuth();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* check access to the manage-app by ip-addresses
|
||||
*/
|
||||
function checkAddress() {
|
||||
if (res && res.data.noWeb == true) {
|
||||
return true;
|
||||
}
|
||||
// if allowadmin value in server.properties has changed,
|
||||
// re-construct the addressFilter
|
||||
if (app.data.addressString != root.getProperty("allowadmin")) {
|
||||
app.data.addressFilter = createAddressFilter();
|
||||
app.data.addressString = root.getProperty("allowadmin");
|
||||
}
|
||||
if (!app.data.addressFilter.matches(java.net.InetAddress.getByName(req.data.http_remotehost))) {
|
||||
app.log("denied request from " + req.data.http_remotehost);
|
||||
// forceStealth seems a bit like overkill here.
|
||||
// display a message that the ip address must be added to server.properties
|
||||
res.write("Access from address " + req.data.http_remotehost + " denied.");
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* response is reset to 401 / authorization required
|
||||
* @arg realm realm for http-auth
|
||||
*/
|
||||
function forceAuth(realm) {
|
||||
res.reset();
|
||||
res.status = 401;
|
||||
res.realm = (realm != null) ? realm : "helma";
|
||||
res.write("Authorization Required. The server could not verify that you are authorized to access the requested page.");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* macro-utility: formatting property lists
|
||||
*/
|
||||
function formatProperties(props, par) {
|
||||
if (props.size() == 0)
|
||||
return "";
|
||||
var e = props.keys();
|
||||
var arr = new Array();
|
||||
while (e.hasMoreElements()) {
|
||||
arr[arr.length] = e.nextElement();
|
||||
}
|
||||
arr.sort(sortProps);
|
||||
for (var i in arr) {
|
||||
// don't print the admin-password
|
||||
if (arr[i].toLowerCase() == "adminusername" || arr[i].toLowerCase() == "adminpassword") continue;
|
||||
res.write(par.itemprefix + arr[i] + par.separator + props.getProperty(arr[i]) + par.itemsuffix);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* macro-utility: formatting an integer value as human readable bytes
|
||||
*/
|
||||
function formatBytes(bytes) {
|
||||
if (bytes > Math.pow(2, 30)) {
|
||||
res.write(Math.round(100 * bytes / Math.pow(2, 30)) / 100 + "gb");
|
||||
} else if (bytes > Math.pow(2, 20)) {
|
||||
res.write(Math.round(100 * bytes / Math.pow(2, 20)) / 100 + "mb");
|
||||
} else {
|
||||
res.write(Math.round(100 * bytes / Math.pow(2, 10)) / 100 + "kb");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* macro-utility: formatting time in millis as human readable age
|
||||
*/
|
||||
function formatAge(age) {
|
||||
var str = "";
|
||||
var days = Math.floor(age / 86400);
|
||||
age = age - days * 86400;
|
||||
var hours = Math.floor(age / 3600);
|
||||
age = age - hours * 3600;
|
||||
var minutes = Math.floor(age / 60);
|
||||
var seconds = Math.floor(age - minutes * 60);
|
||||
if (days > 0)
|
||||
str += (days + " days, ");
|
||||
if (hours > 0)
|
||||
str += (hours + "h, ");
|
||||
str += (minutes + "min");
|
||||
if (days == 0) str += (", " + seconds + "sec");
|
||||
return(str);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* macro-utility: formatting a number-suffix by choosing between singular and plural
|
||||
* @arg value number to be formatted
|
||||
* @arg param-object object to get fields
|
||||
* @param singular string used for value==1
|
||||
* @param plural string used for value!=1
|
||||
*/
|
||||
function formatCount(ct, par) {
|
||||
if (!par || !par.singular || !par.plural) {
|
||||
return "";
|
||||
}
|
||||
if (ct == 1)
|
||||
return par.singular;
|
||||
else
|
||||
return par.plural;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* tries to make out if this server is running linux from java's system properties
|
||||
*/
|
||||
function isLinux() {
|
||||
var str = java.lang.System.getProperty("os.name");
|
||||
return (str != null && str.toLowerCase().indexOf("linux") != -1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
14
src/dist/apps/manage/Global/global.skin
vendored
Normal file
14
src/dist/apps/manage/Global/global.skin
vendored
Normal file
|
@ -0,0 +1,14 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
|
||||
<html>
|
||||
<% skin name="head" %>
|
||||
<body bgcolor="white">
|
||||
|
||||
<table width="90%" border="0" cellspacing="1" cellpadding="5" bgcolor="#000000">
|
||||
<tr>
|
||||
<td width="30%" align="left" valign="top" bgcolor="#cccc99"><% skin name="navig" %></td>
|
||||
<td width="70%" align="left" valign="top" bgcolor="#ffffff"><% response.body %></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</body>
|
||||
</html>
|
59
src/dist/apps/manage/Global/head.skin
vendored
Normal file
59
src/dist/apps/manage/Global/head.skin
vendored
Normal file
|
@ -0,0 +1,59 @@
|
|||
<head>
|
||||
<title><% response.title %></title>
|
||||
<style type="text/css">
|
||||
<!--
|
||||
|
||||
body, p, td, th, li {
|
||||
font-family: verdana, sans-serif;
|
||||
font-size: 10pt;
|
||||
}
|
||||
|
||||
.formEl {
|
||||
border-color:#000000;
|
||||
border-style:solid;
|
||||
border-width:1px;
|
||||
}
|
||||
|
||||
.list_apps {
|
||||
border-color:#ffffff;
|
||||
padding-top:5px;
|
||||
padding-bottom:5px;
|
||||
border-bottom-width:1px;
|
||||
border-bottom-style:dotted;
|
||||
}
|
||||
|
||||
.list_property {
|
||||
border-color:#999999;
|
||||
padding-top:5px;
|
||||
padding-bottom:5px;
|
||||
border-bottom-width:1px;
|
||||
border-bottom-style:dotted;
|
||||
}
|
||||
|
||||
.list_separator {
|
||||
font-weight:bold;
|
||||
background:#dfdfdf;
|
||||
border-color:#999999;
|
||||
padding-top:5px;
|
||||
padding-bottom:5px;
|
||||
border-bottom-width:1px;
|
||||
border-bottom-style:dotted;
|
||||
}
|
||||
|
||||
big {
|
||||
font-size: 18pt;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
a {
|
||||
font-weight:bold;
|
||||
color: #cc3333;
|
||||
text-decoration:none;
|
||||
}
|
||||
a:hover {
|
||||
text-decoration:underline;
|
||||
}
|
||||
|
||||
// -->
|
||||
</style>
|
||||
</head>
|
18
src/dist/apps/manage/Global/macros.js
vendored
Normal file
18
src/dist/apps/manage/Global/macros.js
vendored
Normal file
|
@ -0,0 +1,18 @@
|
|||
/**
|
||||
* macro rendering a skin
|
||||
* @param name name of skin
|
||||
*/
|
||||
function skin_macro(par) {
|
||||
if (par && par.name) {
|
||||
renderSkin(par.name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Macro returning the actual date and time.
|
||||
*/
|
||||
function now_macro() {
|
||||
var date = new Date();
|
||||
return(date.format("dd.MM.yyyy, HH:mm'h' zzz"));
|
||||
}
|
30
src/dist/apps/manage/Global/navig.skin
vendored
Normal file
30
src/dist/apps/manage/Global/navig.skin
vendored
Normal file
|
@ -0,0 +1,30 @@
|
|||
|
||||
<p><a href="<% root.href action="main" %>"><img src="<% root.href action="image" %>" title="helma" border="0" width="174" height="35" align="baseline" style="border-width:3px;border-color:white;"></a>
|
||||
</p>
|
||||
|
||||
<div class="list_apps">
|
||||
<i><% root.appCount filter="active" singular=" app" plural=" apps"%> on
|
||||
<a href="<% root.href action="main" %>"><% root.hostname %> (<% root.hostaddress %>)</a></i>
|
||||
</div>
|
||||
|
||||
<% root.appList filter="active" %>
|
||||
|
||||
<p></p>
|
||||
<div class="list_apps">
|
||||
<i>disabled apps:</i>
|
||||
</div>
|
||||
|
||||
<% root.appList filter="disabled" skin="navig_disabled" %>
|
||||
|
||||
<br/><br/>
|
||||
<p>
|
||||
Information on <a href="http://helma.org/">helma.org</a>:<br/>
|
||||
<li><a href="http://helma.org/docs">reference</a><br/>
|
||||
<li><a href="http://dev.helma.org/Mailing+Lists/">mailinglist</a><br/>
|
||||
<li><a href="https://dev.helma.org/trac/helma/browser/helma/helma/trunk">svn</a><br/>
|
||||
<li><a href="http://helma.org/download/">download</a><br/>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<li><a href="<% root.href action="makekey" %>">generate server password</a>
|
||||
</p>
|
20
src/dist/apps/manage/Global/pwdfeedback.skin
vendored
Normal file
20
src/dist/apps/manage/Global/pwdfeedback.skin
vendored
Normal file
|
@ -0,0 +1,20 @@
|
|||
<body bgcolor="white">
|
||||
|
||||
<table width="500" border="0" cellspacing="0" cellpadding="5" bgcolor="#000000">
|
||||
<tr>
|
||||
<td width="500" align="left" valign="top" bgcolor="#ffffff">
|
||||
|
||||
<big>Generated username and password for helma's manager:</big><br>
|
||||
|
||||
<p>Please copy/paste this line into the server.properties file of your
|
||||
helma installation.</p>
|
||||
|
||||
<pre><% param.propsString %></pre>
|
||||
|
||||
<p>After that proceed to <a href="<% root.href action="main" %>">the manage console</a>,
|
||||
enter your credentials and you should be allowed in.</p>
|
||||
|
||||
</td></tr>
|
||||
</table>
|
||||
|
||||
</body>
|
28
src/dist/apps/manage/Global/pwdform.skin
vendored
Normal file
28
src/dist/apps/manage/Global/pwdform.skin
vendored
Normal file
|
@ -0,0 +1,28 @@
|
|||
<body bgcolor="white">
|
||||
|
||||
<table width="500" border="0" cellspacing="0" cellpadding="5" bgcolor="#000000">
|
||||
<tr>
|
||||
<td width="500" align="left" valign="top" bgcolor="#ffffff">
|
||||
|
||||
<big>Username and password for helma's manager:</big><br>
|
||||
|
||||
<p>Please choose an username and password combination to access the
|
||||
manage application of this server. They will be printed md5-encoded
|
||||
in a format that you've got to copy/paste into the server.properties
|
||||
file.</p>
|
||||
|
||||
<font color="red"><% param.msg %></font>
|
||||
<form method="post">
|
||||
<input class="formEl" name="username" size="25" value="<% param.username %>"> (username)<br>
|
||||
<input class="formEl" type="password" name="password" size="25"> (password)<br>
|
||||
<input class="formEl" type="submit" value="md5 encode"><br>
|
||||
</form>
|
||||
|
||||
<p><b>Warning:</b> The used http-authorization transmits username and password
|
||||
in an unsafe cleartext way. Therefore you're strongly discouraged to
|
||||
use any given combination that is normally protected through SSH.</p>
|
||||
|
||||
</td></tr>
|
||||
</table>
|
||||
|
||||
</body>
|
153
src/dist/apps/manage/Global/renderFunctions.js
vendored
Normal file
153
src/dist/apps/manage/Global/renderFunctions.js
vendored
Normal file
|
@ -0,0 +1,153 @@
|
|||
function renderLink(docEl, param) {
|
||||
var text = "";
|
||||
if (docEl.getType() == docEl.APPLICATION || docEl.getType() == docEl.PROTOTYPE) {
|
||||
text = docEl.getName();
|
||||
} else if (docEl.getType() == docEl.SKIN) {
|
||||
text = docEl.getName() + ".skin";
|
||||
} else if (docEl.getType() == docEl.MACRO) {
|
||||
if (param.handler != "false" && docEl.getParentElement() && docEl.getParentElement().getName() != "global") {
|
||||
text = docEl.getParentElement().getName() + ".";
|
||||
}
|
||||
var str = docEl.getName();
|
||||
if (str.indexOf("_macro")) {
|
||||
text += str.substring(0, str.length - 6);
|
||||
}
|
||||
} else if (docEl.getType() == docEl.FUNCTION) {
|
||||
text = docEl.getName() + "(";
|
||||
var arr = docEl.listParameters();
|
||||
for (var i = 0; i < arr.length; i++) {
|
||||
text += arr[i];
|
||||
if (i < arr.length - 1)
|
||||
text += ", ";
|
||||
}
|
||||
text += ")";
|
||||
} else {
|
||||
text = docEl.getName();
|
||||
}
|
||||
param.href = docEl.href("main");
|
||||
if (!param.target) {
|
||||
param.target = "main";
|
||||
}
|
||||
return renderLinkTag(param) + text + '</a>';
|
||||
}
|
||||
|
||||
|
||||
function renderLinkTag(param) {
|
||||
var sb = new java.lang.StringBuffer ();
|
||||
sb.append('<a');
|
||||
for (var i in param) {
|
||||
sb.append(' ');
|
||||
sb.append(i);
|
||||
sb.append('="');
|
||||
sb.append(param[i]);
|
||||
sb.append('"');
|
||||
}
|
||||
sb.append('>');
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* renders the name of the location of a doc element.
|
||||
*/
|
||||
function renderLocation (docEl, param) {
|
||||
return docEl.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* renders tag list.
|
||||
* @param param.skin skin to render on found DocTags
|
||||
* @param param.separator String printed between tags
|
||||
* @param param.type type string (param|return|author|version|see) to filter tags.
|
||||
*/
|
||||
function renderTags(docEl, param) {
|
||||
var skinname = (param.skin) ? param.skin : "main";
|
||||
var type = param.type;
|
||||
if (type == "params")
|
||||
type = "param";
|
||||
else if (type == "returns")
|
||||
type = "return";
|
||||
else if (type == "arg")
|
||||
type = "param";
|
||||
var str = "";
|
||||
var arr = docEl.listTags();
|
||||
for (var i = 0; i < arr.length; i++) {
|
||||
if (arr[i].getType() == type) {
|
||||
if (type == "see" || type == "overrides") {
|
||||
param.link = renderReference(arr[i], docEl);
|
||||
}
|
||||
str += arr[i].renderSkinAsString(skinname, param);
|
||||
str += (param.separator) ? param.separator : "";
|
||||
}
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* renders a reference to functions in other prototypes, masks
|
||||
* urls in a see tag
|
||||
* (see- and overrides-tags)
|
||||
* @param docTagObj
|
||||
* @param docEl needed to be able to walk up to application object
|
||||
*/
|
||||
function renderReference(docTagObj, docEl) {
|
||||
// prepare the text:
|
||||
var text = docTagObj.getText();
|
||||
text = new java.lang.String (text);
|
||||
text = text.trim();
|
||||
if (text.indexOf("http://") == 0) {
|
||||
// an url is a simple job
|
||||
return '<a href="' + text + '" target="_new">' + text + '</a>';
|
||||
} else {
|
||||
// make sure we only use the first item in the text so that unlinked comments
|
||||
// can follow, store & split the that
|
||||
var tok = new java.util.StringTokenizer (text);
|
||||
var tmp = tok.nextToken();
|
||||
text = " " + text.substring(tmp.length + 1);
|
||||
var parts = tmp.split(".");
|
||||
// try to find the application object
|
||||
var obj = docEl;
|
||||
while (obj != null) {
|
||||
if (obj.getType() == Packages.helma.doc.DocElement.APPLICATION) {
|
||||
var appObj = obj;
|
||||
break;
|
||||
}
|
||||
obj = obj.getParentElement();
|
||||
}
|
||||
var protoObj = appObj.getChildElement("prototype_" + parts[0]);
|
||||
if (protoObj == null) {
|
||||
// prototype wasn't found, return the unlinked tag
|
||||
return tmp + text;
|
||||
}
|
||||
if (parts.length == 1) {
|
||||
// no function specified, return the linked prototype
|
||||
return '<a href="' + protoObj.href("main") + '">' + format(tmp) + '</a>' + text;
|
||||
}
|
||||
// try to find a function object:
|
||||
var arr = protoObj.listChildren();
|
||||
for (var i = 0; i < arr.length; i++) {
|
||||
if (arr[i].getName() == parts [1]) {
|
||||
return '<a href="' + arr[i].href("main") + '">' + format(tmp) + '</a>' + text;
|
||||
}
|
||||
}
|
||||
// function not found:
|
||||
return tmp + text;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* function rendering a comment.
|
||||
* @param param.length comment is shortened to the given length.
|
||||
* @returns string
|
||||
*/
|
||||
function renderComment(docEl, param) {
|
||||
var str = docEl.getComment();
|
||||
if (param.length) {
|
||||
if (param.length < str.length) {
|
||||
return str.substring(0, param.length) + " ...";
|
||||
}
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
26
src/dist/apps/manage/README.md
vendored
Normal file
26
src/dist/apps/manage/README.md
vendored
Normal file
|
@ -0,0 +1,26 @@
|
|||
To get the manage application to work you need to
|
||||
|
||||
- add it to the `apps.properties` file with the following line:
|
||||
|
||||
```
|
||||
manage
|
||||
````
|
||||
|
||||
- use a Helma distribution version 1.5 or higher.
|
||||
|
||||
- add the following properties to the `server.properties` file:
|
||||
|
||||
```
|
||||
allowAdmin = [comma-separated list of hosts or ip-addresses that
|
||||
are allowed to access this application. wildcards
|
||||
are only allowed in addresses, not in hostnames!]
|
||||
adminAccess = <MD5-encoded credentials>
|
||||
```
|
||||
|
||||
Creating the credentials can be done after you've got the application
|
||||
up and running at this address:
|
||||
|
||||
```
|
||||
http://<your-server-name>/manage/makekey
|
||||
```
|
||||
|
130
src/dist/apps/manage/Root/actions.js
vendored
Normal file
130
src/dist/apps/manage/Root/actions.js
vendored
Normal file
|
@ -0,0 +1,130 @@
|
|||
/**
|
||||
* main action, show server-stats
|
||||
* perform start, stop, restart and flush-action
|
||||
*
|
||||
*/
|
||||
function main_action() {
|
||||
|
||||
if (checkAddress() == false) return;
|
||||
|
||||
if (req.data.app != null && req.data.app != "" && req.data.action != null && req.data.action != "") {
|
||||
|
||||
var appObj = root.getApp(req.data.app);
|
||||
// check access for application. md5-encoded uname/pwd can also be put in
|
||||
// app.properties to limit access to a single app
|
||||
if (checkAuth(appObj) == false) return;
|
||||
|
||||
if (req.data.action == "start") {
|
||||
this.startApplication(req.data.app);
|
||||
res.redirect(appObj.href("main"));
|
||||
|
||||
} else if (req.data.action == "stop") {
|
||||
if (checkAuth() == false) return;
|
||||
this.stopApplication(req.data.app);
|
||||
res.redirect(root.href("main"));
|
||||
|
||||
} else if (req.data.action == "restart") {
|
||||
this.stopApplication(req.data.app);
|
||||
this.startApplication(req.data.app);
|
||||
res.redirect(appObj.href("main"));
|
||||
|
||||
} else if (req.data.action == "flush") {
|
||||
appObj.clearCache();
|
||||
res.redirect(appObj.href("main"));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// output only to root
|
||||
if (checkAuth() == false) return;
|
||||
|
||||
res.data.title = "Helma Object Publisher - Serverinfo";
|
||||
res.data.body = this.renderSkinAsString("main");
|
||||
renderSkin("global");
|
||||
}
|
||||
|
||||
/**
|
||||
* return the helma object publisher logo, built into hop core
|
||||
* to be independent of static html-paths
|
||||
*/
|
||||
function image_action() {
|
||||
if (checkAddress() == false) return;
|
||||
|
||||
res.contentType = "image/gif";
|
||||
res.writeBinary(Packages.helma.util.Logo.hop);
|
||||
}
|
||||
|
||||
function makekey_action() {
|
||||
|
||||
if (checkAddress() == false)
|
||||
return;
|
||||
|
||||
var obj = new Object();
|
||||
obj.msg = "";
|
||||
if (req.data.username != null && req.data.password != null) {
|
||||
|
||||
// we have input from webform
|
||||
if (req.data.username == "")
|
||||
obj.msg += "username can't be left empty!<br>";
|
||||
if (req.data.password == "")
|
||||
obj.msg += "password can't be left empty!<br>";
|
||||
if (obj.msg != "") {
|
||||
obj.username = req.data.username;
|
||||
res.reset();
|
||||
res.data.body = renderSkinAsString("pwdform", obj);
|
||||
} else {
|
||||
// render the md5-string:
|
||||
obj.propsString = "adminAccess=" + Packages.helma.util.MD5Encoder.encode(req.data.username + "-" + req.data.password) + "<br>\n";
|
||||
res.data.body = renderSkinAsString("pwdfeedback", obj);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
// no input from webform, so print it
|
||||
res.data.body = renderSkinAsString("pwdform", obj);
|
||||
|
||||
}
|
||||
|
||||
res.data.title = "username & password on " + root.hostname_macro();
|
||||
res.data.head = renderSkinAsString("head");
|
||||
renderSkin("basic");
|
||||
}
|
||||
|
||||
/**
|
||||
* prints server-stats for mrtg-tool.
|
||||
* doesn't check username or password, so that we don't have
|
||||
* to write them cleartext in a mrtg-configfile but checks the
|
||||
* remote address.
|
||||
*/
|
||||
function mrtg_action() {
|
||||
|
||||
if (checkAddress() == false)
|
||||
return;
|
||||
|
||||
|
||||
if (req.data.action == "memory") {
|
||||
|
||||
res.write(this.jvmTotalMemory_macro() + "\n");
|
||||
res.write(this.jvmFreeMemory_macro() + "\n");
|
||||
res.write("0\n0\n");
|
||||
|
||||
} else if (req.data.action == "netstat" && isLinux()) {
|
||||
|
||||
var str = (new File("/proc/net/tcp")).readAll();
|
||||
var arr = str.split("\n");
|
||||
res.write(arr.length - 2 + "\n");
|
||||
res.write("0\n0\n0\n");
|
||||
|
||||
} else if (req.data.action == "loadavg" && isLinux()) {
|
||||
|
||||
// load average of last 5 minutes:
|
||||
var str = (new File("/proc/loadavg")).readAll();
|
||||
var arr = str.split(" ");
|
||||
res.write(arr[1] * 100 + "\n");
|
||||
res.write("0\n0\n0\n");
|
||||
|
||||
} else {
|
||||
res.write("0\n0\n0\n0\n");
|
||||
}
|
||||
}
|
76
src/dist/apps/manage/Root/functions.js
vendored
Normal file
76
src/dist/apps/manage/Root/functions.js
vendored
Normal file
|
@ -0,0 +1,76 @@
|
|||
/**
|
||||
* renders the api of a given application. used from commandline.
|
||||
*/
|
||||
function renderApi(appName) {
|
||||
|
||||
// supress security checks when accessing actions
|
||||
res.data.noWeb = true;
|
||||
|
||||
// start the application
|
||||
this.startApplication(appName);
|
||||
var appObj = this.getApp(appName);
|
||||
var docApp = appObj.getChildElement("api");
|
||||
|
||||
// now render the api
|
||||
var ct = docApp.renderApi();
|
||||
writeln("rendered " + ct + " files");
|
||||
|
||||
// cleanup
|
||||
this.stopApplication(appName);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* lists all applications in appdir.
|
||||
* for active apps use this.getApplications() = helma.main.Server.getApplications()
|
||||
*/
|
||||
function getAllApplications() {
|
||||
var appsDir = this.getAppsHome();
|
||||
var dir = appsDir.listFiles();
|
||||
var arr = new Array();
|
||||
var seen = {};
|
||||
// first check apps directory for apps directories
|
||||
if (dir) {
|
||||
for (var i = 0; i < dir.length; i++) {
|
||||
if (dir[i].isDirectory() && dir[i].name.toLowerCase() != "cvs") {
|
||||
arr[arr.length] = this.getApp(dir[i].name);
|
||||
seen[dir[i].name] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
// then check entries in apps.properties for apps not currently running
|
||||
var props = wrapJavaMap(root.getAppsProperties(null));
|
||||
for (var i in props) {
|
||||
if (i.indexOf(".") < 0 && !seen[i] && !root.getApplication(i)) {
|
||||
arr[arr.length] = this.getApp(i);
|
||||
}
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* get application by name, constructs an hopobject of the prototype application
|
||||
* if the app is not running (and therefore can't be access through
|
||||
* helma.main.ApplicationManager).
|
||||
* ATTENTION: javascript should not overwrite helma.main.Server.getApplication() which
|
||||
* retrieves active applications.
|
||||
* @arg name of application
|
||||
*/
|
||||
function getApp(name) {
|
||||
if (name == null || name == "")
|
||||
return null;
|
||||
var appObj = this.getApplication(name);
|
||||
if (appObj == null)
|
||||
appObj = new Application(name);
|
||||
return appObj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method used by Helma path resolution.
|
||||
*/
|
||||
function getChildElement(name) {
|
||||
return this.getApp(name);
|
||||
}
|
||||
|
||||
|
284
src/dist/apps/manage/Root/macros.js
vendored
Normal file
284
src/dist/apps/manage/Root/macros.js
vendored
Normal file
|
@ -0,0 +1,284 @@
|
|||
/**
|
||||
* macro rendering a skin
|
||||
* @param name name of skin
|
||||
*/
|
||||
function skin_macro(par) {
|
||||
if (par && par.name) {
|
||||
this.renderSkin(par.name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* macro-wrapper for href-function
|
||||
* @param action name of action to call on this prototype, default main
|
||||
*/
|
||||
function href_macro(par) {
|
||||
return this.href((par && par.action)?par.action:"main");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* macro returning the total number of sessions on this server
|
||||
* @see global.formatCount
|
||||
*/
|
||||
function countSessions_macro(par) {
|
||||
var arr = this.getApplications();
|
||||
var sum = 0;
|
||||
for (var i = 0; i < arr.length; i++) {
|
||||
if (arr[i].getName() != app.__app__.getName()) {
|
||||
sum += arr[i].sessions.size();
|
||||
}
|
||||
}
|
||||
return sum + formatCount(sum, par);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* macro returning the number of requests during the last 5 minutes
|
||||
* @see global.formatCount
|
||||
*/
|
||||
function requestCount_macro(par) {
|
||||
if (app.data.stat == null) {
|
||||
return;
|
||||
}
|
||||
var arr = this.getApplications();
|
||||
var sum = 0;
|
||||
for (var i = 0; i < arr.length; i++) {
|
||||
if (arr[i].getName() != app.__app__.getName()) { // don't include manage app
|
||||
var obj = app.data.stat[arr[i].name];
|
||||
if (obj != null) {
|
||||
sum += obj.requestCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
return sum + formatCount(sum, par);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* macro returning the number of errors during the last 5 minutes
|
||||
* @see global.formatCount
|
||||
*/
|
||||
function errorCount_macro(par) {
|
||||
if (app.data.stat == null) {
|
||||
return;
|
||||
}
|
||||
var arr = this.getApplications();
|
||||
var sum = 0;
|
||||
for (var i = 0; i < arr.length; i++) {
|
||||
if (arr[i].getName() != app.__app__.getName()) { // don't include manage app
|
||||
var obj = app.data.stat[arr[i].name];
|
||||
if (obj != null) {
|
||||
sum += obj.errorCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
return sum + formatCount(sum, par);
|
||||
}
|
||||
|
||||
|
||||
function extensions_macro(par) {
|
||||
var vec = this.getExtensions();
|
||||
var str = "";
|
||||
for (var i = 0; i < vec.size(); i++) {
|
||||
str += vec.elementAt(i).getClass().getName();
|
||||
if (i != (vec.size() - 1)) {
|
||||
str += (par && par.separator) ? par.separator : ", ";
|
||||
}
|
||||
}
|
||||
return (str == "") ? null : str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Macro returning hostname of this machine
|
||||
*/
|
||||
function hostname_macro(par) {
|
||||
return java.net.InetAddress.getLocalHost().getHostName()
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Macro returning address of this machine
|
||||
*/
|
||||
function hostaddress_macro(par) {
|
||||
return java.net.InetAddress.getLocalHost().getHostAddress()
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Macro returning the number of running applications,
|
||||
* the manage application being excluded.
|
||||
*/
|
||||
function appCount_macro(par) {
|
||||
if (par && par.filter == "active") {
|
||||
var ct = root.getApplications().length - 1;
|
||||
} else if (par && par.filter == "disabled") {
|
||||
var ct = root.getAllApplications().length - root.getApplications().length;
|
||||
} else {
|
||||
var ct = root.getAllApplications().length - 1;
|
||||
}
|
||||
return ct + formatCount(ct, par);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Macro that lists all running applications,
|
||||
* the manage application being excluded (-1).
|
||||
* @param skin skin of application that will be used.
|
||||
*/
|
||||
function appList_macro(par) {
|
||||
var skin = (par && par.skin) ? par.skin : "navig_active";
|
||||
var apps = new Array();
|
||||
if (par && par.filter == "active") {
|
||||
var arr = root.getApplications();
|
||||
for (var i = 0; i < arr.length; i++) {
|
||||
apps[apps.length] = arr[i];
|
||||
}
|
||||
} else if (par && par.filter == "disabled") {
|
||||
var arr = root.getAllApplications();
|
||||
for (var i in arr) {
|
||||
if (arr[i].isActive() == false) {
|
||||
apps[apps.length] = arr[i];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
var apps = root.getAllApplications();
|
||||
}
|
||||
apps = apps.sort(sortByName);
|
||||
var html = "";
|
||||
var param = new Object();
|
||||
for (var n in apps) {
|
||||
var a = apps[n];
|
||||
if (apps[n].name == app.__app__.getName())
|
||||
continue;
|
||||
var item = a.renderSkinAsString(skin);
|
||||
html += item;
|
||||
}
|
||||
return(html);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Macro that returns the server's uptime nicely formatted
|
||||
*/
|
||||
function uptime_macro() {
|
||||
return formatAge((java.lang.System.currentTimeMillis() - this.starttime) / 1000);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Macro that returns the server's version string
|
||||
*/
|
||||
function version_macro() {
|
||||
return this.version;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Macro that returns the home directory of the hop installation
|
||||
*/
|
||||
function home_macro() {
|
||||
return this.getHopHome().toString();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Macro that returns the free memory in the java virtual machine
|
||||
* @param format if "hr", value will be printed human readable
|
||||
*/
|
||||
function jvmFreeMemory_macro(param) {
|
||||
var m = java.lang.Runtime.getRuntime().freeMemory();
|
||||
return (param && param.hr) ? formatBytes(m) : m;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Macro that returns the total memory available to the java virtual machine
|
||||
* @param format if "hr", value will be printed human readable
|
||||
*/
|
||||
function jvmTotalMemory_macro(param) {
|
||||
var m = java.lang.Runtime.getRuntime().totalMemory();
|
||||
return (param && param.hr) ? formatBytes(m) : m;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Macro that returns the used memory in the java virtual machine
|
||||
* @param format if "hr", value will be printed human readable
|
||||
*/
|
||||
function jvmUsedMemory_macro(param) {
|
||||
var m = java.lang.Runtime.getRuntime().totalMemory() - java.lang.Runtime.getRuntime().freeMemory();
|
||||
return (param && param.hr) ? formatBytes(m) : m;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Macro that returns the version and type of the java virtual machine
|
||||
*/
|
||||
function jvm_macro() {
|
||||
return java.lang.System.getProperty("java.version") + " " + java.lang.System.getProperty("java.vendor");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Macro that returns the home directory of the java virtual machine
|
||||
*/
|
||||
function jvmHome_macro() {
|
||||
return java.lang.System.getProperty("java.home");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Macro that greps all jar-files from the class path variable and lists them.
|
||||
* @param separator string that is printed between the items
|
||||
*/
|
||||
function jvmJars_macro(par) {
|
||||
var separator = (par && par.separator ) ? par.separator : ", ";
|
||||
var str = java.lang.System.getProperty("java.class.path");
|
||||
var arr = str.split(".jar");
|
||||
for (var i in arr) {
|
||||
var str = arr[i];
|
||||
var pos = ( str.lastIndexOf('\\') > str.lastIndexOf('/') ) ? str.lastIndexOf('\\') : str.lastIndexOf('/');
|
||||
res.write(arr[i].substring(pos + 1) + ".jar");
|
||||
if (i < arr.length - 1) res.write(separator);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Macro that returns the name and version of the server's os
|
||||
*/
|
||||
function os_macro() {
|
||||
return java.lang.System.getProperty("os.name") + " " + java.lang.System.getProperty("os.arch") + " " + java.lang.System.getProperty("os.version");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Macro that returns anything from server.properties
|
||||
*/
|
||||
function property_macro(par) {
|
||||
if (par && par.key) {
|
||||
return this.getProperty(key);
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Macro formatting server.properties
|
||||
*/
|
||||
function properties_macro(par) {
|
||||
formatProperties(this.getProperties(), par);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Macro that returns the timezone of this server
|
||||
*/
|
||||
function timezone_macro(par) {
|
||||
return java.util.TimeZone.getDefault().getDisplayName(false, java.util.TimeZone.LONG) + " (" + java.util.TimeZone.getDefault().getID() + ")";
|
||||
}
|
||||
|
||||
|
111
src/dist/apps/manage/Root/main.skin
vendored
Normal file
111
src/dist/apps/manage/Root/main.skin
vendored
Normal file
|
@ -0,0 +1,111 @@
|
|||
<big><% this.hostname %> (<% this.hostaddress %>)</big><br/><br/>
|
||||
|
||||
<table border="0" cellspacing="0" cellpadding="3">
|
||||
|
||||
<tr>
|
||||
<td class="list_separator" colspan="3">helma</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="list_property">uptime:</td>
|
||||
<td class="list_property" width="5"> </td>
|
||||
<td class="list_property" align="left"><% this.uptime %></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="list_property">version:</td>
|
||||
<td class="list_property" width="5"> </td>
|
||||
<td class="list_property" align="left"><% this.version %></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="list_property">homedir:</td>
|
||||
<td class="list_property" width="5"> </td>
|
||||
<td class="list_property" align="left"><% this.home %></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="list_property" valign="top">total active sessions:</td>
|
||||
<td class="list_property" width="5"> </td>
|
||||
<td class="list_property" align="left"><% this.countSessions default=" " %></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="list_property" nowrap valign="top">total requests / 5 min:</td>
|
||||
<td class="list_property" width="5"> </td>
|
||||
<td class="list_property" align="left"><% this.requestCount default=" " %></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="list_property" norwrap valign="top">total errors / 5 min:</td>
|
||||
<td class="list_property" width="5"> </td>
|
||||
<td class="list_property" align="left"><% this.errorCount default=" " %></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="list_property" valign="top">loaded extensions:</td>
|
||||
<td class="list_property" width="5"> </td>
|
||||
<td class="list_property" align="left"><% this.extensions default=" " %></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="list_separator" colspan="3">jre</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="list_property">free memory:</td>
|
||||
<td class="list_property" width="5"> </td>
|
||||
<td class="list_property" align="left"><% this.jvmFreeMemory hr="true" %></td>
|
||||
</tr>
|
||||
|
||||
|
||||
<tr>
|
||||
<td class="list_property">used memory:</td>
|
||||
<td class="list_property" width="5"> </td>
|
||||
<td class="list_property" align="left"><% this.jvmUsedMemory hr="true" %></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="list_property">total memory:</td>
|
||||
<td class="list_property" width="5"> </td>
|
||||
<td class="list_property" align="left"><% this.jvmTotalMemory hr="true" %></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="list_property">java:</td>
|
||||
<td class="list_property" width="5"> </td>
|
||||
<td class="list_property" align="left"><% this.jvm %></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="list_property">javahome:</td>
|
||||
<td class="list_property" width="5"> </td>
|
||||
<td class="list_property" align="left"><% this.jvmHome %></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="list_property">os:</td>
|
||||
<td class="list_property" width="5"> </td>
|
||||
<td class="list_property" align="left"><% this.os %></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="list_property">localtime:</td>
|
||||
<td class="list_property" width="5"> </td>
|
||||
<td class="list_property" align="left"><% now %></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="list_property" valign="top">timezone:</td>
|
||||
<td class="list_property" width="5"> </td>
|
||||
<td class="list_property" align="left"><% this.timezone %></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="list_property" valign="top">loaded Jars:</td>
|
||||
<td class="list_property" width="5"> </td>
|
||||
<td class="list_property" align="left"><% this.jvmJars %></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="list_separator" colspan="3">server.properties</td>
|
||||
</tr>
|
||||
|
||||
<% this.properties itemprefix='<tr><td class="list_property">' separator='</td><td class="list_property" width="5"> </td><td class="list_property" align="left">' itemsuffix='</td></tr>' %>
|
||||
</table>
|
||||
|
||||
|
||||
|
||||
|
12
src/dist/apps/manage/app.properties
vendored
Normal file
12
src/dist/apps/manage/app.properties
vendored
Normal file
|
@ -0,0 +1,12 @@
|
|||
# Set baseURI for application generated URLs, if necessary.
|
||||
# baseURI = /manage
|
||||
|
||||
# A short description of what this application is about:
|
||||
_description = Helma's server management console. Start applications, introspection etc.
|
||||
|
||||
# use higher request timeout because rendering the apidocs
|
||||
# might take more than one minute on a slow computer
|
||||
requestTimeout = 300
|
||||
|
||||
# run scheduler function each minute
|
||||
cron.scheduler.function = scheduler
|
27
src/dist/apps/manage/class.properties
vendored
Normal file
27
src/dist/apps/manage/class.properties
vendored
Normal file
|
@ -0,0 +1,27 @@
|
|||
#
|
||||
# define the root class of this application
|
||||
#
|
||||
root = helma.main.Server
|
||||
|
||||
#
|
||||
# root.factory is used to retrieve the root class of the application
|
||||
# when the instance has already been created when the application comes up.
|
||||
# this is true for the helma server that is scripted here.
|
||||
#
|
||||
root.factory.class = helma.main.Server
|
||||
root.factory.method = getServer
|
||||
|
||||
#
|
||||
# Map Java classes to the prototype used to script them
|
||||
# and, yes, map the root class again.
|
||||
#
|
||||
|
||||
helma.main.Server = Root
|
||||
helma.framework.core.Application = Application
|
||||
helma.doc.DocApplication = DocApplication
|
||||
helma.doc.DocPrototype = DocPrototype
|
||||
helma.doc.DocFunction = DocFunction
|
||||
helma.doc.DocProperties = DocFunction
|
||||
helma.doc.DocSkin = DocFunction
|
||||
helma.doc.DocTag = DocTag
|
||||
|
10
src/dist/apps/test/README.md
vendored
Normal file
10
src/dist/apps/test/README.md
vendored
Normal file
|
@ -0,0 +1,10 @@
|
|||
To run the tests, add something like this to your apps.properties file:
|
||||
|
||||
test
|
||||
test.appdir = apps/test/code
|
||||
test.repository.0 = apps/test/code
|
||||
test.repository.1 = modules/jala/util/Test/code
|
||||
|
||||
And you need to have a JDBC driver for your database in lib/ext,
|
||||
as well as create the database schema provided in one of the
|
||||
db-<product>.sql files.
|
33
src/dist/apps/test/code/Global/global.js
vendored
Normal file
33
src/dist/apps/test/code/Global/global.js
vendored
Normal file
|
@ -0,0 +1,33 @@
|
|||
function onStart() {
|
||||
root.date = new Date();
|
||||
root.string = "root";
|
||||
}
|
||||
|
||||
function hello_macro(param) {
|
||||
return "hello";
|
||||
}
|
||||
|
||||
function echo_macro(param, arg) {
|
||||
return arg || param.what;
|
||||
}
|
||||
|
||||
function isDate_filter(arg) {
|
||||
return arg instanceof Date;
|
||||
}
|
||||
|
||||
function isRootDate_filter(arg) {
|
||||
return (arg instanceof Date) &&
|
||||
arg.getTime() == root.date.getTime();
|
||||
}
|
||||
|
||||
function isResponseDate_filter(arg) {
|
||||
return (arg instanceof Date) && arg == res.data.date;
|
||||
}
|
||||
|
||||
function makeLongString() {
|
||||
var b = new java.lang.StringBuffer();
|
||||
for (var i = 1; i <= 10000; i++) {
|
||||
b.append(i.toString()).append(" ");
|
||||
}
|
||||
return b.toString();
|
||||
}
|
1
src/dist/apps/test/code/Global/subskins.skin
vendored
Normal file
1
src/dist/apps/test/code/Global/subskins.skin
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
mainskin<% #subskin1 %>subskin1<% #subskin2 %>subskin2<% #end %>
|
40
src/dist/apps/test/code/Organisation/type.properties
vendored
Normal file
40
src/dist/apps/test/code/Organisation/type.properties
vendored
Normal file
|
@ -0,0 +1,40 @@
|
|||
|
||||
_db = dbcTest
|
||||
_table = tb_organisation
|
||||
|
||||
_id = org_id
|
||||
_parent = root.organisations
|
||||
|
||||
persons = collection(Person)
|
||||
persons.local = org_id
|
||||
persons.foreign = person_org_id
|
||||
persons.accessname = person_name
|
||||
persons.order = person_name
|
||||
|
||||
range = collection(Person)
|
||||
range.local = org_id
|
||||
range.foreign = person_org_id
|
||||
range.accessname = person_name
|
||||
range.order = person_name
|
||||
range.offset = 100
|
||||
range.maxsize = 100
|
||||
|
||||
generic = collection(Person)
|
||||
generic.local.1 = $prototype
|
||||
generic.foreign.1 = person_generic_prototype
|
||||
generic.local.2 = $id
|
||||
generic.foreign.2 = person_generic_id
|
||||
generic.order = person_name
|
||||
|
||||
groupedGeneric = collection(Person)
|
||||
groupedGeneric.local.1 = $prototype
|
||||
groupedGeneric.foreign.1 = person_generic_prototype
|
||||
groupedGeneric.local.2 = $id
|
||||
groupedGeneric.foreign.2 = person_generic_id
|
||||
groupedGeneric.group = person_name
|
||||
groupedGeneric.group.order = person_name
|
||||
|
||||
name = org_name
|
||||
country = org_country
|
||||
|
||||
someMountpoint = mountpoint(SomeMountpoint)
|
17
src/dist/apps/test/code/Person/type.properties
vendored
Normal file
17
src/dist/apps/test/code/Person/type.properties
vendored
Normal file
|
@ -0,0 +1,17 @@
|
|||
|
||||
_db = dbcTest
|
||||
_table = tb_person
|
||||
|
||||
_id = person_id
|
||||
_parent = organisation.persons, root.persons
|
||||
|
||||
name = person_name
|
||||
height = person_height
|
||||
dateOfBirth = person_dateofbirth
|
||||
|
||||
organisation = object(Organisation)
|
||||
organisation.local = person_org_id
|
||||
organisation.foreign = org_id
|
||||
|
||||
genericPrototype = person_generic_prototype
|
||||
genericId = person_generic_id
|
35
src/dist/apps/test/code/Root/root.js
vendored
Normal file
35
src/dist/apps/test/code/Root/root.js
vendored
Normal file
|
@ -0,0 +1,35 @@
|
|||
function main_action() {
|
||||
res.redirect(root.href("jala.test"));
|
||||
}
|
||||
|
||||
function hello_action() {
|
||||
res.contentType = "text/plain";
|
||||
res.write("Hello");
|
||||
}
|
||||
|
||||
function throwerror_action() {
|
||||
throw Error();
|
||||
}
|
||||
|
||||
function notfound_action() {
|
||||
res.write("Not found");
|
||||
}
|
||||
|
||||
function redirect_action() {
|
||||
res.redirect(this.href("hello"));
|
||||
}
|
||||
|
||||
function error_action() {
|
||||
res.write("Error");
|
||||
}
|
||||
|
||||
function long_action() {
|
||||
res.write(makeLongString());
|
||||
}
|
||||
|
||||
function macro_macro(param) {
|
||||
// change suffix
|
||||
if (param.suffix) param.suffix = ".";
|
||||
return this.string;
|
||||
}
|
||||
|
16
src/dist/apps/test/code/Root/type.properties
vendored
Normal file
16
src/dist/apps/test/code/Root/type.properties
vendored
Normal file
|
@ -0,0 +1,16 @@
|
|||
date = date
|
||||
string = string
|
||||
|
||||
|
||||
organisations = collection(Organisation)
|
||||
organisations.accessname = org_name
|
||||
|
||||
organisationsByCountry = collection(Organisation)
|
||||
organisationsByCountry.group = org_country
|
||||
organisationsByCountry.group.prototype = Country
|
||||
organisationsByCountry.group.order = org_country desc
|
||||
organisationsByCountry.order = org_name desc
|
||||
|
||||
persons = collection(Person)
|
||||
|
||||
someMountpoint = mountpoint(SomeMountpoint)
|
3
src/dist/apps/test/code/app.properties
vendored
Normal file
3
src/dist/apps/test/code/app.properties
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
baseUri = http://localhost:8080/test/
|
||||
# hard-code cache size to default value to make sure there's some cache rotation
|
||||
cacheSize = 500
|
15
src/dist/apps/test/code/db.properties
vendored
Normal file
15
src/dist/apps/test/code/db.properties
vendored
Normal file
|
@ -0,0 +1,15 @@
|
|||
|
||||
#MySQL
|
||||
dbcTest.url = jdbc:mysql://localhost/helmaTest
|
||||
dbcTest.driver = com.mysql.jdbc.Driver
|
||||
dbcTest.user = helma
|
||||
dbcTest.password = secret
|
||||
|
||||
# Oracle
|
||||
# dbcTest.url = jdbc:oracle:thin:@localhost:1521:XE
|
||||
# dbcTest.driver = oracle.jdbc.driver.OracleDriver
|
||||
|
||||
# PostgreSQL
|
||||
# dbcTest.url = jdbc:postgresql:helmaTest
|
||||
# dbcTest.driver = org.postgresql.Driver
|
||||
|
26
src/dist/apps/test/db-mysql.sql
vendored
Normal file
26
src/dist/apps/test/db-mysql.sql
vendored
Normal file
|
@ -0,0 +1,26 @@
|
|||
|
||||
CREATE DATABASE IF NOT EXISTS helmaTest;
|
||||
USE helmaTest;
|
||||
|
||||
GRANT ALL ON helmaTest.* TO helma@localhost IDENTIFIED BY 'secret';
|
||||
|
||||
DROP TABLE IF EXISTS tb_person;
|
||||
DROP TABLE IF EXISTS tb_organisation;
|
||||
|
||||
CREATE TABLE tb_person (
|
||||
person_id MEDIUMINT(10) NOT NULL,
|
||||
person_name TINYTEXT,
|
||||
person_height TINYINT unsigned,
|
||||
person_dateofbirth DATETIME,
|
||||
person_org_id MEDIUMINT(10) unsigned,
|
||||
person_generic_prototype VARCHAR(30),
|
||||
person_generic_id MEDIUMINT(10) unsigned,
|
||||
PRIMARY KEY (person_id)
|
||||
);
|
||||
|
||||
CREATE TABLE tb_organisation (
|
||||
org_id MEDIUMINT(10) unsigned NOT NULL,
|
||||
org_name TINYTEXT,
|
||||
org_country TINYTEXT,
|
||||
PRIMARY KEY (org_id)
|
||||
);
|
15
src/dist/apps/test/db-oracle.sql
vendored
Normal file
15
src/dist/apps/test/db-oracle.sql
vendored
Normal file
|
@ -0,0 +1,15 @@
|
|||
CREATE TABLE tb_person (
|
||||
person_id NUMBER(10) NOT NULL,
|
||||
person_name VARCHAR2(255),
|
||||
person_height NUMBER(10),
|
||||
person_dateofbirth DATE,
|
||||
person_org_id NUMBER(10),
|
||||
PRIMARY KEY (person_id)
|
||||
);
|
||||
|
||||
CREATE TABLE tb_organisation (
|
||||
org_id NUMBER(10) NOT NULL,
|
||||
org_name VARCHAR2(255),
|
||||
org_country VARCHAR2(255),
|
||||
PRIMARY KEY (org_id)
|
||||
);
|
20
src/dist/apps/test/db-postgresql.sql
vendored
Normal file
20
src/dist/apps/test/db-postgresql.sql
vendored
Normal file
|
@ -0,0 +1,20 @@
|
|||
|
||||
CREATE TABLE tb_person (
|
||||
person_id INTEGER NOT NULL,
|
||||
person_name VARCHAR(100),
|
||||
person_height INTEGER,
|
||||
person_dateofbirth TIMESTAMP,
|
||||
person_org_id INTEGER,
|
||||
PRIMARY KEY (person_id)
|
||||
);
|
||||
|
||||
CREATE TABLE tb_organisation (
|
||||
org_id INTEGER NOT NULL,
|
||||
org_name VARCHAR(100),
|
||||
org_country VARCHAR(100),
|
||||
PRIMARY KEY (org_id)
|
||||
);
|
||||
|
||||
CREATE USER helma WITH PASSWORD 'secret';
|
||||
GRANT insert, delete, select, update ON tb_person, tb_organisation TO helma;
|
||||
|
148
src/dist/apps/test/tests/HopObjectBasicMapping.js
vendored
Normal file
148
src/dist/apps/test/tests/HopObjectBasicMapping.js
vendored
Normal file
|
@ -0,0 +1,148 @@
|
|||
tests = [
|
||||
"testEquality",
|
||||
"testSimpleMapping",
|
||||
"testSimpleCollection",
|
||||
"testObjectReference",
|
||||
"testCollectionForReference"
|
||||
];
|
||||
|
||||
function setup() {
|
||||
}
|
||||
|
||||
function testEquality() {
|
||||
var person = new Person();
|
||||
root.persons.add(person);
|
||||
res.commit();
|
||||
var id = person._id;
|
||||
app.clearCache();
|
||||
var person2 = root.persons.get(id);
|
||||
assertNotNull(person2);
|
||||
assertTrue(person !== person2);
|
||||
assertTrue(person._id === person2._id);
|
||||
assertTrue(person == person2);
|
||||
person.remove();
|
||||
}
|
||||
|
||||
function testSimpleMapping() {
|
||||
|
||||
var data = {
|
||||
name: "Oliver Stone",
|
||||
dateOfBirth: new Date(1946, 8, 15, 6, 0, 0),
|
||||
height: 182
|
||||
};
|
||||
var person = new Person();
|
||||
person.name = data.name;
|
||||
person.dateOfBirth = data.dateOfBirth;
|
||||
person.height = data.height;
|
||||
root.persons.add(person);
|
||||
var personId = person._id;
|
||||
|
||||
res.commit(); // Commit Transaction
|
||||
app.clearCache(); // Clear cache so that object is refetched
|
||||
|
||||
var person = Person.getById(personId);
|
||||
assertNotNull(person);
|
||||
assertEqual(person._prototype, "Person");
|
||||
assertEqual(person._id, personId);
|
||||
assertEqual(person.name, data.name);
|
||||
assertEqual(person.height, data.height);
|
||||
assertEqual(person.dateOfBirth.valueOf(), data.dateOfBirth.valueOf());
|
||||
res.commit();
|
||||
|
||||
person.remove();
|
||||
}
|
||||
|
||||
function testSimpleCollection() {
|
||||
|
||||
var data = {
|
||||
name: "Helma"
|
||||
};
|
||||
var orgCount = root.organisations.count();
|
||||
var org = new Organisation();
|
||||
org.name = data.name;
|
||||
root.organisations.add(org);
|
||||
var orgId = org._id;
|
||||
|
||||
assertEqual(orgCount + 1, root.organisations.count());
|
||||
assertNotEqual(root.organisations.indexOf(org), -1);
|
||||
|
||||
// fetch Object via position
|
||||
assertEqual(root.organisations.get(root.organisations.indexOf(org)), org);
|
||||
|
||||
// fetch Object via accessname
|
||||
assertEqual(root.organisations.get(data.name), org);
|
||||
|
||||
// fetch Object via id
|
||||
assertEqual(root.organisations.getById(orgId), org);
|
||||
|
||||
// test list
|
||||
assertEqual(root.organisations.count(), root.organisations.list().length);
|
||||
|
||||
org.remove();
|
||||
|
||||
assertEqual(orgCount, root.organisations.count());
|
||||
assertEqual(root.organisations.indexOf(org), -1);
|
||||
assertNull(root.organisations.get(data.name));
|
||||
assertNull(root.organisations.getById(orgId));
|
||||
|
||||
}
|
||||
|
||||
|
||||
function testObjectReference() {
|
||||
|
||||
var org = new Organisation();
|
||||
org.name = "Helma";
|
||||
root.organisations.add(org);
|
||||
var orgId = org._id;
|
||||
|
||||
var person = new Person();
|
||||
person.name = "Hannes";
|
||||
person.organisation = org;
|
||||
root.persons.add(person);
|
||||
var personId = person._id;
|
||||
|
||||
res.commit(); // Commit Transaction
|
||||
app.clearCache(); // Clear cache so that object is refetched
|
||||
|
||||
var org = Organisation.getById(orgId);
|
||||
var person = Person.getById(personId);
|
||||
assertEqual(person.organisation, org);
|
||||
|
||||
org.remove();
|
||||
res.commit(); // Commit Transaction
|
||||
|
||||
assertNull(person.organisation);
|
||||
|
||||
person.remove();
|
||||
}
|
||||
|
||||
|
||||
function testCollectionForReference() {
|
||||
|
||||
var org = new Organisation();
|
||||
org.name = "Helma";
|
||||
root.organisations.add(org);
|
||||
var orgId = org._id;
|
||||
var personCount = org.persons.count();
|
||||
|
||||
var person = new Person();
|
||||
person.name = "Hannes";
|
||||
person.organisation = org;
|
||||
root.persons.add(person);
|
||||
org.persons.add(person);
|
||||
|
||||
assertEqual(personCount + 1, org.persons.count());
|
||||
assertNotEqual(org.persons.indexOf(person), -1);
|
||||
|
||||
org.persons.removeChild(person);
|
||||
person.remove();
|
||||
|
||||
assertEqual(personCount, org.persons.count());
|
||||
assertEqual(org.persons.indexOf(person), -1);
|
||||
|
||||
org.remove();
|
||||
}
|
||||
|
||||
|
||||
function cleanup() {
|
||||
}
|
183
src/dist/apps/test/tests/HopObjectCollection.js
vendored
Normal file
183
src/dist/apps/test/tests/HopObjectCollection.js
vendored
Normal file
|
@ -0,0 +1,183 @@
|
|||
tests = [
|
||||
"testSize",
|
||||
"testMaxSize",
|
||||
"testAddSmall",
|
||||
"testAddLarge",
|
||||
"testRemoveSmall",
|
||||
"testRemoveLarge",
|
||||
"testUpdateSmall",
|
||||
"testUpdateLarge",
|
||||
"testListSmall",
|
||||
"testListLarge",
|
||||
"testOrderLarge",
|
||||
"testOrderSmall"
|
||||
];
|
||||
|
||||
var helma, ikea;
|
||||
var small = 3, large = 1234;
|
||||
|
||||
function setup() {
|
||||
ikea = makeOrg('Ikea', large);
|
||||
helma = makeOrg('Helma', small);
|
||||
}
|
||||
|
||||
function testSize() {
|
||||
assertEqual(ikea.persons.size(), large);
|
||||
assertEqual(helma.persons.size(), small);
|
||||
}
|
||||
|
||||
function testMaxSize() {
|
||||
assertEqual(ikea.range.size(), 100);
|
||||
assertEqual(helma.range.size(), 0);
|
||||
var person = ikea.range.get("Person Ikea 0150");
|
||||
assertNotNull(person);
|
||||
assertEqual(person, ikea.range.get(50));
|
||||
assertEqual(person, ikea.persons.get(150));
|
||||
assertEqual(50, ikea.range.indexOf(person));
|
||||
assertEqual(150, ikea.persons.indexOf(person));
|
||||
}
|
||||
|
||||
function testAddSmall() {
|
||||
testAdd(helma, small);
|
||||
}
|
||||
|
||||
function testAddLarge() {
|
||||
testAdd(ikea, large);
|
||||
}
|
||||
|
||||
// test directly adding to a collection
|
||||
function testAdd(org, size) {
|
||||
var person = new Person();
|
||||
person.name = "TestPerson";
|
||||
org.persons.add(person);
|
||||
assertEqual(org.persons.size(), size + 1);
|
||||
assertEqual(org.persons.indexOf(person), size);
|
||||
assertEqual(org.persons.contains(person), size);
|
||||
assertEqual(person.href(), org.persons.href() + "TestPerson/");
|
||||
// make sure the add has set the back-reference on the person object.
|
||||
// note that === comparison will return false if the
|
||||
// collection size exceeds the cache size.
|
||||
assertTrue(person.organisation == org);
|
||||
}
|
||||
|
||||
function testRemoveSmall() {
|
||||
testRemove(helma, small);
|
||||
}
|
||||
|
||||
function testRemoveLarge() {
|
||||
testRemove(ikea, large);
|
||||
}
|
||||
|
||||
// test directly removing from a collection
|
||||
function testRemove(org, size) {
|
||||
var person = org.persons.get(org.persons.size() - 1);
|
||||
person.remove();
|
||||
assertEqual(org.persons.size(), size);
|
||||
assertEqual(org.persons.indexOf(person), -1);
|
||||
assertEqual(org.persons.contains(person), -1);
|
||||
}
|
||||
|
||||
function testUpdateSmall() {
|
||||
testUpdate(helma, small);
|
||||
}
|
||||
|
||||
function testUpdateLarge() {
|
||||
testUpdate(ikea, large);
|
||||
}
|
||||
|
||||
// test indirectly adding to and removing form a collection
|
||||
function testUpdate(org, size) {
|
||||
var person = new Person();
|
||||
person.name = "TestPerson";
|
||||
person.organisation = org;
|
||||
person.persist();
|
||||
res.commit();
|
||||
assertEqual(org.persons.size(), size + 1);
|
||||
org.persons.prefetchChildren();
|
||||
assertEqual(org.persons.indexOf(person), size);
|
||||
assertEqual(org.persons.contains(person), size);
|
||||
assertEqual(person.href(), org.persons.href() + "TestPerson/");
|
||||
person.remove();
|
||||
res.commit();
|
||||
assertEqual(org.persons.size(), size);
|
||||
assertEqual(org.persons.indexOf(person), -1);
|
||||
assertEqual(org.persons.contains(person), -1);
|
||||
}
|
||||
|
||||
function testListSmall() {
|
||||
testList(helma, small);
|
||||
}
|
||||
|
||||
function testListLarge() {
|
||||
testList(ikea, large);
|
||||
}
|
||||
|
||||
function testList(org, size) {
|
||||
function iterate(list, start, length) {
|
||||
assertEqual(list.length, length);
|
||||
for (var i = 0; i < length; i++) {
|
||||
assertEqual(list[i].name, "Person " + org.name + (start + i).format(" 0000"));
|
||||
}
|
||||
}
|
||||
iterate(org.persons.list(), 0, size);
|
||||
org.persons.invalidate();
|
||||
iterate(org.persons.list(), 0, size);
|
||||
org.persons.invalidate();
|
||||
iterate(org.persons.list(1, size - 2), 1, size - 2);
|
||||
}
|
||||
|
||||
function testOrderLarge() {
|
||||
testOrder(ikea, ikea.persons.size() - 2);
|
||||
testOrder(ikea, Math.floor(ikea.persons.size() / 2));
|
||||
testOrder(ikea, 2);
|
||||
}
|
||||
|
||||
function testOrderSmall() {
|
||||
testOrder(helma, helma.persons.size() - 1);
|
||||
testOrder(helma, 1);
|
||||
testOrder(helma, 0);
|
||||
}
|
||||
|
||||
function testOrder(org, pos) {
|
||||
var person = new Person();
|
||||
person.name = "Person " + org.name + pos.format(" 0000") + "B";
|
||||
person.organisation = org;
|
||||
root.persons.add(person);
|
||||
res.commit();
|
||||
assertEqual(pos + 1, org.persons.indexOf(person));
|
||||
}
|
||||
|
||||
function cleanup() {
|
||||
var persons = root.persons.list();
|
||||
for each (var person in persons) {
|
||||
person.remove();
|
||||
}
|
||||
ikea.remove();
|
||||
helma.remove();
|
||||
}
|
||||
|
||||
function makeOrg(name, size) {
|
||||
var org = new Organisation();
|
||||
org.name = name;
|
||||
root.organisations.add(org);
|
||||
|
||||
for (var i = 0; i < size; i++) {
|
||||
var person = new Person();
|
||||
person.name = "Person " + name + i.format(" 0000");
|
||||
person.organisation = org;
|
||||
root.persons.add(person);
|
||||
}
|
||||
res.commit();
|
||||
return org;
|
||||
}
|
||||
|
||||
// debugging helpers
|
||||
function dumpDataChange(message) {
|
||||
res.debug(message + ": ");
|
||||
dumpDataChangeFor("Person");
|
||||
dumpDataChangeFor("Organisation");
|
||||
}
|
||||
|
||||
function dumpDataChangeFor(name) {
|
||||
res.debug(name + ": " + app.__app__.getDbMapping(name).getLastDataChange());
|
||||
}
|
93
src/dist/apps/test/tests/HopObjectGeneric.js
vendored
Normal file
93
src/dist/apps/test/tests/HopObjectGeneric.js
vendored
Normal file
|
@ -0,0 +1,93 @@
|
|||
tests = [
|
||||
'testSize',
|
||||
'testContent',
|
||||
'testGroupContent',
|
||||
'testRemove',
|
||||
'testAdd'
|
||||
];
|
||||
|
||||
var org;
|
||||
var size = 16;
|
||||
|
||||
function setup() {
|
||||
org = new Organisation();
|
||||
org.name = "GenericOrg";
|
||||
var i = 0, person;
|
||||
|
||||
function addPerson(collection) {
|
||||
person = new Person();
|
||||
person.name = "GenericPerson " + i.format("00");
|
||||
collection.add(person);
|
||||
i++;
|
||||
}
|
||||
|
||||
// add first half to both collections of transient parent ...
|
||||
while (i < 4)
|
||||
addPerson(org.generic);
|
||||
while (i < 8)
|
||||
addPerson(org.groupedGeneric);
|
||||
root.organisations.add(org);
|
||||
// ... second half to both collections of persistent parent.
|
||||
while (i < 12)
|
||||
addPerson(org.generic);
|
||||
while (i < size)
|
||||
addPerson(org.groupedGeneric);
|
||||
|
||||
res.commit();
|
||||
}
|
||||
|
||||
function testSize() {
|
||||
assertEqual(org.generic.size(), size);
|
||||
org.invalidate();
|
||||
assertEqual(org.generic.size(), size);
|
||||
}
|
||||
|
||||
function testContent() {
|
||||
var list = org.generic.list();
|
||||
assertEqual(list.length, size);
|
||||
for (var i = 0; i < list.length; i++) {
|
||||
assertEqual(list[i].name, "GenericPerson " + i.format("00"));
|
||||
}
|
||||
}
|
||||
|
||||
function testGroupContent() {
|
||||
var list = org.groupedGeneric.list();
|
||||
assertEqual(list.length, size);
|
||||
for (var i = 0; i < list.length; i++) {
|
||||
assertEqual(list[i].groupname, "GenericPerson " + i.format("00"));
|
||||
assertEqual(list[i].size(), 1);
|
||||
assertEqual(list[i].get(0).name, "GenericPerson " + i.format("00"));
|
||||
}
|
||||
}
|
||||
|
||||
function testRemove() {
|
||||
var person = org.generic.get(size/2);
|
||||
org.generic.removeChild(person);
|
||||
assertEqual(org.generic.size(), size - 1);
|
||||
res.rollback();
|
||||
// note: removeChild does not remove the node, nor does it
|
||||
// unset the constraints between parent and child, so after a rollback
|
||||
// the object is back in place. While this behaviour is disputable,
|
||||
// until this is so we test for it.
|
||||
assertEqual(org.generic.size(), size);
|
||||
}
|
||||
|
||||
function testAdd() {
|
||||
var person = new Person();
|
||||
org.generic.add(person);
|
||||
assertEqual(org.generic.size(), size + 1);
|
||||
assertEqual(org.groupedGeneric.size(), size);
|
||||
res.commit();
|
||||
// note: even after commit the grouped collection must not grow
|
||||
// since we added a person without a name
|
||||
assertEqual(org.generic.size(), size + 1);
|
||||
assertEqual(org.groupedGeneric.size(), size);
|
||||
}
|
||||
|
||||
function cleanup() {
|
||||
var persons = org.generic.list();
|
||||
for each (var person in persons) {
|
||||
person.remove();
|
||||
}
|
||||
org.remove();
|
||||
}
|
149
src/dist/apps/test/tests/HopObjectGroupBy.js
vendored
Normal file
149
src/dist/apps/test/tests/HopObjectGroupBy.js
vendored
Normal file
|
@ -0,0 +1,149 @@
|
|||
tests = [
|
||||
"testGroupByAddRemoveCommit",
|
||||
"testGroupByAddRemoveNoCommit",
|
||||
"testGroupOrder",
|
||||
"testGroupTransient"
|
||||
];
|
||||
|
||||
// todo: run with different sizes
|
||||
var size = 1234;
|
||||
|
||||
function setup() {
|
||||
for (var i = 0; i < size; i++) {
|
||||
var org = new Organisation();
|
||||
org.name = "Organisation " + i;
|
||||
org.country = "CH" + i.format("0000");
|
||||
// add to different collections
|
||||
if (i % 2 == 0)
|
||||
root.organisations.add(org);
|
||||
else
|
||||
root.organisationsByCountry.add(org);
|
||||
}
|
||||
res.commit();
|
||||
}
|
||||
|
||||
function testGroupByAddRemoveCommit() {
|
||||
var countryCount = root.organisationsByCountry.count();
|
||||
var org = new Organisation();
|
||||
org.country = "AT" + Math.random();
|
||||
org.name = "Helma" + Math.random();
|
||||
root.organisations.add(org);
|
||||
res.commit(); // Commit Transaction
|
||||
|
||||
var country = root.organisationsByCountry.get(org.country);
|
||||
assertEqual(countryCount + 1, root.organisationsByCountry.count());
|
||||
assertNotNull(country);
|
||||
assertEqual(country._prototype, "Country");
|
||||
assertEqual(country._id, org.country);
|
||||
|
||||
org.remove();
|
||||
res.commit(); // Commit Transaction
|
||||
|
||||
assertNull(root.organisationsByCountry.get(org.country));
|
||||
assertEqual(countryCount, root.organisationsByCountry.count());
|
||||
}
|
||||
|
||||
function testGroupByAddRemoveNoCommit() {
|
||||
|
||||
var countryCount = root.organisationsByCountry.count();
|
||||
var org = new Organisation();
|
||||
org.country = "AT" + Math.random();
|
||||
org.name = "Helma" + Math.random();
|
||||
root.organisations.add(org);
|
||||
root.organisationsByCountry.add(org);
|
||||
|
||||
// FIXME HELMABUG: count does not get incremented immediately
|
||||
assertEqual(countryCount + 1, root.organisationsByCountry.count());
|
||||
|
||||
var country = root.organisationsByCountry.get(org.country);
|
||||
assertNotNull(country);
|
||||
assertEqual(country._prototype, "Country");
|
||||
assertEqual(country._id, org.country);
|
||||
assertEqual(country.count(), 1);
|
||||
assertEqual(country.get(0), org);
|
||||
|
||||
root.organisationsByCountry.removeChild(org);
|
||||
org.remove();
|
||||
|
||||
// FIXME HELMABUG: country is still accessible at this point
|
||||
// similar to http://helma.org/bugs/show_bug.cgi?id=551
|
||||
assertNull(root.organisationsByCountry.get(org.country));
|
||||
|
||||
assertEqual(countryCount, root.organisationsByCountry.count());
|
||||
}
|
||||
|
||||
function testGroupOrder() {
|
||||
|
||||
var org1 = new Organisation();
|
||||
org1.country = "AT";
|
||||
org1.name = "Helma" + Math.random();
|
||||
root.organisations.add(org1);
|
||||
|
||||
var org2 = new Organisation();
|
||||
org2.country = "CH01"; // pre-populated items have countries CH0000..C1234
|
||||
org2.name = "Helma" + Math.random();
|
||||
root.organisations.add(org2);
|
||||
|
||||
var org3 = new Organisation();
|
||||
org3.country = "DE";
|
||||
org3.name = "Helma" + Math.random();
|
||||
root.organisations.add(org3);
|
||||
|
||||
var org4 = new Organisation();
|
||||
org4.country = org3.country;
|
||||
org4.name = "Helma" + Math.random();
|
||||
root.organisations.add(org4);
|
||||
|
||||
res.commit();
|
||||
|
||||
// make sure that countries and organisations are sorted in decreasing order (as specified in type.properties)
|
||||
var countries = root.organisationsByCountry.list();
|
||||
assertEqual(countries.length, size + 3);
|
||||
for (var i = 0; i < countries.length; i++) {
|
||||
if (i>0) {
|
||||
assertTrue(root.organisationsByCountry.get(i-1).groupname >= root.organisationsByCountry.get(i).groupname);
|
||||
}
|
||||
for (var j = 0; j < root.organisationsByCountry.get(i); j++) {
|
||||
if (j > 0) {
|
||||
assertTrue(root.organisationsByCountry.get(i).get(j-1).groupname >= root.organisationsByCountry.get(i).get(j).groupname);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
org1.remove();
|
||||
org2.remove();
|
||||
org3.remove();
|
||||
org4.remove();
|
||||
}
|
||||
|
||||
function testGroupTransient() {
|
||||
|
||||
var temp = new Root();
|
||||
var countryCount = temp.organisationsByCountry.count();
|
||||
var org = new Organisation();
|
||||
org.country = "AT" + Math.random();
|
||||
org.name = "Helma" + Math.random();
|
||||
temp.organisationsByCountry.add(org);
|
||||
|
||||
var country = temp.organisationsByCountry.get(org.country);
|
||||
assertEqual(countryCount + 1, temp.organisationsByCountry.count());
|
||||
assertNotNull(country);
|
||||
assertEqual(country._prototype, "Country");
|
||||
assertEqual(country.groupname, org.country);
|
||||
|
||||
// These don't work as org uses the parent from type.properties
|
||||
// which is root.organisations. Not sure if this is a bug or not.
|
||||
// assertEqual(country, org._parent);
|
||||
// org.remove();
|
||||
country.removeChild(org);
|
||||
|
||||
assertNull(root.organisationsByCountry.get(org.country));
|
||||
assertEqual(countryCount, temp.organisationsByCountry.count());
|
||||
}
|
||||
|
||||
function cleanup() {
|
||||
var orgs = root.organisations.list();
|
||||
for each (var org in orgs) {
|
||||
org.remove();
|
||||
}
|
||||
}
|
56
src/dist/apps/test/tests/HopObjectHref.js
vendored
Normal file
56
src/dist/apps/test/tests/HopObjectHref.js
vendored
Normal file
|
@ -0,0 +1,56 @@
|
|||
tests = [
|
||||
"testSimpleParent",
|
||||
"testFallbackParent",
|
||||
"testMountpoints"
|
||||
];
|
||||
|
||||
|
||||
var org;
|
||||
var person1;
|
||||
var person2;
|
||||
|
||||
function setup() {
|
||||
org = new Organisation();
|
||||
org.name = "Helma";
|
||||
root.organisations.add(org);
|
||||
|
||||
person1 = new Person();
|
||||
person1.name = "Hannes";
|
||||
person1.organisation = org;
|
||||
root.persons.add(person1);
|
||||
|
||||
person2 = new Person();
|
||||
person2.name = "Michi";
|
||||
root.persons.add(person2);
|
||||
}
|
||||
|
||||
function testSimpleParent() {
|
||||
assertEqual(org.href(), root.organisations.href() + org.name + "/");
|
||||
assertEqual(root.organisations, org._parent);
|
||||
assertEqual(root, org._parent._parent);
|
||||
}
|
||||
|
||||
function testFallbackParent() {
|
||||
assertEqual(person1.href(), person1.organisation.persons.href() + person1.name + "/");
|
||||
assertEqual(person1.organisation.persons, person1._parent);
|
||||
|
||||
assertEqual(person2.href(), root.persons.href() + person2._id + "/");
|
||||
assertEqual(root.persons, person2._parent);
|
||||
}
|
||||
|
||||
function testMountpoints() {
|
||||
assertEqual(root.someMountpoint._prototype, "SomeMountpoint");
|
||||
assertEqual(root.someMountpoint._parent, root);
|
||||
assertEqual(root.someMountpoint.href(), root.href() + "someMountpoint/");
|
||||
|
||||
assertEqual(org.someMountpoint._prototype, "SomeMountpoint");
|
||||
assertEqual(org.someMountpoint._parent, org);
|
||||
// FIXME: Helma-Bug ? mountpoints are converted to lower case ?
|
||||
assertEqual(org.someMountpoint.href(), org.href() + "someMountpoint/");
|
||||
}
|
||||
|
||||
function cleanup() {
|
||||
org.remove();
|
||||
person1.remove();
|
||||
person2.remove();
|
||||
}
|
40
src/dist/apps/test/tests/HopObjectReference.js
vendored
Normal file
40
src/dist/apps/test/tests/HopObjectReference.js
vendored
Normal file
|
@ -0,0 +1,40 @@
|
|||
tests = [
|
||||
"testForward",
|
||||
"testBackward",
|
||||
];
|
||||
|
||||
function setup() {
|
||||
var org = new Organisation();
|
||||
var person = new Person();
|
||||
org.name = "Acme Hovercraft";
|
||||
person.name = "Murray Feather";
|
||||
person.organisation = org;
|
||||
org.person = person;
|
||||
person.persist();
|
||||
res.commit();
|
||||
}
|
||||
|
||||
function testForward() {
|
||||
app.clearCache();
|
||||
person = root.persons.get(0);
|
||||
org = root.organisations.get(0);
|
||||
assertEqual(person.organisation, org);
|
||||
assertEqual(person.organisation.name, org.name);
|
||||
assertEqual("Acme Hovercraft", org.name);
|
||||
}
|
||||
|
||||
function testBackward() {
|
||||
app.clearCache();
|
||||
var person = root.persons.get(0);
|
||||
var org = root.organisations.get(0);
|
||||
assertEqual(org.person, person);
|
||||
assertEqual(org.person.name, person.name);
|
||||
assertEqual("Murray Feather", person.name);
|
||||
}
|
||||
|
||||
function cleanup() {
|
||||
var person = root.persons.get(0);
|
||||
var org = root.organisations.get(0);
|
||||
org.remove();
|
||||
person.remove();
|
||||
}
|
319
src/dist/apps/test/tests/Skin.js
vendored
Normal file
319
src/dist/apps/test/tests/Skin.js
vendored
Normal file
|
@ -0,0 +1,319 @@
|
|||
var tests = [
|
||||
"testCommentMacro",
|
||||
"testDeepResolve",
|
||||
"testDeepUnhandled",
|
||||
"testDeep",
|
||||
"testDeepFail",
|
||||
"testDeepFailSilent",
|
||||
"testJavaProp",
|
||||
"testJavaMissing",
|
||||
"testJavaMissingSilent",
|
||||
"testJavaMissingVerbose",
|
||||
"testUndefinedHandler",
|
||||
"testJSProp",
|
||||
"testJSMacro",
|
||||
"testJSFunction",
|
||||
"testJSMissing",
|
||||
"testJSMissingSilent",
|
||||
"testJSMissingVerbose",
|
||||
"testDateFilter",
|
||||
"testNestedRootMacro",
|
||||
"testNestedParamMacro",
|
||||
"testNestedResponseMacro",
|
||||
"testNestedPrefixSuffix",
|
||||
"testResponseProp",
|
||||
"testResponseMacro",
|
||||
"testResponseFunction",
|
||||
"testResponseMissing",
|
||||
"testResponseMissingSilent",
|
||||
"testResponseMissingVerbose",
|
||||
"testRootProp",
|
||||
"testRootMacro",
|
||||
"testRootMissing",
|
||||
"testRootMissingSilent",
|
||||
"testRootMissingVerbose",
|
||||
"testSessionProp",
|
||||
"testSessionMacro",
|
||||
"testSessionFunction",
|
||||
"testSessionMissing",
|
||||
"testSessionMissingDefault",
|
||||
"testSessionMissingSilent",
|
||||
"testSessionMissingVerbose",
|
||||
"testSessionDeepMissing",
|
||||
"testSubskins"
|
||||
];
|
||||
|
||||
var setup = function() {
|
||||
res.handlers.color = new java.awt.Color["(int,int,int)"](0, 255, 0);
|
||||
res.handlers.file = new java.io.File["(java.lang.String,java.lang.String)"](null, "file");
|
||||
res.handlers.jsobject = {
|
||||
banana: "yellow",
|
||||
kiwi_macro: function() { return this.kiwiColor },
|
||||
apple: function() {},
|
||||
kiwiColor: "green"
|
||||
};
|
||||
res.data.date = new Date();
|
||||
res.data.banana = "yellow";
|
||||
res.data.kiwi_macro = function() { return "green" };
|
||||
res.data.apple = function() {};
|
||||
session.data.banana = "yellow";
|
||||
session.data.kiwi_macro = function() { return "green" };
|
||||
session.data.apple = function() {};
|
||||
};
|
||||
|
||||
var testCommentMacro = function() {
|
||||
var skin = createSkin("<% // this.foo bar=<% this.foobar %> FIXME %>ok");
|
||||
var result = renderSkinAsString(skin);
|
||||
assertEqual(result, "ok");
|
||||
}
|
||||
|
||||
var testDeepResolve = function() {
|
||||
res.handlers.deep = {
|
||||
getMacroHandler: function(name) {
|
||||
if (name != "foo") return null;
|
||||
return {
|
||||
bar_macro: function() {
|
||||
return "ok";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var result = renderSkinAsString(createSkin("<% deep.foo.bar %>"));
|
||||
assertEqual(result, "ok");
|
||||
};
|
||||
|
||||
var testDeepUnhandled = function() {
|
||||
res.handlers.deep = {
|
||||
getMacroHandler: function(name) {
|
||||
if (name != "foo") return null;
|
||||
return {
|
||||
onUnhandledMacro: function(name) {
|
||||
if (name == "bar") return "ok";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var result = renderSkinAsString(createSkin("<% deep.foo.bar %>"));
|
||||
assertEqual(result, "ok");
|
||||
};
|
||||
|
||||
var testDeep = function() {
|
||||
res.handlers.deep = {
|
||||
foo: {
|
||||
bar: "ok"
|
||||
}
|
||||
}
|
||||
var result = renderSkinAsString(createSkin("<% deep.foo.bar %>"));
|
||||
assertEqual(result, "ok");
|
||||
};
|
||||
|
||||
var testDeepFail = function() {
|
||||
var result = renderSkinAsString(createSkin("<% root.foo.bar %>"));
|
||||
assertStringContains(result, "Unhandled");
|
||||
var result = renderSkinAsString(createSkin("<% root.foo.bar failmode=silent %>"));
|
||||
assertEqual(result, "");
|
||||
};
|
||||
|
||||
var testDeepFailSilent = function() {
|
||||
res.handlers.deep = {
|
||||
foo: {}
|
||||
};
|
||||
var result = renderSkinAsString(createSkin("<% deep.foo.bar %>"));
|
||||
assertEqual(result, "");
|
||||
var result = renderSkinAsString(createSkin("<% deep.foo.bar failmode=verbose %>"));
|
||||
assertStringContains(result, "Unhandled");
|
||||
};
|
||||
|
||||
|
||||
var testJavaProp = function() {
|
||||
var result = renderSkinAsString(createSkin("<% color.green %>"));
|
||||
assertEqual(result, "255");
|
||||
result = renderSkinAsString(createSkin("<% color.red %>"));
|
||||
assertEqual(result, "0");
|
||||
};
|
||||
|
||||
var testJavaMissing = function() {
|
||||
var result = renderSkinAsString(createSkin("<% colo.foo %>"));
|
||||
assertStringContains(result, "Unhandled");
|
||||
};
|
||||
|
||||
var testJavaMissingSilent = function() {
|
||||
var result = renderSkinAsString(createSkin("<% color.foo failmode=silent default=ok %>"));
|
||||
assertEqual(result, "ok");
|
||||
};
|
||||
|
||||
var testJavaMissingVerbose = function() {
|
||||
var result = renderSkinAsString(createSkin("<% color.foo failmode=verbose %>"));
|
||||
assertStringContains(result, "Unhandled");
|
||||
}
|
||||
|
||||
var testUndefinedHandler = function() {
|
||||
var result = renderSkinAsString(createSkin("<% file.parentFile %>"));
|
||||
assertEqual(result, "");
|
||||
};
|
||||
|
||||
var testJSProp = function() {
|
||||
var result = renderSkinAsString(createSkin("<% jsobject.banana %>"));
|
||||
assertEqual(result, "yellow");
|
||||
};
|
||||
|
||||
var testJSMacro = function() {
|
||||
var result = renderSkinAsString(createSkin("<% jsobject.kiwi %>"));
|
||||
assertEqual(result, "green");
|
||||
};
|
||||
|
||||
var testJSFunction = function() {
|
||||
var result = renderSkinAsString(createSkin("<% jsobject.apple failmode=silent %>"));
|
||||
assertEqual(result, "");
|
||||
};
|
||||
|
||||
var testJSMissing = function() {
|
||||
var result = renderSkinAsString(createSkin("<% jsobject.papaya %>"));
|
||||
assertEqual(result, "");
|
||||
};
|
||||
|
||||
var testJSMissingSilent = function() {
|
||||
var result = renderSkinAsString(createSkin("<% jsobject.papaya failmode=silent %>"));
|
||||
assertEqual(result, "");
|
||||
};
|
||||
|
||||
var testJSMissingVerbose = function() {
|
||||
var result = renderSkinAsString(createSkin("<% jsobject.papaya failmode=verbose %>"));
|
||||
assertStringContains(result, "Unhandled");
|
||||
};
|
||||
|
||||
var testDateFilter = function() {
|
||||
var result = renderSkinAsString(createSkin("<% root.date | isDate %>"));
|
||||
assertEqual(result, "true");
|
||||
};
|
||||
|
||||
var testNestedRootMacro = function() {
|
||||
var skin = "<% echo <% root.date %> | isRootDate %>";
|
||||
var result = renderSkinAsString(createSkin(skin));
|
||||
assertEqual(result, "true");
|
||||
}
|
||||
|
||||
var testNestedParamMacro = function() {
|
||||
var skin = "<% echo <% param.date %> | isDate %>";
|
||||
var result = renderSkinAsString(createSkin(skin), { date: new Date() });
|
||||
assertEqual(result, "true");
|
||||
}
|
||||
|
||||
|
||||
var testNestedResponseMacro = function() {
|
||||
var skin = "<% echo what=<% response.date %> | isResponseDate %>";
|
||||
var result = renderSkinAsString(createSkin(skin));
|
||||
assertEqual(result, "true");
|
||||
};
|
||||
|
||||
var testNestedPrefixSuffix = function() {
|
||||
var skin = "<% root.macro prefix=<% root.string %> suffix=<% root.macro %> %>";
|
||||
var result = renderSkinAsString(createSkin(skin));
|
||||
// root.macro changes suffix to "."
|
||||
assertEqual(result, "rootroot.");
|
||||
}
|
||||
|
||||
var testResponseProp = function() {
|
||||
var result = renderSkinAsString(createSkin("<% response.banana %>"));
|
||||
assertEqual(result, "yellow");
|
||||
};
|
||||
|
||||
var testResponseMacro = function() {
|
||||
var result = renderSkinAsString(createSkin("<% response.kiwi %>"));
|
||||
assertEqual(result, "green");
|
||||
};
|
||||
|
||||
var testResponseFunction = function() {
|
||||
var result = renderSkinAsString(createSkin("<% response.apple failmode=silent %>"));
|
||||
assertEqual(result, "");
|
||||
};
|
||||
|
||||
var testResponseMissing = function() {
|
||||
var result = renderSkinAsString(createSkin("<% response.papaya %>"));
|
||||
assertEqual(result, "");
|
||||
};
|
||||
|
||||
var testResponseMissingSilent = function() {
|
||||
var result = renderSkinAsString(createSkin("<% response.papaya failmode=silent %>"));
|
||||
assertEqual(result, "");
|
||||
};
|
||||
|
||||
var testResponseMissingVerbose = function() {
|
||||
var result = renderSkinAsString(createSkin("<% response.papaya failmode=verbose %>"));
|
||||
assertStringContains(result, "Unhandled");
|
||||
};
|
||||
|
||||
var testRootProp = function() {
|
||||
var result = renderSkinAsString(createSkin("<% root.string %>"));
|
||||
assertEqual(result, "root");
|
||||
};
|
||||
|
||||
var testRootMacro = function() {
|
||||
var result = renderSkinAsString(createSkin("<% root.macro %>"));
|
||||
assertEqual(result, "root");
|
||||
};
|
||||
|
||||
var testRootMissing = function() {
|
||||
var result = renderSkinAsString(createSkin("<% root.undefinedmacro %>"));
|
||||
assertStringContains(result, "Unhandled");
|
||||
};
|
||||
|
||||
var testRootMissingSilent = function() {
|
||||
var result = renderSkinAsString(createSkin("<% root.undefinedmacro failmode=silent %>"));
|
||||
assertEqual(result, "");
|
||||
};
|
||||
|
||||
var testRootMissingVerbose = function() {
|
||||
var result = renderSkinAsString(createSkin("<% root.undefinedmacro failmode=verbose %>"));
|
||||
assertStringContains(result, "Unhandled");
|
||||
};
|
||||
|
||||
var testSessionProp = function() {
|
||||
var result = renderSkinAsString(createSkin("<% session.banana %>"));
|
||||
assertEqual(result, "yellow");
|
||||
};
|
||||
|
||||
var testSessionMacro = function() {
|
||||
var result = renderSkinAsString(createSkin("<% session.kiwi %>"));
|
||||
assertEqual(result, "green");
|
||||
};
|
||||
|
||||
var testSessionFunction = function() {
|
||||
var result = renderSkinAsString(createSkin("<% session.apple failmode=silent %>"));
|
||||
assertEqual(result, "");
|
||||
};
|
||||
|
||||
var testSessionMissingDefault = function() {
|
||||
var result = renderSkinAsString(createSkin("<% session.papaya default=nope %>"));
|
||||
assertEqual(result, "nope");
|
||||
};
|
||||
|
||||
var testSessionMissing = function() {
|
||||
var result = renderSkinAsString(createSkin("<% session.papaya %>"));
|
||||
assertEqual(result, "");
|
||||
};
|
||||
|
||||
var testSessionMissingSilent = function() {
|
||||
var result = renderSkinAsString(createSkin("<% session.papaya failmode=silent %>"));
|
||||
assertEqual(result, "");
|
||||
};
|
||||
|
||||
var testSessionMissingVerbose = function() {
|
||||
var result = renderSkinAsString(createSkin("<% session.papaya failmode=verbose %>"));
|
||||
assertStringContains(result, "Unhandled");
|
||||
};
|
||||
|
||||
var testSessionDeepMissing = function() {
|
||||
var result = renderSkinAsString(createSkin("<% session.user.name %>"));
|
||||
assertStringContains(result, "Unhandled");
|
||||
// assertEqual(result, "");
|
||||
};
|
||||
|
||||
var testSubskins = function() {
|
||||
var result = renderSkinAsString("subskins");
|
||||
assertEqual(result, "mainskin");
|
||||
result = renderSkinAsString("subskins#subskin1");
|
||||
assertEqual(result, "subskin1");
|
||||
result = renderSkinAsString("subskins#subskin2");
|
||||
assertEqual(result, "subskin2");
|
||||
};
|
68
src/dist/apps/test/tests/helma.Http.js
vendored
Normal file
68
src/dist/apps/test/tests/helma.Http.js
vendored
Normal file
|
@ -0,0 +1,68 @@
|
|||
var tests = [
|
||||
"testSimple",
|
||||
"testError",
|
||||
"testNotFound",
|
||||
"testRedirect",
|
||||
"testRedirectNoFollow",
|
||||
"testMaxResponseSize",
|
||||
"testLongResponse"
|
||||
];
|
||||
|
||||
app.addRepository("modules/helma/Http.js");
|
||||
|
||||
var http = new helma.Http();
|
||||
|
||||
var testSimple = function() {
|
||||
var result = http.getUrl(root.href("hello"));
|
||||
assertEqual(result.content, "Hello");
|
||||
assertEqual(result.code, 200);
|
||||
};
|
||||
|
||||
var testError = function() {
|
||||
var result = http.getUrl(root.href("throwerror"));
|
||||
assertEqual(result.content, "Error");
|
||||
assertEqual(result.code, 500);
|
||||
};
|
||||
|
||||
var testNotFound = function() {
|
||||
var result = http.getUrl(root.href("nonExistingAction"));
|
||||
assertEqual(result.content, "Not found");
|
||||
assertEqual(result.code, 404);
|
||||
};
|
||||
|
||||
var testRedirect = function() {
|
||||
var result = http.getUrl(root.href("redirect"));
|
||||
assertEqual(result.content, "Hello");
|
||||
assertEqual(result.code, 200);
|
||||
};
|
||||
|
||||
var testRedirectNoFollow = function() {
|
||||
http.setFollowRedirects(false);
|
||||
var result = null;
|
||||
try {
|
||||
result = http.getUrl(root.href("redirect"));
|
||||
} finally {
|
||||
http.setFollowRedirects(true);
|
||||
}
|
||||
assertEqual(result.content, "");
|
||||
// response codes 302 and 303 are both ok
|
||||
assertTrue(result.code == 302 || result.code == 303);
|
||||
};
|
||||
|
||||
var testMaxResponseSize = function() {
|
||||
http.setMaxResponseSize(3);
|
||||
var error = null;
|
||||
try {
|
||||
http.getUrl(root.href("hello"));
|
||||
} catch (err) {
|
||||
error = err;
|
||||
} finally {
|
||||
http.setMaxResponseSize(null);
|
||||
}
|
||||
assertNotNull(error);
|
||||
};
|
||||
|
||||
var testLongResponse = function() {
|
||||
var result = http.getUrl(root.href("long"));
|
||||
assertEqual(result.content, makeLongString());
|
||||
};
|
347
src/dist/apps/test/tests/helma.Search.js
vendored
Normal file
347
src/dist/apps/test/tests/helma.Search.js
vendored
Normal file
|
@ -0,0 +1,347 @@
|
|||
var tests = [
|
||||
"testConstructor",
|
||||
"testGetDirectory",
|
||||
"testGetRAMDirectory",
|
||||
"testCreateIndex",
|
||||
"testGetReaderWriter",
|
||||
"testIndexLock",
|
||||
"testDocument",
|
||||
"testAddDocuments",
|
||||
"testSearch"
|
||||
];
|
||||
|
||||
app.addRepository("modules/helma/Search.js");
|
||||
|
||||
var indexName = "testindex";
|
||||
var basePath = java.lang.System.getProperty("java.io.tmpdir");
|
||||
var index;
|
||||
|
||||
/**
|
||||
* Test preliminaries
|
||||
*/
|
||||
var setup = function() {
|
||||
// check if there is a (leftover) directory with the same name
|
||||
// in the system's temporary directory - if so throw an exception and stop
|
||||
var dir = new helma.File(basePath, indexName);
|
||||
if (dir.exists()) {
|
||||
throw "There is already a directory '" + dir.getAbsolutePath() +
|
||||
"', please remove it before trying to run test again";
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Test the helma.Search constructor to make sure Lucene is loaded
|
||||
*/
|
||||
var testConstructor = function() {
|
||||
// should not throw an exception
|
||||
var s = new helma.Search();
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Test getDirectory method
|
||||
*/
|
||||
var testGetDirectory = function() {
|
||||
var search = new helma.Search();
|
||||
assertThrows(function() {
|
||||
search.getDirectory();
|
||||
});
|
||||
var dirs = [
|
||||
new helma.File(basePath, indexName),
|
||||
new File(basePath, indexName),
|
||||
new java.io.File(basePath, indexName),
|
||||
basePath + "/" + indexName
|
||||
];
|
||||
var dir, fsDir, dirPath;
|
||||
for (var i in dirs) {
|
||||
dir = dirs[i];
|
||||
if (dir.constructor != String) {
|
||||
dirPath = dir.getAbsolutePath();
|
||||
} else {
|
||||
dirPath = dir;
|
||||
}
|
||||
fsDir = search.getDirectory(dir);
|
||||
assertNotNull(fsDir);
|
||||
assertEqual(fsDir.getFile().getAbsolutePath(), dirPath);
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Test getRAMDirectory method
|
||||
*/
|
||||
var testGetRAMDirectory = function() {
|
||||
var search = new helma.Search();
|
||||
assertThrows(function() {
|
||||
search.getDirectory();
|
||||
});
|
||||
var dirs = [
|
||||
new helma.File(basePath, indexName),
|
||||
new File(basePath, indexName),
|
||||
new java.io.File(basePath, indexName),
|
||||
basePath + "/" + indexName
|
||||
];
|
||||
var dir, ramDir;
|
||||
for (var i in dirs) {
|
||||
dir = dirs[i];
|
||||
ramDir = search.getRAMDirectory(dir);
|
||||
assertNotNull(ramDir);
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Test index creation - this method creates a RAMDirectory based
|
||||
* index for testing and stores it in the global variable "index"
|
||||
*/
|
||||
var testCreateIndex = function() {
|
||||
var search = new helma.Search();
|
||||
// test creating a file based index
|
||||
var fsDir = search.getDirectory(new helma.File(basePath, indexName));
|
||||
index = search.createIndex(fsDir);
|
||||
assertNotNull(index);
|
||||
// explicitly test index.create(true)
|
||||
assertTrue(index.create(true));
|
||||
|
||||
// test creating a ram based index
|
||||
var ramDir = search.getRAMDirectory();
|
||||
index = search.createIndex(ramDir);
|
||||
assertNotNull(index);
|
||||
// explicitly test index.create(true)
|
||||
assertTrue(index.create(true));
|
||||
assertEqual(index.constructor, helma.Search.Index);
|
||||
assertEqual(index.size(), 0);
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Test getting index reader, writer and modifier
|
||||
*/
|
||||
var testGetReaderWriter = function() {
|
||||
// test getReader
|
||||
var reader = index.getReader();
|
||||
assertNotNull(reader);
|
||||
reader.close();
|
||||
// test getWriter
|
||||
var writer = index.getWriter();
|
||||
assertNotNull(writer);
|
||||
writer.close();
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Test index locking
|
||||
*/
|
||||
var testIndexLock = function() {
|
||||
// test if the index is correctly locked when opening a writer
|
||||
var writer = index.getWriter();
|
||||
assertTrue(index.isLocked());
|
||||
// test if getWriter() throws an exception when trying to open a second writer
|
||||
assertThrows(function() {
|
||||
index.getWriter();
|
||||
});
|
||||
writer.close();
|
||||
assertFalse(index.isLocked());
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Test document constructor and methods
|
||||
*/
|
||||
var testDocument = function() {
|
||||
var doc = new helma.Search.Document();
|
||||
var f;
|
||||
|
||||
// test type conversion
|
||||
f = new helma.Search.Document.Field("id", 1);
|
||||
assertEqual(f.value.constructor, String);
|
||||
assertEqual(f.value, "1");
|
||||
var now = new Date();
|
||||
f = new helma.Search.Document.Field("createtime", now);
|
||||
assertEqual(f.dateValue.constructor, Date);
|
||||
assertEqual(f.dateValue.getTime(), now.getTime() - (now.getTime() % 60000));
|
||||
|
||||
// test adding field with default store and index options
|
||||
doc.addField(new helma.Search.Document.Field("id", 1));
|
||||
f = doc.getField("id");
|
||||
assertNotNull(f);
|
||||
assertTrue(f.isStored());
|
||||
assertTrue(f.isIndexed());
|
||||
assertTrue(f.isTokenized());
|
||||
|
||||
// test adding date field with changed field options
|
||||
f = new helma.Search.Document.Field("createtime", new Date(), {
|
||||
store: "no",
|
||||
index: "tokenized"
|
||||
});
|
||||
doc.addField(f);
|
||||
f = doc.getField("createtime");
|
||||
assertNotNull(f);
|
||||
assertFalse(f.isStored());
|
||||
assertTrue(f.isIndexed());
|
||||
assertTrue(f.isTokenized());
|
||||
|
||||
// test deprecated way of calling addField()
|
||||
doc.addField("title", "Just a test", {
|
||||
"store": false,
|
||||
"index": true,
|
||||
"tokenize": false
|
||||
});
|
||||
f = doc.getField("title");
|
||||
assertNotNull(f);
|
||||
assertFalse(f.isStored());
|
||||
assertTrue(f.isIndexed());
|
||||
assertFalse(f.isTokenized());
|
||||
|
||||
// test getFields()
|
||||
var fields = doc.getFields();
|
||||
assertEqual(fields.length, 3);
|
||||
assertEqual(fields[0].name, "id");
|
||||
assertEqual(fields[1].name, "createtime");
|
||||
assertEqual(fields[2].name, "title");
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Test adding documents
|
||||
*/
|
||||
var testAddDocuments = function() {
|
||||
// test addDocument()
|
||||
var doc = new helma.Search.Document();
|
||||
doc.addField(new helma.Search.Document.Field("id", 1));
|
||||
index.addDocument(doc);
|
||||
assertEqual(index.size(), 1);
|
||||
|
||||
// test removeDocument()
|
||||
index.removeDocument("id", 1);
|
||||
assertEqual(index.size(), 0);
|
||||
|
||||
// test addDocuments() and removeDocuments() with an array
|
||||
doc = new helma.Search.Document();
|
||||
doc.addField(new helma.Search.Document.Field("id", 2));
|
||||
index.addDocuments([doc]);
|
||||
assertEqual(index.size(), 1);
|
||||
index.removeDocuments("id", [2]);
|
||||
assertEqual(index.size(), 0);
|
||||
|
||||
// test addDocuments() and removeDocuments() with a Hashtable as argument
|
||||
var ht = new java.util.Hashtable();
|
||||
ht.put("doc", doc);
|
||||
index.addDocuments(ht);
|
||||
ht = new java.util.Hashtable();
|
||||
ht.put("id", 1);
|
||||
ht.put("id", 2);
|
||||
index.removeDocuments("id", ht);
|
||||
assertEqual(index.size(), 0);
|
||||
|
||||
// test addDocuments() and removeDocuments() with a Vector as argument
|
||||
var v = new java.util.Vector();
|
||||
v.add(doc);
|
||||
index.addDocuments(v);
|
||||
v = new java.util.Vector();
|
||||
v.add(1);
|
||||
v.add(2);
|
||||
index.removeDocuments("id", v);
|
||||
assertEqual(index.size(), 0);
|
||||
|
||||
// test updateDocument
|
||||
index.addDocument(doc);
|
||||
doc = new helma.Search.Document();
|
||||
doc.addField("id", 2);
|
||||
index.updateDocument(doc, "id");
|
||||
assertEqual(index.size(), 1);
|
||||
|
||||
// test count()
|
||||
doc = new helma.Search.Document();
|
||||
doc.addField("id", 3);
|
||||
index.addDocument(doc);
|
||||
assertEqual(index.count("id", 3), 1);
|
||||
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Test searching the index
|
||||
*/
|
||||
var testSearch = function() {
|
||||
// clear the index
|
||||
index.create();
|
||||
assertEqual(index.size(), 0);
|
||||
|
||||
// populate the index with test content
|
||||
var names = [
|
||||
"foo",
|
||||
"bar",
|
||||
"baz"
|
||||
];
|
||||
|
||||
var now = new Date();
|
||||
var doc;
|
||||
names.forEach(function(name, idx) {
|
||||
doc = new helma.Search.Document();
|
||||
doc.addField("id", idx + 1);
|
||||
doc.addField("parent", idx % 2);
|
||||
doc.addField("name", name);
|
||||
doc.addField("timestamp", new Date(now.getTime() - (idx * 1e6)));
|
||||
index.addDocument(doc);
|
||||
});
|
||||
assertEqual(index.size(), 3);
|
||||
|
||||
var searcher = index.getSearcher();
|
||||
assertNotNull(searcher);
|
||||
assertNull(searcher.sortFields);
|
||||
assertNotNull(searcher.getSearcher());
|
||||
assertTrue(searcher.getSearcher() instanceof Packages.org.apache.lucene.search.IndexSearcher);
|
||||
|
||||
// test basic search
|
||||
var q = new helma.Search.TermQuery("id", 1);
|
||||
assertEqual(searcher.search(q), 1);
|
||||
assertNotNull(searcher.hits);
|
||||
assertEqual(searcher.hits.constructor, helma.Search.HitCollection);
|
||||
assertEqual(searcher.hits.size(), 1);
|
||||
var hit = searcher.hits.get(0);
|
||||
assertNotNull(hit);
|
||||
assertEqual(hit.constructor, helma.Search.Document);
|
||||
assertEqual(hit.getField("name").constructor, helma.Search.Document.Field);
|
||||
assertEqual(hit.getField("name").value, "foo");
|
||||
// test date value conversion
|
||||
assertEqual(hit.getField("timestamp").value.constructor, String);
|
||||
assertEqual(hit.getField("timestamp").dateValue.constructor, Date);
|
||||
|
||||
// test query filter
|
||||
var qf = new helma.Search.QueryFilter(new helma.Search.TermQuery("parent", 0));
|
||||
q = new helma.Search.WildcardQuery("name", "ba*");
|
||||
assertEqual(searcher.search(q, qf), 1);
|
||||
assertEqual(searcher.hits.get(0).getField("name").value, names[2]);
|
||||
|
||||
// test sorting of hits
|
||||
searcher.sortBy("id", true);
|
||||
assertEqual(searcher.search(q), 2);
|
||||
assertEqual(searcher.hits.get(0).getField("name").value, names[2]);
|
||||
assertEqual(searcher.hits.get(1).getField("name").value, names[1]);
|
||||
|
||||
// test boolean query
|
||||
q = new helma.Search.BooleanQuery();
|
||||
q.addTerm("parent", "0");
|
||||
assertEqual(q.toString(), "[(parent:0)]");
|
||||
q = new helma.Search.BooleanQuery();
|
||||
q.addTerm("parent", "0", "and");
|
||||
assertEqual(q.toString(), "[+(parent:0)]");
|
||||
q = new helma.Search.BooleanQuery();
|
||||
q.addTerm("parent", "0", "not");
|
||||
assertEqual(q.toString(), "[-(parent:0)]");
|
||||
|
||||
searcher.close();
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Cleanup
|
||||
*/
|
||||
var cleanup = function() {
|
||||
// remove the directory containing the test index
|
||||
var dir = new helma.File(basePath, indexName);
|
||||
dir.removeDirectory();
|
||||
return;
|
||||
}
|
11
src/dist/apps/welcome/code/Global/init.js
vendored
Normal file
11
src/dist/apps/welcome/code/Global/init.js
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
function onStart(name) {
|
||||
if (!root.get('first')) {
|
||||
root.name = 'root';
|
||||
var firstNode = new HopObject();
|
||||
firstNode.name = 'first';
|
||||
root.add(firstNode)
|
||||
var secondNode = new HopObject();
|
||||
secondNode.name = 'second';
|
||||
firstNode.add(secondNode)
|
||||
}
|
||||
}
|
8
src/dist/apps/welcome/code/Guide/handler.js
vendored
Normal file
8
src/dist/apps/welcome/code/Guide/handler.js
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
function getChildElement(name) {
|
||||
if (this.get(name))
|
||||
return this.get(name);
|
||||
var page = new Guide();
|
||||
page.name = name;
|
||||
page.parent = this;
|
||||
return page;
|
||||
}
|
40
src/dist/apps/welcome/code/Guide/intro.actions.skin
vendored
Normal file
40
src/dist/apps/welcome/code/Guide/intro.actions.skin
vendored
Normal file
|
@ -0,0 +1,40 @@
|
|||
<h1>actions</h1>
|
||||
|
||||
<p>Every request a Helma application receives is handled by an "action"
|
||||
associated with the requested URL. For example, a request to
|
||||
<a href="http://<% request.http_host %>/example">
|
||||
http://<% request.http_host %>/example</a> will be handled by the
|
||||
"example" action, defined at ./apps/welcome/code/Root/example.hac</p>
|
||||
|
||||
<pre>
|
||||
res.write('Hello, this is the action defined \
|
||||
at ./apps/welcome/code/Root/example.hac');
|
||||
</pre>
|
||||
|
||||
<p>The file example.hac contains the Javascript code that Helma will
|
||||
evaluate when handling that request. In this example, the code inside
|
||||
the example.hac file automatically becomes a prototype method with an
|
||||
"_action" suffix. By leveraging such conventions, Helma allows you to
|
||||
structure your code in clean and uncluttered ways. Alternatively, you
|
||||
can also define actions in generic Javascript files, an examples of
|
||||
which can be found in ./apps/welcome/code/Root/example.js and tested via
|
||||
the URL <a href="http://<% request.http_host %>/anotherexample">
|
||||
http://<% request.http_host %>/anotherexample</a></p>
|
||||
|
||||
<pre>
|
||||
function anotherexample_action() {
|
||||
res.write('Hello again, this is the action \
|
||||
defined in ./apps/welcome/Root/example.js');
|
||||
}
|
||||
</pre>
|
||||
|
||||
<p>Requests that do not specify a particular action are handled by the
|
||||
"main" action. For example, a request to
|
||||
<a href="http://<% request.http_host %>/">http://<% request.http_host %>/</a>
|
||||
will be handled by the "main" action, defined at
|
||||
./apps/welcome/code/Guide/main.hac</p>
|
||||
|
||||
<p>More information about the way Helma handles requests and maps them to
|
||||
actions, and how Helma maps directories and filename extensions to
|
||||
objects in the Javascript environment:
|
||||
<br /><a href="http://dev.helma.org/docs/Request-Response-Cycle/">/docs/Request-Response-Cycle/</a></p>
|
48
src/dist/apps/welcome/code/Guide/intro.applications.skin
vendored
Normal file
48
src/dist/apps/welcome/code/Guide/intro.applications.skin
vendored
Normal file
|
@ -0,0 +1,48 @@
|
|||
<h1>applications</h1>
|
||||
|
||||
<p>Helma can serve multiple independent applications, each accessible
|
||||
through a different mountpoint, using Javascript environments
|
||||
running in their own global scope, and configurable to use separate
|
||||
code repositories.</p>
|
||||
|
||||
<p>A Helma default installation, for example, is serving the applications
|
||||
"manage" and "welcome" and makes them accessible through the
|
||||
<a href="http://<% request.http_host %>/manage/">
|
||||
http://<% request.http_host %>/manage/</a> and
|
||||
<a href="http://<% request.http_host %>/">http://<% request.http_host %>/</a>
|
||||
URLs respectively. The list of active applications is defined by the file
|
||||
./apps.properties in Helma's home directory.</p>
|
||||
|
||||
<pre>
|
||||
# Administrative application to manage all
|
||||
# other apps on this server, accessible via its
|
||||
# default mountpoint at http://host:port/manage
|
||||
# and using its default repository at apps/manage
|
||||
|
||||
manage
|
||||
|
||||
|
||||
# More complex example of an application with
|
||||
# custom configuration:
|
||||
|
||||
welcome
|
||||
welcome.mountpoint = /
|
||||
welcome.repository.0 = apps/welcome/code/
|
||||
welcome.repository.1 = modules/helmaTools.zip
|
||||
welcome.static = apps/welcome/static
|
||||
welcome.staticMountpoint = /static
|
||||
welcome.staticHome = index.html,default.html
|
||||
welcome.staticIndex = true
|
||||
welcome.uploadLimit = 2048
|
||||
</pre>
|
||||
|
||||
<p>Further application specific configurations can be defined in an app.properties
|
||||
file inside an application's code repository. Examples of such a file you will
|
||||
find in the "manage" app's default repository directory at
|
||||
./apps/manage/app.properties and in the "welcome" application's repository at
|
||||
./apps/welcome/code/app.properties.</p>
|
||||
|
||||
<p>More information about these files:
|
||||
<br /><a href="http://dev.helma.org/docs/Properties+Files/apps.properties/">/docs/Properties+Files/apps.properties/</a>
|
||||
<br /><a href="http://dev.helma.org/docs/Properties+Files/app.properties/">/docs/Properties+Files/app.properties/</a>
|
||||
</p>
|
56
src/dist/apps/welcome/code/Guide/intro.dbmapping.skin
vendored
Normal file
56
src/dist/apps/welcome/code/Guide/intro.dbmapping.skin
vendored
Normal file
|
@ -0,0 +1,56 @@
|
|||
<h1>database mapping</h1>
|
||||
|
||||
<p>Helma allows you to map your HopObjects to relational database tables
|
||||
instead of persisting them in the application's embedded XML database.</p>
|
||||
|
||||
<p>The list of available database connections is defined inside the file
|
||||
./db.properties in Helma's home directory or for application specific
|
||||
configurations in a db.properties file inside an application's code
|
||||
repository.</p>
|
||||
|
||||
<pre>
|
||||
myDataSource.url = jdbc:mysql://db.domain.com/space
|
||||
myDataSource.driver = org.gjt.mm.mysql.Driver
|
||||
myDataSource.user = username
|
||||
myDataSource.password = xyz
|
||||
</pre>
|
||||
|
||||
<p>In order to add the specified JDBC driver to the classpath, place it in
|
||||
the ./lib/ext/ directory. Depending on the database system you are using,
|
||||
you may want to <a href="http://developers.sun.com/product/jdbc/drivers">
|
||||
download an appropriate JDBC driver</a>, for example a
|
||||
<a href="http://www.mysql.com/downloads/api-jdbc-stable.html">driver for
|
||||
MySQL</a>.</p>
|
||||
|
||||
<p>Using the <a href="sqlshell">SQLshell</a> from within your application,
|
||||
you may at any time explore your database and issue SQL statements.
|
||||
The SQLshell also allows you to map your database tables to properties
|
||||
of your application's prototypes as desired. A simple configuration for
|
||||
your object/relational mappings might look as follows:</p>
|
||||
|
||||
<pre>
|
||||
_db = myDataSource
|
||||
_table = PERSON
|
||||
_id = ID
|
||||
|
||||
firstname = FIRSTNAME
|
||||
lastname = LASTNAME
|
||||
email = EMAIL
|
||||
createtime = CREATETIME
|
||||
modifytime = MODIFYTIME
|
||||
</pre>
|
||||
|
||||
<p>These configurations would be placed in a type.properties file
|
||||
inside the corresponding prototype directory, for example in
|
||||
./apps/addressbook/Person/type.properties, when following the
|
||||
"addressbook" tutorial.</p>
|
||||
|
||||
<p>To learn how Helma's relational database mapping is put to work and
|
||||
how it relates and integrates with the other central aspects of the
|
||||
framework, <a href="http://dev.helma.org/docs/Object-Relational+Mapping+Tutorial/">follow the
|
||||
tutorial and build the full "addressbook" application</a>.</p>
|
||||
|
||||
<p>More information about the object/relational mapping of HopObject properties:
|
||||
<br /><a href="http://dev.helma.org/docs/Properties+Files/db.properties/">/docs/Properties+Files/db.properties/</a>
|
||||
<br /><a href="http://dev.helma.org/docs/Object-Relational+Mapping/">/docs/Object-Relational+Mapping/</a>
|
||||
</p>
|
37
src/dist/apps/welcome/code/Guide/intro.hopobjects.skin
vendored
Normal file
37
src/dist/apps/welcome/code/Guide/intro.hopobjects.skin
vendored
Normal file
|
@ -0,0 +1,37 @@
|
|||
<h1>hopobjects</h1>
|
||||
|
||||
<p>HopObjects extend the standard Javascript object with Helma-specific
|
||||
properties and functions. They are the central building blocks that allow
|
||||
you to leverage the application framework Helma provides.</p>
|
||||
|
||||
<p>The main HopObject of every application is the "root" object. Every
|
||||
HopObject can have a collection of attached additional HopObjects.
|
||||
Each requested URL is resolved to a particular HopObject according
|
||||
to these collections.</p>
|
||||
|
||||
<p>In the "welcome" application for example, a request to
|
||||
<a href="http://<% request.http_host %>/first/second/">
|
||||
http://<% request.http_host %>/first/second/</a> will be resolved by
|
||||
checking the "root" object's collection for a HopObject named "first"
|
||||
and the "first" object's collection for a HopObject named "second".</p>
|
||||
|
||||
<p>While this path resolution is by default performed based on the ID of
|
||||
the attached HopObjects, collections can be custom configured to use
|
||||
another property as access name. In this example, the HopObject prototype
|
||||
is configured at ./apps/welcome/code/HopObject/type.properties to use the
|
||||
"name" property for this purpose.</p>
|
||||
|
||||
<pre>
|
||||
_children = collection(HopObject)
|
||||
_children.accessname = name
|
||||
name
|
||||
</pre>
|
||||
|
||||
<p>When a new HopObject is added to such a collection, it is automatically
|
||||
stored in Helma's embedded XML database. To see a detailed example of
|
||||
how this works, go to <a href="http://<% request.http_host %>/first/">
|
||||
http://<% request.http_host %>/first/</a> and add additional HopObjects.</p>
|
||||
|
||||
<p>Documentation of HopObject functions and built-in properties:
|
||||
<br /><a href="http://helma.server-side-javascript.org/reference/HopObject.html">/reference/HopObject.html</a>
|
||||
</p>
|
33
src/dist/apps/welcome/code/Guide/intro.javapackages.skin
vendored
Normal file
33
src/dist/apps/welcome/code/Guide/intro.javapackages.skin
vendored
Normal file
|
@ -0,0 +1,33 @@
|
|||
<h1>java packages</h1>
|
||||
|
||||
<p>Helma puts the whole wealth of Java libraries at your fingertips.
|
||||
The "Packages" object in Helma's Javascript environment serves as
|
||||
the doorway to leverage any Java packages in the CLASSPATH. You can
|
||||
<a href="http://www.docjar.com/">add any Java packages</a> to the
|
||||
CLASSPATH simply by putting the jar files in the ./lib/ext/ directory.</p>
|
||||
|
||||
<p>Any public methods that these Java classes define become callable from
|
||||
your application's Javascript environment and you can create and work
|
||||
with Java objects just like you do with Javascript objects. For example,
|
||||
you could create a Java StringBuffer object and then append data to it
|
||||
as follows:</p>
|
||||
|
||||
<pre>
|
||||
var buffer = new Packages.java.lang.StringBuffer();
|
||||
buffer.append('hello');
|
||||
</pre>
|
||||
|
||||
<p>If your application makes extensive use of a Java class, it might be a
|
||||
good idea to wrap that class in a Javascript prototype. That way, the
|
||||
objects your applications works with become true Javascript objects, you
|
||||
can control exactly which class methods are exposed to your application
|
||||
and you can abstract the implementation, allowing you to change the Java
|
||||
classes you use without requiring modifications to your application.</p>
|
||||
|
||||
<p>Various examples of such wrappers around Java classes can be found in the
|
||||
helmaLib, which makes Mail, File, Ftp, Image, Search, SSH and Zip
|
||||
functionality available in this way.</p>
|
||||
|
||||
<p>More information on how Helma makes Java scriptable:
|
||||
<br /><a href="http://www.mozilla.org/rhino/ScriptingJava.html">/rhino/ScriptingJava</a>
|
||||
</p>
|
52
src/dist/apps/welcome/code/Guide/intro.macros.skin
vendored
Normal file
52
src/dist/apps/welcome/code/Guide/intro.macros.skin
vendored
Normal file
|
@ -0,0 +1,52 @@
|
|||
<h1>macros</h1>
|
||||
|
||||
<p>Macros are methods of application logic that can be called through
|
||||
custom macro tags contained in skins. Macros allow skins to pull
|
||||
data from application logic, while other macro tags only push
|
||||
pre-determined data to the skins.</p>
|
||||
|
||||
<p>You will find an example for such a skin in the "welcome" application
|
||||
at ./apps/welcome/code/Root/example_using_macro.skin</p>
|
||||
|
||||
<pre>
|
||||
<p>This is an example of a skin calling a macro.</p>
|
||||
<p>You will find this skin at
|
||||
./apps/welcome/code/Root/example_using_macro.skin</p>
|
||||
<p>This skin is rendered by the action defined at
|
||||
./apps/welcome/code/Root/example_using_macro.hac</p>
|
||||
<p>The macro this skin calls is defined in
|
||||
./apps/welcome/code/Root/example.js</p>
|
||||
<p>You can test it via the URL
|
||||
<a href="<% this.pullLink part="url" %>">
|
||||
<% this.pullLink part="text" %>
|
||||
</a>
|
||||
</p>
|
||||
</pre>
|
||||
|
||||
<p>In this example, the skin calls a "pullLink" macro twice, using a different
|
||||
"part" parameter. Macro methods are defined using a corresponding function
|
||||
name with a "_macro" suffix. The pullLink macro used in this example, you
|
||||
will find defined in ./apps/welcome/code/Root/example.js</p>
|
||||
|
||||
<pre>
|
||||
function pullLink_macro(params) {
|
||||
switch (params.part) {
|
||||
case 'text' :
|
||||
return '/example_using_macro';
|
||||
case 'url' :
|
||||
return this.href('example_using_macro');;
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
|
||||
<p>You can test this macro and see the skin rendered via the URL
|
||||
<a href="http://<% request.http_host %>/example_using_macro">
|
||||
http://<% request.http_host %>/example_using_macro</a></p>
|
||||
|
||||
<p>Note that macros can again make use of skins, which may again contain
|
||||
macro calls. This combination of skins and macros allows actions to
|
||||
delegate the response generation through multiple tiers of "control"
|
||||
and "presentation".</p>
|
||||
|
||||
<p>More information about macro tags and ways in which you can use custom defined macros:
|
||||
<br /><a href="http://dev.helma.org/docs/Request-Response-Cycle/">/docs/Request-Response-Cycle/</a></p>
|
41
src/dist/apps/welcome/code/Guide/intro.prototypes.skin
vendored
Normal file
41
src/dist/apps/welcome/code/Guide/intro.prototypes.skin
vendored
Normal file
|
@ -0,0 +1,41 @@
|
|||
<h1>prototypes</h1>
|
||||
|
||||
<p>Helma's coding conventions revolve around the prototype based object
|
||||
inheritance of Javascript. While Helma does not force you to leverage
|
||||
these coding conventions, doing so will increase productivity and you
|
||||
will achieve better maintainability due to a clean and well organized
|
||||
code structure.</p>
|
||||
|
||||
<p>The HopObject prototype is the core prototype of every Helma application.
|
||||
By default, other prototypes that you create will inherit from the
|
||||
HopObject prototype. Every directory that you create inside your
|
||||
application's code repository becomes automatically a prototype by that
|
||||
name and will inherit the methods, actions, macros and skins that the
|
||||
HopObject prototype provides.</p>
|
||||
|
||||
<p>In the "welcome" application's code repository at ./apps/welcome/code/
|
||||
for example, you will find directories for the HopObject, Root and Guide
|
||||
prototypes. Both the Root and Guide prototypes inherit automatically any
|
||||
code from the HopObject prototype. Additionally, the Root prototype also
|
||||
inherits from the Guide prototype, due to the "_extends" property that is
|
||||
configured in ./apps/welcome/code/Root/type.properties</p>
|
||||
|
||||
<pre>
|
||||
_extends = Guide
|
||||
</pre>
|
||||
|
||||
<p>"Root" is the prototype of the application's root object. The root object
|
||||
of the "welcome" application therefore uses the combined code from these
|
||||
three prototypes, with code in "Root" overriding code from "Guide", which
|
||||
in turn overrides code from "HopObject".</p>
|
||||
|
||||
<p>When Helma receives a request to <a href="http://<% request.http_host %>/">
|
||||
http://<% request.http_host %>/</a> it will look for a "main" action to
|
||||
handle the request. Since it will not find one in "Root", it will use the
|
||||
one defined at ./apps/welcome/code/Guide/main.hac. Requests pointing to a
|
||||
generic HopObject such as <a href="http://<% request.http_host %>/first/">
|
||||
http://<% request.http_host %>/first/</a> on the other hand, will use the
|
||||
main action defined at ./apps/welcome/code/HopObject/main.hac.</p>
|
||||
|
||||
<p>More information on how Helma puts prototypes to work:
|
||||
<br /><a href="http://dev.helma.org/docs/Request-Response-Cycle/">/docs/Request-Response-Cycle/</a></p>
|
14
src/dist/apps/welcome/code/Guide/intro.skin
vendored
Normal file
14
src/dist/apps/welcome/code/Guide/intro.skin
vendored
Normal file
|
@ -0,0 +1,14 @@
|
|||
<div class="lead">
|
||||
<p>Explore the introductions below and discover what you <br />
|
||||
can do with Helma and Javascript on the server-side.</p>
|
||||
</div>
|
||||
|
||||
<script> openbox('pageintro') </script>
|
||||
<h3>introductions</h3>
|
||||
<% response.listintro %>
|
||||
|
||||
<script> closebox() </script>
|
||||
|
||||
<script> openbox('content') </script>
|
||||
<% response.content %>
|
||||
<script> closebox() </script>
|
44
src/dist/apps/welcome/code/Guide/intro.skins.skin
vendored
Normal file
44
src/dist/apps/welcome/code/Guide/intro.skins.skin
vendored
Normal file
|
@ -0,0 +1,44 @@
|
|||
<h1>skins</h1>
|
||||
|
||||
<p>Helma allows you to cleanly separate presentation from application logic
|
||||
through the use of skins. The skins are segments of HTML markup that can
|
||||
contain macro tags, which are replaced with dynamic content when the
|
||||
skin is rendered.</p>
|
||||
|
||||
<p>You will find an example for such a skin in the "welcome" application at
|
||||
./apps/welcome/code/Root/example.skin</p>
|
||||
|
||||
<pre>
|
||||
<p>This is an example of a simple skin.</p>
|
||||
<p>You will find this skin at
|
||||
./apps/welcome/code/Root/example.skin</p>
|
||||
<p>This skin is rendered by the action defined at
|
||||
./apps/welcome/code/Root/example_using_skin.hac</p>
|
||||
<p>You can test it via the URL
|
||||
<a href="<% response.pushLink %>">
|
||||
<% response.pushLinkText %>
|
||||
</a>
|
||||
</p>
|
||||
</pre>
|
||||
|
||||
<p>The rendering of skins is controlled by an application's actions. In the
|
||||
case of the "welcome" application, you will find an example of such an
|
||||
action at ./apps/welcome/code/Root/example_using_skin.hac</p>
|
||||
|
||||
<pre>
|
||||
res.data.pushLink = this.href('example_using_skin');
|
||||
res.data.pushLinkText = '/example_using_skin';
|
||||
this.renderSkin('example');
|
||||
</pre>
|
||||
|
||||
<p>You can test this action and see the skin rendered via the URL
|
||||
<a href="http://<% request.http_host %>/example_using_skin">
|
||||
http://<% request.http_host %>/example_using_skin</a>
|
||||
|
||||
<p>Skins can contain various kinds of "macro tags" such as <% response.pushLink %>
|
||||
used in this example skin, where the value of a dynamic URL is determined by the
|
||||
action and made available to the skin by setting the req.data.pushLink property.</p>
|
||||
|
||||
<p>More information about the way in which Helma defines and renders skins, and the
|
||||
various kinds of available Macro Tags:
|
||||
<br /><a href="http://dev.helma.org/docs/Request-Response-Cycle/">/docs/Request-Response-Cycle/</a></p>
|
31
src/dist/apps/welcome/code/Guide/intro.staticfiles.skin
vendored
Normal file
31
src/dist/apps/welcome/code/Guide/intro.staticfiles.skin
vendored
Normal file
|
@ -0,0 +1,31 @@
|
|||
<h1>static files</h1>
|
||||
|
||||
<p>The default mountpoint of a Helma application is always a code repository,
|
||||
which means that requests will be handled by the application's Javascript
|
||||
environment and will not reference specific server pages. Static files on
|
||||
the other hand are served from separate "static" mountpoints.</p>
|
||||
|
||||
<p>In Helma's default installation, the "welcome" application is serving
|
||||
static files from its "static" directory at ./apps/welcome/static/
|
||||
and makes them accessible through URLs starting with
|
||||
<a href="http://<% request.http_host %>/static/">
|
||||
http://<% request.http_host %>/static/</a></p>
|
||||
|
||||
<p>For example, you should be able to access the file named "test.txt" inside
|
||||
the ./apps/welcome/static/ directory via the URL
|
||||
<a href="http://<% request.http_host %>/static/test.txt">
|
||||
http://<% request.http_host %>/static/test.txt</a></p>
|
||||
|
||||
<p>Inside the ./apps.properties file, you will find the following settings,
|
||||
which control the related behavior:</p>
|
||||
|
||||
<pre>
|
||||
welcome.static = apps/welcome/static
|
||||
welcome.staticMountpoint = /static
|
||||
welcome.staticHome = index.html,default.html
|
||||
welcome.staticIndex = true
|
||||
</pre>
|
||||
|
||||
<p>More information about these and additional settings related to serving static files:
|
||||
<br /><a href="http://dev.helma.org/docs/Properties+Files/apps.properties/">/docs/Properties+Files/apps.properties/</a>
|
||||
</p>
|
11
src/dist/apps/welcome/code/Guide/list.intro.skin
vendored
Normal file
11
src/dist/apps/welcome/code/Guide/list.intro.skin
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
<ul>
|
||||
<li><a href="<% response.root %>intro/applications">applications</a></li>
|
||||
<li><a href="<% response.root %>intro/staticfiles">static files</a></li>
|
||||
<li><a href="<% response.root %>intro/actions">actions</a></li>
|
||||
<li><a href="<% response.root %>intro/skins">skins</a></li>
|
||||
<li><a href="<% response.root %>intro/macros">macros</a></li>
|
||||
<li><a href="<% response.root %>intro/hopobjects">hopobjects</a></li>
|
||||
<li><a href="<% response.root %>intro/prototypes">prototypes</a></li>
|
||||
<li><a href="<% response.root %>intro/dbmapping">database mappings</a></li>
|
||||
<li><a href="<% response.root %>intro/javapackages">java packages</a></li>
|
||||
</ul>
|
7
src/dist/apps/welcome/code/Guide/list.tools.skin
vendored
Normal file
7
src/dist/apps/welcome/code/Guide/list.tools.skin
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
<ul>
|
||||
<li><a href="<% response.root %>tools/about_manage">manage</a></li>
|
||||
<li><a href="<% response.root %>tools/about_shell">shell</a></li>
|
||||
<li><a href="<% response.root %>tools/about_inspector">inspector</a></li>
|
||||
<li><a href="<% response.root %>tools/about_sqlshell">sqlshell</a></li>
|
||||
<li><a href="<% response.root %>tools/debugger">debugger</a></li>
|
||||
</ul>
|
14
src/dist/apps/welcome/code/Guide/list.website.skin
vendored
Normal file
14
src/dist/apps/welcome/code/Guide/list.website.skin
vendored
Normal file
|
@ -0,0 +1,14 @@
|
|||
<ul>
|
||||
<li><a href="http://dev.helma.org/">home</a></li>
|
||||
<li><a href="http://dev.helma.org/mailing+lists/">mailing lists</a></li>
|
||||
<li><a href="http://helma.server-side-javascript.org/hopbot/">irc channel</a></li>
|
||||
<li><a href="http://dev.helma.org/docs/Documentation/">documentation</a></li>
|
||||
<li><a href="http://helma.server-side-javascript.org/reference/">reference</a></li>
|
||||
<li><a href="http://dev.helma.org/development/">project</a></li>
|
||||
<li><a href="http://dev.helma.org/wiki/Helma+Roadmap/">roadmap</a></li>
|
||||
<li><a href="http://dev.helma.org/bug+reporting/">bug reporting</a></li>
|
||||
<li><a href="http://dev.helma.org/docs/Using+the+Source+Code+Repositories/">source</a></li>
|
||||
<li><a href="http://dev.helma.org/wiki/">wiki</a></li>
|
||||
<li><a href="http://dev.helma.org/wiki/Related+Projects/">related projects</a></li>
|
||||
<li><a href="http://dev.helma.org/wiki/Sites+using+Helma/">sites using helma</a></li>
|
||||
</ul>
|
18
src/dist/apps/welcome/code/Guide/main.hac
vendored
Normal file
18
src/dist/apps/welcome/code/Guide/main.hac
vendored
Normal file
|
@ -0,0 +1,18 @@
|
|||
// Prepare some response values used by the skins
|
||||
res.data.href = this.href();
|
||||
res.data.root = root.href();
|
||||
|
||||
// Render three nested skins
|
||||
res.data.listtools = this.renderSkinAsString('list.tools');
|
||||
res.data.listintro = this.renderSkinAsString('list.intro');
|
||||
res.data.listwebsite = this.renderSkinAsString('list.website');
|
||||
if (this.parent && this.parent.name) {
|
||||
res.data.title = 'Welcome to Helma - '+ this.parent.name +' - '+ this.name;
|
||||
res.data.content = this.renderSkinAsString( this.parent.name +'.'+ this.name );
|
||||
res.data.body = this.renderSkinAsString( this.parent.name );
|
||||
}
|
||||
if (!res.data.body) {
|
||||
res.data.title = 'Welcome to Helma - Overview';
|
||||
res.data.body = this.renderSkinAsString('overview');
|
||||
}
|
||||
this.renderSkin('page');
|
19
src/dist/apps/welcome/code/Guide/overview.skin
vendored
Normal file
19
src/dist/apps/welcome/code/Guide/overview.skin
vendored
Normal file
|
@ -0,0 +1,19 @@
|
|||
<div class="lead">
|
||||
<p>Welcome to Helma! Explore the tools, introductions and resources below and
|
||||
discover what you can do with Helma and Javascript on the server-side.</p>
|
||||
</div>
|
||||
|
||||
<script> openbox('tools') </script>
|
||||
<h3>tools</h3>
|
||||
<% response.listtools %>
|
||||
<script> closebox() </script>
|
||||
|
||||
<script> openbox('intro') </script>
|
||||
<h3>introductions</h3>
|
||||
<% response.listintro %>
|
||||
<script> closebox() </script>
|
||||
|
||||
<script> openbox('website') </script>
|
||||
<h3>helma.org</h3>
|
||||
<% response.listwebsite %>
|
||||
<script> closebox() </script>
|
21
src/dist/apps/welcome/code/Guide/tools.about_inspector.skin
vendored
Normal file
21
src/dist/apps/welcome/code/Guide/tools.about_inspector.skin
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
<h1>inspector</h1>
|
||||
|
||||
<p>The Inspector allows you to inspect and modify the properties of
|
||||
HopObjects and to browse the HopObject tree. For example, you
|
||||
can invoke the Inspector on the HopObject named "first" by
|
||||
accessing the "inspector" action at
|
||||
<a href="http://<% request.http_host %>/first/inspector">
|
||||
http://<% request.http_host %>/first/inspector</a></p>
|
||||
|
||||
<img src="/static/guide/inspector.png" width="480" height="332" />
|
||||
|
||||
<p>Note that access to the Inspector is restricted for obvious security
|
||||
reasons. If you have not yet done so, you will be directed on how
|
||||
to configure administrative access when you attempt to use
|
||||
this tool.</p>
|
||||
|
||||
<p>In order to be able to use the Inspector inside your own application,
|
||||
you will need to add the helmaTools code repository to that
|
||||
application. For example by adding modules/helmaTools.zip to the
|
||||
<a href="/intro/applications">list of its repositories in the
|
||||
./apps.properties file</a>.
|
18
src/dist/apps/welcome/code/Guide/tools.about_manage.skin
vendored
Normal file
18
src/dist/apps/welcome/code/Guide/tools.about_manage.skin
vendored
Normal file
|
@ -0,0 +1,18 @@
|
|||
<h1>manage</h1>
|
||||
|
||||
<p>The Manage application allows you to start and stop applications and
|
||||
makes a variety of status information available. It also provides access
|
||||
to the automatically generated API documentation of the application's
|
||||
code repositories and libraries.</p>
|
||||
|
||||
<p>In Helma's default installation, the Manage application can be accessed
|
||||
using the <a href="http://<% request.http_host %>/manage">
|
||||
http://<% request.http_host %>/manage</a> mountpoint.</p>
|
||||
|
||||
<img src="/static/guide/manage.png" width="480" height="440" />
|
||||
|
||||
<p>Note that access to the Manage application is restricted for obvious
|
||||
security reasons. You will first need to edit the ./server.properties
|
||||
file and set adminAccess to your IP address. You then will be
|
||||
directed on how to configure administrative access when you attempt to
|
||||
use this tool.</p>
|
31
src/dist/apps/welcome/code/Guide/tools.about_shell.skin
vendored
Normal file
31
src/dist/apps/welcome/code/Guide/tools.about_shell.skin
vendored
Normal file
|
@ -0,0 +1,31 @@
|
|||
<h1>shell</h1>
|
||||
|
||||
<p>The Shell allows you to run commands and evaluate scripts within
|
||||
your running application. This may be useful for administrative
|
||||
and maintenance tasks for which you may not want to build a GUI
|
||||
or pre-defined scripts. Certainly, the Shell can become very
|
||||
useful during development and debugging.</p>
|
||||
|
||||
<p>By running commands you can inspect and manage data structures
|
||||
beyond the capabilities of the Inspector. By running scripts you
|
||||
can easily test and modify small portions of your application or
|
||||
invoke actions, simulating specific circumstances and measuring
|
||||
their performance.</p>
|
||||
|
||||
<p>For example, you can invoke the Shell on the HopObject
|
||||
named "second" by accessing the "shell" action at
|
||||
<a href="http://<% request.http_host %>/first/second/shell">
|
||||
http://<% request.http_host %>/first/second/shell</a></p>
|
||||
|
||||
<img src="/static/guide/shell.png" width="480" height="475" />
|
||||
|
||||
<p>Note that access to the Shell is restricted for obvious security
|
||||
reasons. If you have not yet done so, you will be directed on how
|
||||
to configure administrative access when you attempt to use
|
||||
this tool.</p>
|
||||
|
||||
<p>In order to be able to use the Shell inside your own application,
|
||||
you will need to add the helmaTools code repository to that
|
||||
application. For example by adding modules/helmaTools.zip to the
|
||||
<a href="/intro/applications">list of its repositories in the
|
||||
./apps.properties file</a>.
|
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