You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by rh...@apache.org on 2006/09/20 00:07:25 UTC

svn commit: r447994 [42/46] - in /incubator/qpid/trunk/qpid: ./ cpp/ cpp/bin/ cpp/broker/ cpp/broker/inc/ cpp/broker/src/ cpp/broker/test/ cpp/client/ cpp/client/inc/ cpp/client/src/ cpp/client/test/ cpp/common/ cpp/common/concurrent/ cpp/common/concur...

Added: incubator/qpid/trunk/qpid/java/management/mc4j/qpid/BlazeConnections.xml
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/management/mc4j/qpid/BlazeConnections.xml?view=auto&rev=447994
==============================================================================
--- incubator/qpid/trunk/qpid/java/management/mc4j/qpid/BlazeConnections.xml (added)
+++ incubator/qpid/trunk/qpid/java/management/mc4j/qpid/BlazeConnections.xml Tue Sep 19 15:06:50 2006
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ -
+ - Copyright (c) 2006 The Apache Software Foundation
+ -
+ - Licensed under the Apache License, Version 2.0 (the "License");
+ - you may not use this file except in compliance with the License.
+ - You may obtain a copy of the License at
+ -
+ -    http://www.apache.org/licenses/LICENSE-2.0
+ -
+ - Unless required by applicable law or agreed to in writing, software
+ - distributed under the License is distributed on an "AS IS" BASIS,
+ - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ - See the License for the specific language governing permissions and
+ - limitations under the License.
+ -
+ -->
+<!DOCTYPE Dashboard PUBLIC "-//MC4J//DTD Dashboard 1.0//EN" "http://mc4j.sourceforge.net/Dashboard_1_0.dtd">
+
+<Dashboard version="1.0" name="Qpid AMQ Connections Statistics">
+
+  <Description>This dashboard shows the statistics of all Qpid Client Connections.</Description>
+
+  <DashboardMatch type="Global" location="/Qpid/Connections">
+      <BeanMatch id="ConnectionBeanList" type="Multiple">
+          <Condition type="BeanObjectNameCondition" filter="type=Connection"/>
+      </BeanMatch>
+  </DashboardMatch>
+
+  <LayoutManager type="java.awt.BorderLayout"/>
+  <Content>
+
+    <!-- *** The header section displays title and a refresh control *** -->
+    <Component type="javax.swing.JPanel">
+        <Constraint type="BorderConstraints" direction="NORTH"/>
+        <LayoutManager type="java.awt.BorderLayout"/>
+        <Border type="javax.swing.border.EmptyBorder" top="(Literal)2" left="(Literal)5" bottom="(Literal)2" right="(Literal)5"/>
+        <Content>
+            <Component type="javax.swing.JPanel">
+                <Constraint type="BorderConstraints" direction="CENTER"/>
+                <LayoutManager type="java.awt.BorderLayout"/>
+                <Content>
+                    <Component type="javax.swing.JLabel" id="titleLable">
+                        <Constraint type="BorderConstraints" direction="CENTER"/>
+                        <Attribute name="text" value="DashboardName"/>
+                        <Attribute name="font" value="(Literal)SansSerif bold 20"/>
+                        <Attribute name="foreground" value="(Literal)0x666666"/>
+                    </Component>
+                    <Component type="javax.swing.JTextArea">
+                        <Constraint type="BorderConstraints" direction="SOUTH"/>
+                        <Attribute name="text" value="DashboardDescription"/>
+                        <Attribute name="font" value="(Literal)DialogInput bold 14"/>
+                        <Attribute name="opaque" value="(Literal)false"/>
+                        <Attribute name="editable" value="(Literal)false"/>
+                    </Component>
+                </Content>
+            </Component>
+            <Component type="org.mc4j.console.dashboard.components.RefreshControlComponent">
+                <Constraint type="BorderConstraints" direction="EAST"/>
+                <Attribute name="refreshDelay" value="(Literal)1000"/>
+            </Component>
+        </Content>
+    </Component>
+
+
+    <Component type="org.mc4j.console.dashboard.components.AttributeTableComponent">
+        <Attribute name="beanList" value="ConnectionBeanList"/>
+        <Constraint type="BorderConstraints" direction="CENTER"/>
+
+        <Attribute name="background" value="(Literal)0xFFFFFF"/>
+        <Attribute name="preferredSize" value="100,100"/>
+
+
+
+        <Attribute name="AttributeName" value="(Literal)RemoteAddress"/>
+        <Attribute name="AttributeName" value="(Literal)ReadBytes"/>
+        <Attribute name="AttributeName" value="(Literal)WrittenBytes"/>
+        <Attribute name="AttributeName" value="(Literal)LastIoTime"/>
+    </Component>
+
+
+  </Content>
+</Dashboard>

Propchange: incubator/qpid/trunk/qpid/java/management/mc4j/qpid/BlazeConnections.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/qpid/trunk/qpid/java/management/mc4j/qpid/BlazeExchanges.xml
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/management/mc4j/qpid/BlazeExchanges.xml?view=auto&rev=447994
==============================================================================
--- incubator/qpid/trunk/qpid/java/management/mc4j/qpid/BlazeExchanges.xml (added)
+++ incubator/qpid/trunk/qpid/java/management/mc4j/qpid/BlazeExchanges.xml Tue Sep 19 15:06:50 2006
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ -
+ - Copyright (c) 2006 The Apache Software Foundation
+ -
+ - Licensed under the Apache License, Version 2.0 (the "License");
+ - you may not use this file except in compliance with the License.
+ - You may obtain a copy of the License at
+ -
+ -    http://www.apache.org/licenses/LICENSE-2.0
+ -
+ - Unless required by applicable law or agreed to in writing, software
+ - distributed under the License is distributed on an "AS IS" BASIS,
+ - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ - See the License for the specific language governing permissions and
+ - limitations under the License.
+ -
+ -->
+<!DOCTYPE Dashboard PUBLIC "-//MC4J//DTD Dashboard 1.0//EN" "http://mc4j.sourceforge.net/Dashboard_1_0.dtd">
+
+<Dashboard version="1.0" name="Qpid AMQ Exchanges">
+
+  <Description>This dashboard shows the statistics of all Qpid Exchanges.</Description>
+
+  <DashboardMatch type="Global" location="/Qpid/Exchanges">
+      <BeanMatch id="ConnectionBeanList" type="Multiple">
+          <Condition type="BeanObjectNameCondition" filter="type=Exchange"/>
+      </BeanMatch>
+  </DashboardMatch>
+
+  <LayoutManager type="java.awt.BorderLayout"/>
+  <Content>
+
+    <!-- *** The header section displays title and a refresh control *** -->
+    <Component type="javax.swing.JPanel">
+        <Constraint type="BorderConstraints" direction="NORTH"/>
+        <LayoutManager type="java.awt.BorderLayout"/>
+        <Border type="javax.swing.border.EmptyBorder" top="(Literal)2" left="(Literal)5" bottom="(Literal)2" right="(Literal)5"/>
+        <Content>
+            <Component type="javax.swing.JPanel">
+                <Constraint type="BorderConstraints" direction="CENTER"/>
+                <LayoutManager type="java.awt.BorderLayout"/>
+                <Content>
+                    <Component type="javax.swing.JLabel" id="titleLable">
+                        <Constraint type="BorderConstraints" direction="CENTER"/>
+                        <Attribute name="text" value="DashboardName"/>
+                        <Attribute name="font" value="(Literal)SansSerif bold 20"/>
+                        <Attribute name="foreground" value="(Literal)0x666666"/>
+                    </Component>
+                    <Component type="javax.swing.JTextArea">
+                        <Constraint type="BorderConstraints" direction="SOUTH"/>
+                        <Attribute name="text" value="DashboardDescription"/>
+                        <Attribute name="font" value="(Literal)DialogInput bold 14"/>
+                        <Attribute name="opaque" value="(Literal)false"/>
+                        <Attribute name="editable" value="(Literal)false"/>
+                    </Component>
+                </Content>
+            </Component>
+            <Component type="org.mc4j.console.dashboard.components.RefreshControlComponent">
+                <Constraint type="BorderConstraints" direction="EAST"/>
+                <Attribute name="refreshDelay" value="(Literal)1000"/>
+            </Component>
+        </Content>
+    </Component>
+
+
+    <Component type="org.mc4j.console.dashboard.components.AttributeTableComponent">
+        <Attribute name="beanList" value="ConnectionBeanList"/>
+        <Constraint type="BorderConstraints" direction="CENTER"/>
+
+        <Attribute name="background" value="(Literal)0xFFFFFF"/>
+        <Attribute name="preferredSize" value="100,100"/>
+
+        <Attribute name="AttributeName" value="(Literal)Name"/>
+        <Attribute name="AttributeName" value="(Literal)Durable"/>
+        <Attribute name="AttributeName" value="(Literal)Bindings"/>
+    </Component>
+
+
+  </Content>
+</Dashboard>

Propchange: incubator/qpid/trunk/qpid/java/management/mc4j/qpid/BlazeExchanges.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/qpid/trunk/qpid/java/management/mc4j/qpid/BlazeQueues.xml
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/management/mc4j/qpid/BlazeQueues.xml?view=auto&rev=447994
==============================================================================
--- incubator/qpid/trunk/qpid/java/management/mc4j/qpid/BlazeQueues.xml (added)
+++ incubator/qpid/trunk/qpid/java/management/mc4j/qpid/BlazeQueues.xml Tue Sep 19 15:06:50 2006
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ -
+ - Copyright (c) 2006 The Apache Software Foundation
+ -
+ - Licensed under the Apache License, Version 2.0 (the "License");
+ - you may not use this file except in compliance with the License.
+ - You may obtain a copy of the License at
+ -
+ -    http://www.apache.org/licenses/LICENSE-2.0
+ -
+ - Unless required by applicable law or agreed to in writing, software
+ - distributed under the License is distributed on an "AS IS" BASIS,
+ - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ - See the License for the specific language governing permissions and
+ - limitations under the License.
+ -
+ -->
+<!DOCTYPE Dashboard PUBLIC "-//MC4J//DTD Dashboard 1.0//EN" "http://mc4j.sourceforge.net/Dashboard_1_0.dtd">
+
+<Dashboard version="1.0" name="Qpid AMQ Queues">
+
+  <Description>This dashboard shows the statistics of all Qpid Queues.</Description>
+
+  <DashboardMatch type="Global" location="/Qpid/Queues">
+      <BeanMatch id="ConnectionBeanList" type="Multiple">
+          <Condition type="BeanObjectNameCondition" filter="type=Queue"/>
+      </BeanMatch>
+  </DashboardMatch>
+
+  <LayoutManager type="java.awt.BorderLayout"/>
+  <Content>
+
+    <!-- *** The header section displays title and a refresh control *** -->
+    <Component type="javax.swing.JPanel">
+        <Constraint type="BorderConstraints" direction="NORTH"/>
+        <LayoutManager type="java.awt.BorderLayout"/>
+        <Border type="javax.swing.border.EmptyBorder" top="(Literal)2" left="(Literal)5" bottom="(Literal)2" right="(Literal)5"/>
+        <Content>
+            <Component type="javax.swing.JPanel">
+                <Constraint type="BorderConstraints" direction="CENTER"/>
+                <LayoutManager type="java.awt.BorderLayout"/>
+                <Content>
+                    <Component type="javax.swing.JLabel" id="titleLable">
+                        <Constraint type="BorderConstraints" direction="CENTER"/>
+                        <Attribute name="text" value="DashboardName"/>
+                        <Attribute name="font" value="(Literal)SansSerif bold 20"/>
+                        <Attribute name="foreground" value="(Literal)0x666666"/>
+                    </Component>
+                    <Component type="javax.swing.JTextArea">
+                        <Constraint type="BorderConstraints" direction="SOUTH"/>
+                        <Attribute name="text" value="DashboardDescription"/>
+                        <Attribute name="font" value="(Literal)DialogInput bold 14"/>
+                        <Attribute name="opaque" value="(Literal)false"/>
+                        <Attribute name="editable" value="(Literal)false"/>
+                    </Component>
+                </Content>
+            </Component>
+            <Component type="org.mc4j.console.dashboard.components.RefreshControlComponent">
+                <Constraint type="BorderConstraints" direction="EAST"/>
+                <Attribute name="refreshDelay" value="(Literal)1000"/>
+            </Component>
+        </Content>
+    </Component>
+
+
+    <Component type="org.mc4j.console.dashboard.components.AttributeTableComponent">
+        <Attribute name="beanList" value="ConnectionBeanList"/>
+        <Constraint type="BorderConstraints" direction="CENTER"/>
+
+        <Attribute name="background" value="(Literal)0xFFFFFF"/>
+        <Attribute name="preferredSize" value="100,100"/>
+
+        <Attribute name="AttributeName" value="(Literal)Name"/>
+        <Attribute name="AttributeName" value="(Literal)AutoDelete"/>
+        <Attribute name="AttributeName" value="(Literal)Durable"/>
+        <Attribute name="AttributeName" value="(Literal)Owner"/>
+        <Attribute name="AttributeName" value="(Literal)MessageCount"/>
+    </Component>
+
+
+  </Content>
+</Dashboard>

Propchange: incubator/qpid/trunk/qpid/java/management/mc4j/qpid/BlazeQueues.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/qpid/trunk/qpid/java/management/mc4j/qpid/BlazeSingleQueue.xml
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/management/mc4j/qpid/BlazeSingleQueue.xml?view=auto&rev=447994
==============================================================================
--- incubator/qpid/trunk/qpid/java/management/mc4j/qpid/BlazeSingleQueue.xml (added)
+++ incubator/qpid/trunk/qpid/java/management/mc4j/qpid/BlazeSingleQueue.xml Tue Sep 19 15:06:50 2006
@@ -0,0 +1,99 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ -
+ - Copyright (c) 2006 The Apache Software Foundation
+ -
+ - Licensed under the Apache License, Version 2.0 (the "License");
+ - you may not use this file except in compliance with the License.
+ - You may obtain a copy of the License at
+ -
+ -    http://www.apache.org/licenses/LICENSE-2.0
+ -
+ - Unless required by applicable law or agreed to in writing, software
+ - distributed under the License is distributed on an "AS IS" BASIS,
+ - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ - See the License for the specific language governing permissions and
+ - limitations under the License.
+ -
+ -->
+<!DOCTYPE Dashboard PUBLIC "-//MC4J//DTD Dashboard 1.0//EN" "http://mc4j.sourceforge.net/Dashboard_1_0.dtd">
+
+<Dashboard version="1.0" name="Qpid Queue Statistics Graph">
+
+  <Description>This dashboard shows the statistics of a Qpid Queue</Description>
+ 
+  <DashboardMatch type="Bean">
+      <BeanMatch id="QueueNode" type="Single">
+          <Condition type="BeanObjectNameCondition" filter="type=Queue"/>
+      </BeanMatch>
+  </DashboardMatch>
+
+  <LayoutManager type="java.awt.BorderLayout"/>
+  <Content>
+    
+    <!-- *** The header section displays title and a refresh control *** -->
+    <Component type="javax.swing.JPanel">
+        <Constraint type="BorderConstraints" direction="NORTH"/>
+        <LayoutManager type="java.awt.BorderLayout"/>
+        <Border type="javax.swing.border.EmptyBorder" top="(Literal)2" left="(Literal)5" bottom="(Literal)2" right="(Literal)5"/>
+        <Content>
+            <Component type="javax.swing.JPanel">
+                <Constraint type="BorderConstraints" direction="CENTER"/>
+                <LayoutManager type="java.awt.BorderLayout"/>
+                <Content>
+                    <Component type="javax.swing.JLabel" id="titleLable">
+                        <Constraint type="BorderConstraints" direction="CENTER"/>
+                        <Attribute name="text" value="DashboardName"/>
+                        <Attribute name="font" value="(Literal)SansSerif bold 20"/>
+                        <Attribute name="foreground" value="(Literal)0x666666"/>
+                    </Component>
+                    <Component type="javax.swing.JTextArea">
+                        <Constraint type="BorderConstraints" direction="SOUTH"/>
+                        <Attribute name="text" value="DashboardDescription"/>
+                        <Attribute name="font" value="(Literal)DialogInput bold 14"/>
+                        <Attribute name="opaque" value="(Literal)false"/>
+                        <Attribute name="editable" value="(Literal)false"/>
+                    </Component>
+                </Content>
+            </Component>
+        </Content>
+    </Component>
+    
+    
+    <!-- *** Scroll pane of info *** -->
+    <Component type="javax.swing.JScrollPane">
+            <Attribute name="background" value="(Literal)0xFFFFFF"/>
+            <Content>
+                <Component type="javax.swing.JPanel">
+                    <Attribute name="background" value="(Literal)0xFFFFFF"/>
+                    <Constraint type="BorderConstraints" direction="CENTER"/>
+                    <Attribute name="preferredSize" value="100,100"/>
+                    <LayoutManager type="java.awt.BoxLayout" axis="Y_AXIS"/>
+                    <Content>
+
+                        <Component type="org.mc4j.console.swing.SectionHolder">
+                            <Attribute name="title" value="(Literal)Queue Depth"/>
+                            <Attribute name="background" value="(Literal)0xFFFFFF"/>
+                            <LayoutManager type="java.awt.GridLayout" rows="1" cols="1"/>
+                            <Content>
+                                <Component type="org.mc4j.console.dashboard.components.NumericAttributeGraph">
+                                    <Attribute name="beanNode" value="QueueNode"/>
+
+                                    <Attribute name="preferredSize" value="(Literal)400,150"/>
+                                    <Attribute name="attributeName" value="(Literal)MessageCount"/>
+                                 </Component>
+                            </Content>
+                        </Component>
+
+                        <Component type="org.mc4j.console.dashboard.components.FillerComponent">
+                            <Attribute name="type" value="(Literal)VERTICAL_GLUE_SHAPE"/>
+                        </Component>
+                    </Content>
+    
+                </Component>
+            </Content>
+    </Component>
+    
+    
+  </Content>
+</Dashboard>

Propchange: incubator/qpid/trunk/qpid/java/management/mc4j/qpid/BlazeSingleQueue.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/qpid/trunk/qpid/java/management/webapp/META-INF/context.xml
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/management/webapp/META-INF/context.xml?view=auto&rev=447994
==============================================================================
--- incubator/qpid/trunk/qpid/java/management/webapp/META-INF/context.xml (added)
+++ incubator/qpid/trunk/qpid/java/management/webapp/META-INF/context.xml Tue Sep 19 15:06:50 2006
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ -
+ - Copyright (c) 2006 The Apache Software Foundation
+ -
+ - Licensed under the Apache License, Version 2.0 (the "License");
+ - you may not use this file except in compliance with the License.
+ - You may obtain a copy of the License at
+ -
+ -    http://www.apache.org/licenses/LICENSE-2.0
+ -
+ - Unless required by applicable law or agreed to in writing, software
+ - distributed under the License is distributed on an "AS IS" BASIS,
+ - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ - See the License for the specific language governing permissions and
+ - limitations under the License.
+ -
+ -->
+<Context path="/">
+</Context>

Propchange: incubator/qpid/trunk/qpid/java/management/webapp/META-INF/context.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/qpid/trunk/qpid/java/management/webapp/WEB-INF/web.xml
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/management/webapp/WEB-INF/web.xml?view=auto&rev=447994
==============================================================================
--- incubator/qpid/trunk/qpid/java/management/webapp/WEB-INF/web.xml (added)
+++ incubator/qpid/trunk/qpid/java/management/webapp/WEB-INF/web.xml Tue Sep 19 15:06:50 2006
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ -
+ - Copyright (c) 2006 The Apache Software Foundation
+ -
+ - Licensed under the Apache License, Version 2.0 (the "License");
+ - you may not use this file except in compliance with the License.
+ - You may obtain a copy of the License at
+ -
+ -    http://www.apache.org/licenses/LICENSE-2.0
+ -
+ - Unless required by applicable law or agreed to in writing, software
+ - distributed under the License is distributed on an "AS IS" BASIS,
+ - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ - See the License for the specific language governing permissions and
+ - limitations under the License.
+ -
+ -->
+
+<web-app version="2.4"
+         xmlns="http://java.sun.com/xml/ns/j2ee"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" >
+</web-app>

Propchange: incubator/qpid/trunk/qpid/java/management/webapp/WEB-INF/web.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/qpid/trunk/qpid/java/module.xml
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/module.xml?view=auto&rev=447994
==============================================================================
--- incubator/qpid/trunk/qpid/java/module.xml (added)
+++ incubator/qpid/trunk/qpid/java/module.xml Tue Sep 19 15:06:50 2006
@@ -0,0 +1,230 @@
+<!--
+ -
+ - Copyright (c) 2006 The Apache Software Foundation
+ -
+ - Licensed under the Apache License, Version 2.0 (the "License");
+ - you may not use this file except in compliance with the License.
+ - You may obtain a copy of the License at
+ -
+ -    http://www.apache.org/licenses/LICENSE-2.0
+ -
+ - Unless required by applicable law or agreed to in writing, software
+ - distributed under the License is distributed on an "AS IS" BASIS,
+ - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ - See the License for the specific language governing permissions and
+ - limitations under the License.
+ -
+ -->
+<project name="module">
+
+  <import file="common.xml"/>
+
+  <map property="module" value="${basedir}">
+    <globmapper from="${project.root}${file.separator}*" to="*"/>
+  </map>
+
+  <property name="module.dir" value="${build.dir}/${module}"/>
+  <property name="module.classes" value="${module.dir}/${classes.dir}"/>
+  <property name="module.precompiled" value="${module.dir}/${src.dir}"/>
+
+  <map property="module.name" value="${module}">
+    <filtermapper>
+      <replacestring from="${file.separator}" to="-"/>
+    </filtermapper>
+  </map>
+
+  <property name="module.jar" location="${module.dir}/${module.name}.jar"/>
+  <property name="module.launcher"
+            location="${module.dir}/${module.name}${launcher.sfx}"/>
+  <property name="module.manifest"
+            location="${module.dir}/${module.name}.mf"/>
+  <property name="module.doc" location="${module.dir}/${doc.dir}"/>
+  <property name="module.src" location="${src.dir}"/>
+  <property name="module.lib" location="${lib.dir}"/>
+  <property name="module.etc" location="${etc.dir}"/>
+
+  <!-- module.depends is supplied by the importing file -->
+  <pathconvert property="module.depends.dirs" pathSep=" ">
+    <path>
+      <dirset dir="${project.root}" includes="${module.depends}"/>
+    </path>
+    <globmapper from="${project.root}${file.separator}*" to="*"/>
+  </pathconvert>
+
+  <map property="module.depends.names" value="${module.depends.dirs}">
+    <filtermapper>
+      <replacestring from="${file.separator}" to="-"/>
+    </filtermapper>
+  </map>
+
+  <map property="module.depends.libs" value="${module.depends.dirs}"
+       setonempty="false">
+    <regexpmapper from="(.*)" to="\1/${lib.dir}/\*\*\/*\.jar" handledirsep="/"/>
+  </map>
+  <map property="module.depends.classes" value="${module.depends.dirs}" join=":">
+    <globmapper from="*" to="${build.dir}/*/${classes.dir}"/>
+  </map>
+
+  <path id="module.src.path">
+    <pathelement location="${module.src}"/>
+    <pathelement location="${module.precompiled}"/>
+  </path>
+
+  <path id="module.class.path">
+    <pathelement location="${module.classes}"/>
+    <fileset dir="${module.lib}" includes="**/*.jar"/>
+    <pathelement path="${module.depends.classes}"/>
+    <fileset dir="${project.root}" includes="${module.depends.libs}"/>
+  </path>
+
+  <pathconvert property="module.manifest.jars" pathsep=" " dirsep="/">
+    <path>
+      <fileset dir="${module.lib}" includes="**/*.jar"/>
+    </path>
+    <globmapper from="${module.lib}${file.separator}*" to="*"/>
+  </pathconvert>
+
+  <map property="module.manifest.deps" value="${module.depends.dirs}">
+    <globmapper from="*" to="*${launcher.sfx}"/>
+  </map>
+
+  <property name="module.manifest.classpath"
+            value="${module.name}.jar ${module.manifest.jars} ${module.manifest.deps}"/>
+
+  <target name="debug">
+    <echo message="basedir = ${basedir}"/>
+    <echo message = "project.root = ${project.root}"/>
+    <echo message = "module = ${module}"/>
+    <echo message = "module.name = ${module.name}"/>
+    <echo message = "module.jar = ${module.jar}"/>
+    <echo message = "module.depends = ${module.depends}"/>
+    <echo message = "module.depends.libs = ${module.depends.libs}"/>
+    <echo message = "module.depends.dirs = ${module.depends.dirs}"/>
+    <echo message = "module.depends.classes = ${module.depends.classes}"/>
+
+    <pathconvert property="module.class.path" refid="module.class.path"/>
+    <echo message = "module.class.path = ${module.class.path}"/>
+    <pathconvert property="pretty.module.class.path"
+                 refid="module.class.path"
+                 pathsep="${line.separator}|   |-- "/>
+    <echo message = "pretty.module.class.path = ${pretty.module.class.path}"/>
+
+    <pathconvert property="module.src.path" refid="module.src.path"/>
+    <echo message= "module.src.path = ${module.src.path}"/>
+    <pathconvert property="pretty.module.src.path"
+                 refid="module.src.path"
+                 pathsep="${line.separator}|   |-- "/>
+    <echo message = "pretty.module.src.path = ${pretty.module.src.path}"/>
+  </target>
+
+  <target name="prepare">
+    <mkdir dir="${module.classes}"/>
+    <mkdir dir="${module.precompiled}"/>
+    <mkdir dir="${module.doc}"/>
+  </target>
+
+  <target name="precompile"/>
+
+  <target name="compile" depends="prepare,precompile">
+    <javac destdir="${module.classes}" target="${java.target}"
+           source="${java.source}" debug="on">
+      <src refid="module.src.path"/>
+      <classpath refid="module.class.path"/>
+    </javac>
+
+    <!-- copy any non java src files into the build tree, e.g. log4j.properties -->
+    <copy todir="${module.classes}" verbose="true">
+      <fileset dir="${module.src}">
+        <exclude name="**/*.java"/>
+        <exclude name="**/package.html"/>
+      </fileset>
+    </copy>
+  </target>
+
+  <target name="dist-bin">
+    <mkdir dir="${destdir}"/>
+    <copy todir="${destdir}" failonerror="false">
+      <fileset dir="${src.bin}"/>
+    </copy>
+    <chmod dir="${destdir}" perm="ugo+rx" includes="**/*"/>
+  </target>
+
+  <target name="build" depends="compile">
+    <antcall target="dist-bin">
+      <param name="destdir" value="${build.dir}/${bin.dir}"/>
+    </antcall>
+    <copy todir="${build.dir}/${etc.dir}" failonerror="false">
+      <fileset dir="${module.etc}" excludes="**/*.conf"/>
+    </copy>
+    <copy todir="${build.dir}/${etc.dir}" failonerror="false">
+      <fileset dir="${build.dir}/${etc.dir}" includes="**/*.dev"/>
+      <mapper>
+        <globmapper from="*.dev" to="*"/>
+      </mapper>
+    </copy>
+  </target>
+
+  <target name="test"/>
+
+  <uptodate property="doc.done" targetfile="${module.doc}/index.html">
+    <srcfiles dir="${module.src}" includes="**/*.java"/>
+  </uptodate>
+
+  <target name="doc" depends="prepare" unless="doc.done">
+    <javadoc destdir="${module.doc}" sourcepathref="module.src.path"
+             classpathref="module.class.path" packagenames="*"/>
+  </target>
+
+  <target name="jar" depends="build">
+    <jar destfile="${module.jar}" basedir="${module.classes}"/>
+  </target>
+
+  <target name="manifest-main" if="module.main">
+    <manifest file="${module.manifest}">
+      <attribute name="Main-Class" value="${module.main}"/>
+      <attribute name="Class-Path" value="${module.manifest.classpath}"/>
+    </manifest>
+  </target>
+
+  <target name="manifest-lib" unless="module.main">
+    <manifest file="${module.manifest}">
+      <attribute name="Class-Path" value="${module.manifest.classpath}"/>
+    </manifest>
+  </target>
+
+  <target name="launcher" depends="manifest-main,manifest-lib">
+    <jar destfile="${module.launcher}" manifest="${module.manifest}"/>
+  </target>
+
+  <condition property="module.nodist">
+    <and>
+      <isset property="module.dist"/>
+      <isfalse value="${module.dist}"/>
+    </and>
+  </condition>
+
+  <target name="dist-lib" depends="jar,launcher,doc" unless="module.nodist">
+    <copy todir="${dist.lib}" file="${module.jar}"/>
+    <copy todir="${dist.lib}" file="${module.launcher}"/>
+    <copy todir="${dist.lib}" failonerror="false">
+      <fileset dir="${module.lib}"/>
+    </copy>
+    <copy todir="${dist.doc}/${module}">
+      <fileset dir="${module.doc}"/>
+    </copy>
+  </target>
+
+  <target name="dist" depends="dist-lib" unless="module.nodist">
+    <antcall target="dist-bin">
+      <param name="destdir" value="${dist.bin}"/>
+    </antcall>
+    <copy todir="${dist.etc}" failonerror="false">
+      <fileset dir="${module.etc}" excludes="**/*.dev"/>
+    </copy>
+  </target>
+
+  <target name="clean">
+    <delete dir="${module.dir}"/>
+  </target>
+
+</project>

Propchange: incubator/qpid/trunk/qpid/java/module.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/qpid/trunk/qpid/java/tasks/src/org/apache/qpid/tasks/BaseTask.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/tasks/src/org/apache/qpid/tasks/BaseTask.java?view=auto&rev=447994
==============================================================================
--- incubator/qpid/trunk/qpid/java/tasks/src/org/apache/qpid/tasks/BaseTask.java (added)
+++ incubator/qpid/trunk/qpid/java/tasks/src/org/apache/qpid/tasks/BaseTask.java Tue Sep 19 15:06:50 2006
@@ -0,0 +1,71 @@
+/*
+ *
+ * Copyright (c) 2006 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.qpid.tasks;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Task;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * BaseTask -- an abstract base task for blaze specific tasks.
+ **/
+
+public abstract class BaseTask extends Task {
+
+    private static Set EMPTY = new HashSet();
+    {
+        EMPTY.add(0);
+        EMPTY.add("");
+    }
+
+    public static class Validator {
+
+        private String name;
+        private Object value;
+
+        private  Validator(String name, Object value) {
+            this.name = name;
+            this.value = value;
+        }
+
+        public Validator required() {
+            if (value == null) {
+                error("value is required");
+            }
+            return this;
+        }
+
+        public Validator nonempty() {
+            if (EMPTY.contains(value)) {
+                error("value is empty");
+            }
+            return this;
+        }
+
+        private void error(String msg) {
+            throw new BuildException(name + ": " + msg);
+        }
+    }
+
+    public Validator validate(String name, Object value) {
+        return new Validator(name, value);
+    }
+
+}

Propchange: incubator/qpid/trunk/qpid/java/tasks/src/org/apache/qpid/tasks/BaseTask.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/qpid/trunk/qpid/java/tasks/src/org/apache/qpid/tasks/Foreach.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/tasks/src/org/apache/qpid/tasks/Foreach.java?view=auto&rev=447994
==============================================================================
--- incubator/qpid/trunk/qpid/java/tasks/src/org/apache/qpid/tasks/Foreach.java (added)
+++ incubator/qpid/trunk/qpid/java/tasks/src/org/apache/qpid/tasks/Foreach.java Tue Sep 19 15:06:50 2006
@@ -0,0 +1,81 @@
+/*
+ *
+ * Copyright (c) 2006 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.qpid.tasks;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.TaskContainer;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Foreach -- an ant task that allows iteration.
+ **/
+
+public class Foreach extends BaseTask implements TaskContainer {
+
+    private String property;
+    private String list;
+    private String delim = "\\s+";
+    private String stop;
+    private List<Task> tasks = new ArrayList<Task>();
+
+    public void setProperty(String p) {
+        property = p;
+    }
+
+    public void setList(String l) {
+        list = l;
+    }
+
+    public void setDelim(String d) {
+        delim = d;
+    }
+
+    public void setStop(String s) {
+        stop = s;
+    }
+
+    public void addTask(Task t) {
+        tasks.add(t);
+    }
+
+    public void execute() {
+        validate("property", property).required().nonempty();
+        validate("list", property).required();
+
+        if (list.length() == 0) {
+            return;
+        }
+
+        String[] values = list.split(delim);
+        for (int i = 0; i < values.length; i++) {
+            String value = values[i];
+            if (stop != null && stop.length() > 0 &&
+                value.equals(stop)) {
+                break;
+            }
+            getProject().setProperty(property, value);
+            for (Task t : tasks) {
+                t.perform();
+            }
+        }
+    }
+
+}

Propchange: incubator/qpid/trunk/qpid/java/tasks/src/org/apache/qpid/tasks/Foreach.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/qpid/trunk/qpid/java/tasks/src/org/apache/qpid/tasks/Map.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/tasks/src/org/apache/qpid/tasks/Map.java?view=auto&rev=447994
==============================================================================
--- incubator/qpid/trunk/qpid/java/tasks/src/org/apache/qpid/tasks/Map.java (added)
+++ incubator/qpid/trunk/qpid/java/tasks/src/org/apache/qpid/tasks/Map.java Tue Sep 19 15:06:50 2006
@@ -0,0 +1,91 @@
+/*
+ *
+ * Copyright (c) 2006 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.qpid.tasks;
+
+import org.apache.tools.ant.BuildException;
+
+import org.apache.tools.ant.util.ChainedMapper;
+import org.apache.tools.ant.util.FileNameMapper;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Map -- an ant task that allows arbitrary use of FileNameMappers
+ **/
+
+public class Map extends BaseTask {
+
+    private String property;
+    private String value;
+    private String split = "\\s+";
+    private String join = " ";
+    private boolean setonempty = true;
+    private ChainedMapper mapper = new ChainedMapper();
+
+    public void setProperty(String p) {
+        property = p;
+    }
+
+    public void setValue(String v) {
+        value = v;
+    }
+
+    public void setSplit(String s) {
+        split = s;
+    }
+
+    public void setJoin(String j) {
+        join = j;
+    }
+
+    public void setSetonempty(boolean b) {
+        setonempty = b;
+    }
+
+    public void add(FileNameMapper m) {
+        mapper.add(m);
+    }
+
+    public void execute() {
+        validate("property", property).required().nonempty();
+        validate("value", value).required();
+
+        if (mapper.getMappers().size() == 0) {
+            throw new BuildException("at least one mapper must is required");
+        }
+
+        String[] parts = value.split(split);
+        StringBuffer buf = new StringBuffer();
+        for (int i = 0; i < parts.length; i++) {
+            if (parts[i].length() == 0) { continue; }
+            String[] names = mapper.mapFileName(parts[i]);
+            for (int j = 0; j < names.length; j++) {
+                if (buf.length() > 0) {
+                    buf.append(join);
+                }
+                buf.append(names[j]);
+            }
+        }
+
+        if (buf.length() > 0 || setonempty) {
+            getProject().setNewProperty(property, buf.toString());
+        }
+    }
+
+}

Propchange: incubator/qpid/trunk/qpid/java/tasks/src/org/apache/qpid/tasks/Map.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/qpid/trunk/qpid/java/tasks/src/org/apache/qpid/tasks/Require.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/tasks/src/org/apache/qpid/tasks/Require.java?view=auto&rev=447994
==============================================================================
--- incubator/qpid/trunk/qpid/java/tasks/src/org/apache/qpid/tasks/Require.java (added)
+++ incubator/qpid/trunk/qpid/java/tasks/src/org/apache/qpid/tasks/Require.java Tue Sep 19 15:06:50 2006
@@ -0,0 +1,62 @@
+package org.apache.qpid.tasks;
+
+import org.apache.tools.ant.taskdefs.Ant;
+
+import java.io.File;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Require
+ *
+ * @author Rafael H. Schloming &lt;rhs@mit.edu&gt;
+ **/
+
+public class Require extends BaseTask {
+
+    private File file;
+    private String target = "";
+    private Ant ant = null;
+    private String key = "";
+
+    public void setFile(File f) {
+        file = f;
+    }
+
+    public void setTarget(String t) {
+        target = t;
+    }
+
+    public void setKey(String k) {
+        key = k;
+    }
+
+    public void execute() {
+        validate("file", file).required();
+
+        String path = file.getAbsolutePath();
+        String hash = Require.class.getName() + ":" +
+            path + ":" + target + ":" + key;
+
+        synchronized (System.class) {
+            if (System.getProperty(hash) != null) {
+                return;
+            }
+
+            Ant ant = (Ant) getProject().createTask("ant");
+            ant.setInheritAll(false);
+            ant.setOwningTarget(getOwningTarget());
+            ant.setTaskName(getTaskName());
+            ant.init();
+            if (target.length() > 0) {
+                ant.setTarget(target);
+            }
+            ant.setAntfile(path);
+            ant.setDir(file.getParentFile());
+            ant.execute();
+
+            System.setProperty(hash, "done");
+        }
+    }
+
+}

Propchange: incubator/qpid/trunk/qpid/java/tasks/src/org/apache/qpid/tasks/Require.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/qpid/trunk/qpid/python/README.txt
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/python/README.txt?view=auto&rev=447994
==============================================================================
--- incubator/qpid/trunk/qpid/python/README.txt (added)
+++ incubator/qpid/trunk/qpid/python/README.txt Tue Sep 19 15:06:50 2006
@@ -0,0 +1,24 @@
+= RUNNING THE PYTHON TESTS =
+
+The tests/ directory contains a collection of python unit tests to
+exercise functions of a broker.
+
+Simplest way to run the tests:
+
+ * Run a broker on the default port
+
+ * ./run_tests
+
+For additional options: ./run_tests --help
+
+
+== Expected failures ==
+
+Until we complete functionality, tests may fail because the tested
+functionality is missing in the broker. To skip expected failures
+in the C++ or Java brokers:
+
+ ./run_tests -I cpp_failing.txt
+ ./run_tests -I java_failing.txt
+
+If you fix a failure, please remove it from the corresponding list.

Propchange: incubator/qpid/trunk/qpid/python/README.txt
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/qpid/trunk/qpid/python/amqp-doc
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/python/amqp-doc?view=auto&rev=447994
==============================================================================
--- incubator/qpid/trunk/qpid/python/amqp-doc (added)
+++ incubator/qpid/trunk/qpid/python/amqp-doc Tue Sep 19 15:06:50 2006
@@ -0,0 +1,75 @@
+#!/usr/bin/env python
+#
+# Copyright (c) 2006 The Apache Software Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+import sys, re
+from qpid.spec import load, pythonize
+from getopt import gnu_getopt as getopt, GetoptError
+from fnmatch import fnmatchcase as fnmatch
+
+def die(msg):
+  print >> sys.stderr, msg
+  sys.exit(1)
+
+def usage(msg = ""):
+  return ("""%s
+
+Usage %s [<options>] [<pattern_1> ... <pattern_n>]
+
+Options:
+  -e, --regexp         use regex instead of glob when matching
+  -s, --spec <url>     location of amqp.xml
+""" % (msg, sys.argv[0])).strip()
+
+try:
+  opts, args = getopt(sys.argv[1:], "s:e", ["regexp", "spec="])
+except GetoptError, e:
+  die(str(e))
+
+regexp = False
+spec = "../specs/amqp-8.0.xml"
+for k, v in opts:
+  if k == "-e" or k == "--regexp": regexp = True
+  if k == "-s" or k == "--spec": spec = v
+
+if regexp:
+  def match(pattern, value):
+    try:
+      return re.match(pattern, value)
+    except Exception, e:
+      die("error: '%s': %s" % (pattern, e))
+else:
+  def match(pattern, value):
+    return fnmatch(value, pattern)
+
+spec = load(spec)
+methods = {}
+patterns = args
+for pattern in patterns:
+  for c in spec.classes:
+    for m in c.methods:
+      name = pythonize("%s_%s" % (c.name, m.name))
+      if match(pattern, name):
+        methods[name] = m.define_method(name)
+
+if patterns:
+  if methods:
+    AMQP = type("AMQP[%s]" % ", ".join(patterns), (), methods)
+  else:
+    die("no matches")
+else:
+  AMQP = spec.define_class("AMQP")
+
+help(AMQP)

Propchange: incubator/qpid/trunk/qpid/python/amqp-doc
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/qpid/trunk/qpid/python/cpp_failing.txt
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/python/cpp_failing.txt?view=auto&rev=447994
==============================================================================
    (empty)

Propchange: incubator/qpid/trunk/qpid/python/cpp_failing.txt
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/qpid/trunk/qpid/python/doc/test-requirements.txt
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/python/doc/test-requirements.txt?view=auto&rev=447994
==============================================================================
--- incubator/qpid/trunk/qpid/python/doc/test-requirements.txt (added)
+++ incubator/qpid/trunk/qpid/python/doc/test-requirements.txt Tue Sep 19 15:06:50 2006
@@ -0,0 +1,10 @@
+ * start and stop server, possibly in different configurations, should
+   at least be able to specify host and port
+
+ * initiate multiple connections/server
+
+ * initiate multiple channels/connection
+
+ * enable positive and negative tests for any protocol interaction
+
+ * test harness must be as robust as possible to spec changes

Propchange: incubator/qpid/trunk/qpid/python/doc/test-requirements.txt
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/qpid/trunk/qpid/python/java_failing.txt
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/python/java_failing.txt?view=auto&rev=447994
==============================================================================
--- incubator/qpid/trunk/qpid/python/java_failing.txt (added)
+++ incubator/qpid/trunk/qpid/python/java_failing.txt Tue Sep 19 15:06:50 2006
@@ -0,0 +1,13 @@
+tests.basic.BasicTests.test_consume_exclusive
+tests.basic.BasicTests.test_consume_no_local
+tests.basic.BasicTests.test_consume_queue_errors
+tests.basic.BasicTests.test_consume_unique_consumers
+tests.exchange.RecommendedTypesRuleTests.testFanout
+tests.exchange.RequiredInstancesRuleTests.testAmqFanOut
+tests.queue.QueueTests.test_declare_exclusive
+tests.queue.QueueTests.test_declare_passive
+tests.queue.QueueTests.test_delete_ifempty
+tests.queue.QueueTests.test_delete_ifunused
+tests.queue.QueueTests.test_delete_simple
+tests.queue.QueueTests.test_purge
+tests.queue.QueueTests.test_bind

Propchange: incubator/qpid/trunk/qpid/python/java_failing.txt
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/qpid/trunk/qpid/python/pal2py
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/python/pal2py?view=auto&rev=447994
==============================================================================
--- incubator/qpid/trunk/qpid/python/pal2py (added)
+++ incubator/qpid/trunk/qpid/python/pal2py Tue Sep 19 15:06:50 2006
@@ -0,0 +1,255 @@
+#!/usr/bin/env python
+import sys, os, xml
+
+from qpid.spec import load, pythonize
+from textwrap import TextWrapper
+from xml.sax.handler import ContentHandler
+
+class Block:
+
+  def __init__(self, children):
+    self.children = children
+
+  def emit(self, out):
+    for child in self.children:
+      if not hasattr(child, "emit"):
+        raise ValueError(child)
+      child.emit(out)
+
+    if not self.children:
+      out.line("pass")
+
+class If:
+
+  def __init__(self, expr, cons, alt = None):
+    self.expr = expr
+    self.cons = cons
+    self.alt = alt
+
+  def emit(self, out):
+    out.line("if ")
+    self.expr.emit(out)
+    out.write(":")
+    out.level += 1
+    self.cons.emit(out)
+    out.level -= 1
+    if self.alt:
+      out.line("else:")
+      out.level += 1
+      self.alt.emit(out)
+      out.level -= 1
+
+class Stmt:
+
+  def __init__(self, code):
+    self.code = code
+
+  def emit(self, out):
+    out.line(self.code)
+
+class Expr:
+
+  def __init__(self, code):
+    self.code = code
+
+  def emit(self, out):
+    out.write(self.code)
+
+class Abort:
+
+  def __init__(self, expr):
+    self.expr = expr
+
+  def emit(self, out):
+    out.line("assert False, ")
+    self.expr.emit(out)
+
+WRAPPER = TextWrapper()
+
+def wrap(text):
+  return WRAPPER.wrap(" ".join(text.split()))
+
+class Doc:
+
+  def __init__(self, text):
+    self.text = text
+
+  def emit(self, out):
+    out.line('"""')
+    for line in wrap(self.text):
+      out.line(line)
+    out.line('"""')
+
+class Frame:
+
+  def __init__(self, attrs):
+    self.attrs = attrs
+    self.children = []
+    self.text = None
+
+  def __getattr__(self, attr):
+    return self.attrs[attr]
+
+def isunicode(s):
+  if isinstance(s, str):
+    return False
+  for ch in s:
+    if ord(ch) > 127:
+      return True
+  return False
+
+def string_literal(s):
+  if s == None:
+    return None
+  if isunicode(s):
+    return "%r" % s
+  else:
+    return "%r" % str(s)
+
+TRUTH = {
+  "1": True,
+  "0": False,
+  "true": True,
+  "false": False
+  }
+
+LITERAL = {
+  "shortstr": string_literal,
+  "longstr": string_literal,
+  "bit": lambda s: TRUTH[s.lower()],
+  "longlong": lambda s: "%r" % long(s)
+  }
+
+def literal(s, field):
+  return LITERAL[field.type](s)
+
+def palexpr(s, field):
+  if s.startswith("$"):
+    return "msg.%s" % s[1:]
+  else:
+    return literal(s, field)
+
+class Translator(ContentHandler):
+
+  def __init__(self, spec):
+    self.spec = spec
+    self.stack = []
+    self.content = None
+    self.root = Frame(None)
+    self.push(self.root)
+
+  def emit(self, out):
+    blk = Block(self.root.children)
+    blk.emit(out)
+    out.write("\n")
+
+  def peek(self):
+    return self.stack[-1]
+
+  def pop(self):
+    return self.stack.pop()
+
+  def push(self, frame):
+    self.stack.append(frame)
+
+  def startElement(self, name, attrs):
+    self.push(Frame(attrs))
+
+  def endElement(self, name):
+    frame = self.pop()
+    if hasattr(self, name):
+      child = getattr(self, name)(frame)
+    else:
+      child = self.handle(name, frame)
+
+    if child:
+      self.peek().children.append(child)
+
+  def characters(self, text):
+    frame = self.peek()
+    if frame.text:
+      frame.text += text
+    else:
+      frame.text = text
+
+  def handle(self, name, frame):
+    for klass in self.spec.classes:
+      pyklass = pythonize(klass.name)
+      if name.startswith(pyklass):
+        name = name[len(pyklass) + 1:]
+        break
+    else:
+      raise ValueError("unknown class: %s" % name)
+
+    for method in klass.methods:
+      pymethod = pythonize(method.name)
+      if name == pymethod:
+        break
+    else:
+      raise ValueError("unknown method: %s" % name)
+
+    args = ["%s = %s" % (key, palexpr(val, method.fields.bypyname[key]))
+            for key, val in frame.attrs.items()]
+    if method.content and self.content:
+      args.append("content = %r" % string_literal(self.content))
+    code = "ssn.%s_%s(%s)" % (pyklass, pymethod, ", ".join(args))
+    if pymethod == "consume":
+      code = "consumer_tag = %s.consumer_tag" % code
+    return Stmt(code)
+
+  def pal(self, frame):
+    return Block([Doc(frame.text)] + frame.children)
+
+  def include(self, frame):
+    base, ext = os.path.splitext(frame.filename)
+    return Stmt("from %s import *" % base)
+
+  def session(self, frame):
+    return Block([Stmt("cli = open()"), Stmt("ssn = cli.channel(0)"),
+                  Stmt("ssn.channel_open()")] + frame.children)
+
+  def empty(self, frame):
+    return If(Expr("msg == None"), Block(frame.children))
+
+  def abort(self, frame):
+    return Abort(Expr(string_literal(frame.text)))
+
+  def wait(self, frame):
+    return Stmt("msg = ssn.queue(consumer_tag).get(timeout=%r)" %
+                (int(frame.timeout)/1000))
+
+  def basic_arrived(self, frame):
+    if frame.children:
+      return If(Expr("msg != None"), Block(frame.children))
+
+  def basic_content(self, frame):
+    self.content = frame.text
+
+class Emitter:
+
+  def __init__(self, out):
+    self.out = out
+    self.level = 0
+
+  def write(self, code):
+    self.out.write(code)
+
+  def line(self, code):
+    self.write("\n%s%s" % ("  "*self.level, code))
+
+  def flush(self):
+    self.out.flush()
+
+  def close(self):
+    self.out.close()
+
+
+for f in sys.argv[2:]:
+  base, ext = os.path.splitext(f)
+  spec = load(sys.argv[1])
+  t = Translator(spec)
+  xml.sax.parse(f, t)
+#  out = Emitter(open("%s.py" % base))
+  out = Emitter(sys.stdout)
+  t.emit(out)
+  out.close()

Propchange: incubator/qpid/trunk/qpid/python/pal2py
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/qpid/trunk/qpid/python/qpid/__init__.py
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/python/qpid/__init__.py?view=auto&rev=447994
==============================================================================
--- incubator/qpid/trunk/qpid/python/qpid/__init__.py (added)
+++ incubator/qpid/trunk/qpid/python/qpid/__init__.py Tue Sep 19 15:06:50 2006
@@ -0,0 +1,17 @@
+#
+# Copyright (c) 2006 The Apache Software Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+import spec, codec, connection, content, peer, delegate, client

Propchange: incubator/qpid/trunk/qpid/python/qpid/__init__.py
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/qpid/trunk/qpid/python/qpid/client.py
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/python/qpid/client.py?view=auto&rev=447994
==============================================================================
--- incubator/qpid/trunk/qpid/python/qpid/client.py (added)
+++ incubator/qpid/trunk/qpid/python/qpid/client.py Tue Sep 19 15:06:50 2006
@@ -0,0 +1,111 @@
+#
+# Copyright (c) 2006 The Apache Software Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+"""
+An AQMP client implementation that uses a custom delegate for
+interacting with the server.
+"""
+
+import threading
+from peer import Peer, Closed
+from delegate import Delegate
+from connection import Connection, Frame
+from spec import load
+from queue import Queue
+
+
+class Client:
+
+  def __init__(self, host, port, spec, vhost = None):
+    self.host = host
+    self.port = port
+    self.spec = spec
+
+    self.mechanism = None
+    self.response = None
+    self.locale = None
+
+    self.vhost = vhost
+    if self.vhost == None:
+      self.vhost = self.host
+
+    self.queues = {}
+    self.lock = threading.Lock()
+
+    self.closed = False
+    self.started = threading.Event()
+
+    self.conn = Connection(self.host, self.port, self.spec)
+    self.peer = Peer(self.conn, ClientDelegate(self))
+
+  def wait(self):
+    self.started.wait()
+    if self.closed:
+      raise EOFError()
+
+  def queue(self, key):
+    self.lock.acquire()
+    try:
+      try:
+        q = self.queues[key]
+      except KeyError:
+        q = Queue(0)
+        self.queues[key] = q
+    finally:
+      self.lock.release()
+    return q
+
+  def start(self, response, mechanism="AMQPLAIN", locale="en_US"):
+    self.mechanism = mechanism
+    self.response = response
+    self.locale = locale
+
+    self.conn.connect()
+    self.conn.init()
+    self.peer.start()
+    self.wait()
+    self.channel(0).connection_open(self.vhost)
+
+  def channel(self, id):
+    return self.peer.channel(id)
+
+class ClientDelegate(Delegate):
+
+  def __init__(self, client):
+    Delegate.__init__(self)
+    self.client = client
+
+  def connection_start(self, ch, msg):
+    ch.connection_start_ok(mechanism=self.client.mechanism,
+                           response=self.client.response,
+                           locale=self.client.locale)
+
+  def connection_tune(self, ch, msg):
+    ch.connection_tune_ok(*msg.fields)
+    self.client.started.set()
+
+  def basic_deliver(self, ch, msg):
+    self.client.queue(msg.consumer_tag).put(msg)
+
+  def channel_close(self, ch, msg):
+    ch.close(msg)
+
+  def connection_close(self, ch, msg):
+    self.client.peer.close(msg)
+
+  def close(self, reason):
+    self.client.closed = True
+    self.client.started.set()

Propchange: incubator/qpid/trunk/qpid/python/qpid/client.py
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/qpid/trunk/qpid/python/qpid/codec.py
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/python/qpid/codec.py?view=auto&rev=447994
==============================================================================
--- incubator/qpid/trunk/qpid/python/qpid/codec.py (added)
+++ incubator/qpid/trunk/qpid/python/qpid/codec.py Tue Sep 19 15:06:50 2006
@@ -0,0 +1,221 @@
+#!/usr/bin/env python
+
+#
+# Copyright (c) 2006 The Apache Software Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+"""
+Utility code to translate between python objects and AMQP encoded data
+fields.
+"""
+
+from cStringIO import StringIO
+from struct import *
+
+class EOF(Exception):
+  pass
+
+class Codec:
+
+  def __init__(self, stream):
+    self.stream = stream
+    self.nwrote = 0
+    self.nread = 0
+    self.incoming_bits = []
+    self.outgoing_bits = []
+
+  def read(self, n):
+    data = self.stream.read(n)
+    if n > 0 and len(data) == 0:
+      raise EOF()
+    self.nread += len(data)
+    return data
+
+  def write(self, s):
+    self.flushbits()
+    self.stream.write(s)
+    self.nwrote += len(s)
+
+  def flush(self):
+    self.flushbits()
+    self.stream.flush()
+
+  def flushbits(self):
+    if len(self.outgoing_bits) > 0:
+      bytes = []
+      index = 0
+      for b in self.outgoing_bits:
+        if index == 0: bytes.append(0)
+        if b: bytes[-1] |= 1 << index
+        index = (index + 1) % 8
+      del self.outgoing_bits[:]
+      for byte in bytes:
+        self.encode_octet(byte)
+
+  def pack(self, fmt, *args):
+    self.write(pack(fmt, *args))
+
+  def unpack(self, fmt):
+    size = calcsize(fmt)
+    data = self.read(size)
+    values = unpack(fmt, data)
+    if len(values) == 1:
+      return values[0]
+    else:
+      return values
+
+  def encode(self, type, value):
+    getattr(self, "encode_" + type)(value)
+
+  def decode(self, type):
+    return getattr(self, "decode_" + type)()
+
+  # bit
+  def encode_bit(self, o):
+    if o:
+      self.outgoing_bits.append(True)
+    else:
+      self.outgoing_bits.append(False)
+
+  def decode_bit(self):
+    if len(self.incoming_bits) == 0:
+      bits = self.decode_octet()
+      for i in range(8):
+        self.incoming_bits.append(bits >> i & 1 != 0)
+    return self.incoming_bits.pop(0)
+
+  # octet
+  def encode_octet(self, o):
+    self.pack("!B", o)
+
+  def decode_octet(self):
+    return self.unpack("!B")
+
+  # short
+  def encode_short(self, o):
+    self.pack("!H", o)
+
+  def decode_short(self):
+    return self.unpack("!H")
+
+  # long
+  def encode_long(self, o):
+    self.pack("!L", o)
+
+  def decode_long(self):
+    return self.unpack("!L")
+
+  # longlong
+  def encode_longlong(self, o):
+    self.pack("!Q", o)
+
+  def decode_longlong(self):
+    return self.unpack("!Q")
+
+  def enc_str(self, fmt, s):
+    size = len(s)
+    self.pack(fmt, size)
+    self.write(s)
+
+  def dec_str(self, fmt):
+    size = self.unpack(fmt)
+    return self.read(size)
+
+  # shortstr
+  def encode_shortstr(self, s):
+    self.enc_str("!B", s)
+
+  def decode_shortstr(self):
+    return self.dec_str("!B")
+
+  # longstr
+  def encode_longstr(self, s):
+    if isinstance(s, dict):
+      self.encode_table(s)
+    else:
+      self.enc_str("!L", s)
+
+  def decode_longstr(self):
+    return self.dec_str("!L")
+
+  # table
+  def encode_table(self, tbl):
+    enc = StringIO()
+    codec = Codec(enc)
+    for key, value in tbl.items():
+      codec.encode_shortstr(key)
+      if isinstance(value, basestring):
+        codec.write("S")
+        codec.encode_longstr(value)
+      else:
+        codec.write("I")
+        codec.encode_long(value)
+    s = enc.getvalue()
+    self.encode_long(len(s))
+    self.write(s)
+
+  def decode_table(self):
+    size = self.decode_long()
+    start = self.nread
+    result = {}
+    while self.nread - start < size:
+      key = self.decode_shortstr()
+      type = self.read(1)
+      if type == "S":
+        value = self.decode_longstr()
+      elif type == "I":
+        value = self.decode_long()
+      else:
+        raise ValueError(repr(type))
+      result[key] = value
+    return result
+
+def test(type, value):
+  if isinstance(value, (list, tuple)):
+    values = value
+  else:
+    values = [value]
+  stream = StringIO()
+  codec = Codec(stream)
+  for v in values:
+    codec.encode(type, v)
+  codec.flush()
+  enc = stream.getvalue()
+  stream.reset()
+  dup = []
+  for i in xrange(len(values)):
+    dup.append(codec.decode(type))
+  if values != dup:
+    raise AssertionError("%r --> %r --> %r" % (values, enc, dup))
+
+if __name__ == "__main__":
+  def dotest(type, value):
+    args = (type, value)
+    test(*args)
+
+  for value in ("1", "0", "110", "011", "11001", "10101", "10011"):
+    for i in range(10):
+      dotest("bit", map(lambda x: x == "1", value*i))
+
+  for value in ({}, {"asdf": "fdsa", "fdsa": 1, "three": 3}, {"one": 1}):
+    dotest("table", value)
+
+  for type in ("octet", "short", "long", "longlong"):
+    for value in range(0, 256):
+      dotest(type, value)
+
+  for type in ("shortstr", "longstr"):
+    for value in ("", "a", "asdf"):
+      dotest(type, value)

Propchange: incubator/qpid/trunk/qpid/python/qpid/codec.py
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/qpid/trunk/qpid/python/qpid/connection.py
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/python/qpid/connection.py?view=auto&rev=447994
==============================================================================
--- incubator/qpid/trunk/qpid/python/qpid/connection.py (added)
+++ incubator/qpid/trunk/qpid/python/qpid/connection.py Tue Sep 19 15:06:50 2006
@@ -0,0 +1,265 @@
+#
+# Copyright (c) 2006 The Apache Software Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+"""
+A Connection class containing socket code that uses the spec metadata
+to read and write Frame objects. This could be used by a client,
+server, or even a proxy implementation.
+"""
+
+import socket, codec
+from cStringIO import StringIO
+from spec import load, pythonize
+from codec import EOF
+
+class SockIO:
+
+  def __init__(self, sock):
+    self.sock = sock
+
+  def write(self, buf):
+#    print "OUT: %r" % buf
+    self.sock.sendall(buf)
+
+  def read(self, n):
+    data = ""
+    while len(data) < n:
+      try:
+        s = self.sock.recv(n - len(data))
+      except socket.error:
+        break
+      if len(s) == 0:
+        break
+#      print "IN: %r" % s
+      data += s
+    return data
+
+  def flush(self):
+    pass
+
+class Connection:
+
+  def __init__(self, host, port, spec):
+    self.host = host
+    self.port = port
+    self.spec = spec
+    self.FRAME_END = self.spec.constants.byname["frame end"].id
+
+  def connect(self):
+    sock = socket.socket()
+    sock.connect((self.host, self.port))
+    sock.setblocking(1)
+    self.codec = codec.Codec(SockIO(sock))
+
+  def flush(self):
+    self.codec.flush()
+
+  INIT="!4s4B"
+
+  def init(self):
+    self.codec.pack(Connection.INIT, "AMQP", 1, 1, self.spec.major,
+                    self.spec.minor)
+
+  def write(self, frame):
+    c = self.codec
+    c.encode_octet(self.spec.constants.byname[frame.payload.type].id)
+    c.encode_short(frame.channel)
+    frame.payload.encode(c)
+    c.encode_octet(self.FRAME_END)
+
+  def read(self):
+    c = self.codec
+    type = self.spec.constants.byid[c.decode_octet()].name
+    channel = c.decode_short()
+    payload = Frame.DECODERS[type].decode(self.spec, c)
+    end = c.decode_octet()
+    if end != self.FRAME_END:
+      raise "frame error: expected %r, got %r" % (self.FRAME_END, end)
+    frame = Frame(channel, payload)
+    return frame
+
+class Frame:
+
+  METHOD = "frame method"
+  HEADER = "frame header"
+  BODY = "frame body"
+  OOB_METHOD = "frame oob method"
+  OOB_HEADER = "frame oob header"
+  OOB_BODY = "frame oob body"
+  TRACE = "frame trace"
+  HEARTBEAT = "frame heartbeat"
+
+  DECODERS = {}
+
+  def __init__(self, channel, payload):
+    self.channel = channel
+    self.payload = payload
+
+  def __str__(self):
+    return "[%d] %s" % (self.channel, self.payload)
+
+class Payload:
+
+  class __metaclass__(type):
+
+    def __new__(cls, name, bases, dict):
+      for req in ("encode", "decode", "type"):
+        if not dict.has_key(req):
+          raise TypeError("%s must define %s" % (name, req))
+      dict["decode"] = staticmethod(dict["decode"])
+      t = type.__new__(cls, name, bases, dict)
+      if t.type != None:
+        Frame.DECODERS[t.type] = t
+      return t
+
+  type = None
+
+  def encode(self, enc): abstract
+
+  def decode(spec, dec): abstract
+
+class Method(Payload):
+
+  type = Frame.METHOD
+
+  def __init__(self, method, *args):
+    if len(args) != len(method.fields):
+      argspec = ["%s: %s" % (pythonize(f.name), f.type)
+                 for f in method.fields]
+      raise TypeError("%s.%s expecting (%s), got %s" %
+                      (pythonize(method.klass.name),
+                       pythonize(method.name), ", ".join(argspec), args))
+    self.method = method
+    self.args = args
+
+  def encode(self, enc):
+    buf = StringIO()
+    c = codec.Codec(buf)
+    c.encode_short(self.method.klass.id)
+    c.encode_short(self.method.id)
+    for field, arg in zip(self.method.fields, self.args):
+      c.encode(field.type, arg)
+    c.flush()
+    enc.encode_longstr(buf.getvalue())
+
+  def decode(spec, dec):
+    enc = dec.decode_longstr()
+    c = codec.Codec(StringIO(enc))
+    klass = spec.classes.byid[c.decode_short()]
+    meth = klass.methods.byid[c.decode_short()]
+    args = tuple([c.decode(f.type) for f in meth.fields])
+    return Method(meth, *args)
+
+  def __str__(self):
+    return "%s %s" % (self.method, ", ".join([str(a) for a in self.args]))
+
+class Header(Payload):
+
+  type = Frame.HEADER
+
+  def __init__(self, klass, weight, size, **properties):
+    self.klass = klass
+    self.weight = weight
+    self.size = size
+    self.properties = properties
+
+  def __getitem__(self, name):
+    return self.properties[name]
+
+  def __setitem__(self, name, value):
+    self.properties[name] = value
+
+  def __delitem__(self, name):
+    del self.properties[name]
+
+  def encode(self, enc):
+    buf = StringIO()
+    c = codec.Codec(buf)
+    c.encode_short(self.klass.id)
+    c.encode_short(self.weight)
+    c.encode_longlong(self.size)
+
+    # property flags
+    nprops = len(self.klass.fields)
+    flags = 0
+    for i in range(nprops):
+      f = self.klass.fields.items[i]
+      flags <<= 1
+      if self.properties.get(f.name) != None:
+        flags |= 1
+      # the last bit indicates more flags
+      if i > 0 and (i % 15) == 0:
+        flags <<= 1
+        if nprops > (i + 1):
+          flags |= 1
+          c.encode_short(flags)
+          flags = 0
+    flags <<= ((16 - (nprops % 15)) % 16)
+    c.encode_short(flags)
+
+    # properties
+    for f in self.klass.fields:
+      v = self.properties.get(f.name)
+      if v != None:
+        c.encode(f.type, v)
+    c.flush()
+    enc.encode_longstr(buf.getvalue())
+
+  def decode(spec, dec):
+    c = codec.Codec(StringIO(dec.decode_longstr()))
+    klass = spec.classes.byid[c.decode_short()]
+    weight = c.decode_short()
+    size = c.decode_longlong()
+
+    # property flags
+    bits = []
+    while True:
+      flags = c.decode_short()
+      for i in range(15, 0, -1):
+        if flags >> i & 0x1 != 0:
+          bits.append(True)
+        else:
+          bits.append(False)
+      if flags & 0x1 == 0:
+        break
+
+    # properties
+    properties = {}
+    for b, f in zip(bits, klass.fields):
+      if b:
+        properties[f.name] = c.decode(f.type)
+
+    return Header(klass, weight, size, **properties)
+
+  def __str__(self):
+    return "%s %s %s %s" % (self.klass, self.weight, self.size,
+                            self.properties)
+
+class Body(Payload):
+
+  type = Frame.BODY
+
+  def __init__(self, content):
+    self.content = content
+
+  def encode(self, enc):
+    enc.encode_longstr(self.content)
+
+  def decode(spec, dec):
+    return Body(dec.decode_longstr())
+
+  def __str__(self):
+    return "Body(%r)" % self.content

Propchange: incubator/qpid/trunk/qpid/python/qpid/connection.py
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/qpid/trunk/qpid/python/qpid/content.py
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/python/qpid/content.py?view=auto&rev=447994
==============================================================================
--- incubator/qpid/trunk/qpid/python/qpid/content.py (added)
+++ incubator/qpid/trunk/qpid/python/qpid/content.py Tue Sep 19 15:06:50 2006
@@ -0,0 +1,47 @@
+#
+# Copyright (c) 2006 The Apache Software Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+"""
+A simple python representation for AMQP content.
+"""
+
+def default(val, defval):
+  if val == None:
+    return defval
+  else:
+    return val
+
+class Content:
+
+  def __init__(self, body = "", children = None, properties = None):
+    self.body = body
+    self.children = default(children, [])
+    self.properties = default(properties, {})
+
+  def size(self):
+    return len(self.body)
+
+  def weight(self):
+    return len(self.children)
+
+  def __getitem__(self, name):
+    return self.properties[name]
+
+  def __setitem__(self, name, value):
+    self.properties[name] = value
+
+  def __delitem__(self, name):
+    del self.properties[name]

Propchange: incubator/qpid/trunk/qpid/python/qpid/content.py
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/qpid/trunk/qpid/python/qpid/delegate.py
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/python/qpid/delegate.py?view=auto&rev=447994
==============================================================================
--- incubator/qpid/trunk/qpid/python/qpid/delegate.py (added)
+++ incubator/qpid/trunk/qpid/python/qpid/delegate.py Tue Sep 19 15:06:50 2006
@@ -0,0 +1,52 @@
+#
+# Copyright (c) 2006 The Apache Software Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+"""
+Delegate implementation intended for use with the peer module.
+"""
+
+import threading, inspect
+from spec import pythonize
+
+class Delegate:
+
+  def __init__(self):
+    self.handlers = {}
+    self.invokers = {}
+    # initialize all the mixins
+    self.invoke_all("init")
+
+  def invoke_all(self, meth, *args, **kwargs):
+    for cls in inspect.getmro(self.__class__):
+      if hasattr(cls, meth):
+        getattr(cls, meth)(self, *args, **kwargs)
+
+  def dispatch(self, channel, message):
+    method = message.method
+    spec = method.klass.spec
+
+    try:
+      handler = self.handlers[method]
+    except KeyError:
+      name = "%s_%s" % (pythonize(method.klass.name),
+                        pythonize(method.name))
+      handler = getattr(self, name)
+      self.handlers[method] = handler
+
+    return handler(channel, message)
+
+  def close(self, reason):
+    self.invoke_all("close", reason)

Propchange: incubator/qpid/trunk/qpid/python/qpid/delegate.py
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/qpid/trunk/qpid/python/qpid/message.py
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/python/qpid/message.py?view=auto&rev=447994
==============================================================================
--- incubator/qpid/trunk/qpid/python/qpid/message.py (added)
+++ incubator/qpid/trunk/qpid/python/qpid/message.py Tue Sep 19 15:06:50 2006
@@ -0,0 +1,81 @@
+#
+# Copyright (c) 2006 The Apache Software Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+from sets import Set
+
+class Message:
+
+  COMMON_FIELDS = Set(("content", "method", "fields"))
+
+  def __init__(self, method, fields, content = None):
+    self.method = method
+    self.fields = fields
+    self.content = content
+
+  def __len__(self):
+    l = len(self.fields)
+    if method.content:
+      l += 1
+    return len(self.fields)
+
+  def _idx(self, idx):
+    if idx < 0: idx += len(self)
+    if idx < 0 or idx > len(self):
+      raise IndexError(idx)
+    return idx
+
+  def __getitem__(self, idx):
+    idx = self._idx(idx)
+    if idx == len(self.fields):
+      return self.content
+    else:
+      return self.fields[idx]
+
+  def __setitem__(self, idx, value):
+    idx = self._idx(idx)
+    if idx == len(self.fields):
+      self.content = value
+    else:
+      self.fields[idx] = value
+
+  def _slot(self, attr):
+    if attr in Message.COMMON_FIELDS:
+      env = self.__dict__
+      key = attr
+    else:
+      env = self.fields
+      try:
+        field = self.method.fields.bypyname[attr]
+        key = self.method.fields.index(field)
+      except KeyError:
+        raise AttributeError(attr)
+    return env, key
+
+  def __getattr__(self, attr):
+    env, key = self._slot(attr)
+    return env[key]
+
+  def __setattr__(self, attr, value):
+    env, key = self._slot(attr)
+    env[attr] = value
+
+  STR = "%s %s content = %s"
+  REPR = STR.replace("%s", "%r")
+
+  def __str__(self):
+    return Message.STR % (self.method, self.fields, self.content)
+
+  def __repr__(self):
+    return Message.REPR % (self.method, self.fields, self.content)

Propchange: incubator/qpid/trunk/qpid/python/qpid/message.py
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/qpid/trunk/qpid/python/qpid/peer.py
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/python/qpid/peer.py?view=auto&rev=447994
==============================================================================
--- incubator/qpid/trunk/qpid/python/qpid/peer.py (added)
+++ incubator/qpid/trunk/qpid/python/qpid/peer.py Tue Sep 19 15:06:50 2006
@@ -0,0 +1,209 @@
+#
+# Copyright (c) 2006 The Apache Software Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+"""
+This module contains a skeletal peer implementation useful for
+implementing an AMQP server, client, or proxy. The peer implementation
+sorts incoming frames to their intended channels, and dispatches
+incoming method frames to a delegate.
+"""
+
+import thread, traceback, socket, sys, logging
+from connection import Frame, EOF, Method, Header, Body
+from message import Message
+from queue import Queue, Closed as QueueClosed
+from content import Content
+from cStringIO import StringIO
+
+class Peer:
+
+  def __init__(self, conn, delegate):
+    self.conn = conn
+    self.delegate = delegate
+    self.outgoing = Queue(0)
+    self.work = Queue(0)
+    self.channels = {}
+    self.Channel = type("Channel%s" % conn.spec.klass.__name__,
+                        (Channel, conn.spec.klass), {})
+    self.lock = thread.allocate_lock()
+
+  def channel(self, id):
+    self.lock.acquire()
+    try:
+      try:
+        ch = self.channels[id]
+      except KeyError:
+        ch = self.Channel(id, self.outgoing)
+        self.channels[id] = ch
+    finally:
+      self.lock.release()
+    return ch
+
+  def start(self):
+    thread.start_new_thread(self.writer, ())
+    thread.start_new_thread(self.reader, ())
+    thread.start_new_thread(self.worker, ())
+
+  def fatal(message=None):
+    """Call when an unexpected exception occurs that will kill a thread.
+
+    In this case it's better to crash the process than to continue in
+    an invalid state with a missing thread."""
+    if message: print >> sys.stderr, message
+    traceback.print_exc()
+    
+  def reader(self):
+    try:
+      while True:
+        try:
+          frame = self.conn.read()
+        except EOF, e:
+          self.close(e)
+          break
+        ch = self.channel(frame.channel)
+        ch.dispatch(frame, self.work)
+    except:
+      self.fatal()
+
+  def close(self, reason):
+    for ch in self.channels.values():
+      ch.close(reason)
+    self.delegate.close(reason)
+
+  def writer(self):
+    try:
+      while True:
+        try:
+          message = self.outgoing.get()
+          self.conn.write(message)
+        except socket.error, e:
+          self.close(e)
+          break
+        self.conn.flush()
+    except:
+      self.fatal()
+
+  def worker(self):
+    try:
+      while True:
+        self.dispatch(self.work.get())
+    except:
+      self.fatal()
+
+  def dispatch(self, queue):
+    frame = queue.get()
+    channel = self.channel(frame.channel)
+    payload = frame.payload
+    if payload.method.content:
+      content = read_content(queue)
+    else:
+      content = None
+    # Let the caller deal with exceptions thrown here.
+    message = Message(payload.method, payload.args, content)
+    self.delegate.dispatch(channel, message)
+
+class Closed(Exception): pass
+
+class Channel:
+
+  def __init__(self, id, outgoing):
+    self.id = id
+    self.outgoing = outgoing
+    self.incoming = Queue(0)
+    self.responses = Queue(0)
+    self.queue = None
+    self.closed = False
+    self.reason = None
+
+  def close(self, reason):
+    if self.closed:
+      return
+    self.closed = True
+    self.reason = reason
+    self.incoming.close()
+    self.responses.close()
+
+  def dispatch(self, frame, work):
+    payload = frame.payload
+    if isinstance(payload, Method):
+      if payload.method.response:
+        self.queue = self.responses
+      else:
+        self.queue = self.incoming
+        work.put(self.incoming)
+    self.queue.put(frame)
+
+  def invoke(self, method, args, content = None):
+    if self.closed:
+      raise Closed(self.reason)
+
+    frame = Frame(self.id, Method(method, *args))
+    self.outgoing.put(frame)
+
+    if method.content:
+      if content == None:
+        content = Content()
+      self.write_content(method.klass, content, self.outgoing)
+
+    try:
+      # here we depend on all nowait fields being named nowait
+      f = method.fields.byname["nowait"]
+      nowait = args[method.fields.index(f)]
+    except KeyError:
+      nowait = False
+
+    try:
+      if not nowait and method.responses:
+        resp = self.responses.get().payload
+        if resp.method.content:
+          content = read_content(self.responses)
+        else:
+          content = None
+        if resp.method in method.responses:
+          return Message(resp.method, resp.args, content)
+        else:
+          raise ValueError(resp)
+    except QueueClosed, e:
+      if self.closed:
+        raise Closed(self.reason)
+      else:
+        raise e
+
+  def write_content(self, klass, content, queue):
+    size = content.size()
+    header = Frame(self.id, Header(klass, content.weight(), size))
+    queue.put(header)
+    for child in content.children:
+      self.write_content(klass, child, queue)
+    # should split up if content.body exceeds max frame size
+    if size > 0:
+      queue.put(Frame(self.id, Body(content.body)))
+
+def read_content(queue):
+  frame = queue.get()
+  header = frame.payload
+  children = []
+  for i in range(header.weight):
+    children.append(read_content(queue))
+  size = header.size
+  read = 0
+  buf = StringIO()
+  while read < size:
+    body = queue.get()
+    content = body.payload.content
+    buf.write(content)
+    read += len(content)
+  return Content(buf.getvalue(), children, header.properties.copy())

Propchange: incubator/qpid/trunk/qpid/python/qpid/peer.py
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/qpid/trunk/qpid/python/qpid/queue.py
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/python/qpid/queue.py?view=auto&rev=447994
==============================================================================
--- incubator/qpid/trunk/qpid/python/qpid/queue.py (added)
+++ incubator/qpid/trunk/qpid/python/qpid/queue.py Tue Sep 19 15:06:50 2006
@@ -0,0 +1,42 @@
+#
+# Copyright (c) 2006 The Apache Software Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+"""
+This module augments the standard python multithreaded Queue
+implementation to add a close() method so that threads blocking on the
+content of a queue can be notified if the queue is no longer in use.
+"""
+
+from Queue import Queue as BaseQueue, Empty, Full
+
+class Closed(Exception): pass
+
+class Queue(BaseQueue):
+
+  END = object()
+
+  def close(self):
+    self.put(Queue.END)
+
+  def get(self, block = True, timeout = None):
+    result = BaseQueue.get(self, block, timeout)
+    if result == Queue.END:
+      # this guarantees that any other waiting threads or any future
+      # calls to get will also result in a Closed exception
+      self.put(Queue.END)
+      raise Closed()
+    else:
+      return result

Propchange: incubator/qpid/trunk/qpid/python/qpid/queue.py
------------------------------------------------------------------------------
    svn:eol-style = native