[Zope-Checkins] CVS: Zope3/lib/python/Zope/App/OFS/Services/ServiceManager/Views/Browser - AddServiceDirective.py:1.1 ComponentAdding.py:1.1 PackagesContents.py:1.1 add_service_1.pt:1.1 add_service_2.pt:1.1 packages_contents.pt:1.1 Adding.py:1.2 Bindings.py:1.3 configure.zcml:1.7 services_bindings.pt:1.3 Contents.py:NONE ServiceAdding.py:NONE add.pt:NONE

Jim Fulton jim@zope.com
Thu, 11 Jul 2002 14:22:04 -0400


Update of /cvs-repository/Zope3/lib/python/Zope/App/OFS/Services/ServiceManager/Views/Browser
In directory cvs.zope.org:/tmp/cvs-serv7355/lib/python/Zope/App/OFS/Services/ServiceManager/Views/Browser

Modified Files:
	Adding.py Bindings.py configure.zcml services_bindings.pt 
Added Files:
	AddServiceDirective.py ComponentAdding.py PackagesContents.py 
	add_service_1.pt add_service_2.pt packages_contents.pt 
Removed Files:
	Contents.py ServiceAdding.py add.pt 
Log Message:

Reimplemented service managers to be package based. Service managers
are no longer containers. They have a packages subobject (not a
packages service) that contains packages. TTW components are created
in packages. To register a component, create the appropriate component
directive objects (these should be called configuration objects).

This should be viewed as a prototype to illustrate the idea of
packages. Lots of things can change (especially UI) and many things
aren't done (e.g. visiting created directives).

In the course of this, I fixed a bunch of bugs and problems in
traversal machinery. 

I also renamed Zope.ComponentArchitecture.IServiceManager back to
IServiceService, since this interface doesn't actually specify any
management.  



=== Added File Zope3/lib/python/Zope/App/OFS/Services/ServiceManager/Views/Browser/AddServiceDirective.py ===
##############################################################################
#
# Copyright (c) 2002 Zope Corporation and Contributors.
# All Rights Reserved.
# 
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
# 
##############################################################################
"""XXX short summary goes here.

XXX longer description goes here.

$Id: AddServiceDirective.py,v 1.1 2002/07/11 18:21:32 jim Exp $
"""
__metaclass__ = type

from Zope.ComponentArchitecture import getServiceManager
from Zope.Publisher.Browser.BrowserView import BrowserView
from Zope.App.OFS.Services.ServiceManager.ServiceDirective \
     import ServiceDirective

class AddServiceDirective(BrowserView):


    def services(self):
        service = getServiceManager(self.context.context)
        definitions = service.getServiceDefinitions()
        return [name for (name, interface) in definitions]

    def components(self):
        service_type = self.request['service_type']
        service = getServiceManager(self.context.context)
        type = service.getInterfaceFor(service_type)
        return [info['path']
                for info in
                service.queryComponent(type=type)
                ]

    def action(self, service_type, component_path, status=""):
        sd = ServiceDirective(service_type, component_path)
        self.context.add(sd)
        service = getServiceManager(self.context.context)
        if status:
            if status == 'register':
                service.addService(sd)
            else:
                service.bindService(sd)
        self.request.response.redirect(self.context.nextURL())



=== Added File Zope3/lib/python/Zope/App/OFS/Services/ServiceManager/Views/Browser/ComponentAdding.py ===
##############################################################################
#
# Copyright (c) 2002 Zope Corporation and Contributors.
# All Rights Reserved.
# 
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
# 
##############################################################################
"""

$Id: ComponentAdding.py,v 1.1 2002/07/11 18:21:32 jim Exp $
"""

from Zope.App.OFS.Container.Views.Browser.Adding import Adding
from Zope.App.OFS.Services.ServiceManager.IServiceAdding import IServiceAdding

class ServiceAdding(Adding):
    
    __implements__ = IServiceAdding



=== Added File Zope3/lib/python/Zope/App/OFS/Services/ServiceManager/Views/Browser/PackagesContents.py ===
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
# 
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
# 
##############################################################################
"""

Revision information: $Id: PackagesContents.py,v 1.1 2002/07/11 18:21:32 jim Exp $
"""
from Zope.App.OFS.Container.Views.Browser.Contents import Contents
from Zope.App.OFS.Services.ServiceManager.IServiceManager \
     import IServiceManager
from Zope.App.OFS.Services.ServiceManager.Package import Package



from Zope.Publisher.Browser.BrowserView import BrowserView

from Zope.App.PageTemplate import ViewPageTemplateFile
from Zope.App.OFS.Container.IContainer import IContainer
from Zope.ComponentArchitecture import queryView, getView

class PackagesContents(Contents):

    __used_for__ = IServiceManager

    index = ViewPageTemplateFile('packages_contents.pt')

    def addPackage(self, name):
        self.context.setObject(name, Package())
        self.request.response.redirect('.')


=== Added File Zope3/lib/python/Zope/App/OFS/Services/ServiceManager/Views/Browser/add_service_1.pt ===
<html metal:use-macro="views/standard_macros/page">
<head><title>Add a service component</title></head>
<body>
<div metal:fill-slot="body">

<p>Select a service type:</p>

<form action="step2.html">
<select name="service_type">
  <option tal:repeat="service view/services"
          tal:attributes="value service"
          tal:content="service">service</option>
</select>
<br>
<input type=submit value="Continue"/>
</form>

</div></body></html>


=== Added File Zope3/lib/python/Zope/App/OFS/Services/ServiceManager/Views/Browser/add_service_2.pt ===
<html metal:use-macro="views/standard_macros/page">
<head><title>Contact Information</title></head>
<body>
<div metal:fill-slot="body">

<form action="finish.html" method="post">
  <input type="hidden" name="service_type" value="" 
         tal:attributes="value request/service_type" />
  <table>
     <tr>
       <th>Service Type</th>
       <td tal:content="request/service_type">Roles</td>
     </tr>
     <tr>
       <th>Component</th>
       <td><select name="component_path">
             <option tal:repeat="path view/components"
                     tal:attributes="value path"
                     tal:content="path">path</option>
           </select>
       </td>
     </tr>
       <td colspan=2>
          <input type="radio" name="status" value="" checked />Unregistered<br>
          <input type="radio" name="status" value="register" />Registered<br>
          <input type="radio" name="status" value="active" />Active<br>
       </td>
     <tr>

  </table>
  <input type="submit" />
</form>

</div></body></html>


=== Added File Zope3/lib/python/Zope/App/OFS/Services/ServiceManager/Views/Browser/packages_contents.pt ===
<html metal:use-macro="views/standard_macros/page">
<head>
<style metal:fill-slot="headers" type="text/css">
</style>
</head>
<body>
<div metal:fill-slot="body">

<form action="." method="get">
  <table class="ContentListing">
  
    <caption>Package Contents</caption>
  
    <tbody>
  
      <tr>
	<td class="ContentIcon"><br /> </td>
	<th class="ContentTitle">Title</th>
      </tr>
      <tr tal:repeat="info view/listContentInfo">
  
	<td class="ContentSelect">
	  <input type="checkbox" name="ids:list" value="id"
		 tal:attributes="value info/id" />
	</td>
  
	<td class="ContentIcon" tal:content="structure info/icon|default">
	</td>
  
	<td class="ContentTitle">
	  <a href="subfolder_id"
	     tal:attributes="href string:${info/url}"
	     tal:content="info/title"
	  >Folder Title or ID here</a>
	</td>
  
      </tr>
  
      <tr tal:condition="nothing">
  
	<td class="ContentIcon">
	  <img alt="Document" src="../../ZMI/www/document_icon.gif" />
	</td>
  
	<td class="ContentTitle">
	   <a href="document_id">Document Title or ID here</a>
	</td>
  
      </tr>
    </tbody>
  
  </table>
  <br />
    <input type="text" name="name" />
    <input type="submit" name="@@addPackage.html:method" value="Add"
           i18nXXX:attributes="value string:menu_add_button" />
    <input type="submit" name="@@removeObjects.html:method" value="Delete"
           i18nXXX:attributes="value string:menu_delete_button" /> 
</form>

</div>
</body>
</html>


=== Zope3/lib/python/Zope/App/OFS/Services/ServiceManager/Views/Browser/Adding.py 1.1 => 1.2 ===
 
 from Zope.App.OFS.Container.Views.Browser.Adding import Adding as ContentAdding
 
-class ServiceAdding(ContentAdding):
+
+class ComponentAdding(ContentAdding):
     """Adding component for service containers
     """
     
-    menu_id = "add_service"
+    menu_id = "add_component"
 
-__doc__ = ServiceAdding.__doc__ + __doc__
+__doc__ = ComponentAdding.__doc__ + __doc__


=== Zope3/lib/python/Zope/App/OFS/Services/ServiceManager/Views/Browser/Bindings.py 1.2 => 1.3 ===
 
 from Zope.App.PageTemplate import ViewPageTemplateFile
 from Zope.Publisher.Browser.BrowserView import BrowserView
+from Zope.ComponentArchitecture import getView
 from Zope.ComponentArchitecture.ContextDependent import ContextDependent
 from Zope.ComponentArchitecture.Exceptions import ComponentLookupError
 from Zope.Proxy.ProxyIntrospection import removeAllProxies
@@ -27,63 +28,84 @@
     index = ViewPageTemplateFile('services_bindings.pt')
 
     def getServicesTable(self):
-        """
-        """
-        context = self.context
-        allServices = removeAllProxies(context.getServiceDefinitions())
-        localServices = removeAllProxies(context.items())
-        services = []
-        for serviceName, service in allServices:
-            serviceMap={}
-            availableServices = []
+        service_types = list(self.context.getBoundServiceTypes())
+        service_types.sort()
 
-            acquiredOrNone = 'None'
-            bound = context.getBoundService(serviceName)
+        table = []
+
+        for service_type in service_types:
+            directives = self.context.getDirectives(service_type)
+
+            if directives and directives[0] is None:
+                active = None
+                inactive = 1
+            else:
+                active = 1
+                inactive = None
+
+            directive_data = []
+            for directive in directives:
+                if directive is None:
+                    continue
+
+                service = directive.getService(self.context)
+                service_url = str(
+                    getView(service, 'absolute_url', self.request))
+                sm_url = '/'.join(service_url.split('/')[:-2])
+
+                component_path = directive.component_path
+                l = component_path.find('/++etc++Services')
+                sm_path = component_path[:l]
+                componen_path = component_path[l+17:]
+
+                directive_data.append({
+                    'sm_url': sm_url,
+                    'sm_path': sm_path,
+                    'component_url': service_url,
+                    'component_path': component_path,
+                    })
+                    
             
-            if bound is None:
-                try:
-                    acquired = context.getService(serviceName)
-                    acquiredOrNone = 'Acquired'
-                except ComponentLookupError:
-                    pass
-                bound = acquiredOrNone
-                                
-            availableServices.append(acquiredOrNone)
+            table.append({
+                'name': service_type,
+                'directives': directive_data,
+                'active': active,
+                'inactive': inactive,
+            })
+
 
+        return table
+
+    def _bound_status(self, service_type):
+        directives = self.context.getDirectives(service_type)
+        if directives and directives[0] is not None:
+            return '0'
+        return 'disabled'
             
-            for localServiceName, localService in localServices:
-                if service.isImplementedBy(localService):
-                    availableServices.append(localServiceName)
-
-            serviceMap['name'] = serviceName
-            serviceMap['services'] = availableServices
-            serviceMap['bound'] = bound
-            services.append(serviceMap)
-        return services
-    
-    def action(self, boundService, REQUEST):
-        # boundService is a dict service_name:bound_name
-        # the bound_names Acquired and None are special
+    def action(self):
+        if self.request.get('REQUEST_METHOD') != 'POST':
+            return self.index()
         
-        context = self.context
         
+        # Update the binding data based on informatioin in the request
+        service_types = self.context.getBoundServiceTypes()
         change_count = 0
-        
-        for service_name, new_bound_name in boundService.items():
-            # check to see if the bound name has changed
-            current_bound_name = context.getBoundService(service_name)
-            if new_bound_name in ('Acquired', 'None'):
-                new_bound_name = None
-            if current_bound_name != new_bound_name:
-                change_count += 1
-
-                if new_bound_name is None:
-                    context.unbindService(service_name)
-                else:
-                    context.bindService(service_name, new_bound_name)
+
+        for service_type in service_types:
+            setting = self.request.get("service %s" % service_type)
+            if setting is not None:
+                current = self._bound_status(service_type)
+                if current is not setting:
+                    change_count += 1
+                    if setting == 'disable':
+                        self.context.disableService(service_type)
+                    else:
+                        self.context.enableService(service_type, int(setting))
+                        
         if change_count:
-            message = "bindings changed"
+            message = "%s bindings changed" % change_count
         else:
             message = "no bindings changed"
-        return self.index(REQUEST=REQUEST, message=message)
+
+        return self.index(message=message)
     


=== Zope3/lib/python/Zope/App/OFS/Services/ServiceManager/Views/Browser/configure.zcml 1.6 => 1.7 ===
-<zopeConfigure
-   xmlns='http://namespaces.zope.org/zope'
-   xmlns:browser='http://namespaces.zope.org/browser'
+<zope:zopeConfigure
+   xmlns:zope='http://namespaces.zope.org/zope'
+   xmlns='http://namespaces.zope.org/browser'
+   package="Zope.App.OFS.Services.ServiceManager"
 >
 
-  <browser:defaultView 
-     for="Zope.App.OFS.Services.ServiceManager.IServiceManager."
+  <defaultView 
+     for=".IServiceManager."
      name="index.html"
      />
-
-  <browser:view 
-     for="Zope.App.OFS.Services.ServiceManager.IServiceManager."
+ 
+  <view 
      permission="Zope.ManageServices" 
-     factory=".Contents."
-     >
+     for=".IServiceManager."
+     factory=".Views.Browser.Bindings." >
 
-    <browser:page name="index.html"
-                  attribute="index"
-                  />
-    <browser:page name="addServiceManager.html"
-                  attribute="addServiceManager"
+    <page name="index.html"
+                  attribute="action"
                   />
 
-  </browser:view> 
+  </view> 
 
-  <browser:view 
-     name="+"
-     permission="Zope.ManageServices" 
-     for="Zope.App.OFS.Services.ServiceManager.IServiceManager."
-     factory=".Adding.ServiceAdding">
+  <menuItems menu="zmi_views" for=".IServiceManager.">
+    <menuItem title="Services" action="@@index.html"/>
+    <menuItem title="Packages" action="Packages/@@index.html"/>
+    <menuItem title="Default Package" action="Packages/default/@@index.html"/>
+  </menuItems>
 
-    <browser:page name="index.html"  attribute="index"  />
-    <browser:page name="action.html" attribute="action" />
 
-  </browser:view> 
-  
-  <browser:view 
-     permission="Zope.ManageServices" 
-     for="Zope.App.OFS.Services.ServiceManager.IServiceManager."
-     factory=".Bindings." >
+  <defaultView for=".IPackages." name="index.html" />
+
+  <view
+      for=".IPackages."
+      permission="Zope.ManageServices" 
+      factory=".Views.Browser.PackagesContents.">
 
-    <browser:page name="bindings.html"
+    <page name="index.html"
                   attribute="index"
                   />
-    <browser:page name="changeBindings.html"
-                  attribute="action"
+    <page name="addPackage.html"
+                  attribute="addPackage"
+                  />
+    <page name="removeObjects"
+                  attribute="removeObjects"
                   />
+  </view>
+
+  <defaultView for=".IPackage." name="index.html" />
+
+
+  <view 
+     for=".IPackage."
+     permission="Zope.ManageServices"
+     factory="Zope.App.OFS.Container.Views.Browser.Contents."
+     >
+
+    <page name="index.html" attribute="index" />
+    <page name="removeObjects.html" attribute="removeObjects" />
+   </view>
+
+
+   <menu id="add_component" 
+                 title="Menu of objects to be added to service managers"
+                 />
+
+
+  <view 
+     name="+"
+     permission="Zope.ManageServices" 
+     for=".IPackage."
+     factory=".Views.Browser.Adding.ComponentAdding">
+
+    <page name="index.html"  attribute="index"  />
+    <page name="action.html" attribute="action" />
+
+  </view> 
 
-  </browser:view> 
+  <view for="Zope.App.OFS.Container.IAdding."
+                name="ServiceDirective"
+                factory=".Views.Browser.AddServiceDirective."
+                >
+      <page name="step1.html" template="Views/Browser/add_service_1.pt" />
+      <page name="step2.html" template="Views/Browser/add_service_2.pt" />
+      <page name="finish.html" attribute="action" />
+  </view>
 
+  <menuItem menu="add_component" for="Zope.App.OFS.Container.IAdding."
+     action="ServiceDirective"  title="Service Directive" />
 
-  <browser:menuItems menu="zmi_views" 
-    for="Zope.App.OFS.Services.ServiceManager.ServiceManager.IServiceManager.">
-    <browser:menuItem title="Contents" action="@@index.html"/>
-    <browser:menuItem title="Bindings" action="@@bindings.html"/>
-  </browser:menuItems>
+</zope:zopeConfigure>
 
-</zopeConfigure>


=== Zope3/lib/python/Zope/App/OFS/Services/ServiceManager/Views/Browser/services_bindings.pt 1.2 => 1.3 ===
     <style metal:fill-slot="headers" type="text/css"> </style>
   </head>
   <body metal:fill-slot="body" >
-    <form action="changeBindings.html" method="post">
+
+    <tal:span tal:define="global services_table view/getServicesTable" />
+
+    <div tal:condition="services_table">
+    <p>Services configured in this service manager.</p>
+
+    <p>For each service, the service name is given and all of the
+       components registered to provide the service are shown.  You
+       map select the component to provide the service or disable the
+       service.
+    </p>
+
+    <p>Select a service name or a component name to visit the service
+       or component. </p>
+    </div>
+
+    <p tal:condition="not:services_table">
+       No services have been
+       configured
+    </p>
+
+    <p>To configure a service, add a service component to a
+       <em>package</em> in <a href="Packages">Packages</a> or to
+       the <a href="Packages/default">default package</a>. After the
+       component is added, add a service directive that configures the
+       component to provide a service.
+    </p>
+
+    <form action="@@index.html" method="post" tal:condition="services_table">
+
     <table>
-    <tr><th>Name</th><th>boundService</th></tr>
-     <tr tal:repeat="service view/getServicesTable">
-       <td tal:content="service/name">Name</td>
-       <td>
-         <select tal:attributes="name string:boundService.${service/name}:record">
-           <option tal:repeat="available service/services"
-                   tal:attributes="value available;
-                                   selected python:service['bound'] == available or None"
-                   tal:content="available">Service</option>
-         </select>
-       </td>
-     </tr>
+
+       <tr tal:repeat="service services_table">
+         <td valign="top" align="right">
+            <a href="Roles"
+               tal:content="service/name"
+               tal:attributes="href service/name"
+               tal:condition="service/active"
+               >Roles</a>
+            <span tal:replace="service/name" 
+                  tal:condition="service/inactive" />
+         </td>
+         <td>
+
+           <table>
+             <tr tal:repeat="directive service/directives">          
+                <td><input type="radio" name="Roles" value="0"
+                        tal:attributes="
+                          name string:service ${service/name};
+                          value repeat/directive/index;
+                          checked service/active;
+                          " />
+                </td>
+                <td><a href="."
+                       tal:attributes="href directive/sm_url"
+                       tal:content="directive/sm_path"
+                       >/</a></td>
+                <td><a href="."
+                       tal:attributes="href directive/component_url"
+                       tal:content="directive/component_path"
+                    >default/RS</a></td>
+             </tr>
+             <tr tal:replace="nothing">
+                <td><input type="radio" name="Roles" value="1" />
+                </td>
+                <td><a href=".">/</a></td>
+                <td><a href=".">acme/RoleService</a></td>
+             </tr>
+             <tr tal:replace="nothing">
+                <td><input type="radio" name="Roles" value="2" />
+                </td>
+                <td><a href=".">/ZopeCorp/Engineering</a></td>
+                <td><a href=".">default/roles</a></td>
+             </tr>
+             <tr>
+                <td><input type="radio" name="Roles" value="disable"
+                           tal:attributes="
+                              name string:service ${service/name};
+                              checked service/inactive;
+                              "
+                           /></td>
+                <td colspan="2"><em>Disable this service</em></td>
+             </tr>
+             <tr><td><br /></td></tr>
+           </table>
+
+         </td>
+       </tr>
+
+       <tr tal:replace="nothing">
+         <td valign="top" align="right">
+             <a href="Views">Views</a>
+         </td>
+         <td>
+
+           <table>
+             <tr>          
+                <td><input type="radio" name="Views" value="0" checked/>
+                </td>
+                <td><a href=".">/</a></td>
+                <td><a href=".">default/views</a></td>
+             </tr>
+             <tr>
+                <td><input type="radio" name="Views" value="1" />
+                </td>
+                <td><a href=".">/</a></td>
+                <td><a href=".">default/altViews</a></td>
+             </tr>
+             <tr>
+                <td><input type="radio" name="Views" value="2" />
+                </td>
+                <td><a href=".">/ZopeCorp</a></td>
+                <td><a href=".">default/views</a></td>
+             </tr>
+             <tr>
+                <td><input type="radio" name="Views" value="disable" /></td>
+                <td colspan="2"><em>Disable this service</em></td>
+             </tr>
+             <tr><td><br /></td></tr>
+           </table>
+
+         </td>
+       </tr>
+
     </table>
-    <input type=submit value="change bindings">
+
+    <input type=submit value="Change"><br>
+
     </form>
   </body>
 </html>

=== Removed File Zope3/lib/python/Zope/App/OFS/Services/ServiceManager/Views/Browser/Contents.py ===

=== Removed File Zope3/lib/python/Zope/App/OFS/Services/ServiceManager/Views/Browser/ServiceAdding.py ===

=== Removed File Zope3/lib/python/Zope/App/OFS/Services/ServiceManager/Views/Browser/add.pt ===