diff options
Diffstat (limited to 'trunk/infrastructure/framework-src/modules')
31 files changed, 0 insertions, 4671 deletions
diff --git a/trunk/infrastructure/framework-src/modules/atomfeed.js b/trunk/infrastructure/framework-src/modules/atomfeed.js deleted file mode 100644 index 4b86eeb..0000000 --- a/trunk/infrastructure/framework-src/modules/atomfeed.js +++ /dev/null @@ -1,72 +0,0 @@ -/** - * Copyright 2009 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS-IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import("stringutils.sprintf"); - -// TODO: validate XHTML of entries? - -function _xmlDate(d) { - return sprintf("%04d-%02d-%02dT%02d:%02d:%02dZ", - d.getUTCFullYear(), d.getUTCMonth()+1, d.getUTCDate(), - d.getUTCHours(), d.getUTCMinutes(), d.getUTCSeconds()); -} - -// "entries" is an object with "forEach" member (an Array works). -// Each entry should have these properties: -// * title -// * author -// * published (Date) -// * updated (Date) -// * href (URL for HTML version) -// * content (valid xhtml) -// -// NOTE: entries should be sorted descending by entry.updated (newest first) -// - -function renderFeed(title, lastUpdated, entries, href) { - function ampesc(url) { - return url.replace(/&/g, '&'); - } - - var r = []; - r.push('<?xml version="1.0" encoding="utf-8"?>', - '<feed xmlns="http://www.w3.org/2005/Atom">'); - - r.push('<title type="text">' + title + '</title>'); - r.push('<updated>' + _xmlDate(lastUpdated) + '</updated>'); - r.push('<link rel="self" href="' + request.url + '" />'); - r.push('<link rel="alternate" type="text/html" href="' + href + '" />'); - r.push('<id>' + ampesc(request.url) + '</id>'); - - entries.forEach(function(entry) { - r.push('<entry>', - '<title>' + entry.title + '</title>', - '<author><name>' + entry.author + '</name></author>', - '<published>' + _xmlDate(entry.published) + '</published>', - '<updated>' + _xmlDate(entry.updated) + '</updated>', - '<link rel="alternate" type="text/html" href="' + entry.href + '" />', - '<id>'+ampesc(entry.href)+'</id>', - '<content type="xhtml">', - '<div xmlns="http://www.w3.org/1999/xhtml">'+entry.content+'</div>', - '</content>', - '</entry>'); - }); - - r.push('</feed>'); - - return r.join('\n'); -} - diff --git a/trunk/infrastructure/framework-src/modules/blob.js b/trunk/infrastructure/framework-src/modules/blob.js deleted file mode 100644 index af788a0..0000000 --- a/trunk/infrastructure/framework-src/modules/blob.js +++ /dev/null @@ -1,50 +0,0 @@ -/** - * Copyright 2009 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS-IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - - -/** - * Constructs and returns a new Blob from a JavaScript string. - */ -function stringToBlob(contentType, string) { - return { contentType: contentType, - _stringData: string, - numDataBytes: string.length*2 }; -} - -/** - * Constructs and returns a new Blob from a Java byte array (byte[]). - */ -function byteArrayToBlob(contentType, javaByteArray) { - return { contentType: contentType, - _binaryData: javaByteArray, - numDataBytes: javaByteArray.length }; -} - -/** - * Serves a Blob to the client, using the appropriate content-type, - * and stops execution of the current request. - */ -function serveBlob(blob) { - response.setContentType(blob.contentType); - if (blob._binaryData) { - response.writeBytes(new java.lang.String(blob._binaryData, 0)); - } - else if (blob._stringData) { - response.write(blob._stringData); - } - response.stop(); -} diff --git a/trunk/infrastructure/framework-src/modules/cache_utils.js b/trunk/infrastructure/framework-src/modules/cache_utils.js deleted file mode 100644 index f2a360c..0000000 --- a/trunk/infrastructure/framework-src/modules/cache_utils.js +++ /dev/null @@ -1,36 +0,0 @@ -/** - * Copyright 2009 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS-IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import("sync"); - -/* performs function on an object from the cache, all within a lock */ -function syncedWithCache(name, fn) { - return sync.doWithStringLock("cache/"+name, function() { - var parts = name.split("."); - var obj = appjet.cache; - for (var i = 0; i < parts.length; i++) { - var p = parts[i]; - if (!obj[p]) { - obj[p] = {}; - } - obj = obj[p]; - } - return fn(obj); - }); -} - - - diff --git a/trunk/infrastructure/framework-src/modules/comet.js b/trunk/infrastructure/framework-src/modules/comet.js deleted file mode 100644 index 2331f8b..0000000 --- a/trunk/infrastructure/framework-src/modules/comet.js +++ /dev/null @@ -1,91 +0,0 @@ -/** - * Copyright 2009 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS-IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileOverview - * Comet presents a real-time bidirectional-channel interface. Using comet, your - * server can push data to any connected client without waiting for that client - * to issue a request. - * - * <tt>comet</tt> reserves the <tt>/newcomet</tt> path and its subpaths for its - * own use. - */ - -/** - * Gets a list of all client currently connected to the server. - * @function - * @name connections - * @return {array} An array of the string ids of all connected clients. - */ -function connections() { - return Packages.net.appjet.ajstdlib.Comet.connections(appjet.context); -} - -function getNumCurrentConnections() { - return Packages.net.appjet.ajstdlib.Comet.getNumCurrentConnections(); -} - -function isConnected(id) { - return Packages.net.appjet.ajstdlib.Comet.isConnected(id); -} - -function disconnect(id) { - Packages.net.appjet.ajstdlib.Comet.disconnect(id); -} - -function getAttribute(id, key) { - var ret = Packages.net.appjet.ajstdlib.Comet.getAttribute(appjet.context, id, key); - if (ret != null) - return String(ret); -} - -function setAttribute(id, key, value) { - Packages.net.appjet.ajstdlib.Comet.setAttribute(appjet.context, id, key, value); -} - -/** - * Sends a message to a particular client. - * @functionn - * @name sendMessage - * @param {string} id The <tt>id</tt> of the client to send to. - * @param {string} data The string data to send to the client. - */ -function sendMessage(id, msg) { - Packages.net.appjet.ajstdlib.Comet.write(id, msg); -} - -function headInclude() { return '<script src="'+appjet.config.cometPrefix+'/js/client.js"></script>'; }; -function clientCode() { - return Packages.net.appjet.ajstdlib.Comet.getClientCode(appjet.context); -}; -function clientMTime() { - return Packages.net.appjet.ajstdlib.Comet.getClientMTime(appjet.context); -}; - -/** - * WebSocket allows the client to connect to the server via a - * "bidirectional" channel. Messages sent by the server are received by - * the client without the need for additional connections or other delays. - * @class - * @name WebSocket - * @param {string} id The id to use for this client. - */ - -/** - * Connects to the server using the id specified in the constructor. - * @methodOf WebSocket - * @name connect - */ diff --git a/trunk/infrastructure/framework-src/modules/dateutils.js b/trunk/infrastructure/framework-src/modules/dateutils.js deleted file mode 100644 index 72e87c8..0000000 --- a/trunk/infrastructure/framework-src/modules/dateutils.js +++ /dev/null @@ -1,48 +0,0 @@ -/** - * Copyright 2009 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS-IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -function noon(date) { - return new Date(date.toString().split(' ').slice(0, 4).join(' ') + " 12:00"); -} - -function nextMonth(date) { - var newDate = new Date(date.getTime()); - var newMonth = date.getMonth() + 1; - var newYear = date.getFullYear(); - while (newMonth >= 12) { - newYear += 1; - newMonth -= 12; - } - newDate.setMonth(newMonth); - newDate.setFullYear(newYear); - return newDate; -} - -var months = - ["January", "February", "March", "April", "May", "June", - "July", "August", "September", "October", "November", "December"]; - -var shortMonths = months.map(function(mon) { return mon.substr(0, 3); }); - -var days = - ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]; - -var shortDays = days.map(function(day) { return day.substr(0, 3); }); - -function dateFormat(date, format) { - var formatter = new Packages.java.text.SimpleDateFormat(format); - return String(formatter.format(date).toString()); -}
\ No newline at end of file diff --git a/trunk/infrastructure/framework-src/modules/dispatch.js b/trunk/infrastructure/framework-src/modules/dispatch.js deleted file mode 100644 index e7e3ef0..0000000 --- a/trunk/infrastructure/framework-src/modules/dispatch.js +++ /dev/null @@ -1,149 +0,0 @@ -/** - * Copyright 2009 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS-IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileOverview Dispatching for dynamic pages and static files rendered from disk. - */ - -import("jsutils.eachProperty"); -import("stringutils"); - -jimport("java.lang.System.out.println"); - -//---------------------------------------------------------------- -// Util -//---------------------------------------------------------------- - -function PrefixMatcher(p) { - var rs = p.replace(/([\[\]\^\$\\\.\*\+\?\(\)\{\}\|])/g, "\\$1"); - var r = new RegExp('^' + rs + '(.*)$'); - return function(path) { - return r.exec(path); - } -} - -// Like PrefixMatcher, but makes trailing '/' optional, as in /ep/admin or /ep/admin/. -// If trailing '/' is omitted, will redirect to same path with trailing /. -function DirMatcher(p) { - if (p.substr(-1) == '/') { - p = p.substr(0, p.length-1); - } - var prefixMatcher = PrefixMatcher(p+'/'); - return function(path) { - if (path == p) { - response.redirect(p+'/'); - } - return prefixMatcher(path); - } -} - -function _pathMatches(p, loc) { - // returns a regex-result kind of array with length >= 1, or null - if (typeof(loc) == 'string') { - return (p == loc) ? [loc] : null; - } - if (typeof(loc) == 'function') { - return (loc(p) || null); - } - if (loc.exec) { // regexp - var r = loc.exec(p); - return r || null; - } - throw new Error('Uknown type of location: '+loc); -} - -//---------------------------------------------------------------- -// Dispatcher -//---------------------------------------------------------------- - -var Dispatcher = function() { - this._routes = []; // Array([location, (local file path or function)]) -}; - -Dispatcher.prototype.addLocations = function(l) { - var that = this; - l.forEach(function(x) { that._routes.push(x); }); -}; - -Dispatcher.prototype.dispatch = function() { - var p = request.path; - var served = false; - - for (var i = 0; (i < this._routes.length) && (served == false); i++) { - var loc = this._routes[i][0]; - var dst = this._routes[i][1]; - - var match = _pathMatches(p, loc); - if (match) { - if (typeof(dst) != 'function') { - throw new Error('dispatch only dispatches to functions, and this is not a function: '+typeof(dst)); - } - - // call dst(group1, group2, group3, ...) - served = dst.apply(this, Array.prototype.slice.call(match, 1)); - } - }; - - return served; -}; - -//---------------------------------------------------------------- -// fdisp -//---------------------------------------------------------------- - -function forward(module) { - return function(name) { - if (name === "") { - name = "main"; - } - if (name) { - name = name.replace(/\-/g, '_'); - } - var onreq = module['onRequest']; - var f = module['render_'+name]; - var fg = module['render_'+name+'_get']; - var fp = module['render_'+name+'_post']; - - var served = false; - - if (onreq) { - served = onreq(name); - } - - if (served) { - return true; - } - - var method = request.method; - if (method == "HEAD") { - method = "GET"; - } - - if (f) { - f(); - served = true; - } else if (method == "GET" && fg) { - fg(); - served = true; - } else if (method == "POST" && fp) { - fp(); - served = true; - } - - return served; - }; -} - diff --git a/trunk/infrastructure/framework-src/modules/ejs.js b/trunk/infrastructure/framework-src/modules/ejs.js deleted file mode 100644 index bf14ed3..0000000 --- a/trunk/infrastructure/framework-src/modules/ejs.js +++ /dev/null @@ -1,471 +0,0 @@ -/*-------------------------------------------------------------------------- - * EJS - Embedded JavaScript, version 0.1.0 - * Copyright (c) 2007 Edward Benson - * http://www.edwardbenson.com/projects/ejs - * ------------------------------------------------------------------------ - * - * EJS is freely distributable under the terms of an MIT-style license. - * - * EJS is a client-side preprocessing engine written in and for JavaScript. - * If you have used PHP, ASP, JSP, or ERB then you get the idea: code embedded - * in <% // Code here %> tags will be executed, and code embedded in <%= .. %> - * tags will be evaluated and appended to the output. - * - * This is essentially a direct JavaScript port of Masatoshi Seki's erb.rb - * from the Ruby Core, though it contains a subset of ERB's functionality. - * - * Requirements: - * prototype.js - * - * Usage: - * // source should be either a string or a DOM node whose innerHTML - * // contains EJB source. - * var source = "<% var ejb="EJB"; %><h1>Hello, <%= ejb %>!</h1>"; - * var compiler = new EjsCompiler(source); - * compiler.compile(); - * var output = eval(compiler.out); - * alert(output); // -> "<h1>Hello, EJB!</h1>" - * - * For a demo: see demo.html - * For the license: see license.txt - * - *--------------------------------------------------------------------------*/ - -import("jsutils.*"); -import("funhtml"); - -jimport("java.lang.System.out.println"); -jimport("net.appjet.ajstdlib.execution.executeCodeInNewScope"); - -/* Make a split function like Ruby's: "abc".split(/b/) -> ['a', 'b', 'c'] */ -function rsplit(x, regex) { - var item = x; - var result = regex.exec(item); - var retArr = new Array(); - while (result != null) - { - var first_idx = result.index; - var last_idx = regex.lastIndex; - if ((first_idx) != 0) - { - var first_bit = item.substring(0,first_idx); - retArr.push(item.substring(0,first_idx)); - item = item.slice(first_idx); - } - retArr.push(result[0]); - item = item.slice(result[0].length); - result = regex.exec(item); - } - if (! item == '') - { - retArr.push(item); - } - return retArr; -}; - -/* Chop is nice to have too */ -function chop(x) { - return x.substr(0, x.length - 1); -} - -/* Adaptation from the Scanner of erb.rb */ -var EjsScanner = function(source, left, right) { - this.left_delimiter = left +'%'; //<% - this.right_delimiter = '%'+right; //> - this.double_left = left+'%%'; - this.double_right = '%%'+right; - this.left_equal = left+'%='; - this.left_comment = left+'%#'; - if(left=='[') { - this.SplitRegexp = /(\[%%)|(%%\])|(\[%=)|(\[%#)|(\[%)|(%\]\n)|(%\])|(\n)/; - } - else { - this.SplitRegexp = new RegExp('('+this.double_left+')|(%%'+this.double_right+')|('+this.left_equal+')|('+this.left_comment+')|('+this.left_delimiter+')|('+this.right_delimiter+'\n)|('+this.right_delimiter+')|(\n)') - } - - this.source = source; - this.stag = null; - this.lines = 0; -}; -EjsView = function(data) { - this.data = data; -}; -EjsView.prototype.partial = function(options, data){ - if(!data) data = this.data; - return new EJS(options).render(data); -}; - -EjsScanner.to_text = function(input){ - if(input == null || input === undefined) - return ''; - if(input instanceof Date) - return input.toDateString(); - if(input.toString) - return input.toString(); - return ''; -} - -EjsScanner.prototype = { - - /* For each line, scan! */ - scan: function(block) { - scanline = this.scanline; - regex = this.SplitRegexp; - if (! this.source == '') - { - var source_split = rsplit(this.source, /\n/); - for(var i=0; i<source_split.length; i++) { - var item = source_split[i]; - this.scanline(item, regex, block); - } - } - }, - - /* For each token, block! */ - scanline: function(line, regex, block) { - this.lines++; - var line_split = rsplit(line, regex); - for(var i=0; i<line_split.length; i++) { - var token = line_split[i]; - if (token != null) { - try{ - block(token, this); - }catch(e){ - throw {type: 'EjsScanner', line: this.lines}; - } - } - } - } -}; - -/* Adaptation from the Buffer of erb.rb */ -var EjsBuffer = function(pre_cmd, post_cmd) { - this.line = new Array(); - this.script = ""; - this.pre_cmd = pre_cmd; - this.post_cmd = post_cmd; - - for (var i=0; i<this.pre_cmd.length; i++) - { - this.push(pre_cmd[i]); - } -} -EjsBuffer.prototype = { - - push: function(cmd) { - this.line.push(cmd); - }, - - cr: function() { - this.script = this.script + this.line.join('; '); - this.line = new Array(); - this.script = this.script + "\n"; - }, - - close: function() { - if (this.line.length > 0) - { - for (var i=0; i<this.post_cmd.length; i++) - { - this.push(pre_cmd[i]); - } - this.script = this.script + this.line.join('; '); - line = null; - } - } - -}; - -/* Adaptation from the Compiler of erb.rb */ -EjsCompiler = function(source, left) { - this.pre_cmd = ['var ___ejsO = "";']; - this.post_cmd = new Array(); - this.source = ' '; - if (source != null) - { - if (typeof source == 'string') - { - source = source.replace(/\r\n/g, "\n"); - source = source.replace(/\r/g, "\n"); - this.source = source; - } - else if (source.innerHTML) - { - this.source = source.innerHTML; - } - if (typeof this.source != 'string') - { - this.source = ""; - } - } - left = left || '<' - var right = '>' - switch(left) { - case '[': - right = ']' - break; - case '<': - break; - default: - throw left+' is not a supported deliminator' - break; - } - this.scanner = new EjsScanner(this.source, left, right); - this.out = ''; -} -EjsCompiler.prototype = { - compile: function(options) { - options = options || {}; - this.out = ''; - var put_cmd = "___ejsO += "; - var insert_cmd = put_cmd; - var buff = new EjsBuffer(this.pre_cmd, this.post_cmd); - var content = ''; - var clean = function(content) - { - content = content.replace(/\\/g, '\\\\'); - content = content.replace(/\n/g, '\\n'); - content = content.replace(/\"/g, '\\"'); - return content; - }; - this.scanner.scan(function(token, scanner) { - if (scanner.stag == null) - { - //alert(token+'|'+(token == "\n")) - switch(token) { - case '\n': - content = content + "\n"; - buff.push(put_cmd + '"' + clean(content) + '";'); - buff.cr(); - content = ''; - break; - case scanner.left_delimiter: - case scanner.left_equal: - case scanner.left_comment: - scanner.stag = token; - if (content.length > 0) - { - // Chould be content.dump in Ruby - - buff.push(put_cmd + '"' + clean(content) + '"'); - } - content = ''; - break; - case scanner.double_left: - content = content + scanner.left_delimiter; - break; - default: - content = content + token; - break; - } - } - else { - switch(token) { - case scanner.right_delimiter: - switch(scanner.stag) { - case scanner.left_delimiter: - if (content[content.length - 1] == '\n') - { - content = chop(content); - buff.push(content); - buff.cr(); - } - else { - buff.push(content); - } - break; - case scanner.left_equal: - buff.push(insert_cmd + "(EjsScanner.to_text(" + content + "))"); - break; - } - scanner.stag = null; - content = ''; - break; - case scanner.double_right: - content = content + scanner.right_delimiter; - break; - default: - content = content + token; - break; - } - } - }); - if (content.length > 0) - { - // Chould be content.dump in Ruby - buff.push(put_cmd + '"' + clean(content) + '"'); - } - buff.close(); - this.out = buff.script + ";"; - var to_be_evaled = [ - 'var process = function(_CONTEXT,_VIEW) {', - ' with(_VIEW) {', - ' with (_CONTEXT) {', - this.out, - ' return ___ejsO;', - ' }', - ' }', - '};' - ].join(''); - // make funhtml.* available in parent scope. - var parentScope = {}; - parentScope.EjsScanner = EjsScanner; - keys(funhtml).forEach(function(k) { - parentScope[k] = funhtml[k]; - }); - var ret = executeCodeInNewScope( - parentScope, - to_be_evaled, - (options.name || "template"), - 1 - ); - this.process = ret.process; - } -} - - -//type, cache, folder -EJS = function( options ){ - this.set_options(options); - - if(options.url){ - var template = EJS.get(options.url, this.cache); - if (template) return template; - if (template == EJS.INVALID_PATH) return null; - this.text = EJS.request(options.url); - if(this.text == null){ - //EJS.update(options.url, this.INVALID_PATH); - throw 'There is no template at '+options.url; - } - this.name = options.url; - }else if(options.element) - { - if(typeof options.element == 'string'){ - var name = options.element; - options.element = document.getElementById( options.element ); - if(options.element == null) throw name+'does not exist!'; - } - if(options.element.value){ - this.text = options.element.value; - }else{ - this.text = options.element.innerHTML; - } - this.name = options.element.id; - this.type = '['; - } - var template = new EjsCompiler(this.text, this.type); - - template.compile(options); - - - EJS.update(this.name, this); - this.template = template; -}; -EJS.config = function(options){ - EJS.cache = options.cache != null ? options.cache : EJS.cache; - EJS.type = options.type != null ? options.type : EJS.type; - var templates_directory = {}; //nice and private container - - EJS.get = function(path, cache){ - if(cache == false) return null; - if(templates_directory[path]) return templates_directory[path]; - return null; - }; - - EJS.update = function(path, template) { - if(path == null) return; - templates_directory[path] = template; - }; - - EJS.INVALID_PATH = -1; - - -}; -EJS.config( {cache: true, type: '<' } ); - -EJS.prototype = { - render : function(object){ - var v = new EjsView(object); - return this.template.process.call(v, object, v); - }, - out : function(){ - return this.template.out; - }, - set_options : function(options){ - this.type = options.type != null ? options.type : EJS.type; - this.cache = options.cache != null ? options.cache : EJS.cache; - this.text = options.text != null ? options.text : null; - this.name = options.name != null ? options.name : null; - }, - // called without options, returns a function that takes the object - // called with options being a string, uses that as a url - // called with options as an object - update : function(element, options){ - if(typeof element == 'string'){ - element = document.getElementById(element); - } - if(options == null){ - _template = this; - return function(object){ - EJS.prototype.update.call(_template, element, object); - }; - } - if(typeof options == 'string'){ - params = {}; - params.url = options; - _template = this; - params.onComplete = function(request){ - var object = eval( request.responseText ); - EJS.prototype.update.call(_template, element, object); - }; - EJS.ajax_request(params); - }else - { - element.innerHTML = this.render(options); - } - } -}; - - EJS.newRequest = function(){ - var factories = [function() { return new ActiveXObject("Msxml2.XMLHTTP"); },function() { return new XMLHttpRequest(); },function() { return new ActiveXObject("Microsoft.XMLHTTP"); }]; - for(var i = 0; i < factories.length; i++) { - try { - var request = factories[i](); - if (request != null) return request; - } - catch(e) { continue;} - } - }; - - EJS.request = function(path){ - var request = new EJS.newRequest(); - request.open("GET", path, false); - - try{request.send(null);} - catch(e){return null;} - - if ( request.status == 404 || request.status == 2 ||(request.status == 0 && request.responseText == '') ) return null; - - return request.responseText - }; - EJS.ajax_request = function(params){ - params.method = ( params.method ? params.method : 'GET'); - - var request = new EJS.newRequest(); - request.onreadystatechange = function(){ - if(request.readyState == 4){ - if(request.status == 200){ - params.onComplete(request); - }else - { - params.onComplete(request); - } - } - }; - request.open(params.method, params.url); - request.send(null); - }; - -//} - - diff --git a/trunk/infrastructure/framework-src/modules/email.js b/trunk/infrastructure/framework-src/modules/email.js deleted file mode 100644 index 2d81dc3..0000000 --- a/trunk/infrastructure/framework-src/modules/email.js +++ /dev/null @@ -1,53 +0,0 @@ -/** - * Copyright 2009 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS-IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -// import("jsutils.eachProperty"); -// -// function _paramObjectToParamArray(params, enc) { -// var pa = []; -// eachProperty(params, function(k, v) { -// pa.push(enc ? encodeURIComponent(k.toString()) : k.toString()); -// pa.push(enc ? encodeURIComponent(v.toString()) : v.toString()); -// }); -// return pa; -// } - -/** - * Simple way to send an email to a single recipient. Emails will have a - * "from" address of <code>noreply@{appjet.appName}.{appjet.mainDomain}</code>. - * - * Sending is limited to 100 emails per developer account per day. However, - * emails sent to the address on file for the app's owner are not counted - * toward this limit. - * - * @example -result = sendEmail("noone@example.com", "Test Subject", - "Greetings!", {"Reply-To": "sender@example.com"}); - * - * @param {strings} toAddress An array of email address strings, or a single string. - * @param {string} subject The message subject. - * @param {string} body The message body. - * @param {object} [headers] Optional headers to include in the - * message, as a dictionary of {name: value} entries. - */ -function sendEmail(toAddress, fromAddress, subject, headers, body) { - if (typeof(toAddress) == 'string') - toAddress = [toAddress]; - var ret = Packages.net.appjet.ajstdlib.email.sendEmail(toAddress, fromAddress, subject, headers, body); - if (ret != "") - throw new Error(ret); -} - diff --git a/trunk/infrastructure/framework-src/modules/exceptionutils.js b/trunk/infrastructure/framework-src/modules/exceptionutils.js deleted file mode 100644 index b572a3a..0000000 --- a/trunk/infrastructure/framework-src/modules/exceptionutils.js +++ /dev/null @@ -1,210 +0,0 @@ -/** - * Copyright 2009 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS-IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import("ejs.EJS"); -import("funhtml.*"); -import("jsutils.{scalaF0,scalaF1}"); -import("stringutils.{toHTML,sprintf}"); - -function _getException(ex) { - if (ex instanceof java.lang.Throwable) { - return new net.appjet.bodylock.JSRuntimeException(ex.getMessage(), ex); - } else if (ex.javaException) { - return new net.appjet.bodylock.JSRuntimeException(ex.javaException.getMessage(), ex.javaException); - } else if (ex.rhinoException) { - return new net.appjet.bodylock.JSRuntimeException(ex.rhinoException.getMessage(), ex.rhinoException); - } else { - return ex; - } -} - -function _convertStackFrameToTable(id, frame) { - var r = frame.errorContext(4); - var out = []; - var t = TABLE({className: "codecontext"}); - var counter = r._1(); - r._3().foreach(scalaF1(function(s) { - var row = TR(TD({className: "linecell"}, counter++), TD(String(s))); - if (counter-1 == frame.errorLine()) - row[1].attribs['class'] = "offendingline"; - t.push(row); - })); - if (id != 0) - out.push(DIV({className: "errorframe", - onclick: "toggleFrameView('"+id+"')"}, - IMG({className: "zippy", style: "margin-right: 0.5em;", align: "top", src: "http://appjet.com/img/open-arrow.png", id: "image"+id}), - SPAN({className: "errordetail"}, "...was called from "+frame.name()+ " (line "+frame.errorLine()+"):"), - SPAN({className: "sourceline"}, " "+frame.errorContext(0)._3().first()))); - out.push(DIV({id: 'frame'+id, style: (id == 0 ? "" : "display: none;")}, t)); - return out.map(function(tag) { return toHTML(tag); }).join(""); -} - -function getStackTraceHTML(ex) { - ex = _getException(ex); - if (ex.frames().isEmpty()) - return "No stack trace available."; - var out = []; - var counter = 0; - var firstFrame = ex.frames().first(); - out.push(toHTML(DIV({id: "errortitle"}, "Error in "+firstFrame.name()))); - out.push(toHTML(DIV({id: "errormessage"}, ""+ex.cause().getMessage()+" at "+firstFrame.name()+" (Line "+firstFrame.errorLine()+")"))); - ex.frames().foreach(scalaF1(function(frame) { - out.push(_convertStackFrameToTable(counter++, frame)); - })); - return out.join(""); -} - -function getStackTraceFullpage(ex) { - var tmpl = new EJS({text: _tmpl}); - return tmpl.render({trace: getStackTraceHTML(ex)}); -} - -function getStackTracePlain(ex) { - ex = _getException(ex); - if (ex.frames().isEmpty()) { - var cause = ex.cause(); - var sw = new java.io.StringWriter(); - cause.printStackTrace(new java.io.PrintWriter(sw)); - return sw.toString(); - } - var out = []; - var firstFrame = ex.frames().first(); - out.push("Error in "+firstFrame.name()); - out.push(""+ex.cause().getMessage()+" at "+firstFrame.name()+" (Line "+firstFrame.errorLine()+")"); - var counter = 0; - ex.frames().foreach(scalaF1(function(frame) { - if (counter++ > 0) { - out.push(""); - out.push("...was called from "+frame.name()+" (line "+frame.errorLine()+"): "+frame.errorContext(0)._3().first()); - } - var r = frame.errorContext(4); - var c2 = r._1(); - r._3().foreach(scalaF1(function(s) { - var pre = " "; - if (c2 == frame.errorLine()) - pre = ">"; - out.push(sprintf("%s %4s | %s", pre, ""+c2, s)); - c2++; - })); - })); - return out.join("\n"); -} - -/* template follows */ -var _tmpl = """<!DOCTYPE HTML PUBLIC - "-//W3C//DTD XHTML 1.0 Strict//EN" - "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"> -<head> - <title>AppJet Error</title> - <meta http-equiv="Content-type" content="text/html; charset=utf-8" /> - <meta http-equiv="Content-Language" content="en-us" /> - <script type="text/javascript" src="http://appjet.com/js/343607636acfee88faa2b638330a3370/jquery-1.2.6.js"></script> - <script type="text/javascript"> -function toggleFrameView(frameId) { - var hidden = $("#frame"+frameId+":hidden") - var visible = $("#frame"+frameId+":visible") - if (hidden.length > 0) { - hidden.show("normal") - $("#image"+frameId).attr("src", "http://appjet.com/img/close-arrow.png") - } else { - visible.hide("normal") - $("#image"+frameId).attr("src", "http://appjet.com/img/open-arrow.png") - } -} - -function toggleErrorView() { - var hidden = $("#hiddentrace:hidden"); - var visible = $("#hiddentrace:visible"); - if (hidden.length > 0) { - hidden.slideDown("normal"); - } else { - visible.slideUp("normal"); - } - return false; -} - -function load() { - $(".zippy").attr("src", "http://appjet.com/img/open-arrow.png") -} -</script> -<style> -body { - font-family: verdana, helvetica, sans-serif; - font-size: 60%; - margin: 1em; -} -#header { border-bottom: 1px solid red; margin-bottom: 0.8em; } -#errortitle { font-weight: bold; font-size: 1.6em; margin-bottom: 0.76em;} -#errormessage { font-size: 1.4em; margin-bottom: 1.0em} -#errorexplanation { - background-color: #ffd; margin: 1em; padding: 0 1em; - border: 1px solid #cc9; - line-height: 150%; -} -#errorexplanation ul, #errorexplanation li { margin: 0; padding: 0; } -#errorexplanation ul { padding-left: 2em; } -#errorexplanation { font-size: 9pt; } -#errorexplanation code { font-size: 10pt; } -#errorexplanation code { padding: 1px; background: #ddc; margin: 0 5px; - white-space:nowrap; } -#errorexplanation code.quote { background: #fcc; } -#errorexplanation p, #errorexplanation li { margin: 1em 0 } -#frame0 { margin-top: 2.0em; } -.errorframe { - margin-bottom: 0.5em; - margin-top: 1em; - cursor: pointer; - color: blue; -} -.errordetail { - text-decoration: underline; -} -.errorframe:hover { - color: #c47827; -} -.sourceline { - font-size: 1.4em; - color: black; - font-family: monospace; -} -#statuscode { - float: right; - font-size: 2.4em; - font-weight: bold; -} -.codecontext { - border: 1px solid black; - font-family: monospace; - font-size: 1.4em; -} -.codecontext td { padding: 0.1em 0.3em; } -.codecontext .linecell { border-right: 1px solid #888; } -.codecontext .offendingline { background-color: #ffcccc; } -.errotemplate .codecontext .linecell { border-right: 1px solid black; } -pre { - margin: 0px; - padding: 0px; - border: 0px; -} - -#errorexplanation tt { font-size: 85%; color: #666; } -</style> -</head> -<body onload="load()"> -<%= trace %> -</body> -</html>""" diff --git a/trunk/infrastructure/framework-src/modules/execution.js b/trunk/infrastructure/framework-src/modules/execution.js deleted file mode 100644 index 1cec418..0000000 --- a/trunk/infrastructure/framework-src/modules/execution.js +++ /dev/null @@ -1,58 +0,0 @@ -/** - * Copyright 2009 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS-IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import("jsutils.{scalaF0,scalaF1}"); - -/** - * Asynchronously call a function as soon as the current request completes. - **/ -function async(f) { - Packages.net.appjet.ajstdlib.execution.runAsync(appjet.context, f); -} - -function initTaskThreadPool(name, poolSize) { - Packages.net.appjet.ajstdlib.execution.createNamedTaskThreadPool(name, poolSize); -} - -function scheduleTask(poolName, taskName, delayMillis, args) { - return Packages.net.appjet.ajstdlib.execution.scheduleTaskInPool(poolName, taskName, delayMillis, args); -} - -function shutdownAndWaitOnTaskThreadPool(poolName, timeoutMillis) { - return Packages.net.appjet.ajstdlib.execution.shutdownAndWaitOnTaskThreadPool(poolName, timeoutMillis); -} - -function fancyAssEval(initCode, mainCode) { - function init(runner) { - Packages.net.appjet.bodylock.BodyLock.evaluateString( - runner.globalScope(), - initCode, - "eval'd code imports", - 1); - } - var runner = Packages.net.appjet.oui.ScopeReuseManager.getEmpty(scalaF1(init)); - var ec = new Packages.net.appjet.oui.ExecutionContext( - new Packages.net.appjet.oui.RequestWrapper(request.underlying), - null, runner); - return Packages.net.appjet.oui.ExecutionContextUtils.withContext(ec, - scalaF0(function() { - return Packages.net.appjet.bodylock.BodyLock.evaluateString( - runner.globalScope(), - mainCode, - "eval'd code main", - 1); - })); -}
\ No newline at end of file diff --git a/trunk/infrastructure/framework-src/modules/fastJSON.js b/trunk/infrastructure/framework-src/modules/fastJSON.js deleted file mode 100644 index 3198b96..0000000 --- a/trunk/infrastructure/framework-src/modules/fastJSON.js +++ /dev/null @@ -1,27 +0,0 @@ -/** - * Copyright 2009 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS-IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -jimport("net.appjet.oui.FastJSON"); -jimport("java.lang.System.out.println"); - -function stringify(x) { - return String(FastJSON.stringify(x)); -} - -function parse(x) { - return FastJSON.parse(appjet.context, x); -} - diff --git a/trunk/infrastructure/framework-src/modules/faststatic.js b/trunk/infrastructure/framework-src/modules/faststatic.js deleted file mode 100644 index 5cca676..0000000 --- a/trunk/infrastructure/framework-src/modules/faststatic.js +++ /dev/null @@ -1,318 +0,0 @@ -/** - * Copyright 2009 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS-IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileOverview serving static files, including js and css, and cacheing - * and minifying. - * - * Terminology Note: - * "path" is confusing because paths can be part of URLs and part - * of filesystem paths, and static files have both types of paths - * associated with them. Therefore, in this module: - * - * LOCALDIR or LOCALFILE refers to directories or files on the filesystem. - * - * HREF is used to describe things that go in a URL. - */ - -import("fileutils.{readFile,readFileBytes}"); -import("yuicompressor"); -import("stringutils"); -import("varz"); -import("ejs.EJS"); - -jimport("java.lang.System.out.println"); - -//---------------------------------------------------------------- -// Content Type Guessing -//---------------------------------------------------------------- - -var _contentTypes = { - 'gif': 'image/gif', - 'png': 'image/png', - 'jpg': 'image/jpeg', - 'jpeg': 'image/jpeg', - 'css': 'text/css', - 'js': 'application/x-javascript', - 'txt': 'text/plain', - 'html': 'text/html; charset=utf-8', - 'ico': 'image/x-icon', - 'swf': 'application/x-shockwave-flash', - 'zip': 'application/zip', - 'xml': 'application/xml' -}; - -var _gzipableTypes = { - 'text/css': true, - 'application/x-javascript': true, - 'text/html; charset=utf-8': true -}; - -function _guessContentType(path) { - var ext = path.split('.').pop().toLowerCase(); - return _contentTypes[ext] || 'text/plain'; -} - -//---------------------------------------------------------------- - -function _getCache(name) { - var m = 'faststatic'; - if (!appjet.cache[m]) { - appjet.cache[m] = {}; - } - var c = appjet.cache[m]; - if (!c[name]) { - c[name] = {}; - } - return c[name]; -} - -var _mtimeCheckInterval = 5000; // 5 seconds - -function _getMTime(f) { - var mcache = _getCache('mtimes'); - var now = +(new Date); - if (appjet.config.devMode || - !(mcache[f] && (now - mcache[f].lastCheck < _mtimeCheckInterval))) { - var jfile = new net.appjet.oui.JarVirtualFile(f); - if (jfile.exists() && !jfile.isDirectory()) { - mcache[f] = { - lastCheck: now, - mtime: jfile.lastModified() - }; - } else { - mcache[f] = null; - } - } - if (mcache[f]) { - return +mcache[f].mtime; - } else { - return null; - } -} - -function _wrapFile(localFile) { - return { - getPath: function() { return localFile; }, - getMTime: function() { return _getMTime(localFile); }, - getContents: function() { return _readFileAndProcess(localFile, 'string'); } - }; -} - -function _readFileAndProcess(fileName, type) { - if (fileName.slice(-8) == "_ejs.css") { - // run CSS through EJS - var template = readFile(fileName); - var ejs = new EJS({text:template, name:fileName}); - var resultString = ejs.render({}); - if (type == 'bytes') { - return new java.lang.String(resultString).getBytes("UTF-8"); - } - else { - return resultString; - } - } - else if (type == 'string') { - return readFile(fileName); - } - else if (type == 'bytes') { - return readFileBytes(fileName); - } -} - -function _cachedFileBytes(f) { - var mtime = _getMTime(f); - if (!mtime) { return null; } - var fcache = _getCache('file-bytes-cache'); - if (!(fcache[f] && (fcache[f].mtime == mtime))) { - varz.incrementInt("faststatic-file-bytes-cache-miss"); - var bytes = _readFileAndProcess(f, 'bytes'); - if (bytes) { - fcache[f] = {mtime: mtime, bytes: bytes}; - }; - } - if (fcache[f] && fcache[f].bytes) { - return fcache[f].bytes; - } else { - return null; - } -} - -function _shouldGzip(contentType) { - var userAgent = request.headers["User-Agent"]; - if (! userAgent) return false; - if (! (/Firefox/.test(userAgent) || /webkit/i.test(userAgent))) return false; - if (! _gzipableTypes[contentType]) return false; - - return request.acceptsGzip; -} - -function _getCachedGzip(original, key) { - var c = _getCache("gzipped"); - if (! c[key] || ! java.util.Arrays.equals(c[key].original, original)) { - c[key] = {original: original, - gzip: stringutils.gzip(original)}; - } - return c[key].gzip; -} - -function _setGzipHeader() { - response.setHeader("Content-Encoding", "gzip"); -} - -//---------------------------------------------------------------- - -/** - * Function for serving a single static file. - */ -function singleFileServer(localPath, opts) { - var contentType = _guessContentType(localPath); - - return function() { - (opts.cache ? response.alwaysCache() : response.neverCache()); - response.setContentType(contentType); - var bytes = _cachedFileBytes(localPath); - if (bytes) { - if (_shouldGzip(contentType)) { - bytes = _getCachedGzip(bytes, "file:"+localPath); - _setGzipHeader(); - } - response.writeBytes(bytes); - return true; - } else { - return false; - } - }; -} - -/** - * valid opts: - * alwaysCache: default false - */ -function directoryServer(localDir, opts) { - if (stringutils.endsWith(localDir, "/")) { - localDir = localDir.substr(0, localDir.length-1); - } - return function(relpath) { - if (stringutils.startsWith(relpath, "/")) { - relpath = relpath.substr(1); - } - if (relpath.indexOf('..') != -1) { - response.forbid(); - } - (opts.cache ? response.alwaysCache() : response.neverCache()); - var contentType = _guessContentType(relpath); - response.setContentType(contentType); - var fullPath = localDir + "/" + relpath; - var bytes = _cachedFileBytes(fullPath); - - if (bytes) { - if (_shouldGzip(contentType)) { - bytes = _getCachedGzip(bytes, "file:"+fullPath); - _setGzipHeader(); - } - response.writeBytes(bytes); - return true; - } else { - return false; - } - }; -} - -/** - * Serves cat files, which are concatenated versions of many files. - */ -function compressedFileServer(opts) { - var cfcache = _getCache('compressed-files'); - return function() { - var key = request.path.split('/').slice(-1)[0]; - var contentType = _guessContentType(request.path); - response.setContentType(contentType); - response.alwaysCache(); - var data = cfcache[key]; - if (data) { - if (_shouldGzip(contentType)) { - data = _getCachedGzip((new java.lang.String(data)).getBytes(response.getCharacterEncoding()), "comp:"+key); - _setGzipHeader(); - response.writeBytes(data); - } else { - response.write(data); - } - return true; - } else { - return false; - } - }; -} - -function getCompressedFilesKey(type, baseLocalDir, localFileList) { - if (stringutils.endsWith(baseLocalDir, '/')) { - baseLocalDir = baseLocalDir.substr(0, baseLocalDir.length-1); - } - - var fileList = []; - // convert passed-in file list into list of our file objects - localFileList.forEach(function(f) { - if (typeof(f) == 'string') { - fileList.push(_wrapFile(baseLocalDir+'/'+f)); - } else { - fileList.push(f); - } - }); - - // have we seen this exact fileset before? - var fsId = fileList.map(function(f) { return f.getPath(); }).join('|'); - var fsMTime = Math.max.apply(this, - fileList.map(function(f) { return f.getMTime(); })); - - var kdcache = _getCache('fileset-keydata-cache'); - if (!(kdcache[fsId] && (kdcache[fsId].mtime == fsMTime))) { - //println("cache miss for fileset: "+fsId); - //println("compressing fileset..."); - kdcache[fsId] = { - mtime: fsMTime, - keyString: _compressFilesAndMakeKey(type, fileList) - }; - } - return kdcache[fsId].keyString; -} - -function _compressFilesAndMakeKey(type, fileList) { - function _compress(s) { - if (type == 'css') { - varz.incrementInt("faststatic-yuicompressor-compressCSS"); - return yuicompressor.compressCSS(s); - } else if (type == 'js') { - varz.incrementInt("faststatic-yuicompressor-compressJS"); - return yuicompressor.compressJS(s); - } else { - throw Error('Dont know how to compress this filetype: '+type); - } - } - - var fullstr = ""; - fileList.forEach(function(f) { - fullstr += _compress(f.getContents()); - }); - - fullstr = _compress(fullstr); - - var key = stringutils.md5(fullstr) + '.' + type; - var cfcache = _getCache('compressed-files'); - cfcache[key] = fullstr; - return key; -} - diff --git a/trunk/infrastructure/framework-src/modules/fileutils.js b/trunk/infrastructure/framework-src/modules/fileutils.js deleted file mode 100644 index aaf12e2..0000000 --- a/trunk/infrastructure/framework-src/modules/fileutils.js +++ /dev/null @@ -1,108 +0,0 @@ -/** - * Copyright 2009 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS-IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** @fileOverview misc file functions */ - -jimport("java.io.File", - "java.io.DataInputStream", - "java.io.FileInputStream", - "java.lang.reflect.Array", - "java.lang.Byte", - "java.io.FileReader", - "java.io.BufferedReader", - "net.appjet.oui.JarVirtualFile"); - -function readFileBytes(path) { - var jfile = new JarVirtualFile(path); - if (!jfile.exists() || jfile.isDirectory()) { - throw 'Not a file: '+path; - } - return net.appjet.common.util.BetterFile.getStreamBytes(jfile.openStream()); -} - -function readFile(path) { - var bytes = readFileBytes(path); - if (bytes !== null) { - return String(new java.lang.String(bytes)); - } else { - return null; - } -} - -function fileLastModified(path) { - var jfile = new JarVirtualFile(path); - if (!jfile.exists()) { - throw "Not a file: "+path; - } - return jfile.lastModified(); -} - -//---------------------------------------------------------------- -// real files -//---------------------------------------------------------------- - -function readRealFileBytes(path) { - var jfile = new File(path); - if (!jfile.exists() || jfile.isDirectory()) { - throw 'Not a real file: '+path; - } - var jdata = new DataInputStream(new FileInputStream(jfile)); - var size = jfile.length(); - var bytes = Array.newInstance(Byte.TYPE, size); - jdata.read(bytes, 0, size); - jdata.close(); - return bytes; -} - -function readRealFile(path) { - var bytes = readRealFileBytes(path); - if (bytes !== null) { - return String(new java.lang.String(bytes)); - } else { - return null; - } -} - -function writeRealFile(path, data) { - var jf = new Packages.java.io.File(path); - var fw = new Packages.java.io.FileWriter(jf); - fw.write(data); - fw.flush(); - fw.close(); -} - - -function eachFileLine(file, fn) { - var iter = fileLineIterator(file); - while (iter.hasNext) { - fn(iter.next); - } -} - -function fileLineIterator(file) { - var reader = new BufferedReader(new FileReader(file)); - var nextLine = reader.readLine(); - return { - get hasNext() { return nextLine !== null }, - get next() { - var curLine = nextLine; - if (this.hasNext) { - nextLine = reader.readLine(); - } - return curLine; - } - }; -} diff --git a/trunk/infrastructure/framework-src/modules/funhtml.js b/trunk/infrastructure/framework-src/modules/funhtml.js deleted file mode 100644 index c27b667..0000000 --- a/trunk/infrastructure/framework-src/modules/funhtml.js +++ /dev/null @@ -1,158 +0,0 @@ -/** - * Copyright 2009 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS-IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileOverview Functional HTML tag writing.<br/> - * - * <p>This library allows you to write HTML in the form of nested function - * calls. By default, a function is predefined for each tag, with the function - * name being in all caps. A dictionary of HTML attributes can optionally be - * passed as a first argument to a tag; other arguments become child tags. - * Attribute names that conflict with JavaScript - * keywords have been renamed; use "className" in place of "class" and - * "htmlFor" in place of "for".</p> - * - * <p>Tag objects inherit from Array, so array methods can be used to - * manipulate a tag's list of child tags.</p> - * - * @example -print(P({id:"sec3"},"Tags are ",B(I("crazy"))," awesome.")); - */ - -import("jsutils.eachProperty"); -import("stringutils"); -import("stringutils.toHTML"); - -function html(x) { - // call out to stringutils.html(). - var args = Array.prototype.slice.call(arguments); - return stringutils.html.apply(this, args); -}; - -function toHTML(x) { - // call out to stringutils.toHTML(). - var args = Array.prototype.slice.call(arguments); - return stringutils.toHTML.apply(this, args) -}; - -//---------------------------------------------------------------- -// tags. -//---------------------------------------------------------------- - -var _neverSingletones = { - 'TEXTAREA': true, - 'SCRIPT': true, - 'DIV': true, - 'IFRAME': true, - 'UL': true, - 'TABLE': true -}; - -/** - * Imports a specified list of tags. All HTML tags are automatically imported - * by default, but you may wish to use the tag library to write other kinds - * of mark-up. For each tag you want to import, pass in the name (including - * any punctuation) with the (upper/lower) case you want to use for the function - * (traditionally all uppercase). The function name will have punctuation - * replaced with underscores, and the printed tag will be all lowercase. - * - * @param {object} scopeObj where to define the tags; to define in the global scope, pass <code>this</code> from the top level (not from inside a function) - * @param {array} tagArray an array of strings, the tags to import - * @example -importTags(this, ["MEDIA:TITLE"]); -print(MEDIA_TITLE({type:"html"}, "funny pictures")); -// prints <media:title type="html">funny pictures</media:title> - */ -function _importTags(scopeObj, tagArray) { - tagArray.forEach(function(arg) { - var funcName = arg.replace(/:/g, "_").replace(/-/g, "_"); - var tagName = arg.toLowerCase(); - scopeObj[funcName] = function() { - var tag = []; - tag.name = tagName; - var contents = Array.prototype.slice.call(arguments); - if (contents.length > 0) { - if (contents[0] && - (! contents[0].toHTML) && - ((typeof contents[0]) == "object") && - (! Array.prototype.isPrototypeOf(contents[0])) && - (! Date.prototype.isPrototypeOf(contents[0]))) { - // first arg is attributes - tag.attribs = contents[0]; - contents.shift(); - } - else { - tag.attribs = {}; - } - contents.forEach(function (content) { - tag.push(content); - }); - } - else { - tag.attribs = {}; - } - tag.toString = function() { return this.toHTML(); }; // this behavior is relied on - tag.toHTML = function() { - var t = this; - var result = []; - result.add = function(x) { this.push(x); return this; }; - result.add('<').add(t.name); - if (t.attribs) { - eachProperty(t.attribs, function(k,v) { - if (k == "className") k = "class"; - if (k == "htmlFor") k = "for"; - if (!(v === undefined)) { - // escape quotes and newlines in values - v = String(v).replace(/\"/g, '\\"').replace(/\n/g, '\\n'); - result.add(' ').add(k).add('="').add(v).add('"'); - } - }); - } - if ((t.length < 1) && (!(t.name.toUpperCase() in _neverSingletones))) { - result.add(' />'); - } - else { - result.add('>'); - t.forEach(function (x) { - result.add(toHTML(x)); - }); - result.add('</').add(t.name).add('\n>'); - } - return result.join(""); - }; - return tag; - }; - }); -} - -var _html_tags = - ["A", "ABBR", "ACRONYM", "ADDRESS", "APPLET", "AREA", "B", - "BASE", "BASEFONT", "BDO", "BIG", "BLOCKQUOTE", "BODY", - "BR", "BUTTON", "CAPTION", "CENTER", "CITE", "CODE", "COL", - "COLGROUP", "DD", "DEL", "DIR", "DIV", "DFN", "DL", "DT", - "EM", "FIELDSET", "FONT", "FORM", "FRAME", "FRAMESET", - "H1", "H2", "H3", "H4", "H5", "H6", - "HEAD", "HR", "HTML", "I", "IFRAME", "IMG", "INPUT", - "INS", "ISINDEX", "KBD", "LABEL", "LEGEND", "LI", "LINK", - "MAP", "MENU", "META", "NOFRAMES", "NOSCRIPT", "OBJECT", - "OL", "OPTGROUP", "OPTION", "P", "PARAM", "PRE", "Q", "S", - "SAMP", "SCRIPT", "SELECT", "SMALL", "SPAN", "STRIKE", - "STRONG", "STYLE", "SUB", "SUP", "TABLE", "TBODY", "TD", - "TEXTAREA", "TFOOT", "TH", "THEAD", "TITLE", "TR", "TT", - "U", "UL", "VAR", "XMP"]; - -_importTags(this, _html_tags); - diff --git a/trunk/infrastructure/framework-src/modules/global/appjet.js b/trunk/infrastructure/framework-src/modules/global/appjet.js deleted file mode 100644 index 135ac44..0000000 --- a/trunk/infrastructure/framework-src/modules/global/appjet.js +++ /dev/null @@ -1,107 +0,0 @@ -/** - * Copyright 2009 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS-IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import("jsutils.scalaF0"); - -//---------------------------------------------------------------- -// global static "appjet" object -//---------------------------------------------------------------- - -/** - * @fileOverview The global appjet object contains access to the AppJet runtime, - * app meta-data, and other information. - */ -var appjet = { - -/** - * This is the interface to the execution context. You probably won't need - * to use this, but if you do, be careful! - * @type object - */ -get context() { - return net.appjet.oui.ExecutionContextUtils.currentContext(); -}, - -get executionId() { - return this.context.executionId(); -}, - -// /** -// * Holds the current request's requestId. (These IDs may be reused!) -// * @type String -// */ -// get requestId() { -// return this.context.requestId(); -// }, - -/** - * Volatile cache that persists between requests. (JavaScript object). - */ -get cache() { - return Packages.net.appjet.ajstdlib.ajstdlib.attributes() - .getOrElseUpdate("cache", scalaF0({})); -}, - -get cacheRoot() { - return function(name) { - return Packages.net.appjet.ajstdlib.ajstdlib.attributes() - .getOrElseUpdate("cache-"+(name?name:""), scalaF0({})); - }; -}, - -/** - * A global lock for this app (ReentrantLock object). - */ -get globalLock() { - return net.appjet.ajstdlib.ajstdlib.globalLock(); -}, - -/** - * Per-request cache, cleared between requests. - */ -get requestCache() { - return this.context.attributes().getOrElseUpdate("requestCache", scalaF0({})) -}, - -/** - * Per-scope cache, persisted in this "server" instance. - */ -get scopeCache() { - return this.context.runner().attributes().getOrElseUpdate("scopeCache", scalaF0({})); -}, - -/** - * config params for app. - */ -get config() { - return Packages.net.appjet.oui.config.configObject(this.context.runner().globalScope()); -}, - -/** - * tells appjet not to re-use this "scope"/"server" - */ -get retireScope() { - return function() { this.context.runner().reuseOk_$eq(false); } -}, - -/** - * How many milliseconds the server has been running for. - */ -get uptime() { - return Date.now() - Packages.net.appjet.oui.main.startTime().getTime(); -} - -}; // end: var appjet = {...
\ No newline at end of file diff --git a/trunk/infrastructure/framework-src/modules/global/request.js b/trunk/infrastructure/framework-src/modules/global/request.js deleted file mode 100644 index a4327f9..0000000 --- a/trunk/infrastructure/framework-src/modules/global/request.js +++ /dev/null @@ -1,312 +0,0 @@ -/** - * Copyright 2009 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS-IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import("stringutils.trim"); -import("jsutils.scalaF0") - -function _cx() { return appjet.context }; - -function _addIfNotPresent(obj, key, value) { - if (!(key in obj)) obj[key] = value; -} - -var request = { - -get isDefined() { - return ( - _cx() != null && - _cx().request() != null && - (! _cx().request().isFake()) && - _cx().request().req() != null - ); -}, - -get cache() { - var req = _cx().request().req(); - if (req.getAttribute("jsCache") == null) { - req.setAttribute("jsCache", {}); - } - return req.getAttribute("jsCache"); -}, - -get continuation() { - if (this.isDefined) { - var c = Packages.net.appjet.ajstdlib.execution.getContinuation(_cx()); - var u = this.underlying; - return { - suspend: function(timeout) { - return Packages.net.appjet.ajstdlib.execution.sync( - u, scalaF0(function() { return c.suspend(timeout); })); - }, - resume: function() { - Packages.net.appjet.ajstdlib.execution.sync( - u, scalaF0(function() { c.resume(); })) - } - } - } -}, - -get underlying() { - if (this.isDefined) { - return _cx().request().req(); - } -}, - -/** - * The request path following the hostname. For example, if the user - * is visiting yourapp.appjet.net/foo, then this will be set to - * "/foo". - * - * This does not include CGI parameters or the domain name, and always - * begins with a "/". - * - * @type string - */ -get path() { - if (this.isDefined) { - return String(_cx().request().path()); - } -}, - -/** - * The value request query string. - * - * For example, if the user visits "yourapp.appjet.net/foo?id=20", then - * query will be "id=20". - * - * @type string - */ -get query() { - if (this.isDefined) { - if (_cx().request().query() != null) { - return _cx().request().query(); - } - } -}, - -/** - * The content of a POST request. Retrieving this value may interfere - * with the ability to get post request parameters sent in the body of - * a request via the "params" property. Use with care. - * - * @type string - */ -get content() { - if (this.isDefined) { - if (_cx().request().content() != null) { - return _cx().request().content(); - } - } -}, - -/** - * Either "GET" or "POST" (uppercase). - * @type string - */ -get method() { - if (this.isDefined) { - return String(_cx().request().method().toUpperCase()); - } -}, - -/** - * Whether the curent HTTP request is a GET request. - * @type boolean - */ -get isGet() { - return (this.method == "GET"); -}, - -/** - * Whether the current HTTP request is a POST request. - * @type boolean - */ -get isPost() { - return (this.method == "POST"); -}, - -/** - * Either "http" or "https" (lowercase). - * @type string - */ -get scheme() { - if (this.isDefined) { - return String(_cx().request().scheme()); - } -}, - -/** - * Whether the current request arrived using HTTPS. - * @type boolean - */ -get isSSL() { - return (this.scheme == "https"); -}, - -/** - * Holds the IP address of the user making the request. - * @type string - */ -get clientAddr() { - if (this.isDefined) { - return String(_cx().request().clientAddr()); - } -}, - -/** - * Parameters associated with the request, either from the query string - * or from the contents of a POST, e.g. from a form. Parameters are accessible - * by name as properties of this object. The property value is either a - * string (typically) or an array of strings (if the parameter occurs - * multiple times in the request). - * - * @type object - */ -get params() { - if (this.isDefined) { - var cx = _cx(); - var req = cx.request(); - return cx.attributes().getOrElseUpdate("requestParams", - scalaF0(function() { return req.params(cx.runner().globalScope()); })); - } -}, - -/** - * Uploaded files associated with the request, from the contents of a POST. - * - * @type object - */ -get files() { - if (this.isDefined) { - var cx = _cx(); - var req = cx.request(); - return cx.attributes().getOrElseUpdate("requestFiles", - scalaF0(function() { return req.files(cx.runner().globalScope()); })); - } -}, - -/** - * Used to access the HTTP headers of the current request. Properties are - * header names, and each value is either a string (typically) or an - * array of strings (if the header occurs multiple times in the request). - * - * @example -print(request.headers["User-Agent"]); - * - * @type object - */ -get headers() { - if (this.isDefined) { - var cx = _cx(); - var req = cx.request(); - return cx.attributes().getOrElseUpdate("requestHeaders", - scalaF0(function() { return req.headers(cx.runner().globalScope()); })); - } -}, - -// TODO: this is super inefficient to do each time someone accesses -// request.cookies.foo. We should probably store _cookies in the requestCache. -get cookies() { - var _cookies = {}; - var cookieHeaderArray = this.headers['Cookie']; - if (!cookieHeaderArray) { return {}; } - if (!(cookieHeaderArray instanceof Array)) - cookieHeaderArray = [cookieHeaderArray]; - var name, val; - - cookieHeaderArray.forEach(function (cookieHeader) { - cookieHeader.split(';').forEach(function(cs) { - var parts = cs.split('='); - if (parts.length == 2) { - name = trim(parts[0]); - val = trim(unescape(parts[1])); - _addIfNotPresent(_cookies, name, val); - } - }); - }); - - return _cookies; -}, - -/** - * Holds the full URL of the request. - */ -get url() { - if (this.isDefined) { - return this.scheme+"://"+this.host+this.path+(this.query ? "?"+this.query : ""); - } -}, - -get host() { - if (this.isDefined) { - // required by HTTP/1.1 to be present. - return String(this.headers['Host']).toLowerCase(); - } -}, - -get domain() { - if (this.isDefined) { - // like host, but without the port if there is one. - return this.host.split(':')[0]; - } -}, - -get uniqueId() { - return String(_cx().executionId()); -}, - -get protocol() { - if (this.isDefined) { - return String(_cx().request().protocol()); - } -}, - -get userAgent() { - if (this.isDefined) { - var agentString = (request.headers['User-Agent'] || "?"); - return { - toString: function() { return agentString; }, - isIPhone: function() { return (agentString.indexOf("(iPhone;") > 0); } - }; - } -}, - -get acceptsGzip() { - if (this.isDefined) { - var headerArray = this.headers["Accept-Encoding"]; - if (! (headerArray instanceof Array)) { - headerArray = [headerArray]; - } - // Want to see if some accept-encoding header OK's gzip. - // Starting with: "Accept-Encoding: gzip; q=0.5, deflate; q=1.0" - // 1. Split into ["gzip; q=0.5", "delfate; q=1.0"] - // 2. See if some entry is gzip with q > 0. (q is optional.) - return headerArray.some(function(header) { - if (! header) return false; - return header.split(/,\s*/).some(function(validEncoding) { - if (!validEncoding.indexOf("gzip") == 0) { - return false; - } - if (/q=[0\.]*$/.test(validEncoding)) { - return false; - } - return true; - }); - }); - } -} - -}; // end: var request = {... diff --git a/trunk/infrastructure/framework-src/modules/global/response.js b/trunk/infrastructure/framework-src/modules/global/response.js deleted file mode 100644 index 7236920..0000000 --- a/trunk/infrastructure/framework-src/modules/global/response.js +++ /dev/null @@ -1,294 +0,0 @@ -/** - * Copyright 2009 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS-IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileOverview Helpers for the HTTP response. - */ - -/** @ignore */ -function _cx() { return appjet.context }; - -/** @ignore */ -function _cookiestring(c) { - var x = ''; - if (!c.name) { throw new Error('cookie name is required'); } - if (!c.value) { c.value = ''; } - x += (c.name + '=' + escape(c.value)); - - // expires - if (c.expires instanceof Date) { - x += ('; expires='+_cookiedate(c.expires)); - } - if (typeof(c.expires) == 'number') { - var today = (new Date()).valueOf(); - var d = new Date(today + 86400000*c.expires); - x += ('; expires='+_cookiedate(d)); - } - - // domain - if (c.domain) { x += ('; domain='+c.domain); } - - // path - if (c.path) { x += ('; path='+c.path); } - - // secure - if (c.secure == true) { x += '; secure'; } - - return x; -}; - -/** @ignore */ -function _cookiedate(d) { - var x = d.toGMTString(); - var p = x.split(' '); - return [p[0], [p[1], p[2], p[3]].join('-'), p[4], p[5]].join(' '); -}; - -var response = { - -get isDefined() { - return _cx().response() != null; -} - -}; - -/** - * Halts the program immediately and returns 403 Forbidden error to the user. - */ -response.forbid = function() { - _cx().response().error(403, "Forbidden"); -}; - -/** - * Halts the program immediately. - * - * @param {boolean} renderCurrentPage if false, an empty page will be rendered, - * otherwise calls to print() so far will be displayed. Either way, no more - * code will be executed. - */ -response.stop = function(renderCurrentPage) { - _cx().response().stop(); -}; - -/** - * Halts the program immediately and returns a 404 not found error to the user. - */ -response.notFound = function() { - _cx().response().error(404, "404: Not found"); -}; - -/** - * Halts the program immediately and sends an HTTP redirect response (302), - * redirecting to the given path (relative or absolute). - * - * @param {string} path The new path - */ -response.redirect = function(path) { - if ((! path) && path != "") { - throw new Error("Invalid redirect: "+path); - } - if (path.indexOf('/') == 0) { - // make sure absolute URL has proper host/port - path = request.scheme+"://"+request.host+path; - } - _cx().response().redirect(path); -}; - -/** - * Sets the status code in the HTTP response. - * - * @param {number} newCode - */ -response.setStatusCode = function(newCode) { - _cx().response().setStatusCode(newCode); -}; -response.getStatusCode = function() { - return _cx().response().getStatusCode(); -}; - -response.sendError = function(errorCode, errorHtml) { - _cx().response().error(errorCode, errorHtml); -}; - -response.reset = function() { - _cx().response().reset(); -}; - -/** - * Sets any header of the HTTP response. - * - * @example -response.setHeader('Cache-Control', 'no-cache'); - * - * @param {string} name - * @param {string} value - */ -response.setHeader = function(name, value) { - _cx().response().setHeader(name, value); -}; - -/** - * Adds the name,value pair to the headers. Useful for headers that are - * allowed to repeat, such as Set-Cookie. - * - * @param {string} name - * @param {string} value - */ -response.addHeader = function(name, value) { - _cx().response().addHeader(name, value); -}; - -/** - * Returns the value of a previously-set header. Useful in the - * postRequestHandler to see values of headers set during normal - * request processing. - * - * @param {string} name - * @return {array} An array of header values. Empty array if none set. - */ -response.getHeader = function(name) { - if (! this.isDefined) { - return []; - } else { - return _cx().response().getHeader(name); - } -}; - -/** - * Removes all instances of a header of the HTTP response. - * - * @param {string} name - */ -response.removeHeader = function(name) { - _cx().response().removeHeader(name); -}; - -/** - * Low-level hook for writing raw data to the response. - * @param {string} data will be written, verbatim, to the HTTP resonse. - */ -response.write = function(data) { - _cx().response().write(data); -}; - -/** - * Low-level hook for writing raw byte data to the response. Especially - * useful for writing the result of a <code>wget</code> of image data, - * or writing an uploaded file. - * @param {string} data will be written, verbatim, to the HTTP resonse. - */ -response.writeBytes = function(data) { - _cx().response().writeBytes(data); -}; - -//---------------------------------------------------------------- -// Cookies! -//---------------------------------------------------------------- - -/** - * Set a cookie in the response. - * - * @example -response.setCookie({ - name: "SessionID", - value: "25", - secure: true, - expires: 14 // 14 days -}); - * - * @param {object} cookieObject This may contain any of the following: -<ul> - <li>name (required): The name of the cookie</li> - <li>value (required): The value of the cookie. (Note: this value will be escaped). - <li>expires (optional): If an integer, means number of days until it expires; - if a Date object, means exact date on which to expire.</li> - <li>domain (optional): The cookie domain</li> - <li>path (optional): To restrict the cookie to a specific path.</li> - <li>secure (optional): Whether this cookie should only be sent securely.</li> -</ul> - */ -response.setCookie = function(cookieObject) { - this.addHeader('Set-Cookie', _cookiestring(cookieObject)); - - var p3pHeader = this.getHeader("P3P"); - if ((! p3pHeader) || p3pHeader.length == 0) { - // The existence of this "privacy policy" header allows cookies set on - // pages inside iframes to be accepted by IE. (This is some kind of - // default policy copied from an example online. -- dgreensp) - this.setHeader('P3P', 'CP="IDC DSP COR CURa ADMa OUR IND PHY ONL COM STA"'); - } -}; - -/** - * Tells the client to delete the cookie of the given name (by setting - * its expiration time to zero). - * @param {string} name The name of the cookie to delete. - */ -response.deleteCookie = function(name) { - this.setCookie({name: name, value: '', expires: 0}); -}; - -function _trim(s) { - return String((new java.lang.String(s)).trim()); -} - -response.getCookie = function(name) { - var cookieHeaders = this.getHeader('Set-Cookie'); - if (! cookieHeaders) { return; } - for (var i = 0; i < cookieHeaders.length; ++i) { - if (_trim(cookieHeaders[i].split("=")[0]) == name) - return _trim(cookieHeaders[i].split(";")[0].split("=")[1]); - } -}; - -/** - * Sets the Content-Type header of the response. If the content-type includes - * a charset, that charset is used to send the response. - * @param {string} contentType the new content-type - */ -response.setContentType = function(contentType) { - _cx().response().setContentType(contentType); -}; - -response.getCharacterEncoding = function() { - return _cx().response().getCharacterEncoding(); -} - -response.neverCache = function() { - // be aggressive about not letting the response be cached. - var that = this; - function sh(k,v) { that.setHeader(k,v); } - sh('Expires', 'Sat, 18 Jun 1983 07:07:07 GMT'); - sh('Last-Modified', (new Date()).toGMTString()); - sh('Cache-Control', ('no-store, no-cache, must-revalidate, '+ - 'post-check=0, pre-check=0')); - sh('Pragma', 'no-cache'); -}; - -response.alwaysCache = function() { - var that = this; - function sh(k,v) { that.setHeader(k,v); } - that.removeHeader('Last-Modified'); - that.removeHeader('Pragma'); - var futureDate = new Date(); - futureDate.setTime(Date.now() + 315360000000); - sh('Expires', futureDate.toGMTString()); - sh('Cache-Control', 'max-age=315360000'); -}; - -response.setGzip = function(gzip) { - _cx().response().setGzip(gzip); -} diff --git a/trunk/infrastructure/framework-src/modules/image.js b/trunk/infrastructure/framework-src/modules/image.js deleted file mode 100644 index 8aec74b..0000000 --- a/trunk/infrastructure/framework-src/modules/image.js +++ /dev/null @@ -1,110 +0,0 @@ -/** - * Copyright 2009 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS-IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import("blob"); - -jimport("java.awt.image.BufferedImage"); -jimport("org.apache.sanselan.Sanselan"); -jimport("org.apache.sanselan.ImageFormat"); - -if (java.lang.System.getProperty("java.awt.headless") == null) { - // If the system property isn't set either way, then default to "headless" mode, - // so that we don't start calling the window manager when the AWT classes - // are loaded. For example, on OS X the java process is given a Dock icon - // when we create our first BufferedImage. - java.lang.System.setProperty("java.awt.headless", "true"); -} - -/** - * Encodes the given pixel data into an image blob, ready to be served to - * the client. Pixels are specified as 32-bit ints in the format AARRGGBB, - * and the order is across rows first, then down columns. If useTransparency - * is true, then all pixels should have an alpha channel as their - * most-significant byte, with 0xff being fully opaque. If useTransparency - * is false, all pixels are fully opaque and the high byte is ignored. - * Supported formats: GIF. - * <p> - * For example, to create a GIF image consisting of a green pixel followed - * by a transparent pixel to the right of it, use: - * imageBlobFromPixels(2, 1, [0xff00ff00, 0x00000000], true, "gif") - */ - -function pixelsToImageBlob(width, height, pixelArrayARGB, useTransparency, format) { - var image = _makeBufferedImage(width, height); - var array = _makePixelArray(width, height); - var alphaMask = (useTransparency ? 0x00000000 : 0xff000000); - - for(var i=0; i<array.length; i++) { - // bitwise operations cause a JS number to become a signed 32-bit int - array[i] = (pixelArrayARGB[i] | alphaMask); - } - - _setImagePixels(image, array); - - if (format.toLowerCase() == "gif") { - return _bufferedImage2gifBlob(image); - } - return null; -} - -/** - * Creates a blob of image data in a format readable by a web browser - * that consists of a solid, opaque color and has the given width - * and height. The sixHexDigits must be a number, such as - * 0x12fda3, or a string, such as "12fda3". - */ -function solidColorImageBlob(width, height, sixHexDigits) { - var image = _makeBufferedImage(width, height); - var array = _makePixelArray(width, height); - - var pixel = 0xffffff; - if ((typeof sixHexDigits) == "number") { - pixel = sixHexDigits; - } - else if ((typeof sixHexDigits) == "string") { - pixel = Number("0x"+sixHexDigits); - } - - // bitwise operations cause a JS number to become a signed 32-bit int - pixel = ((pixel & 0xffffff) | 0xff000000); - - java.util.Arrays.fill(array, pixel); - _setImagePixels(image, array); - - return _bufferedImage2gifBlob(image); -} - -function _makeBufferedImage(width, height) { - return new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); -} - -function _makePixelArray(width, height) { - return java.lang.reflect.Array.newInstance(java.lang.Integer.TYPE, - width*height); -} - -function _setImagePixels(image, array) { - var width = image.getWidth(); - var height = image.getHeight(); - - image.setRGB(0, 0, width, height, array, 0, width); -} - -function _bufferedImage2gifBlob(image) { - // Use the Apache Sanselan image library because it nails transparent GIFs. - var bytes = Sanselan.writeImageToBytes(image, ImageFormat.IMAGE_FORMAT_GIF, null); - return blob.byteArrayToBlob("image/gif", bytes); -} diff --git a/trunk/infrastructure/framework-src/modules/jsutils.js b/trunk/infrastructure/framework-src/modules/jsutils.js deleted file mode 100644 index 02f81a2..0000000 --- a/trunk/infrastructure/framework-src/modules/jsutils.js +++ /dev/null @@ -1,195 +0,0 @@ -/** - * Copyright 2009 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS-IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileOverview A collection of core JavaScript utilities. - */ - -/** - * Iterator convenience for JavaScript Objects. - * - * Note that if func returns false, the iteration will be immediately terminated. - * (Returning undefined, or not specifying a return type, does not terminate the iteration). - * - * @example -var pastels = { - red: "#fcc", - green: "#cfc", - blue: "#ccf" -}; -eachProperty(pastels, function(key, value) { - print(DIV({style: 'background: '+value+';'}, key)); -}); - * - * @param {object} obj The object over which to iterate. - * @param {function} func The function to run on each [key,value] pair. - */ -function eachProperty(obj, func) { - var r; - for (k in obj) { - if (!obj.hasOwnProperty || obj.hasOwnProperty(k)) { - r = func(k,obj[k]); - if (r === false) { - break; - } - } - } -} - -/** - * Douglas Crockford's "object" function for prototypal inheritance, taken from - * http://javascript.crockford.com/prototypal.html - * - * @param {object} parent The parent object. - * @return {object} A new object whose prototype is parent. - */ -function object(parent) { - function f() {}; - f.prototype = parent; - return new f(); -} - -/** - * Creates an array of the properties of <code>obj</code>, - * <em>not</em> including built-in or inherited properties. If no - * argument is given, applies to the global object. - * - * @example -// Prints "abc" -keys({a: 1, b: 2, c: 3}).forEach(function(k) { - print(k); -} - * - * @example -// Prints all the functions and object members of the global "appjet" object, -// one per line. -print(keys(appjet).join('\n')); - * - * @param {object} obj - */ -function keys(obj) { - var array = []; - var o = obj; - if (o == undefined) { - o = this; - } - for(var k in o) { - if (!obj.hasOwnProperty || o.hasOwnProperty(k)) { - array.push(k); - } - } - return array; -} - -/** - * Comparator that returns -1, +1, or 0 depending on whether a < b, or a > b, or - * neither, respectively. - * @param {object} a - * @param {object} b - * @return {number} -1, 0, or +1 - */ -function cmp(a,b) { - if (a < b) { - return -1; - } - if (a > b) { - return 1; - } - return 0; -} - -function arrayToSet(arr) { - var set = {}; - arr.forEach(function(x) { - set[x] = true; - }); - return set; -} - -function mergeArrays(mergeFunction, a1, a2, etc) { - var len = a1.length; - var arrays = Array.prototype.slice.call(arguments, 1); - for (var i = 0; i < arrays.length; ++i) { - if (arrays[i].length != len) { - return; - } - } - out = []; - for (var i = 0; i < a1.length; ++i) { - out.push(mergeFunction.apply(this, arrays.map(function(array) { return array[i]; }))); - } - return out; -} - -function debug(obj) { - if (typeof(obj) == 'object') { - var ret = []; - if (obj) { - eachProperty(obj, function(k, v) { - ret.push(k+" -> "+debug(v)); - }); - return '['+ret.join(", ")+']'; - } else { - return String(obj); - } - } else { - return String(obj); - } -} - -/** - * Create a scala function out of the given JS function. - */ -function scalaFn(nargs, f) { - if (typeof(f) == 'function') { - return new Packages.scala['Function'+nargs]({ - apply: f - }); - } else { - return new Packages.scala['Function'+nargs]({ - apply: function() { return f; } - }) - } -} - -function scalaF0(f) { - return scalaFn(0, f); -} - -function scalaF1(f) { - return scalaFn(1, f); -} - -/** - * Some bonus functions for functional programming. - */ -function f_curry(thisPtr, f, arg1, arg2, etc) { - var curriedArgs = Array.prototype.slice.call(arguments, 2); - return function() { - var args = Array.prototype.slice.call(arguments, 0); - return f.apply(thisPtr, curriedArgs.concat(args)); - } -} - -function f_limitArgs(thisPtr, f, n) { - return function() { - var args = Array.prototype.slice.call(arguments, 0, n); - return f.apply(thisPtr, args); - } -} - - - diff --git a/trunk/infrastructure/framework-src/modules/netutils.js b/trunk/infrastructure/framework-src/modules/netutils.js deleted file mode 100644 index 6616b76..0000000 --- a/trunk/infrastructure/framework-src/modules/netutils.js +++ /dev/null @@ -1,88 +0,0 @@ -/** - * Copyright 2009 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS-IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileOverview A collection of network-related utilities. - */ - -import("jsutils.eachProperty"); - -jimport("java.net.InetAddress"); - - -function urlPost(url0, params, options) { - var url = new java.net.URL(url0); - - var data; - if (typeof(params) == 'string') { - data = params; - } else if (typeof(params) == 'object') { - var components = []; - eachProperty(params, function(k, v) { - components.push(encodeURIComponent(k)+"="+encodeURIComponent(v)); - }); - data = components.join('&'); - } - var dataBytes = (new java.lang.String(data)).getBytes("UTF-8"); - var conn = url.openConnection(); - conn.setInstanceFollowRedirects(true); - conn.setRequestMethod("POST"); - conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=utf-8"); - conn.setRequestProperty("Content-Length", dataBytes.length); - conn.setDoInput(true); - conn.setDoOutput(true); - conn.setConnectTimeout(30*1000); - conn.setReadTimeout(30*1000); - conn.getOutputStream().write(dataBytes); - var content = conn.getContent(); - var responseCode = conn.getResponseCode(); - var contentType = conn.getContentType(); - var contentEncoding = conn.getContentEncoding(); - - if ((content instanceof java.io.InputStream) && (new java.lang.String(contentType)).startsWith("text/")) { - if (! contentEncoding) { - var encoding = contentType.split(/;\s*/); - if (encoding.length > 1) { - encoding = encoding[1].split("="); - if (encoding[0] == "charset") - contentEncoding = encoding[1]; - } - } - content = net.appjet.common.util.BetterFile.getStreamBytes(content); - if (contentEncoding) { - content = (new java.lang.String(content, contentEncoding)); - } - } - - return { - content: content, - status: responseCode, - contentType: contentType, - contentEncoding: contentEncoding - }; -} - -function getHostnameFromIp(ip) { - var ret = null; - try { - var addr = InetAddress.getByName(ip); - ret = addr.getHostName(); - } catch (ex) { } - return ret; -} - - - diff --git a/trunk/infrastructure/framework-src/modules/profiler.js b/trunk/infrastructure/framework-src/modules/profiler.js deleted file mode 100644 index 223c197..0000000 --- a/trunk/infrastructure/framework-src/modules/profiler.js +++ /dev/null @@ -1,48 +0,0 @@ -/** - * Copyright 2009 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS-IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -/** - * @fileDescription - * Sosme profiling functions. - */ -var time = function() { - return Packages.net.appjet.oui.profiler.time(); -} - -var record = function(op, time) { - Packages.net.appjet.oui.profiler.record(op, time); -} - -var recordCumulative = function(op, time) { - Packages.net.appjet.oui.profiler.recordCumulative(op, time); -} - -var reset = function() { - Packages.net.appjet.oui.profiler.reset(); -} - -var print = function() { - Packages.net.appjet.oui.profiler.print(); -} - -var rcb = function(op, cumulative) { - var start = time(); - return function() { - var end = time(); - (cumulative ? recordCumulative : record)(op, end-start); - } -}
\ No newline at end of file diff --git a/trunk/infrastructure/framework-src/modules/sessions.js b/trunk/infrastructure/framework-src/modules/sessions.js deleted file mode 100644 index 3d0041b..0000000 --- a/trunk/infrastructure/framework-src/modules/sessions.js +++ /dev/null @@ -1,156 +0,0 @@ -/** - * Copyright 2009 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS-IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import("dateutils"); -import("fastJSON"); -import("fileutils"); -import("jsutils.{eachProperty,keys}"); -import("stringutils.{randomHash,startsWith,endsWith}"); -import("sync"); - -jimport("net.appjet.common.util.ExpiringMapping"); - -//---------------------------------------------------------------- - -var _DEFAULT_COOKIE_NAME = "SessionID"; -var _DEFAULT_SERVER_EXPIRATION = 3*24*60*60*1000; // 72 hours - -function getSessionId(cookieName, createIfNotPresent, domain) { - if (request.isComet || request.isCron) { - return null; - } - - if (request.cookies[cookieName]) { - return request.cookies[cookieName]; - } - - if (!createIfNotPresent) { - return null; - } - - // Keep sessionId in requestCache so this function can be called multiple - // times per request without multiple calls to setCookie(). - if (!appjet.requestCache.sessionId) { - var sessionId = randomHash(16); - - response.setCookie({ - name: cookieName, - value: sessionId, - path: "/", - domain: (domain || undefined) - }); - - appjet.requestCache.sessionId = sessionId; - } - - return appjet.requestCache.sessionId; -} - -function _getExpiringSessionMap(db) { - sync.callsyncIfTrue(db, - function() { return (!db.map); }, - function() { db.map = new ExpiringMapping(_DEFAULT_SERVER_EXPIRATION); }); - return db.map; -} - -function _getCachedDb() { - return appjet.cacheRoot("net.appjet.ajstdlib.session"); -} - -//---------------------------------------------------------------- - -function getSession(opts) { - // Session options. - if (!opts) { opts = {}; } - var cookieName = opts.cookieName || _DEFAULT_COOKIE_NAME; - - // get cookie ID (sets response cookie if necessary) - var sessionId = getSessionId(cookieName, true, opts.domain); - - // get expiring session map - var db = _getCachedDb(); - var map = _getExpiringSessionMap(db); - - // get session data object - var domainKey = (opts.domain ? opts.domain : ""); - var dataKey = [domainKey, sessionId].join('$'); - - var sessionData = map.get(dataKey); - if (!sessionData) { - sessionData = {}; - map.put(dataKey, sessionData); - } - else { - map.touch(dataKey); - } - - return sessionData; -} - -function writeSessionsToDisk() { - var dateString = dateutils.dateFormat(new Date(), "yyyy-MM-dd"); - var dataFile = new Packages.java.io.File(appjet.config.sessionStoreDir+"/sessions-"+dateString+".jslog"); - dataFile.getParentFile().mkdirs(); - var writer = new java.io.FileWriter(dataFile); - var map = _getCachedDb().map; - if (! map) { return; } - var keyIterator = map.listAllKeys().iterator(); - while (keyIterator.hasNext()) { - var key = keyIterator.next(); - var session = map.get(key); - if (keys(session).length == 0) { continue; } - var obj = { key: key, session: session }; - var json = fastJSON.stringify(obj); - writer.write(json); - writer.write("\n"); - } - writer.flush(); - writer.close(); -} - -function _extractDate(fname) { - var datePart = fname.substr("sessions-".length, "2009-09-24".length); - return Number(datePart.split("-").join("")); -} - -function readLatestSessionsFromDisk() { - var dir = new Packages.java.io.File(appjet.config.sessionStoreDir); - if (! dir.exists()) { return; } - var files = dir.listFiles(new Packages.java.io.FilenameFilter({ - accept: function(dir, name) { - return startsWith(name, "sessions") && endsWith(name, ".jslog") - } - })); - if (files.length == 0) { return; } - var latestFile = files[0]; - for (var i = 1; i < files.length; ++i) { - if (_extractDate(files[i].getName()) > _extractDate(latestFile.getName())) { - latestFile = files[i]; - } - } - var map = _getExpiringSessionMap(_getCachedDb()); - fileutils.eachFileLine(latestFile, function(json) { - try { - var obj = fastJSON.parse(json); - var key = obj.key; - var session = obj.session; - map.put(key, session); - } catch (err) { - Packages.java.lang.System.out.println("Error reading sessions file on line '"+json+"': "+String(err)); - } - }); - latestFile.renameTo(new Packages.java.io.File(latestFile.getParent()+"/used-"+latestFile.getName())); -} diff --git a/trunk/infrastructure/framework-src/modules/sqlbase/persistent_vars.js b/trunk/infrastructure/framework-src/modules/sqlbase/persistent_vars.js deleted file mode 100644 index 1c4cc95..0000000 --- a/trunk/infrastructure/framework-src/modules/sqlbase/persistent_vars.js +++ /dev/null @@ -1,57 +0,0 @@ -/** - * Copyright 2009 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS-IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -import("sqlbase.sqlobj"); -import("sqlbase.sqlcommon"); - -jimport("java.lang.System.out.println"); - -// TODO: add caching? - -// Curently supports: -// Strings - -function get(name) { - if (!sqlcommon.doesTableExist('persistent_vars')) { - return undefined; - } - var r = sqlobj.selectSingle('persistent_vars', {name: name}); - if (!r) { - return undefined; - } - return r.stringVal; -} - -function put(name, val) { - if (typeof(val) != 'string') { - throw Error("unsupported type for persistent_vars: "+typeof(val)); - } - - var r = sqlobj.selectSingle('persistent_vars', {name: name}); - if (r) { - sqlobj.updateSingle('persistent_vars', {id: r.id}, {stringVal: val}); - } else { - sqlobj.insert('persistent_vars', {name: name, stringVal: val}); - } -} - -function remove(name) { - var r = sqlobj.selectSingle('persistent_vars', {name: name}); - if (r) { - sqlobj.deleteRows('persistent_vars', {id: r.id}); - } -} diff --git a/trunk/infrastructure/framework-src/modules/sqlbase/sqlbase.js b/trunk/infrastructure/framework-src/modules/sqlbase/sqlbase.js deleted file mode 100644 index 3df1a0f..0000000 --- a/trunk/infrastructure/framework-src/modules/sqlbase/sqlbase.js +++ /dev/null @@ -1,205 +0,0 @@ -/** - * Copyright 2009 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS-IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import("jsutils.*"); -import("sqlbase.sqlcommon"); -import("fastJSON"); -import("timer"); - -jimport("java.lang.System.out.println"); - -function _sqlbase() { - return sqlcommon.getSqlBase(); -} - -/** - * Creates a SQL table suitable for storing a mapping from String to JSON value. - * Maximum key length is 128 characters. Has no effect if the table already exists. - */ -function createJSONTable(tableName) { - _sqlbase().createJSONTable(String(tableName)); -} - -/** - * Retrieves a JavaScript object or value from a table. Returns undefined - * if there is no mapping for the given string key. Requires that the table - * exist. - */ -function getJSON(tableName, stringKey) { - var result = _sqlbase().getJSON(String(tableName), String(stringKey)); - if (result) { - - return fastJSON.parse(String(result))['x']; - - /* performance-testing JSON - var obj1 = timer.time("JSON.parse (json2)", function() { - return JSON.parse(String(result))['x']; - }); - var obj2 = timer.time("JSON.parse (fastJSON)", function() { - return fastJSON.parse(String(result))['x']; - }); - return obj2; - */ - } - return undefined; -} - -function getAllJSON(tableName, start, count) { - var result = _sqlbase().getAllJSON(String(tableName), Number(start), Number(count)); - return Array.prototype.map.call(result, function(x) { - return {id: x.id(), value: fastJSON.parse(String(x.value()))['x']}; - }) -} - -function getAllJSONKeys(tableName) { - var result = _sqlbase().getAllJSONKeys(String(tableName)); - return Array.prototype.map.call(result, function(x) { return String(x); }); -} - -/** - * Assigns a JavaScript object or primitive value to a string key in a table. - * Maximum key length is 128 characters. Requires that the table exist. - */ -function putJSON(tableName, stringKey, objectOrValue) { - var obj = ({x:objectOrValue}); - - var json = fastJSON.stringify(obj); - - /* performance-testing JSON - - var json1 = timer.time("JSON.stringify (json2)", function() { - return JSON.stringify(obj); - }); - var json2 = timer.time("JSON.stringify (fastJSON)", function() { - return fastJSON.stringify(obj); - }); - - if (json1 != json2) { - println("json strings do not match!"); - println("\n\n"); - println(json1); - println("\n"); - println(json2); - println("\n\n"); - }*/ - - _sqlbase().putJSON(String(tableName), String(stringKey), json); -} - -/** - * Removes the mapping for a string key from a table. Requires that the table - * exist. - */ -function deleteJSON(tableName, stringKey) { - _sqlbase().deleteJSON(String(tableName), String(stringKey)); -} - -/** - * Creates a SQL table suitable for storing a mapping from (key,n) to string. - * The mapping may be sparse, but storage is most efficient when n are consecutive. - * The "length" of the array is not stored and must be externally maintained. - * Maximum key length is 128 characters. This call has no effect if the table - * already exists. - */ -function createStringArrayTable(tableName) { - _sqlbase().createStringArrayTable(String(tableName)); -} - -/** - * Assigns a string value to a (key,n) pair in a StringArray table. Maximum key length - * is 128 characters. Requires that the table exist. - */ -function putStringArrayElement(tableName, stringKey, n, value) { - _sqlbase().putStringArrayElement(String(tableName), String(stringKey), - Number(n), String(value)); -} - -/** - * Equivalent to a series of consecutive puts of the elements of valueArray, with the first - * one going to n=startN, the second to n=startN+1, and so on, but much more efficient. - */ -function putConsecutiveStringArrayElements(tableName, stringKey, startN, valueArray) { - var putter = _sqlbase().putMultipleStringArrayElements(String(tableName), String(stringKey)); - for(var i=0;i<valueArray.length;i++) { - putter.put(Number(startN)+i, String(valueArray[i])); - } - putter.finish(); -} - -/** - * Equivalent to a series of puts of the (key,value) entries of the JavaScript object - * nToValue, using as few database operations as possible. - */ -function putDictStringArrayElements(tableName, stringKey, nToValue) { - var nArray = []; - for(var n in nToValue) { - nArray.push(n); - } - nArray.sort(function(a,b) { return Number(a) - Number(b); }); - - var putter = _sqlbase().putMultipleStringArrayElements(String(tableName), String(stringKey)); - nArray.forEach(function(n) { - putter.put(Number(n), String(nToValue[n])); - }); - putter.finish(); -} - -/** - * Retrieves a string value from a StringArray table. Returns undefined - * if there is no mapping for the given (key,n) pair. Requires that the table - * exist. - */ -function getStringArrayElement(tableName, stringKey, n) { - var result = _sqlbase().getStringArrayElement(String(tableName), - String(stringKey), Number(n)); - if (result) { - return String(result); - } - return undefined; -} - -/** - * Retrieves all values from the database page that contains the mapping for n. - * Properties are added to destMap for n, if present in the database, and any other - * numeric entries in the same page. No return value. - */ -function getPageStringArrayElements(tableName, stringKey, n, destMap) { - var array = _sqlbase().getPageStringArrayElements(String(tableName), String(stringKey), n); - for(var i=0;i<array.length;i++) { - var entry = array[i]; - destMap[entry.index()] = String(entry.value()); - } -} - -/** - * Removes the mapping for a (key,n) pair from a StringArray table. Requires that the table - * exist. - */ -function deleteStringArrayElement(tableName, stringKey, n) { - _sqlbase().putStringArrayElement(String(tableName), String(stringKey), Number(n), null); -} - -/** - * Removes all mappings and metadata associated with a given key in a table. - */ -function clearStringArray(tableName, stringKey) { - _sqlbase().clearStringArray(String(tableName), stringKey); -} - -function getStringArrayAllKeys(tableName) { - var result = _sqlbase().getStringArrayAllKeys(String(tableName)); - return Array.prototype.map.call(result, function(x) { return String(x); }); -} diff --git a/trunk/infrastructure/framework-src/modules/sqlbase/sqlcommon.js b/trunk/infrastructure/framework-src/modules/sqlbase/sqlcommon.js deleted file mode 100644 index 360f5e2..0000000 --- a/trunk/infrastructure/framework-src/modules/sqlbase/sqlcommon.js +++ /dev/null @@ -1,99 +0,0 @@ -/** - * Copyright 2009 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS-IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import("jsutils.scalaF1") -import("stringutils.startsWith"); - -jimport("net.appjet.ajstdlib.SQLBase"); -jimport("java.lang.System.out.println"); - -function _sqlbase() { return appjet.cache.sqlbase }; - -function init(driver, url, username, password) { - var dbName = url.split(":")[1]; - println("Using "+dbName+" database type."); - - appjet.cache.sqlbase = new SQLBase(driver, url, username, password); - - // Test the connection - println("Establishing "+dbName+" connection (this may take a minute)..."); - try { - withConnection(function() { - return; - }); - } catch (ex) { - println("Error establishing "+dbName+" connection:"); - println(ex.toString().split('\n')[0]); - if (_sqlbase().isMysql()) { - println("Perhaps mysql server is not running, or you did not specify "+ - "proper database credentials with --etherpad.SQL_PASSWORD "+ - "and --etherpad.SQL_USERNAME?"); - } - if (_sqlbase().isDerby()) { - println("Perhaps database directory "+appjet.config.derbyHome+ - " is not writable?"); - } - println("Exiting..."); - Packages.java.lang.System.exit(1); - } - println(dbName+" connection established."); -} - -function onShutdown() { - _sqlbase().close(); -} - -function withConnection(f) { - return _sqlbase().withConnection(scalaF1(f)); -} - -function inTransaction(f) { - return _sqlbase().inTransaction(scalaF1(f)); -} - -function closing(s, f) { - if (s instanceof java.sql.Connection) { - throw new java.lang.IllegalArgumentException("Don't want to use 'closing()' on a sql connection!"); - } - try { - return f(); - } - finally { - s.close(); - } -} - -function doesTableExist(table) { - return withConnection(function(conn) { - return _sqlbase().doesTableExist(conn, table); - }); -} - -function autoIncrementClause() { - return _sqlbase().autoIncrementClause(); -} - -function createTableOptions() { - return _sqlbase().createTableOptions(); -} - -function btquote(x) { return _sqlbase().quoteIdentifier(x); } - -function getSqlBase() { return _sqlbase(); } - -function isMysql() { return _sqlbase().isMysql(); } -function isDerby() { return _sqlbase().isDerby(); } - diff --git a/trunk/infrastructure/framework-src/modules/sqlbase/sqlobj.js b/trunk/infrastructure/framework-src/modules/sqlbase/sqlobj.js deleted file mode 100644 index 4bc1263..0000000 --- a/trunk/infrastructure/framework-src/modules/sqlbase/sqlobj.js +++ /dev/null @@ -1,505 +0,0 @@ -/** - * Copyright 2009 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS-IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import("cache_utils.syncedWithCache"); -import("sqlbase.sqlcommon.*"); -import("jsutils.*"); - -jimport("java.lang.System.out.println"); -jimport("java.sql.Statement"); - -function _withCache(name, fn) { - return syncedWithCache('sqlobj.'+name, fn); -} - -function getIdColspec() { - return ('INT NOT NULL '+autoIncrementClause()+' PRIMARY KEY'); -} - -function getLongtextColspec(extra) { - var spec = getSqlBase().longTextType(); - if (extra) { - spec = (spec + " " + extra); - } - return spec; -} - -function getBoolColspec(extra) { - var spec; - if (isMysql()) { - spec = 'TINYINT(1)'; - } else { - spec = 'SMALLINT'; - } - if (extra) { - spec = (spec + " " + extra); - } - return spec; -} - -function getDateColspec(extra) { - var spec; - if (isMysql()) { - spec = 'DATETIME'; - } else { - spec = 'TIMESTAMP'; - } - if (extra) { - spec = (spec + " " + extra); - } - return spec; -} - -function _bq(x) { return btquote(x); } - -/* - * for debugging queries - */ -function _qdebug(q) { - if (appjet.config.debugSQL) { - println(q); - } -} - -/** executeFn is either "execute" or "executeUpdate" "executeQuery" */ -function _execute(stmnt, executeFn) { - if (!executeFn) { - executeFn = 'execute'; - } - return withConnection(function(conn) { - var pstmnt = conn.prepareStatement(stmnt); - return closing(pstmnt, function() { - _qdebug(stmnt); - return pstmnt[executeFn](); - }); - }); -} - -function _executeUpdate(stmnt) { - return _execute(stmnt, 'executeUpdate'); -} - -function _executeQuery(stmnt) { - return _execute(stmnt, 'executeQuery'); -} - -/* - * Not all SQL/JS types supported. - */ -function _getJsValFromResultSet(rs, type, colName) { - var r; - if (type == java.sql.Types.VARCHAR || - type == java.sql.Types.LONGVARCHAR || - type == java.sql.Types.CHAR) { - r = String(rs.getString(colName)); - } else if (type == java.sql.Types.TIMESTAMP) { - var t = rs.getTimestamp(colName); - if (t) { - r = new Date(t.getTime()); - } else { - r = null; - } - } else if (type == java.sql.Types.INTEGER || - type == java.sql.Types.SMALLINT || - type == java.sql.Types.TINYINT) { - r = rs.getInt(colName); - } else if (type == java.sql.Types.BIT) { - r = rs.getBoolean(colName); - } else { - throw Error("Cannot fetch sql type ID "+type+" (columnName = "+colName+")"); - } - - if (rs.wasNull()) { - r = null; - } - return r; -} - -function _lookupColumnType(tableName, columnName) { - return withConnection(function(conn) { - var metadata = conn.getMetaData(); - var rs = metadata.getColumns(null, null, tableName, columnName); - if (!rs) { - throw Error("Table '"+tableName+"' does not appear to have colum '"+columnName+"'."); - } - var rsmd = rs.getMetaData(); - var colCount = rsmd.getColumnCount(); -// rs.first(); - rs.next(); - var type = rs.getInt("DATA_TYPE"); - return type; - }); -} - -/* cached, on misses calls _lookuParameterType */ -function _getParameterType(tableName, columnName) { - var key = [tableName, columnName].join("."); - return _withCache('column-types', function(cache) { - if (!cache[key]) { - cache[key] = _lookupColumnType(tableName, columnName); - } - return cache[key]; - }); -} - -/* - * Not all SQL/JS types supported. - */ -function _setPreparedValues(tableName, pstmnt, keyList, obj, indexOffset) { - if (!indexOffset) { indexOffset = 0; } - - for (var i = 1; i <= keyList.length; i++) { - var k = keyList[i-1]; - var v = obj[k]; - var j = i + indexOffset; - - if (v === undefined) { - throw Error("value is undefined for key "+k); - } - - if (v === null) { - var type = _getParameterType(tableName, k); - pstmnt.setNull(j, type); - } else if (typeof(v) == 'string') { - pstmnt.setString(j, v); - } else if (typeof(v) == 'number') { - pstmnt.setInt(j, v); - } else if (typeof(v) == 'boolean') { - pstmnt.setBoolean(j, v); - } else if (v.valueOf && v.getDate && v.getHours) { - pstmnt.setTimestamp(j, new java.sql.Timestamp(+v)); - } else { - throw Error("Cannot insert this type of javascript object: "+typeof(v)+" (key="+k+", value = "+v+")"); - } - } -} - -function _resultRowToJsObj(resultSet) { - var resultObj = {}; - - var metaData = resultSet.getMetaData(); - var colCount = metaData.getColumnCount(); - for (var i = 1; i <= colCount; i++) { - var colName = metaData.getColumnName(i); - var type = metaData.getColumnType(i); - resultObj[colName] = _getJsValFromResultSet(resultSet, type, colName); - } - - return resultObj; -} - -/* - * Inserts the object into the given table, and returns auto-incremented ID if any. - */ -function insert(tableName, obj) { - var keyList = keys(obj); - - var stmnt = "INSERT INTO "+_bq(tableName)+" ("; - stmnt += keyList.map(function(k) { return _bq(k); }).join(', '); - stmnt += ") VALUES ("; - stmnt += keyList.map(function(k) { return '?'; }).join(', '); - stmnt += ")"; - - return withConnection(function(conn) { - var pstmnt = conn.prepareStatement(stmnt, Statement.RETURN_GENERATED_KEYS); - return closing(pstmnt, function() { - _setPreparedValues(tableName, pstmnt, keyList, obj, 0); - _qdebug(stmnt); - pstmnt.executeUpdate(); - var rs = pstmnt.getGeneratedKeys(); - if (rs != null) { - return closing(rs, function() { - if (rs.next()) { - return rs.getInt(1); - } - }); - } - }); - }); -}; - -/* - * Selects a single object given the constraintMap. If there are more - * than 1 objects that match, it will return a single one of them - * (unspecified which one). If no objects match, returns null. - * - * constraints is a javascript object of column names to values. - * Currently only supports string equality of constraints. - */ -function selectSingle(tableName, constraints) { - var keyList = keys(constraints); - - var stmnt = "SELECT * FROM "+_bq(tableName)+" WHERE ("; - stmnt += keyList.map(function(k) { return '('+_bq(k)+' = '+'?)'; }).join(' AND '); - stmnt += ')'; - if (isMysql()) { - stmnt += ' LIMIT 1'; - } - - return withConnection(function(conn) { - var pstmnt = conn.prepareStatement(stmnt); - return closing(pstmnt, function() { - _setPreparedValues(tableName, pstmnt, keyList, constraints, 0); - _qdebug(stmnt); - var resultSet = pstmnt.executeQuery(); - return closing(resultSet, function() { - if (!resultSet.next()) { - return null; - } - return _resultRowToJsObj(resultSet); - }); - }); - }); -} - -function _makeConstraintString(key, value) { - if (typeof(value) != 'object' || ! (value instanceof Array)) { - return '('+_bq(key)+' = ?)'; - } else { - var comparator = value[0]; - return '('+_bq(key)+' '+comparator+' ?)'; - } -} - -function _preparedValuesConstraints(constraints) { - var c = {}; - eachProperty(constraints, function(k, v) { - c[k] = (typeof(v) != 'object' || ! (v instanceof Array) ? v : v[1]); - }); - return c; -} - -function selectMulti(tableName, constraints, options) { - if (!options) { - options = {}; - } - - var constraintKeys = keys(constraints); - - var stmnt = "SELECT * FROM "+_bq(tableName)+" "; - - if (constraintKeys.length > 0) { - stmnt += "WHERE ("; - stmnt += constraintKeys.map(function(key) { - return _makeConstraintString(key, constraints[key]); - }).join(' AND '); - stmnt += ')'; - } - - if (options.orderBy) { - var orderEntries = []; - options.orderBy.split(",").forEach(function(orderBy) { - var asc = "ASC"; - if (orderBy.charAt(0) == '-') { - orderBy = orderBy.substr(1); - asc = "DESC"; - } - orderEntries.push(_bq(orderBy)+" "+asc); - }); - stmnt += " ORDER BY "+orderEntries.join(", "); - } - - if (options.limit) { - stmnt += " LIMIT "+options.limit; - } - - return withConnection(function(conn) { - var pstmnt = conn.prepareStatement(stmnt); - return closing(pstmnt, function() { - _setPreparedValues( - tableName, pstmnt, constraintKeys, - _preparedValuesConstraints(constraints), 0); - - _qdebug(stmnt); - var resultSet = pstmnt.executeQuery(); - var resultArray = []; - - return closing(resultSet, function() { - while (resultSet.next()) { - resultArray.push(_resultRowToJsObj(resultSet)); - } - - return resultArray; - }); - }); - }); -} - -/* returns number of rows updated */ -function update(tableName, constraints, obj) { - var objKeys = keys(obj); - var constraintKeys = keys(constraints); - - var stmnt = "UPDATE "+_bq(tableName)+" SET "; - stmnt += objKeys.map(function(k) { return ''+_bq(k)+' = ?'; }).join(', '); - stmnt += " WHERE ("; - stmnt += constraintKeys.map(function(k) { return '('+_bq(k)+' = ?)'; }).join(' AND '); - stmnt += ')'; - - return withConnection(function(conn) { - var pstmnt = conn.prepareStatement(stmnt); - return closing(pstmnt, function() { - _setPreparedValues(tableName, pstmnt, objKeys, obj, 0); - _setPreparedValues(tableName, pstmnt, constraintKeys, constraints, objKeys.length); - _qdebug(stmnt); - return pstmnt.executeUpdate(); - }); - }); -} - -function updateSingle(tableName, constraints, obj) { - var count = update(tableName, constraints, obj); - if (count != 1) { - throw Error("save count != 1. instead, count = "+count); - } -} - -function deleteRows(tableName, constraints) { - var constraintKeys = keys(constraints); - var stmnt = "DELETE FROM "+_bq(tableName)+" WHERE ("; - stmnt += constraintKeys.map(function(k) { return '('+_bq(k)+' = ?)'; }).join(' AND '); - stmnt += ')'; - withConnection(function(conn) { - var pstmnt = conn.prepareStatement(stmnt); - closing(pstmnt, function() { - _setPreparedValues(tableName, pstmnt, constraintKeys, constraints); - _qdebug(stmnt); - pstmnt.executeUpdate(); - }); - }) -} - -//---------------------------------------------------------------- -// table management -//---------------------------------------------------------------- - -/* - * Create a SQL table, specifying column names and types with a - * javascript object. - */ -function createTable(tableName, colspec, indices) { - if (doesTableExist(tableName)) { - return; - } - - var stmnt = "CREATE TABLE "+_bq(tableName)+ " ("; - stmnt += keys(colspec).map(function(k) { return (_bq(k) + ' ' + colspec[k]); }).join(', '); - if (indices) { - stmnt += ', ' + keys(indices).map(function(k) { return 'INDEX (' + _bq(k) + ')'; }).join(', '); - } - stmnt += ')'+createTableOptions(); - _execute(stmnt); -} - -function dropTable(tableName) { - _execute("DROP TABLE "+_bq(tableName)); -} - -function dropAndCreateTable(tableName, colspec, indices) { - if (doesTableExist(tableName)) { - dropTable(tableName); - } - - return createTable(tableName, colspec, indices); -} - -function renameTable(oldName, newName) { - _executeUpdate("RENAME TABLE "+_bq(oldName)+" TO "+_bq(newName)); -} - -function modifyColumn(tableName, columnName, newSpec) { - _executeUpdate("ALTER TABLE "+_bq(tableName)+" MODIFY "+_bq(columnName)+" "+newSpec); -} - -function alterColumn(tableName, columnName, alteration) { - var q = "ALTER TABLE "+_bq(tableName)+" ALTER COLUMN "+_bq(columnName)+" "+alteration; - _executeUpdate(q); -} - -function changeColumn(tableName, columnName, newSpec) { - var q = ("ALTER TABLE "+_bq(tableName)+" CHANGE COLUMN "+_bq(columnName) - +" "+newSpec); - _executeUpdate(q); -} - -function addColumns(tableName, colspec) { - inTransaction(function(conn) { - eachProperty(colspec, function(name, definition) { - var stmnt = "ALTER TABLE "+_bq(tableName)+" ADD COLUMN "+_bq(name)+" "+definition; - _executeUpdate(stmnt); - }); - }); -} - -function dropColumn(tableName, columnName) { - var stmnt = "ALTER TABLE "+_bq(tableName)+" DROP COLUMN "+_bq(columnName); - _executeUpdate(stmnt); -} - -function listTables() { - return withConnection(function(conn) { - var metadata = conn.getMetaData(); - var resultSet = metadata.getTables(null, null, null, null); - var resultArray = []; - - return closing(resultSet, function() { - while (resultSet.next()) { - resultArray.push(resultSet.getString("TABLE_NAME")); - } - return resultArray; - }); - }); -} - -function setTableEngine(tableName, engineName) { - var stmnt = "ALTER TABLE "+_bq(tableName)+" ENGINE="+_bq(engineName); - _executeUpdate(stmnt); -} - -function getTableEngine(tableName) { - if (!isMysql()) { - throw Error("getTableEngine() only supported by MySQL database type."); - } - - var tableEngines = {}; - - withConnection(function(conn) { - var stmnt = "show table status"; - var pstmnt = conn.prepareStatement(stmnt); - closing(pstmnt, function() { - _qdebug(stmnt); - var resultSet = pstmnt.executeQuery(); - closing(resultSet, function() { - while (resultSet.next()) { - var n = resultSet.getString("Name"); - var eng = resultSet.getString("Engine"); - tableEngines[n] = eng; - } - }); - }); - }); - - return tableEngines[tableName]; -} - -function createIndex(tableName, columns) { - var indexName = "idx_"+(columns.join("_")); - var stmnt = "CREATE INDEX "+_bq(indexName)+" on "+_bq(tableName)+" ("; - stmnt += columns.map(_bq).join(", "); - stmnt += ")"; - _executeUpdate(stmnt); -} - diff --git a/trunk/infrastructure/framework-src/modules/stringutils.js b/trunk/infrastructure/framework-src/modules/stringutils.js deleted file mode 100644 index 3fe5611..0000000 --- a/trunk/infrastructure/framework-src/modules/stringutils.js +++ /dev/null @@ -1,399 +0,0 @@ -/** - * Copyright 2009 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS-IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileOverview A collection of various string utilities. - */ - -// TODO: uncomment with import works with * - -import("funhtml.{TABLE,TR,TH,TD,OL,LI}"); -import("jsutils.{object,eachProperty}"); - -//import("funhtml.*"); - -jimport("java.util.Random"); -jimport("java.lang.System.currentTimeMillis"); - - -/** - * Removes leading and trailing whitespace from a string. - * @param {string} str - * @return {string} The trimmed string. - */ -function trim(str) { - return str.replace(/^\s+|\s+$/g, ""); -} - -//---------------------------------------------------------------- -// String prototype enhancements. -// TODO: should we move this to a new library "enhancedstring"? -//---------------------------------------------------------------- -startsWith = function(s, prefix) { - return (s.indexOf(prefix) == 0); -}; -endsWith = function(s, suffix) { - return (s.substr(s.length - suffix.length) == suffix); -}; -contains = function(s, x) { - return (s.indexOf(x) != -1); -}; -makeTitle = function(s) { - if (! s) return; - return s.split(" ").map(function(x) { - return x[0].toUpperCase() + x.substr(1) - }).join(" "); -} -repeat = function(s, n) { - var out = []; - while (n-- > 0) { - out.push(s); - } - return out.join(''); -} - -/* - * Helper function that converts a raw string to an HTML string, with - * character entities replaced by appropriate HTML codes, and newlines - * rentered as BRs. - * - * <p>A more general version of this function is toHTML(), which can operate - * on not just strings, but any object. - * - * @param {string} str the raw string - * @return {string} HTML-formatted string - */ -function _stringToHTML(str) { - return String(net.appjet.oui.Util.stringToHTML(str)); -} - -// used to convert an object to HTML when the object does not have a -// toHTML method. -// -function _coerceObjectToHTML(obj) { - var t = TABLE({border: 1, cellpadding: 2, cellspacing: 0}); - eachProperty(obj, function(name, value) { - t.push(TR(TH(String(name)), TD(String(value)))); - }); - return toHTML(t); -} - -// Converts an array to an HTML list by listing its properties and -// recursively converting the values to HTML by calling toHTML() on -// each of them. -function _objectToOL(obj) { - var l = OL(); - eachProperty(obj, function(name, value) { - l.push(LI({value: name}, value)); - }); - return l; -} - -function _sameProperties(obj1, obj2) { - if (typeof(obj1) != 'object' || typeof(obj2) != 'object') - return typeof(obj1) == typeof(obj2); - - var mismatch = 0; - eachProperty(obj1, function(name) { - if (! obj2.hasOwnProperty(name)) { - mismatch++; - }}); - eachProperty(obj2, function(name) { - if (! obj1.hasOwnProperty(name)) { - mismatch++; - }}); - return mismatch < 2; -} - -// -// for pretty-printing arrays. needs a lot of work. -// -function _arrayToHTML(a) { - if (a.length === 0) { - return ""; - } - if (typeof(a[0]) != 'object') { - return toHTML(_objectToOL(a)); - } else if (! _sameProperties(a[0], a[1])) { - return toHTML(_objectToOL(a)); - } else { - return _likeObjectsToHTML(function (f) { - a.forEach(function(value, i) { - f({index: i}, value, {}); - });}, null); - } -} - -/** @ignore */ - -// a foreaching function that takes three arguments: properties to put first, -// properties to put in the middle, and properties to put at the end. -// and a table header (with large colspan) -function _likeObjectsToHTML(forEachFunction, tophead) { - objs = []; - prepnames = new StringSet(); - objpnames = new StringSet(); - postpnames = new StringSet(); - rows = []; - - var t = TABLE({border: 1, cellpadding: 2, cellspacing: 0}); - var head = TR(); - if (tophead) - t.push(tophead); - t.push(head); - - var butWaitTheresMore = false; - var howManyMore = 0; - - forEachFunction(function(pre, o, post) { - if (objs.length >= 10) { - butWaitTheresMore = true; - howManyMore++; - return; - } - objs.push({pre: pre, o: o, post: post}); - var tr = TR(); - rows.push(tr); - t.push(tr); - - eachProperty(pre, function(name) { prepnames.add(name); }); - eachProperty(o, function(name) { objpnames.add(name); }); - eachProperty(post, function(name) { postpnames.add(name); }); - }); - var numpnames = 0; - var appendTDsForPropName = function (where) { - return function(name) { - numpnames++; - head.push(TH(name)); - for (var j = 0; j < objs.length; ++j) { - if (! (objs[j][where] === undefined) && ! (objs[j][where][name] === undefined)) - rows[j].push(TD(String(objs[j][where][name]))); - else - rows[j].push(TD()); - } - }; - }; - prepnames.forEach(appendTDsForPropName("pre")); - objpnames.forEach(appendTDsForPropName("o")); - postpnames.forEach(appendTDsForPropName("post")); - if (butWaitTheresMore) { - t.push(TR(TD({colspan: numpnames}, "..."+howManyMore+ - " additional element"+(howManyMore == 1 ? "" : "s")+" omitted..."))); - } - return toHTML(t); -} - -/** - * Returns a string with any number of variables substituted in, as - * popularized by C's function of the same name. Some common substitutions: - * - * <ul><li>%d - an integer</li><li>%f - a floating-point number</li><li>%b - a boolean</li> - * <li>%s - a string</li></ul> - * - * <p>Each time one of these "slot" appears in your format string, the next argument is displayed - * according to the type of slot you specified. - * - * <p>AppJet supports <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/Formatter.html"> - * Java's specification of printf</a>, which has a ton of features, including selecting - * arguments out of order, formatting dates and times, and specifying how many characters - * wide each slot should be. - * - * @example -var x = 5; -response.write(sprintf("an integer: %d", x)); -response.write(sprintf("Two strings: [%s] and [%s].", "string one", "string two")); - * - * @param {string} formatString - * @param {*} arg1 - * @param {*} arg2 - * @param {*} arg3 ... - */ -function sprintf(formatString, arg1, arg2, etc) { - if (typeof(formatString) != 'string') { - throw new Error('printf takes a string as the first argument.'); - } - var argList = java.lang.reflect.Array.newInstance(java.lang.Object, arguments.length-1); - for (var i = 1; i < arguments.length; i++) { - if (arguments[i] instanceof Date) - argList[i-1] = arguments[i].getTime(); - else - argList[i-1] = arguments[i]; - } - return String(net.appjet.ajstdlib.printf.printf(formatString, argList)); -}; - -/** - * Replaces keys of data found in string with their corresponding values. - * - * <p>(Inspired by http://javascript.crockford.com/remedial.html) - * - * @example -var data = {name: "Aaron", age: 25, today: new Date()}; -print(supplant(data, """ - -{name}'s age is {age} years, as of {today}. - -""")); - - * @param {object} data dictionary of values - * @param {string} str - * @return {string} str with keys of data replaced by their values - */ -function supplant(data, str) { - var s = str; - var o = data; - function rep(a, b) { - var r = o[b]; - if (typeof(r) != 'undefined') { - return r; - } else { - return a; - } - } - return s.replace(/{([^{}]*)}/g, rep); -}; - -//---------------------------------------------------------------- -// raw printing -//---------------------------------------------------------------- -var _raw_prototype; - -/** - * Used for printing un-escaped HTML, such as your own HTML tags. - * - * <p>Normally, printing a string will cause it to be translated - * so that it appears the same on the screen as it did in your code. - * If you're writing your own HTML, you don't want it to be processed - * this way. Wrapping a string in html(...) by-passes normal printing behavior, - * so that print(html(" -- html goes here ---")) will write the HTML - * directly to the page. - * - * <p>If you want to mix your own HTML code with HTML code generated from a - * tag object, you can get the HTML for the tag by calling its toHTML(...) method. - * - * <p>Multiple arguments to html(...) will be concatenated into one string. - * - * @example -print(html(""" -<br /> -<br /> -<div><p>Here is some text inside a P inside a DIV.</p> -</div> -<br /> -""")); - * - * @param {string} text the raw text - * @return {object} an object which, when printed, prints the raw html text - */ -function html(text) { - if (!_raw_prototype) { - _raw_prototype = object(Object.prototype); - _raw_prototype.toString = function() { return this._text; }; - _raw_prototype.toHTML = function() { return this._text; }; - } - var rawObj = object(_raw_prototype); - rawObj._text = Array.prototype.map.call(arguments, String).join(''); - return rawObj; -} - -/** - * This function is used by print(...) to convert a string or object - * into nice-looking printable HTML. It may be useful in conjunction - * with html(...) if you wish to work directly with HTML. - * - * <p>You can control how toHTML(...) (and therefore print(...)) behave on an object - * by giving that object a .toHTML() function. - * - * @param {*} x any javascript variable - * @return {string} html-formatted string - */ -function toHTML(x) { - if (typeof(x) == 'undefined') { - return 'undefined'; - } - if (x === null) { - return 'null'; - } - if (typeof x == "string" || (x instanceof java.lang.String)) { - return _stringToHTML(x); - } - if (typeof(x.toHTML) == "function") { - return x.toHTML(); - } - if (typeof(x) == "xml") { - return _stringToHTML(x.toSource()); - } - if (x instanceof Array) { - return _arrayToHTML(x); - } - if (x instanceof Date) { - var pieces = x.toString().split(" "); - return pieces.slice(0, 5).join(' ') + ' ' + pieces[6]; - } - if (typeof(x) == "object") { - return _coerceObjectToHTML(x); - } - // TODO: add more types to auto-printing, such as functions, - // numbers, what else? - return _stringToHTML(""+x); -} - - -/** - * Generates a random string of specified length using upper-case letters, lower-case letters, and numbers. - */ - -var _jrand = new Random(currentTimeMillis()); - -function randomString(nchars) { - var result = ''; - - // 48-58 or 65-91 or 97-123 (inclusive-exclusive) - // 0-10 or 0-26 or 0-26 - // 0-62 - - for (var i = 0; i < nchars; i++) { - var x = _jrand.nextInt(62); - var code; - if (x < 10) { code = x + 48; } - if (x >= 10 && x < 36) { code = x - 10 + 65/*a*/; } - if (x >= 36) { code = x - 36 + 97/*A*/; } - result += String.fromCharCode(code); - } - return result; -} - -function md5(x) { - return net.appjet.ajstdlib.md5.md5(x); -} - -function randomHash(len) { - var x = md5(""+_jrand.nextDouble()*1e12+_jrand.nextDouble()*1e12); - if (len) { - return String(x).substr(0,len); - } else { - return x; - } -} - -function gzip(x) { - return net.appjet.oui.Util.gzip(x) -} - -function isNumeric(x) { - return !!(/^\d+$/.test(x)); -} - diff --git a/trunk/infrastructure/framework-src/modules/sync.js b/trunk/infrastructure/framework-src/modules/sync.js deleted file mode 100644 index a222ea0..0000000 --- a/trunk/infrastructure/framework-src/modules/sync.js +++ /dev/null @@ -1,81 +0,0 @@ -/** - * Copyright 2009 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS-IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -jimport("java.util.concurrent.locks.ReentrantLock"); -jimport("net.appjet.oui.GlobalSynchronizer"); - -/** - * synchronously calls a no-argument function. - * f may have return values. - */ -function callsync(obj, f) { - if (!obj._LOCK) { - try { - appjet.globalLock.lock(); - if (! obj._LOCK) { - obj._LOCK = new ReentrantLock(); - } - } finally { - appjet.globalLock.unlock(); - } - } - try { - obj._LOCK.lock(); - return f(); - } finally { - obj._LOCK.unlock(); - } -} - -/** - * synchronously calls a no-argument function iff - * condition() is true. condition may be called - * twice and shouldn't have side-effects. - */ -function callsyncIfTrue(obj, condition, f) { - if (condition()) { - callsync(obj, function() { - if (condition()) { - f(); - } - }); - } -} - -/** - * returns a function that synchronously calls - * f with its own arguments - */ -function wrapsync(obj, f, thisArg) { - return function() { - var args = Array.prototype.slice.call(arguments); - var wrapper = function() { - return f.apply(thisArg, args); - } - callsync(obj, wrapper); - } -} - -function doWithStringLock(lockName, fn) { - GlobalSynchronizer.acquire(lockName); - try { - return fn(); - } - finally { - GlobalSynchronizer.release(lockName); - } -} - diff --git a/trunk/infrastructure/framework-src/modules/timer.js b/trunk/infrastructure/framework-src/modules/timer.js deleted file mode 100644 index 01be175..0000000 --- a/trunk/infrastructure/framework-src/modules/timer.js +++ /dev/null @@ -1,29 +0,0 @@ -/** - * Copyright 2009 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS-IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import("jsutils.*"); - -jimport("net.appjet.ajstdlib.timer"); - -function time(name, f) { - var t = timer.start(name); - try { - return f(); - } finally { - t.done(); - } -} - diff --git a/trunk/infrastructure/framework-src/modules/varz.js b/trunk/infrastructure/framework-src/modules/varz.js deleted file mode 100644 index 0e55d20..0000000 --- a/trunk/infrastructure/framework-src/modules/varz.js +++ /dev/null @@ -1,52 +0,0 @@ -/** - * Copyright 2009 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS-IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -jimport("java.util.concurrent.atomic.AtomicInteger"); - -import("sync"); - -function varz() { - sync.callsyncIfTrue(appjet.cache, - function() { return ! appjet.cache.varz; }, - function() { appjet.cache.varz = {}; }); - return appjet.cache.varz; -} - -function _getInteger(name) { - sync.callsyncIfTrue(varz(), - function() { return ! varz()[name] }, - function() { varz()[name] = new AtomicInteger(0) }); - return varz()[name]; -} - -function incrementInt(name) { - _getInteger(name).getAndIncrement(); -} - -function addToInt(name, count) { - _getInteger(name).getAndAdd(count); -} - -function getSnapshot() { - var ret = {}; - for (var k in varz()) { - if (k[0] == '_') { - continue; - } - ret[k] = varz()[k].toString(); - } - return ret; -} diff --git a/trunk/infrastructure/framework-src/modules/yuicompressor.js b/trunk/infrastructure/framework-src/modules/yuicompressor.js deleted file mode 100644 index 572cc0d..0000000 --- a/trunk/infrastructure/framework-src/modules/yuicompressor.js +++ /dev/null @@ -1,85 +0,0 @@ -/** - * Copyright 2009 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS-IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -jimport("java.lang.System.err") -jimport("yuicompressor.org.mozilla.javascript.ErrorReporter"); -jimport("com.yahoo.platform.yui.compressor.JavaScriptCompressor") -jimport("com.yahoo.platform.yui.compressor.CssCompressor") -jimport("java.io.StringReader"); -jimport("java.io.StringWriter"); - -/** - * Compresses the given JavaScript code into an equivalent, shorter string of code using - * YUICompressor. In addition to removing white-space and comments, YUICompressor - * does a full semantic parse of the code and renames non-global variables to have - * very short names. Scopes that are visible to "eval" and "with" are excluded from - * variable renaming, making the operation very safe. - * <p> - * For example, - * yuicompressor.compressJS("function foo() { var longVariableName = 3; return longVariableName }"); - * produces - * "function foo(){var A=3;return A;}" - */ - -function compressJS(code) { - function getComplaint(message, sourceName, line, lineSource, lineOffset) { - if (line < 0) return message; - else return (line+":"+lineOffset+":"+message); - } - function complaintHandler(func) { - return function(message, sourceName, line, lineSource, lineOffset) { - return func(getComplaint(message, sourceName, line, lineSource, lineOffset)); - } - } - var myErrorReporter = new JavaAdapter(ErrorReporter, { - warning: complaintHandler(function (msg) { - if (msg.indexOf("Try to use a single 'var' statement per scope.") >= 0) - return; - err.println("yuicompressor.compressJS warning: "+msg); - }), - error: complaintHandler(function (msg) { - throw new Error("yuicompressor.compressJS error: "+msg); - }), - runtimeError: complaintHandler(function (msg) { - throw new Error("yuicompressor.compressJS error: "+msg); - }) - }); - - var munge = true; - var verbose = false; - var optimize = true; - var wrapPos = 100; // characters, no wrap == -1 - var compressor = new JavaScriptCompressor(new StringReader(code), myErrorReporter); - var writer = new StringWriter(); - compressor.compress(writer, 100, munge, verbose, true, !optimize); - return String(writer.toString()); -} - -/** - * Compresses the given CSS code into an equivalent, shorter string of code using - * YUICompressor. Besides removing unnecessary white-space and comments, the operation - * performs an assortment of semantics-preserving optimizations. The operation attempts - * to preserve common "hacks" that take advantage of browser differences in parsing. - */ - -function compressCSS(code) { - var compressor = new CssCompressor(new StringReader(code)); - var wrapPos = 100; // characters, no wrap == -1 - var writer = new StringWriter(); - compressor.compress(writer, wrapPos); - return String(writer.toString()); -} |