You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@struts.apache.org by mu...@apache.org on 2007/03/03 06:49:21 UTC

svn commit: r514083 [25/49] - in /struts/struts2/trunk/plugins/dojo: ./ src/ src/main/ src/main/java/ src/main/java/org/ src/main/java/org/apache/ src/main/java/org/apache/struts2/ src/main/java/org/apache/struts2/components/ src/main/java/org/apache/s...

Added: struts/struts2/trunk/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/src/loader_xd.js
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/src/loader_xd.js?view=auto&rev=514083
==============================================================================
--- struts/struts2/trunk/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/src/loader_xd.js (added)
+++ struts/struts2/trunk/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/src/loader_xd.js Fri Mar  2 21:48:54 2007
@@ -0,0 +1,437 @@
+/*
+	Copyright (c) 2004-2006, The Dojo Foundation
+	All Rights Reserved.
+
+	Licensed under the Academic Free License version 2.1 or above OR the
+	modified BSD license. For more information on Dojo licensing, see:
+
+		http://dojotoolkit.org/community/licensing.shtml
+*/
+
+//Cross-domain package loader.
+
+//FIXME: How will xd loading work with debugAtAllCosts? Any bad interactions?
+//FIXME: widgets won't work fully (HTML/CSS) and also because of the requireIf() thing.
+
+dojo.hostenv.resetXd = function(){
+	//This flag indicates where or not we have crossed into xdomain territory. Once any package says
+	//it is cross domain, then the rest of the packages have to be treated as xdomain because we need
+	//to evaluate packages in order. If there is a xdomain package followed by a xhr package, we can't load
+	//the xhr package until the one before it finishes loading. The text of the xhr package will be converted
+	//to match the format for a xd package and put in the xd load queue.
+	//You can force all packages to be treated as xd by setting the djConfig.forceXDomain.
+	this.isXDomain = djConfig.forceXDomain || false;
+
+	this.xdTimer = 0;
+	this.xdInFlight = {};
+	this.xdOrderedReqs = [];
+	this.xdDepMap = {};
+	this.xdContents = [];
+}
+
+//Call reset immediately to set the state.
+dojo.hostenv.resetXd();
+
+dojo.hostenv.createXdPackage = function(contents){
+	//Find dependencies.
+	var deps = [];
+    var depRegExp = /dojo.(require|requireIf|requireAll|provide|requireAfterIf|requireAfter|kwCompoundRequire|conditionalRequire|hostenv\.conditionalLoadModule|.hostenv\.loadModule|hostenv\.moduleLoaded)\(([\w\W]*?)\)/mg;
+    var match;
+	while((match = depRegExp.exec(contents)) != null){
+		deps.push("\"" + match[1] + "\", " + match[2]);
+	}
+
+	//Create package object and the call to packageLoaded.
+	var output = [];
+	output.push("dojo.hostenv.packageLoaded({\n");
+
+	//Add dependencies
+	if(deps.length > 0){
+		output.push("depends: [");
+		for(var i = 0; i < deps.length; i++){
+			if(i > 0){
+				output.push(",\n");
+			}
+			output.push("[" + deps[i] + "]");
+		}
+		output.push("],");
+	}
+
+	//Add the contents of the file inside a function.
+	//Pass in dojo as an argument to the function to help with
+	//allowing multiple versions of dojo in a page.
+	output.push("\ndefinePackage: function(dojo){");
+	output.push(contents);
+	output.push("\n}});");
+	
+	return output.join("");
+}
+
+dojo.hostenv.loadPath = function(relpath, module /*optional*/, cb /*optional*/){
+	//Only do getBaseScriptUri if path does not start with a URL with a protocol.
+	//If there is a colon before the first / then, we have a URL with a protocol.
+	var colonIndex = relpath.indexOf(":");
+	var slashIndex = relpath.indexOf("/");
+	var uri;
+	var currentIsXDomain = false;
+	if(colonIndex > 0 && colonIndex < slashIndex){
+		uri = relpath;
+		this.isXDomain = currentIsXDomain = true;
+	}else{
+		uri = this.getBaseScriptUri() + relpath;
+
+		//Is ithe base script URI-based URL a cross domain URL?
+		colonIndex = uri.indexOf(":");
+		slashIndex = uri.indexOf("/");
+		if(colonIndex > 0 && colonIndex < slashIndex && (!location.host || uri.indexOf("http://" + location.host) != 0)){
+			this.isXDomain = currentIsXDomain = true;
+		}
+	}
+
+	if(djConfig.cacheBust && dojo.render.html.capable) { uri += "?" + String(djConfig.cacheBust).replace(/\W+/g,""); }
+	try{
+		return ((!module || this.isXDomain) ? this.loadUri(uri, cb, currentIsXDomain, module) : this.loadUriAndCheck(uri, module, cb));
+	}catch(e){
+		dojo.debug(e);
+		return false;
+	}
+}
+
+//Overriding loadUri for now. Wanted to override getText(), but it is used by
+//the widget code in too many, synchronous ways right now. This means the xd stuff
+//is not suitable for widgets yet.
+dojo.hostenv.loadUri = function(uri, cb, currentIsXDomain, module){
+	if(this.loadedUris[uri]){
+		return 1;
+	}
+
+	//Add the module (package) to the list of modules.
+	if(this.isXDomain){
+		//Curious: is this array going to get whacked with multiple access since scripts
+		//load asynchronously and may be accessing the array at the same time?
+		//JS is single-threaded supposedly, so it should be ok. And we don't need
+		//a precise ordering.
+		this.xdOrderedReqs.push(module);
+
+		//Add to waiting packages.
+		//If this is a __package__.js file, then this must be
+		//a package.* request (since xdomain can only work with the first
+		//path in a package search list. However, .* module names are not
+		//passed to this function, so do an adjustment here.
+		if(uri.indexOf("__package__") != -1){
+			module += ".*";
+		}
+
+		this.xdInFlight[module] = true;
+
+		//Increment inFlightCount
+		//This will stop the modulesLoaded from firing all the way.
+		this.inFlightCount++;
+				
+		//Start timer
+		if(!this.xdTimer){
+			this.xdTimer = setInterval("dojo.hostenv.watchInFlightXDomain();", 100);
+		}
+		this.xdStartTime = (new Date()).getTime();
+	}
+
+	if (currentIsXDomain){
+		//Fix name to be a .xd.fileextension name.
+		var lastIndex = uri.lastIndexOf('.');
+		if(lastIndex <= 0){
+			lastIndex = uri.length - 1;
+		}
+
+		var xdUri = uri.substring(0, lastIndex) + ".xd";
+		if(lastIndex != uri.length - 1){
+			xdUri += uri.substring(lastIndex, uri.length);
+		}
+
+		//Add to script src
+		var element = document.createElement("script");
+		element.type = "text/javascript";
+		element.src = xdUri;
+		if(!this.headElement){
+			this.headElement = document.getElementsByTagName("head")[0];
+		}
+		this.headElement.appendChild(element);
+	}else{
+		var contents = this.getText(uri, null, true);
+		if(contents == null){ return 0; }
+		
+		if(this.isXDomain){
+			var pkg = this.createXdPackage(contents);
+			dj_eval(pkg);
+		}else{
+			if(cb){ contents = '('+contents+')'; }
+			var value = dj_eval(contents);
+			if(cb){
+				cb(value);
+			}
+		}
+	}
+
+	//These steps are done in the non-xd loader version of this function.
+	//Maintain these steps to fit in with the existing system.
+	this.loadedUris[uri] = true;
+	return 1;
+}
+
+dojo.hostenv.packageLoaded = function(pkg){
+	var deps = pkg.depends;
+	var requireList = null;
+	var requireAfterList = null;
+	var provideList = [];
+	if(deps && deps.length > 0){
+		var dep = null;
+		var insertHint = 0;
+		var attachedPackage = false;
+		for(var i = 0; i < deps.length; i++){
+			dep = deps[i];
+
+			//Look for specific dependency indicators.
+			if (dep[0] == "provide" || dep[0] == "hostenv.moduleLoaded"){
+				provideList.push(dep[1]);
+			}else{
+				if(!requireList){
+					requireList = [];
+				}
+				if(!requireAfterList){
+					requireAfterList = [];
+				}
+
+				var unpackedDeps = this.unpackXdDependency(dep);
+				if(unpackedDeps.requires){
+					requireList = requireList.concat(unpackedDeps.requires);
+				}
+				if(unpackedDeps.requiresAfter){
+					requireAfterList = requireAfterList.concat(unpackedDeps.requiresAfter);
+				}
+			}
+
+			//Call the dependency indicator to allow for the normal dojo setup.
+			//Only allow for one dot reference, for the hostenv.* type calls.
+			var depType = dep[0];
+			var objPath = depType.split(".");
+			if(objPath.length == 2){
+				dojo[objPath[0]][objPath[1]].apply(dojo[objPath[0]], dep.slice(1));
+			}else{
+				dojo[depType].apply(dojo, dep.slice(1));
+			}
+		}
+
+		//Save off the package contents for definition later.
+		var contentIndex = this.xdContents.push({content: pkg.definePackage, isDefined: false}) - 1;
+
+		//Add provide/requires to dependency map.
+		for(var i = 0; i < provideList.length; i++){
+			this.xdDepMap[provideList[i]] = { requires: requireList, requiresAfter: requireAfterList, contentIndex: contentIndex };
+		}
+
+		//Now update the inflight status for any provided packages in this loaded package.
+		//Do this at the very end (in a *separate* for loop) to avoid shutting down the 
+		//inflight timer check too soon.
+		for(var i = 0; i < provideList.length; i++){
+			this.xdInFlight[provideList[i]] = false;
+		}
+	}
+}
+
+//This is a bit brittle: it has to know about the dojo methods that deal with dependencies
+//It would be ideal to intercept the actual methods and do something fancy at that point,
+//but I have concern about knowing which provide to match to the dependency in that case,
+//since scripts can load whenever they want, and trigger new calls to dojo.hostenv.packageLoaded().
+dojo.hostenv.unpackXdDependency = function(dep){
+	//Extract the dependency(ies).
+	var newDeps = null;
+	var newAfterDeps = null;
+	switch(dep[0]){
+		case "requireIf":
+		case "requireAfterIf":
+		case "conditionalRequire":
+			//First arg (dep[1]) is the test. Depedency is dep[2].
+			if((dep[1] === true)||(dep[1]=="common")||(dep[1] && dojo.render[dep[1]].capable)){
+				newDeps = [{name: dep[2], content: null}];
+			}
+			break;
+		case "requireAll":
+			//the arguments are an array, each element a call to require.
+			//Get rid of first item, which is "requireAll".
+			dep.shift();
+			newDeps = dep;
+			dojo.hostenv.flattenRequireArray(newDeps);
+			break;
+		case "kwCompoundRequire":
+		case "hostenv.conditionalLoadModule":
+			var modMap = dep[1];
+			var common = modMap["common"]||[];
+			var newDeps = (modMap[dojo.hostenv.name_]) ? common.concat(modMap[dojo.hostenv.name_]||[]) : common.concat(modMap["default"]||[]);	
+			dojo.hostenv.flattenRequireArray(newDeps);
+			break;
+		case "require":
+		case "requireAfter":
+		case "hostenv.loadModule":
+			//Just worry about dep[1]
+			newDeps = [{name: dep[1], content: null}];
+			break;
+	}
+
+	//The requireAfterIf or requireAfter needs to be evaluated after the current package is evaluated.
+	if(dep[0] == "requireAfterIf"){
+		newAfterDeps = newDeps;
+		newDeps = null;
+	}
+	return {requires: newDeps, requiresAfter: newAfterDeps};
+}
+
+//Walks the requires and evaluates package contents in
+//the right order.
+dojo.hostenv.xdWalkReqs = function(){
+	var reqChain = null;
+	var req;
+	for(var i = 0; i < this.xdOrderedReqs.length; i++){
+		req = this.xdOrderedReqs[i];
+		if(this.xdDepMap[req]){
+			reqChain = [req];
+			reqChain[req] = true; //Allow for fast lookup of the req in the array
+			this.xdEvalReqs(reqChain);
+		}
+	}
+}
+
+//Trace down any requires.
+dojo.hostenv.xdTraceReqs = function(reqs, reqChain){
+	if(reqs && reqs.length > 0){
+		var nextReq;
+		for(var i = 0; i < reqs.length; i++){
+			nextReq = reqs[i].name;
+			if(nextReq && !reqChain[nextReq]){
+				//New req depedency. Follow it down.
+				reqChain.push(nextReq);
+				reqChain[nextReq] = true;
+				this.xdEvalReqs(reqChain);
+			}
+		}
+	}
+}
+
+//Do a depth first, breadth second search and eval or reqs.
+dojo.hostenv.xdEvalReqs = function(reqChain){
+	if(reqChain.length > 0){
+		var req = reqChain[reqChain.length - 1];
+		var pkg = this.xdDepMap[req];
+		if(pkg){
+			//Trace down any requires for this package.
+			this.xdTraceReqs(pkg.requires, reqChain);
+
+			//Evaluate the package.
+			var contents = this.xdContents[pkg.contentIndex];
+			if(!contents.isDefined){
+				//Evaluate the package to bring it into being.
+				//Pass dojo in so that later, to support multiple versions of dojo
+				//in a page, we can pass which version of dojo to use.
+				contents.content(dojo);
+				contents.isDefined = true;
+			}
+			this.xdDepMap[req] = null;
+
+			//Trace down any requireAfters for this package..
+			this.xdTraceReqs(pkg.requiresAfter, reqChain);
+		}
+
+		//Done with that require. Remove it and go to the next one.
+		reqChain.pop();
+		this.xdEvalReqs(reqChain);
+	}
+}
+
+dojo.hostenv.clearXdInterval = function(){
+	clearInterval(this.xdTimer);
+	this.xdTimer = 0;
+}
+
+dojo.hostenv.watchInFlightXDomain = function(){
+	//Make sure we haven't waited timed out.
+	var waitInterval = (djConfig.xdWaitSeconds || 30) * 1000;
+
+	if(this.xdStartTime + waitInterval < (new Date()).getTime()){
+		this.clearXdInterval();
+		var noLoads = "";
+		for(var param in this.xdInFlight){
+			if(this.xdInFlight[param]){
+				noLoads += param + " ";
+			}
+		}
+		dojo.raise("Could not load cross-domain packages: " + noLoads);
+	}
+
+	//If any are true, then still waiting.
+	//Come back later.	
+	for(var param in this.xdInFlight){
+		if(this.xdInFlight[param]){
+			return;
+		}
+	}
+
+	//All done loading. Clean up and notify that we are loaded.
+	this.clearXdInterval();
+
+	this.xdWalkReqs();
+
+	//Evaluate any packages that were not evaled before.
+	//This normally shouldn't happen with proper dojo.provide and dojo.require
+	//usage, but providing it just in case. Note that these may not be executed
+	//in the original order that the developer intended.
+	//Pass dojo in so that later, to support multiple versions of dojo
+	//in a page, we can pass which version of dojo to use.
+	for(var i = 0; i < this.xdContents.length; i++){
+		var current = this.xdContents[i];
+		if(current.content && !current.isDefined){
+			current.content(dojo);
+		}
+	}
+
+	//Clean up for the next round of xd loading.
+	this.resetXd();
+
+	//Clear inflight count so we will finally do finish work.
+	this.inFlightCount = 0; 
+	this.callLoaded();
+}
+
+dojo.hostenv.flattenRequireArray = function(target){
+	//Each result could be an array of 3 elements  (the 3 arguments to dojo.require).
+	//We only need the first one.
+	if(target){
+		for(var i = 0; i < target.length; i++){
+			if(target[i] instanceof Array){
+				target[i] = {name: target[i][0], content: null};
+			}else{
+				target[i] = {name: target[i], content: null};
+			}
+		}
+	}
+}
+
+//Need to preload any flattened i18n bundles before we start
+//executing code, since we cannot do it synchronously, as the
+//i18n code normally expects.
+dojo.hostenv.xdHasCalledPreload = false;
+dojo.hostenv.xdRealCallLoaded = dojo.hostenv.callLoaded;
+dojo.hostenv.callLoaded = function(){
+	//If getModulePrefix for dojo returns anything other than "src", that means
+	//there is a path registered for dojo, with implies that dojo was xdomain loaded.
+	if(this.xdHasCalledPreload || dojo.hostenv.getModulePrefix("dojo") == "src"){
+		this.xdRealCallLoaded();
+		this.xdHasCalledPreload = true;
+	}else{
+		if(this.localesGenerated){
+			this.registerNlsPrefix = function(){
+				//Need to set the nls prefix to be the xd location.
+				dojo.registerModulePath("nls", dojo.hostenv.getModulePrefix("dojo") + "/../nls");	
+			};
+			this.preloadLocalizations();
+		}
+		this.xdHasCalledPreload = true;
+	}
+}

Added: struts/struts2/trunk/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/src/logging/ConsoleLogger.js
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/src/logging/ConsoleLogger.js?view=auto&rev=514083
==============================================================================
--- struts/struts2/trunk/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/src/logging/ConsoleLogger.js (added)
+++ struts/struts2/trunk/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/src/logging/ConsoleLogger.js Fri Mar  2 21:48:54 2007
@@ -0,0 +1,108 @@
+/*
+	Copyright (c) 2004-2006, The Dojo Foundation
+	All Rights Reserved.
+
+	Licensed under the Academic Free License version 2.1 or above OR the
+	modified BSD license. For more information on Dojo licensing, see:
+
+		http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.logging.ConsoleLogger");
+dojo.require("dojo.logging.Logger");
+
+dojo.lang.extend(dojo.logging.MemoryLogHandler,{
+	
+	debug:function(){
+		dojo.hostenv.println.apply(this,arguments);
+	},
+	info:function(){
+		dojo.hostenv.println.apply(this,arguments);
+	},
+	warn:function(){
+		dojo.hostenv.println.apply(this,arguments);
+	},
+	error:function(){
+		dojo.hostenv.println.apply(this,arguments);
+	},
+	critical:function(){
+		dojo.hostenv.println.apply(this,arguments);
+	},
+	
+	emit:function(record){
+		if (!djConfig.isDebug) { return; }
+		
+		var funcName=null;
+		switch(record.level){
+			case 1:
+				funcName="debug";
+				break;
+			case 2:
+				funcName="info";
+				break;
+			case 3:
+				funcName="warn";
+				break;
+			case 4:
+				funcName="error";
+				break;
+			case 5:
+				funcName="critical";
+				break;
+			default:
+				funcName="debug";
+		}
+		
+		var logStr = String(dojo.log.getLevelName(record.level)+": "
+					+record.time.toLocaleTimeString())+": "+record.message;
+		if(record.msgArgs && record.msgArgs.length > 0){
+			this[funcName].call(this, logStr, record.msgArgs);
+		} else {
+			this[funcName].call(this, logStr);
+		}
+		
+		this.data.push(record);
+		if(this.numRecords != -1){
+			while(this.data.length>this.numRecords){
+				this.data.shift();
+			}
+		}
+	}
+});
+
+if(!dj_undef("console") && !dj_undef("info", console)){
+dojo.lang.extend(dojo.logging.MemoryLogHandler,{
+	debug:function(){
+		console.debug.apply(this, arguments);
+	},
+	info:function(){
+		console.info.apply(this, arguments);
+	},
+	warn:function(){
+		console.warn.apply(this, arguments);
+	},
+	error:function(){
+		console.error.apply(this, arguments);
+	},
+	critical:function(){
+		console.error.apply(this, arguments);
+	}
+});
+
+dojo.lang.extend(dojo.logging.Logger,{
+	exception: function(msg, e, squelch){
+		var args=[msg];
+		
+		if(e){
+			msg+=" : "+ e.name + " " + (e.description||e.message);
+			args.push(e);
+		}
+		
+		this.logType("ERROR", args);
+		if(!squelch){
+			throw e;
+		}
+	}
+});
+
+}

Added: struts/struts2/trunk/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/src/logging/Logger.js
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/src/logging/Logger.js?view=auto&rev=514083
==============================================================================
--- struts/struts2/trunk/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/src/logging/Logger.js (added)
+++ struts/struts2/trunk/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/src/logging/Logger.js Fri Mar  2 21:48:54 2007
@@ -0,0 +1,387 @@
+/*
+	Copyright (c) 2004-2006, The Dojo Foundation
+	All Rights Reserved.
+
+	Licensed under the Academic Free License version 2.1 or above OR the
+	modified BSD license. For more information on Dojo licensing, see:
+
+		http://dojotoolkit.org/community/licensing.shtml
+*/
+
+/*		This is the dojo logging facility, which is imported from nWidgets
+		(written by Alex Russell, CLA on file), which is patterned on the
+		Python logging module, which in turn has been heavily influenced by
+		log4j (execpt with some more pythonic choices, which we adopt as well).
+
+		While the dojo logging facilities do provide a set of familiar
+		interfaces, many of the details are changed to reflect the constraints
+		of the browser environment. Mainly, file and syslog-style logging
+		facilites are not provided, with HTTP POST and GET requests being the
+		only ways of getting data from the browser back to a server. Minimal
+		support for this (and XML serialization of logs) is provided, but may
+		not be of practical use in a deployment environment.
+
+		The Dojo logging classes are agnostic of any environment, and while
+		default loggers are provided for browser-based interpreter
+		environments, this file and the classes it define are explicitly
+		designed to be portable to command-line interpreters and other
+		ECMA-262v3 envrionments.
+
+	the logger needs to accomidate:
+		log "levels"
+		type identifiers
+		file?
+		message
+		tic/toc?
+
+	The logger should ALWAYS record:
+		time/date logged
+		message
+		type
+		level
+*/
+// TODO: conver documentation to javadoc style once we confirm that is our choice
+// TODO: define DTD for XML-formatted log messages
+// TODO: write XML Formatter class
+// TODO: write HTTP Handler which uses POST to send log lines/sections
+
+// Filename:	LogCore.js
+// Purpose:		a common logging infrastructure for dojo
+// Classes:		dojo.logging, dojo.logging.Logger, dojo.logging.Record, dojo.logging.LogFilter
+// Global Objects:	dojo.logging
+// Dependencies:	none
+
+dojo.provide("dojo.logging.Logger");
+dojo.require("dojo.lang.common");
+
+/*
+	A simple data structure class that stores information for and about
+	a logged event. Objects of this type are created automatically when
+	an event is logged and are the internal format in which information
+	about log events is kept.
+*/
+
+dojo.logging.Record = function(lvl, msg){
+	this.level = lvl;
+	this.message = "";
+	this.msgArgs = [];
+	this.time = new Date();
+	
+	if(dojo.lang.isArray(msg)){
+		if(msg.length > 0 && dojo.lang.isString(msg[0])){
+			this.message=msg.shift();
+		}
+		this.msgArgs=msg;
+	}else{
+		this.message=msg;
+	}
+	// FIXME: what other information can we receive/discover here?
+}
+
+// an empty parent (abstract) class which concrete filters should inherit from.
+dojo.logging.LogFilter = function(loggerChain){
+	this.passChain = loggerChain || "";
+	this.filter = function(record){
+		// FIXME: need to figure out a way to enforce the loggerChain
+		// restriction
+		return true; // pass all records
+	}
+}
+
+dojo.logging.Logger = function(){
+	this.cutOffLevel = 0;
+	this.propagate = true;
+	this.parent = null;
+	// storage for dojo.logging.Record objects seen and accepted by this logger
+	this.data = [];
+	this.filters = [];
+	this.handlers = [];
+}
+
+dojo.extend(dojo.logging.Logger,{
+	argsToArr: function(args){
+		// utility function, reproduced from __util__ here to remove dependency
+		var ret = [];
+		for(var x=0; x<args.length; x++){
+			ret.push(args[x]);
+		}
+		return ret;
+	},
+
+	setLevel: function(lvl){
+		this.cutOffLevel = parseInt(lvl);
+	},
+
+	isEnabledFor: function(lvl){
+		return parseInt(lvl) >= this.cutOffLevel;
+	},
+
+	getEffectiveLevel: function(){
+		if((this.cutOffLevel==0)&&(this.parent)){
+			return this.parent.getEffectiveLevel();
+		}
+		return this.cutOffLevel;
+	},
+
+	addFilter: function(flt){
+		this.filters.push(flt);
+		return this.filters.length-1;
+	},
+
+	removeFilterByIndex: function(fltIndex){
+		if(this.filters[fltIndex]){
+			delete this.filters[fltIndex];
+			return true;
+		}
+		return false;
+	},
+
+	removeFilter: function(fltRef){
+		for(var x=0; x<this.filters.length; x++){
+			if(this.filters[x]===fltRef){
+				delete this.filters[x];
+				return true;
+			}
+		}
+		return false;
+	},
+
+	removeAllFilters: function(){
+		this.filters = []; // clobber all of them
+	},
+
+	filter: function(rec){
+		for(var x=0; x<this.filters.length; x++){
+			if((this.filters[x]["filter"])&&
+			   (!this.filters[x].filter(rec))||
+			   (rec.level<this.cutOffLevel)){
+				return false;
+			}
+		}
+		return true;
+	},
+
+	addHandler: function(hdlr){
+		this.handlers.push(hdlr);
+		return this.handlers.length-1;
+	},
+
+	handle: function(rec){
+		if((!this.filter(rec))||(rec.level<this.cutOffLevel)){ return false; }
+		for(var x=0; x<this.handlers.length; x++){
+			if(this.handlers[x]["handle"]){
+			   this.handlers[x].handle(rec);
+			}
+		}
+		// FIXME: not sure what to do about records to be propagated that may have
+		// been modified by the handlers or the filters at this logger. Should
+		// parents always have pristine copies? or is passing the modified record
+		// OK?
+		// if((this.propagate)&&(this.parent)){ this.parent.handle(rec); }
+		return true;
+	},
+
+	// the heart and soul of the logging system
+	log: function(lvl, msg){
+		if(	(this.propagate)&&(this.parent)&&
+			(this.parent.rec.level>=this.cutOffLevel)){
+			this.parent.log(lvl, msg);
+			return false;
+		}
+		// FIXME: need to call logging providers here!
+		this.handle(new dojo.logging.Record(lvl, msg));
+		return true;
+	},
+
+	// logger helpers
+	debug:function(msg){
+		return this.logType("DEBUG", this.argsToArr(arguments));
+	},
+
+	info: function(msg){
+		return this.logType("INFO", this.argsToArr(arguments));
+	},
+
+	warning: function(msg){
+		return this.logType("WARNING", this.argsToArr(arguments));
+	},
+
+	error: function(msg){
+		return this.logType("ERROR", this.argsToArr(arguments));
+	},
+
+	critical: function(msg){
+		return this.logType("CRITICAL", this.argsToArr(arguments));
+	},
+
+	exception: function(msg, e, squelch){
+		// FIXME: this needs to be modified to put the exception in the msg
+		// if we're on Moz, we can get the following from the exception object:
+		//		lineNumber
+		//		message
+		//		fileName
+		//		stack
+		//		name
+		// on IE, we get:
+		//		name
+		//		message (from MDA?)
+		//		number
+		//		description (same as message!)
+		if(e){
+			var eparts = [e.name, (e.description||e.message)];
+			if(e.fileName){
+				eparts.push(e.fileName);
+				eparts.push("line "+e.lineNumber);
+				// eparts.push(e.stack);
+			}
+			msg += " "+eparts.join(" : ");
+		}
+
+		this.logType("ERROR", msg);
+		if(!squelch){
+			throw e;
+		}
+	},
+
+	logType: function(type, args){
+		return this.log.apply(this, [dojo.logging.log.getLevel(type), 
+			args]);
+	},
+	
+	warn:function(){
+		this.warning.apply(this,arguments);
+	},
+	err:function(){
+		this.error.apply(this,arguments);
+	},
+	crit:function(){
+		this.critical.apply(this,arguments);
+	}
+});
+
+// the Handler class
+dojo.logging.LogHandler = function(level){
+	this.cutOffLevel = (level) ? level : 0;
+	this.formatter = null; // FIXME: default formatter?
+	this.data = [];
+	this.filters = [];
+}
+dojo.lang.extend(dojo.logging.LogHandler,{
+	
+	setFormatter:function(formatter){
+		dojo.unimplemented("setFormatter");
+	},
+	
+	flush:function(){},
+	close:function(){},
+	handleError:function(){},
+	
+	handle:function(record){
+		if((this.filter(record))&&(record.level>=this.cutOffLevel)){
+			this.emit(record);
+		}
+	},
+	
+	emit:function(record){
+		dojo.unimplemented("emit");
+	}
+});
+
+// set aliases since we don't want to inherit from dojo.logging.Logger
+void(function(){ // begin globals protection closure
+	var names = [
+		"setLevel", "addFilter", "removeFilterByIndex", "removeFilter",
+		"removeAllFilters", "filter"
+	];
+	var tgt = dojo.logging.LogHandler.prototype;
+	var src = dojo.logging.Logger.prototype;
+	for(var x=0; x<names.length; x++){
+		tgt[names[x]] = src[names[x]];
+	}
+})(); // end globals protection closure
+
+dojo.logging.log = new dojo.logging.Logger();
+
+// an associative array of logger objects. This object inherits from
+// a list of level names with their associated numeric levels
+dojo.logging.log.levels = [ {"name": "DEBUG", "level": 1},
+						   {"name": "INFO", "level": 2},
+						   {"name": "WARNING", "level": 3},
+						   {"name": "ERROR", "level": 4},
+						   {"name": "CRITICAL", "level": 5} ];
+
+dojo.logging.log.loggers = {};
+
+dojo.logging.log.getLogger = function(name){
+	if(!this.loggers[name]){
+		this.loggers[name] = new dojo.logging.Logger();
+		this.loggers[name].parent = this;
+	}
+	return this.loggers[name];
+}
+
+dojo.logging.log.getLevelName = function(lvl){
+	for(var x=0; x<this.levels.length; x++){
+		if(this.levels[x].level == lvl){
+			return this.levels[x].name;
+		}
+	}
+	return null;
+}
+
+dojo.logging.log.addLevelName = function(name, lvl){
+	if(this.getLevelName(name)){
+		this.err("could not add log level "+name+" because a level with that name already exists");
+		return false;
+	}
+	this.levels.append({"name": name, "level": parseInt(lvl)});
+	return true;
+}
+
+dojo.logging.log.getLevel = function(name){
+	for(var x=0; x<this.levels.length; x++){
+		if(this.levels[x].name.toUpperCase() == name.toUpperCase()){
+			return this.levels[x].level;
+		}
+	}
+	return null;
+}
+
+// a default handler class, it simply saves all of the handle()'d records in
+// memory. Useful for attaching to with dojo.event.connect()
+dojo.logging.MemoryLogHandler = function(level, recordsToKeep, postType, postInterval){
+	// mixin style inheritance
+	dojo.logging.LogHandler.call(this, level);
+	// default is unlimited
+	this.numRecords = (typeof djConfig['loggingNumRecords'] != 'undefined') ? djConfig['loggingNumRecords'] : ((recordsToKeep) ? recordsToKeep : -1);
+	// 0=count, 1=time, -1=don't post TODO: move this to a better location for prefs
+	this.postType = (typeof djConfig['loggingPostType'] != 'undefined') ? djConfig['loggingPostType'] : ( postType || -1);
+	// milliseconds for time, interger for number of records, -1 for non-posting,
+	this.postInterval = (typeof djConfig['loggingPostInterval'] != 'undefined') ? djConfig['loggingPostInterval'] : ( postType || -1);
+}
+
+dojo.lang.inherits(dojo.logging.MemoryLogHandler, dojo.logging.LogHandler);
+dojo.lang.extend(dojo.logging.MemoryLogHandler,{
+	
+	emit:function(record){
+		if (!djConfig.isDebug) { return; }
+		
+		var logStr = String(dojo.log.getLevelName(record.level)+": "
+					+record.time.toLocaleTimeString())+": "+record.message;
+		if(!dj_undef("println", dojo.hostenv)){
+			dojo.hostenv.println(logStr);
+		}
+		
+		this.data.push(record);
+		if(this.numRecords != -1){
+			while(this.data.length>this.numRecords){
+				this.data.shift();
+			}
+		}
+	}
+});
+
+dojo.logging.logQueueHandler = new dojo.logging.MemoryLogHandler(0,50,0,10000);
+
+dojo.logging.log.addHandler(dojo.logging.logQueueHandler);
+dojo.log = dojo.logging.log;

Added: struts/struts2/trunk/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/src/logging/__package__.js
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/src/logging/__package__.js?view=auto&rev=514083
==============================================================================
--- struts/struts2/trunk/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/src/logging/__package__.js (added)
+++ struts/struts2/trunk/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/src/logging/__package__.js Fri Mar  2 21:48:54 2007
@@ -0,0 +1,15 @@
+/*
+	Copyright (c) 2004-2006, The Dojo Foundation
+	All Rights Reserved.
+
+	Licensed under the Academic Free License version 2.1 or above OR the
+	modified BSD license. For more information on Dojo licensing, see:
+
+		http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.kwCompoundRequire({
+	common: [["dojo.logging.Logger", false, false]],
+	rhino: ["dojo.logging.RhinoLogger"]
+});
+dojo.provide("dojo.logging.*");

Added: struts/struts2/trunk/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/src/math.js
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/src/math.js?view=auto&rev=514083
==============================================================================
--- struts/struts2/trunk/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/src/math.js (added)
+++ struts/struts2/trunk/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/src/math.js Fri Mar  2 21:48:54 2007
@@ -0,0 +1,127 @@
+/*
+	Copyright (c) 2004-2006, The Dojo Foundation
+	All Rights Reserved.
+
+	Licensed under the Academic Free License version 2.1 or above OR the
+	modified BSD license. For more information on Dojo licensing, see:
+
+		http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.math");
+
+dojo.math.degToRad = function(/* float */x) {
+	//	summary
+	//	Converts degrees to radians.
+	return (x*Math.PI) / 180; 	//	float
+}
+dojo.math.radToDeg = function(/* float */x) { 
+	//	summary
+	//	Converts radians to degrees.
+	return (x*180) / Math.PI; 	//	float
+}
+
+dojo.math.factorial = function(/* integer */n){
+	//	summary
+	//	Returns n!
+	if(n<1){ return 0; }
+	var retVal = 1;
+	for(var i=1;i<=n;i++){ retVal *= i; }
+	return retVal;	//	integer
+}
+
+dojo.math.permutations = function(/* integer */n, /* integer */k) {
+	//	summary
+	//	The number of ways of obtaining an ordered subset of k elements from a set of n elements
+	if(n==0 || k==0) return 1;
+	return (dojo.math.factorial(n) / dojo.math.factorial(n-k));	//	float
+}
+
+dojo.math.combinations = function (/* integer */n, /* integer */r) {
+	//	summary
+	//	The number of ways of picking n unordered outcomes from r possibilities
+	if(n==0 || r==0) return 1;
+	return (dojo.math.factorial(n) / (dojo.math.factorial(n-r) * dojo.math.factorial(r)));	//	float
+}
+
+dojo.math.bernstein = function(/* float */t, /* float */n, /* float */i) {
+	//	summary
+	//	Calculates a weighted average based on the Bernstein theorem.
+	return (dojo.math.combinations(n,i) * Math.pow(t,i) * Math.pow(1-t,n-i));	//	float
+}
+
+dojo.math.gaussianRandom = function(){
+	//	summary
+	//	Returns random numbers with a Gaussian distribution, with the mean set at 0 and the variance set at 1.
+	var k = 2;
+	do {
+		var i = 2 * Math.random() - 1;
+		var j = 2 * Math.random() - 1;
+		k = i * i + j * j;
+	} while (k >= 1);
+	k = Math.sqrt((-2 * Math.log(k)) / k);
+	return i * k;	//	float
+}
+
+dojo.math.mean = function() {
+	//	summary
+	//	Calculates the mean of an Array of numbers.
+	var array = dojo.lang.isArray(arguments[0]) ? arguments[0] : arguments;
+	var mean = 0;
+	for (var i = 0; i < array.length; i++) { mean += array[i]; }
+	return mean / array.length;	//	float
+}
+
+dojo.math.round = function(/* float */number, /* integer */places) {
+	//	summary
+	//	Extends Math.round by adding a second argument specifying the number of decimal places to round to.
+	// TODO: add support for significant figures
+	if (!places) { var shift = 1; }
+	else { var shift = Math.pow(10, places); }
+	return Math.round(number * shift) / shift;	//	float
+}
+
+dojo.math.sd = dojo.math.standardDeviation = function(/* array */){
+	//	summary
+	//	Calculates the standard deviation of an Array of numbers
+	var array = dojo.lang.isArray(arguments[0]) ? arguments[0] : arguments;
+	return Math.sqrt(dojo.math.variance(array));	//	float
+}
+
+dojo.math.variance = function(/* array */) {
+	//	summary
+	//	Calculates the variance of an Array of numbers
+	var array = dojo.lang.isArray(arguments[0]) ? arguments[0] : arguments;
+	var mean = 0, squares = 0;
+	for (var i = 0; i < array.length; i++) {
+		mean += array[i];
+		squares += Math.pow(array[i], 2);
+	}
+	return (squares / array.length) - Math.pow(mean / array.length, 2);	//	float
+}
+
+dojo.math.range = function(/* integer */a, /* integer */b, /* integer */step) {
+	//	summary
+	//	implementation of Python's range()
+    if(arguments.length < 2) {
+        b = a;
+        a = 0;
+    }
+    if(arguments.length < 3) {
+        step = 1;
+    }
+
+    var range = [];
+    if(step > 0) {
+        for(var i = a; i < b; i += step) {
+            range.push(i);
+        }
+    } else if(step < 0) {
+        for(var i = a; i > b; i += step) {
+            range.push(i);
+        }
+    } else {
+        throw new Error("dojo.math.range: step must be non-zero");
+    }
+    return range;	//	array
+}

Added: struts/struts2/trunk/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/src/math/__package__.js
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/src/math/__package__.js?view=auto&rev=514083
==============================================================================
--- struts/struts2/trunk/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/src/math/__package__.js (added)
+++ struts/struts2/trunk/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/src/math/__package__.js Fri Mar  2 21:48:54 2007
@@ -0,0 +1,18 @@
+/*
+	Copyright (c) 2004-2006, The Dojo Foundation
+	All Rights Reserved.
+
+	Licensed under the Academic Free License version 2.1 or above OR the
+	modified BSD license. For more information on Dojo licensing, see:
+
+		http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.kwCompoundRequire({
+	common: [
+		["dojo.math", false, false],
+		["dojo.math.curves", false, false],
+		["dojo.math.points", false, false]
+	]
+});
+dojo.provide("dojo.math.*");

Added: struts/struts2/trunk/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/src/math/curves.js
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/src/math/curves.js?view=auto&rev=514083
==============================================================================
--- struts/struts2/trunk/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/src/math/curves.js (added)
+++ struts/struts2/trunk/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/src/math/curves.js Fri Mar  2 21:48:54 2007
@@ -0,0 +1,242 @@
+/*
+	Copyright (c) 2004-2006, The Dojo Foundation
+	All Rights Reserved.
+
+	Licensed under the Academic Free License version 2.1 or above OR the
+	modified BSD license. For more information on Dojo licensing, see:
+
+		http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.math.curves");
+dojo.require("dojo.math");
+
+/* Curves from Dan's 13th lib stuff.
+ * See: http://pupius.co.uk/js/Toolkit.Drawing.js
+ *      http://pupius.co.uk/dump/dojo/Dojo.Math.js
+ */
+
+dojo.math.curves = {
+	Line: function(/* array */start, /* array */end) {
+		//	summary
+		//	Creates a straight line object
+		this.start = start;
+		this.end = end;
+		this.dimensions = start.length;
+
+		for(var i = 0; i < start.length; i++) {
+			start[i] = Number(start[i]);
+		}
+
+		for(var i = 0; i < end.length; i++) {
+			end[i] = Number(end[i]);
+		}
+
+		//simple function to find point on an n-dimensional, straight line
+		this.getValue = function(/* float */n){
+			//	summary
+			//	Returns the point at point N (in terms of percentage) on this line.
+			var retVal = new Array(this.dimensions);
+			for(var i=0;i<this.dimensions;i++)
+				retVal[i] = ((this.end[i] - this.start[i]) * n) + this.start[i];
+			return retVal;	//	array
+		}
+		return this;	//	dojo.math.curves.Line
+	},
+
+	Bezier: function(/* array */pnts) {
+		//	summary
+		//	Creates a bezier curve
+		//	Takes an array of points, the first is the start point, the last is end point and the ones in
+		//	between are the Bezier control points.
+		this.getValue = function(/* float */step) {
+			//	summary
+			//	Returns the point at point N (in terms of percentage) on this curve.
+			if(step >= 1) return this.p[this.p.length-1];	// if step>=1 we must be at the end of the curve
+			if(step <= 0) return this.p[0];					// if step<=0 we must be at the start of the curve
+			var retVal = new Array(this.p[0].length);
+			for(var k=0;j<this.p[0].length;k++) { retVal[k]=0; }
+			for(var j=0;j<this.p[0].length;j++) {
+				var C=0; var D=0;
+				for(var i=0;i<this.p.length;i++) {
+					C += this.p[i][j] * this.p[this.p.length-1][0]
+						* dojo.math.bernstein(step,this.p.length,i);
+				}
+				for(var l=0;l<this.p.length;l++) {
+					D += this.p[this.p.length-1][0] * dojo.math.bernstein(step,this.p.length,l);
+				}
+				retVal[j] = C/D;
+			}
+			return retVal;	//	array
+		}
+		this.p = pnts;
+		return this;	//	dojo.math.curves.Bezier
+	},
+
+	CatmullRom : function(/* array */pnts, /* float */c) {
+		//	summary
+		//	Creates a catmull-rom spline curve with c tension.
+		this.getValue = function(/* float */step) {
+			//	summary
+			//	Returns the point at point N (in terms of percentage) on this curve.
+			var percent = step * (this.p.length-1);
+			var node = Math.floor(percent);
+			var progress = percent - node;
+
+			var i0 = node-1; if(i0 < 0) i0 = 0;
+			var i = node;
+			var i1 = node+1; if(i1 >= this.p.length) i1 = this.p.length-1;
+			var i2 = node+2; if(i2 >= this.p.length) i2 = this.p.length-1;
+
+			var u = progress;
+			var u2 = progress*progress;
+			var u3 = progress*progress*progress;
+
+			var retVal = new Array(this.p[0].length);
+			for(var k=0;k<this.p[0].length;k++) {
+				var x1 = ( -this.c * this.p[i0][k] ) + ( (2 - this.c) * this.p[i][k] ) + ( (this.c-2) * this.p[i1][k] ) + ( this.c * this.p[i2][k] );
+				var x2 = ( 2 * this.c * this.p[i0][k] ) + ( (this.c-3) * this.p[i][k] ) + ( (3 - 2 * this.c) * this.p[i1][k] ) + ( -this.c * this.p[i2][k] );
+				var x3 = ( -this.c * this.p[i0][k] ) + ( this.c * this.p[i1][k] );
+				var x4 = this.p[i][k];
+
+				retVal[k] = x1*u3 + x2*u2 + x3*u + x4;
+			}
+			return retVal;	//	array
+		}
+
+		if(!c) this.c = 0.7;
+		else this.c = c;
+		this.p = pnts;
+
+		return this;	//	dojo.math.curves.CatmullRom
+	},
+
+	// FIXME: This is the bad way to do a partial-arc with 2 points. We need to have the user
+	// supply the radius, otherwise we always get a half-circle between the two points.
+	Arc : function(/* array */start, /* array */end, /* boolean? */ccw) {
+		//	summary
+		//	Creates an arc with a counter clockwise switch
+		var center = dojo.math.points.midpoint(start, end);
+		var sides = dojo.math.points.translate(dojo.math.points.invert(center), start);
+		var rad = Math.sqrt(Math.pow(sides[0], 2) + Math.pow(sides[1], 2));
+		var theta = dojo.math.radToDeg(Math.atan(sides[1]/sides[0]));
+		if( sides[0] < 0 ) {
+			theta -= 90;
+		} else {
+			theta += 90;
+		}
+		dojo.math.curves.CenteredArc.call(this, center, rad, theta, theta+(ccw?-180:180));
+	},
+
+	CenteredArc : function(/* array */center, /* float */radius, /* array */start, /* array */end) {
+		//	summary
+		// 	Creates an arc object, with center and radius (Top of arc = 0 degrees, increments clockwise)
+		//  center => 2D point for center of arc
+		//  radius => scalar quantity for radius of arc
+		//  start  => to define an arc specify start angle (default: 0)
+		//  end    => to define an arc specify start angle
+		this.center = center;
+		this.radius = radius;
+		this.start = start || 0;
+		this.end = end;
+
+		this.getValue = function(/* float */n) {
+			//	summary
+			//	Returns the point at point N (in terms of percentage) on this curve.
+			var retVal = new Array(2);
+			var theta = dojo.math.degToRad(this.start+((this.end-this.start)*n));
+
+			retVal[0] = this.center[0] + this.radius*Math.sin(theta);
+			retVal[1] = this.center[1] - this.radius*Math.cos(theta);
+	
+			return retVal;	//	array
+		}
+
+		return this;	//	dojo.math.curves.CenteredArc
+	},
+
+	Circle : function(/* array */center, /* float */radius) {
+		//	summary
+		// Special case of Arc (start = 0, end = 360)
+		dojo.math.curves.CenteredArc.call(this, center, radius, 0, 360);
+		return this;	//	dojo.math.curves.Circle
+	},
+
+	Path : function() {
+		//	summary
+		// 	Generic path shape, created from curve segments
+		var curves = [];
+		var weights = [];
+		var ranges = [];
+		var totalWeight = 0;
+
+		this.add = function(/* dojo.math.curves.* */curve, /* float */weight) {
+			//	summary
+			//	Add a curve segment to this path
+			if( weight < 0 ) { dojo.raise("dojo.math.curves.Path.add: weight cannot be less than 0"); }
+			curves.push(curve);
+			weights.push(weight);
+			totalWeight += weight;
+			computeRanges();
+		}
+
+		this.remove = function(/* dojo.math.curves.* */curve) {
+			//	summary
+			//	Remove a curve segment from this path
+			for(var i = 0; i < curves.length; i++) {
+				if( curves[i] == curve ) {
+					curves.splice(i, 1);
+					totalWeight -= weights.splice(i, 1)[0];
+					break;
+				}
+			}
+			computeRanges();
+		}
+
+		this.removeAll = function() {
+			//	summary
+			//	Remove all curve segments
+			curves = [];
+			weights = [];
+			totalWeight = 0;
+		}
+
+		this.getValue = function(/* float */n) {
+			//	summary
+			//	Returns the point at point N (in terms of percentage) on this curve.
+			var found = false, value = 0;
+			for(var i = 0; i < ranges.length; i++) {
+				var r = ranges[i];
+				//w(r.join(" ... "));
+				if( n >= r[0] && n < r[1] ) {
+					var subN = (n - r[0]) / r[2];
+					value = curves[i].getValue(subN);
+					found = true;
+					break;
+				}
+			}
+
+			// FIXME: Do we want to assume we're at the end?
+			if( !found ) {
+				value = curves[curves.length-1].getValue(1);
+			}
+
+			for(var j = 0; j < i; j++) {
+				value = dojo.math.points.translate(value, curves[j].getValue(1));
+			}
+			return value;	//	array
+		}
+
+		function computeRanges() {
+			var start = 0;
+			for(var i = 0; i < weights.length; i++) {
+				var end = start + weights[i] / totalWeight;
+				var len = end - start;
+				ranges[i] = [start, end, len];
+				start = end;
+			}
+		}
+
+		return this;	//	dojo.math.curves.Path
+	}
+};

Added: struts/struts2/trunk/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/src/math/matrix.js
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/src/math/matrix.js?view=auto&rev=514083
==============================================================================
--- struts/struts2/trunk/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/src/math/matrix.js (added)
+++ struts/struts2/trunk/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/src/math/matrix.js Fri Mar  2 21:48:54 2007
@@ -0,0 +1,377 @@
+/*
+	Copyright (c) 2004-2006, The Dojo Foundation
+	All Rights Reserved.
+
+	Licensed under the Academic Free License version 2.1 or above OR the
+	modified BSD license. For more information on Dojo licensing, see:
+
+		http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.math.matrix");
+
+// some of this code is based on
+// http://www.mkaz.com/math/MatrixCalculator.java
+// (published under a BSD Open Source License)
+//
+// the rest is from my vague memory of matricies in school [cal]
+//
+// the copying of arguments is a little excessive, and could be trimmed back in
+// the case where a function doesn't modify them at all (but some do!)
+//
+// 2006-06-25: Some enhancements submitted by Erel Segal:
+// * addition: a tolerance constant for determinant calculations.
+// * performance fix: removed unnecessary argument copying.
+// * addition: function "product" for multiplying more than 2 matrices
+// * addition: function "sum" for adding any number of matrices
+// * bug fix: inversion of a 1x1 matrix without using the adjoint
+// * performance fixes: upperTriangle
+// * addition: argument "value" to function create, to initialize the matrix with a custom val
+// * addition: functions "ones" and "zeros" - like Matlab[TM] functions with the same name.
+// * addition: function "identity" for creating an identity matrix of a given size.
+// * addition: argument "decimal_points" to function format
+// * bug fix: adjoint of a 0-size matrix
+// * performance fixes: adjoint
+//
+
+dojo.math.matrix.iDF = 0;
+
+// Erel: values lower than this value are considered zero (in detereminant calculations).
+// It is analogous to Maltab[TM]'s "eps".
+dojo.math.matrix.ALMOST_ZERO = 1e-10;
+dojo.math.matrix.multiply = function(a, b){
+	var ay = a.length;
+	var ax = a[0].length;
+	var by = b.length;
+	var bx = b[0].length;
+
+	if (ax != by){
+		dojo.debug("Can't multiply matricies of sizes "+ax+','+ay+' and '+bx+','+by);
+		return [[0]];
+	}
+
+	var c = [];
+	for(var k=0; k<ay; k++){
+		c[k] = [];
+		for(var i=0; i<bx; i++){
+			c[k][i] = 0;
+			for(var m=0; m<ax; m++){
+				c[k][i] += a[k][m]*b[m][i];
+			}
+		}
+	}
+	return c;
+}
+
+// Erel: added a "product" function to calculate product of more than 2 matrices:
+dojo.math.matrix.product = function() {
+	if (arguments.length==0) {
+		dojo.debug ("can't multiply 0 matrices!");
+		return 1;
+	}
+	var result = arguments[0];
+	for (var i=1; i<arguments.length; i++){
+		result = dojo.math.matrix.multiply(result,arguments[i]);
+	}
+	return result;
+}
+
+// Erel: added a "sum" function to calculate sum of more than 2 matrices:
+dojo.math.matrix.sum = function() {
+	if (arguments.length==0) {
+		dojo.debug ("can't sum 0 matrices!");
+		return 0;
+	}
+	var result = dojo.math.matrix.copy(arguments[0]);
+	var rows = result.length;
+	if (rows==0) {
+		dojo.debug ("can't deal with matrices of 0 rows!");
+		return 0;
+	}
+	var cols = result[0].length;
+	if (cols==0) {
+		dojo.debug ("can't deal with matrices of 0 cols!");
+		return 0;
+	}
+	for (var i=1; i<arguments.length; ++i) {
+		var arg = arguments[i];
+		if (arg.length!=rows || arg[0].length!=cols) {
+			dojo.debug ("can't add matrices of different dimensions: first dimensions were " + rows + "x" + cols + ", current dimensions are "+arg.length + "x" + arg[0].length);
+			return 0;
+		}
+		
+		// The actual addition:
+		for (var r=0; r<rows; r++){
+			for (var c=0; c<cols; c++){
+				result[r][c] += arg[r][c];
+			}
+		}
+	}
+	return result;
+}
+
+
+dojo.math.matrix.inverse = function(a){
+	// Erel: added special case: inverse of a 1x1 matrix can't be calculated by adjoint
+	if (a.length==1 && a[0].length==1){
+		return [[ 1 / a[0][0] ]];
+	}
+
+	// Formula used to Calculate Inverse:
+	// inv(A) = 1/det(A) * adj(A)
+	
+	var tms = a.length;
+	var m = dojo.math.matrix.create(tms, tms);
+	var mm = dojo.math.matrix.adjoint(a);
+	var det = dojo.math.matrix.determinant(a);
+	var dd = 0;
+
+	if(det == 0){
+		dojo.debug("Determinant Equals 0, Not Invertible.");
+		return [[0]];
+	}else{
+		dd = 1 / det;
+	}
+
+	for (var i = 0; i < tms; i++){
+		for (var j = 0; j < tms; j++) {
+			m[i][j] = dd * mm[i][j];
+		}
+	}
+	return m;
+}
+
+dojo.math.matrix.determinant = function(a){
+	if (a.length != a[0].length){
+		dojo.debug("Can't calculate the determiant of a non-squre matrix!");
+		return 0;
+	}
+
+	var tms = a.length;
+	var det = 1;
+	var b = dojo.math.matrix.upperTriangle(a);
+
+	for (var i=0; i < tms; i++){
+		var bii = b[i][i];
+		if (Math.abs(bii) < dojo.math.matrix.ALMOST_ZERO){
+			return 0;
+		}
+		det *= bii;
+	}
+	det = det * dojo.math.matrix.iDF;
+	return det;
+}
+
+dojo.math.matrix.upperTriangle = function(m){
+	m = dojo.math.matrix.copy(m);     // Copy m, because m is changed!
+	var f1 = 0;
+	var temp = 0;
+	var tms = m.length;
+	var v = 1;
+
+	//Erel: why use a global variable and not a local variable?
+	dojo.math.matrix.iDF = 1;
+
+	for (var col = 0; col < tms - 1; col++) {
+		if (typeof m[col][col] != 'number'){
+			dojo.debug("non-numeric entry found in a numeric matrix: m["+col+"]["+col+"]="+m[col][col]);
+		}
+		v = 1;
+		var stop_loop = 0;
+		
+		// check if there is a 0 in diagonal
+		while ((m[col][col] == 0) && !stop_loop) {
+			// if so,  switch rows until there is no 0 in diagonal:
+			if (col + v >= tms){
+				// check if switched all rows
+				dojo.math.matrix.iDF = 0;
+				stop_loop = 1;
+			}else{
+				for (var r = 0; r < tms; r++) {
+					temp = m[col][r];
+					m[col][r] = m[col + v][r]; // switch rows
+					m[col + v][r] = temp;
+				}
+				v++; // count row switchs
+				dojo.math.matrix.iDF *= -1; // each switch changes determinant factor
+			}
+		}
+		
+		// loop over lower-right triangle (where row>col):
+		// for each row, make m[row][col] = 0 by linear operations that don't change the determinant:
+		for (var row = col + 1; row < tms; row++) {
+			if (typeof m[row][col] != 'number'){
+				dojo.debug("non-numeric entry found in a numeric matrix: m["+row+"]["+col+"]="+m[row][col]);
+			}
+			if (typeof m[col][row] != 'number'){
+				dojo.debug("non-numeric entry found in a numeric matrix: m["+col+"]["+row+"]="+m[col][row]);
+			}
+			if (m[col][col] != 0) {
+				var f1 = (-1) * m[row][col] / m[col][col];
+				// this should make m[row][col] zero:
+				// 	m[row] += f1 * m[col];
+				for (var i = col; i < tms; i++) {
+					m[row][i] = f1 * m[col][i] + m[row][i];
+				}
+			}
+		}
+	}
+	return m;
+}
+
+// Erel: added parameter "value" - a custom default value to fill the matrix with.
+dojo.math.matrix.create = function(a, b, value){
+	if(!value){
+		value = 0;
+	}
+	var m = [];
+	for(var i=0; i<b; i++){
+		m[i] = [];
+		for(var j=0; j<a; j++){
+			m[i][j] = value;
+		}
+	}
+	return m;
+}
+
+// Erel implement Matlab[TM] functions "ones" and "zeros"
+dojo.math.matrix.ones = function(a,b) { 
+	return dojo.math.matrix.create(a,b,1); 
+}
+dojo.math.matrix.zeros = function(a,b) { 
+	return dojo.math.matrix.create(a,b,0); 
+}
+
+// Erel: added function that returns identity matrix.
+//	size = number of rows and cols in the matrix.
+//	scale = an optional value to multiply the matrix by (default is 1).
+dojo.math.matrix.identity = function(size, scale){
+	if (!scale){
+		scale = 1;
+	}
+	var m = [];
+	for(var i=0; i<size; i++){
+		m[i] = [];
+		for(var j=0; j<size; j++){
+			m[i][j] = (i==j? scale: 0);
+		}
+	}
+	return m;
+}
+
+dojo.math.matrix.adjoint = function(a){
+	var tms = a.length;
+
+	// Erel: added "<=" to catch zero-size matrix
+	if (tms <= 1){
+		dojo.debug("Can't find the adjoint of a matrix with a dimension less than 2");
+		return [[0]];
+	}
+
+	if (a.length != a[0].length){
+		dojo.debug("Can't find the adjoint of a non-square matrix");
+		return [[0]];
+	}
+
+	var m = dojo.math.matrix.create(tms, tms);
+
+	var ii = 0;
+	var jj = 0;
+	var ia = 0;
+	var ja = 0;
+	var det = 0;
+	var ap = dojo.math.matrix.create(tms-1, tms-1);
+
+	for (var i = 0; i < tms; i++){
+		for (var j = 0; j < tms; j++){
+			ia = 0;
+			for (ii = 0; ii < tms; ii++) {   // create a temporary matrix for determinant calc
+				if (ii==i){
+					continue;       // skip current row
+				}
+				ja = 0;
+				for (jj = 0; jj < tms; jj++) {
+					if (jj==j){
+						continue;       // skip current col
+					}
+					ap[ia][ja] = a[ii][jj];
+					ja++;
+				}
+				ia++;
+			}
+		
+			det = dojo.math.matrix.determinant(ap);
+			m[i][j] = Math.pow(-1 , (i + j)) * det;
+		}
+	}
+	m = dojo.math.matrix.transpose(m);
+	return m;
+}
+
+dojo.math.matrix.transpose = function(a){
+	var m = dojo.math.matrix.create(a.length, a[0].length);
+	for (var i = 0; i < a.length; i++){
+		for (var j = 0; j < a[i].length; j++){
+			m[j][i] = a[i][j];
+		}
+	}
+	return m;
+}
+
+// Erel: added decimal_points argument
+dojo.math.matrix.format = function(a, decimal_points){
+	if (arguments.length<=1){
+		decimal_points = 5;
+	}
+
+	function format_int(x, dp){
+		var fac = Math.pow(10 , dp);
+		var a = Math.round(x*fac)/fac;
+		var b = a.toString();
+		if (b.charAt(0) != '-'){ b = ' ' + b;}
+		var has_dp = 0;
+		for(var i=1; i<b.length; i++){
+			if (b.charAt(i) == '.'){ has_dp = 1; }
+		}
+		if (!has_dp){ b += '.'; }
+		while(b.length < dp+3){ b += '0'; }
+		return b;
+	}
+
+	var ya = a.length;
+	var xa = ya>0? a[0].length: 0;
+	var buffer = '';
+	for (var y=0; y<ya; y++){
+		buffer += '| ';
+		for (var x=0; x<xa; x++){
+			buffer += format_int(a[y][x], decimal_points) + ' ';
+		}
+		buffer += '|\n';
+	}
+	return buffer;
+}
+
+dojo.math.matrix.copy = function(a){
+	var ya = a.length;
+	var xa = a[0].length;
+	var m = dojo.math.matrix.create(xa, ya);
+	for (var y=0; y<ya; y++){
+		for (var x=0; x<xa; x++){
+			m[y][x] = a[y][x];
+		}
+	}
+	return m;
+}
+
+dojo.math.matrix.scale = function(k, a){
+	a = dojo.math.matrix.copy(a);  // Copy a because a is changed!
+	var ya = a.length;
+	var xa = a[0].length;
+
+	for (var y=0; y<ya; y++){
+		for (var x=0; x<xa; x++){
+			a[y][x] *= k;
+		}
+	}
+	return a;
+}

Added: struts/struts2/trunk/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/src/math/points.js
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/src/math/points.js?view=auto&rev=514083
==============================================================================
--- struts/struts2/trunk/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/src/math/points.js (added)
+++ struts/struts2/trunk/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/src/math/points.js Fri Mar  2 21:48:54 2007
@@ -0,0 +1,54 @@
+/*
+	Copyright (c) 2004-2006, The Dojo Foundation
+	All Rights Reserved.
+
+	Licensed under the Academic Free License version 2.1 or above OR the
+	modified BSD license. For more information on Dojo licensing, see:
+
+		http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.math.points");
+dojo.require("dojo.math");
+
+dojo.math.points = {
+	translate: function(/* array */a, /* array */b) {
+		//	summary
+		//	translate a by b, and return the result.
+		if( a.length != b.length ) {
+			dojo.raise("dojo.math.translate: points not same size (a:[" + a + "], b:[" + b + "])");
+		}
+		var c = new Array(a.length);
+		for(var i = 0; i < a.length; i++) {
+			c[i] = a[i] + b[i];
+		}
+		return c;	//	array
+	},
+
+	midpoint: function(/* array */a, /* array */b) {
+		//	summary
+		//	Find the point midway between a and b
+		if( a.length != b.length ) {
+			dojo.raise("dojo.math.midpoint: points not same size (a:[" + a + "], b:[" + b + "])");
+		}
+		var c = new Array(a.length);
+		for(var i = 0; i < a.length; i++) {
+			c[i] = (a[i] + b[i]) / 2;
+		}
+		return c;	//	array
+	},
+
+	invert: function(/* array */a) {
+		//	summary
+		//	invert the values in a and return it.
+		var b = new Array(a.length);
+		for(var i = 0; i < a.length; i++) { b[i] = -a[i]; }
+		return b;	//	array
+	},
+
+	distance: function(/* array */a, /* array */b) {
+		//	summary
+		//	Calculate the distance between point a and point b
+		return Math.sqrt(Math.pow(b[0]-a[0], 2) + Math.pow(b[1]-a[1], 2));	// 	float
+	}
+};

Added: struts/struts2/trunk/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/src/namespaces/dojo.js
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/src/namespaces/dojo.js?view=auto&rev=514083
==============================================================================
--- struts/struts2/trunk/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/src/namespaces/dojo.js (added)
+++ struts/struts2/trunk/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/src/namespaces/dojo.js Fri Mar  2 21:48:54 2007
@@ -0,0 +1,153 @@
+/*
+	Copyright (c) 2004-2006, The Dojo Foundation
+	All Rights Reserved.
+
+	Licensed under the Academic Free License version 2.1 or above OR the
+	modified BSD license. For more information on Dojo licensing, see:
+
+		http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.namespaces.dojo");
+dojo.require("dojo.ns");
+
+(function(){
+	//mapping of all widget short names to their full package names
+	// This is used for widget autoloading - no dojo.require() is necessary.
+	// If you use a widget in markup or create one dynamically, then this
+	// mapping is used to find and load any dependencies not already loaded.
+	// You should use your own namespace for any custom widgets.
+	// For extra widgets you use, dojo.declare() may be used to explicitly load them.
+	var map = {
+		html: {
+			"accordioncontainer": "dojo.widget.AccordionContainer",
+			"button": "dojo.widget.Button",
+			"chart": "dojo.widget.Chart",
+			"checkbox": "dojo.widget.Checkbox",
+			"colorpalette": "dojo.widget.ColorPalette",
+			"combobox": "dojo.widget.ComboBox",
+			"combobutton": "dojo.widget.Button",
+			"contentpane": "dojo.widget.ContentPane",
+			"contextmenu": "dojo.widget.ContextMenu",
+			"currencytextbox": "dojo.widget.CurrencyTextbox",
+			"datepicker": "dojo.widget.DatePicker",
+			"datetextbox": "dojo.widget.DateTextbox",
+			"debugconsole": "dojo.widget.DebugConsole",
+			"dialog": "dojo.widget.Dialog",
+			"docpane": "dojo.widget.DocPane",
+			"dropdownbutton": "dojo.widget.Button",
+			"dropdowndatepicker": "dojo.widget.DropdownDatePicker",
+			"dropdowntimepicker": "dojo.widget.DropdownTimePicker",
+			"emaillisttextbox": "dojo.widget.InternetTextbox",
+			"emailtextbox": "dojo.widget.InternetTextbox",
+			"editor2": "dojo.widget.Editor2",
+			"editor2toolbar": "dojo.widget.Editor2Toolbar",
+			"editor": "dojo.widget.Editor",
+			"editortree": "dojo.widget.EditorTree",
+			"editortreecontextmenu": "dojo.widget.EditorTreeContextMenu",
+			"editortreenode": "dojo.widget.EditorTreeNode",
+			"filteringtable": "dojo.widget.FilteringTable",
+			"fisheyelist": "dojo.widget.FisheyeList",
+			"editortreecontroller": "dojo.widget.EditorTreeController",
+			"googlemap": "dojo.widget.GoogleMap",
+			"editortreeselector": "dojo.widget.EditorTreeSelector",
+			"floatingpane": "dojo.widget.FloatingPane",
+			"form": "dojo.widget.Form",
+			"hslcolorpicker": "dojo.widget.HslColorPicker",
+			"inlineeditbox": "dojo.widget.InlineEditBox",
+			"integerspinner": "dojo.widget.IntegerSpinner",
+			"integertextbox": "dojo.widget.IntegerTextbox",
+			"ipaddresstextbox": "dojo.widget.InternetTextbox",
+			"layoutcontainer": "dojo.widget.LayoutContainer",
+			"linkpane": "dojo.widget.LinkPane",
+			"pagecontainer": "dojo.widget.PageContainer",
+			"pagecontroller": "dojo.widget.PageContainer",
+			"popupcontainer": "dojo.widget.Menu2",
+			"popupmenu2": "dojo.widget.Menu2",
+			"menuitem2": "dojo.widget.Menu2",
+			"menuseparator2": "dojo.widget.Menu2",
+			"menubar2": "dojo.widget.Menu2",
+			"menubaritem2": "dojo.widget.Menu2",
+			"monthlyCalendar": "dojo.widget.MonthlyCalendar",
+			"radiogroup": "dojo.widget.RadioGroup",
+			"realnumbertextbox": "dojo.widget.RealNumberTextbox",
+			"regexptextbox": "dojo.widget.RegexpTextbox",
+			"repeater": "dojo.widget.Repeater", 
+			"richtext": "dojo.widget.RichText",
+			"remotetabcontroller": "dojo.widget.RemoteTabController",
+			"resizehandle": "dojo.widget.ResizeHandle",
+			"resizabletextarea": "dojo.widget.ResizableTextarea",
+			"select": "dojo.widget.Select",
+			"slideshow": "dojo.widget.SlideShow",
+			"sortabletable": "dojo.widget.SortableTable",
+			"splitcontainer": "dojo.widget.SplitContainer",
+			"svgbutton": "dojo.widget.SvgButton",
+			"tabcontainer": "dojo.widget.TabContainer",
+			"tabcontroller": "dojo.widget.TabContainer",
+			"taskbar": "dojo.widget.TaskBar",
+			"textbox": "dojo.widget.Textbox",
+			"timepicker": "dojo.widget.TimePicker",
+			"timetextbox": "dojo.widget.DateTextbox",
+			"titlepane": "dojo.widget.TitlePane",
+			"toaster": "dojo.widget.Toaster",
+			"toggler": "dojo.widget.Toggler",
+			"toolbar": "dojo.widget.Toolbar",
+			"tooltip": "dojo.widget.Tooltip",
+			"tree": "dojo.widget.Tree",
+			"treebasiccontroller": "dojo.widget.TreeBasicController",
+			"treecontextmenu": "dojo.widget.TreeContextMenu",
+			"treeselector": "dojo.widget.TreeSelector",
+			"treecontrollerextension": "dojo.widget.TreeControllerExtension",
+			"treenode": "dojo.widget.TreeNode",
+			"treerpccontroller": "dojo.widget.TreeRPCController",
+			"treebasiccontrollerv3": "dojo.widget.TreeBasicControllerV3",
+			"treecontextmenuv3": "dojo.widget.TreeContextMenuV3",
+			"treedeselectondblselect": "dojo.widget.TreeDeselectOnDblselect",
+			"treedisablewrapextension": "dojo.widget.TreeDisableWrapExtension",
+			"treedndcontrollerv3": "dojo.widget.TreeDndControllerV3",
+			"treedociconextension": "dojo.widget.TreeDocIconExtension",
+			"treeeditor": "dojo.widget.TreeEditor",
+			"treeemphaseonselect": "dojo.widget.TreeEmphaseOnSelect",
+			"treelinkextension": "dojo.widget.TreeLinkExtension",
+			"treeloadingcontrollerv3": "dojo.widget.TreeLoadingControllerV3",
+			"treemenuitemv3": "dojo.widget.TreeContextMenuV3",
+			"treerpccontrollerv3": "dojo.widget.TreeRpcControllerV3",
+			"treeselectorv3": "dojo.widget.TreeSelectorV3",
+			"treev3": "dojo.widget.TreeV3",
+			"urltextbox": "dojo.widget.InternetTextbox",
+			"usphonenumbertextbox": "dojo.widget.UsTextbox",
+			"ussocialsecuritynumbertextbox": "dojo.widget.UsTextbox",
+			"usstatetextbox": "dojo.widget.UsTextbox",
+			"usziptextbox": "dojo.widget.UsTextbox",
+			"validationtextbox": "dojo.widget.ValidationTextbox",
+			"treeloadingcontroller": "dojo.widget.TreeLoadingController",
+			"widget": "dojo.widget.Widget",
+			"wizard": "dojo.widget.Wizard",
+			"yahoomap": "dojo.widget.YahooMap"
+		},
+		svg: {
+			"chart": "dojo.widget.svg.Chart",
+			"hslcolorpicker": "dojo.widget.svg.HslColorPicker"
+		},
+		vml: {
+			"chart": "dojo.widget.vml.Chart"
+		}
+	};
+
+	dojo.addDojoNamespaceMapping = function(/*String*/shortName, /*String*/packageName){
+	// summary:
+	//	Add an entry to the mapping table for the dojo: namespace
+	//
+	// shortName: the name to be used as the widget's tag name in the dojo: namespace
+	// packageName: the path to the Javascript module in dotted package notation
+		map[shortName]=packageName;    
+	};
+	
+	function dojoNamespaceResolver(name, domain){
+		if(!domain){ domain="html"; }
+		if(!map[domain]){ return null; }
+		return map[domain][name];    
+	}
+
+	dojo.registerNamespaceResolver("dojo", dojoNamespaceResolver);
+})();

Added: struts/struts2/trunk/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/src/ns.js
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/src/ns.js?view=auto&rev=514083
==============================================================================
--- struts/struts2/trunk/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/src/ns.js (added)
+++ struts/struts2/trunk/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/src/ns.js Fri Mar  2 21:48:54 2007
@@ -0,0 +1,142 @@
+/*
+	Copyright (c) 2004-2006, The Dojo Foundation
+	All Rights Reserved.
+
+	Licensed under the Academic Free License version 2.1 or above OR the
+	modified BSD license. For more information on Dojo licensing, see:
+
+		http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.ns");
+
+dojo.ns = {
+	// summary: private object that implements widget namespace management
+	namespaces: {},
+	failed: {},
+	loading: {},
+	loaded: {},
+	register: function(/*String*/name, /*String*/module, /*Function?*/resolver, /*Boolean?*/noOverride){
+		// summary: creates and registers a dojo.ns.Ns object
+		if(!noOverride || !this.namespaces[name]){
+			this.namespaces[name] = new dojo.ns.Ns(name, module, resolver);
+		}
+	},
+	allow: function(/*String*/name){
+		// summary: Returns false if 'name' is filtered by configuration or has failed to load, true otherwise
+		if(this.failed[name]){return false;} // Boolean
+		if((djConfig.excludeNamespace)&&(dojo.lang.inArray(djConfig.excludeNamespace, name))){return false;} // Boolean
+		// If the namespace is "dojo", or the user has not specified allowed namespaces return true.
+		// Otherwise, if the user has specifically allowed this namespace, return true, otherwise false.
+		return((name==this.dojo)||(!djConfig.includeNamespace)||(dojo.lang.inArray(djConfig.includeNamespace, name))); // Boolean
+	},
+	get: function(/*String*/name){
+		// summary
+		//  Return Ns object registered to 'name', if any
+		return this.namespaces[name]; // Ns
+	},
+	require: function(/*String*/name){
+		// summary
+  	//  Try to ensure that 'name' is registered, loading a namespace manifest if necessary
+		var ns = this.namespaces[name];
+		if((ns)&&(this.loaded[name])){return ns;} // Ns
+		if(!this.allow(name)){return false;} // Boolean
+ 		if(this.loading[name]){
+			// FIXME: do we really ever have re-entrancy situation? this would appear to be really bad
+			// original code did not throw an exception, although that seems the only course
+			// adding debug output here to track if this occurs.
+			dojo.debug('dojo.namespace.require: re-entrant request to load namespace "' + name + '" must fail.'); 
+			return false; // Boolean
+		}
+		// workaround so we don't break the build system
+		var req = dojo.require;
+		this.loading[name] = true;
+		try {
+			//dojo namespace file is always in the Dojo namespaces folder, not any custom folder
+			if(name=="dojo"){
+				req("dojo.namespaces.dojo");
+			}else{
+				// if no registered module prefix, use ../<name> by convention
+				if(!dojo.hostenv.moduleHasPrefix(name)){
+					dojo.registerModulePath(name, "../" + name);
+				}
+				req([name, 'manifest'].join('.'), false, true);
+			}
+			if(!this.namespaces[name]){
+				this.failed[name] = true; //only look for a namespace once
+			}
+		}finally{
+			this.loading[name]=false;
+		}
+		return this.namespaces[name]; // Ns
+	}
+}
+
+dojo.ns.Ns = function(/*String*/name, /*String*/module, /*Function?*/resolver){
+	// summary: this object simply encapsulates namespace data
+	this.name = name;
+	this.module = module;
+	this.resolver = resolver;
+	this._loaded = [ ];
+	this._failed = [ ];
+}
+
+dojo.ns.Ns.prototype.resolve = function(/*String*/name, /*String*/domain, /*Boolean?*/omitModuleCheck){
+	//summary: map component with 'name' and 'domain' to a module via namespace resolver, if specified
+	if(!this.resolver || djConfig["skipAutoRequire"]){return false;} // Boolean
+	var fullName = this.resolver(name, domain);
+	//only load a widget once. This is a quicker check than dojo.require does
+	if((fullName)&&(!this._loaded[fullName])&&(!this._failed[fullName])){
+		//workaround so we don't break the build system
+		var req = dojo.require;
+		req(fullName, false, true); //omit the module check, we'll do it ourselves.
+		if(dojo.hostenv.findModule(fullName, false)){
+			this._loaded[fullName] = true;
+		}else{
+			if(!omitModuleCheck){dojo.raise("dojo.ns.Ns.resolve: module '" + fullName + "' not found after loading via namespace '" + this.name + "'");} 
+			this._failed[fullName] = true;
+		}
+	}
+	return Boolean(this._loaded[fullName]); // Boolean
+}
+
+dojo.registerNamespace = function(/*String*/name, /*String*/module, /*Function?*/resolver){
+	// summary: maps a module name to a namespace for widgets, and optionally maps widget names to modules for auto-loading
+	// description: An unregistered namespace is mapped to an eponymous module.
+	//	For example, namespace acme is mapped to module acme, and widgets are
+	//	assumed to belong to acme.widget. If you want to use a different widget
+	//	module, use dojo.registerNamespace.
+	dojo.ns.register.apply(dojo.ns, arguments);
+}
+
+dojo.registerNamespaceResolver = function(/*String*/name, /*Function*/resolver){
+	// summary: a resolver function maps widget names to modules, so the
+	//	widget manager can auto-load needed widget implementations
+	//
+	// description: The resolver provides information to allow Dojo
+	//	to load widget modules on demand. When a widget is created,
+	//	a namespace resolver can tell Dojo what module to require
+	//	to ensure that the widget implementation code is loaded.
+	//
+	// name: will always be lower-case.
+	//
+	// example:
+	//  dojo.registerNamespaceResolver("acme",
+	//    function(name){ 
+	//      return "acme.widget."+dojo.string.capitalize(name);
+	//    }
+	//  );
+	var n = dojo.ns.namespaces[name];
+	if(n){
+		n.resolver = resolver;
+	}
+}
+
+dojo.registerNamespaceManifest = function(/*String*/module, /*String*/path, /*String*/name, /*String*/widgetModule, /*Function?*/resolver){
+	// summary: convenience function to register a module path, a namespace, and optionally a resolver all at once.
+	dojo.registerModulePath(name, path);
+	dojo.registerNamespace(name, widgetModule, resolver);
+}
+
+// NOTE: rather put this in dojo.widget.Widget, but that fubars debugAtAllCosts
+dojo.registerNamespace("dojo", "dojo.widget");

Added: struts/struts2/trunk/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/src/profile.js
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/src/profile.js?view=auto&rev=514083
==============================================================================
--- struts/struts2/trunk/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/src/profile.js (added)
+++ struts/struts2/trunk/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/src/profile.js Fri Mar  2 21:48:54 2007
@@ -0,0 +1,146 @@
+/*
+	Copyright (c) 2004-2006, The Dojo Foundation
+	All Rights Reserved.
+
+	Licensed under the Academic Free License version 2.1 or above OR the
+	modified BSD license. For more information on Dojo licensing, see:
+
+		http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.profile");
+
+// summary:
+//		provides a manual profiling utility that can be used to gather relative
+//		timing data.
+
+
+// FIXME: need to tie into the event system or provide a closure-based way to
+// watch timings of functions without manually instrumenting them.
+// FIXME: need to make the dump() function work in command line environments
+
+dojo.profile = {
+	_profiles: {},
+	_pns: [],
+
+	start:function(/*String*/ name){
+		// summary:
+		//		start an iteration for the profiling target with the specified
+		//		name. If a previously started iteration has not yet been ended
+		//		for this name, it's automatically closed out and a new
+		//		iteration begun.
+		// name:
+		//		a unique name to identify the thing being profiled
+		if(!this._profiles[name]){
+			this._profiles[name] = {iters: 0, total: 0};
+			this._pns[this._pns.length] = name;
+		}else{
+			if(this._profiles[name]["start"]){
+				this.end(name);
+			}
+		}
+		this._profiles[name].end = null;
+		this._profiles[name].start = new Date();
+	},
+
+	end:function(/*String*/ name){
+		// summary:
+		//		closes a timing loop for the named profiling target
+		// name:
+		//		a unique name to identify the thing being profiled. The name
+		//		passed to end() should be the same as that passed to start()
+		var ed = new Date();
+		if((this._profiles[name])&&(this._profiles[name]["start"])){
+			with(this._profiles[name]){
+				end = ed;
+				total += (end - start);
+				start = null;
+				iters++;
+			}
+		}else{
+			// oops! bad call to end(), what should we do here?
+			return true;
+		}
+	},
+
+	dump:function(/*boolean*/ appendToDoc){
+		// summary:
+		//		output profiling data to an HTML table, optionally adding it to
+		//		the bottom of the document. If profiling data has already been
+		//		generated and appended to the document, it's replaced with the
+		//		new data.
+		// appendToDoc:
+		//		optional. Defautls to "false". Should profiling information be
+		//		added to the document?
+		var tbl = document.createElement("table");
+		with(tbl.style){
+			border = "1px solid black";
+			borderCollapse = "collapse";
+		}
+		var hdr = tbl.createTHead();
+		var hdrtr = hdr.insertRow(0);
+		// document.createElement("tr");
+		var cols = ["Identifier","Calls","Total","Avg"];
+		for(var x=0; x<cols.length; x++){
+			var ntd = hdrtr.insertCell(x);
+			with(ntd.style){
+				backgroundColor = "#225d94";
+				color = "white";
+				borderBottom = "1px solid black";
+				borderRight = "1px solid black";
+				fontFamily = "tahoma";
+				fontWeight = "bolder";
+				paddingLeft = paddingRight = "5px";
+			}
+			ntd.appendChild(document.createTextNode(cols[x]));
+		}
+
+		for(var x=0; x < this._pns.length; x++){
+			var prf = this._profiles[this._pns[x]];
+			this.end(this._pns[x]);
+			if(prf.iters>0){
+				var bdytr = tbl.insertRow(true);
+				var vals = [this._pns[x], prf.iters, prf.total, parseInt(prf.total/prf.iters)];
+				for(var y=0; y<vals.length; y++){
+					var cc = bdytr.insertCell(y);
+					cc.appendChild(document.createTextNode(vals[y]));
+					with(cc.style){
+						borderBottom = "1px solid gray";
+						paddingLeft = paddingRight = "5px";
+						if(x%2){
+							backgroundColor = "#e1f1ff";
+						}
+						if(y>0){
+							textAlign = "right";
+							borderRight = "1px solid gray";
+						}else{
+							borderRight = "1px solid black";
+						}
+					}
+				}
+			}
+		}
+
+		if(appendToDoc){
+			var ne = document.createElement("div");
+			ne.id = "profileOutputTable";
+			with(ne.style){
+				fontFamily = "Courier New, monospace";
+				fontSize = "12px";
+				lineHeight = "16px";
+				borderTop = "1px solid black";
+				padding = "10px";
+			}
+			if(document.getElementById("profileOutputTable")){
+				dojo.body().replaceChild(ne, document.getElementById("profileOutputTable"));
+			}else{
+				dojo.body().appendChild(ne);
+			}
+			ne.appendChild(tbl);
+		}
+
+		return tbl; // DOMNode
+	}
+}
+
+dojo.profile.stop = dojo.profile.end;