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");