You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cxf.apache.org by GitBox <gi...@apache.org> on 2018/05/10 21:59:20 UTC

[GitHub] reta closed pull request #407: [CXF-7716] Reduce StringBuilders and other performance changes.

reta closed pull request #407: [CXF-7716] Reduce StringBuilders and other performance changes.
URL: https://github.com/apache/cxf/pull/407
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/lifecycle/PerRequestResourceProvider.java b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/lifecycle/PerRequestResourceProvider.java
index 1bc98bd9def..61881fbbf8d 100644
--- a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/lifecycle/PerRequestResourceProvider.java
+++ b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/lifecycle/PerRequestResourceProvider.java
@@ -19,9 +19,11 @@
 
 package org.apache.cxf.jaxrs.lifecycle;
 
+import java.lang.annotation.Annotation;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
+import java.lang.reflect.Type;
 import java.util.Collections;
 import java.util.Map;
 
@@ -45,6 +47,9 @@
     private Constructor<?> c;
     private Method postConstructMethod;
     private Method preDestroyMethod;
+    private final Class<?>[] params;
+    private final Annotation[][] anns;
+    private final Type[] genericTypes;
 
     public PerRequestResourceProvider(Class<?> clazz) {
         c = ResourceUtils.findResourceConstructor(clazz, true);
@@ -52,6 +57,9 @@ public PerRequestResourceProvider(Class<?> clazz) {
             throw new RuntimeException("Resource class " + clazz
                                        + " has no valid constructor");
         }
+        params = c.getParameterTypes();
+        anns = c.getParameterAnnotations();
+        genericTypes = c.getGenericParameterTypes();
         postConstructMethod = ResourceUtils.findPostConstructMethod(clazz);
         preDestroyMethod = ResourceUtils.findPreDestroyMethod(clazz);
     }
@@ -75,7 +83,7 @@ protected Object createInstance(Message m) {
             (ProviderInfo<?>)m.getExchange().getEndpoint().get(Application.class.getName());
         Map<Class<?>, Object> mapValues = CastUtils.cast(application == null ? null
             : Collections.singletonMap(Application.class, application.getProvider()));
-        Object[] values = ResourceUtils.createConstructorArguments(c, m, true, mapValues);
+        Object[] values = ResourceUtils.createConstructorArguments(c, m, true, mapValues, params, anns, genericTypes);
         try {
             Object instance = values.length > 0 ? c.newInstance(values) : c.newInstance(new Object[]{});
             InjectionUtils.invokeLifeCycleMethod(instance, postConstructMethod);
diff --git a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/URITemplate.java b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/URITemplate.java
index 29777a8981b..b5059f3ddca 100644
--- a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/URITemplate.java
+++ b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/URITemplate.java
@@ -130,10 +130,34 @@ public String getPatternValue() {
 
     private static String escapeCharacters(String expression) {
 
-        StringBuilder sb = new StringBuilder();
-        for (int i = 0; i < expression.length(); i++) {
-            char ch = expression.charAt(i);
-            sb.append(isReservedCharacter(ch) ? "\\" + ch : ch);
+        int length = expression.length();
+        int i = 0;
+        char ch = ' ';
+        for (; i < length; ++i) {
+            ch = expression.charAt(i);
+            if (isReservedCharacter(ch)) {
+                break;
+            }
+        }
+
+        if (i == length) {
+            return expression;
+        }
+
+        // Allows for up to 8 escaped characters before we start creating more
+        // StringBuilders. 8 is an arbitrary limit, but it seems to be
+        // sufficient in most cases.
+        StringBuilder sb = new StringBuilder(length + 8);
+        sb.append(expression, 0, i);
+        sb.append('\\');
+        sb.append(ch);
+        ++i;
+        for (; i < length; ++i) {
+            ch = expression.charAt(i);
+            if (isReservedCharacter(ch)) {
+                sb.append('\\');
+            }
+            sb.append(ch);
         }
         return sb.toString();
     }
diff --git a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ProviderFactory.java b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ProviderFactory.java
index e62d3396e1c..03b6a5e64b8 100644
--- a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ProviderFactory.java
+++ b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ProviderFactory.java
@@ -222,7 +222,7 @@ protected static Object createProvider(String className, Bus bus) {
                         if (argCls != null && argCls.isAssignableFrom(contextCls)) {
                             List<MediaType> mTypes = JAXRSUtils.getProduceTypes(
                                  cr.getProvider().getClass().getAnnotation(Produces.class));
-                            if (JAXRSUtils.intersectMimeTypes(mTypes, type).size() > 0) {
+                            if (JAXRSUtils.doMimeTypesIntersect(mTypes, type)) {
                                 injectContextValues(cr, m);
                                 candidates.add((ContextResolver<T>)cr.getProvider());
                             }
@@ -728,10 +728,7 @@ private void sortContextResolvers() {
         MessageBodyReader<?> ep = pi.getProvider();
         List<MediaType> supportedMediaTypes = JAXRSUtils.getProviderConsumeTypes(ep);
 
-        List<MediaType> availableMimeTypes =
-            JAXRSUtils.intersectMimeTypes(Collections.singletonList(mediaType), supportedMediaTypes, false);
-
-        return availableMimeTypes.size() != 0;
+        return JAXRSUtils.doMimeTypesIntersect(Collections.singletonList(mediaType), supportedMediaTypes);
     }
 
     private boolean isReadable(ProviderInfo<MessageBodyReader<?>> pi,
@@ -752,11 +749,7 @@ private boolean isReadable(ProviderInfo<MessageBodyReader<?>> pi,
         MessageBodyWriter<?> ep = pi.getProvider();
         List<MediaType> supportedMediaTypes = JAXRSUtils.getProviderProduceTypes(ep);
 
-        List<MediaType> availableMimeTypes =
-            JAXRSUtils.intersectMimeTypes(Collections.singletonList(mediaType),
-                                          supportedMediaTypes, false);
-
-        return availableMimeTypes.size() != 0;
+        return JAXRSUtils.doMimeTypesIntersect(Collections.singletonList(mediaType), supportedMediaTypes);
     }
 
     private boolean isWriteable(ProviderInfo<MessageBodyWriter<?>> pi,
diff --git a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/AccumulatingIntersector.java b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/AccumulatingIntersector.java
new file mode 100644
index 00000000000..3d2537f46c6
--- /dev/null
+++ b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/AccumulatingIntersector.java
@@ -0,0 +1,74 @@
+/**
+ * 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.utils;
+
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Set;
+
+import javax.ws.rs.core.MediaType;
+
+public class AccumulatingIntersector implements MimeTypesIntersector {
+    private static final String MEDIA_TYPE_DISTANCE_PARAM = "d";
+    private final Set<MediaType> supportedMimeTypeList = new LinkedHashSet<MediaType>();
+    private final boolean addRequiredParamsIfPossible;
+    private final boolean addDistanceParameter;
+
+    AccumulatingIntersector(boolean addRequiredParamsIfPossible, boolean addDistanceParameter) {
+        this.addRequiredParamsIfPossible = addRequiredParamsIfPossible;
+        this.addDistanceParameter = addDistanceParameter;
+    }
+
+    @Override
+    public boolean intersect(MediaType requiredType, MediaType userType) {
+        boolean requiredTypeWildcard = requiredType.getType().equals(MediaType.MEDIA_TYPE_WILDCARD);
+        boolean requiredSubTypeWildcard = requiredType.getSubtype().contains(MediaType.MEDIA_TYPE_WILDCARD);
+
+        String type = requiredTypeWildcard ? userType.getType() : requiredType.getType();
+        String subtype = requiredSubTypeWildcard ? userType.getSubtype() : requiredType.getSubtype();
+
+        Map<String, String> parameters = userType.getParameters();
+        if (addRequiredParamsIfPossible) {
+            parameters = new LinkedHashMap<String, String>(parameters);
+            for (Map.Entry<String, String> entry : requiredType.getParameters().entrySet()) {
+                if (!parameters.containsKey(entry.getKey())) {
+                    parameters.put(entry.getKey(), entry.getValue());
+                }
+            }
+        }
+        if (addDistanceParameter) {
+            int distance = 0;
+            if (requiredTypeWildcard) {
+                distance++;
+            }
+            if (requiredSubTypeWildcard) {
+                distance++;
+            }
+            parameters.put(MEDIA_TYPE_DISTANCE_PARAM, Integer.toString(distance));
+        }
+        getSupportedMimeTypeList().add(new MediaType(type, subtype, parameters));
+        return true;
+    }
+
+    public Set<MediaType> getSupportedMimeTypeList() {
+        return supportedMimeTypeList;
+    }
+}
diff --git a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/HttpUtils.java b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/HttpUtils.java
index 41286c358fb..53a21434fe3 100644
--- a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/HttpUtils.java
+++ b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/HttpUtils.java
@@ -117,24 +117,29 @@ public static String pathDecode(String value) {
 
     private static String componentEncode(String reservedChars, String value) {
 
-        StringBuilder buffer = new StringBuilder();
-        StringBuilder bufferToEncode = new StringBuilder();
-
-        for (int i = 0; i < value.length(); i++) {
+        StringBuilder buffer = null;
+        int length = value.length();
+        int startingIndex = 0;
+        for (int i = 0; i < length; i++) {
             char currentChar = value.charAt(i);
             if (reservedChars.indexOf(currentChar) != -1) {
-                if (bufferToEncode.length() > 0) {
-                    buffer.append(urlEncode(bufferToEncode.toString()));
-                    bufferToEncode.setLength(0);
+                if (buffer == null) {
+                    buffer = new StringBuilder(length + 8);
+                }
+                // If it is going to be an empty string nothing to encode.
+                if (i != startingIndex) {
+                    buffer.append(urlEncode(value.substring(startingIndex, i)));
                 }
                 buffer.append(currentChar);
-            } else {
-                bufferToEncode.append(currentChar);
+                startingIndex = i + 1;
             }
         }
 
-        if (bufferToEncode.length() > 0) {
-            buffer.append(urlEncode(bufferToEncode.toString()));
+        if (buffer == null) {
+            return urlEncode(value);
+        }
+        if (startingIndex < length) {
+            buffer.append(urlEncode(value.substring(startingIndex, length)));
         }
 
         return buffer.toString();
@@ -186,15 +191,21 @@ public static String encodePartiallyEncoded(String encoded, boolean query) {
             return encoded;
         }
         Matcher m = ENCODE_PATTERN.matcher(encoded);
-        StringBuilder sb = new StringBuilder();
+
+        if (!m.find()) {
+            return query ? HttpUtils.queryEncode(encoded) : HttpUtils.pathEncode(encoded);
+        }
+
+        int length = encoded.length();
+        StringBuilder sb = new StringBuilder(length + 8);
         int i = 0;
-        while (m.find()) {
+        do {
             String before = encoded.substring(i, m.start());
             sb.append(query ? HttpUtils.queryEncode(before) : HttpUtils.pathEncode(before));
             sb.append(m.group());
             i = m.end();
-        }
-        String tail = encoded.substring(i, encoded.length());
+        } while (m.find());
+        String tail = encoded.substring(i, length);
         sb.append(query ? HttpUtils.queryEncode(tail) : HttpUtils.pathEncode(tail));
         return sb.toString();
     }
diff --git a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java
index 3094a3eb767..252f4cd06b3 100644
--- a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java
+++ b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java
@@ -35,7 +35,6 @@
 import java.util.Comparator;
 import java.util.HashSet;
 import java.util.LinkedHashMap;
-import java.util.LinkedHashSet;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
@@ -1400,21 +1399,21 @@ public static void writeMessageBody(List<WriterInterceptor> writers,
     public static boolean matchConsumeTypes(MediaType requestContentType,
                                             OperationResourceInfo ori) {
 
-        return !intersectMimeTypes(ori.getConsumeTypes(), requestContentType).isEmpty();
+        return doMimeTypesIntersect(ori.getConsumeTypes(), requestContentType);
     }
 
     public static boolean matchProduceTypes(MediaType acceptContentType,
                                               OperationResourceInfo ori) {
 
-        return !intersectMimeTypes(ori.getProduceTypes(), acceptContentType).isEmpty();
+        return doMimeTypesIntersect(ori.getProduceTypes(), acceptContentType);
     }
 
     public static boolean matchMimeTypes(MediaType requestContentType,
                                          MediaType acceptContentType,
                                          OperationResourceInfo ori) {
 
-        return intersectMimeTypes(ori.getConsumeTypes(), requestContentType).size() != 0
-            && intersectMimeTypes(ori.getProduceTypes(), acceptContentType).size() != 0;
+        return doMimeTypesIntersect(ori.getConsumeTypes(), requestContentType)
+                && doMimeTypesIntersect(ori.getProduceTypes(), acceptContentType);
     }
 
     public static List<MediaType> parseMediaTypes(String types) {
@@ -1439,6 +1438,16 @@ public static boolean matchMimeTypes(MediaType requestContentType,
         return acceptValues;
     }
 
+    public static boolean doMimeTypesIntersect(List<MediaType> mimeTypesA, MediaType mimeTypeB) {
+        return doMimeTypesIntersect(mimeTypesA, Collections.singletonList(mimeTypeB));
+    }
+
+    public static boolean doMimeTypesIntersect(List<MediaType> requiredMediaTypes, List<MediaType> userMediaTypes) {
+        final NonAccumulatingIntersector intersector = new NonAccumulatingIntersector();
+        intersectMimeTypes(requiredMediaTypes, userMediaTypes, intersector);
+        return intersector.doIntersect();
+    }
+
     /**
      * intersect two mime types
      *
@@ -1451,11 +1460,19 @@ public static boolean matchMimeTypes(MediaType requestContentType,
                                                      boolean addRequiredParamsIfPossible) {
         return intersectMimeTypes(requiredMediaTypes, userMediaTypes, addRequiredParamsIfPossible, false);
     }
+
     public static List<MediaType> intersectMimeTypes(List<MediaType> requiredMediaTypes,
                                                      List<MediaType> userMediaTypes,
                                                      boolean addRequiredParamsIfPossible,
                                                      boolean addDistanceParameter) {
-        Set<MediaType> supportedMimeTypeList = new LinkedHashSet<MediaType>();
+        final AccumulatingIntersector intersector = new AccumulatingIntersector(addRequiredParamsIfPossible,
+                addDistanceParameter);
+        intersectMimeTypes(requiredMediaTypes, userMediaTypes, intersector);
+        return new ArrayList<>(intersector.getSupportedMimeTypeList());
+    }
+
+    private static void intersectMimeTypes(List<MediaType> requiredMediaTypes, List<MediaType> userMediaTypes,
+            MimeTypesIntersector intersector) {
 
         for (MediaType requiredType : requiredMediaTypes) {
             for (MediaType userType : userMediaTypes) {
@@ -1464,12 +1481,10 @@ public static boolean matchMimeTypes(MediaType requestContentType,
                     boolean parametersMatched = true;
                     for (Map.Entry<String, String> entry : userType.getParameters().entrySet()) {
                         String value = requiredType.getParameters().get(entry.getKey());
-                        if (value != null && entry.getValue() != null
-                            && !(stripDoubleQuotesIfNeeded(value).equals(
-                                    stripDoubleQuotesIfNeeded(entry.getValue())))) {
-                            
-                            if (HTTP_CHARSET_PARAM.equals(entry.getKey())
-                                && value.equalsIgnoreCase(entry.getValue())) {
+                        if (value != null && entry.getValue() != null && !(stripDoubleQuotesIfNeeded(value)
+                                .equals(stripDoubleQuotesIfNeeded(entry.getValue())))) {
+
+                            if (HTTP_CHARSET_PARAM.equals(entry.getKey()) && value.equalsIgnoreCase(entry.getValue())) {
                                 continue;
                             }
                             parametersMatched = false;
@@ -1479,40 +1494,15 @@ public static boolean matchMimeTypes(MediaType requestContentType,
                     if (!parametersMatched) {
                         continue;
                     }
-                    boolean requiredTypeWildcard = requiredType.getType().equals(MediaType.MEDIA_TYPE_WILDCARD);
-                    boolean requiredSubTypeWildcard = requiredType.getSubtype().contains(MediaType.MEDIA_TYPE_WILDCARD);
-
-                    String type = requiredTypeWildcard ? userType.getType() : requiredType.getType();
-                    String subtype = requiredSubTypeWildcard ? userType.getSubtype() : requiredType.getSubtype();
-
-                    Map<String, String> parameters = userType.getParameters();
-                    if (addRequiredParamsIfPossible) {
-                        parameters = new LinkedHashMap<String, String>(parameters);
-                        for (Map.Entry<String, String> entry : requiredType.getParameters().entrySet()) {
-                            if (!parameters.containsKey(entry.getKey())) {
-                                parameters.put(entry.getKey(), entry.getValue());
-                            }
-                        }
-                    }
-                    if (addDistanceParameter) {
-                        int distance = 0;
-                        if (requiredTypeWildcard) {
-                            distance++;
-                        }
-                        if (requiredSubTypeWildcard) {
-                            distance++;
-                        }
-                        parameters.put(MEDIA_TYPE_DISTANCE_PARAM, Integer.toString(distance));
+
+                    if (!intersector.intersect(requiredType, userType)) {
+                        return;
                     }
-                    supportedMimeTypeList.add(new MediaType(type, subtype, parameters));
                 }
             }
         }
-
-        return new ArrayList<>(supportedMimeTypeList);
-
     }
-    
+
     private static String stripDoubleQuotesIfNeeded(String value) {
         if (value != null && value.startsWith("\"") 
             && value.endsWith("\"") && value.length() > 1) {
diff --git a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/MimeTypesIntersector.java b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/MimeTypesIntersector.java
new file mode 100644
index 00000000000..3dd3e47be76
--- /dev/null
+++ b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/MimeTypesIntersector.java
@@ -0,0 +1,26 @@
+/**
+ * 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.utils;
+
+import javax.ws.rs.core.MediaType;
+
+public interface MimeTypesIntersector {
+    boolean intersect(MediaType requiredType, MediaType userType);
+}
diff --git a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/NonAccumulatingIntersector.java b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/NonAccumulatingIntersector.java
new file mode 100644
index 00000000000..7f6661e6c39
--- /dev/null
+++ b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/NonAccumulatingIntersector.java
@@ -0,0 +1,36 @@
+/**
+ * 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.utils;
+
+import javax.ws.rs.core.MediaType;
+
+public class NonAccumulatingIntersector implements MimeTypesIntersector {
+    private boolean doIntersect;
+
+    @Override
+    public boolean intersect(MediaType requiredType, MediaType userType) {
+        doIntersect = true;
+        return false;
+    }
+
+    public boolean doIntersect() {
+        return doIntersect;
+    }
+}
diff --git a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/ResourceUtils.java b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/ResourceUtils.java
index 39d97696a54..1b32e855f25 100644
--- a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/ResourceUtils.java
+++ b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/ResourceUtils.java
@@ -816,12 +816,23 @@ private static UserOperation getOperationFromElement(Element e) {
                                                       Message m,
                                                       boolean perRequest,
                                                       Map<Class<?>, Object> contextValues) {
-        if (m == null) {
-            m = new MessageImpl();
-        }
         Class<?>[] params = c.getParameterTypes();
         Annotation[][] anns = c.getParameterAnnotations();
         Type[] genericTypes = c.getGenericParameterTypes();
+        return createConstructorArguments(c, m, perRequest, contextValues, params, anns, genericTypes);
+    }
+
+    public static Object[] createConstructorArguments(Constructor<?> c,
+                                                      Message m,
+                                                      boolean perRequest,
+                                                      Map<Class<?>,
+                                                      Object> contextValues,
+                                                      Class<?>[] params,
+                                                      Annotation[][] anns,
+                                                      Type[] genericTypes) {
+        if (m == null) {
+            m = new MessageImpl();
+        }
         @SuppressWarnings("unchecked")
         MultivaluedMap<String, String> templateValues =
             (MultivaluedMap<String, String>)m.get(URITemplate.TEMPLATE_PARAMETERS);


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services