chg: replaced ant with gradle

This commit is contained in:
Tobi Schäfer 2020-03-16 16:53:52 +01:00
parent cee0be52e0
commit 5cbeb9f01d
609 changed files with 87626 additions and 638 deletions

View file

@ -0,0 +1,323 @@
/*
* Helma License Notice
*
* The contents of this file are subject to the Helma License
* Version 2.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://adele.helma.org/download/helma/license.txt
*
* Copyright 1998-2005 Helma Software. All Rights Reserved.
*
* $RCSfile: helma.Inspector.js,v $
* $Author: czv $
* $Revision: 1.5 $
* $Date: 2006/04/24 11:12:40 $
*/
// take care of any dependencies
app.addRepository('modules/core/String.js');
app.addRepository('modules/core/Number.js');
app.addRepository('modules/helma/Html.js');
if (!global.helma) {
global.helma = {};
}
helma.Inspector = function(hopObj) {
if (!hopObj)
hopObj == root;
var version = "4.0";
var children = [];
var properties = [];
var collections = [];
var html = new helma.Html();
var keySorter = new String.Sorter("key");
var idSorter = new Number.Sorter("id");
var skins = {
child: createSkin(helma.Inspector.child_skin),
collection: createSkin(helma.Inspector.collection_skin),
date: createSkin(helma.Inspector.date_skin),
editor: createSkin(helma.Inspector.editor_skin),
property: createSkin(helma.Inspector.property_skin)
};
var genOptions = function(start, end, selected) {
res.push();
for (var i=start; i<=end; i+=1) {
res.write("<option");
if (i == selected)
res.write(' selected="selected"');
res.write(">");
if (i < 10)
res.write("0");
res.write(i);
res.write("</option>\n");
}
return res.pop();
};
this.render = function() {
for (var i in hopObj) {
var obj = {
key: i,
value: hopObj[i]
};
if (hopObj[i]) {
if (obj.value._prototype &&
obj.value._prototype == "HopObject")
collections.push(obj);
else
properties.push(obj);
}
}
properties.sort(keySorter);
collections.sort(keySorter);
var n = hopObj.size();
for (var i=0; i<n; i++) {
var h = hopObj.get(i);
var obj = {
key: i,
value: h,
id: h._id
};
children.push(obj);
}
children.sort(idSorter);
res.handlers.inspector = this;
renderSkin("helma.Inspector.main");
return;
};
this.action = function() {
if (req.data.done) {
helma.invalidate('inspector');
res.redirect(path.href());
}
if (!helma.auth('inspector'))
res.abort();
if (req.data.cancel)
res.redirect(req.action);
else if (req.data.save) {
if (req.data.type == "date") {
hopObj[req.data.key] = new Date(
req.data.y, req.data.M-1, req.data.d,
req.data.H, req.data.m, req.data.s
);
} else
hopObj[req.data.key] = req.data[req.data.key];
res.redirect(req.action);
};
this.render();
};
/***** M A C R O S *****/
this.version_macro = function() {
return version;
};
this.title_macro = function() {
var str = String(hopObj);
res.write(hopObj);
return;
};
this.prototype_macro = function() {
if (hopObj != root)
res.write(hopObj._prototype);
return;
};
this.this_macro = function() {
res.write(hopObj);
return;
};
this.parent_macro = function() {
res.write(hopObj._parent);
return;
};
this.href_macro = function() {
res.write(hopObj.href(req.action));
return;
};
this.path_macro = function() {
for (var i=0; i<path.length-1; i++) {
var obj = path[i];
html.link({href: obj.href(req.action)},
(obj == root ? obj._prototype : obj));
res.write(" / ");
}
return;
};
this.collections_macro = function() {
for (var i in collections) {
var obj = collections[i];
var param = {
href: obj.value.href(req.action),
key: obj.key,
size: obj.value.size()
};
renderSkin(skins.collection, param);
}
return;
};
this.childProto_macro = function() {
var first = hopObj.get(0);
if (first)
res.write(first._prototype);
return;
};
this.properties_macro = function() {
if (hopObj._id) {
renderSkin(skins.property, {
title: "_id", value: hopObj._id
});
renderSkin(skins.property, {
title: "_prototype", value: hopObj._prototype
});
}
if (hopObj._parent) {
renderSkin(skins.property, {
title: html.linkAsString({
href: hopObj._parent.href(req.action)
}, "_parent"),
value: hopObj._parent
});
}
for (var i in properties) {
var obj = properties[i];
if (obj.value instanceof Date) {
var param = {value: obj.value.toString()};
param.title = html.linkAsString({
href: "javascript:void(null)",
onclick: "toggleEditor(this)"
}, obj.key);
param.key = obj.key;
param.years = genOptions(1970, 2070, obj.value.getFullYear());
param.months = genOptions(1, 12, obj.value.getMonth()+1);
param.days = genOptions(1, 31, obj.value.getDate());
param.hours = genOptions(0, 23, obj.value.getHours());
param.minutes = genOptions(0, 59, obj.value.getMinutes());
param.seconds = genOptions(0, 59, obj.value.getSeconds());
renderSkin(skins.date, param);
} else {
var param = {value: obj.value};
if (obj.value.href) {
param.title = html.linkAsString({href: obj.value.href(req.action)}, obj.key);
renderSkin(skins.property, param);
} else {
param.title = html.linkAsString({
href: "javascript:void(null)",
onclick: "toggleEditor(this)"
}, obj.key);
param.key = obj.key;
renderSkin(skins.editor, param);
}
}
}
return;
};
this.children_macro = function() {
for (var i in children) {
var obj = children[i];
renderSkin(skins.child, {
href: obj.value.href(req.action),
//prototype: obj.value._prototype,
title: obj.value
});
}
return;
};
for (var i in this)
this.dontEnum(i);
return this;
};
/***** S K I N S *****/
helma.Inspector.child_skin = '<tr>\
<td><a href="<% param.href %>"><% param.prototype suffix="&nbsp;" %><% param.title %></a></td>\
</tr>';
helma.Inspector.collection_skin = '<tr>\
<td><a href="<% param.href %>"><% param.key %></a></td>\
<td align="right"><% param.size %></td>\
</tr>';
helma.Inspector.property_skin = '<tr>\
<td><% param.title %></td>\
<td><% param.value encoding="all" %></td>\
</tr>';
helma.Inspector.date_skin = '<tr>\
<td><% param.title %></td>\
<td>\
<div class="display" id="<% param.key %>_display"><% param.value encoding="form" %></div>\
<div class="editor" id="<% param.key %>_editor">\
<form action="<% inspector.href %>" method="post">\
<input type="hidden" name="key" value="<% param.key %>" />\
<input type="hidden" name="type" value="date" />\
<select name="y"><% param.years %></select>.<select name="M"><% param.months %></select>.\
<select name="d"><% param.days %></select>, <select name="H"><% param.hours %></select>:<select name="m"><% param.minutes %></select>:<select name="s"><% param.seconds %></select><br />\
<input type="submit" name="save" value="Save" />\
<input type="reset" name="reset" value="Reset" />\
<input type="submit" name="cancel" value="Cancel" />\
</form></div>\
</td>\
</tr>';
helma.Inspector.editor_skin = '<tr>\
<td><% param.title %></td>\
<td>\
<div class="display" id="<% param.key %>_display"><% param.value encoding="form" %></div>\
<div class="editor" id="<% param.key %>_editor">\
<form action="<% inspector.href %>" method="post">\
<textarea name="<% param.key %>" <% param.key prefix=\'id="content_\' suffix=\'"\' %> cols="40" rows="1"><% param.value encoding="form" %></textarea><br />\
<input type="hidden" name="key" value="<% param.key %>" />\
<input type="submit" name="save" value="Save" />\
<input type="reset" name="reset" value="Reset" />\
<input type="submit" name="cancel" value="Cancel" />\
</form>\
</div>\
</td>\
</tr>';
HopObject.prototype[ (app.properties['inspectorAction'] || 'inspector') +'_action' ] = function() {
if (!helma.auth('inspector'))
res.abort();
if (typeof helma == "undefined" || !helma.Inspector) {
res.write("Could not create instance of helma.Inspector ");
res.write("(probably due to missing helmaLib v4.0+)");
return;
}
var inspector = new helma.Inspector(this);
inspector.action();
return;
};
helma.lib = "Inspector";
helma.dontEnum(helma.lib);
for (var i in helma[helma.lib])
helma[helma.lib].dontEnum(i);
for (var i in helma[helma.lib].prototype)
helma[helma.lib].prototype.dontEnum(i);
delete helma.lib;

View file

@ -0,0 +1,157 @@
<?xml version="1.0"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" >
<head>
<title>helma.Inspector v<% inspector.version %></title>
<style type="text/css">
<!--
body, p, div, td, th {
font-size: 12px;
font-family: arial, sans-serif;
}
h1 {
margin: 0;
}
a {
color: blue;
background-color: white;
text-decoration: none;
}
a:hover {
color: white;
background-color: blue;
}
table#main {
background-color: white;
}
table {
width: 100%;
background-color: #cccccc;
}
td {
padding: 0 5px;
background-color: white;
vertical-align: top;
}
th {
padding: 0 5px;
font-size: 0.75em;
text-transform: uppercase;
letter-spacing: 1px;
color: white;
background-color: #000099;
}
textarea {
background-color: lightyellow;
font-size: 12px;
font-family: arial, sans-serif;
width: 400px;
height: 150px;
margin-top: 5px;
}
select {
margin-top: 5px;
background-color: lightyellow;
}
input {
margin-top: 5px;
font-size: 11px;
}
.display {
width: 400px;
height: 17px;
overflow: hidden;
}
.editor {
display: none;
}
//-->
</style>
<script type="text/javascript">
<!--
var lastEditor;
function toggleEditor(obj) {
var openEditor = function() {
var key = obj.firstChild.nodeValue;
var display = document.getElementById(key + "_display");
var editor = document.getElementById(obj.firstChild.nodeValue + "_editor");
display.style.display = "none";
editor.style.display = "block";
lastEditor = obj;
};
var closeEditor = function() {
var key = lastEditor.firstChild.nodeValue;
var display = document.getElementById(key + "_display");
var editor = document.getElementById(key + "_editor");
display.style.display = "block";
editor.style.display = "none";
lastEditor = null;
};
if (obj != lastEditor) {
if (lastEditor)
closeEditor();
openEditor();
} else if (lastEditor)
closeEditor();
return;
}
//-->
</script>
</head>
<body>
<h1><% inspector.title %></h1>
<div><% inspector.path %><strong><% inspector.title %></strong></div><br />
<table id="main" cellpadding="0" cellspacing="0">
<tr>
<td width="20%">
<table cellpadding="0" cellspacing="1">
<tr>
<th><% inspector.childProto default="child" %>&nbsp;objects</th>
</tr>
<% inspector.children default='<tr><td colspan="2" align="center"><em>none</em></td></tr>' %>
</table>
</td>
<td width="60%">
<table cellpadding="0" cellspacing="1">
<tr>
<th colspan="2">properties</th>
</tr>
<% inspector.properties %>
</table>
</td>
<td width="20%">
<table cellpadding="0" cellspacing="1">
<tr>
<th colspan="2">collections</th>
</tr>
<% inspector.collections default='<tr><td colspan="2" align="center"><em>none</em></td></tr>' %>
</table>
</td>
</tr>
</table>
</body>
</html>

View file

@ -0,0 +1,807 @@
/*
* Copyright (C) 2004 Hannes Wallnoefer
*/
////////////////////////////////////////////////////////////////////////
// Html element functions
////////////////////////////////////////////////////////////////////////
if (!global.helma) {
global.helma = {};
}
helma.Markup = {};
helma.Markup.element = function(name, attributes, content) {
if (!name) {
throw "helma.Markup.element called without element name";
}
// open tag
res.write("<");
res.write(name);
if (attributes) {
for (var i in attributes) {
if (typeof(attributes[i]) == "undefined")
continue;
res.write(" ");
res.write(i);
res.write("=\"");
res.write(encodeForm(attributes[i]));
res.write("\"");
}
}
// if no child objects create empty element and return
if (typeof(content) == "undefined") {
res.write(" />");
return;
}
res.write(">");
// write content
res.write(content);
// close tag
res.write("</");
res.write(name);
res.write(">");
}
helma.Markup.Element = function(name, attributes, children) {
return new MarkupElement(name, attributes, children);
}
helma.Markup.form = function(attributes, content) {
this.element("form", attributes, content);
}
helma.Markup.Form = function(attributes, children) {
return new MarkupElement("form", attributes, children);
}
helma.Markup.textarea = function(attributes, content) {
this.element("textarea", attributes, encodeForm(content));
}
helma.Markup.Textarea = function(attributes, children) {
return new HtmlTextarea(attributes, children);
}
helma.Markup.input = function(attributes, content) {
this.element("input", attributes, content);
}
helma.Markup.Input = function(attributes, children) {
return new MarkupElement("input", attributes, children);
}
helma.Markup.button = function(attributes, content) {
if (!attributes)
attributes = {};
attributes.type = "button";
this.element("input", attributes, content);
}
helma.Markup.Button = function(attributes, children) {
if (!attributes)
attributes = {};
attributes.type = "button";
return new MarkupElement("input", attributes, children);
}
helma.Markup.submit = function(attributes, content) {
if (!attributes)
attributes = {};
attributes.type = "submit";
this.element("input", attributes, content);
}
helma.Markup.Submit = function(attributes, children) {
if (!attributes)
attributes = {};
attributes.type = "submit";
return new MarkupElement("input", attributes, children);
}
helma.Markup.hidden = function(attributes, content) {
if (!attributes)
attributes = {};
attributes.type = "hidden";
this.element("input", attributes, content);
}
helma.Markup.Hidden = function(attributes, children) {
if (!attributes)
attributes = {};
attributes.type = "hidden";
return new MarkupElement("input", attributes, children);
}
helma.Markup.file = function(attributes, content) {
if (!attributes)
attributes = {};
attributes.type = "file";
this.element("input", attributes, content);
}
helma.Markup.File = function(attributes, children) {
if (!attributes)
attributes = {};
attributes.type = "file";
return new MarkupElement("input", attributes, children);
}
helma.Markup.password = function(attributes, content) {
if (!attributes)
attributes = {};
attributes.type = "password";
this.element("input", attributes, content);
}
helma.Markup.Password = function(attributes, children) {
if (!attributes)
attributes = {};
attributes.type = "password";
return new MarkupElement("input", attributes, children);
}
helma.Markup.checkbox = function(attributes, content) {
if (!attributes)
attributes = {};
attributes.type = "checkbox";
if (!attributes.checked)
delete(attributes.checked);
this.element("input", attributes, content);
}
helma.Markup.Checkbox = function(attributes, children) {
if (!attributes)
attributes = {};
attributes.type = "checkbox";
if (!attributes.checked)
delete(attributes.checked);
return new MarkupElement("input", attributes, children);
}
helma.Markup.select = function(attributes, children, selected, firstLine) {
res.write(new HtmlSelect(attributes, children, selected, firstLine));
}
helma.Markup.Select = function(attributes, children, selected, firstLine) {
return new HtmlSelect(attributes, children, selected, firstLine);
}
helma.Markup.head = function(attributes, content) {
this.element("head", attributes, content);
}
helma.Markup.Head = function(attributes, children) {
return new MarkupElement("head", attributes, children);
}
helma.Markup.title = function(attributes, content) {
this.element("title", attributes, content);
}
helma.Markup.Title = function(attributes, children) {
return new MarkupElement("title", attributes, children);
}
helma.Markup.body = function(attributes, content) {
this.element("body", attributes, content);
}
helma.Markup.Body = function(attributes, children) {
return new MarkupElement("body", attributes, children);
}
helma.Markup.div = function(attributes, content) {
this.element("div", attributes, content);
}
helma.Markup.Div = function(attributes, children) {
return new MarkupElement("div", attributes, children);
}
helma.Markup.p = function(attributes, content) {
this.element("p", attributes, content);
}
helma.Markup.P = function(attributes, children) {
return new MarkupElement("p", attributes, children);
}
helma.Markup.b = function(attributes, content) {
this.element("b", attributes, content);
}
helma.Markup.B = function(attributes, children) {
return new MarkupElement("b", attributes, children);
}
helma.Markup.span = function(attributes, content) {
this.element("span", attributes, content);
}
helma.Markup.Span = function(attributes, children) {
return new MarkupElement("span", attributes, children);
}
helma.Markup.img = function(attributes) {
this.element("img", attributes);
}
helma.Markup.Img = function(attributes) {
return new MarkupElement("img", attributes);
}
helma.Markup.script = function(attributes, content) {
this.element("script", attributes, content);
}
helma.Markup.Script = function(attributes, children) {
return new MarkupElement("script", attributes, children);
}
helma.Markup.ul = function(attributes, content) {
this.element("ul", attributes, content);
}
helma.Markup.Ul = function(attributes, children) {
return new MarkupElement("ul", attributes, children);
}
helma.Markup.ol = function(attributes, content) {
this.element("ol", attributes, content);
}
helma.Markup.Ol = function(attributes, children) {
return new MarkupElement("ol", attributes, children);
}
helma.Markup.li = function(attributes, content) {
this.element("li", attributes, content);
}
helma.Markup.Li = function(attributes, children) {
return new MarkupElement("li", attributes, children);
}
helma.Markup.a = function(attributes, content) {
this.element("a", attributes, content);
}
helma.Markup.link = helma.Markup.a;
helma.Markup.A = function(attributes, children) {
return new MarkupElement("a", attributes, children);
}
helma.Markup.table = function(attributes, content) {
this.element("table", attributes, content);
}
helma.Markup.Table = function(attributes, children) {
return new MarkupElement("table", attributes, children);
}
helma.Markup.Colgroup = function(attributes, children) {
return new MarkupElement("colgroup", attributes, children);
}
helma.Markup.colgroup = function(attributes, content) {
this.element("colgroup", attributes, content);
}
helma.Markup.Col = function(attributes, children) {
return new MarkupElement("col", attributes, children);
}
helma.Markup.col = function(attributes, content) {
this.element("col", attributes, content);
}
helma.Markup.tr = function(attributes, content) {
this.element("tr", attributes, content);
}
helma.Markup.Tr = function(attributes, children) {
return new MarkupElement("tr", attributes, children);
}
helma.Markup.th = function(attributes, content) {
this.element("th", attributes, content);
}
helma.Markup.Th = function(attributes, children) {
return new MarkupElement("th", attributes, children);
}
helma.Markup.td = function(attributes, content) {
this.element("td", attributes, content);
}
helma.Markup.Td = function(attributes, children) {
return new MarkupElement("td", attributes, children);
}
helma.Markup.h1 = function(attributes, content) {
this.element("h1", attributes, content);
}
helma.Markup.H1 = function(attributes, children) {
return new MarkupElement("h1", attributes, children);
}
helma.Markup.h2 = function(attributes, content) {
this.element("h2", attributes, content);
}
helma.Markup.H2 = function(attributes, children) {
return new MarkupElement("h2", attributes, children);
}
helma.Markup.h3 = function(attributes, content) {
this.element("h3", attributes, content);
}
helma.Markup.H3 = function(attributes, children) {
return new MarkupElement("h3", attributes, children);
}
helma.Markup.h4 = function(attributes, content) {
this.element("h4", attributes, content);
}
helma.Markup.H4 = function(attributes, children) {
return new MarkupElement("h4", attributes, children);
}
helma.Markup.h5 = function(attributes, content) {
this.element("h5", attributes, content);
}
helma.Markup.H5 = function(attributes, children) {
return new MarkupElement("h5", attributes, children);
}
helma.Markup.h6 = function(attributes, content) {
this.element("h6", attributes, content);
}
helma.Markup.H6 = function(attributes, children) {
return new MarkupElement("h6", attributes, children);
}
helma.Markup.pre = function(attributes, content) {
this.element("pre", attributes, content);
}
helma.Markup.Pre = function(attributes, children) {
return new MarkupElement("pre", attributes, children);
}
helma.Markup.br = function(attributes) {
this.element("br", attributes);
}
helma.Markup.Br = function(attributes, children) {
return new MarkupElement("br", attributes, children);
}
helma.Markup.openTag = function(name, attributes) {
if (!name) {
throw "helma.Markup.openTag called without element name";
}
res.write("<");
res.write(name);
if (attributes) {
for (var i in attributes) {
if (typeof(attributes[i]) == "undefined")
continue;
res.write(" ");
res.write(i);
res.write("=\"");
res.write(encodeForm(attributes[i]));
res.write("\"");
}
}
res.write(">");
}
helma.Markup.closeTag = function(name) {
res.write("</");
res.write(name);
res.write(">");
}
/**
* utility object to provide an easy way
* for programmatically creating an x/html table.
* @param Number the number of columns in the table
* @param Object the table's, its rows' and cells' attributes
* @return Object an instance of TableWriter
*/
helma.Markup.TableWriter = function(numberOfColumns, attr) {
this.ncols = numberOfColumns;
if (isNaN(this.ncols))
throw "Illegal argument in TableWriter(): first argument must be a number";
if (this.ncols < 1)
throw "Illegal argument in TableWriter(): first argument must be > 1";
this.written = 0;
// if no attributes object given, create an empty one
if (!attr)
attr = {};
if (!attr.trEven) attr.trEven = attr.tr;
if (!attr.trOdd) attr.trOdd = attr.tr;
if (!attr.trHead) attr.trHead = attr.trEven;
if (!attr.tdEven) attr.tdEven = attr.td;
if (!attr.tdOdd) attr.tdOdd = attr.td;
if (!attr.thEven) attr.thEven = attr.th;
if (!attr.thOdd) attr.thOdd = attr.th;
this.attr = attr;
// write header row? set to true to use "th" tags for first row
this.writeHeader = false;
// write to string buffer rather than response?
this.writeString = false;
/**
* Write a table cell.
* @param String the table cell content as text
* @param attr an optional attributes holder for the td tag
*/
this.write = function(text, attr) {
// set up some variables
var isHeaderRow = (this.writeHeader && this.written < this.ncols);
var isNewRow = (this.written % this.ncols == 0);
var isEvenRow = ((this.written / this.ncols) % 2 == 0);
var isEvenCol = ((this.written % this.ncols) % 2 == 0);
// write out table and table row tags
if (this.written == 0) {
if (this.writeString)
res.push();
helma.Markup.openTag("table", this.attr.table);
helma.Markup.openTag("tr", this.attr.trHead);
} else if (isNewRow) {
helma.Markup.closeTag("tr");
if (isEvenRow)
helma.Markup.openTag("tr", this.attr.trEven);
else
helma.Markup.openTag("tr", this.attr.trOdd);
}
// get the attribute object for the table cell
if (!attr) {
// no explicit attribute given
if (isEvenCol)
attr = isHeaderRow ? this.attr.thEven : this.attr.tdEven;
else
attr = isHeaderRow ? this.attr.thOdd : this.attr.tdOdd;
}
// write out table cell tag
helma.Markup.openTag(isHeaderRow ? "th" : "td", attr);
// write out table cell contents
if (text)
res.write(text);
// close table cell
helma.Markup.closeTag(isHeaderRow ? "th" : "td");
if (attr && !isNaN(attr.colspan))
this.written += attr.colspan;
else
this.written += 1;
return;
};
/**
* Close all open table tags.
*/
this.close = function() {
if (this.written > 0) {
while (this.written++ % this.ncols != 0)
res.write("<td></td>");
res.write("</tr></table>");
this.written = 0;
}
if (this.writeString)
return res.pop();
return;
};
return this;
}
////////////////////////////////////////////////////////////////////////
// MarkupElement is the base class for all elements
////////////////////////////////////////////////////////////////////////
/**
* Element constructor. Takes a name,
* a map of attributes and an array of child
* elements as arguments.
*/
function MarkupElement(name, attributes, children) {
if (!attributes)
attributes = {};
this.attr = attributes;
// if (name && !this._elementName) {
this._elementName = name;
// } else {
if (attributes && attributes.name) {
this.name = attributes.name;
// this.attr.name = name;
}
this.map = {};
this.add(children);
this.initValueProperty();
}
/**
* Add a new child element
*/
MarkupElement.prototype.add = function(child) {
if (typeof(child) == "undefined") {
return;
}
// initialize child array if necessary
if (!this.children) {
this.children = [];
}
if (child instanceof Array) {
for (var i in child) {
this.add(child[i]);
}
return;
}
// add new child
this.children.push(child);
// register child if it has a name property
if (child) {
if (child.name && !this.map[child.name]) {
this.map[child.name] = child;
}
// register grandchilds unless the name slot is already taken
for (var i in child.map) {
var c = child.map[i];
if (c && c.name && !this.map[c.name]) {
this.map[c.name] = c;
}
}
// set parent property in child
child.parent = this;
}
}
MarkupElement.prototype.firstChild = function() {
return this.children ? this.children[0] : undefined;
}
MarkupElement.prototype.lastChild = function() {
return this.children ? this.children[this.children.length - 1] : undefined;
}
/**
* Render the element to the response buffer.
*/
MarkupElement.prototype.render = function(writer) {
if (!writer)
writer = res;
this.processValueProperty();
// open tag
if (this._elementName) {
writer.write("<");
writer.write(this._elementName);
for (var i in this.attr) {
if (typeof(this.attr[i]) == "undefined")
continue;
writer.write(" ");
writer.write(i);
writer.write("=\"");
writer.write(encodeForm(this.attr[i]));
writer.write("\"");
}
// render type attribute if set
if (this._type) {
writer.write(" type=\"");
writer.write(this._type);
writer.write("\"");
}
// if no child objects create empty element and return
if (typeof(this.children) == "undefined") {
writer.write(" />");
return;
}
writer.write(">");
}
// write child elements
if (typeof(this.children) != "undefined") {
if (this.children instanceof Array) {
for (var i in this.children) {
if (typeof(this.children[i]) instanceof MarkupElement) {
this.children[i].render();
} else if (this.children[i]) {
writer.write(this.children[i]);
}
}
} else {
writer.write(this.children);
}
}
// close tag
if (this._elementName) {
writer.write("</");
writer.write(this._elementName);
writer.write(">");
}
}
/**
* Return an object containing the rendered child elements
* of this element keyed by element name. This is suitable
* for rendering the elements of a markup object through
* a skin, using the object returned by this function as macro
* handler.
*/
MarkupElement.prototype.renderMap = function() {
var map = {};
if (this.children && typeof(this.children) == "object") {
for (var i in this.children) {
if (typeof(this.children[i]) == "object") {
var comp = this.children[i];
map[comp.name] = comp.toString();
}
}
}
return map;
}
/**
* Return an array containing the rendered child elements
* of this element keyed index position. This is suitable
* for those cases where we want to print out a markup
* object's elements programmatically.
*/
MarkupElement.prototype.renderArray = function() {
var list = [];
if (this.children && typeof(this.children) == "object") {
for (var i in this.children) {
if (typeof(this.children[i]) == "object") {
var comp = this.children[i];
list.push(comp.toString());
}
}
}
return list;
}
/**
* Render the element to a string.
*/
MarkupElement.prototype.toString = function() {
res.push();
this.render(res);
return res.pop();
}
/**
* Recursively populate this object and its child objects,
* reading values from the argument object.
*/
MarkupElement.prototype.populate = function(obj) {
// if no object passed populate from req.data
if (!obj)
obj = req.data;
// set value
if (this.name && this._type != "submit")
this.value = obj[this.name];
// populate named child elements
for (var i in this.map) {
if (typeof(this.map[i]) == "object" && this.map[i].populate) {
this.map[i].populate(obj);
}
}
}
/**
* Recursively validate this element and its child elements.
*/
MarkupElement.prototype.validate = function() {
// apply constraints
if (this.constraints) {
for (var i in this.constraints) {
this.contstraints[i].apply(this);
}
}
// validate child elements
for (var i in this.map) {
if (typeof(this.map[i]) == "object" && this.map[i].validate) {
this.map[i].validate();
}
}
}
/**
* Set up this Element's value property.
*/
MarkupElement.prototype.initValueProperty = function() {
this.value = this.attr.value;
}
/**
* Process this Element's value property.
*/
MarkupElement.prototype.processValueProperty = function() {
this.attr.value = this.value;
}
////////////////////////////////////////////////////////////////////////
// MarkupElement subclasses for Html form elements.
////////////////////////////////////////////////////////////////////////
/**
* Html textarea
*/
function HtmlTextarea(attributes, children) {
this.constructor("textarea", attributes, children);
}
HtmlTextarea.prototype = new MarkupElement("textarea");
/**
* Set up this Textarea's value property.
*/
HtmlTextarea.prototype.initValueProperty = function() {
if (typeof(this.attr.value) != "undefined")
this.value = this.attr.value;
else if (this.children && this.children.length > 0)
this.value = this.children[0];
}
/**
* Process this Textarea's value property.
*/
HtmlTextarea.prototype.processValueProperty = function() {
this.children = [encodeForm(this.value)];
}
/**
* Select list
*/
function HtmlSelect(attributes, children, selectedValue, firstLine) {
var options = [];
if (firstLine)
options.push(new MarkupElement("option", {value: ""}, ""));
if (children instanceof Array) {
for (var i in children) {
var child = children[i];
var value, display;
if (child instanceof Array && child.length == 2) {
value = child[0];
display = child[1];
} else if (child.value != null && child.display != null) {
value = child.value;
display = child.display;
} else {
display = child;
value = i;
}
var attr = {value: value};
if (value == selectedValue)
attr.selected = "selected";
options.push(new MarkupElement("option", attr, display));
}
}
this.constructor("select", attributes, options);
}
HtmlSelect.prototype = new MarkupElement("select");

View file

@ -0,0 +1,91 @@
if (!global.helma) {
global.helma = {};
}
/**
* Performs basic admin level access checking for the specifed realm
* @param String realm for which access should be checked and bootstrapped
* @return true if access id verified, otherwise renders login form with bootstrapping instructions
*/
helma.auth = function(realm) {
// helper function, checks if the client host matches an allowed host pattern,
// hostnames are converted, wildcards are only allowed in ip-addresses
var hostIsAllowed = function() {
if (!getProperty(realm+'AccessAllowed'))
return true;
else if (getProperty(realm+'AccessAllowed') == 'false')
return false;
var filter = new Packages.helma.util.InetAddressFilter();
var str = getProperty(realm+'AccessAllowed');
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);
}
}
}
}
return filter.matches(java.net.InetAddress.getByName(req.data.http_remotehost));
}
// Check if current session is authenticated for this realm
if (session.data[realm+'Authenticated'] && hostIsAllowed())
return true;
// Otherwise, guide to properly configure access authentication for this realm
res.data.fontface = 'Trebuchet MS, Verdana, sans-serif';
res.data.href = path[path.length-1].href(req.action);
var pw = getProperty('adminAccess');
var param = {};
var accessAllowed = true;
if (req.data.username && req.data.password) {
if (pw && hostIsAllowed()) {
if (pw == Packages.helma.util.MD5Encoder.encode(req.data.username + "-" + req.data.password)) {
session.data[realm+'Authenticated'] = true;
res.redirect(res.data.href);
} else {
param.message = 'Sorry, wrong password!';
}
} else {
param.message = 'Currently, '+ realm + ' access is not allowed!<br />';
if (!pw) param.message += '\
The adminAccess property is not set.<br />\
Before proceeding, add the following line to your app.properties or server.properties file:\
<br /><br />adminAccess='
+ Packages.helma.util.MD5Encoder.encode(req.data.username + "-" + req.data.password);
else param.message += 'The '+ realm +'AccessAllowed property does not match your host.<br />\
Before proceeding, remove this property from your app.properties or server.properties file \
or include your host as follows:<br /><br />'
+ realm +'AccessAllowed=' + req.data.http_remotehost;
}
}
res.data.header = 'Authentication for '+ realm +' access';
renderSkin('helma.auth.login', param);
return false;
}
helma.dontEnum('auth');
/**
* Invalidates a previously authenticated realm
* @param String realm for which an authentication should be invalidated
* @return true if an authenticated realm was invalidated, otherwise false
*/
helma.invalidate = function(realm) {
if (session.data[realm+'Authenticated']) {
delete session.data[realm+'Authenticated'];
return true;
}
else {
return false;
}
}
helma.dontEnum('invalidate');

View file

@ -0,0 +1,23 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title><% response.title %></title>
<style type="text/css">
body {
background-color: #ffffff;
margin: 20px;
font: 12px <% response.fontface %>;
}
</style>
</head>
<body>
<% response.header prefix="<h3>" suffix="</h3>" %>
<% param.message prefix="<p style=\'color: red\'>" suffix="</p>" %>
<form name="login" method="post">
<p>Please enter the administrators username and password to proceed:</p>
<p>Username:<br /><input type="text" name="username"></p>
<p>Password:<br /><input type="password" name="password"></p>
<input type="submit" value="Authenticate">
</form>
</body>
</html>

View file

@ -0,0 +1,60 @@
if (!global.helma) {
global.helma = {};
}
/**
* Checks shell access, renders the shell skin and evaluates submitted shell commands and scripts
*/
helma.shell = function(realm) {
if (req.data.done) {
helma.invalidate('shell');
helma.invalidate('sqlshell');
helma.invalidate('inspector');
res.redirect(this.href());
}
if (!helma.auth('shell'))
res.abort();
res.data.fontface = 'Trebuchet MS, Verdana, sans-serif';
res.data.href = this.href();
res.data.commands = encodeForm(req.data.commands);
var evalcode = req.data.command || req.data.commands;
if (!evalcode && helma.Inspector) {
if (!session.data.inspectorAuthenticated)
session.data.inspectorAuthenticated = true;
evalcode = '(new helma.Inspector(this)).action();"<hr>";';
}
if (evalcode) {
try {
var startTime = new Date();
var evalResult = eval(evalcode);
var stopTime = new Date();
res.write(evalResult);
if (req.data.commands) {
res.write('<br /><br />')
res.write('<span style="font-family:'+res.data.fontface+'; color:grey; font-size:11px">')
res.write('Script evaluated in ' + (stopTime.getTime() - startTime.getTime()) +' milliseconds.');
res.write('</span><hr />');
} else if (!req.data.command) {
res.write('<hr />');
}
} catch ( e ) {
res.write('<span class="error">');
if ( e.javaException ) {
var s = new java.io.StringWriter();
e.javaException.printStackTrace( new java.io.PrintWriter( s ) );
res.write( s.toString() );
} else {
res.write( format( e + '<br />' + e.fileName + ', lineNumber = ' + e.lineNumber ) );
}
res.write('</span>');
if (req.data.commands) res.write('<hr />');
}
}
if (!req.data.command) renderSkin('helma.shell');
}
helma.dontEnum('shell');
/**
* Checks shell access, renders the shell skin and evaluates submitted shell commands and scripts
*/
HopObject.prototype[ (app.properties['shellAction'] || 'shell') +'_action' ] = helma.shell;

View file

@ -0,0 +1,124 @@
<style>
body {
//font: 12px <% response.fontface %>;
}
.commandshell {
font: 12px <% response.fontface %>;
border: 1px solid groove;
background-color:#eee;
}
.error {
background-color: #ffdddd;
}
.command {
padding-top: 5px;
}
.cell {
font: 12px <% response.fontface %>;
border-bottom: 1px solid #ddd;
padding: 2px 0px 2px 0px;
}
.hot {
background-color: #eef5ee;
cursor: pointer;
}
.cold {
background-color: #ffffff;
cursor: auto;
}
</style>
<script>
function getRequest() {
return window.ActiveXObject
? new ActiveXObject( "Microsoft.XMLHTTP" )
: new XMLHttpRequest()
;
}
function load( url, data, param ) {
var req = getRequest();
req.onreadystatechange = getHandler( req, param );
req.open( data ? "POST" : "GET", url, true );
if ( data ) {
req.setRequestHeader( "Content-Type", "application/x-www-form-urlencoded" );
var params = [];
for ( var x in data )
params.push( encodeURIComponent( x ) + "=" + encodeURIComponent( data[ x ] ) )
req.send( params.join( "&" ) );
} else {
req.send();
}
}
function handle( input, event ) {
var key = event.keyCode ? event.keyCode : event.charCode;
if (( key == 13 && input.value ) || event == 'enter') { // enter
var command = input.value;
input.value = "";
emitCell( command, ++id );
lines.push( command );
delta = 0;
load( '<% response.href %>shell', { command: command }, { id: id } );
if ( hotCellId )
cellOut( document.getElementById( hotCellId ) );
window.scroll( 0, 1000000 );
} else if ( key == 38 && delta < lines.length ) { // up
delta++;
input.value = lines[ lines.length - delta ];
} else if ( key == 40 ) { // down
if ( delta > 0 )
delta--;
input.value = lines[ lines.length - delta ] || "";
}
}
function getHandler( req, param ) {
return function() {
if ( req.readyState == 4 )
document.getElementById( param.id ).innerHTML = req.responseText;
}
}
function recallCommand( i ) {
var input = document.getElementById( "command" );
input.value = lines[ i ];
input.focus();
}
function cellIn( cell ) {
cell.className = "cell hot";
hotCellId = cell.id;
}
function cellOut( cell ) {
cell.className = "cell cold";
hotCellId = null;
}
function emitCell( command, resultId ) {
var str = "";
str += "<div id=\"cell" + resultId + "\" class=\"cell cold\" onmouseover=\"cellIn( this )\" onmouseout=\"cellOut( this )\" onclick=\"recallCommand( " + lines.length + " )\">";
str += "<b>" + command + "</b><br />";
str += "<div id='" + resultId + "'>...</div>";
str += "</div>";
emit( str );
}
function emit( str ) {
document.getElementById( "result" ).innerHTML += str;
}
// --
var id = 1;
var lines = [];
var delta = 0;
var hotCellId = null;
</script>
<div id="result"></div>
<div class="command">
<input type="text" class="commandshell" id="command" onkeydown="handle( this, event )" size="80" />
<input type="submit" name="evaluate" value="Run Command" onclick="handle( document.getElementById( 'command' ), 'enter' )" />
</div>
<script>
document.getElementById( "command" ).focus();
</script>
<form name="shellform" method="post">
<div>
<textarea class="commandshell" style="background-color:#f6f6f6;" name="commands" rows="25" cols="100"
wrap="off"><% response.commands %></textarea>
</div>
<input type="submit" name="evaluate" value="Run Script" />
<input type="submit" name="done" value="Done" />
</form>

View file

@ -0,0 +1,753 @@
if (!global.helma) {
global.helma = {};
}
helma.sqlshell = {};
/**
* Get the helma datasource with the given name
*/
helma.sqlshell.getDatasource = function(name) {
return app.getDbSource(name);
}
/**
* Get an array of names of all defined data sources suitable for use
* in html.select macro.
*/
helma.sqlshell.getDatasources = function() {
var dbmap = app.getDbProperties();
var sources = [];
for (var i in dbmap) {
var dot = i.indexOf(".");
if (dot > -1 && i.lastIndexOf(".url") == i.length-4) {
var source = i.substring(0, dot);
sources.push([source, source]);
}
}
return sources;
}
helma.sqlshell.getRepositories = function() {
var rep = [];
var repos = app.getRepositories();
for (var i in repos) {
if (repos[i].getClass() == Packages.helma.framework.repository.FileRepository)
rep.push([i, repos[i].name]);
}
return rep;
}
helma.sqlshell.getProtoRepositories = function(protoName) {
var rep = [];
var proto = app.getPrototype(protoName);
if (proto) {
var repos = proto.getRepositories();
for (var i in repos) {
if (repos[i].getClass() == Packages.helma.framework.repository.FileRepository)
rep.push([i, repos[i].name]);
}
}
return rep;
}
/**
* Main action to set the Helma Dbsource, display forms, perform queries.
*/
helma.sqlshell.main = function() {
// If done, end sqlshell session
if (req.data.done) {
helma.invalidate('sqlshell');
if (session.data.sqlShellReturnUrl) {
var targetUrl = session.data.sqlShellReturnUrl;
delete session.data.sqlShellReturnUrl;
} else {
var targetUrl = path.href();
}
res.redirect(targetUrl);
}
// Check if sqlshell is called from the shell tool
if (req.data.introFrom) {
session.data.sqlShellReturnUrl = req.data.introFrom;
if (session.data.shellAuthenticated)
session.data.sqlshellAuthenticated = true;
}
// Check authentication
if (!helma.auth('sqlshell'))
res.abort();
// Handle authenticated requests
res.handlers.html = helma.sqlshell.html;
var param = {};
param.datasource = req.data.datasource;
res.data.fontface = 'Verdana, sans-serif';
/* if (req.data.schema)
session.data.sqlshellSchema = req.data.schema;
if (req.data.datasource)
session.data.sqlshellDatasource = req.data.datasource; */
var dsource = req.data.datasource ?
helma.sqlshell.getDatasource(req.data.datasource) : null;
if (dsource) {
(new helma.sqlshell.Datasource(dsource)).main();
} else {
if (req.data.datasource && req.isPost()) {
param.message = "Sorry, data source " + req.data.datasource +
" is not defined for this application.";
}
res.data.header = "Choose data source";
res.data.datasources = helma.sqlshell.getDatasources();
res.data.body = renderSkinAsString("helma.sqlshell.selectdb", param);
renderSkin("helma.sqlshell.page");
}
}
helma.sqlshell.Datasource = function(datasource) {
this.datasource = datasource;
this.name = datasource.name;
return this;
}
/**
* Get an array of schema names defined in the current database.
*/
helma.sqlshell.Datasource.prototype.getSchemas = function(meta) {
// get available schemas and set up an array for the drop down box:
var schemas = [];
var t = meta.getSchemas();
while (t.next()) {
var s = t.getString(1);
schemas.push([s, s]);
}
return schemas;
}
/**
* Get table names and set up an array for the drop down box
*/
helma.sqlshell.Datasource.prototype.getTables = function(meta, schema) {
var tables = [["", ""]];
var t = meta.getTables (null, schema, "%", null);
while (t.next()) {
var table = t.getString (3);
tables.push([table, table]);
}
return tables;
}
helma.sqlshell.Datasource.prototype.getColumns = function(meta, schema, table) {
var columns = [];
var t = meta.getColumns(null, schema, table, "%");
while (t.next()) {
columns.push(t.getString(4));
}
return columns;
}
helma.sqlshell.Datasource.prototype.getPrototypes = function() {
var protos = [["", ""]];
var protomap = app.getPrototypes();
for (var i in protomap) {
if (protomap[i].lowerCaseName != "global") {
protos.push([protomap[i].name, protomap[i].name]);
}
}
return protos.sort(function(a, b) {return a < b ? -1 : 1;});
}
helma.sqlshell.Datasource.prototype.href = function(name) {
var href = path.href(req.action) + "?datasource=";
href += encode(req.data.datasource);
href += "&schema=";
href += encode(req.data.schema);
href += "&tab=";
href += req.data.tab;
return href;
}
helma.sqlshell.Datasource.prototype.href_macro = function(param) {
return this.href(param.name);
}
helma.sqlshell.colors = {
explore: "#bd9", query: "#db9", map: "#9bd"
}
helma.sqlshell.Datasource.prototype.main = function() {
res.handlers.datasource = this;
if (!req.data.tab) {
req.data.tab = "explore";
}
res.data.tabcolor = helma.sqlshell.colors[req.data.tab];
var param = new Object();
param.action = this.href();
// get connection
var con = this.datasource.getConnection();
// get database meta data
var meta = con.getMetaData();
res.data.datasources = helma.sqlshell.getDatasources();
res.data.schemas = this.getSchemas(meta);
var schema = req.data.schema;
res.data.tables = this.getTables(meta, schema);
if (req.data.action) {
app.data.repositories = helma.sqlshell.getRepositories();
if (req.data.action == "createproto" ) {
var repos = app.repositories[req.data.repository];
var file = new File(repos.directory.toString(), req.data.protoname);
if (file.mkdir()) {
renderSkin(this.getSkin("closePopup"), {
parentUrl: this.href() + "&prototype=" + req.data.protoname,
message: "<p>Created directory " + file + "</p>" +
"<p>Please wait for prototypes to be updated...</p>"
} );
return;
} else {
res.debug("Couldn't create directory: " + file);
res.data.body = renderSkinAsString(this.getSkin("newproto"));
}
} else if (req.data.action == "extras") {
var p = {};
var t = app.getPrototype(req.data.target);
var target = t && t.dbMapping ? t.dbMapping.tableName : null;
p.targetColumns = this.getColumns(meta, schema, target).toSource();
p.localColumns = this.getColumns(meta, schema, req.data.__sqlshell_table__).toSource();
res.data.body = renderSkinAsString(this.getSkin(req.data.action), p);
} else if (req.data.action == "generate") {
if (req.data.create) {
renderSkin(this.getSkin("closePopup"), {
parentUrl: this.href() + "&prototype=" + req.data.__sqlshell_prototype__,
message: "<p>Created type mapping " + file + "</p>" +
"<p>Please wait for prototypes to be updated...</p>"
} );
} else {
var fields = {};
var s = new java.lang.StringBuffer();
for (var i in req.data) {
if (i.indexOf("maptype_") == 0) {
fields[i.substring(8)] = req.data[i];
}
s.append("<input type='hidden' name='").append(i)
.append("' value='").append("" + req.data[i]).append("'>");
}
if (req.data.__sqlshell_create__) {
// res.data.body = renderSkinAsString(this.getSkin("generate"), p);
var repos = app.getPrototype(req.data.__sqlshell_prototype__).repositories;
var resName = "type.properties";
for (var i in repos) {
var resource = repos[i].getResource(resName);
if (resource && resource.exists()) {
if (resource.getClass() == Packages.helma.framework.repository.FileResource) {
var file = new File(resource.getName());
var backup = new File(resource.getName() + ".bak");
if (backup.exists()) {
var n = 1;
do {
backup = new File(resource.getName() + ".bak." + n++)
} while (backup.exists());
}
if (!file.renameTo(backup)) {
res.debug("ERROR: Couldn't create backup for " + resource);
}
} else {
res.debug("WARNING: Couldn't move " + resource);
}
}
}
var file = new File(repos[req.data.__sqlshell_repository__].getResource(resName).getName());
file.open();
file.writeln("# Created by Helma SqlShell at " + new Date());
if (req.data.__sqlshell_extends__)
file.writeln("_extends = " + req.data.__sqlshell_extends__);
if (req.data.__sqlshell_primaryKey__)
file.writeln("_id = " + req.data.__sqlshell_primaryKey__);
if (req.data.__sqlshell_protoColumn__)
file.writeln("_prototype = " + req.data.__sqlshell_protoColumn__);
if (req.data.__sqlshell_nameColumn__)
file.writeln("_name = " + req.data.__sqlshell_nameColumn__);
file.writeln("");
for (var i in fields) {
var propType = parseInt(fields[i]);
var propName = req.data[i];
if (!propName) continue;
file.write(propName);
file.write(" = ");
switch (propType) {
case 0:
file.writeln(req.data[i]);
break;
case 1:
file.writeln("object(" + req.data["target_" + i] + ")");
break;
case 2:
file.writeln("collection(" + req.data["target_" + i] + ")");
break;
case 3:
file.writeln("mountpoint(" + req.data["target_" + i] + ")");
break;
default:
res.debug(i + ": " + fields[i]);
}
for (var m in this.mappingOptions) {
if (this.mappingOptions[m] <= propType && req.data[i + "_" + m]) {
file.write(propName);
file.write(".");
file.write(m.replace("_", "."));
file.write(" = ");
file.writeln(req.data[i + "_" + m]);
}
}
file.writeln("");
}
file.close();
res.data.body = "Successfully created mapping in " + file;
} else {
var p = {};
p.data = s.toString();
res.data.repositories = helma.sqlshell.getProtoRepositories(req.data.__sqlshell_prototype__);
res.data.body = renderSkinAsString(this.getSkin("generate"), p);
}
}
} else {
res.data.body = renderSkinAsString(this.getSkin(req.data.action));
}
} else {
// should we display type info on some table?
if (req.data.tab == "explore") {
param.body = this.explore(meta, schema, param);
} else if (req.data.tab == "query") {
param.body = this.query(con, param);
} else if (req.data.tab == "map") {
param.body = this.map(meta, schema, con, param);
}
// render the inner page skin and then the whole page
res.data.body = renderSkinAsString("helma.sqlshell.main", param);
}
renderSkin("helma.sqlshell.page");
}
helma.sqlshell.Datasource.prototype.explore = function(meta, schema, param) {
res.push();
renderSkin(this.getSkin("explore"), param);
if (req.data.__sqlshell_table__) {
var tableStyle = { table: { "class": "explore" }, td: { "class": "explore" } };
var t = meta.getColumns(null, schema, req.data.__sqlshell_table__, "%");
var writer = new helma.Markup.TableWriter(6, tableStyle);
writer.writeHeader = true;
var columnNames = ["Column Name", "Column Type", "Column Size",
"Nullable", "Default Value", "Extras"];
for (var c in columnNames) {
writer.write(columnNames[c]);
}
while (t.next()) {
writer.write(t.getString(4));
writer.write(t.getString(6));
writer.write(t.getString(7));
writer.write(t.getString(18));
writer.write(t.getString(13));
writer.write(t.getString(12));
}
writer.close();
}
return res.pop();
}
helma.sqlshell.Datasource.prototype.query = function(con, param) {
// some SQL has been submitted - evaluate it
if (req.data.sql) {
var query = req.data.sql.trim();
con.setReadOnly(false);
var stmt = con.createStatement();
var value;
try {
value = stmt.execute(query);
if (!value) {
param.updated = stmt.getUpdateCount();
} else {
var rs = stmt.getResultSet();
var rsmeta = rs.getMetaData();
var ncol = rsmeta.getColumnCount();
res.push();
var tableStyle = { table: { "class": "query" }, td: { "class": "query" } };
var writer = new helma.Markup.TableWriter(ncol, tableStyle);
writer.writeHeader = true;
for (var i=1; i<=ncol; i++) {
writer.write(rsmeta.getColumnName(i));
}
while (rs.next()) {
for (var i=1; i<=ncol; i++) {
writer.write(encode(rs.getString(i)));
}
}
writer.close();
param.resultset = res.pop();
}
} catch (error) {
param.message = "Error: " + error;
}
}
return renderSkinAsString(this.getSkin("query"), param);
}
helma.sqlshell.Datasource.prototype.map = function(meta, schema, con, param) {
// for (var i in req.data) res.debug(i);
res.push();
res.data.prototypes = this.getPrototypes();
var proto = app.getPrototype(req.data.__sqlshell_prototype__);
if (proto) {
var tableStyle = { table: { "class": "map" }, td: { "class": "map" } };
var dbmap = proto.getDbMapping();
if (!req.data.__sqlshell_table__ ||
req.data.__sqlshell_prototype__ != req.data.previousProto) {
req.data.__sqlshell_table__ = dbmap.tableName;
}
param.tableSelect = renderSkinAsString(createSkin('Map to table \
<% html.select name="__sqlshell_table__" options="response.tables" \
onchange="document.forms.tab.submit();"%>'));
}
renderSkin(this.getSkin("map"), param);
if (proto) {
var maptypes = ["Primitive", "Reference", "Collection", "Mountpoint"];
var tableStyle = { table: { "class": "map" }, td: { "class": "map" } };
if (req.data.__sqlshell_table__) {
var primKey = "";
try {
var k = meta.getPrimaryKeys(null, schema, req.data.__sqlshell_table__);
if (k.next()) {
primKey = k.getString(4);
}
if (k.next()) {
helma.Markup.p({"class": "error"}, "Table has composed primary key!");
}
} catch (error) {
helma.Markup.p({"class": "error"}, "Error retrieving primary key: " + error);
}
var t = meta.getColumns(null, schema, req.data.__sqlshell_table__, "%");
var columns = [];
res.data.columns = [["", ""]];
while (t.next()) {
var colname = t.getString(4);
columns.push(colname);
res.data.columns.push([colname, colname]);
}
var writer = new helma.Markup.TableWriter(2, tableStyle);
writer.write("Extends ");
var ext = dbmap.getExtends() || app.getPrototype("hopobject").name;
writer.write(helma.Markup.Select({name: "__sqlshell_extends__"}, res.data.prototypes, ext));
writer.write("Primary key column ");
writer.write(helma.Markup.Select({name: "__sqlshell_primaryKey__"}, res.data.columns, primKey));
writer.write("Prototype column ");
writer.write(helma.Markup.Select({name: "__sqlshell_protoColumn__"}, res.data.columns, dbmap.prototypeField));
writer.write("Name column ");
writer.write(helma.Markup.Select({name: "__sqlshell_nameColumn__"}, res.data.columns, dbmap.nameField));
writer.close();
tableStyle = { table: { "class": "map", id: "maptable" }, td: { "class": "map" } };
writer = new helma.Markup.TableWriter(5, tableStyle);
writer.writeHeader = true;
var headers = ["Column Name", "Property Name", "Mapping",
"Target Prototype", "Extras"];
for (var c in headers) {
writer.write(headers[c]);
}
for (var col in columns) {
var colname = columns[col];
// if (colname == primKey) continue;
var rel = dbmap.columnNameToRelation(colname);
var value = rel && rel.propName ? rel.propName : this.toCamelCase(colname);
var type = rel ? rel.refType : 0;
var targetDisplay = type > 0 ? '': ' style="display: none;"';
var target = rel && rel.targetType ? rel.targetType.typeName : "";
writer.write(colname);
writer.write('<input name="' + colname + '" value="' + value +'">');
writer.write(helma.Markup.Select({name: "maptype_" + colname,
onchange: "toggleEditor(this)"}, maptypes, type));
writer.write('<div id="refedit_' + colname + '"' + targetDisplay +'>' +
helma.Markup.Select({name: "target_" + colname}, res.data.prototypes, target) + '</div>');
var buffer = new java.lang.StringBuffer();
var config = rel ? wrapJavaMap(rel.config) : {};
for (var i in this.mappingOptions) {
// var name = i.replace('_', '.');
var name = colname + "_" + i;
buffer.append(helma.Markup.Hidden({id: name, name: name, value: config[i] }).toString());
}
buffer.append(helma.Markup.A({href: this.href() + "&action=extras&col=" + colname,
id:"extralink_" + colname, style: type > 0 ? '': 'display: none;',
onclick: "openExtraEditor(this.href, '" + colname + "'); return false;"},
"edit").toString());
writer.write(buffer);
/* writer.write(helma.Markup.A({href: this.href() + "&action=extras&col=" + colname,
id:"extralink_" + colname, style: type > 0 ? '': 'display: none;',
onclick: "openPopup(this.href, 'extras'); return false;"},
"edit")); */
}
var props = dbmap.getPropertyNames();
var collectionCount = 0;
for (var p in props) {
var rel = dbmap.propertyToRelation(props[p]);
if (rel.refType < 1 || (rel.dbField && rel.dbField != primKey)) {
continue;
}
var propName = rel.propName;
var target = rel.targetType ? rel.targetType.typeName : "";
var type = rel.refType;
if (type == 2 && !rel.dbField) {
// helma does not separate between collections and mountpoints internally
type = 3;
}
var colname = "collection_" + (collectionCount++);
writer.write("");
writer.write('<input name="' + colname + '" value="' + propName +'">');
writer.write(helma.Markup.Select({name: "maptype_" + colname,
onchange: "toggleEditor(this)"}, maptypes, type));
writer.write('<div id="refedit_' + colname + '">' +
helma.Markup.Select({name: "target_" + colname}, res.data.prototypes, target) + '</div>');
var buffer = new java.lang.StringBuffer();
var config = wrapJavaMap(rel.config);
for (var i in this.mappingOptions) {
// var name = i.replace('_', '.');
var name = colname + "_" + i;
buffer.append(helma.Markup.Hidden({id: name, name: name, value: config[i] }).toString());
}
buffer.append(helma.Markup.A({href: this.href() + "&action=extras&col=" + colname,
id:"extralink_" + colname,
onclick: "openExtraEditor(this.href, '" + colname + "'); return false;"},
"edit").toString());
writer.write(buffer);
}
writer.close();
// FIXME: MAJOR HACK **********************************
res.writeln('<script type="text/javascript">');
res.writeln('var colcount = ' + collectionCount + ';');
res.write('var rowtemplate = \'<td class="map"></td><td class="map"><input name="$$$" value=""></td>');
res.write('<td class="map">')
helma.Markup.select({name: "maptype_$$$",
onchange: "toggleEditor(this)"}, maptypes, 2);
res.write('</td><td class="map">')
res.write('<div id="refedit_$$$">' +
helma.Markup.Select({name: "target_$$$"}, res.data.prototypes, target) + '</div>');
res.write('</td><td class="map">')
for (var i in this.mappingOptions) {
// var name = i.replace('_', '.');
var name = "$$$_" + i;
helma.Markup.hidden({id: name, name: name, value: "" });
}
helma.Markup.a({href: this.href() + "&action=extras&col=$$$",
id:"extralink_$$$",
onclick: "openExtraEditor(this.href, \\'$$$\\'); return false;"},
"edit");
res.write('</td>');
res.writeln("';");
res.writeln('</script>');
// END OF MAJOR HACK **********************************
helma.Markup.a({href: "#", onclick:'return appendTableRow("maptable");'}, "Add Collection");
res.write(" ");
helma.Markup.submit({name: "generateMapping",
onclick:"submitFormToPopup(document.forms.tab, '" + this.href() + "&action=generate', 'generate',500,350); return false;",
value: "Generate Mapping"});
}
}
return res.pop();
}
helma.sqlshell.Datasource.prototype.mappingOptions = {
local: 1,
foreign: 1,
order: 2,
accessname: 2,
group: 2,
group_order: 2,
group_prototype: 2,
filter: 2,
filter_additionalTables: 2,
loadmode: 1,
cachemode: 2,
maxsize: 2,
hints: 2,
logicalOperator: 2,
readonly: 2,
"private": 2
}
helma.sqlshell.Datasource.prototype.toCamelCase = function(str) {
var s = str.toLowerCase().split(/[-_]/);
str = s[0];
for (var i=1; i<s.length; i++) {
str += s[i].charAt(0).toUpperCase() + s[i].substring(1);
}
return str;
}
helma.sqlshell.Datasource.prototype.getSkin = function(name) {
switch (name) {
case "query": return createSkin('<div class="activetab">SQL:<br>\
<textarea cols="60" rows="6" wrap="virtual"\
name="sql"><% request.sql encode="form" %></textarea><br>\
<input type="submit" value="Submit"> \
<input type="reset" value="Reset"></div>\
<% param.message prefix="<p style=\'color: red\'>" suffix="</p>" %>\
<% param.updated prefix="<p><span style=\'background-color: yellow\'>"\
prefix="Statement executed, "\
suffix=" row(s) affected</span></p>" %>\
<% param.resultset %>');
case "explore": return createSkin('<div class="activetab">Describe Table \
<% html.select name="__sqlshell_table__" options="response.tables" \
onchange="document.forms.tab.submit();" %>\
<input type="submit" value="Submit"></div>\
<% param.tableheader prefix="<h4>" suffix="</h4>" %>\
<% param.tableinfo %>');
case "map": return createSkin('<div class="activetab">Prototype \
<% html.select name="__sqlshell_prototype__" options="response.prototypes" \
onchange="document.forms.tab.submit();" %>\
<a onclick="openPopup(\'' +this.href() + '&action=newproto\', \'newproto\',500,250); return false;" \
href="?popup=newproto">[new]</a>\
<% param.tableSelect %> \
<input type="hidden" name="previousProto" value="<% request.__sqlshell_prototype__ %>">\
<input type="submit" value="Set">\
<input type="reset" value="Reset">\
</div>');
case "newproto": return createSkin('<form method="POST" action="' + this.href() + '&action=createproto">\
Prototype Name: <br><input name="protoname"><br>\
Create in Repository: <br><% html.select name="repository" options="app.repositories" %><br><br>\
<input type="submit" name="create" value="Create Prototype">\
</form>');
case "extras": return createSkin('<form name="extras">\
<h4>Extra parameters for ' + req.data.col + '</h4>\
<table>\
<script type="text/javascript">\
var localColumns = <% param.localColumns %>;\
var targetColumns = <% param.targetColumns %>;\
extraEditor("' + req.data.col + '", localColumns, targetColumns);\
</script>\
</table>\
<input type="submit" value="Apply" \
onclick="applyExtras(\'' + req.data.col + '\'); return false;">\
</form>');
case "generate": return createSkin('<form method="POST" action="' + this.href() + '&action=generate">\
Create type.properties in Repository: <br><% html.select name="__sqlshell_repository__"\
options="response.repositories" %><br><br>\
<input type="submit" name="__sqlshell_create__" value="Create Type Mapping">\
<% param.data %>\
</form>');
case "closePopup": return createSkin('<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">\
<!--\
This is an empty page that closes the current popup window and\
optionally refreshes the parent page (passed as parentUrl).\
-->\
<html>\
<head>\
<title>closing window</title>\
<script>\
var parentUrl = "<% param.parentUrl %>";\
function doClose() {\
if (parentUrl)\
opener.location.href = parentUrl;\
window.close();\
}\
setTimeout("doClose()", 150000);\
</script>\
</head>\
<body>\
<% param.message %>\
</body>\
</html>');
default: return createSkin("No skin defined for " + name);
}
}
helma.sqlshell.Datasource.href =
HopObject.prototype[ (app.properties['sqlshellAction'] || 'sqlshell') +'_action' ] = helma.sqlshell.main;
helma.dontEnum('sqlshell');
////////////////////////////////////////////////////////////////////////
// Macro handler for Html tags
////////////////////////////////////////////////////////////////////////
helma.sqlshell.html = {
tablink_macro: function(param) {
var href = req.action + "?datasource=";
href += encode(req.data.datasource);
href += "&schema=";
href += encode(req.data.schema);
href += "&tab=";
href += param.name;
var attr = { href: href, "class": "tab" };
if (req.data.tab == param.name) {
attr["class"] += " activetab";
} else {
attr["class"] += " passivetab";
}
helma.Markup.element("a", attr, param.name);
},
select_macro: function(param) {
if (!param.name) {
throw "dropDown macro requires name attribute";
}
if (!param.options) {
throw "dropDown macro requires options attribute";
}
var opts = param.options.split(".");
if (opts.length != 2) {
throw "options attribute must be of the form 'handler.options'";
}
var handler = this.getHandler(opts[0]);
if (!handler) {
throw "handler '"+opts[0]+" not found - " +
"valid options are (response|request|session|app)";
}
var options = handler[opts[1]];
if (!options) {
throw param.options+" is not defined ";
}
if (options.length == 0) {
return;
}
var attr = {};
for (var i in param) {
if (i != "options" && i != "prefix" && i != "suffix") {
attr[i] = param[i];
}
}
helma.Markup.select(attr, options, req.data[param.name], param.firstoption);
},
getHandler: function (handlerName) {
switch (handlerName) {
case "response":
return res.data;
case "request":
return req.data;
case "session":
return session.data;
case "app":
return app.data;
}
return null;
}
}

View file

@ -0,0 +1,30 @@
<h3>Helma Sql Shell</h3>
<div style="float:right;">
<form method="get" action="<% datasource.href %>" name="datasource">
<input type="hidden" name="tab" value="<% request.tab %>">
<% html.select name="datasource" options="response.datasources"
prefix="Data Source: " onchange="document.forms.datasource.submit(); %>
&nbsp;&nbsp;
<% html.select name="schema" options="response.schemas"
prefix="Schema: " onchange="document.forms.datasource.submit(); %>
</form>
</div>
<form method="post" action="<% datasource.href %>" name="tab">
<div class="tabs">
<% html.tablink name="explore" %>
<% html.tablink name="query" %>
<% html.tablink name="map" %>
</div>
<input type="hidden" name="datasource" value="<% request.datasource %>">
<input type="hidden" name="schema" value="<% request.schema %>">
<input type="hidden" name="tab" value="<% request.tab %>">
<% param.body %>
<p><input type="submit" name="done" value="Done" /></p>
</form>

View file

@ -0,0 +1,207 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Helma SqlShell <% response.title %></title>
<style type="text/css">
body {
background-color: #ffffff;
margin: 20px;
font: 12px <% response.fontface %>;
}
h1, h2, h3 {
border-bottom: 1px solid #cccc99;
font-family: <% response.fontface %>;
}
pre {
padding: 10px;
border: 1px solid black;
background-color: #ccccff;
overflow: auto;
}
table {
border: 1px solid <% response.tabcolor %>;
border-collapse:collapse;
margin-bottom: 1em;
}
th {
text-align: left;
background-color: white;
padding-right: 2em;
}
td {
font: 12px <% response.fontface %>;
border-top: 1px solid <% response.tabcolor %>;
padding: 2px;
max-height: 40em;
overflow: auto;
}
.tabs {
padding-top: 1em;
}
.activetab {
background-color: <% response.tabcolor %>;
color: black;
}
.passivetab {
color: #666;
}
div.activetab {
padding: 0.8em;
margin-bottom: 1em;
}
a.tab {
font-size: 13px;
text-decoration: none;
padding: 0.4em;
line-height: 2em;
}
</style>
<script type="text/javascript">
function toggleEditor(elem) {
var colname = elem.name.substring(8);
var chooser = document.getElementById("refedit_" + colname);
var link = document.getElementById("extralink_" + colname);
if (elem.value == "0") {
if (chooser) chooser.style.display = "none";
if (link) link.style.display = "none";
} else {
if (chooser) chooser.style.display = "inline";
if (link) link.style.display = "inline";
}
}
function openPopup(url, name, width, height) {
if (isNaN(width)) width = 500;
if (isNaN(height)) height = 500;
// create reasonable screen location for popup
var position = ",left=" +
Math.floor((screen.availWidth - width) / 2) +
",top=" +
Math.floor((screen.availHeight - height) / 2) +
",scrollbars=yes,resizable=yes";
var popup = window.open(url, name, 'width=' + width + ',height=' + height + position);
popup.focus();
}
function openExtraEditor(url, name, width, height) {
var target = document.getElementsByName("target_" + name)[0];
url += "&target=" + target.value;
var table = document.getElementsByName("__sqlshell_table__")[0];
url += "&table=" + table.value;
openPopup(url, "extras", width, height);
}
function submitFormToPopup(form, url, name, width, height) {
openPopup(null, name, width, height);
var prevTarget = form.target;
var prevAction = form.action;
form.target = name;
form.action = url;
form.submit();
form.target = prevTarget;
form.action = prevAction;
}
function appendTableRow(parent) {
var row = document.createElement("tr");
var table = document.getElementById(parent);
if (row && table) {
var colname = "collection_" + (colcount++);
table.appendChild(row);
row.innerHTML = rowtemplate.replace(/\$\$\$/g, colname);
}
return false;
}
function extraEditor(propname, localCols, targetCols) {
var type = opener.document.getElementsByName("maptype_" + propname)[0];
for (var i in mappingOptions) {
var fieldname = propname + '_' + i;
if (!type || parseInt(type.value) < mappingOptions[i]) continue;
var field = opener.document.getElementById(fieldname);
if (field) {
document.write("<tr><td>" + i + "</td><td>");
if (i in {foreign: 1, accessname: 1, group:1} && targetCols) {
writeSelect(fieldname, field.value, targetCols);
} else if (i == "local" && localCols) {
writeSelect(fieldname, field.value, localCols);
} else {
document.write("<input name=\'" + fieldname + "\' value=\'" + field.value + "\'>");
}
document.write("</td></tr>");
} else document.write(fieldname + "<br>");
}
}
function writeSelect(name, value, options) {
document.write("<select name=\'" + name + "\'>");
document.write("<option value=''>");
for (var i in options) {
document.write("<option value=\'" + options[i] + "\'");
document.write(value == options[i] ? " selected=\'selected=\'>" : ">");
document.write(options[i]);
document.write("</option>");
}
document.write("</select>");
}
var mappingOptions = {
local: 1,
foreign: 1,
order: 2,
accessname: 2,
group: 2,
group_order: 2,
group_prototype: 2,
filter: 2,
filter_additionalTables: 2,
loadmode: 1,
cachemode: 2,
maxsize: 2,
hints: 2,
logicalOperator: 2,
readonly: 2,
"private": 2
}
function applyExtras(propname) {
if (opener && opener.document) {
for (var i=0; i<document.extras.elements.length; i++) {
var e = document.extras.elements[i];
if (!e || !e.name || e.name.indexOf(propname) != 0) {
continue;
}
var e2 = opener.document.getElementById(e.name);
if (e2) {
e2.value = e.value;
}
}
} else {
alert("Error applying changes: opener.document is not defined");
}
window.close();
}
</script>
</head>
<body>
<% response.header prefix="<h3>" suffix="</h3>" %>
<% response.body %>
</body>
</html>

View file

@ -0,0 +1,10 @@
<p>Data sources are defined in db.properties files either at server or application level.</p>
<% param.message prefix="<p style='color: red'>" suffix="</p>" %>
<form method="post">
Please enter a valid data source name:
<% html.select name="datasource" options="response.datasources" %>
&nbsp;&nbsp;
<input type="submit" value=" OK " />
</form>