juergen     02/05/22 00:37:46

  Modified:    src/webdav/server/org/apache/slide/webdav/method
                        PropPatchMethod.java
  Log:
  Replaced usage of the org.w3c.dom classes by JDOM.
  (ralf)
  
  Revision  Changes    Path
  1.46      +276 -216  
jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/PropPatchMethod.java
  
  Index: PropPatchMethod.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/PropPatchMethod.java,v
  retrieving revision 1.45
  retrieving revision 1.46
  diff -u -r1.45 -r1.46
  --- PropPatchMethod.java      20 May 2002 12:10:14 -0000      1.45
  +++ PropPatchMethod.java      22 May 2002 07:37:46 -0000      1.46
  @@ -1,7 +1,7 @@
   /*
  - * $Header: 
/home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/PropPatchMethod.java,v
 1.45 2002/05/20 12:10:14 pnever Exp $
  - * $Revision: 1.45 $
  - * $Date: 2002/05/20 12:10:14 $
  + * $Header: 
/home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/PropPatchMethod.java,v
 1.46 2002/05/22 07:37:46 juergen Exp $
  + * $Revision: 1.46 $
  + * $Date: 2002/05/22 07:37:46 $
    *
    * ====================================================================
    *
  @@ -70,7 +70,6 @@
   import javax.servlet.http.*;
   import javax.xml.parsers.ParserConfigurationException;
   
  -import org.w3c.dom.*;
   import org.xml.sax.SAXException;
   
   import org.apache.util.PropertyWriter;
  @@ -87,7 +86,13 @@
   import org.apache.slide.webdav.util.resourcekind.ResourceKind;
   import org.apache.slide.webdav.util.resourcekind.AbstractResourceKind;
   import org.apache.slide.webdav.util.resourcekind.CheckedInVersionControlled;
  -import org.apache.slide.util.*;
  +import org.apache.slide.util.Configuration;
  +
  +import org.jdom.Element;
  +import org.jdom.Document;
  +import org.jdom.Namespace;
  +
  +import org.jdom.output.XMLOutputter;
   
   /**
    * PROPPATCH method.
  @@ -113,14 +118,14 @@
       protected VersioningHelper versioningHelper = null;
       
       /**
  -     * Properties to set. Vector of SlideProperty objects.
  +     * Properties to set.
        */
  -    private Vector propertiesToSet;
  +    private PropPatchProperties propertiesToSet;
       
       /**
  -     * Properties to remove. Vector of String.
  +     * Properties to remove.
        */
  -    private Vector propertiesToRemove;
  +    private PropPatchProperties propertiesToRemove;
       
       
       /**
  @@ -173,91 +178,93 @@
           if (resourcePath == null) {
               resourcePath = "/";
           }
  -        
  -        propertiesToSet = new Vector();
  -        
  -        propertiesToRemove = new Vector();
  +        propertiesToSet = new PropPatchProperties();
  +        propertiesToRemove = new PropPatchProperties();
           
           if (requestBody.length() != 0) {
  +        
               try {
  -                Node setNode = null;
  -                Node removeNode = null;
  +                retrieveRequestContent();
  +        
  +                Element setNode = null;
  +                Element removeNode = null;
                   
  -                Document document = parseRequestContent();
  +                Document document = getRequestContent();
                   
                   // Get the root element of the document
  -                Element rootElement = document.getDocumentElement();
  -                NodeList childList = rootElement.getChildNodes();
  -                
  -                for (int i=0; i < childList.getLength(); i++) {
  -                    Node currentNode = childList.item(i);
  -                    switch (currentNode.getNodeType()) {
  -                        case Node.TEXT_NODE:
  -                            break;
  -                        case Node.ELEMENT_NODE:
  -                            if (currentNode.getNodeName().endsWith("set")) {
  -                                NodeList tempList =
  -                                    currentNode.getChildNodes();
  -                                for (int j=0; j < tempList.getLength(); j++) {
  -                                    switch (tempList.item(j).getNodeType()) {
  -                                        case Node.TEXT_NODE:
  -                                            break;
  -                                        case Node.ELEMENT_NODE:
  -                                            if (tempList.item(j).getNodeName()
  -                                                .endsWith("prop")) {
  -                                                parseSetNode(tempList.item(j));
  +                Element rootElement = document.getRootElement();
  +                if ( (rootElement == null) || ( ! 
E_PROPERTYUPDATE.equals(rootElement.getName()) ) ) {
  +                    throw new SAXException("&lt;"+E_PROPERTYUPDATE+"&gt; element 
missing");
  +                }
  +                Iterator childrenIterator = rootElement.getChildren().iterator();
  +                Element child = null;
  +                while (childrenIterator.hasNext()) {
  +                    child = (Element)childrenIterator.next();
  +                    if (E_SET.equals(child.getName())) {
  +                        propertiesToSet = new 
PropPatchProperties(getPropElement(child));
                                               }
  -                                            break;
  +                    else if (E_REMOVE.equals(child.getName())) {
  +                        propertiesToRemove = new 
PropPatchProperties(getPropElement(child));
                                       }
  +                    else {
  +                        throw new SAXException("Expected &lt;"+E_SET+"&gt; or 
&lt;"+E_REMOVE+"&gt; element");
                                   }
                               }
  -                            if (currentNode.getNodeName().endsWith("remove")) {
  -                                NodeList tempList = currentNode.getChildNodes();
  -                                for (int j=0; j < tempList.getLength(); j++) {
  -                                    switch (tempList.item(j).getNodeType()) {
  -                                        case Node.TEXT_NODE:
  -                                            break;
  -                                        case Node.ELEMENT_NODE:
  -                                            if (tempList.item(j).getNodeName()
  -                                                .endsWith("prop")) {
  -                                                parseRemoveNode(tempList.item(j));
  +                
  +                
                                               }
  -                                            break;
  +            catch (SAXException e) {
  +                try {
  +                    resp.sendError(WebdavStatus.SC_BAD_REQUEST, e.getMessage());
                                       }
  +                catch (IOException ioe) {
  +                    ioe.printStackTrace();
                                   }
  -                            }
  -                            break;
  -                    }
  -                }
  -                
  -            } catch (SAXException e) {
  -                e.printStackTrace();
  -                resp.setStatus(WebdavStatus.SC_BAD_REQUEST);
                   throw new WebdavException(WebdavStatus.SC_BAD_REQUEST);
  -            } catch (ParserConfigurationException e) {
  -                System.err.println(e.getMessage());
  +                            }
  +            catch (IOException  e){
                   resp.setStatus(WebdavStatus.SC_INTERNAL_SERVER_ERROR);
  -                throw new WebdavException
  -                    (WebdavStatus.SC_INTERNAL_SERVER_ERROR);
  -            } catch (IOException e) {
  -                System.err.println(e.getMessage());
  -                e.printStackTrace();
  +                throw new WebdavException(WebdavStatus.SC_INTERNAL_SERVER_ERROR);
  +                    }
  +            catch (ParserConfigurationException  e){
                   resp.setStatus(WebdavStatus.SC_INTERNAL_SERVER_ERROR);
  -                throw new WebdavException
  -                    (WebdavStatus.SC_INTERNAL_SERVER_ERROR);
  +                throw new WebdavException(WebdavStatus.SC_INTERNAL_SERVER_ERROR);
  +                }
               }
  -        } else {
  +        else {
               try {
                   resp.sendError(WebdavStatus.SC_BAD_REQUEST,
                                  WebdavStatus.getStatusText
                                      (WebdavStatus.SC_BAD_REQUEST));
  -            } catch (IOException e) {
  +            }
  +            catch (IOException e) {
                   e.printStackTrace();
               }
           }
           
       }
       
  +    /**
  +     * Checks if the given Element has exactly one child named
  +     * <code>&lt;prop&gt;</code>. If the check succeeds the
  +     * <code>&lt;prop&gt;</code> element is returned, otherwise a
  +     * SAXException is thrown.
  +     *
  +     * @param      parent  the parent Element of the <code>&lt;prop&gt;</code>.
  +     *
  +     * @return     the <code>&lt;prop&gt;</code> element.
  +     *
  +     * @throws     SAXException  if the check fails.
  +     */
  +    private Element getPropElement(Element parent) throws SAXException {
  +        List childrenList = parent.getChildren();
  +        if ( (childrenList.size() != 1) ||
  +                ( ! E_PROP.equals(((Element)childrenList.get(0)).getName()) ) ) {
  +            throw new SAXException("Expected &lt;"+E_PROP+"&gt; element");
  +        }
  +        return (Element)childrenList.get(0);
  +    }
  +    
       
       /**
        * Execute the request.
  @@ -314,20 +321,18 @@
               
               // Modifying the properties
               
  -            Enumeration propertyList = null;
  -            
  -            propertyList = propertiesToSet.elements();
  -            
  -            while (propertyList.hasMoreElements()) {
  +            Iterator propertyIterator = null;
                   
  -                Property currentProperty =
  -                    (Property) propertyList.nextElement();
  +            propertyIterator = propertiesToSet.iterator();
  +            PropPatchProperty currentProperty = null;
  +            while (propertyIterator.hasNext()) {
                   
  +                currentProperty = (PropPatchProperty)propertyIterator.next();
                   if (checkPropertyModification(currentProperty, revisionDescriptor)) 
{
                       NodeProperty newProperty =
  -                        new NodeProperty(currentProperty.name,
  -                                         currentProperty.value,
  -                                         currentProperty.namespace);
  +                        new NodeProperty(currentProperty.getName(),
  +                                         currentProperty.getValue(),
  +                                         currentProperty.getNamespace());
                       revisionDescriptor.setProperty(newProperty);
                       
                   }
  @@ -336,17 +341,13 @@
                   }
               }
               
  -            propertyList = propertiesToRemove.elements();
  -            
  -            while (propertyList.hasMoreElements()) {
  -                
  -                Property currentProperty =
  -                    (Property) propertyList.nextElement();
  +            propertyIterator = propertiesToRemove.iterator();
  +            while (propertyIterator.hasNext()) {
                   
  +                currentProperty = (PropPatchProperty)propertyIterator.next();
                   if (checkPropertyModification(currentProperty, revisionDescriptor)) 
{
  -                    revisionDescriptor.removeProperty(
  -                        currentProperty.name,
  -                        currentProperty.namespace);
  +                    revisionDescriptor.removeProperty(currentProperty.getName(),
  +                                                      
currentProperty.getNamespace());
                   }
                   else {
                       allOperationsExcecuted = false;
  @@ -408,86 +409,6 @@
       // -------------------------------------------------------- Private Methods
       
       
  -    /**
  -     * Parse the set property node given.
  -     */
  -    private void parseSetNode(Node setNode) {
  -        
  -        NodeList childList = setNode.getChildNodes();
  -        
  -        for (int i=0; i < childList.getLength(); i++) {
  -            Node currentNode = childList.item(i);
  -            switch (currentNode.getNodeType()) {
  -                case Node.TEXT_NODE:
  -                    break;
  -                case Node.ELEMENT_NODE:
  -                    
  -                    Property propertyToSet = getProperty(currentNode);
  -                    
  -                    StringWriter writer = new StringWriter();
  -                    propertyWriter = new PropertyWriter(writer, true);
  -                    
  -                    // Printing all child nodes using the DOM printer
  -                    NodeList childNodes = currentNode.getChildNodes();
  -                    Node childNode = childNodes.item(0);
  -                    int pos = 0;
  -                    while (childNode != null) {
  -                        propertyWriter.print(childNode);
  -                        childNode = childNodes.item(++pos);
  -                    }
  -                    
  -                    String nodeValue = writer.toString();
  -                    propertyToSet.value = nodeValue;
  -                    
  -                    propertiesToSet.addElement(propertyToSet);
  -                    
  -                    break;
  -            }
  -        }
  -    }
  -    
  -    
  -    /**
  -     * Parse the remove property node given.
  -     */
  -    private void parseRemoveNode(Node removeNode) {
  -        
  -        NodeList childList = removeNode.getChildNodes();
  -        
  -        for (int i=0; i < childList.getLength(); i++) {
  -            Node currentNode = childList.item(i);
  -            switch (currentNode.getNodeType()) {
  -                case Node.TEXT_NODE:
  -                    break;
  -                case Node.ELEMENT_NODE:
  -                    
  -                    Property propertyToRemove = getProperty(currentNode);
  -                    
  -                    propertiesToRemove.addElement(propertyToRemove);
  -                    
  -                    break;
  -            }
  -        }
  -    }
  -    
  -    
  -    /**
  -     * Parse the namespace info of a node name.
  -     *
  -     * @param node The DOM node to parse
  -     * @return The corresponding Property object
  -     */
  -    private Property getProperty(Node node) {
  -        
  -        Property property = new Property();
  -        
  -        property.name = node.getLocalName();
  -        property.namespace = node.getNamespaceURI();
  -        property.namespaceAbbrev = node.getPrefix();
  -        
  -        return property;
  -        
  -    }
       
       
       
  @@ -498,18 +419,18 @@
        * @param property The property object
        * @param rd the revision descriptor containing all properties
        */
  -    private boolean checkPropertyModification(Property property, 
NodeRevisionDescriptor rd) {
  -        NodeProperty originalProperty = rd.getProperty(property.name, 
property.namespace);
  +    private boolean checkPropertyModification(PropPatchProperty property, 
NodeRevisionDescriptor rd) {
  +        NodeProperty originalProperty = rd.getProperty(property.getName(), 
property.getNamespace());
           boolean result;
           if (originalProperty == null) {
               // those virtual live properties can not be modified
  -            result = (!property.name.equals(P_LOCKDISCOVERY)) &&
  -                (!property.name.equals(P_SUPPORTEDLOCK));
  +            result = (!property.getName().equals(P_LOCKDISCOVERY)) &&
  +                (!property.getName().equals(P_SUPPORTEDLOCK));
           }
           else {
               result = !originalProperty.isProtected();
           }
  -        if (!result) property.status = WebdavStatus.SC_CONFLICT;
  +        if (!result) property.setStatus(WebdavStatus.SC_CONFLICT);
           return result;
           
       }
  @@ -522,37 +443,35 @@
       private void writeReport()
           throws WebdavException {
           
  -        org.jdom.Element multistatus = new org.jdom.Element(E_MULTISTATUS, 
NamespaceCache.DEFAULT_NAMESPACE);
  -        org.jdom.Element response = new org.jdom.Element(E_RESPONSE, 
NamespaceCache.DEFAULT_NAMESPACE);
  +        Element multistatus = new Element(E_MULTISTATUS, 
NamespaceCache.DEFAULT_NAMESPACE);
  +        Element response = new Element(E_RESPONSE, 
NamespaceCache.DEFAULT_NAMESPACE);
           multistatus.addContent(response);
  -        org.jdom.Element href = new org.jdom.Element(E_HREF, 
NamespaceCache.DEFAULT_NAMESPACE);
  +        Element href = new Element(E_HREF, NamespaceCache.DEFAULT_NAMESPACE);
           href.setText(getFullPath(requestUri));
           response.addContent(href);
           
           // Parse the two properties list, and printout their status
  -        Enumeration propertyList = null;
  +        Iterator propertyIterator = propertiesToSet.iterator();
           
  -        propertyList = propertiesToSet.elements();
  -        
  -        while(propertyList.hasMoreElements()) {
  -            Property property = (Property) propertyList.nextElement();
  -            org.jdom.Element propstat = createPropstatElement(property);
  +        while(propertyIterator.hasNext()) {
  +            PropPatchProperty property = (PropPatchProperty) 
propertyIterator.next();
  +            Element propstat = createPropstatElement(property);
               response.addContent(propstat);
           }
           
  -        propertyList = propertiesToRemove.elements();
  +        propertyIterator = propertiesToRemove.iterator();
           
  -        while(propertyList.hasMoreElements()) {
  -            Property property = (Property) propertyList.nextElement();
  -            org.jdom.Element propstat = createPropstatElement(property);
  +        while(propertyIterator.hasNext()) {
  +            PropPatchProperty property = (PropPatchProperty) 
propertyIterator.next();
  +            Element propstat = createPropstatElement(property);
               response.addContent(propstat);
           }
           
           try {
               resp.setContentType(TEXT_XML_UTF_8);
               Writer writer = resp.getWriter();
  -            new org.jdom.output.XMLOutputter(XML_REPONSE_INDENT, true).
  -                output(new org.jdom.Document(multistatus), writer);
  +            new XMLOutputter(XML_REPONSE_INDENT, true).
  +                output(new Document(multistatus), writer);
               writer.flush();
           } catch (Exception e) {
               e.printStackTrace();
  @@ -565,25 +484,25 @@
        * Creates a <code>&lt;propstat&gt;</code> element for the given
        * <code>property</code>.
        *
  -     * @param      property  the Property for which to create a
  +     * @param      property  the PropPatchProperty for which to create a
        *                       <code>&lt;propstat&gt;</code> element.
        *
        * @return     the created <code>&lt;propstat&gt;</code> element.
        */
  -    private org.jdom.Element createPropstatElement(Property property) {
  +    private Element createPropstatElement(PropPatchProperty property) {
           
  -        org.jdom.Element propstat = new org.jdom.Element(E_PROPSTAT, 
NamespaceCache.DEFAULT_NAMESPACE);
  -        org.jdom.Element prop = new org.jdom.Element(E_PROP, 
NamespaceCache.DEFAULT_NAMESPACE);
  +        Element propstat = new Element(E_PROPSTAT, 
NamespaceCache.DEFAULT_NAMESPACE);
  +        Element prop = new Element(E_PROP, NamespaceCache.DEFAULT_NAMESPACE);
           propstat.addContent(prop);
           
  -        org.jdom.Namespace namespace = org.jdom.Namespace.NO_NAMESPACE;
  -        if (property.namespace != null) {
  -            namespace = NamespaceCache.getNamespace(property.namespace);
  +        Namespace namespace = Namespace.NO_NAMESPACE;
  +        if (property.getNamespace() != null) {
  +            namespace = NamespaceCache.getNamespace(property.getNamespace());
           }
  -        org.jdom.Element propertyElement = new org.jdom.Element(property.name, 
namespace);
  +        Element propertyElement = new Element(property.getName(), namespace);
           prop.addContent(propertyElement);
           
  -        org.jdom.Element status = new org.jdom.Element(E_STATUS, 
NamespaceCache.DEFAULT_NAMESPACE);
  +        Element status = new Element(E_STATUS, NamespaceCache.DEFAULT_NAMESPACE);
           status.setText("HTTP/1.1 " + property.status + " "
                              + WebdavStatus.getStatusText(property.status));
           propstat.addContent(status);
  @@ -591,20 +510,6 @@
       }
       
       
  -    // --------------------------------------------------- Property Inner Class
  -    
  -    
  -    private class Property {
  -        
  -        public String name;
  -        public String value;
  -        public String namespace;
  -        public String namespaceAbbrev;
  -        public int status = WebdavStatus.SC_OK;
  -        
  -    }
  -    
  -    
       
       /**
        * Returns true
  @@ -667,16 +572,41 @@
               }
           }
           
  -        List propertyList = new ArrayList(propertiesToRemove.size() + 
propertiesToSet.size());
  -        propertyList.addAll(propertiesToRemove);
  -        propertyList.addAll(propertiesToSet);
  -        java.util.Iterator iterator = propertyList.iterator();
  -        Property property = null;
  +        ViolatedPrecondition violatedPrecondition =
  +            checkPropertySpecificPreconditions(propertiesToSet);
  +        if (violatedPrecondition != null) {
  +            return violatedPrecondition;
  +        }
  +        violatedPrecondition =
  +            checkPropertySpecificPreconditions(propertiesToRemove);
  +        if (violatedPrecondition != null) {
  +            return violatedPrecondition;
  +        }
  +        
  +        return null;
  +    }
  +    
  +    /**
  +     * Checks the property specific preconditions
  +     * <ul>
  +     * <li>&lt;DAV:cannot-modify-protected-property&gt;</li>
  +     * <li>&lt;DAV:supported-live-property&gt;</li>
  +     * </ul>
  +     *
  +     * @param      properties  the PropPatchProperties to check.
  +     *
  +     * @return     the precondition that has been violated (if any,
  +     *             otherwise <code>null</code>).
  +     */
  +    private ViolatedPrecondition 
checkPropertySpecificPreconditions(PropPatchProperties properties) {
  +        
  +        Iterator iterator = properties.iterator();
  +        PropPatchProperty property = null;
           while (iterator.hasNext()) {
  -            property = (Property)iterator.next();
  +            property = (PropPatchProperty)iterator.next();
               
               // check precondition DAV:cannot-modify-protected-property
  -            if (AbstractResourceKind.isProtectedProperty(property.name)) {
  +            if (AbstractResourceKind.isProtectedProperty(property.getName())) {
                   return new ViolatedPrecondition(C_CANNOT_MODIFY_PROTECTED_PROPERTY,
                                                   WebdavStatus.SC_FORBIDDEN);
               }
  @@ -689,6 +619,136 @@
       }
       
       
  +    /**
  +     * An extension of the RequestedProperties class manages PropPatchProperty
  +     * instead of RequestedProperty.
  +     */
  +    public static class PropPatchProperties extends RequestedPropertiesImpl {
  +        
  +        /**
  +         * Default constructor.
  +         */
  +        public PropPatchProperties() {
  +            super();
  +        }
  +        
  +        /**
  +         * Constructs a List of PropPatchProperty from a &lt;DAV:prop&gt; element.
  +         *
  +         * @param      propElement  the &lt;DAV:prop&gt; from which to create the
  +         *                          List of PropPatchProperty.
  +         */
  +        public PropPatchProperties (Element propElement) {
  +            super(propElement);
  +        }
  +        
  +        /**
  +         * Creates a RequestedProperty from the given parameters. This method
  +         * may be overwritten by subclasses in order to create appropriate
  +         * implementations of RequestedProperty.
  +         *
  +         * @param      name       the name of the propery.
  +         * @param      namespace  the namespace of the propery.
  +         * @param      text       the text of the propery element.
  +         * @param      children   the children of the propery element.
  +         *
  +         * @return     the created RequestedProperty.
  +         */
  +        protected RequestedProperty createRequestedProperty(String name, String 
namespace, String text, List children) {
  +            
  +            String value = text;
  +            if (children.size() > 0) {
  +                value = new XMLValue(children).toString();
  +            }
  +            return new PropPatchProperty(name, namespace, value);
  +        }
  +        
  +    }
       
  +    /**
  +     * An extension of the RequestedProperty class which supports a property value.
  +     */
  +    public static class PropPatchProperty extends RequestedPropertyImpl {
  +        
  +        /**
  +         * The value of the property.
  +         */
  +        protected String value = null;
  +        
  +        /**
  +         * The status of the PropPatch operation on this property.
  +         */
  +        protected int status = WebdavStatus.SC_OK;
  +        
  +        
  +        /**
  +         * Constructs a PropPatchProperty using the default namespace as defined
  +         * in NodeProperty.
  +         *
  +         * @param      propertyName  the name of the property.
  +         */
  +        public PropPatchProperty (String propertyName) {
  +            super(propertyName);
  +        }
  +        
  +        /**
  +         * Constructs a PropPatchProperty.
  +         *
  +         * @param      propertyName  the name of the property.
  +         * @param      namespace     the namespace of the property.
  +         */
  +        public PropPatchProperty (String propertyName, String namespace) {
  +            super(propertyName, namespace);
  +        }
  +        
  +        /**
  +         * Constructs a PropPatchProperty.
  +         *
  +         * @param      propertyName  the name of the property.
  +         * @param      namespace     the namespace of the property.
  +         * @param      value         the value of the property.
  +         */
  +        public PropPatchProperty (String propertyName, String namespace, String 
value) {
  +            super(propertyName, namespace);
  +            this.value = value;
  +        }
  +    
  +        /**
  +         * Returns the value of the property.
  +         *
  +         * @return     the value of the property.
  +         */
  +        public String getValue() {
  +            return value;
  +        }
  +        
  +        /**
  +         * Sets the status of the PropPatch operation on this property.
  +         *
  +         * @param      status  the status of the PropPatch operation on this 
property.
  +         */
  +        public void setStatus(int status) {
  +            this.status = status;
  +        }
  +        
  +        /**
  +         * Returns the status of the PropPatch operation on this property.
  +         *
  +         * @return     the status of the PropPatch operation on this property.
  +         */
  +        public int getStatus() {
  +            return status;
  +        }
  +        
  +        
  +        /**
  +         * Returns a String representation of this instance.
  +         *
  +         * @return     a String representation of this instance.
  +         */
  +        public String toString() {
  +            return getNamespace()+":"+getName()+"["+getValue()+"]";
  +        }
  +    }
       
   }
  
  
  

--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to