This is an automated email from the ASF dual-hosted git repository.

remm pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tomcat.git


The following commit(s) were added to refs/heads/main by this push:
     new 40c094b8ba Refine the dead properties handling
40c094b8ba is described below

commit 40c094b8ba52513b1468a45db0d9ad0c36a64fbf
Author: remm <r...@apache.org>
AuthorDate: Sun Oct 20 23:46:05 2024 +0200

    Refine the dead properties handling
    
    Add a proof of concept otherwise it is not possible to validate it.
    Add namespaces on elments to the DOMWriter.
---
 .../servlets/TransientPropertiesWebdavServlet.java | 186 +++++++++++++++++++++
 .../apache/catalina/servlets/WebdavServlet.java    |  71 ++++++--
 java/org/apache/catalina/util/DOMWriter.java       |  12 +-
 .../catalina/servlets/TestWebdavServlet.java       |  84 ++++------
 4 files changed, 286 insertions(+), 67 deletions(-)

diff --git 
a/java/org/apache/catalina/servlets/TransientPropertiesWebdavServlet.java 
b/java/org/apache/catalina/servlets/TransientPropertiesWebdavServlet.java
new file mode 100644
index 0000000000..80c979c190
--- /dev/null
+++ b/java/org/apache/catalina/servlets/TransientPropertiesWebdavServlet.java
@@ -0,0 +1,186 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.catalina.servlets;
+
+import java.io.IOException;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.concurrent.ConcurrentHashMap;
+
+import jakarta.servlet.ServletException;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+
+import org.apache.catalina.util.DOMWriter;
+import org.apache.catalina.util.XMLWriter;
+import org.w3c.dom.Node;
+
+/**
+ * Extended WebDAV Servlet that implements dead properties using storage in 
memory.
+ */
+public class TransientPropertiesWebdavServlet extends WebdavServlet {
+
+    private static final long serialVersionUID = 1L;
+
+    private final ConcurrentHashMap<String,ArrayList<Node>> deadProperties = 
new ConcurrentHashMap<>();
+
+    @Override
+    protected void doOptions(HttpServletRequest req, HttpServletResponse resp) 
throws ServletException, IOException {
+        resp.addHeader("DAV", "1,2,3");
+        resp.addHeader("Allow", determineMethodsAllowed(req));
+        resp.addHeader("MS-Author-Via", "DAV");
+    }
+
+    @Override
+    protected void proppatchResource(String path, 
ArrayList<ProppatchOperation> operations) {
+        boolean protectedProperty = false;
+        // Check for the protected properties
+        for (ProppatchOperation operation : operations) {
+            if (operation.getProtectedProperty()) {
+                protectedProperty = true;
+                operation.setStatusCode(HttpServletResponse.SC_FORBIDDEN);
+            }
+        }
+        if (protectedProperty) {
+            for (ProppatchOperation operation : operations) {
+                if (!operation.getProtectedProperty()) {
+                    operation.setStatusCode(WebdavStatus.SC_FAILED_DEPENDENCY);
+                }
+            }
+        } else {
+            ArrayList<Node> properties = deadProperties.get(path);
+            if (properties == null) {
+                properties = new ArrayList<Node>();
+                deadProperties.put(path, properties);
+            }
+            synchronized (properties) {
+                for (ProppatchOperation operation : operations) {
+                    if (operation.getUpdateType() == PropertyUpdateType.SET) {
+                        Node node = 
operation.getPropertyNode().cloneNode(true);
+                        boolean found = false;
+                        for (int i = 0; i < properties.size(); i++) {
+                            Node propertyNode = properties.get(i);
+                            if (propertyEquals(node, propertyNode)) {
+                                found = true;
+                                properties.set(i, node);
+                                break;
+                            }
+                        }
+                        if (!found) {
+                            properties.add(node);
+                        }
+                    } if (operation.getUpdateType() == 
PropertyUpdateType.REMOVE) {
+                        Node node = operation.getPropertyNode();
+                        for (int i = 0; i < properties.size(); i++) {
+                            Node propertyNode = properties.get(i);
+                            if (propertyEquals(node, propertyNode)) {
+                                properties.remove(i);
+                                break;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    @Override
+    protected boolean propfindResource(String path, Node property, boolean 
nameOnly, XMLWriter generatedXML) {
+        ArrayList<Node> properties = deadProperties.get(path);
+        if (properties != null) {
+            synchronized (properties) {
+                if (nameOnly) {
+                    // Add the names of all properties
+                    for (Node node : properties) {
+                        generatedXML.writeElement(node.getPrefix(),
+                                node.getNamespaceURI(),
+                                node.getLocalName(), XMLWriter.NO_CONTENT);
+                    }
+                } else if (property != null) {
+                    // Add a single property
+                    Node foundNode = null;
+                    for (Node node : properties) {
+                        if (propertyEquals(node, property)) {
+                            foundNode = node;
+                        }
+                    }
+                    if (foundNode != null) {
+                        StringWriter strWriter = new StringWriter();
+                        DOMWriter domWriter = new DOMWriter(strWriter);
+                        domWriter.print(foundNode);
+                        generatedXML.writeRaw(strWriter.toString());
+                        return true;
+                    }
+                } else {
+                    StringWriter strWriter = new StringWriter();
+                    DOMWriter domWriter = new DOMWriter(strWriter);
+                    // Add all properties
+                    for (Node node : properties) {
+                        domWriter.print(node);
+                    }
+                    generatedXML.writeRaw(strWriter.toString());
+                }
+            }
+        }
+        return false;
+    }
+
+    @Override
+    protected void copyResource(String source, String dest) {
+        ArrayList<Node> properties = deadProperties.get(source);
+        ArrayList<Node> propertiesDest = deadProperties.get(dest);
+        if (properties != null) {
+            if (propertiesDest == null) {
+                propertiesDest = new ArrayList<Node>();
+                deadProperties.put(dest, propertiesDest);
+            }
+            synchronized (properties) {
+                synchronized (propertiesDest) {
+                    for (Node node : properties) {
+                        node = node.cloneNode(true);
+                        boolean found = false;
+                        for (int i = 0; i < propertiesDest.size(); i++) {
+                            Node propertyNode = propertiesDest.get(i);
+                            if (propertyEquals(node, propertyNode)) {
+                                found = true;
+                                propertiesDest.set(i, node);
+                                break;
+                            }
+                        }
+                        if (!found) {
+                            propertiesDest.add(node);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    @Override
+    protected void deleteResource(String path) {
+        deadProperties.remove(path);
+    }
+
+    private boolean propertyEquals(Node node1, Node node2) {
+        if (node1.getLocalName().equals(node2.getLocalName())
+                && ((node1.getNamespaceURI() == null && 
node2.getNamespaceURI() == null)
+                        || (node1.getNamespaceURI() != null && 
node1.getNamespaceURI().equals(node2.getNamespaceURI())))) {
+            return true;
+        }
+        return false;
+    }
+}
\ No newline at end of file
diff --git a/java/org/apache/catalina/servlets/WebdavServlet.java 
b/java/org/apache/catalina/servlets/WebdavServlet.java
index 15f5d398d6..4f1df32636 100644
--- a/java/org/apache/catalina/servlets/WebdavServlet.java
+++ b/java/org/apache/catalina/servlets/WebdavServlet.java
@@ -998,7 +998,7 @@ public class WebdavServlet extends DefaultServlet 
implements PeriodicEventListen
 
 
     /**
-     * Apply proppatch to the specified path. This should be overriden by 
subclasses to provide
+     * Apply proppatch to the specified path. This should be overridden by 
subclasses to provide
      * useful behavior. The default implementation prevents setting protected 
properties
      * (anything from the DAV: namespace), and sets 507 for a set attempt on 
dead properties.
      *
@@ -1964,6 +1964,8 @@ public class WebdavServlet extends DefaultServlet 
implements PeriodicEventListen
                     errorList.put(dest, 
Integer.valueOf(WebdavStatus.SC_CONFLICT));
                     return false;
                 }
+            } else {
+                copyResource(source, dest);
             }
 
             if (infiniteCopy) {
@@ -2006,6 +2008,8 @@ public class WebdavServlet extends DefaultServlet 
implements PeriodicEventListen
                 if (!resources.write(dest, is, false)) {
                     errorList.put(source, 
Integer.valueOf(WebdavStatus.SC_INTERNAL_SERVER_ERROR));
                     return false;
+                } else {
+                    copyResource(source, dest);
                 }
             } catch (IOException e) {
                 log(sm.getString("webdavservlet.inputstreamclosefail", 
source), e);
@@ -2017,6 +2021,16 @@ public class WebdavServlet extends DefaultServlet 
implements PeriodicEventListen
         return true;
     }
 
+    /**
+     * Copy resource. This should be overridden by subclasses to provide
+     * useful behavior. The default implementation prevents setting protected 
properties
+     * (anything from the DAV: namespace), and sets 507 for a set attempt on 
dead properties.
+     *
+     * @param source the copy source path
+     * @param dest the copy destination path
+     */
+    protected void copyResource(String source, String dest) {
+    }
 
     /**
      * Delete a resource.
@@ -2071,7 +2085,7 @@ public class WebdavServlet extends DefaultServlet 
implements PeriodicEventListen
                 sendNotAllowed(req, resp);
                 return false;
             }
-            unlockResource(path, null);
+            deleteResource(path);
         } else {
 
             Map<String,Integer> errorList = new LinkedHashMap<>();
@@ -2094,7 +2108,7 @@ public class WebdavServlet extends DefaultServlet 
implements PeriodicEventListen
                     errorList.put(path, 
Integer.valueOf(WebdavStatus.SC_METHOD_NOT_ALLOWED));
                 }
             } else {
-                unlockResource(path, null);
+                deleteResource(path);
             }
 
             if (!errorList.isEmpty()) {
@@ -2108,6 +2122,17 @@ public class WebdavServlet extends DefaultServlet 
implements PeriodicEventListen
         return true;
     }
 
+    /**
+     * Delete specified resource. This should be overridden by subclasses to 
provide
+     * useful behavior. The default implementation prevents setting protected 
properties
+     * (anything from the DAV: namespace), and sets 507 for a set attempt on 
dead properties.
+     *
+     * @param path the path of the resource to delete
+     */
+    protected void deleteResource(String path) {
+        unlockResource(path, null);
+    }
+
     private void unlockResource(String path, String lockToken) {
         LockInfo lock = resourceLocks.get(path);
         if (lock != null) {
@@ -2195,7 +2220,7 @@ public class WebdavServlet extends DefaultServlet 
implements PeriodicEventListen
                         errorList.put(childName, 
Integer.valueOf(WebdavStatus.SC_METHOD_NOT_ALLOWED));
                     }
                 } else {
-                    unlockResource(childName, null);
+                    deleteResource(childName);
                 }
             }
         }
@@ -2299,9 +2324,6 @@ public class WebdavServlet extends DefaultServlet 
implements PeriodicEventListen
                 generatedXML.writeElement("D", "prop", XMLWriter.OPENING);
 
                 generatedXML.writeProperty("D", "creationdate", 
getISOCreationDate(created));
-                generatedXML.writeElement("D", "displayname", 
XMLWriter.OPENING);
-                generatedXML.writeData(resourceName);
-                generatedXML.writeElement("D", "displayname", 
XMLWriter.CLOSING);
                 if (isFile) {
                     generatedXML.writeProperty("D", "getlastmodified", 
FastHttpDateFormat.formatDate(lastModified));
                     generatedXML.writeProperty("D", "getcontentlength", 
Long.toString(contentLength));
@@ -2338,7 +2360,6 @@ public class WebdavServlet extends DefaultServlet 
implements PeriodicEventListen
                 generatedXML.writeElement("D", "prop", XMLWriter.OPENING);
 
                 generatedXML.writeElement("D", "creationdate", 
XMLWriter.NO_CONTENT);
-                generatedXML.writeElement("D", "displayname", 
XMLWriter.NO_CONTENT);
                 if (isFile) {
                     generatedXML.writeElement("D", "getcontentlanguage", 
XMLWriter.NO_CONTENT);
                     generatedXML.writeElement("D", "getcontentlength", 
XMLWriter.NO_CONTENT);
@@ -2468,7 +2489,9 @@ public class WebdavServlet extends DefaultServlet 
implements PeriodicEventListen
 
 
     /**
-     * Generate propfind XML fragments for dead properties.
+     * Generate propfind XML fragments for dead properties. This should be 
overridden by subclasses to provide
+     * useful behavior. The default implementation prevents setting protected 
properties
+     * (anything from the DAV: namespace), and sets 507 for a set attempt on 
dead properties.
      *
      * @param path the resource path
      * @param property the dead property, if null then all dead properties 
must be written
@@ -2477,6 +2500,30 @@ public class WebdavServlet extends DefaultServlet 
implements PeriodicEventListen
      * @return true if property was specified and a corresponding dead 
property was found on the resource, false otherwise
      */
     protected boolean propfindResource(String path, Node property, boolean 
nameOnly, XMLWriter generatedXML) {
+        if (nameOnly) {
+            generatedXML.writeElement("D", "displayname", 
XMLWriter.NO_CONTENT);
+        } else if (property == null) {
+            String resourceName = path;
+            int lastSlash = path.lastIndexOf('/');
+            if (lastSlash != -1) {
+                resourceName = resourceName.substring(lastSlash + 1);
+            }
+            generatedXML.writeElement("D", "displayname", XMLWriter.OPENING);
+            generatedXML.writeData(resourceName);
+            generatedXML.writeElement("D", "displayname", XMLWriter.CLOSING);
+        } else {
+            String davName = getDAVNode(property);
+            if ("displayname".equals(davName)) {
+                String resourceName = path;
+                int lastSlash = path.lastIndexOf('/');
+                if (lastSlash != -1) {
+                    resourceName = resourceName.substring(lastSlash + 1);
+                }
+                generatedXML.writeElement("D", "displayname", 
XMLWriter.OPENING);
+                generatedXML.writeData(resourceName);
+                generatedXML.writeElement("D", "displayname", 
XMLWriter.CLOSING);
+            }
+        }
         return false;
     }
 
@@ -2575,7 +2622,7 @@ public class WebdavServlet extends DefaultServlet 
implements PeriodicEventListen
 
 
     private static String getDAVNode(Node node) {
-        if (node.getNamespaceURI().equals(DEFAULT_NAMESPACE)) {
+        if (DEFAULT_NAMESPACE.equals(node.getNamespaceURI())) {
             return node.getLocalName();
         }
         return null;
@@ -2731,7 +2778,9 @@ public class WebdavServlet extends DefaultServlet 
implements PeriodicEventListen
         public ProppatchOperation(PropertyUpdateType updateType, Node 
propertyNode) {
             this.updateType = updateType;
             this.propertyNode = propertyNode;
-            protectedProperty = getDAVNode(propertyNode) != null;
+            String davName = getDAVNode(propertyNode);
+            protectedProperty = davName != null
+                    && (!(davName.equals("displayname") || 
davName.equals("getcontentlanguage")));
         }
         /**
          * @return the updateType
diff --git a/java/org/apache/catalina/util/DOMWriter.java 
b/java/org/apache/catalina/util/DOMWriter.java
index 0cd3532526..7ef95b1ffa 100644
--- a/java/org/apache/catalina/util/DOMWriter.java
+++ b/java/org/apache/catalina/util/DOMWriter.java
@@ -64,14 +64,22 @@ public class DOMWriter {
                 out.print('<');
                 out.print(node.getLocalName());
                 Attr attrs[] = sortAttributes(node.getAttributes());
+                boolean xmlns = false;
                 for (Attr attr : attrs) {
                     out.print(' ');
                     out.print(attr.getLocalName());
-
+                    if ("xmlns".equals(attr.getLocalName())) {
+                        xmlns = true;
+                    }
                     out.print("=\"");
                     out.print(Escape.xml("", true, attr.getNodeValue()));
                     out.print('"');
                 }
+                if (!xmlns && node.getNamespaceURI() != null) {
+                    out.print(" xmlns=\"");
+                    out.print(Escape.xml(node.getNamespaceURI()));
+                    out.print('"');
+                }
                 out.print('>');
                 printChildren(node);
                 break;
@@ -88,7 +96,7 @@ public class DOMWriter {
 
             // print text
             case Node.TEXT_NODE:
-                out.print(Escape.xml("", true, node.getNodeValue()));
+                out.print(Escape.xml("", false, node.getNodeValue()));
                 break;
 
             // print processing instruction
diff --git a/test/org/apache/catalina/servlets/TestWebdavServlet.java 
b/test/org/apache/catalina/servlets/TestWebdavServlet.java
index 8272381a56..71f7977ae4 100644
--- a/test/org/apache/catalina/servlets/TestWebdavServlet.java
+++ b/test/org/apache/catalina/servlets/TestWebdavServlet.java
@@ -20,7 +20,6 @@ import java.io.File;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.StringReader;
-import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 
@@ -36,7 +35,6 @@ import org.apache.catalina.Wrapper;
 import org.apache.catalina.startup.SimpleHttpClient;
 import org.apache.catalina.startup.Tomcat;
 import org.apache.catalina.startup.TomcatBaseTest;
-import org.apache.catalina.util.XMLWriter;
 import org.apache.tomcat.util.buf.ByteChunk;
 import org.apache.tomcat.websocket.server.WsContextListener;
 import org.xml.sax.InputSource;
@@ -230,7 +228,7 @@ public class TestWebdavServlet extends TomcatBaseTest {
             "<D:propertyupdate xmlns:D=\"DAV:\" 
xmlns:T=\"http://tomcat.apache.org/testsuite\";>\n" +
             "  <D:set>\n" +
             "    <D:prop>\n" +
-            "      <T:customprop 
xmlns:T=\"http://tomcat.apache.org/testsuite\";>\n" +
+            "      <T:customprop>\n" +
             "        <T:myvalue/>\n" +
             "      </T:customprop>\n" +
             "    </D:prop>\n" +
@@ -248,7 +246,7 @@ public class TestWebdavServlet extends TomcatBaseTest {
         File tempWebapp = new File(getTemporaryDirectory(), 
"webdav-properties");
         Assert.assertTrue(tempWebapp.mkdirs());
         Context ctxt = tomcat.addContext("", tempWebapp.getAbsolutePath());
-        Wrapper webdavServlet = Tomcat.addServlet(ctxt, "webdav", new 
CustomWebdavServlet());
+        Wrapper webdavServlet = Tomcat.addServlet(ctxt, "webdav", new 
TransientPropertiesWebdavServlet());
         webdavServlet.addInitParameter("listings", "true");
         webdavServlet.addInitParameter("secret", "foo");
         webdavServlet.addInitParameter("readonly", "false");
@@ -289,7 +287,17 @@ public class TestWebdavServlet extends TomcatBaseTest {
         Assert.assertEquals(WebdavStatus.SC_MULTI_STATUS, 
client.getStatusCode());
         
Assert.assertTrue(client.getResponseBody().contains("opaquelocktoken:"));
 
-        client.setRequest(new String[] { "PROPFIND / HTTP/1.1" + 
SimpleHttpClient.CRLF +
+        client.setRequest(new String[] { "PROPPATCH /file1.txt HTTP/1.1" + 
SimpleHttpClient.CRLF +
+                "Host: localhost:" + getPort() + SimpleHttpClient.CRLF +
+                "Content-Length: " + PROPPATCH_PROPNAME.length() + 
SimpleHttpClient.CRLF +
+                "Connection: Close" + SimpleHttpClient.CRLF +
+                SimpleHttpClient.CRLF + PROPPATCH_PROPNAME });
+        client.connect();
+        client.processRequest(true);
+        Assert.assertEquals(WebdavStatus.SC_MULTI_STATUS, 
client.getStatusCode());
+        
Assert.assertTrue(client.getResponseBody().contains("<T:othercustomprop"));
+
+        client.setRequest(new String[] { "PROPFIND /file1.txt HTTP/1.1" + 
SimpleHttpClient.CRLF +
                 "Host: localhost:" + getPort() + SimpleHttpClient.CRLF +
                 "Content-Length: " + PROPFIND_PROPNAME.length() + 
SimpleHttpClient.CRLF +
                 "Connection: Close" + SimpleHttpClient.CRLF +
@@ -299,7 +307,7 @@ public class TestWebdavServlet extends TomcatBaseTest {
         Assert.assertEquals(WebdavStatus.SC_MULTI_STATUS, 
client.getStatusCode());
         
Assert.assertTrue(client.getResponseBody().contains("<D:getcontenttype/>"));
 
-        client.setRequest(new String[] { "PROPFIND / HTTP/1.1" + 
SimpleHttpClient.CRLF +
+        client.setRequest(new String[] { "PROPFIND /file1.txt HTTP/1.1" + 
SimpleHttpClient.CRLF +
                 "Host: localhost:" + getPort() + SimpleHttpClient.CRLF +
                 "Content-Length: " + PROPFIND_PROP.length() + 
SimpleHttpClient.CRLF +
                 "Connection: Close" + SimpleHttpClient.CRLF +
@@ -309,18 +317,28 @@ public class TestWebdavServlet extends TomcatBaseTest {
         Assert.assertEquals(WebdavStatus.SC_MULTI_STATUS, 
client.getStatusCode());
         
Assert.assertTrue(client.getResponseBody().contains("<D:getcontenttype>"));
         
Assert.assertFalse(client.getResponseBody().contains("<D:getlastmodified>"));
-        Assert.assertTrue(client.getResponseBody().contains("<T:myvalue/>"));
+        Assert.assertTrue(client.getResponseBody().contains("<myvalue 
xmlns=\"http://tomcat.apache.org/testsuite\";>"));
 
-        client.setRequest(new String[] { "PROPPATCH /file1.txt HTTP/1.1" + 
SimpleHttpClient.CRLF +
+        client.setRequest(new String[] { "MOVE /file1.txt HTTP/1.1" + 
SimpleHttpClient.CRLF +
                 "Host: localhost:" + getPort() + SimpleHttpClient.CRLF +
-                "Content-Length: " + PROPPATCH_PROPNAME.length() + 
SimpleHttpClient.CRLF +
+                "Destination: /file3.txt" + SimpleHttpClient.CRLF +
                 "Connection: Close" + SimpleHttpClient.CRLF +
-                SimpleHttpClient.CRLF + PROPPATCH_PROPNAME });
+                SimpleHttpClient.CRLF });
+        client.connect();
+        client.processRequest(true);
+        Assert.assertEquals(HttpServletResponse.SC_CREATED, 
client.getStatusCode());
+
+        client.setRequest(new String[] { "PROPFIND /file3.txt HTTP/1.1" + 
SimpleHttpClient.CRLF +
+                "Host: localhost:" + getPort() + SimpleHttpClient.CRLF +
+                "Content-Length: " + PROPFIND_PROP.length() + 
SimpleHttpClient.CRLF +
+                "Connection: Close" + SimpleHttpClient.CRLF +
+                SimpleHttpClient.CRLF + PROPFIND_PROP });
         client.connect();
         client.processRequest(true);
         Assert.assertEquals(WebdavStatus.SC_MULTI_STATUS, 
client.getStatusCode());
-        Assert.assertTrue(proppatchSuccess);
-        
Assert.assertTrue(client.getResponseBody().contains("<T:othercustomprop"));
+        
Assert.assertTrue(client.getResponseBody().contains("<D:getcontenttype>"));
+        
Assert.assertFalse(client.getResponseBody().contains("<D:getlastmodified>"));
+        Assert.assertTrue(client.getResponseBody().contains("<myvalue 
xmlns=\"http://tomcat.apache.org/testsuite\";>"));
 
     }
 
@@ -979,46 +997,4 @@ public class TestWebdavServlet extends TomcatBaseTest {
         }
     }
 
-    private static boolean proppatchSuccess = false;
-
-    private class CustomWebdavServlet extends WebdavServlet {
-
-        private static final long serialVersionUID = 1L;
-
-        @Override
-        protected void proppatchResource(String path, 
ArrayList<ProppatchOperation> operations) {
-            for (ProppatchOperation operation : operations) {
-                if (operation.getUpdateType().equals(PropertyUpdateType.SET)
-                        && 
operation.getPropertyNode().getLocalName().equals("customprop")) {
-                    proppatchSuccess = true;
-                }
-                operation.setStatusCode(HttpServletResponse.SC_OK);
-            }
-        }
-
-        @Override
-        protected boolean propfindResource(String path, org.w3c.dom.Node 
property, boolean nameOnly, XMLWriter generatedXML) {
-            if (nameOnly) {
-                generatedXML.writeElement("T", 
"http://tomcat.apache.org/testsuite";, "customprop", XMLWriter.NO_CONTENT);
-                generatedXML.writeElement("T", 
"http://tomcat.apache.org/testsuite";, "othercustomprop", XMLWriter.NO_CONTENT);
-            } else if (property == null) {
-                generatedXML.writeElement("T", 
"http://tomcat.apache.org/testsuite";, "customprop", XMLWriter.OPENING);
-                generatedXML.writeElement("T", "myvalue", 
XMLWriter.NO_CONTENT);
-                generatedXML.writeElement("T", "customprop", 
XMLWriter.CLOSING);
-                generatedXML.writeElement("T", 
"http://tomcat.apache.org/testsuite";, "othercustomprop", XMLWriter.OPENING);
-                generatedXML.writeElement("T", "myothervalue", 
XMLWriter.NO_CONTENT);
-                generatedXML.writeElement("T", "othercustomprop", 
XMLWriter.CLOSING);
-            } else if (property.getLocalName().equals("customprop")) {
-                generatedXML.writeElement("T", 
"http://tomcat.apache.org/testsuite";, "customprop", XMLWriter.OPENING);
-                generatedXML.writeElement("T", "myvalue", 
XMLWriter.NO_CONTENT);
-                generatedXML.writeElement("T", "customprop", 
XMLWriter.CLOSING);
-                return true;
-            } else if (property.getLocalName().equals("othercustomprop")) {
-                return false;
-            }
-            return false;
-        }
-
-    }
-
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to