Commits

Anonymous committed 268d807

Updating XWork jar
Added validator information to the config-browser
lots of Jalopy reformatting (hasn't anyone else been doing ant builds?)

git-svn-id: http://svn.opensymphony.com/svn/webwork/trunk@414573baa09-0c28-0410-bef9-dab3c582ae83

Comments (0)

Files changed (74)

lib/core/xwork-1.0.1.jar

Binary file modified.

src/config-browser/com/opensymphony/webwork/config_browser/ListValidatorsAction.java

+package com.opensymphony.webwork.config_browser;
+
+import com.opensymphony.xwork.ActionSupport;
+import com.opensymphony.xwork.validator.ActionValidatorManager;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * ListValidatorsAction loads the validations for a given class and context
+ * @author Jason Carreira
+ * Date: May 31, 2004 5:06:16 PM
+ */
+public class ListValidatorsAction extends ActionSupport {
+    private Class clazz;
+    private String context;
+    List validators = Collections.EMPTY_LIST;
+
+    public Class getClazz() {
+        return clazz;
+    }
+
+    public void setClazz(Class clazz) {
+        this.clazz = clazz;
+    }
+
+    public String stripPackage(Class clazz) {
+        return clazz.getName().substring(clazz.getName().lastIndexOf('.') + 1);
+    }
+
+    public String getContext() {
+        return context;
+    }
+
+    public void setContext(String context) {
+        this.context = context;
+    }
+
+    public List getValidators() {
+        return validators;
+    }
+
+    public String execute() throws Exception {
+        loadValidators();
+        return super.execute();
+    }
+
+    protected void loadValidators() {
+        validators = ActionValidatorManager.getValidators(clazz,context);
+    }
+}

src/config-browser/com/opensymphony/webwork/config_browser/ShowValidatorAction.java

+package com.opensymphony.webwork.config_browser;
+
+import ognl.Ognl;
+import ognl.OgnlException;
+
+import java.util.*;
+import java.beans.BeanInfo;
+import java.beans.Introspector;
+import java.beans.IntrospectionException;
+import java.beans.PropertyDescriptor;
+
+import com.opensymphony.xwork.util.OgnlUtil;
+import com.opensymphony.xwork.validator.Validator;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * ShowValidatorAction
+ * @author Jason Carreira
+ * Date: Jun 1, 2004 9:01:02 PM
+ */
+public class ShowValidatorAction extends ListValidatorsAction {
+    private static Log log = LogFactory.getLog(ShowValidatorAction.class);
+
+    Set properties = Collections.EMPTY_SET;
+    int selected = 0;
+
+    public int getSelected() {
+        return selected;
+    }
+
+    public void setSelected(int selected) {
+        this.selected = selected;
+    }
+
+    public Set getProperties() {
+        return properties;
+    }
+
+    public Validator getSelectedValidator() {
+        return (Validator) validators.get(selected);
+    }
+
+    public String execute() throws Exception {
+        loadValidators();
+        Validator validator = getSelectedValidator();
+        properties = new TreeSet();
+        try {
+            Map context = Ognl.createDefaultContext(validator);
+            BeanInfo beanInfoFrom = null;
+            try {
+                beanInfoFrom = Introspector.getBeanInfo(validator.getClass(), Object.class);
+            } catch (IntrospectionException e) {
+                log.error("An error occurred", e);
+                addActionError("An error occurred while introspecting a validator of type " + validator.getClass().getName());
+                return ERROR;
+            }
+
+            PropertyDescriptor[] pds = beanInfoFrom.getPropertyDescriptors();
+
+            for (int i = 0; i < pds.length; i++) {
+                PropertyDescriptor pd = pds[i];
+                String name = pd.getName();
+                try {
+                    Object expr = OgnlUtil.compile(name);
+                    Object value = Ognl.getValue(expr, context, validator);
+                    properties.add(new PropertyInfo(name,pd.getPropertyType(),value));
+                } catch (OgnlException e) {
+                    addActionError("Caught OGNL exception while getting property value for '" + name + "' on validator of type " + validator.getClass().getName());
+                }
+            }
+        } catch (Exception e) {
+            log.warn("Unable to retrieve properties.",e);
+            addActionError("Unable to retrieve properties: " + e.toString());
+        }
+
+        if (hasErrors())
+            return ERROR;
+        else
+            return SUCCESS;
+    }
+
+    public static class PropertyInfo implements Comparable {
+        private String name;
+        private Class type;
+        private Object value;
+
+        public PropertyInfo(String name, Class type, Object value) {
+            if (name == null) {
+                throw new IllegalArgumentException("Name must not be null");
+            }
+            if (type == null) {
+                throw new IllegalArgumentException("Type must not be null");
+            }
+            this.name = name;
+            this.type = type;
+            this.value = value;
+        }
+
+        public Class getType() {
+            return type;
+        }
+
+        public void setType(Class type) {
+            this.type = type;
+        }
+
+        public Object getValue() {
+            return value;
+        }
+
+        public void setValue(Object value) {
+            this.value = value;
+        }
+
+        public String getName() {
+            return name;
+        }
+
+        public void setName(String name) {
+            this.name = name;
+        }
+
+        public boolean equals(Object o) {
+            if (this == o) return true;
+            if (!(o instanceof PropertyInfo)) return false;
+
+            final PropertyInfo propertyInfo = (PropertyInfo) o;
+
+            if (!name.equals(propertyInfo.name)) return false;
+            if (!type.equals(propertyInfo.type)) return false;
+            if (value != null ? !value.equals(propertyInfo.value) : propertyInfo.value != null) return false;
+
+            return true;
+        }
+
+        public int hashCode() {
+            int result;
+            result = name.hashCode();
+            result = 29 * result + type.hashCode();
+            result = 29 * result + (value != null ? value.hashCode() : 0);
+            return result;
+        }
+
+        public int compareTo(Object o) {
+            PropertyInfo other = (PropertyInfo) o;
+            return this.name.compareTo(other.name);
+        }
+    }
+}

src/config-browser/config-browser.xml

         
 		<global-results>
 			<result name="error" type="velocity">/error.vm</result>
+			<result name="input" type="velocity">/error.vm</result>
 		</global-results>
 
 		<action name="actionNames" class="com.opensymphony.webwork.config_browser.ActionNamesAction">
 
 		<action name="showConfig" class="com.opensymphony.webwork.config_browser.ShowConfigAction">
 			<result type="velocity" name="success">/showConfig.vm</result>
-		</action> 
+		</action>
+
+        <action name="showValidators" class="com.opensymphony.webwork.config_browser.ListValidatorsAction">
+            <result name="error" type="velocity">/simple-error.vm</result>
+			<result name="input" type="velocity">/simple-error.vm</result>
+			<result type="velocity" name="success">/showValidators.vm</result>
+		</action>
+
+        <action name="validatorDetails" class="com.opensymphony.webwork.config_browser.ShowValidatorAction">
+			<result type="velocity" name="success">/validatorDetails.vm</result>
+		</action>
     </package>
 </xwork>

src/config-browser/config-styles.css

+<style type="text/css">
+	/* colors, backgrounds, borders, link indication */
+body {
+	background: #fff;
+	color: #000;
+}
+
+.app h3, .app h4, .tabs td, .tabs th, .functnbar {
+	background-image: url(../images/nw_maj_rond.gif);
+	background-repeat: no-repeat;
+}
+
+.functnbar, .functnbar2 {
+	background-color: #aaa;
+}
+
+.functnbar2, .functnbar3 {
+	background-color: #aaa;
+	background-image: url(../images/sw_maj_rond.gif);
+	background-repeat: no-repeat;
+	background-position: bottom left;
+}
+
+.functnbar3 {
+	background-color: #ddd;
+	background-image: url(../images/sw_med_rond.gif);
+}
+
+.functnbar, .functnbar2, .functnbar3 {
+	color: #000;
+}
+
+.functnbar a, .functnbar2 a, .functnbar3 a {
+	color: #000;
+	text-decoration: underline;
+}
+
+#navcolumn .body div, body.docs #toc li li {
+	background-image: url(../images/strich.gif);
+	background-repeat: no-repeat;
+	background-position: .5em .5em;
+}
+
+#searchbox .body div, #navcolumn .body .heading {
+	background-image: none;
+}
+
+a:link, #navcolumn a:visited, .app a:visited, .tasknav a:visited {
+	color: blue;
+}
+
+a:link.selfref, a:visited.selfref {
+	color: #555 !important;
+	text-decoration: none;
+}
+
+a:active, a:hover, #leftcol a:active, #leftcol a:hover {
+	color: #f30 !important;
+}
+
+#leftcol a, #breadcrumbs a {
+	text-decoration: none;
+}
+
+.app h3, .app h4 {
+	color: #fff;
+}
+
+.app h3 {
+	background-color: #333;
+}
+
+.app h3 a:link, .app h3 a:visited, .app h4 a:link, .app h4 a:visited {
+	color: #fff !important;
+	text-decoration: underline;
+}
+
+.app h4 {
+	background-color: #888;
+}
+
+.a td {
+	background: #ddd;
+}
+
+.b td {
+	background: #efefef;
+}
+
+table, th, td {
+	border: none;
+}
+
+div.colbar {
+	background: #eee;
+	border-color: #999 #EEE #EEE #999;
+	border-width: 1px;
+	border-style: solid;
+}
+
+.toolgroup {
+	background: #efefef;
+}
+
+.toolgroup .label {
+	border-bottom: 1px solid #666;
+	border-right: 1px solid #666;
+	background: #ddd;
+	color: #555;
+}
+
+.toolgroup .body {
+	border-right: 1px solid #aaa;
+	border-bottom: 1px solid #aaa;
+}
+
+#breadcrumbs {
+	border-top: 1px solid #fff;
+	background-color: #ccc;
+}
+
+#main {
+	border-top: 1px solid #999;
+}
+
+#rightcol div.www, #rightcol div.help {
+	border: 1px solid #ddd;
+}
+
+body.docs div.docs {
+	background-color: #fff;
+	border-left: 1px solid #ddd;
+	border-top: 1px solid #ddd;
+}
+
+#helptext .label {
+	background-image: url(../images/icon_help_sml.gif);
+	background-repeat: no-repeat;
+	background-position: 97%;
+}
+
+body.docs {
+	background: #eee url(../images/help_logo.gif) top right no-repeat !important;
+}
+
+.docs h3, .docs h4 {
+	border-top: solid 1px #000;
+}
+
+#apphead h2 em {
+	color: #777;
+}
+
+.app th {
+	background-color: #bbb;
+}
+
+.tabs th {
+	border-right: 1px solid #333;
+	background-color: #ddd;
+	color: #fff;
+	border-left: 1px solid #fff;
+}
+
+.tabs td {
+	background-color: #999;
+	border-bottom: 1px solid #fff;
+	border-right: 1px solid #fff;
+	border-left: 1px solid #fff;
+}
+
+.tabs {
+	border-bottom: 6px #ddd solid;
+}
+
+.tabs th, .tabs th a:link, .tabs th a:visited {
+	color: #555;
+}
+
+.tabs td, .tabs td a:link, .tabs td a:visited {
+	color: #fff;
+}
+
+.tabs a {
+	text-decoration: none;
+}
+
+.axial th {
+	background-color: #ddd;
+	color: black;
+}
+
+.alert {
+	background-color: #ff9;
+}
+
+.expandedwaste {
+	background: url(../images/icon_arrowwaste2_sml.gif) no-repeat;
+}
+
+.collapsedwaste {
+	background: url(../images/icon_arrowwaste1_sml.gif) no-repeat;
+}
+
+.filebrowse .expanded, .filebrowse-alt .expanded {
+	background-image: url(../images/icon_arrowfolderopen2_sml.gif);
+	background-repeat: no-repeat;
+}
+
+.filebrowse .collapsed, .filebrowse-alt .collapsed {
+	background-image: url(../images/icon_arrowfolderclosed1_sml.gif);
+	background-repeat: no-repeat;
+}
+
+.filebrowse .leafnode, .filebrowse-alt .leafnode {
+	background-image: url(../images/icon_folder_sml.gif);
+	background-repeat: no-repeat;
+}
+
+.filebrowse .leaf, .filebrowse-alt .leaf {
+	background-image: url(../images/icon_doc_sml.gif);
+	background-repeat: no-repeat;
+}
+
+.sortup {
+	background: url(../images/icon_sortup.gif) no-repeat;
+}
+
+.sortdown {
+	background: url(../images/icon_sortdown.gif) no-repeat;
+}
+
+.collapsedwaste {
+	background: url(../images/icon_arrowwaste1_sml.gif) no-repeat;
+}
+
+body .grid td {
+	border-top: 1px solid #ccc;
+	border-left: 1px solid #ccc;
+	background-color: transparent;
+}
+
+.confirm {
+	color: #090;
+}
+
+.info {
+	color: #069;
+}
+
+.errormessage, .warningmessage, .donemessage, .infomessage {
+	border-top: 5px solid #900;
+	border-left: 1px solid #900;
+	background-image: url(../images/icon_error_lrg.gif);
+	background-repeat: no-repeat;
+	background-position: 5px 1.33em;
+}
+
+.warningmessage {
+	background-image: url(../images/icon_warning_lrg.gif);
+	border-color: #c60;
+}
+
+.donemessage {
+	background-image: url(../images/icon_success_lrg.gif);
+	border-color: #090;
+}
+
+.infomessage {
+	background-image: url(../images/icon_info_lrg.gif);
+	border-color: #069;
+}
+
+.docinfo {
+	background: url(../images/icon_doc_lrg.gif) no-repeat;
+}
+
+.dirinfo {
+	background: url(../images/icon_folder_lrg.gif) no-repeat;
+}
+
+.memberinfo {
+	background: url(../images/icon_members_lrg.gif) no-repeat;
+}
+
+.usergroupinfo {
+	background: url(../images/icon_usergroups_lrg.gif) no-repeat;
+}
+
+.errormark, .warningmark, .donemark, .infomark {
+	background: url(../images/icon_error_sml.gif) no-repeat;
+}
+
+.warningmark {
+	background-image: url(../images/icon_warning_sml.gif);
+}
+
+.donemark {
+	background-image: url(../images/icon_success_sml.gif);
+}
+
+.infomark {
+	background-image: url(../images/icon_info_sml.gif);
+}
+
+.cvsdiff, .cvsblame {
+	background-color: #ccc;
+}
+
+.cvsdiffadd {
+	background-color: #afa;
+}
+
+.cvsdiffremove {
+	background-color: #faa;
+}
+
+.cvsdiffchanges1 {
+	background-color: #ff7;
+}
+
+.cvsdiffchanges2 {
+	background-color: #ff7;
+}
+
+li.selection ul a {
+	background: #fff;
+}
+
+.band1 {
+	color: #fff;
+	background-color: #663;
+}
+
+.band2 {
+	color: #fff;
+	background-color: #66C;
+}
+
+.band3 {
+	background-color: #C99;
+}
+
+.band4 {
+	background-color: #CFF;
+}
+
+.band5 {
+	color: #fff;
+	background-color: #336;
+}
+
+.band6 {
+	color: #fff;
+	background-color: #966;
+}
+
+.band7 {
+	background-color: #9CC;
+}
+
+.band8 {
+	background-color: #FFC;
+}
+
+.band9 {
+	color: #fff;
+	background-color: #633;
+}
+
+.band10 {
+	color: #fff;
+	background-color: #699;
+}
+
+.band11 {
+	background-color: #CC9;
+}
+
+.band12 {
+	background-color: #CCF;
+}
+
+.band13 {
+	color: #fff;
+	background-color: #366;
+}
+
+.band14 {
+	color: #fff;
+	background-color: #996;
+}
+
+.band15 {
+	background-color: #99C;
+}
+
+.band16 {
+	background-color: #FCC;
+}
+
+.app .helplink, #helptext .helplink {
+	cursor: help;
+}
+
+.legend th, .bars th {
+	background-color: #fff;
+}
+
+/* font and text properties, exclusive of link indication, alignment, text-indent */
+body, th, td, input, select {
+	font-family: Verdana, Helvetica, Arial, sans-serif;
+}
+
+code, pre {
+	font-family: 'Andale Mono', Courier, monospace;
+}
+
+body, .app h3, .app h4, #rightcol h3, pre, code, #apphead h2 small {
+	font-size: x-small;
+	voice-family: "\"}\"";
+	voice-family: inherit;
+	font-size: small;
+}
+
+small, div#footer, div#login, div.tabs th, div.tabs td, input, select, .paginate, .functnbar, .functnbar2, .functnbar3, #breadcrumbs, .courtesylinks, #rightcol div.help, .colbar, .tasknav, body.docs div#toc, #leftcol, .legend, .bars {
+	font-size: xx-small;
+	voice-family: "\"}\"";
+	voice-family: inherit;
+	font-size: x-small;
+}
+
+.tabs td, .tabs th, dt, .tasknav .selfref, #login .username, .selection {
+	font-weight: bold;
+}
+
+li.selection ul {
+	font-weight: normal;
+}
+
+h4, table {
+	font-size: 1em;
+}
+
+#apphead h2 em {
+	font-style: normal;
+}
+
+#banner h1 {
+	font-size: 1.25em;
+}
+
+/* box properties (exclusive of borders), positioning, alignments, list types, text-indent */
+#bodycol h2 {
+	margin-top: .3em;
+	margin-bottom: .5em;
+}
+
+p, ul, ol, dl, .bars table {
+	margin-top: .67em;
+	margin-bottom: .67em;
+}
+
+h3, h4 {
+	margin-bottom: 0;
+}
+
+form {
+	margin: 0;
+}
+
+#bodycol {
+	padding-left: 12px;
+	padding-right: 12px;
+	width: 100%;
+	voice-family: "\"}\"";
+	voice-family: inherit;
+	width: auto;
+}
+
+html>body #bodycol {
+	width: auto;
+}
+
+.docs {
+	line-height: 1.4;
+}
+
+ol ol {
+	list-style-type: lower-alpha;
+}
+
+ol ol ol {
+	list-style-type: lower-roman;
+}
+
+.app h3, .app h4 {
+	padding: 5px;
+	margin-right: 2px;
+	margin-left: 2px;
+}
+
+.app td, .app th {
+	padding: 2px 3px;
+}
+
+.h3 p, .h4 p, .h3 dt, .h4 dt {
+	margin-right: 7px;
+	margin-left: 7px;
+}
+
+.tasknav {
+	margin-bottom: 1.33em;
+}
+
+div.colbar {
+	padding: 3px;
+	margin: 2px 2px 0;
+}
+
+.tabs {
+	margin-top: .67em;
+	margin-right: 2px;
+	margin-left: 2px;
+	padding-left: 8px;
+}
+
+.tabs td, .tabs th {
+	padding: 3px 9px;
+}
+
+#rightcol div.www, #rightcol div.help {
+	padding: 0 .5em;
+}
+
+body.docs #toc {
+	position: absolute;
+	top: 15px;
+	left: 0px;
+	width: 120px;
+	padding: 0 20px 0 0;
+}
+
+body.docs #toc ul, #toc ol {
+	margin-left: 0;
+	padding-left: 0;
+}
+
+body.docs #toc li {
+	margin-top: 7px;
+	padding-left: 10px;
+	list-style-type: none;
+}
+
+body.docs div.docs {
+	margin: 61px 0 0 150px;
+	padding: 1em 2em 1em 1em !important;
+}
+
+.docs p+p {
+	text-indent: 5%;
+	margin-top: -.67em;
+}
+
+.docs h3, .docs h4 {
+	margin-bottom: .1em;
+	padding-top: .3em;
+}
+
+.functnbar, .functnbar2, .functnbar3 {
+	padding: 5px;
+	margin: .67em 2px;
+}
+
+.functnbar3 {
+	margin-top: 0;
+}
+
+body {
+	padding: 1em;
+}
+
+body.composite, body.docs {
+	margin: 0;
+	padding: 0;
+}
+
+th, td {
+	text-align: left;
+	vertical-align: top;
+}
+
+.right {
+	text-align: right !important;
+}
+
+.center {
+	text-align: center !important;
+}
+
+.axial th, .axial th .strut {
+	text-align: right;
+}
+
+.app .axial td th {
+	text-align: left;
+}
+
+body .stb {
+	margin-top: 1em;
+	text-indent: 0;
+}
+
+body .mtb {
+	margin-top: 2em;
+	text-indent: 0;
+}
+
+.courtesylinks {
+	margin-top: 1em;
+	padding-top: 1em;
+}
+
+dd {
+	margin-bottom: .67em;
+}
+
+.toolgroup {
+	margin-bottom: 6px;
+}
+
+.toolgroup .body {
+	padding: 4px 4px 4px 0;
+}
+
+.toolgroup .label {
+	padding: 4px;
+}
+
+.toolgroup .body div {
+	padding-bottom: .3em;
+	padding-left: 1em;
+}
+
+.toolgroup .body div div {
+	margin-top: .3em;
+	padding-bottom: 0;
+}
+
+.tier1 {
+	margin-left: 0;
+}
+
+.tier2 {
+	margin-left: 1.5em;
+}
+
+.tier3 {
+	margin-left: 3em;
+}
+
+.tier4 {
+	margin-left: 4.5em;
+}
+
+.tier5 {
+	margin-left: 6em;
+}
+
+.tier6 {
+	margin-left: 7.5em;
+}
+
+.tier7 {
+	margin-left: 9em;
+}
+
+.tier8 {
+	margin-left: 10.5em;
+}
+
+.tier9 {
+	margin-left: 12em;
+}
+
+.tier10 {
+	margin-left: 13.5em;
+}
+
+.filebrowse .expanded, .filebrowse .collapsed {
+	padding-left: 34px;
+}
+
+.filebrowse .leafnode, .filebrowse .leaf {
+	padding-left: 20px;
+}
+
+.messagechild {
+	padding-left: 34px;
+}
+
+.filebrowse-alt .expanded, .filebrowse-alt .collapsed, .filebrowse-alt .leaf, .filebrowse-alt .leafnode, .expandedwaste, .collapsedwaste, .sortup, .sortdown {
+	/* hide from macie5\*/
+	float: left;
+	/* resume */
+	display: inline-block;
+	height: 15px;
+	width: 34px;
+	padding-left: 0 !important;
+}
+
+.filebrowse-alt .leaf, .filebrowse-alt .leafnode, .sortup, .sortdown {
+	width: 20px;
+}
+
+.filebrowse ul, .filebrowse-alt ul {
+	list-style-type: none;
+	padding-left: 0;
+	margin-left: 0;
+}
+
+.filebrowse ul ul, .filebrowse-alt ul ul {
+	margin-left: 1.5em;
+	margin-top: 0;
+	padding-top: .67em;
+}
+
+.filebrowse li, .filebrowse-alt li {
+	margin-bottom: .67em;
+}
+
+td.filebrowse h3 {
+	margin-top: 0;
+}
+
+.errormessage, .warningmessage, .donemessage, .infomessage, .docinfo, .dirinfo, .memberinfo, .usergroupinfo {
+	margin: .67em 0;
+	padding: .33em 0 .67em 42px;
+	min-height: 32px;
+}
+
+.errormark, .warningmark, .donemark, .infomark {
+	padding-left: 20px;
+	min-height: 15px;
+}
+
+.alt {
+	display: none;
+}
+
+#banner h1 {
+	margin: 0;
+}
+
+#leftcol {
+	width: 14em;
+}
+
+.axial th, .axial th .strut, #leftcol .strut {
+	width: 12em;
+}
+
+#breadcrumbs {
+	padding: 2px 8px;
+}
+
+.app h3, .app h4, .bars {
+	clear: both;
+}
+
+.legend {
+	float: right;
+}
+
+.legend th, .bars th {
+	text-align: right;
+	padding-left: 1em;
+}
+
+.bars table {
+	table-layout: fixed;
+}
+
+.bars th {
+	width: 12em;
+}
+
+#projectdocumentlist td.filebrowse-alt {
+	padding-right: .75em;
+}
+
+</style>

src/config-browser/page-header.vm

 <head>
 <title>$pageTitle</title>
 <meta http-equiv="Content-type" content="text/html; charset=ISO-8859-1" />
-<style type="text/css">
-	/* colors, backgrounds, borders, link indication */
-body {
-	background: #fff;
-	color: #000;
-}
-
-.app h3, .app h4, .tabs td, .tabs th, .functnbar {
-	background-image: url(../images/nw_maj_rond.gif);
-	background-repeat: no-repeat;
-}
-
-.functnbar, .functnbar2 {
-	background-color: #aaa;
-}
-
-.functnbar2, .functnbar3 {
-	background-color: #aaa;
-	background-image: url(../images/sw_maj_rond.gif);
-	background-repeat: no-repeat;
-	background-position: bottom left;
-}
-
-.functnbar3 {
-	background-color: #ddd;
-	background-image: url(../images/sw_med_rond.gif);
-}
-
-.functnbar, .functnbar2, .functnbar3 {
-	color: #000;
-}
-
-.functnbar a, .functnbar2 a, .functnbar3 a {
-	color: #000;
-	text-decoration: underline;
-}
-
-#navcolumn .body div, body.docs #toc li li {
-	background-image: url(../images/strich.gif);
-	background-repeat: no-repeat;
-	background-position: .5em .5em;
-}
-
-#searchbox .body div, #navcolumn .body .heading {
-	background-image: none;
-}
-
-a:link, #navcolumn a:visited, .app a:visited, .tasknav a:visited {
-	color: blue;
-}
-
-a:link.selfref, a:visited.selfref {
-	color: #555 !important;
-	text-decoration: none;
-}
-
-a:active, a:hover, #leftcol a:active, #leftcol a:hover {
-	color: #f30 !important;
-}
-
-#leftcol a, #breadcrumbs a {
-	text-decoration: none;
-}
-
-.app h3, .app h4 {
-	color: #fff;
-}
-
-.app h3 {
-	background-color: #333;
-}
-
-.app h3 a:link, .app h3 a:visited, .app h4 a:link, .app h4 a:visited {
-	color: #fff !important;
-	text-decoration: underline;
-}
-
-.app h4 {
-	background-color: #888;
-}
-
-.a td {
-	background: #ddd;
-}
-
-.b td {
-	background: #efefef;
-}
-
-table, th, td {
-	border: none;
-}
-
-div.colbar {
-	background: #eee;
-	border-color: #999 #EEE #EEE #999;
-	border-width: 1px;
-	border-style: solid;
-}
-
-.toolgroup {
-	background: #efefef;
-}
-
-.toolgroup .label {
-	border-bottom: 1px solid #666;
-	border-right: 1px solid #666;
-	background: #ddd;
-	color: #555;
-}
-
-.toolgroup .body {
-	border-right: 1px solid #aaa;
-	border-bottom: 1px solid #aaa;
-}
-
-#breadcrumbs {
-	border-top: 1px solid #fff;
-	background-color: #ccc;
-}
-
-#main {
-	border-top: 1px solid #999;
-}
-
-#rightcol div.www, #rightcol div.help {
-	border: 1px solid #ddd;
-}
-
-body.docs div.docs {
-	background-color: #fff;
-	border-left: 1px solid #ddd;
-	border-top: 1px solid #ddd;
-}
-
-#helptext .label {
-	background-image: url(../images/icon_help_sml.gif);
-	background-repeat: no-repeat;
-	background-position: 97%;
-}
-
-body.docs {
-	background: #eee url(../images/help_logo.gif) top right no-repeat !important;
-}
-
-.docs h3, .docs h4 {
-	border-top: solid 1px #000;
-}
-
-#apphead h2 em {
-	color: #777;
-}
-
-.app th {
-	background-color: #bbb;
-}
-
-.tabs th {
-	border-right: 1px solid #333;
-	background-color: #ddd;
-	color: #fff;
-	border-left: 1px solid #fff;
-}
-
-.tabs td {
-	background-color: #999;
-	border-bottom: 1px solid #fff;
-	border-right: 1px solid #fff;
-	border-left: 1px solid #fff;
-}
-
-.tabs {
-	border-bottom: 6px #ddd solid;
-}
-
-.tabs th, .tabs th a:link, .tabs th a:visited {
-	color: #555;
-}
-
-.tabs td, .tabs td a:link, .tabs td a:visited {
-	color: #fff;
-}
-
-.tabs a {
-	text-decoration: none;
-}
-
-.axial th {
-	background-color: #ddd;
-	color: black;
-}
-
-.alert {
-	background-color: #ff9;
-}
-
-.expandedwaste {
-	background: url(../images/icon_arrowwaste2_sml.gif) no-repeat;
-}
-
-.collapsedwaste {
-	background: url(../images/icon_arrowwaste1_sml.gif) no-repeat;
-}
-
-.filebrowse .expanded, .filebrowse-alt .expanded {
-	background-image: url(../images/icon_arrowfolderopen2_sml.gif);
-	background-repeat: no-repeat;
-}
-
-.filebrowse .collapsed, .filebrowse-alt .collapsed {
-	background-image: url(../images/icon_arrowfolderclosed1_sml.gif);
-	background-repeat: no-repeat;
-}
-
-.filebrowse .leafnode, .filebrowse-alt .leafnode {
-	background-image: url(../images/icon_folder_sml.gif);
-	background-repeat: no-repeat;
-}
-
-.filebrowse .leaf, .filebrowse-alt .leaf {
-	background-image: url(../images/icon_doc_sml.gif);
-	background-repeat: no-repeat;
-}
-
-.sortup {
-	background: url(../images/icon_sortup.gif) no-repeat;
-}
-
-.sortdown {
-	background: url(../images/icon_sortdown.gif) no-repeat;
-}
-
-.collapsedwaste {
-	background: url(../images/icon_arrowwaste1_sml.gif) no-repeat;
-}
-
-body .grid td {
-	border-top: 1px solid #ccc;
-	border-left: 1px solid #ccc;
-	background-color: transparent;
-}
-
-.confirm {
-	color: #090;
-}
-
-.info {
-	color: #069;
-}
-
-.errormessage, .warningmessage, .donemessage, .infomessage {
-	border-top: 5px solid #900;
-	border-left: 1px solid #900;
-	background-image: url(../images/icon_error_lrg.gif);
-	background-repeat: no-repeat;
-	background-position: 5px 1.33em;
-}
-
-.warningmessage {
-	background-image: url(../images/icon_warning_lrg.gif);
-	border-color: #c60;
-}
-
-.donemessage {
-	background-image: url(../images/icon_success_lrg.gif);
-	border-color: #090;
-}
-
-.infomessage {
-	background-image: url(../images/icon_info_lrg.gif);
-	border-color: #069;
-}
-
-.docinfo {
-	background: url(../images/icon_doc_lrg.gif) no-repeat;
-}
-
-.dirinfo {
-	background: url(../images/icon_folder_lrg.gif) no-repeat;
-}
-
-.memberinfo {
-	background: url(../images/icon_members_lrg.gif) no-repeat;
-}
-
-.usergroupinfo {
-	background: url(../images/icon_usergroups_lrg.gif) no-repeat;
-}
-
-.errormark, .warningmark, .donemark, .infomark {
-	background: url(../images/icon_error_sml.gif) no-repeat;
-}
-
-.warningmark {
-	background-image: url(../images/icon_warning_sml.gif);
-}
-
-.donemark {
-	background-image: url(../images/icon_success_sml.gif);
-}
-
-.infomark {
-	background-image: url(../images/icon_info_sml.gif);
-}
-
-.cvsdiff, .cvsblame {
-	background-color: #ccc;
-}
-
-.cvsdiffadd {
-	background-color: #afa;
-}
-
-.cvsdiffremove {
-	background-color: #faa;
-}
-
-.cvsdiffchanges1 {
-	background-color: #ff7;
-}
-
-.cvsdiffchanges2 {
-	background-color: #ff7;
-}
-
-li.selection ul a {
-	background: #fff;
-}
-
-.band1 {
-	color: #fff;
-	background-color: #663;
-}
-
-.band2 {
-	color: #fff;
-	background-color: #66C;
-}
-
-.band3 {
-	background-color: #C99;
-}
-
-.band4 {
-	background-color: #CFF;
-}
-
-.band5 {
-	color: #fff;
-	background-color: #336;
-}
-
-.band6 {
-	color: #fff;
-	background-color: #966;
-}
-
-.band7 {
-	background-color: #9CC;
-}
-
-.band8 {
-	background-color: #FFC;
-}
-
-.band9 {
-	color: #fff;
-	background-color: #633;
-}
-
-.band10 {
-	color: #fff;
-	background-color: #699;
-}
-
-.band11 {
-	background-color: #CC9;
-}
-
-.band12 {
-	background-color: #CCF;
-}
-
-.band13 {
-	color: #fff;
-	background-color: #366;
-}
-
-.band14 {
-	color: #fff;
-	background-color: #996;
-}
-
-.band15 {
-	background-color: #99C;
-}
-
-.band16 {
-	background-color: #FCC;
-}
-
-.app .helplink, #helptext .helplink {
-	cursor: help;
-}
-
-.legend th, .bars th {
-	background-color: #fff;
-}
-
-/* font and text properties, exclusive of link indication, alignment, text-indent */
-body, th, td, input, select {
-	font-family: Verdana, Helvetica, Arial, sans-serif;
-}
-
-code, pre {
-	font-family: 'Andale Mono', Courier, monospace;
-}
-
-body, .app h3, .app h4, #rightcol h3, pre, code, #apphead h2 small {
-	font-size: x-small;
-	voice-family: "\"}\"";
-	voice-family: inherit;
-	font-size: small;
-}
-
-small, div#footer, div#login, div.tabs th, div.tabs td, input, select, .paginate, .functnbar, .functnbar2, .functnbar3, #breadcrumbs, .courtesylinks, #rightcol div.help, .colbar, .tasknav, body.docs div#toc, #leftcol, .legend, .bars {
-	font-size: xx-small;
-	voice-family: "\"}\"";
-	voice-family: inherit;
-	font-size: x-small;
-}
-
-.tabs td, .tabs th, dt, .tasknav .selfref, #login .username, .selection {
-	font-weight: bold;
-}
-
-li.selection ul {
-	font-weight: normal;
-}
-
-h4, table {
-	font-size: 1em;
-}
-
-#apphead h2 em {
-	font-style: normal;
-}
-
-#banner h1 {
-	font-size: 1.25em;
-}
-
-/* box properties (exclusive of borders), positioning, alignments, list types, text-indent */
-#bodycol h2 {
-	margin-top: .3em;
-	margin-bottom: .5em;
-}
-
-p, ul, ol, dl, .bars table {
-	margin-top: .67em;
-	margin-bottom: .67em;
-}
-
-h3, h4 {
-	margin-bottom: 0;
-}
-
-form {
-	margin: 0;
-}
-
-#bodycol {
-	padding-left: 12px;
-	padding-right: 12px;
-	width: 100%;
-	voice-family: "\"}\"";
-	voice-family: inherit;
-	width: auto;
-}
-
-html>body #bodycol {
-	width: auto;
-}
-
-.docs {
-	line-height: 1.4;
-}
-
-ol ol {
-	list-style-type: lower-alpha;
-}
-
-ol ol ol {
-	list-style-type: lower-roman;
-}
-
-.app h3, .app h4 {
-	padding: 5px;
-	margin-right: 2px;
-	margin-left: 2px;
-}
-
-.app td, .app th {
-	padding: 2px 3px;
-}
-
-.h3 p, .h4 p, .h3 dt, .h4 dt {
-	margin-right: 7px;
-	margin-left: 7px;
-}
-
-.tasknav {
-	margin-bottom: 1.33em;
-}
-
-div.colbar {
-	padding: 3px;
-	margin: 2px 2px 0;
-}
-
-.tabs {
-	margin-top: .67em;
-	margin-right: 2px;
-	margin-left: 2px;
-	padding-left: 8px;
-}
-
-.tabs td, .tabs th {
-	padding: 3px 9px;
-}
-
-#rightcol div.www, #rightcol div.help {
-	padding: 0 .5em;
-}
-
-body.docs #toc {
-	position: absolute;
-	top: 15px;
-	left: 0px;
-	width: 120px;
-	padding: 0 20px 0 0;
-}
-
-body.docs #toc ul, #toc ol {
-	margin-left: 0;
-	padding-left: 0;
-}
-
-body.docs #toc li {
-	margin-top: 7px;
-	padding-left: 10px;
-	list-style-type: none;
-}
-
-body.docs div.docs {
-	margin: 61px 0 0 150px;
-	padding: 1em 2em 1em 1em !important;
-}
-
-.docs p+p {
-	text-indent: 5%;
-	margin-top: -.67em;
-}
-
-.docs h3, .docs h4 {
-	margin-bottom: .1em;
-	padding-top: .3em;
-}
-
-.functnbar, .functnbar2, .functnbar3 {
-	padding: 5px;
-	margin: .67em 2px;
-}
-
-.functnbar3 {
-	margin-top: 0;
-}
-
-body {
-	padding: 1em;
-}
-
-body.composite, body.docs {
-	margin: 0;
-	padding: 0;
-}
-
-th, td {
-	text-align: left;
-	vertical-align: top;
-}
-
-.right {
-	text-align: right !important;
-}
-
-.center {
-	text-align: center !important;
-}
-
-.axial th, .axial th .strut {
-	text-align: right;
-}
-
-.app .axial td th {
-	text-align: left;
-}
-
-body .stb {
-	margin-top: 1em;
-	text-indent: 0;
-}
-
-body .mtb {
-	margin-top: 2em;
-	text-indent: 0;
-}
-
-.courtesylinks {
-	margin-top: 1em;
-	padding-top: 1em;
-}
-
-dd {
-	margin-bottom: .67em;
-}
-
-.toolgroup {
-	margin-bottom: 6px;
-}
-
-.toolgroup .body {
-	padding: 4px 4px 4px 0;
-}
-
-.toolgroup .label {
-	padding: 4px;
-}
-
-.toolgroup .body div {
-	padding-bottom: .3em;
-	padding-left: 1em;
-}
-
-.toolgroup .body div div {
-	margin-top: .3em;
-	padding-bottom: 0;
-}
-
-.tier1 {
-	margin-left: 0;
-}
-
-.tier2 {
-	margin-left: 1.5em;
-}
-
-.tier3 {
-	margin-left: 3em;
-}
-
-.tier4 {
-	margin-left: 4.5em;
-}
-
-.tier5 {
-	margin-left: 6em;
-}
-
-.tier6 {
-	margin-left: 7.5em;
-}
-
-.tier7 {
-	margin-left: 9em;
-}
-
-.tier8 {
-	margin-left: 10.5em;
-}
-
-.tier9 {
-	margin-left: 12em;
-}
-
-.tier10 {
-	margin-left: 13.5em;
-}
-
-.filebrowse .expanded, .filebrowse .collapsed {
-	padding-left: 34px;
-}
-
-.filebrowse .leafnode, .filebrowse .leaf {
-	padding-left: 20px;
-}
-
-.messagechild {
-	padding-left: 34px;
-}
-
-.filebrowse-alt .expanded, .filebrowse-alt .collapsed, .filebrowse-alt .leaf, .filebrowse-alt .leafnode, .expandedwaste, .collapsedwaste, .sortup, .sortdown {
-	/* hide from macie5\*/
-	float: left;
-	/* resume */
-	display: inline-block;
-	height: 15px;
-	width: 34px;
-	padding-left: 0 !important;
-}
-
-.filebrowse-alt .leaf, .filebrowse-alt .leafnode, .sortup, .sortdown {
-	width: 20px;
-}
-
-.filebrowse ul, .filebrowse-alt ul {
-	list-style-type: none;
-	padding-left: 0;
-	margin-left: 0;
-}
-
-.filebrowse ul ul, .filebrowse-alt ul ul {
-	margin-left: 1.5em;
-	margin-top: 0;
-	padding-top: .67em;
-}
-
-.filebrowse li, .filebrowse-alt li {
-	margin-bottom: .67em;
-}
-
-td.filebrowse h3 {
-	margin-top: 0;
-}
-
-.errormessage, .warningmessage, .donemessage, .infomessage, .docinfo, .dirinfo, .memberinfo, .usergroupinfo {
-	margin: .67em 0;
-	padding: .33em 0 .67em 42px;
-	min-height: 32px;
-}
-
-.errormark, .warningmark, .donemark, .infomark {
-	padding-left: 20px;
-	min-height: 15px;
-}
-
-.alt {
-	display: none;
-}
-
-#banner h1 {
-	margin: 0;
-}
-
-#leftcol {
-	width: 14em;
-}
-
-.axial th, .axial th .strut, #leftcol .strut {
-	width: 12em;
-}
-
-#breadcrumbs {
-	padding: 2px 8px;
-}
-
-.app h3, .app h4, .bars {
-	clear: both;
-}
-
-.legend {
-	float: right;
-}
-
-.legend th, .bars th {
-	text-align: right;
-	padding-left: 1em;
-}
-
-.bars table {
-	table-layout: fixed;
-}
-
-.bars th {
-	width: 12em;
-}
-
-#projectdocumentlist td.filebrowse-alt {
-	padding-right: .75em;
-}
-
-</style>
+#include ("/config-styles.css")
 </head>
 <body class="composite" marginwidth="0" marginheight="0" leftmargin="0" topmargin="0">
 
-<div id="banner">
-	<table border="0" cellspacing="0" cellpadding="8" width="100%">
-		<tr>
-			<td>
-				<!-- Placeholder for logo -->
-			</td>
-
-			<td valign="center">
-			</td>
-			<td>
-				<div align="right" id="login">
-					<div>
-						<!-- Logged in area -->
-					</div>
-					<div>
-						<!--<a href="logout.action">Logout</a>-->
-					</div>
-				</div>
-			</td>
-		</tr>
-	</table>
-</div>
-
 <div id="breadcrumbs">
 	<table border="0" cellspacing="0" cellpadding="4" width="100%">
 		<tr>
   
 <table border="0" cellspacing="0" cellpadding="4" width="100%" id="main">
 	<tr valign="top">
+	    #if (!$hideNav)
 		<td id="leftcol" width="20%">
 			<div id="navcolumn">
 				## Quick hack to show menu features :)
 				</div>
 			</div>
 		</td>
+		#end
 		<td>
 			<div id="bodycol">
 				<div id="apphead">
-					<h2><decorator:title default="Untitled page"/></h2>
+					<h2>$pageTitle</h2>
 				</div>
 				<div id="content" class="app">				

src/config-browser/showConfig.vm

 #set($detailsSelected = false)
 #set($interceptorsSelected = false)
 #set($propertiesSelected = false)
+#set($validatorsSelected = false)
 <!-- Set selected to true -->
 #if($detailView == "results")
 	#set($detailsSelected = true)
 #elseif($detailView == "interceptors")
 	#set($interceptorsSelected = true)
-#else
+#elseif($detailView == "properties")
 	#set($propertiesSelected = true)
+#else
+    #set($validatorsSelected = true)
 #end
 
 #startTabs()
 	#tab("Results" "${url}results" $detailsSelected)
 	#tab("Interceptors" "${url}interceptors" $interceptorsSelected)
 	#tab("Properties" "${url}properties" $propertiesSelected)
+	#tab("Validators" "${url}validators" $validatorsSelected)
 #endTabs()
 
 #if($detailsSelected)
     	#foreach ($r in $config.results)
     		#rows()
     			<td>$r.name</td>
-    			<td>$r.clazz.name</td>
+    			<td>$r.className</td>
     			<td>
     				#foreach ($name in $r.params.keySet())
     					$name = $r.params.get($name)<br>
     		</tr>
     	#end
     </table>
-#else
+#elseif ($propertiesSelected)
     <table width="100%">
         <tr><th>Name</th><th>Type</th></tr>
         #foreach ($prop in $properties)
     		</tr>
     	#end
     </table>
-
+#else
+    #bodytag (Action "name='showValidators'" "executeResult=true")
+        #param("clazz" "$config.className")
+        #param("context" "$actionName")
+    #end
 #end
 
 #endPage()

src/config-browser/showValidators.vm

+<!-- Validators -->
+<table width="100%">
+    <tr><th>Type</th><th>&nbsp;</th></tr>
+    #set ($row = 0)
+    #foreach ($i in $validators)
+        #rows()
+            <td>$action.stripPackage($i.class)</td>
+            <td>
+            <a href="#" onClick="window.open('validatorDetails.action?clazz=$clazz.name&context=$context&selected=$row', 'Validator Details', 'resizable=yes,toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=yes,width=640,height=480');">details</a>
+            </td>
+        </tr>
+        #set ($row = $row + 1)
+    #end
+</table>

src/config-browser/simple-error.vm

+#errorMessageMultiple("An error occured" "Unable to execute $action.class.name" $action.actionErrors)

src/config-browser/validatorDetails.vm

+#parse("/tigris-macros.vm")
+#set ($hideNav = true)
+#startPage("Validator Details")
+<table>
+<tr><td width="100%">
+#bodytag (Form)
+    #tag( Label "label='Validated Class'" "name='$action.stripPackage($clazz)'")
+    #tag( Label "label='Context'" "name='$context'")
+    #tag( Label "label='Validator Number'" "name='$selected'")
+    #tag( Label "label='Validator Type'" "name='$action.stripPackage($selectedValidator.class)'")
+#end
+</td><td style="text-align: right;"><!-- Placeholder for Action Graph --></td></tr>
+</table>
+<table width="100%" title="Properties">
+    <tr><th>Name</th><th>Value</th><th>Type</th></tr>
+    #foreach ($prop in $properties)
+        #rows()
+            <td>$prop.name</td>
+            <td>#if ($prop.value) $prop.value #else <b>null</b> #end</td>
+            <td>$prop.type.name</td>
+        </tr>
+    #end
+</table>
+#endPage()

src/etc/example/i18n.xml

                 <param name="location">shop.vm</param>
             </result>
         </action>
-        <action name="i18n.Cart" class="com.opensymphony.webwork.example.i18n.Cart">
-            <result name="success" type="velocity">
-                <param name="location">cart.vm</param>
-            </result>
-        </action>
+<!--        <action name="i18n.Cart" class="com.opensymphony.webwork.example.i18n.Cart">-->
+<!--            <result name="success" type="velocity">-->
+<!--                <param name="location">cart.vm</param>-->
+<!--            </result>-->
+<!--        </action>-->
         <action name="i18n.CDList" class="com.opensymphony.webwork.example.i18n.CDList">
             <result name="success" type="velocity">
                 <param name="location">cdlist.vm</param>
                 <param name="location">shop.jsp</param>
             </result>