You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by re...@apache.org on 2020/07/09 11:40:40 UTC
svn commit: r1879702 - in /jackrabbit/branches/2.20: ./
jackrabbit-jcr-server/src/test/java/org/apache/jackrabbit/webdav/server/
jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/
jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/...
Author: reschke
Date: Thu Jul 9 11:40:40 2020
New Revision: 1879702
URL: http://svn.apache.org/viewvc?rev=1879702&view=rev
Log:
JCR-4166: support GZIP content coding in requests (merged r1878706 into 2.20)
Added:
jackrabbit/branches/2.20/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/ContentCodingAwareRequest.java
- copied unchanged from r1878706, jackrabbit/trunk/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/ContentCodingAwareRequest.java
Modified:
jackrabbit/branches/2.20/ (props changed)
jackrabbit/branches/2.20/jackrabbit-jcr-server/src/test/java/org/apache/jackrabbit/webdav/server/ContentCodingTest.java
jackrabbit/branches/2.20/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/DavException.java
jackrabbit/branches/2.20/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/WebdavRequestImpl.java
jackrabbit/branches/2.20/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/package-info.java
jackrabbit/branches/2.20/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/server/AbstractWebdavServlet.java
jackrabbit/branches/2.20/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/server/package-info.java
jackrabbit/branches/2.20/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/xml/DomUtil.java
jackrabbit/branches/2.20/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/xml/package-info.java
Propchange: jackrabbit/branches/2.20/
------------------------------------------------------------------------------
Merged /jackrabbit/trunk:r1878706
Modified: jackrabbit/branches/2.20/jackrabbit-jcr-server/src/test/java/org/apache/jackrabbit/webdav/server/ContentCodingTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/2.20/jackrabbit-jcr-server/src/test/java/org/apache/jackrabbit/webdav/server/ContentCodingTest.java?rev=1879702&r1=1879701&r2=1879702&view=diff
==============================================================================
--- jackrabbit/branches/2.20/jackrabbit-jcr-server/src/test/java/org/apache/jackrabbit/webdav/server/ContentCodingTest.java (original)
+++ jackrabbit/branches/2.20/jackrabbit-jcr-server/src/test/java/org/apache/jackrabbit/webdav/server/ContentCodingTest.java Thu Jul 9 11:40:40 2020
@@ -16,7 +16,6 @@
*/
package org.apache.jackrabbit.webdav.server;
-import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
@@ -25,7 +24,7 @@ import java.util.zip.GZIPOutputStream;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpHead;
import org.apache.http.client.methods.HttpPut;
-import org.apache.http.entity.InputStreamEntity;
+import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.entity.StringEntity;
import org.apache.http.message.BasicHeader;
import org.apache.jackrabbit.webdav.DavConstants;
@@ -54,7 +53,7 @@ public class ContentCodingTest extends W
entity.setContentEncoding(new BasicHeader("Content-Encoding", "qux"));
put.setEntity(entity);
status = this.client.execute(put, this.context).getStatusLine().getStatusCode();
- assertTrue("server must signal error for unknown content coding", status == 415);
+ assertTrue("server must signal error for unknown content coding, got: " + status, status == 415);
} finally {
if (status / 2 == 100) {
delete(testUri);
@@ -68,22 +67,19 @@ public class ContentCodingTest extends W
try {
byte bytes[] = "foobarfoobarfoobar".getBytes("UTF-8");
HttpPut put = new HttpPut(testUri);
- ByteArrayOutputStream bos = new ByteArrayOutputStream();
- OutputStream gos = new GZIPOutputStream(bos);
- gos.write(bytes);
- gos.flush();
- assertTrue(bos.toByteArray().length != bytes.length);
- InputStreamEntity entity = new InputStreamEntity(new ByteArrayInputStream(bos.toByteArray()));
+ byte gzbytes[] = asGzipOctets(bytes);
+ assertTrue(gzbytes.length != bytes.length);
+ ByteArrayEntity entity = new ByteArrayEntity(gzbytes);
entity.setContentEncoding(new BasicHeader("Content-Encoding", "gzip"));
put.setEntity(entity);
status = this.client.execute(put, this.context).getStatusLine().getStatusCode();
- assertTrue("server create or signal error", status == 201 || status == 415);
+ assertTrue("server create or signal error, got: " + status, status == 201 || status == 415);
if (status / 2 == 100) {
// check length
HttpHead head = new HttpHead(testUri);
HttpResponse response = this.client.execute(head, this.context);
assertEquals(200, response.getStatusLine().getStatusCode());
- assertEquals(bytes.length, response.getFirstHeader("Content-Length").getValue());
+ assertEquals(bytes.length, Integer.parseInt(response.getFirstHeader("Content-Length").getValue()));
}
} finally {
if (status / 2 == 100) {
@@ -98,13 +94,59 @@ public class ContentCodingTest extends W
assertEquals(207, status);
}
+ private static String PF = "<D:propfind xmlns:D=\"DAV:\"><D:prop><D:resourcetype/></D:prop></D:propfind>";
+
public void testPropfindUnknownContentCoding() throws IOException {
HttpPropfind propfind = new HttpPropfind(uri, DavConstants.PROPFIND_BY_PROPERTY, 0);
- StringEntity entity = new StringEntity(
- "<D:propfind xmlns:D=\"DAV:\"><D:prop xmlns:R=\"http://ns.example.com/boxschema/\"><R:bigbox/></D:prop></D:propfind>");
+ StringEntity entity = new StringEntity(PF);
entity.setContentEncoding(new BasicHeader("Content-Encoding", "qux"));
propfind.setEntity(entity);
+ HttpResponse response = this.client.execute(propfind, this.context);
+ int status = response.getStatusLine().getStatusCode();
+ assertTrue("server must signal error for unknown content coding, got: " + status, status == 415);
+ assertEquals("gzip", response.getFirstHeader("Accept").getValue());
+ }
+
+ public void testPropfindGzipContentCoding() throws IOException {
+ HttpPropfind propfind = new HttpPropfind(uri, DavConstants.PROPFIND_BY_PROPERTY, 0);
+ ByteArrayEntity entity = new ByteArrayEntity(asGzipOctets(PF));
+ entity.setContentEncoding(new BasicHeader("Content-Encoding", "gzip"));
+ propfind.setEntity(entity);
+ int status = this.client.execute(propfind, this.context).getStatusLine().getStatusCode();
+ assertEquals(207, status);
+ }
+
+ // double encoded, empty list member in field value, mixed upper/lower in
+ // coding name
+ public void testPropfindGzipContentCodingTwice() throws IOException {
+ HttpPropfind propfind = new HttpPropfind(uri, DavConstants.PROPFIND_BY_PROPERTY, 0);
+ ByteArrayEntity entity = new ByteArrayEntity(asGzipOctets(asGzipOctets(PF)));
+ entity.setContentEncoding(new BasicHeader("Content-Encoding", "gziP,, Gzip"));
+ propfind.setEntity(entity);
int status = this.client.execute(propfind, this.context).getStatusLine().getStatusCode();
- assertTrue("server must signal error for unknown content coding", status == 415);
+ assertEquals(207, status);
+ }
+
+ // double encoded, but only when encoding in header field
+ public void testPropfindGzipContentCodingBadSpec() throws IOException {
+ HttpPropfind propfind = new HttpPropfind(uri, DavConstants.PROPFIND_BY_PROPERTY, 0);
+ ByteArrayEntity entity = new ByteArrayEntity(asGzipOctets(asGzipOctets(PF)));
+ entity.setContentEncoding(new BasicHeader("Content-Encoding", "gzip"));
+ propfind.setEntity(entity);
+ int status = this.client.execute(propfind, this.context).getStatusLine().getStatusCode();
+ assertEquals(400, status);
+ }
+
+ private static byte[] asGzipOctets(String input) throws IOException {
+ return asGzipOctets(input.getBytes("UTF-8"));
+ }
+
+ private static byte[] asGzipOctets(byte[] input) throws IOException {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ OutputStream gos = new GZIPOutputStream(bos);
+ gos.write(input);
+ gos.flush();
+ gos.close();
+ return bos.toByteArray();
}
}
Modified: jackrabbit/branches/2.20/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/DavException.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/2.20/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/DavException.java?rev=1879702&r1=1879701&r2=1879702&view=diff
==============================================================================
--- jackrabbit/branches/2.20/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/DavException.java (original)
+++ jackrabbit/branches/2.20/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/DavException.java Thu Jul 9 11:40:40 2020
@@ -139,6 +139,15 @@ public class DavException extends Except
}
/**
+ * Return the error condition attached to this <code>DavException</code>.
+ *
+ * @return errorCondition
+ */
+ public Element getErrorCondition() {
+ return errorCondition;
+ }
+
+ /**
* Returns a DAV:error element containing the error condition or
* <code>null</code> if no specific condition is available. See
* <a href="http://www.ietf.org/rfc/rfc3253.txt">RFC 3253</a>
@@ -163,4 +172,4 @@ public class DavException extends Except
return null;
}
}
-}
\ No newline at end of file
+}
Modified: jackrabbit/branches/2.20/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/WebdavRequestImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/2.20/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/WebdavRequestImpl.java?rev=1879702&r1=1879701&r2=1879702&view=diff
==============================================================================
--- jackrabbit/branches/2.20/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/WebdavRequestImpl.java (original)
+++ jackrabbit/branches/2.20/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/WebdavRequestImpl.java Thu Jul 9 11:40:40 2020
@@ -30,12 +30,15 @@ import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
+import java.util.zip.GZIPInputStream;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletInputStream;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
+import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.apache.jackrabbit.webdav.bind.BindInfo;
@@ -62,6 +65,7 @@ import org.apache.jackrabbit.webdav.prop
import org.apache.jackrabbit.webdav.property.DavPropertySet;
import org.apache.jackrabbit.webdav.property.DefaultDavProperty;
import org.apache.jackrabbit.webdav.property.PropEntry;
+import org.apache.jackrabbit.webdav.server.AbstractWebdavServlet;
import org.apache.jackrabbit.webdav.transaction.TransactionConstants;
import org.apache.jackrabbit.webdav.transaction.TransactionInfo;
import org.apache.jackrabbit.webdav.version.LabelInfo;
@@ -80,7 +84,7 @@ import org.xml.sax.SAXException;
/**
* <code>WebdavRequestImpl</code>...
*/
-public class WebdavRequestImpl implements WebdavRequest, DavConstants {
+public class WebdavRequestImpl implements WebdavRequest, DavConstants, ContentCodingAwareRequest {
private static Logger log = LoggerFactory.getLogger(WebdavRequestImpl.class);
@@ -308,7 +312,7 @@ public class WebdavRequestImpl implement
}
// try to parse the request body
try {
- InputStream in = httpRequest.getInputStream();
+ InputStream in = getDecodedInputStream(httpRequest);
if (in != null) {
// use a buffered input stream to find out whether there actually
// is a request body
@@ -324,7 +328,8 @@ public class WebdavRequestImpl implement
if (log.isDebugEnabled()) {
log.debug("Unable to build an XML Document from the request body: " + e.getMessage());
}
- throw new DavException(DavServletResponse.SC_BAD_REQUEST);
+ Throwable cause = e.getCause();
+ throw (cause instanceof DavException) ? (DavException) cause : new DavException(DavServletResponse.SC_BAD_REQUEST);
} catch (ParserConfigurationException e) {
if (log.isDebugEnabled()) {
log.debug("Unable to build an XML Document from the request body: " + e.getMessage());
@@ -367,6 +372,39 @@ public class WebdavRequestImpl implement
return propfindProps;
}
+ private static InputStream getDecodedInputStream(HttpServletRequest request) throws IOException {
+ List<String> contentCodings = AbstractWebdavServlet.getContentCodings(request);
+ int len = contentCodings.size();
+
+ log.trace("content codings: " + contentCodings);
+ InputStream result = request.getInputStream();
+
+ for (int i = 1; i <= len; i++) {
+ String s = contentCodings.get(len - i);
+ log.trace("decoding: " + s);
+ if ("gzip".equals(s)) {
+ result = new GZIPInputStream(result);
+ } else {
+ String message = "Unsupported content coding: " + s;
+ try {
+ Element condition = DomUtil.createElement(
+ DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(), PRECONDITION_SUPPORTED);
+ throw new IOException(
+ new DavException(HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE, message, null, condition));
+ } catch (ParserConfigurationException ex) {
+ throw new IOException(message);
+ }
+ }
+ }
+
+ return result;
+ }
+
+ @Override
+ public String getAcceptableCodings() {
+ return "gzip";
+ }
+
/**
* Parse the propfind request body in order to determine the type of the propfind
* and the set of requested property.
@@ -940,7 +978,7 @@ public class WebdavRequestImpl implement
}
public ServletInputStream getInputStream() throws IOException {
- return httpRequest.getInputStream();
+ return new MyServletInputStream(getDecodedInputStream(httpRequest));
}
public String getParameter(String s) {
@@ -1030,4 +1068,78 @@ public class WebdavRequestImpl implement
public int getLocalPort() {
return httpRequest.getLocalPort();
}
+
+ private static class MyServletInputStream extends ServletInputStream {
+
+ private final InputStream delegate;
+
+ public MyServletInputStream(InputStream delegate) {
+ this.delegate = delegate;
+ }
+
+ @Override
+ public int available() throws IOException {
+ return delegate.available();
+ }
+
+ @Override
+ public void close() throws IOException {
+ delegate.close();
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ return delegate.equals(other);
+ }
+
+ @Override
+ public int hashCode() {
+ return delegate.hashCode();
+ }
+
+ @Override
+ public void mark(int readlimit) {
+ delegate.mark(readlimit);
+ }
+
+ @Override
+ public boolean markSupported() {
+ return delegate.markSupported();
+ }
+
+ @Override
+ public int read() throws IOException {
+ return delegate.read();
+ }
+
+ @Override
+ public int read(byte[] b, int off, int len) throws IOException {
+ return delegate.read(b, off, len);
+ }
+
+ @Override
+ public int read(byte[] b) throws IOException {
+ return delegate.read(b);
+ }
+
+ @Override
+ public int readLine(byte[] b, int off, int len) throws IOException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void reset() throws IOException {
+ delegate.reset();
+ }
+
+ @Override
+ public long skip(long n) throws IOException {
+ return delegate.skip(n);
+ }
+
+ @Override
+ public String toString() {
+ return delegate.toString();
+ }
+ }
}
Modified: jackrabbit/branches/2.20/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/package-info.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/2.20/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/package-info.java?rev=1879702&r1=1879701&r2=1879702&view=diff
==============================================================================
--- jackrabbit/branches/2.20/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/package-info.java (original)
+++ jackrabbit/branches/2.20/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/package-info.java Thu Jul 9 11:40:40 2020
@@ -14,5 +14,5 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-@org.osgi.annotation.versioning.Version("1.3.0")
+@org.osgi.annotation.versioning.Version("1.4.0")
package org.apache.jackrabbit.webdav;
Modified: jackrabbit/branches/2.20/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/server/AbstractWebdavServlet.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/2.20/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/server/AbstractWebdavServlet.java?rev=1879702&r1=1879701&r2=1879702&view=diff
==============================================================================
--- jackrabbit/branches/2.20/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/server/AbstractWebdavServlet.java (original)
+++ jackrabbit/branches/2.20/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/server/AbstractWebdavServlet.java Thu Jul 9 11:40:40 2020
@@ -16,6 +16,7 @@
*/
package org.apache.jackrabbit.webdav.server;
+import org.apache.jackrabbit.webdav.ContentCodingAwareRequest;
import org.apache.jackrabbit.webdav.DavCompliance;
import org.apache.jackrabbit.webdav.DavConstants;
import org.apache.jackrabbit.webdav.DavException;
@@ -76,9 +77,11 @@ import org.apache.jackrabbit.webdav.vers
import org.apache.jackrabbit.webdav.version.VersionableResource;
import org.apache.jackrabbit.webdav.version.report.Report;
import org.apache.jackrabbit.webdav.version.report.ReportInfo;
+import org.apache.jackrabbit.webdav.xml.DomUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
+import org.w3c.dom.Element;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
@@ -91,6 +94,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
+import java.util.Locale;
/**
* <code>AbstractWebdavServlet</code>
@@ -290,13 +294,15 @@ abstract public class AbstractWebdavServ
// JCR-4165: reject any content-coding in request until we can
// support it (see JCR-4166)
- List<String> ces = getContentCodings(request);
- if (!ces.isEmpty()) {
- webdavResponse.setStatus(HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE);
- webdavResponse.setHeader("Accept-Encoding", "identity");
- webdavResponse.setContentType("text/plain; charset=UTF-8");
- webdavResponse.getWriter().println("Content-Encodings not supported, but received: " + ces);
- webdavResponse.getWriter().flush();
+ if (!(webdavRequest instanceof ContentCodingAwareRequest)) {
+ List<String> ces = getContentCodings(request);
+ if (!ces.isEmpty()) {
+ webdavResponse.setStatus(HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE);
+ webdavResponse.setHeader("Accept-Encoding", "identity");
+ webdavResponse.setContentType("text/plain; charset=UTF-8");
+ webdavResponse.getWriter().println("Content-Encodings not supported, but received: " + ces);
+ webdavResponse.getWriter().flush();
+ }
}
// check matching if=header for lock-token relevant operations
@@ -308,12 +314,14 @@ abstract public class AbstractWebdavServ
if (!execute(webdavRequest, webdavResponse, methodCode, resource)) {
super.service(request, response);
}
-
} catch (DavException e) {
- if (e.getErrorCode() == HttpServletResponse.SC_UNAUTHORIZED) {
- sendUnauthorized(webdavRequest, webdavResponse, e);
+ handleDavException(webdavRequest, webdavResponse, e);
+ } catch (IOException ex) {
+ Throwable cause = ex.getCause();
+ if (cause instanceof DavException) {
+ handleDavException(webdavRequest, webdavResponse, (DavException) cause);
} else {
- webdavResponse.sendError(e);
+ throw ex;
}
} finally {
WebdavRequestContextHolder.clearContext();
@@ -321,6 +329,21 @@ abstract public class AbstractWebdavServ
}
}
+ private void handleDavException(WebdavRequest webdavRequest, WebdavResponse webdavResponse, DavException ex)
+ throws IOException {
+ if (ex.getErrorCode() == HttpServletResponse.SC_UNAUTHORIZED) {
+ sendUnauthorized(webdavRequest, webdavResponse, ex);
+ } else {
+ Element condition = ex.getErrorCondition();
+ if (DomUtil.matches(condition, ContentCodingAwareRequest.PRECONDITION_SUPPORTED)) {
+ if (webdavRequest instanceof ContentCodingAwareRequest) {
+ webdavResponse.setHeader("accept", ((ContentCodingAwareRequest) webdavRequest).getAcceptableCodings());
+ }
+ }
+ webdavResponse.sendError(ex);
+ }
+ }
+
/**
* Sets the "WWW-Authenticate" header and writes the appropriate error
* to the given webdav response.
@@ -1415,7 +1438,11 @@ abstract public class AbstractWebdavServ
return new OutputContextImpl(response, out);
}
- private List<String> getContentCodings(HttpServletRequest request) {
+ /**
+ * Obtain the (ordered!) list of content codings that have been used in the
+ * request
+ */
+ public static List<String> getContentCodings(HttpServletRequest request) {
List<String> result = Collections.emptyList();
for (@SuppressWarnings("unchecked")
Enumeration<String> ceh = request.getHeaders("Content-Encoding"); ceh.hasMoreElements();) {
@@ -1424,7 +1451,7 @@ abstract public class AbstractWebdavServ
if (result.isEmpty()) {
result = new ArrayList<String>();
}
- result.add(h.trim());
+ result.add(h.trim().toLowerCase(Locale.ENGLISH));
}
}
}
Modified: jackrabbit/branches/2.20/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/server/package-info.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/2.20/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/server/package-info.java?rev=1879702&r1=1879701&r2=1879702&view=diff
==============================================================================
--- jackrabbit/branches/2.20/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/server/package-info.java (original)
+++ jackrabbit/branches/2.20/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/server/package-info.java Thu Jul 9 11:40:40 2020
@@ -14,5 +14,5 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-@org.osgi.annotation.versioning.Version("1.1.0")
+@org.osgi.annotation.versioning.Version("1.2.0")
package org.apache.jackrabbit.webdav.server;
Modified: jackrabbit/branches/2.20/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/xml/DomUtil.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/2.20/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/xml/DomUtil.java?rev=1879702&r1=1879701&r2=1879702&view=diff
==============================================================================
--- jackrabbit/branches/2.20/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/xml/DomUtil.java (original)
+++ jackrabbit/branches/2.20/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/xml/DomUtil.java Thu Jul 9 11:40:40 2020
@@ -530,6 +530,19 @@ public class DomUtil {
}
/**
+ * Create a new DOM element with the specified local name and namespace.
+ *
+ * @param factory
+ * @param qName
+ * @return a new DOM element
+ * @see Document#createElement(String)
+ * @see Document#createElementNS(String, String)
+ */
+ public static Element createElement(Document factory, QName elementName) {
+ return factory.createElementNS(elementName.getNamespaceURI(), getPrefixedName(elementName));
+ }
+
+ /**
* Create a new DOM element with the specified local name and namespace and
* add the specified text as Text node to it.
*
@@ -764,15 +777,34 @@ public class DomUtil {
* @see Document#createElementNS(String, String)
*/
public static String getPrefixedName(String localName, Namespace namespace) {
- if (namespace == null
- || Namespace.EMPTY_NAMESPACE.equals(namespace)
- || Namespace.EMPTY_NAMESPACE.getPrefix().equals(namespace.getPrefix())) {
+ return getPrefixName(namespace.getURI(), namespace.getPrefix(), localName);
+ }
+
+ /**
+ * Return the qualified name of a DOM node consisting of
+ * namespace prefix + ":" + local name. If the specified namespace is <code>null</code>
+ * or contains an empty prefix, the local name is returned.<br>
+ * NOTE, that this is the value to be used for the 'qualified Name' parameter
+ * expected with the namespace sensitive factory methods.
+ *
+ * @param qName
+ * @return qualified name consisting of prefix, ':' and local name.
+ * @see Document#createAttributeNS(String, String)
+ * @see Document#createElementNS(String, String)
+ */
+ public static String getPrefixedName(QName name) {
+ return getPrefixName(name.getNamespaceURI(), name.getPrefix(), name.getLocalPart());
+ }
+
+ private static String getPrefixName(String namespaceURI, String prefix, String localName) {
+ if (namespaceURI == null || prefix == null || "".equals(namespaceURI) || "".equals(prefix)) {
return localName;
+ } else {
+ StringBuffer buf = new StringBuffer(prefix);
+ buf.append(":");
+ buf.append(localName);
+ return buf.toString();
}
- StringBuffer buf = new StringBuffer(namespace.getPrefix());
- buf.append(":");
- buf.append(localName);
- return buf.toString();
}
/**
Modified: jackrabbit/branches/2.20/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/xml/package-info.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/2.20/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/xml/package-info.java?rev=1879702&r1=1879701&r2=1879702&view=diff
==============================================================================
--- jackrabbit/branches/2.20/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/xml/package-info.java (original)
+++ jackrabbit/branches/2.20/jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/xml/package-info.java Thu Jul 9 11:40:40 2020
@@ -14,5 +14,5 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-@org.osgi.annotation.versioning.Version("1.1.0")
+@org.osgi.annotation.versioning.Version("1.2.0")
package org.apache.jackrabbit.webdav.xml;