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 2013/04/26 13:31:35 UTC
svn commit: r1476142 - in /cxf/trunk:
rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/
rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/impl/
systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/
Author: sergeyb
Date: Fri Apr 26 11:31:28 2013
New Revision: 1476142
URL: http://svn.apache.org/r1476142
Log:
[CXF-4986] Fixing MetadataMap to enforce the read only for stores which are not copied and all 2.0 filter contexts to set a proper flag on it; using HttpServletRequest to save the filter properties if possible
Added:
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/PropertyHolderFactory.java (with props)
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/ServletRequestPropertyHolder.java (with props)
Modified:
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/AbstractPropertiesImpl.java
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/ContainerRequestContextImpl.java
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/MetadataMap.java
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/ReaderInterceptorContextImpl.java
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/WriterInterceptorContextImpl.java
cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/impl/MetadataMapTest.java
cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookServer20.java
Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/AbstractPropertiesImpl.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/AbstractPropertiesImpl.java?rev=1476142&r1=1476141&r2=1476142&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/AbstractPropertiesImpl.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/AbstractPropertiesImpl.java Fri Apr 26 11:31:28 2013
@@ -19,46 +19,32 @@
package org.apache.cxf.jaxrs.impl;
import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-import org.apache.cxf.helpers.CastUtils;
+import org.apache.cxf.jaxrs.impl.PropertyHolderFactory.PropertyHolder;
import org.apache.cxf.message.Message;
public abstract class AbstractPropertiesImpl {
-
- private static final String PROPERTY_KEY = "jaxrs.filter.properties";
-
protected Message m;
- private Map<String, Object> props;
+ private PropertyHolder holder;
public AbstractPropertiesImpl(Message message) {
+ holder = PropertyHolderFactory.getPropertyHolder(message);
this.m = message;
- this.props = CastUtils.cast((Map<?, ?>)message.get(PROPERTY_KEY));
}
public Object getProperty(String name) {
- return props == null ? null : props.get(name);
+ return holder.getProperty(name);
}
public void removeProperty(String name) {
- if (props != null) {
- props.remove(name);
- }
+ holder.removeProperty(name);
}
public void setProperty(String name, Object value) {
- if (props == null) {
- props = new HashMap<String, Object>();
- m.put(PROPERTY_KEY, props);
- }
- props.put(name, value);
-
+ holder.setProperty(name, value);
}
public Collection<String> getPropertyNames() {
- return props == null ? Collections.<String>emptyList()
- : Collections.unmodifiableSet(props.keySet());
+ return holder.getPropertyNames();
}
}
Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/ContainerRequestContextImpl.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/ContainerRequestContextImpl.java?rev=1476142&r1=1476141&r2=1476142&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/ContainerRequestContextImpl.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/ContainerRequestContextImpl.java Fri Apr 26 11:31:28 2013
@@ -79,7 +79,7 @@ public class ContainerRequestContextImpl
public MultivaluedMap<String, String> getHeaders() {
h = null;
return new MetadataMap<String, String>(
- (Map<String, List<String>>)m.get(Message.PROTOCOL_HEADERS), false, true, true);
+ (Map<String, List<String>>)m.get(Message.PROTOCOL_HEADERS), false, false, true);
}
Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/MetadataMap.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/MetadataMap.java?rev=1476142&r1=1476141&r2=1476142&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/MetadataMap.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/MetadataMap.java Fri Apr 26 11:31:28 2013
@@ -35,6 +35,7 @@ import javax.ws.rs.core.MultivaluedMap;
public class MetadataMap<K, V> implements MultivaluedMap<K, V> {
private boolean caseInsensitive;
+ private boolean readOnly;
private Map<K, List<V>> m;
public MetadataMap() {
@@ -62,8 +63,7 @@ public class MetadataMap<K, V> implement
this (store, true, readOnly, caseInsensitive);
}
- // TODO: Review the use of this constructor,
- // refactor the code, copyStore and readOnly are duplicates
+
public MetadataMap(Map<K, List<V>> store, boolean copyStore,
boolean readOnly, boolean caseInsensitive) {
@@ -72,17 +72,17 @@ public class MetadataMap<K, V> implement
if (store != null) {
for (Map.Entry<K, List<V>> entry : store.entrySet()) {
List<V> values = new ArrayList<V>(entry.getValue());
- m.put(entry.getKey(), readOnly
- ? Collections.unmodifiableList(values) : values);
+ m.put(entry.getKey(), values);
}
}
- if (readOnly) {
- this.m = Collections.unmodifiableMap(m);
- }
} else {
this.m = store;
}
+ if (readOnly) {
+ this.m = Collections.unmodifiableMap(m);
+ }
this.caseInsensitive = caseInsensitive;
+ this.readOnly = readOnly;
}
@@ -105,7 +105,7 @@ public class MetadataMap<K, V> implement
data = new ArrayList<V>();
m.put(key, data);
}
- return data;
+ return readOnly ? Collections.unmodifiableList(data) : data;
}
public V getFirst(K key) {
Added: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/PropertyHolderFactory.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/PropertyHolderFactory.java?rev=1476142&view=auto
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/PropertyHolderFactory.java (added)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/PropertyHolderFactory.java Fri Apr 26 11:31:28 2013
@@ -0,0 +1,83 @@
+/**
+ * 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.jaxrs.impl;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.cxf.helpers.CastUtils;
+import org.apache.cxf.message.Message;
+
+public final class PropertyHolderFactory {
+ private PropertyHolderFactory() {
+
+ }
+
+ public static PropertyHolder getPropertyHolder(Message m) {
+ return m.containsKey("HTTP.REQUEST") ? new ServletRequestPropertyHolder(m) : new MessagePropertyHolder(m);
+ }
+
+ public interface PropertyHolder {
+ Object getProperty(String name);
+ void removeProperty(String name);
+ void setProperty(String name, Object value);
+ Collection<String> getPropertyNames();
+ }
+
+ private static class MessagePropertyHolder implements PropertyHolder {
+ private static final String PROPERTY_KEY = "jaxrs.filter.properties";
+ private Message m;
+ private Map<String, Object> props;
+
+ public MessagePropertyHolder(Message m) {
+ this.m = m;
+ this.props = CastUtils.cast((Map<?, ?>)m.get(PROPERTY_KEY));
+ }
+ public Object getProperty(String name) {
+ return props == null ? null : props.get(name);
+ }
+
+ public void removeProperty(String name) {
+ if (props != null) {
+ props.remove(name);
+ }
+ }
+
+
+ public void setProperty(String name, Object value) {
+ if (props == null) {
+ props = new HashMap<String, Object>();
+ m.put(PROPERTY_KEY, props);
+ }
+ if (value == null) {
+ removeProperty(name);
+ } else {
+ props.put(name, value);
+ }
+
+ }
+
+ public Collection<String> getPropertyNames() {
+ return props == null ? Collections.<String>emptyList()
+ : Collections.unmodifiableSet(props.keySet());
+ }
+ }
+}
Propchange: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/PropertyHolderFactory.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/PropertyHolderFactory.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/ReaderInterceptorContextImpl.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/ReaderInterceptorContextImpl.java?rev=1476142&r1=1476141&r2=1476142&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/ReaderInterceptorContextImpl.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/ReaderInterceptorContextImpl.java Fri Apr 26 11:31:28 2013
@@ -53,7 +53,7 @@ public class ReaderInterceptorContextImp
@Override
public MultivaluedMap<String, String> getHeaders() {
return new MetadataMap<String, String>(
- (Map<String, List<String>>)m.get(Message.PROTOCOL_HEADERS), false, true, true);
+ (Map<String, List<String>>)m.get(Message.PROTOCOL_HEADERS), false, false, true);
}
@Override
Added: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/ServletRequestPropertyHolder.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/ServletRequestPropertyHolder.java?rev=1476142&view=auto
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/ServletRequestPropertyHolder.java (added)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/ServletRequestPropertyHolder.java Fri Apr 26 11:31:28 2013
@@ -0,0 +1,70 @@
+/**
+ * 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.jaxrs.impl;
+
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.LinkedList;
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.cxf.jaxrs.impl.PropertyHolderFactory.PropertyHolder;
+import org.apache.cxf.message.Message;
+
+public class ServletRequestPropertyHolder implements PropertyHolder {
+ private static final String ENDPOINT_ADDRESS_PROPERTY = "org.apache.cxf.transport.endpoint.address";
+ private HttpServletRequest request;
+ public ServletRequestPropertyHolder(Message m) {
+ request = (HttpServletRequest)m.get("HTTP.REQUEST");
+ }
+
+ @Override
+ public Object getProperty(String name) {
+ return request.getAttribute(name);
+ }
+
+ @Override
+ public void removeProperty(String name) {
+ request.removeAttribute(name);
+ }
+
+ @Override
+ public void setProperty(String name, Object value) {
+ if (value == null) {
+ removeProperty(name);
+ } else {
+ request.setAttribute(name, value);
+ }
+ }
+
+ @Override
+ public Collection<String> getPropertyNames() {
+ List<String> list = new LinkedList<String>();
+ Enumeration<String> attrNames = request.getAttributeNames();
+ while (attrNames.hasMoreElements()) {
+ String name = attrNames.nextElement();
+ if (!ENDPOINT_ADDRESS_PROPERTY.equals(name)) {
+ list.add(name);
+ }
+ }
+ return list;
+ }
+
+}
Propchange: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/ServletRequestPropertyHolder.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/ServletRequestPropertyHolder.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/WriterInterceptorContextImpl.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/WriterInterceptorContextImpl.java?rev=1476142&r1=1476141&r2=1476142&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/WriterInterceptorContextImpl.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/WriterInterceptorContextImpl.java Fri Apr 26 11:31:28 2013
@@ -64,7 +64,7 @@ public class WriterInterceptorContextImp
@Override
public MultivaluedMap<String, Object> getHeaders() {
return new MetadataMap<String, Object>(
- (Map<String, List<Object>>)m.get(Message.PROTOCOL_HEADERS), false, true, true);
+ (Map<String, List<Object>>)m.get(Message.PROTOCOL_HEADERS), false, false, true);
}
@Override
Modified: cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/impl/MetadataMapTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/impl/MetadataMapTest.java?rev=1476142&r1=1476141&r2=1476142&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/impl/MetadataMapTest.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/impl/MetadataMapTest.java Fri Apr 26 11:31:28 2013
@@ -21,7 +21,12 @@ package org.apache.cxf.jaxrs.impl;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedList;
import java.util.List;
+import java.util.Map;
+
+import javax.ws.rs.core.MultivaluedMap;
import org.junit.Assert;
import org.junit.Test;
@@ -210,13 +215,59 @@ public class MetadataMapTest extends Ass
}
@Test(expected = UnsupportedOperationException.class)
- public void testReadOnly() {
+ public void testReadOnlyRemove() {
MetadataMap<String, Object> m = new MetadataMap<String, Object>();
m.add("baz", "bar");
MetadataMap<String, Object> m2 = new MetadataMap<String, Object>(m, true, false);
m2.remove("baz");
}
+ @Test(expected = UnsupportedOperationException.class)
+ public void testReadOnlyAdd() {
+ MetadataMap<String, Object> m = new MetadataMap<String, Object>();
+ m.add("baz", "bar");
+ MetadataMap<String, Object> m2 = new MetadataMap<String, Object>(m, true, false);
+ m2.add("bar", "foo");
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void testReadOnlyAddFirst() {
+ MetadataMap<String, Object> m = new MetadataMap<String, Object>();
+ m.add("baz", "bar");
+ MetadataMap<String, Object> m2 = new MetadataMap<String, Object>(m, true, false);
+ m2.addFirst("baz", "bar2");
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void testReadOnlyAdd2() {
+ Map<String, List<String>> values = new HashMap<String, List<String>>();
+ List<String> list = new LinkedList<String>();
+ list.add("bar");
+ values.put("baz", list);
+ MultivaluedMap<String, String> map =
+ new MetadataMap<String, String>(values, false, true, true);
+ map.add("baz", "baz");
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void testReadOnlyAddFirst2() {
+ Map<String, List<String>> values = new HashMap<String, List<String>>();
+ List<String> list = new LinkedList<String>();
+ list.add("bar");
+ values.put("baz", list);
+ MultivaluedMap<String, String> map =
+ new MetadataMap<String, String>(values, false, true, true);
+ map.addFirst("baz", "bar2");
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void testReadOnlyPutSingle() {
+ Map<String, List<String>> values = new HashMap<String, List<String>>();
+ MultivaluedMap<String, String> map =
+ new MetadataMap<String, String>(values, false, true, true);
+ map.putSingle("baz", "baz");
+ }
+
@Test
public void testGetCaseInsensitive() {
MetadataMap<String, Object> m = new MetadataMap<String, Object>();
Modified: cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookServer20.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookServer20.java?rev=1476142&r1=1476141&r2=1476142&view=diff
==============================================================================
--- cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookServer20.java (original)
+++ cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookServer20.java Fri Apr 26 11:31:28 2013
@@ -33,6 +33,7 @@ import java.util.ArrayList;
import java.util.List;
import javax.annotation.Priority;
+import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.InternalServerErrorException;
import javax.ws.rs.NameBinding;
import javax.ws.rs.WebApplicationException;
@@ -140,11 +141,14 @@ public class BookServer20 extends Abstra
@PreMatching
@Priority(3)
private static class PreMatchContainerRequestFilter2 implements ContainerRequestFilter {
-
+ @Context
+ private HttpServletRequest servletRequest;
@Override
public void filter(ContainerRequestContext context) throws IOException {
if (!"true".equals(context.getProperty("FirstPrematchingFilter"))
- || !"true".equals(context.getProperty("DynamicPrematchingFilter"))) {
+ || !"true".equals(context.getProperty("DynamicPrematchingFilter"))
+ || !"true".equals(servletRequest.getAttribute("FirstPrematchingFilter"))
+ || !"true".equals(servletRequest.getAttribute("DynamicPrematchingFilter"))) {
throw new RuntimeException();
}
context.getHeaders().add("BOOK", "12");