[rhmessaging-commits] rhmessaging commits: r1769 - in mgmt: cumin/python/cumin and 2 other directories.

rhmessaging-commits at lists.jboss.org rhmessaging-commits at lists.jboss.org
Thu Mar 6 23:59:23 EST 2008


Author: justi9
Date: 2008-03-06 23:59:23 -0500 (Thu, 06 Mar 2008)
New Revision: 1769

Modified:
   mgmt/Makefile
   mgmt/cumin/python/cumin/broker.py
   mgmt/cumin/python/cumin/broker.strings
   mgmt/cumin/python/cumin/queue.py
   mgmt/cumin/python/cumin/queue.strings
   mgmt/cumin/python/cumin/widgets.py
   mgmt/cumin/python/cumin/widgets.strings
   mgmt/cumin/python/wooly/__init__.py
   mgmt/cumin/python/wooly/__init__.strings
   mgmt/cumin/python/wooly/forms.py
   mgmt/cumin/python/wooly/forms.strings
   mgmt/cumin/python/wooly/server.py
   mgmt/misc/boneyard.py
   mgmt/misc/boneyard.strings
Log:
Phase 1 of the form overhaul.

Takes the error attr and error renderering off of Widget.  That was
dubious idea to start with.

Introduces form fields, a type of form in put with a title, a slot for
errors, and which can server in a special kind of field-oriented form.

Moves some dead code to the boneyard.



Modified: mgmt/Makefile
===================================================================
--- mgmt/Makefile	2008-03-07 00:34:26 UTC (rev 1768)
+++ mgmt/Makefile	2008-03-07 04:59:23 UTC (rev 1769)
@@ -1,5 +1,8 @@
-.PHONY: dist clean
+.PHONY: help dist clean
 
+help:
+	@echo Targets: dist, clean, tags
+
 dist: clean
 	mkdir -p dist/lib/python/mint
 	mkdir -p dist/lib/python/wooly

Modified: mgmt/cumin/python/cumin/broker.py
===================================================================
--- mgmt/cumin/python/cumin/broker.py	2008-03-07 00:34:26 UTC (rev 1768)
+++ mgmt/cumin/python/cumin/broker.py	2008-03-07 04:59:23 UTC (rev 1769)
@@ -143,9 +143,6 @@
         self.add_mode(self.remove)
         self.set_remove_mode(self.remove)
 
-        self.prop = BrokerConfigPropertyForm(app, "prop")
-        self.add_mode(self.prop)
-
         self.queue = QueueFrame(app, "queue")
         self.add_mode(self.queue)
 
@@ -161,11 +158,6 @@
         self.clients_close = ClientSetClose(app, "clientsclose")
         self.add_mode(self.clients_close)
 
-    def show_config_property(self, session, prop):
-        self.prop.set_config_property(session, prop)
-        self.page().set_current_frame(session, self.prop)
-        return self.show_mode(session, self.prop)
-
     def show_queue(self, session, queue):
         self.queue.set_object(session, queue)
         self.page().set_current_frame(session, self.queue)
@@ -192,87 +184,6 @@
     def get_title(self, session, broker):
         return "Broker '%s'" % broker.name
 
-class BrokerConfigPropertyForm(CuminForm, Frame):
-    def __init__(self, app, name):
-        super(BrokerConfigPropertyForm, self).__init__(app, name)
-
-        self.param = ConfigPropertyParameter(app, "param")
-        self.add_parameter(self.param)
-
-        self.source = Parameter(app, "source")
-        self.source.set_default("local")
-        self.add_parameter(self.source)
-
-        self.profile = RadioInput(app, "profile", self)
-        self.profile.set_parameter(self.source)
-        self.profile.set_value("profile")
-        self.add_child(self.profile)
-
-        self.pvalue = TextInput(app, "profile_value", self)
-        self.pvalue.set_disabled(True)
-        self.add_child(self.pvalue)
-
-        self.broker = RadioInput(app, "broker", self)
-        self.broker.set_parameter(self.source)
-        self.broker.set_value("broker")
-        self.add_child(self.broker)
-
-        self.svalue = TextInput(app, "broker_value", self)
-        self.svalue.set_disabled(True)
-        self.add_child(self.svalue)
-
-        self.local = RadioInput(app, "local", self)
-        self.local.set_parameter(self.source)
-        self.local.set_value("local")
-        self.add_child(self.local)
-
-        self.lvalue = TextInput(app, "local_value", self)
-        self.add_child(self.lvalue)
-
-    def get_title(self, session, prop):
-        return "Edit Property '%s'" % prop.name
-
-    def get_object(self, session, object):
-        return self.param.get(session)
-
-    def set_config_property(self, session, prop):
-        return self.param.set(session, prop)
-
-    def process_cancel(self, session, prop):
-        branch = session.branch()
-        self.page().show_broker(branch, prop.get_broker()).show_view(branch)
-        self.page().set_redirect_url(session, branch.marshal())
-
-    def process_submit(self, session, prop):
-        source = self.source.get(session)
-        
-        if source == "profile":
-            prop.value = get_profile_value(prop)
-        elif source == "broker":
-            prop.value = prop.broker_value
-        elif source == "local":
-            prop.value = self.lvalue.get(session)
-        else:
-            raise Exception()
-
-        self.process_cancel(session, prop)
-
-    def process_display(self, session, prop):
-        self.pvalue.set(session, get_profile_value(prop))
-        self.svalue.set(session, prop.broker_value)
-        self.lvalue.set(session, prop.value)
-
-def get_profile_value(prop):
-    profile = prop.get_broker().get_broker_profile()
-    value = None
-
-    if profile:
-        for p in profile.config_property_items():
-            if p.name == prop.name:
-                value = p.value
-
-    return value
-
 class BrokerStatus(CuminStatus):
     pass
 
@@ -297,10 +208,6 @@
         self.tabs.add_tab(self.BrokerQueueTab(app, "queues"))
         self.tabs.add_tab(self.BrokerExchangeTab(app, "exchanges"))
         self.tabs.add_tab(self.BrokerClientTab(app, "clients"))
-        #self.config = self.BrokerConfigTab(app, "config")
-        #self.tabs.add_tab(self.config)
-        #self.tabs.add_tab(self.BrokerStatsTab(app, "stats"))
-        #self.tabs.add_tab(self.BrokerLogTab(app, "log"))
 
         self.missing = self.BrokerMissing(app, "missing")
         self.body.add_mode(self.missing)
@@ -319,8 +226,7 @@
 
     def do_process(self, session, reg):
         if reg.broker:
-            vhost = Vhost.selectBy(broker=reg.broker, name="/")[0]
-            self.vhost.set(session, vhost)
+            self.vhost.set(session, reg.getDefaultVhost())
         else:
             self.body.show_mode(session, self.missing)
 
@@ -363,15 +269,25 @@
         else:
             return fmt_none()
 
-    class BrokerQueueTab(QueueSet):
+    class BrokerQueueTab(Widget):
+        def __init__(self, app, name):
+            super(BrokerView.BrokerQueueTab, self).__init__(app, name)
+
+            self.__queues = QueueSet(app, "items")
+            self.add_child(self.__queues)
+
         def get_object(self, session, reg):
             return self.parent.parent.parent.vhost.get(session)
 
-        def get_title(self, session, broker):
-            vhost = self.parent.parent.parent.vhost.get(session)
-            return super(BrokerView.BrokerQueueTab, self).get_title \
-                (session, vhost)
+        def get_title(self, session, reg):
+            vhost = reg.getDefaultVhost()
+            return "Queues %s" % fmt_count(vhost.queues.count())
 
+        def render_add_queue_href(self, session, object):
+            branch = session.branch()
+            self.frame().show_queue(branch, None).show_add(branch)
+            return branch.marshal()
+
     class BrokerExchangeTab(ExchangeSet):
         def get_object(self, session, reg):
             return self.parent.parent.parent.vhost.get(session)
@@ -390,33 +306,6 @@
             return super(BrokerView.BrokerClientTab, self).get_title \
                 (session, vhost)
 
-    class BrokerConfigTab(ConfigPropertySet):
-        def get_title(self, session, broker):
-            return "Configuration"
-
-        def do_get_items(self, session, broker):
-            return broker.properties
-
-        def maybe_highlight(self, value, comparedto):
-            if str(value) != str(comparedto):
-                value = "<span class=\"BrokerConfigTab diff\">%s</span>" \
-                        % value
-
-            return value
-
-        def render_item_broker_value(self, session, prop):
-            return self.maybe_highlight(prop.broker_value, prop.value)
-
-        def render_item_profile_value(self, session, prop):
-            value = get_profile_value(prop)
-            return self.maybe_highlight(value, prop.value)
-
-        def render_item_edit_href(self, session, prop):
-            branch = session.branch()
-            frame = self.page().show_broker(branch, prop.get_broker())
-            frame.show_config_property(branch, prop)
-            return branch.marshal()
-
     class BrokerStatsTab(Widget):
         def get_title(self, session, broker):
             return "Statistics"

Modified: mgmt/cumin/python/cumin/broker.strings
===================================================================
--- mgmt/cumin/python/cumin/broker.strings	2008-03-07 00:34:26 UTC (rev 1768)
+++ mgmt/cumin/python/cumin/broker.strings	2008-03-07 04:59:23 UTC (rev 1769)
@@ -39,87 +39,6 @@
   {hidden_inputs}
 </form>
 
-[BrokerConfigTab.css]
-.BrokerConfigTab.diff {
-  background-color: #ff9;
-}
-
-[BrokerSetGroupInput.html]
-<select name="{name}" tabindex="{tab_index}" {disabled_attr} onchange="getElementById('{submit_id}').click()">
-  <option value="">Choose Group...</option>
-  {items}
-</select>
-
-[BrokerConfigTab.html]
-<ul class="actions">
-  <li><a class="nav" href="{href}">Add Property</a></li>
-  <li><a href="{href}">Apply Configuration to Broker</a></li>
-</ul>
-
-<table class="mobjects">
-  <tr>
-    <th>Name</th>
-    <th>Configured Value</th>
-    <th>Broker Value</th>
-    <th>Profile Value</th>
-    <th></th>
-  </tr>
-
-  {items}
-</table>
-
-[BrokerConfigTab.item_html]
-<tr>
-  <td>{item_name}</td>
-  <td>{item_value}</td>
-  <td>{item_broker_value}</td>
-  <td>{item_profile_value}</td>
-  <td><a class="action" href="{item_edit_href}">Edit</a></td>
-</tr>
-
-[BrokerConfigPropertyForm.css]
-.BrokerConfigPropertyForm div.value {
-  margin: 1em 2em;
-}
-
-[BrokerConfigPropertyForm.html]
-<form id="{id}" class="BrokerConfigPropertyForm mform" method="post" action="?">
-  <div class="head">
-    <h1>{title}</h1>
-  </div>
-  <div class="body">
-    <span class="legend">Value</span>
-    <fieldset>
-      <div class="field">
-        {profile} Use the value from the broker profile
-        <div class="value">{profile_value}</div>
-      </div>
-      <div class="field">
-        {broker} Use the value currently set on the broker
-        <div class="value">{broker_value}</div>
-      </div>
-      <div class="field">
-        {local} Set a new value
-        <div class="value">{local_value}</div>
-      </div>
-    </fieldset>
-
-    {hidden_inputs}
-  </div>
-  <div class="foot">
-    <div style="float: left;"><button>Help</button></div>
-    {submit}
-    {cancel}
-  </div>
-</form>
-<script defer="defer">
-(function() {
-    var elem = wooly.doc().elembyid("{id}").node.elements[1];
-    elem.focus();
-    elem.select();
-}())
-</script>
-
 [BrokerView.javascript]
 function updateBroker(data) {
     var model = data.objectify();
@@ -172,6 +91,13 @@
 window.setInterval(updateTimer, 1000);
 </script>
 
+[BrokerQueueTab.html]
+<ul class="actions">
+  <li><a class="nav" href="{add_queue_href}">Add Queue</a></li>
+</ul>
+
+{items}
+
 [BrokerBrowser.html]
 <table class="browser">
   <tr>

Modified: mgmt/cumin/python/cumin/queue.py
===================================================================
--- mgmt/cumin/python/cumin/queue.py	2008-03-07 00:34:26 UTC (rev 1768)
+++ mgmt/cumin/python/cumin/queue.py	2008-03-07 04:59:23 UTC (rev 1769)
@@ -1,3 +1,5 @@
+import pdb
+
 from mint import *
 from wooly import *
 from wooly.widgets import *
@@ -58,7 +60,7 @@
         self.add_child(self.__purge)
 
     def get_title(self, session, vhost):
-        return "Queues %s" % fmt_count(vhost.queues.count())
+        return "Queues %s" % fmt_count(Queue.select().count())
 
     def render_sql_where(self, session, vhost):
         elems = list()
@@ -167,6 +169,10 @@
         self.add_mode(self.view)
         self.set_view_mode(self.view)
 
+        self.add = QueueAdd(app, "add")
+        self.add_mode(self.add)
+        self.set_add_mode(self.add)
+
         self.purge = QueuePurge(app, "purge")
         self.add_mode(self.purge)
 
@@ -181,7 +187,10 @@
         return queue
 
     def get_title(self, session, queue):
-        return "Queue '%s'" % queue.name
+        if queue:
+            return "Queue '%s'" % queue.name
+        else:
+            return "Queue"
 
 class QueueStatus(CuminStatus):
     def render_consumers(self, session, queue):
@@ -289,124 +298,41 @@
     def render_item_name(self, session, binding):
         return binding.exchange.name or "<em>Default</em>"
 
-class QueueForm(CuminForm):
+class QueueForm(CuminFieldForm, Frame):
     def __init__(self, app, name):
         super(QueueForm, self).__init__(app, name)
 
-        self.queue_name = TextInput(app, "queue_name", self)
-        self.add_child(self.queue_name)
+        self.namef = NameField(app, "name", self)
+        self.add_field(self.namef)
 
-        self.latency_priority = Parameter(app, "tuning")
-        self.latency_priority.set_default("m")
-        self.add_parameter(self.latency_priority)
+        self.durable = DurabilityField(app, "durable", self)
+        self.add_field(self.durable)
 
-        self.latency = RadioInput(app, "latency", self)
-        self.latency.set_parameter(self.latency_priority)
-        self.latency.set_value("h")
-        self.add_child(self.latency)
-
-        self.balanced = RadioInput(app, "balanced", self)
-        self.balanced.set_parameter(self.latency_priority)
-        self.balanced.set_value("m")
-        self.add_child(self.balanced)
-
-        self.throughput = RadioInput(app, "throughput", self)
-        self.throughput.set_parameter(self.latency_priority)
-        self.throughput.set_value("l")
-        self.add_child(self.throughput)
-
-    def validate(self, session):
-        error = None
-
-        name = self.queue_name.get(session)
-
-        if name == "":
-            error = EmptyInputError(self.queue_name)
-            self.queue_name.add_error(session, error)
-        elif " " in name:
-            error = Error("""
-            The queue name is invalid; allowed characters are
-            letters, digits, ".", and "_"
-            """)
-            self.queue_name.add_error(session, error)
-
-        return error is None
-
 class QueueAdd(QueueForm):
-    def process_cancel(self, session, vhost):
-        branch = session.branch()
-        self.page().show_broker(branch, vhost.broker).show_view(branch)
-        self.page().set_redirect_url(session, branch.marshal())
+    def process_submit(self, session, object):
+        errors = self.validate(session)
 
-    def process_submit(self, session, vhost):
-        if self.validate(session):
-            queue = Queue()
-            queue.name = self.queue_name.get(session)
+        if errors:
+            pass
+        else:
+            reg = self.frame().frame().get_object(session, None)
+            vhost = reg.getDefaultVhost()
 
-            vhost.addQueue(queue)
+            name = self.namef.get(session)
+            durable = self.durable.get(session)
+
+            print "XXX add queue", name, self.durable.get(session)
             
             branch = session.branch()
-            self.page().show_queue(branch, queue).show_view(branch)
+            #self.frame().frame().show_queue(branch, queue).show_view(branch)
+            self.page().pop_current_frame(branch)
+            self.page().pop_current_frame(branch).show_view(branch)
             self.page().set_redirect_url(session, branch.marshal())
 
-    def get_title(self, session, vhost):
-        return "Add Queue to Host Template '%s'" % vhost.name
-        
-class QueueEdit(QueueForm):
-    def process_cancel(self, session, queue):
-        branch = session.branch()
-        self.page().show_queue(branch, queue).show_view(branch)
-        self.page().set_redirect_url(session, branch.marshal())
+    def get_title(self, session, object):
+        reg = self.frame().frame().get_object(session, None)
+        return "Add Queue to Broker '%s'" % reg.name
 
-    def process_submit(self, session, queue):
-        if self.validate(session):
-            queue.lock()
-            try:
-                queue.name = self.queue_name.get(session)
-                queue.latency_priority = self.latency_priority.get(session)
-            finally:
-                queue.unlock()
-
-            branch = session.branch()
-            self.page().show_queue(branch, queue).show_view(branch)
-            self.process_cancel(session, queue)
-
-    def process_display(self, session, queue):
-        self.queue_name.set(session, queue.name)
-        self.latency_priority.set(session, queue.latency_priority)
-
-    def get_title(self, session, queue):
-        return "Edit Queue '%s'" % queue.name
-
-class QueueRemove(CuminConfirmForm):
-    def get_title(self, session, queue):
-        return "Remove Queue '%s'" % queue.name
-
-    def process_cancel(self, session, queue):
-        branch = session.branch()
-        self.page().show_queue(branch, queue).show_view(branch)
-        self.page().set_redirect_url(session, branch.marshal())
-
-    def process_submit(self, session, queue):
-        vhost = queue.get_virtual_host()
-
-        queue.remove()
-
-        branch = session.branch()
-        self.page().show_broker(branch, vhost.get_broker()).show_view(branch)
-        self.page().set_redirect_url(session, branch.marshal())
-
-    def render_submit_content(self, session, queue):
-        return "Yes, Remove Queue '%s'" % queue.name
-
-    def render_cancel_content(self, session, queue):
-        return "No, Cancel"
-
-def doit(error, args):
-    pass
-    #print error, args
-    #print "did it!"
-
 class QueuePurge(CuminConfirmForm):
     def get_title(self, session, queue):
         return "Purge Queue '%s'" % queue.name

Modified: mgmt/cumin/python/cumin/queue.strings
===================================================================
--- mgmt/cumin/python/cumin/queue.strings	2008-03-07 00:34:26 UTC (rev 1768)
+++ mgmt/cumin/python/cumin/queue.strings	2008-03-07 04:59:23 UTC (rev 1769)
@@ -59,50 +59,6 @@
   {hidden_inputs}
 </form>
 
-[QueueForm.html]
-<form id="{id}" class="mform" method="post" action="?">
-  <div class="head">
-    <h1>{title}</h1>
-  </div>
-  <div class="body">
-    <span class="legend">Name</span>
-    <fieldset>
-      <div class="field">{queue_name}</div>
-    </fieldset>
-
-    <span class="legend">Latency Tuning</span>
-    <fieldset>
-      <div class="field">
-        {latency}
-        <em>Lower Latency:</em> Tune for shorter delays, with reduced volume
-      </div>
-      <div class="field">
-        {balanced}
-        <em>Balanced</em>
-      </div>
-      <div class="field">
-        {throughput}
-        <em>Higher Throughput:</em> Tune for increased volume, with longer
-        delays
-      </div>
-    </fieldset>
-
-    {hidden_inputs}
-  </div>
-  <div class="foot">
-    <div style="display: block; float: left;"><button>Help</button></div>
-    {submit}
-    {cancel}
-  </div>
-</form>
-<script defer="defer">
-(function() {
-    var elem = wooly.doc().elembyid("{id}").node.elements[1];
-    elem.focus();
-    elem.select();
-}())
-</script>
-
 [QueueStatus.javascript]
 function updateQueueStatus(id, queue) {
     updateStatus(id, queue);

Modified: mgmt/cumin/python/cumin/widgets.py
===================================================================
--- mgmt/cumin/python/cumin/widgets.py	2008-03-07 00:34:26 UTC (rev 1768)
+++ mgmt/cumin/python/cumin/widgets.py	2008-03-07 04:59:23 UTC (rev 1769)
@@ -149,6 +149,9 @@
         def render_content(self, session, object):
             return self.parent.render_submit_content(session, object)
 
+class CuminFieldForm(CuminForm, FieldForm):
+    pass
+
 class CuminConfirmForm(CuminForm):
     def __init__(self, app, name):
         super(CuminConfirmForm, self).__init__(app, name)
@@ -526,3 +529,59 @@
 
     def render_elem_name(self, session, object):
         return self.column.ids.path()
+
+class NameField(StringField):
+    def __init__(self, app, name, form):
+        super(NameField, self).__init__(app, name, form)
+
+        self.required = True
+        self.illegal_chars = ""
+        self.legal_chars_desc = None
+
+    def get_title(self, session, object):
+        return "Name"
+
+    def do_validate(self, session, errors):
+        name = self.get(session)
+
+        if name == "":
+            errors.append(MissingValueError())
+        else:
+            for char in self.illegal_chars:
+                if char in name:
+                    msg = "The name contains illegal characters"
+                    if self.legal_chars_desc:
+                        msg = msg + "; " + self.legal_chars_desc
+
+                    errors.append(Error(msg))
+
+                    break
+
+class DurabilityField(RadioField):
+    def __init__(self, app, name, form):
+        super(DurabilityField, self).__init__(app, name, form)
+
+        param = Parameter(app, "param")
+        param.default = "durable"
+        self.add_parameter(param)
+        self.set_parameter(param)
+
+        self.add_option(self.Durable(app, "durable", form))
+        self.add_option(self.Transient(app, "transient", form))
+
+    def get_title(self, session, object):
+        return "Durable?"
+
+    class Durable(RadioFieldOption):
+        def get_value(self, session, object):
+            return "durable"
+
+        def get_title(self, session, object):
+            return "Durable"
+
+    class Transient(RadioFieldOption):
+        def get_value(self, session, object):
+            return "transient"
+
+        def get_title(self, session, object):
+            return "Transient"

Modified: mgmt/cumin/python/cumin/widgets.strings
===================================================================
--- mgmt/cumin/python/cumin/widgets.strings	2008-03-07 00:34:26 UTC (rev 1768)
+++ mgmt/cumin/python/cumin/widgets.strings	2008-03-07 04:59:23 UTC (rev 1769)
@@ -1,3 +1,17 @@
+[CuminFieldForm.html]
+<form id="{id}" class="mform" method="post" action="?">
+  <div class="head">{title}</div>
+  <div class="body">{fields}</div>
+  <div class="foot">
+    {submit}
+    {cancel}
+  </div>
+  {hidden_inputs}
+</form>
+<script>
+  wooly.doc().elembyid("{id}").node.elements[0].focus();
+</script>
+
 [CuminConfirmForm.html]
 <form id="{id}" class="mform" method="post" action="?">
   <div class="head">

Modified: mgmt/cumin/python/wooly/__init__.py
===================================================================
--- mgmt/cumin/python/wooly/__init__.py	2008-03-07 00:34:26 UTC (rev 1768)
+++ mgmt/cumin/python/wooly/__init__.py	2008-03-07 04:59:23 UTC (rev 1769)
@@ -101,12 +101,7 @@
         self.html_class = None
         
         self.__main_tmpl = Template(self, "html")
-        self.__errors_tmpl = Template(self, "errors_html")
-        self.__error_message_tmpl = Template(self, "error_message_html")
 
-        self.__errors = self.ErrorsAttribute(app, "errors")
-        self.add_attribute(self.__errors)
-
         self.args = self.ArgsAttribute(app, "args")
         self.add_attribute(self.args)
 
@@ -123,10 +118,6 @@
             if cls is Widget:
                 break
 
-    class ErrorsAttribute(Attribute):
-        def get_default(self, session):
-            return list()
-
     class ArgsAttribute(Attribute):
         def get_default(self, session):
             if self.widget.parent:
@@ -219,12 +210,6 @@
             if str:
                 return str
 
-    def get_errors(self, session):
-        return self.__errors.get(session)
-
-    def add_error(self, session, error):
-        self.__errors.get(session).append(error)
-
     def get(self, session, name):
         return self.args.get(session).get(name)
 
@@ -306,25 +291,6 @@
 
         return writer.to_string()
 
-    def render_errors(self, session, object):
-        writer = Writer()
-        
-        if self.get_errors(session):
-            self.__errors_tmpl.render(session, object, writer)
-
-        return writer.to_string()
-
-    def render_error_messages(self, session, object):
-        writer = Writer()
-
-        for error in self.get_errors(session):
-            self.__error_message_tmpl.render(session, error, writer)
-
-        return writer.to_string()
-
-    def render_error_message(self, session, error):
-        return error.message
-
     def prt(self):
         print self
 
@@ -666,6 +632,13 @@
         return "%s(trunk=%s,app=%s)" % \
             (self.__class__.__name__, self.trunk, self.app)
 
+class Error(object):
+    def __init__(self, message=None):
+        self.message = message
+
+    def get_message(self, session):
+        return self.message
+
 class StringIOWriter(object):
     def __init__(self):
         self.writer = StringIO()
@@ -693,10 +666,6 @@
 class Writer(StringIOWriter):
     pass
 
-class Error(object):
-    def __init__(self, message):
-        self.message = message
-
 class Template(object):
     def __init__(self, widget, key):
         self.widget = widget

Modified: mgmt/cumin/python/wooly/__init__.strings
===================================================================
--- mgmt/cumin/python/wooly/__init__.strings	2008-03-07 00:34:26 UTC (rev 1768)
+++ mgmt/cumin/python/wooly/__init__.strings	2008-03-07 04:59:23 UTC (rev 1769)
@@ -1,8 +1,2 @@
 [Widget.html]
 {content}
-
-[Widget.errors_html]
-<ul class="errors">{error_messages}</ul>
-
-[Widget.error_message_html]
-<li>{error_message}</li>

Modified: mgmt/cumin/python/wooly/forms.py
===================================================================
--- mgmt/cumin/python/wooly/forms.py	2008-03-07 00:34:26 UTC (rev 1768)
+++ mgmt/cumin/python/wooly/forms.py	2008-03-07 04:59:23 UTC (rev 1769)
@@ -74,7 +74,7 @@
         return self.param.get_default(session)
 
     def set_default(self, default):
-        self.param.set_default(default)
+        return self.param.set_default(default)
 
     def set_tab_index(self, tab_index):
         self.tab_index = tab_index
@@ -94,12 +94,17 @@
     def render_disabled_attr(self, session, object):
         return self.disabled and "disabled=\"disabled\"" or None
 
+class MissingValueError(Error):
+    def get_message(self, session):
+        return "This value is required"
+
 class EmptyInputError(Error):
-    def __init__(self, input):
-        message = "Input '%s' is empty; it is required" % input.name
+    def __init__(self):
+        message = "This value is required"
 
         super(EmptyInputError, self).__init__(message)
 
+# XXX rename to ScalarInput.  it's less confusing v-a-v StringInput
 class TextInput(FormInput):
     def __init__(self, app, name, form):
         super(TextInput, self).__init__(app, name, form)
@@ -151,16 +156,20 @@
 
         self.value = None
 
-    def set_value(self, value):
+    def xxx_set_value(self, value):
         self.value = value
 
+    def get_value(self, session, object):
+        pass
+
     def render_value(self, session, object):
-        return self.value
+        return self.get_value(session, object)
 
     def render_checked_attr(self, session, object):
         value = self.get(session)
 
-        return value and value == self.value and "checked=\"checked\""
+        if value and value == self.get_value(session, object):
+            return "checked=\"checked\""
 
 class FormButton(FormInput):
     def __init__(self, app, name, form):
@@ -205,3 +214,170 @@
 
     def render_item_selected_attr(self, session, object):
         return None
+
+class FieldSet(Widget):
+    def __init__(self, app, name):
+        super(FieldSet, self).__init__(app, name)
+
+        self.fields = list()
+
+    def add_field(self, field):
+        assert isinstance(field, FormField)
+
+        self.fields.append(field)
+        self.add_child(field)
+
+    def render_fields(self, session, object):
+        writer = Writer()
+
+        for field in self.fields:
+            writer.write(field.render(session, object))
+
+        return writer.to_string()
+
+class FormField(Widget):
+    def __init__(self, app, name, form):
+        super(FormField, self).__init__(app, name)
+
+        self.__form = form
+        self.__param = None
+
+        self.__errors = FormFieldErrors(app, "errors")
+        self.add_child(self.__errors)
+
+    def get_parameter(self):
+        return self.__param
+
+    def set_parameter(self, param):
+        assert isinstance(param, Parameter)
+
+        self.__param = param
+        return param
+
+    def get(self, session):
+        return self.__param.get(session)
+
+    def set(self, session, value):
+        return self.__param.set(session, value)
+
+    def validate(self, session):
+        errors = self.__errors.attr.get(session)
+
+        self.do_validate(session, errors)
+
+        return errors
+
+    def do_validate(self, session, errors):
+        pass
+
+    def render_errors(self, session, object):
+        if self.__errors.attr.get(session):
+            return self.__errors.render(session, object)
+
+class FormFieldErrors(ItemSet):
+    def __init__(self, app, name):
+        super(FormFieldErrors, self).__init__(app, name)
+
+        self.attr = self.Errors(app, "attr")
+        self.add_attribute(self.attr)
+
+    def get_items(self, session, object):
+        return self.attr.get(session)
+
+    def render_item_content(self, session, item):
+        return item.get_message(session)
+
+    class Errors(Attribute):
+        def get_default(self, session):
+            return list()
+
+class ScalarField(FormField):
+    def __init__(self, app, name, form):
+        super(ScalarField, self).__init__(app, name, form)
+
+        self.__input = None
+
+    def get_input(self):
+        return self.__input
+
+    def set_input(self, input):
+        assert isinstance(input, FormInput)
+
+        self.set_parameter(input.get_parameter())
+        self.__input = input
+        return input
+
+    def render_content(self, session, object):
+        return self.__input.render(session, object)
+
+class StringField(ScalarField):
+    def __init__(self, app, name, form):
+        super(StringField, self).__init__(app, name, form)
+        
+        input = TextInput(app, "input", form)
+        self.add_child(input)
+        self.set_input(input)
+
+class IntegerField(ScalarField):
+    def __init__(self, app, name, form):
+        super(IntegerInputField, self).__init__(app, name, form)
+
+        input = Integer(app, "input", form)
+        self.add_child(input)
+        self.set_input(input)
+
+class RadioField(FormField):
+    def __init__(self, app, name, form):
+        super(RadioField, self).__init__(app, name, form)
+
+        self.options = list()
+
+    def add_option(self, option):
+        assert isinstance(option, RadioFieldOption)
+
+        option.set_parameter(self.get_parameter())
+        self.options.append(option)
+        self.add_child(option)
+
+    def render_content(self, session, object):
+        writer = Writer()
+
+        for option in self.options:
+            writer.write(option.render(session, object))
+
+        return writer.to_string()
+
+class RadioFieldOption(RadioInput):
+    pass
+
+class ButtonForm(Form):
+    def __init__(self, app, name):
+        super(ButtonForm. self).__init__(app, name)
+
+        self.buttons = list()
+
+    def add_button(self, button):
+        assert type(button) is FormButton
+
+        self.buttons.append(button)
+        self.add_child(button)
+
+    def render_buttons(self, session, object):
+        writer = Writer()
+
+        for button in self.buttons:
+            writer.write(button.render(session, object))
+
+        return writer.to_string()
+
+class FieldForm(Form, FieldSet):
+    def __init__(self, app, name):
+        super(FieldForm, self).__init__(app, name)
+
+    def validate(self, session):
+        errors = list()
+
+        for field in self.fields:
+            errors.extend(field.validate(session))
+
+        return errors

Modified: mgmt/cumin/python/wooly/forms.strings
===================================================================
--- mgmt/cumin/python/wooly/forms.strings	2008-03-07 00:34:26 UTC (rev 1768)
+++ mgmt/cumin/python/wooly/forms.strings	2008-03-07 04:59:23 UTC (rev 1769)
@@ -2,7 +2,6 @@
 <button class="{class}" id="{id}" type="submit" name="{name}" value="{value}" tabindex="{tab_index}" {disabled_attr}>{content}</button>
 
 [TextInput.html]
-{errors}
 <input type="text" name="{name}" value="{value}" tabindex="{tab_index}" {disabled_attr} size="{size}"/>
 
 [CheckboxInput.html]
@@ -12,22 +11,67 @@
 <input type="radio" name="{name}" value="{value}" tabindex="{tab_index}" {checked_attr} {disabled_attr}/>
 
 [CheckboxInputSet.html]
-{errors}{items}
+{items}
 
 [CheckboxInputSet.item_html]
 <input type="checkbox" name="{name}" value="{item_value}" tabindex="{tab_index}" {item_checked_attr} {disabled_attr}/>
 {item_content}
 
 [RadioInputSet.html]
-{errors}{items}
+{items}
 
 [RadioInputSet.item_html]
 <input type="radio" name="{name}" value="{item_value}" tabindex="{tab_index}" {item_checked_attr} {disabled_attr}/>
 {item_content}
 
 [OptionInputSet.html]
-{errors}
 <select name="{name}" tabindex="{tab_index}" {disabled_attr}>{items}</select>
 
 [OptionInputSet.item_html]
 <option value="{item_value}" {item_selected_attr}>{item_content}</option>
+
+[FieldSet.html]
+<div class="fieldset">
+  <div class="title">{title}</div>
+  <div class="fields">{fields}</div>
+</div>
+
+[FormField.css]
+div.field {
+  padding: 0;
+  margin: 0;
+}
+
+div.field div.title {
+  font-weight: bold;
+  margin: 0 0 1em 0;
+}
+
+div.field div.content {
+  margin: 0 0 1em 1em;
+}
+
+[FormField.html]
+<div class="field">
+  <div class="title">{title}</div>
+  {errors}
+  <div class="content">{content}</div>
+</div>
+
+[FormFieldErrors.html]
+<ul class="errors">{items}</ul>
+
+[FormFieldErrors.item_html]
+<li>{item_content}</li>
+
+[RadioFieldOption.html]
+<div>
+  <input type="radio" name="{name}" value="{value}"
+         tabindex="{tab_index}" {checked_attr} {disabled_attr}/>
+  {title}
+</div>
+
+[FieldForm.html]
+<form id="{id}">
+  {fields}
+</form>

Modified: mgmt/cumin/python/wooly/server.py
===================================================================
--- mgmt/cumin/python/wooly/server.py	2008-03-07 00:34:26 UTC (rev 1768)
+++ mgmt/cumin/python/wooly/server.py	2008-03-07 04:59:23 UTC (rev 1769)
@@ -32,11 +32,6 @@
         self.__server.stop()
 
     def service(self, env, respond):
-        if False and env["PATH_INFO"].endswith(".html"):
-            print "------------------------------------"
-            for key in sorted(env):
-                print key, env[key]
-
         session = Session(self.app)
         session.unmarshal_page(env["PATH_INFO"])
         session.unmarshal_url_vars(env["QUERY_STRING"])

Modified: mgmt/misc/boneyard.py
===================================================================
--- mgmt/misc/boneyard.py	2008-03-07 00:34:26 UTC (rev 1768)
+++ mgmt/misc/boneyard.py	2008-03-07 04:59:23 UTC (rev 1769)
@@ -138,3 +138,111 @@
 
     def render_none(self, session, model):
         return none()
+
+class BrokerConfigPropertyForm(CuminForm, Frame):
+    def __init__(self, app, name):
+        super(BrokerConfigPropertyForm, self).__init__(app, name)
+
+        self.param = ConfigPropertyParameter(app, "param")
+        self.add_parameter(self.param)
+
+        self.source = Parameter(app, "source")
+        self.source.set_default("local")
+        self.add_parameter(self.source)
+
+        self.profile = RadioInput(app, "profile", self)
+        self.profile.set_parameter(self.source)
+        self.profile.set_value("profile")
+        self.add_child(self.profile)
+
+        self.pvalue = TextInput(app, "profile_value", self)
+        self.pvalue.set_disabled(True)
+        self.add_child(self.pvalue)
+
+        self.broker = RadioInput(app, "broker", self)
+        self.broker.set_parameter(self.source)
+        self.broker.set_value("broker")
+        self.add_child(self.broker)
+
+        self.svalue = TextInput(app, "broker_value", self)
+        self.svalue.set_disabled(True)
+        self.add_child(self.svalue)
+
+        self.local = RadioInput(app, "local", self)
+        self.local.set_parameter(self.source)
+        self.local.set_value("local")
+        self.add_child(self.local)
+
+        self.lvalue = TextInput(app, "local_value", self)
+        self.add_child(self.lvalue)
+
+    def get_title(self, session, prop):
+        return "Edit Property '%s'" % prop.name
+
+    def get_object(self, session, object):
+        return self.param.get(session)
+
+    def set_config_property(self, session, prop):
+        return self.param.set(session, prop)
+
+    def process_cancel(self, session, prop):
+        branch = session.branch()
+        self.page().show_broker(branch, prop.get_broker()).show_view(branch)
+        self.page().set_redirect_url(session, branch.marshal())
+
+    def process_submit(self, session, prop):
+        source = self.source.get(session)
+        
+        if source == "profile":
+            prop.value = get_profile_value(prop)
+        elif source == "broker":
+            prop.value = prop.broker_value
+        elif source == "local":
+            prop.value = self.lvalue.get(session)
+        else:
+            raise Exception()
+
+        self.process_cancel(session, prop)
+
+    def process_display(self, session, prop):
+        self.pvalue.set(session, get_profile_value(prop))
+        self.svalue.set(session, prop.broker_value)
+        self.lvalue.set(session, prop.value)
+
+class BrokerConfigTab(ConfigPropertySet):
+    def get_title(self, session, broker):
+        return "Configuration"
+
+    def do_get_items(self, session, broker):
+        return broker.properties
+
+    def maybe_highlight(self, value, comparedto):
+        if str(value) != str(comparedto):
+            value = "<span class=\"BrokerConfigTab diff\">%s</span>" \
+                    % value
+
+        return value
+
+    def render_item_broker_value(self, session, prop):
+        return self.maybe_highlight(prop.broker_value, prop.value)
+
+    def render_item_profile_value(self, session, prop):
+        value = get_profile_value(prop)
+        return self.maybe_highlight(value, prop.value)
+
+    def render_item_edit_href(self, session, prop):
+        branch = session.branch()
+        frame = self.page().show_broker(branch, prop.get_broker())
+        frame.show_config_property(branch, prop)
+        return branch.marshal()
+
+def get_profile_value(prop):
+    profile = prop.get_broker().get_broker_profile()
+    value = None
+
+    if profile:
+        for p in profile.config_property_items():
+            if p.name == prop.name:
+                value = p.value
+
+    return value

Modified: mgmt/misc/boneyard.strings
===================================================================
--- mgmt/misc/boneyard.strings	2008-03-07 00:34:26 UTC (rev 1768)
+++ mgmt/misc/boneyard.strings	2008-03-07 04:59:23 UTC (rev 1769)
@@ -80,3 +80,84 @@
 
 [ClusterBrowser.item_html]
 <li>{item_link}</li>
+
+[BrokerConfigTab.css]
+.BrokerConfigTab.diff {
+  background-color: #ff9;
+}
+
+[BrokerSetGroupInput.html]
+<select name="{name}" tabindex="{tab_index}" {disabled_attr} onchange="getElementById('{submit_id}').click()">
+  <option value="">Choose Group...</option>
+  {items}
+</select>
+
+[BrokerConfigTab.html]
+<ul class="actions">
+  <li><a class="nav" href="{href}">Add Property</a></li>
+  <li><a href="{href}">Apply Configuration to Broker</a></li>
+</ul>
+
+<table class="mobjects">
+  <tr>
+    <th>Name</th>
+    <th>Configured Value</th>
+    <th>Broker Value</th>
+    <th>Profile Value</th>
+    <th></th>
+  </tr>
+
+  {items}
+</table>
+
+[BrokerConfigTab.item_html]
+<tr>
+  <td>{item_name}</td>
+  <td>{item_value}</td>
+  <td>{item_broker_value}</td>
+  <td>{item_profile_value}</td>
+  <td><a class="action" href="{item_edit_href}">Edit</a></td>
+</tr>
+
+[BrokerConfigPropertyForm.css]
+.BrokerConfigPropertyForm div.value {
+  margin: 1em 2em;
+}
+
+[BrokerConfigPropertyForm.html]
+<form id="{id}" class="BrokerConfigPropertyForm mform" method="post" action="?">
+  <div class="head">
+    <h1>{title}</h1>
+  </div>
+  <div class="body">
+    <span class="legend">Value</span>
+    <fieldset>
+      <div class="field">
+        {profile} Use the value from the broker profile
+        <div class="value">{profile_value}</div>
+      </div>
+      <div class="field">
+        {broker} Use the value currently set on the broker
+        <div class="value">{broker_value}</div>
+      </div>
+      <div class="field">
+        {local} Set a new value
+        <div class="value">{local_value}</div>
+      </div>
+    </fieldset>
+
+    {hidden_inputs}
+  </div>
+  <div class="foot">
+    <div style="float: left;"><button>Help</button></div>
+    {submit}
+    {cancel}
+  </div>
+</form>
+<script defer="defer">
+(function() {
+    var elem = wooly.doc().elembyid("{id}").node.elements[1];
+    elem.focus();
+    elem.select();
+}())
+</script>




More information about the rhmessaging-commits mailing list