You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by se...@apache.org on 2012/03/14 00:35:13 UTC
svn commit: r1300410 - in /cxf/branches/2.5.x-fixes: ./
common/common/src/main/java/org/apache/cxf/staxutils/
rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/
Author: sergeyb
Date: Tue Mar 13 23:35:13 2012
New Revision: 1300410
URL: http://svn.apache.org/viewvc?rev=1300410&view=rev
Log:
Merged revisions 1298832 via svnmerge from
https://svn.apache.org/repos/asf/cxf/trunk
........
r1298832 | sergeyb | 2012-03-09 14:04:08 +0000 (Fri, 09 Mar 2012) | 1 line
[CXF-4172] Some refactoring plus working around the lack of streaming support in Jettison
........
Added:
cxf/branches/2.5.x-fixes/common/common/src/main/java/org/apache/cxf/staxutils/DocumentDepthProperties.java (with props)
Modified:
cxf/branches/2.5.x-fixes/ (props changed)
cxf/branches/2.5.x-fixes/common/common/src/main/java/org/apache/cxf/staxutils/DepthRestrictingStreamReader.java
cxf/branches/2.5.x-fixes/common/common/src/main/java/org/apache/cxf/staxutils/StaxUtils.java
cxf/branches/2.5.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractJAXBProvider.java
cxf/branches/2.5.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JSONProvider.java
cxf/branches/2.5.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JSONUtils.java
Propchange: cxf/branches/2.5.x-fixes/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Tue Mar 13 23:35:13 2012
@@ -1 +1 @@
-/cxf/trunk:1236902,1297296,1298470,1298601-1298624,1298830,1299635,1299682,1299707,1300342
+/cxf/trunk:1236902,1297296,1298470,1298601-1298624,1298830,1298832,1299635,1299682,1299707,1300342
Propchange: cxf/branches/2.5.x-fixes/
------------------------------------------------------------------------------
Binary property 'svnmerge-integrated' - no diff available.
Modified: cxf/branches/2.5.x-fixes/common/common/src/main/java/org/apache/cxf/staxutils/DepthRestrictingStreamReader.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.5.x-fixes/common/common/src/main/java/org/apache/cxf/staxutils/DepthRestrictingStreamReader.java?rev=1300410&r1=1300409&r2=1300410&view=diff
==============================================================================
--- cxf/branches/2.5.x-fixes/common/common/src/main/java/org/apache/cxf/staxutils/DepthRestrictingStreamReader.java (original)
+++ cxf/branches/2.5.x-fixes/common/common/src/main/java/org/apache/cxf/staxutils/DepthRestrictingStreamReader.java Tue Mar 13 23:35:13 2012
@@ -23,11 +23,18 @@ import java.util.Stack;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
+/**
+ * XMLStreamReader implementation which can be used to enforce a number of
+ * depth-restricting policies. The following properties are currently supported:
+ * - total number of elements in the document
+ * - the maximum depth of the given element; the root element will be checked by default
+ * - the maximum number of immediate child nodes for individual elements
+ *
+ * More sophisticated policies can be supported in the future.
+ */
public class DepthRestrictingStreamReader extends DepthXMLStreamReader {
- private int elementCountThreshold = -1;
- private int innerElementLevelThreshold = -1;
- private int innerElementCountThreshold = -1;
+ private DocumentDepthProperties props;
private int totalElementCount;
private Stack<Integer> stack = new Stack<Integer>();
@@ -36,25 +43,33 @@ public class DepthRestrictingStreamReade
int innerElementLevelThreshold,
int innerElementCountThreshold) {
super(reader);
- this.elementCountThreshold = elementCountThreshold;
- this.innerElementLevelThreshold = innerElementLevelThreshold;
- this.innerElementCountThreshold = innerElementCountThreshold;
+ this.props = new DocumentDepthProperties(elementCountThreshold,
+ innerElementLevelThreshold,
+ innerElementCountThreshold);
+ }
+
+ public DepthRestrictingStreamReader(XMLStreamReader reader,
+ DocumentDepthProperties props) {
+ super(reader);
+ this.props = props;
}
@Override
public int next() throws XMLStreamException {
int next = super.next();
if (next == START_ELEMENT) {
- if (innerElementLevelThreshold != -1 && getDepth() >= innerElementLevelThreshold) {
+ if (props.getInnerElementLevelThreshold() != -1
+ && getDepth() >= props.getInnerElementLevelThreshold()) {
throw new DepthExceededStaxException();
}
- if (elementCountThreshold != -1 && ++totalElementCount >= elementCountThreshold) {
+ if (props.getElementCountThreshold() != -1
+ && ++totalElementCount >= props.getElementCountThreshold()) {
throw new DepthExceededStaxException();
}
- if (innerElementCountThreshold != -1) {
+ if (props.getInnerElementCountThreshold() != -1) {
if (!stack.empty()) {
int currentCount = stack.pop();
- if (++currentCount >= innerElementCountThreshold) {
+ if (++currentCount >= props.getInnerElementCountThreshold()) {
throw new DepthExceededStaxException();
} else {
stack.push(currentCount);
@@ -63,11 +78,9 @@ public class DepthRestrictingStreamReade
stack.push(0);
}
- } else if (next == END_ELEMENT && innerElementCountThreshold != -1) {
+ } else if (next == END_ELEMENT && props.getInnerElementCountThreshold() != -1) {
stack.pop();
}
return next;
}
-
-
}
Added: cxf/branches/2.5.x-fixes/common/common/src/main/java/org/apache/cxf/staxutils/DocumentDepthProperties.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.5.x-fixes/common/common/src/main/java/org/apache/cxf/staxutils/DocumentDepthProperties.java?rev=1300410&view=auto
==============================================================================
--- cxf/branches/2.5.x-fixes/common/common/src/main/java/org/apache/cxf/staxutils/DocumentDepthProperties.java (added)
+++ cxf/branches/2.5.x-fixes/common/common/src/main/java/org/apache/cxf/staxutils/DocumentDepthProperties.java Tue Mar 13 23:35:13 2012
@@ -0,0 +1,59 @@
+/**
+ * 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.cxf.staxutils;
+
+public class DocumentDepthProperties {
+ private int elementCountThreshold = -1;
+ private int innerElementLevelThreshold = -1;
+ private int innerElementCountThreshold = -1;
+ public DocumentDepthProperties() {
+
+ }
+ public DocumentDepthProperties(int elementCountThreshold,
+ int innerElementLevelThreshold,
+ int innerElementCountThreshold) {
+ this.elementCountThreshold = elementCountThreshold;
+ this.innerElementLevelThreshold = innerElementLevelThreshold;
+ this.innerElementCountThreshold = innerElementCountThreshold;
+ }
+
+ public boolean isEffective() {
+ return elementCountThreshold != -1 || innerElementLevelThreshold != -1
+ || innerElementCountThreshold != -1;
+ }
+
+ public void setElementCountThreshold(int elementCountThreshold) {
+ this.elementCountThreshold = elementCountThreshold;
+ }
+ public int getElementCountThreshold() {
+ return elementCountThreshold;
+ }
+ public void setInnerElementLevelThreshold(int innerElementLevelThreshold) {
+ this.innerElementLevelThreshold = innerElementLevelThreshold;
+ }
+ public int getInnerElementLevelThreshold() {
+ return innerElementLevelThreshold;
+ }
+ public void setInnerElementCountThreshold(int innerElementCountThreshold) {
+ this.innerElementCountThreshold = innerElementCountThreshold;
+ }
+ public int getInnerElementCountThreshold() {
+ return innerElementCountThreshold;
+ }
+}
Propchange: cxf/branches/2.5.x-fixes/common/common/src/main/java/org/apache/cxf/staxutils/DocumentDepthProperties.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cxf/branches/2.5.x-fixes/common/common/src/main/java/org/apache/cxf/staxutils/DocumentDepthProperties.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Modified: cxf/branches/2.5.x-fixes/common/common/src/main/java/org/apache/cxf/staxutils/StaxUtils.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.5.x-fixes/common/common/src/main/java/org/apache/cxf/staxutils/StaxUtils.java?rev=1300410&r1=1300409&r2=1300410&view=diff
==============================================================================
--- cxf/branches/2.5.x-fixes/common/common/src/main/java/org/apache/cxf/staxutils/StaxUtils.java (original)
+++ cxf/branches/2.5.x-fixes/common/common/src/main/java/org/apache/cxf/staxutils/StaxUtils.java Tue Mar 13 23:35:13 2012
@@ -82,6 +82,7 @@ import org.apache.cxf.helpers.DOMUtils;
import org.apache.cxf.helpers.XMLUtils;
public final class StaxUtils {
+ public static final String TOTAL_ELEMENT_COUNT = "org.apache.cxf.staxutils.totalElementCountThreshold";
public static final String INNER_ELEMENT_COUNT = "org.apache.cxf.staxutils.innerElementCountThreshold";
public static final String INNER_ELEMENT_LEVEL = "org.apache.cxf.staxutils.innerElementLevelThreshold";
@@ -530,7 +531,10 @@ public final class StaxUtils {
}
break;
case XMLStreamConstants.CHARACTERS:
- writer.writeCharacters(reader.getText());
+ String s = reader.getText();
+ if (s != null) {
+ writer.writeCharacters(s);
+ }
break;
case XMLStreamConstants.COMMENT:
writer.writeComment(reader.getText());
Modified: cxf/branches/2.5.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractJAXBProvider.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.5.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractJAXBProvider.java?rev=1300410&r1=1300409&r2=1300410&view=diff
==============================================================================
--- cxf/branches/2.5.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractJAXBProvider.java (original)
+++ cxf/branches/2.5.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractJAXBProvider.java Tue Mar 13 23:35:13 2012
@@ -74,6 +74,7 @@ import org.apache.cxf.message.Message;
import org.apache.cxf.phase.PhaseInterceptorChain;
import org.apache.cxf.staxutils.DepthRestrictingStreamReader;
import org.apache.cxf.staxutils.DepthXMLStreamReader;
+import org.apache.cxf.staxutils.DocumentDepthProperties;
import org.apache.cxf.staxutils.StaxUtils;
import org.apache.cxf.staxutils.transform.TransformUtils;
@@ -118,6 +119,7 @@ public abstract class AbstractJAXBProvid
private boolean validateOutput;
private boolean validateBeforeWrite;
private ValidationEventHandler eventHandler;
+ private DocumentDepthProperties depthProperties;
public void setValidationHandler(ValidationEventHandler handler) {
eventHandler = handler;
@@ -577,8 +579,6 @@ public abstract class AbstractJAXBProvid
this.inDropElements = dropElementsSet;
}
-
-
public void setAttributesToElements(boolean value) {
this.attributesToElements = value;
}
@@ -610,23 +610,39 @@ public abstract class AbstractJAXBProvid
}
protected XMLStreamReader createDepthReaderIfNeeded(XMLStreamReader reader, InputStream is) {
+ DocumentDepthProperties props = getDepthProperties();
+ if (props != null && props.isEffective()) {
+ reader = TransformUtils.createNewReaderIfNeeded(reader, is);
+ return new DepthRestrictingStreamReader(reader, props);
+ }
+ return reader;
+ }
+
+ protected DocumentDepthProperties getDepthProperties() {
+ if (depthProperties != null) {
+ return depthProperties;
+ }
if (getContext() != null) {
- String elementCountStr = (String)getContext().getContextualProperty(
+ String totalElementCountStr = (String)getContext().getContextualProperty(
+ StaxUtils.TOTAL_ELEMENT_COUNT);
+ String innerElementCountStr = (String)getContext().getContextualProperty(
StaxUtils.INNER_ELEMENT_COUNT);
String elementLevelStr = (String)getContext().getContextualProperty(
StaxUtils.INNER_ELEMENT_LEVEL);
- if (elementCountStr != null || elementLevelStr != null) {
+ if (totalElementCountStr != null || innerElementCountStr != null || elementLevelStr != null) {
try {
+ int totalElementCount = totalElementCountStr != null
+ ? Integer.valueOf(totalElementCountStr) : -1;
int elementLevel = elementLevelStr != null ? Integer.valueOf(elementLevelStr) : -1;
- int elementCount = elementCountStr != null ? Integer.valueOf(elementCountStr) : -1;
- reader = TransformUtils.createNewReaderIfNeeded(reader, is);
- reader = new DepthRestrictingStreamReader(reader, -1, elementLevel, elementCount);
+ int innerElementCount = innerElementCountStr != null
+ ? Integer.valueOf(innerElementCountStr) : -1;
+ return new DocumentDepthProperties(totalElementCount, elementLevel, innerElementCount);
} catch (Exception ex) {
throw new WebApplicationException(ex);
}
}
}
- return reader;
+ return null;
}
public void setValidateBeforeWrite(boolean validateBeforeWrite) {
@@ -637,6 +653,10 @@ public abstract class AbstractJAXBProvid
this.validateOutput = validateOutput;
}
+ public void setDepthProperties(DocumentDepthProperties depthProperties) {
+ this.depthProperties = depthProperties;
+ }
+
@XmlRootElement
protected static class CollectionWrapper {
Modified: cxf/branches/2.5.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JSONProvider.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.5.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JSONProvider.java?rev=1300410&r1=1300409&r2=1300410&view=diff
==============================================================================
--- cxf/branches/2.5.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JSONProvider.java (original)
+++ cxf/branches/2.5.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JSONProvider.java Tue Mar 13 23:35:13 2012
@@ -258,10 +258,9 @@ public class JSONProvider extends Abstra
if (BADGER_FISH_CONVENTION.equals(convention)) {
reader = JSONUtils.createBadgerFishReader(is);
} else {
- reader = JSONUtils.createStreamReader(is, readXsiType, namespaceMap);
+ reader = JSONUtils.createStreamReader(is, readXsiType, namespaceMap, getDepthProperties());
}
reader = createTransformReaderIfNeeded(reader, is);
- reader = createDepthReaderIfNeeded(reader, is);
return reader;
}
Modified: cxf/branches/2.5.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JSONUtils.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.5.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JSONUtils.java?rev=1300410&r1=1300409&r2=1300410&view=diff
==============================================================================
--- cxf/branches/2.5.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JSONUtils.java (original)
+++ cxf/branches/2.5.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JSONUtils.java Tue Mar 13 23:35:13 2012
@@ -40,14 +40,21 @@ import javax.xml.stream.XMLStreamWriter;
import org.apache.cxf.common.WSDLConstants;
import org.apache.cxf.common.util.StringUtils;
import org.apache.cxf.staxutils.DelegatingXMLStreamWriter;
+import org.apache.cxf.staxutils.DepthExceededStaxException;
import org.apache.cxf.staxutils.DepthXMLStreamReader;
+import org.apache.cxf.staxutils.DocumentDepthProperties;
import org.apache.cxf.staxutils.transform.IgnoreNamespacesWriter;
+import org.codehaus.jettison.AbstractXMLInputFactory;
import org.codehaus.jettison.AbstractXMLStreamWriter;
import org.codehaus.jettison.badgerfish.BadgerFishXMLInputFactory;
import org.codehaus.jettison.badgerfish.BadgerFishXMLOutputFactory;
+import org.codehaus.jettison.json.JSONException;
+import org.codehaus.jettison.json.JSONObject;
+import org.codehaus.jettison.json.JSONTokener;
import org.codehaus.jettison.mapped.Configuration;
import org.codehaus.jettison.mapped.MappedNamespaceConvention;
import org.codehaus.jettison.mapped.MappedXMLInputFactory;
+import org.codehaus.jettison.mapped.MappedXMLStreamReader;
import org.codehaus.jettison.mapped.MappedXMLStreamWriter;
import org.codehaus.jettison.mapped.TypeConverter;
@@ -134,13 +141,57 @@ public final class JSONUtils {
public static XMLStreamReader createStreamReader(InputStream is, boolean readXsiType,
ConcurrentHashMap<String, String> namespaceMap) throws Exception {
+ return createStreamReader(is, readXsiType, namespaceMap, null);
+ }
+
+ public static XMLStreamReader createStreamReader(InputStream is, boolean readXsiType,
+ ConcurrentHashMap<String, String> namespaceMap,
+ DocumentDepthProperties depthProps) throws Exception {
if (readXsiType) {
namespaceMap.putIfAbsent(XSI_URI, XSI_PREFIX);
}
- MappedXMLInputFactory factory = new MappedXMLInputFactory(namespaceMap);
+ XMLInputFactory factory = depthProps != null
+ ? new JettisonMappedReaderFactory(namespaceMap, depthProps)
+ : new MappedXMLInputFactory(namespaceMap);
return new JettisonReader(namespaceMap, factory.createXMLStreamReader(is));
}
+ private static class JettisonMappedReaderFactory extends AbstractXMLInputFactory {
+ private MappedNamespaceConvention convention;
+ private DocumentDepthProperties depthProps;
+ public JettisonMappedReaderFactory(Map<?, ?> nstojns, DocumentDepthProperties depthProps) {
+ convention = new MappedNamespaceConvention(new Configuration(nstojns));
+ this.depthProps = depthProps;
+ }
+ @Override
+ public XMLStreamReader createXMLStreamReader(JSONTokener tokener) throws XMLStreamException {
+ try {
+ JSONObject root = new JettisonJSONObject(tokener, depthProps);
+ return new MappedXMLStreamReader(root, convention);
+ } catch (JSONException e) {
+ throw new XMLStreamException(e);
+ }
+ }
+ }
+
+ private static class JettisonJSONObject extends JSONObject {
+ private static final long serialVersionUID = 9016458891093343731L;
+ private int threshold;
+ public JettisonJSONObject(JSONTokener tokener, DocumentDepthProperties depthProps)
+ throws JSONException {
+ super(tokener);
+ this.threshold = depthProps.getElementCountThreshold() != -1
+ ? depthProps.getElementCountThreshold() : depthProps.getInnerElementCountThreshold();
+ }
+ @Override
+ public JSONObject put(String key, Object value) throws JSONException {
+ if (threshold != -1 && super.length() >= threshold) {
+ throw new DepthExceededStaxException();
+ }
+ return super.put(key, value);
+ }
+ }
+
private static class JettisonReader extends DepthXMLStreamReader {
private Map<String, String> namespaceMap;
public JettisonReader(Map<String, String> nsMap,