[rhmessaging-commits] rhmessaging commits: r2244 - mgmt/trunk/cumin/python/cumin.

rhmessaging-commits at lists.jboss.org rhmessaging-commits at lists.jboss.org
Tue Aug 5 16:33:37 EDT 2008


Author: eallen
Date: 2008-08-05 16:33:37 -0400 (Tue, 05 Aug 2008)
New Revision: 2244

Added:
   mgmt/trunk/cumin/python/cumin/binding.py
   mgmt/trunk/cumin/python/cumin/binding.strings
Log:
FormField for entering and validating binding info

Added: mgmt/trunk/cumin/python/cumin/binding.py
===================================================================
--- mgmt/trunk/cumin/python/cumin/binding.py	                        (rev 0)
+++ mgmt/trunk/cumin/python/cumin/binding.py	2008-08-05 20:33:37 UTC (rev 2244)
@@ -0,0 +1,365 @@
+from cumin.util import sorted_by, is_active
+from formats import fmt_shorten
+from wooly.forms import FormInput, FormField
+from wooly.resources import StringCatalog
+from wooly import Template, Writer, Attribute
+from wooly.parameters import DictParameter
+
+strings = StringCatalog(__file__)
+
+class ExchangeInput(FormInput):
+    def __init__(self, app, name, form):
+        super(ExchangeInput, self).__init__(app, name, form)
+
+        self.exchange = None
+        self.instance_data = None
+        
+        self.name_tmpl = Template(self, "name_html")
+        self.key_tmpl = Template(self, "key_html")
+
+    def get_args(self, session):
+        return (self.exchange,)
+    
+    def get_exchange_info(self, session, exchange):
+        binding_info = self.form.bindings.dict_param.get(session)
+        if str(exchange.id) in binding_info:
+            return binding_info[str(exchange.id)]
+
+    def get_exchange_info_for(self, session, exchange, key):
+        exchange_info = self.get_exchange_info(session, exchange)
+        if exchange_info:
+            if key in exchange_info:
+                return exchange_info[key]
+            
+    def render_exchange_name(self, session, exchange):
+        return exchange.name
+
+    def render_exchange_fmt_name(self, session, exchange):
+        return fmt_shorten(exchange.name)
+
+    def render_name_path(self, session, *args):
+        return "_".join((self.instance_data, "name"))
+    
+    def render_exchange_type(self, session, exchange):
+        return exchange.type
+
+    def render_exchange_type_path(self, session, exchange):
+        return "_".join((self.instance_data, "type"))
+        
+    def render_exchange_id(self, session, exchange):
+        return exchange.id
+    
+    def render_exchange_checked(self, session, exchange):
+        exchange_info = self.get_exchange_info(session, exchange)
+        if exchange_info:
+            if "name" in exchange_info:
+                return "checked=\"checked\""
+
+    def render_exchange_name_input(self, session, exchange):
+        writer = Writer()
+        self.name_tmpl.render(writer, session, exchange)
+        return writer.to_string()
+        
+    def render_exchange_key_input(self, session, exchange):
+        writer = Writer()
+        self.key_tmpl.render(writer, session, exchange)
+        return writer.to_string()
+        
+    def render_onclick(self, session, exchange):
+        pass
+    
+    def render_list_error(self, session, exchange):
+        errors = self.parent.binding_errors.get(session)
+        if exchange.name in errors:
+            return "<ul class=\"errors\" style=\"margin:0; float:left;\"><li>%s</li></ul>" % \
+                "</li><li>".join(errors[exchange.name])
+                
+    def render_dict_error(self, session, exchange, key):
+        errors = self.parent.binding_errors.get(session)
+        if exchange.name in errors:
+            exchange_errors = errors[exchange.name]
+            if key in exchange_errors:
+                return "<ul class=\"errors\" style=\"margin:0; float:left;\"><li>%s</li></ul>" % \
+                "</li><li>".join(exchange_errors[key])
+    
+    def set_instance_data(self, exchange, dict_key):
+        self.exchange = exchange
+        self.instance_data = dict_key
+    
+class DirectExchangeInput(ExchangeInput):
+    pass
+
+class FanoutExchangeInput(ExchangeInput):
+    pass
+
+class BindingKeyExchangeInput(ExchangeInput):
+    def __init__(self, app, name, form):
+        super(BindingKeyExchangeInput, self).__init__(app, name, form)
+
+    def render_key_path(self, session, exchange):
+        return "_".join((self.instance_data, "key"))
+
+    def render_key_error(self, session, exchange):
+        return self.render_list_error(session, exchange)
+                
+    def render_key_value(self, session, exchange):
+        return self.get_exchange_info_for(session, exchange, "key")
+        
+class TopicExchangeInput(BindingKeyExchangeInput):
+    pass
+
+class XMLExchangeInput(BindingKeyExchangeInput):
+    def __init__(self, app, name, form):
+        super(XMLExchangeInput, self).__init__(app, name, form)
+
+    def render_xquery_path(self, session, exchange):
+        return "_".join((self.instance_data, "xquery"))
+    
+    def render_headers_class(self, session, exchange):
+        exchange_info = self.get_exchange_info(session, exchange)
+        if not exchange_info or not "name" in exchange_info: 
+            return "initial_header_state"
+
+    def render_key_error(self, session, exchange):
+        return self.render_dict_error(session, exchange, "key")
+    
+    def render_onclick(self, session, exchange):
+        return "onclick=\"toggle_row(this, 'xml_extra')\""
+    
+    def render_xquery_error(self, session, exchange):
+        return self.render_dict_error(session, exchange, "xquery")
+    
+    def render_xquery_value(self, session, exchange):
+        return self.get_exchange_info_for(session, exchange, "xquery")
+
+class HeadersExchangeInput(BindingKeyExchangeInput):
+    def __init__(self, app, name, form):
+        super(HeadersExchangeInput, self).__init__(app, name, form)
+
+    def render_x_match_path(self, session, exchange):
+        return "_".join((self.instance_data, "x-match"))
+
+    def render_mkey_path(self, session, exchange):
+        return "_".join((self.instance_data, "mkey"))
+    
+    def render_headers_class(self, session, exchange):
+        exchange_info = self.get_exchange_info(session, exchange)
+        if not exchange_info or not "name" in exchange_info: 
+            return "initial_header_state"
+
+    def render_all_checked(self, session, exchange):
+        checked = self.render_any_checked(session, exchange)
+        if not checked:
+            return "checked=\"checked\""
+        
+    def render_any_checked(self, session, exchange):
+        exchange_info = self.get_exchange_info(session, exchange)
+        if exchange_info:
+            if "x-match" in exchange_info:
+                if exchange_info["x-match"] == "any":
+                    return "checked=\"checked\""
+                
+    def render_mkey1_value(self, session, exchange):
+        return self.get_exchange_info_for(session, exchange, "mkey.1")
+
+    def render_mkey2_value(self, session, exchange):
+        return self.get_exchange_info_for(session, exchange, "mkey.2")
+
+    def render_mkey3_value(self, session, exchange):
+        return self.get_exchange_info_for(session, exchange, "mkey.3")
+
+    def render_mnv1_value(self, session, exchange):
+        return self.get_exchange_info_for(session, exchange, "mkey.1.nv")
+    
+    def render_mnv2_value(self, session, exchange):
+        return self.get_exchange_info_for(session, exchange, "mkey.2.nv")
+
+    def render_mnv3_value(self, session, exchange):
+        return self.get_exchange_info_for(session, exchange, "mkey.3.nv")
+        
+    def render_key_error(self, session, exchange):
+        return self.render_dict_error(session, exchange, "key")
+    
+    def render_mkey1_error(self, session, exchange):
+        return self.render_dict_error(session, exchange, "mkey.1")
+
+    def render_mkey2_error(self, session, exchange):
+        return self.render_dict_error(session, exchange, "mkey.2")
+
+    def render_mkey3_error(self, session, exchange):
+        return self.render_dict_error(session, exchange, "mkey.3")
+
+    def render_onclick(self, session, exchange):
+        return "onclick=\"toggle_row(this, 'headers_extra')\""
+    
+
+
+class ExchangeKeysField(FormField):
+    def __init__(self, app, name, form, title="Initial bindings:"):
+        super(ExchangeKeysField, self).__init__(app, name, form)
+
+        self.dict_param = DictParameter(app, "exchange", form)
+        self.add_parameter(self.dict_param)
+        form.add_form_parameter(self.dict_param)
+
+        self.direct_input = DirectExchangeInput(app, "direct", form)
+        self.add_child(self.direct_input)
+
+        self.topic_input = TopicExchangeInput(app, "topic", form)
+        self.add_child(self.topic_input)
+
+        self.fanout_input = FanoutExchangeInput(app, "fanout", form)
+        self.add_child(self.fanout_input)
+
+        self.xml_input = XMLExchangeInput(app, "xml", form)
+        self.add_child(self.xml_input)
+
+        self.headers_input = HeadersExchangeInput(app, "headers", form)
+        self.add_child(self.headers_input)
+        
+        self.title = title
+        
+        self.binding_errors = self.Errors(self, "binding_errors")
+        self.add_attribute(self.binding_errors)
+
+    def get_args(self, session):
+        broker = self.get_parent_named("broker")
+        reg = broker.get_object(session)
+        return (reg.getDefaultVhost(),)
+        
+    class Errors(Attribute):
+        def get_default(self, session):
+            return dict()
+
+    def render_title(self, session, vhost):
+        return self.title
+    
+    def render_exchanges(self, session, vhost):
+        sortedExchanges = sorted_by(vhost.exchanges)
+
+        # render each exchange we support
+        writer = Writer()
+        for exchange in sortedExchanges:
+            if is_active(exchange):
+                # instance_key gives us a unique path for each exchange
+                # we will be rendering
+                instance_key = self.dict_param.get_instance_key(str(exchange.id))
+                if exchange.type == "direct":
+                    if exchange.name:
+                        self.direct_input.set_instance_data(exchange, instance_key)
+                        writer.write(self.direct_input.render(session))
+                elif exchange.type == "topic":
+                    if not exchange.name == "qpid.management":
+                        self.topic_input.set_instance_data(exchange, instance_key)
+                        writer.write(self.topic_input.render(session))
+                elif exchange.type == "fanout":
+                    self.fanout_input.set_instance_data(exchange, instance_key)
+                    writer.write(self.fanout_input.render(session))
+                elif exchange.type == "xml":
+                    self.xml_input.set_instance_data(exchange, instance_key)
+                    writer.write(self.xml_input.render(session))
+                elif exchange.type == "headers":
+                    self.headers_input.set_instance_data(exchange, instance_key)
+                    writer.write(self.headers_input.render(session))
+        
+        return writer.to_string()
+    
+    def get_binding_info(self, session, queue_name):
+
+        form_binding_info = self.process_binding_info(session, queue_name)
+        binding_info = self.dict_param.get(session)
+        berrs = self.binding_errors.get(session)
+
+        for exchange in form_binding_info:
+            type = form_binding_info[exchange]["type"]
+            if type == "topic":
+                if not "key" in form_binding_info[exchange]:
+                    name = form_binding_info[exchange]["name"]
+                    errs = berrs.setdefault(name, list())
+                    errs.append("A binding key is required")
+            elif type == "headers":
+                if not "key" in form_binding_info[exchange]:
+                    name = form_binding_info[exchange]["name"]
+                    errs = berrs.setdefault(name, dict())
+                    errs["key"] = ["A binding key is required"]
+                for key_num in ("1", "2", "3"):
+                    mkey = "mkey."+key_num
+                    mkeynv = mkey+".nv"
+                    if mkeynv in binding_info[exchange]:
+                        if not mkey in binding_info[exchange]:
+                            name = binding_info[exchange]["name"]
+                            if not name in berrs:
+                                berrs.setdefault(name, dict())
+                            berrs[name][mkey] = ["Missing key"]
+            elif type == "xml":
+                if not "key" in form_binding_info[exchange]:
+                    name = form_binding_info[exchange]["name"]
+                    errs = berrs.setdefault(name, dict())
+                    errs["key"] = ["A binding key is required"]
+                if not "xquery" in form_binding_info[exchange]:
+                    name = binding_info[exchange]["name"]
+                    if not name in berrs:
+                        berrs.setdefault(name, dict())
+                    berrs[name]["xquery"] = ["Missing xquery"]
+                    
+        if len(berrs):
+            # Tell dictionary to clear out any
+            # values the next time the page is submitted
+            # before it starts adding new entries.
+            # This is needed because checkboxes don't
+            # send a blank value when they are cleared.
+            self.dict_param.set_clear_on_add()
+        else:
+            self.dict_param.clear()
+
+        return (len(berrs), form_binding_info)
+        
+    def process_binding_info(self, session, queue_name):
+        binding_info = self.dict_param.get(session)
+        form_binding_info = dict()
+        for this_exchange in binding_info:
+            # if the exchange checkbox is checked
+            if "name" in binding_info[this_exchange]:
+                form_binding_info[this_exchange] = dict()
+                arguments = dict()
+                type = binding_info[this_exchange]["type"]
+                if type == "headers":
+                    arguments["x-match"] = binding_info[this_exchange]["x-match"]
+
+                    # Fill out the other arguments.
+                    # The form has input boxes named mkey.* and mkey.*.nv
+                    # We need to create an arguments dictionary entry
+                    # of the form {mkey.*.value: mkey.*.nv.value}
+                    for match_info in binding_info[this_exchange]:
+                        if binding_info[this_exchange][match_info]:
+                            if match_info.startswith("mkey") \
+                                and not match_info.endswith("nv"):
+                                # find the value in the matching .nv field
+                                match_value = self._find_match_value(binding_info, 
+                                                        this_exchange, match_info)
+                                # it is valid for the value in the .nv field
+                                # to be empty
+                                arguments[binding_info[this_exchange][match_info]] = \
+                                    match_value or None
+                elif type == "xml":
+                    if "xquery" in binding_info[this_exchange]:
+                        arguments["xquery"] = binding_info[this_exchange]["xquery"]
+                elif type == "direct":
+                    binding_info[this_exchange]["key"] = queue_name
+                #topic and fanout exchanges don't need any processing
+                
+                form_binding_info[this_exchange]["name"] = binding_info[this_exchange]["name"]
+                if "key" in binding_info[this_exchange]:
+                    form_binding_info[this_exchange]["key"] = binding_info[this_exchange]["key"]
+                form_binding_info[this_exchange]["arguments"] = arguments
+                # type is used in form validation only
+                form_binding_info[this_exchange]["type"] = binding_info[this_exchange]["type"]
+
+        return form_binding_info
+
+    def _find_match_value(self, binding_info, this_exchange, match_info):
+        for m_info in binding_info[this_exchange]:
+            if m_info.startswith(match_info):
+                if m_info.endswith("nv"):
+                    return binding_info[this_exchange][m_info] 
+

Added: mgmt/trunk/cumin/python/cumin/binding.strings
===================================================================
--- mgmt/trunk/cumin/python/cumin/binding.strings	                        (rev 0)
+++ mgmt/trunk/cumin/python/cumin/binding.strings	2008-08-05 20:33:37 UTC (rev 2244)
@@ -0,0 +1,155 @@
+
+[ExchangeInput.name_html]
+		<td><input type="checkbox" 
+				id="{id}.{exchange_id}"
+      			name="{name_path}" value="{exchange_name}" size="15" 
+      			tabindex="100" {exchange_checked}
+      			{onclick} />
+      		<input type="hidden" 
+      			name="{exchange_type_path}" value="{exchange_type}" /></td>
+      	<td><label class="exchange_name" for="{id}.{exchange_id}">{exchange_fmt_name}</label></td>
+    	<td class="exchange_type">{exchange_type}</td>
+
+[ExchangeInput.key_html]
+    	<td><input type="text" 
+      			name="{key_path}" id="{exchange_name}" 
+      			value="{key_value}" size="32" maxlength="256" tabindex="100" />
+      		{key_error}</td>
+
+[DirectExchangeInput.html]
+	<tr>
+		{exchange_name_input}
+		<td>&nbsp;</td>
+     </tr>
+
+[TopicExchangeInput.html]
+	<tr>
+		{exchange_name_input}
+		{exchange_key_input}
+     </tr>
+
+[FanoutExchangeInput.html]
+	<tr>
+		{exchange_name_input}
+		<td>&nbsp;</td>
+     </tr>
+
+[XMLExchangeInput.html]
+	<tr>
+		{exchange_name_input}
+		{exchange_key_input}
+    </tr>
+    <tr id="xml_extra" class="{headers_class}"><td colspan="4"><table>
+    <tr>
+      	<td>XQuery:</td>
+      	<td colspan="3"><textarea name="{xquery_path}" id="{exchange_name}"
+      		tabindex="100" rows="4" cols="40">{xquery_value}</textarea>{xquery_error}</td>
+     </tr></table></td></tr>
+
+[HeadersExchangeInput.html]
+	<tr>
+		{exchange_name_input}
+		{exchange_key_input}
+    </tr>
+    <tr id="headers_extra" class="{headers_class}"><td colspan="4"><table>
+ 	<tr>
+ 		<td>&nbsp;</td>
+      	<td>x-match Type:</td>
+      	<td colspan="2"><input type="radio" id="headers.x-match.all" 
+      						name="{x_match_path}" value="all" {all_checked} /> 
+      						<label for="headers.x-match.all">All</label>
+						<input type="radio" id="headers.x-match.any" 
+      						name="{x_match_path}" value="any" {any_checked}/> 
+      						<label for="headers.x-match.any">Any</label>
+      	</td>
+    </tr>
+    <tr>
+ 		<td>&nbsp;</td>
+     	<td>Match Keys:</td>
+     	<td colspan="2">
+     		<table class="xmlExchange">
+			  <thead>
+     			<tr>
+     			<th>Key</th><th>type, value</th>
+     			</tr>
+     		  </thead>
+     		  <tbody>
+     		    <tr>
+     		    	<td><input type="text" name="{mkey_path}.1" value="{mkey1_value}" tabindex="100" />{mkey1_error}</td>
+     		    	<td><input type="text" name="{mkey_path}.1.nv" value="{mnv1_value}" tabindex="100" /></td>
+     		    </tr>
+     		    <tr>
+     		    	<td><input type="text" name="{mkey_path}.2" value="{mkey2_value}" tabindex="100" />{mkey2_error}</td>
+     		    	<td><input type="text" name="{mkey_path}.2.nv" value="{mnv2_value}" tabindex="100" /></td>
+     		    </tr>
+     		    <tr>
+     		    	<td><input type="text" name="{mkey_path}.3" value="{mkey3_value}" tabindex="100" />{mkey3_error}</td>
+     		    	<td><input type="text" name="{mkey_path}.3.nv" value="{mnv3_value}" tabindex="100" /></td>
+     		    </tr>
+     		  </tbody>
+     		  </table>
+     	</td>
+    </tr></table></td></tr>
+	  
+[ExchangeKeysField.css]
+td.exchange_type {
+	font-style: italic;
+}
+
+table.mobjects tr#headers_extra {
+  border-top: 0px;
+}
+
+table.mobjects tr.initial_header_state {
+	display:none;
+}
+
+table.xmlExchange {
+  border-collapse: collapse;
+  border: 1px dotted #ccc;
+  margin: 0;
+}
+
+table.xmlExchange tr {
+  border-top: 0px solid #fff;
+}
+
+table.mobjects label.exchange_name {
+	font-weight: bold;
+}
+
+table.mobjects td.exchange_type, table.mobjects th.exchange_type {
+	font-style: italic;
+}
+
+[ExchangeKeysField.javascript]
+function toggle_row(chk, row_id) {
+	
+	var display = "none";
+	var headers_extra = document.getElementById(row_id);
+	if (chk.checked)
+		display = "table-row";
+		
+	headers_extra.style.display = display;
+}
+
+[ExchangeKeysField.html]
+<div class="field">
+  <div class="title">{title}</div>
+  
+<div class="inputs">
+<table class="mobjects" id="exchange_types">
+  <thead>
+	<tr>
+		<th colspan="2"><label class="exchange_name">Exchange Name</label></th>
+		<th class="exchange_type">Exchange Type</th>
+		<th>Binding Key</th>
+	</tr>
+  </thead>
+  <tbody>
+  {exchanges}
+  </tbody>
+</table>
+</div>
+</div>
+




More information about the rhmessaging-commits mailing list