Author: sergeyb
Date: Thu Jan 29 17:45:43 2009
New Revision: 738937
URL: http://svn.apache.org/viewvc?rev=738937&view=rev
Log:
CXF-1991: applying a 2nd quality patch on behalf of Andrzej Michalec plus fix
for UriInfo.getMatchedURIs and ExceptionMapper injection issue
Modified:
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/JAXRSInvoker.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/UriBuilderImpl.java
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/UriInfoImpl.java
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/JAXRSInInterceptor.java
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/MethodInvocationInfo.java
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/URITemplate.java
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java
cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/impl/UriBuilderImplTest.java
cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/model/URITemplateTest.java
cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java
Modified:
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/JAXRSInvoker.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/JAXRSInvoker.java?rev=738937&r1=738936&r2=738937&view=diff
==============================================================================
---
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/JAXRSInvoker.java
(original)
+++
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/JAXRSInvoker.java
Thu Jan 29 17:45:43 2009
@@ -22,7 +22,9 @@
import java.lang.reflect.Method;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
+import java.util.Map;
import java.util.ResourceBundle;
import java.util.logging.Logger;
@@ -116,7 +118,9 @@
try {
result = invoke(exchange, resourceObject, methodToInvoke, params);
} catch (Fault ex) {
- Response excResponse =
JAXRSUtils.convertFaultToResponse(ex.getCause(), baseAddress);
+ Response excResponse =
JAXRSUtils.convertFaultToResponse(ex.getCause(),
+
baseAddress,
+
exchange.getInMessage());
if (excResponse == null) {
ProviderFactory.getInstance(baseAddress).clearThreadLocalProxies();
ClassResourceInfo criRoot =
@@ -180,7 +184,9 @@
return this.invoke(exchange, newParams, newResourceObjects);
} catch (WebApplicationException ex) {
- Response excResponse = JAXRSUtils.convertFaultToResponse(ex,
baseAddress);
+ Response excResponse = JAXRSUtils.convertFaultToResponse(ex,
+
baseAddress,
+
exchange.getInMessage());
return new MessageContentsList(excResponse);
}
}
@@ -236,12 +242,29 @@
return result;
}
+ @SuppressWarnings("unchecked")
private void pushOntoStack(OperationResourceInfo ori, Class<?> realClass,
Message msg) {
OperationResourceInfoStack stack =
msg.get(OperationResourceInfoStack.class);
if (stack == null) {
stack = new OperationResourceInfoStack();
msg.put(OperationResourceInfoStack.class, stack);
}
- stack.push(new MethodInvocationInfo(ori, realClass));
+
+
+ MultivaluedMap<String, String> params =
+ (MultivaluedMap)msg.get(URITemplate.TEMPLATE_PARAMETERS);
+ List<String> values = null;
+ if (params == null || params.size() == 1) {
+ values = Collections.emptyList();
+ } else {
+ values = new ArrayList<String>(params.size() - 1);
+ // if we have {bar}/{foo}/{bar} then we have a problem
+ for (Map.Entry<String, List<String>> entry : params.entrySet()) {
+ if (!entry.getKey().equals(URITemplate.FINAL_MATCH_GROUP)) {
+ values.addAll(entry.getValue());
+ }
+ }
+ }
+ stack.push(new MethodInvocationInfo(ori, realClass, values));
}
}
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=738937&r1=738936&r2=738937&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
Thu Jan 29 17:45:43 2009
@@ -21,7 +21,7 @@
import java.util.ArrayList;
import java.util.Collection;
-import java.util.HashMap;
+import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -33,7 +33,7 @@
private Map<K, List<V>> m;
public MetadataMap() {
- this(new HashMap<K, List<V>>());
+ this(new LinkedHashMap<K, List<V>>());
}
public MetadataMap(Map<K, List<V>> store) {
Modified:
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/UriBuilderImpl.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/UriBuilderImpl.java?rev=738937&r1=738936&r2=738937&view=diff
==============================================================================
---
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/UriBuilderImpl.java
(original)
+++
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/UriBuilderImpl.java
Thu Jan 29 17:45:43 2009
@@ -24,9 +24,15 @@
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
import java.util.Iterator;
+import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import javax.ws.rs.Path;
import javax.ws.rs.core.MultivaluedMap;
@@ -34,10 +40,13 @@
import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.UriBuilderException;
+import org.apache.cxf.jaxrs.model.URITemplate;
import org.apache.cxf.jaxrs.utils.JAXRSUtils;
public class UriBuilderImpl extends UriBuilder {
+ private static final Pattern DECODE_PATTERN =
Pattern.compile("%[0-9a-fA-F][0-9a-fA-F]");
+
private String scheme;
private String userInfo;
private int port;
@@ -46,22 +55,96 @@
private String fragment;
private MultivaluedMap<String, String> query = new MetadataMap<String,
String>();
+ /**
+ * Creates builder with empty URI.
+ */
public UriBuilderImpl() {
}
- public UriBuilderImpl(URI uri) {
+ /**
+ * Creates builder initialized with given URI.
+ *
+ * @param uri initial value for builder
+ * @throws IllegalArgumentException when uri is null
+ */
+ public UriBuilderImpl(URI uri) throws IllegalArgumentException {
setUriParts(uri);
}
@Override
public URI build(Object... values) throws IllegalArgumentException,
UriBuilderException {
try {
- return new URI(scheme, userInfo, host, port, buildPath(),
buildQuery(), fragment);
+ String path = buildPath();
+ path = substituteVarargs(path, values);
+ return new URI(scheme, userInfo, host, port, path, buildQuery(),
fragment);
+ } catch (URISyntaxException ex) {
+ throw new UriBuilderException("URI can not be built", ex);
+ }
+ }
+
+ private String substituteVarargs(String path, Object... values) {
+ Map<String, String> varValueMap = new HashMap<String, String>();
+ URITemplate templ = new URITemplate(path);
+ // vars in set are properly ordered due to linking in hash set
+ Set<String> uniqueVars = new
LinkedHashSet<String>(templ.getVariables());
+ if (values.length < uniqueVars.size()) {
+ throw new IllegalArgumentException("Unresolved variables; only " +
values.length
+ + " value(s) given for " +
uniqueVars.size()
+ + " unique variable(s)");
+ }
+ int idx = 0;
+ for (String var : uniqueVars) {
+ Object oval = values[idx++];
+ varValueMap.put(var, oval.toString());
+ }
+ return templ.substitute(varValueMap);
+ }
+
+ @Override
+ public URI buildFromEncoded(Object... values) throws
IllegalArgumentException, UriBuilderException {
+ // Problem: multi-arg URI c-tor always forces encoding, operation
contract would be broken;
+ // use os single-arg URI c-tor requires unnecessary concatenate-parse
roundtrip.
+ // Solution: decode back given values and pass as non-decoded to
regular build() method
+ for (int i = 0; i < values.length; i++) {
+ values[i] = decodePartiallyEncoded(values[i].toString());
+ }
+ return build(values);
+ }
+
+ @Override
+ public URI buildFromMap(Map<String, ? extends Object> map) throws
IllegalArgumentException,
+ UriBuilderException {
+ try {
+ String path = buildPath();
+ path = substituteMapped(path, map);
+ return new URI(scheme, userInfo, host, port, path, buildQuery(),
fragment);
} catch (URISyntaxException ex) {
throw new UriBuilderException("URI can not be built", ex);
}
}
+ private String substituteMapped(String path, Map<String, ? extends Object>
varValueMap) {
+ URITemplate templ = new URITemplate(path);
+ Set<String> uniqueVars = new HashSet<String>(templ.getVariables());
+ if (varValueMap.size() < uniqueVars.size()) {
+ throw new IllegalArgumentException("Unresolved variables; only " +
varValueMap.size()
+ + " value(s) given for " +
uniqueVars.size()
+ + " unique variable(s)");
+ }
+ return templ.substitute(varValueMap);
+ }
+
+ @Override
+ public URI buildFromEncodedMap(Map<String, ? extends Object> map) throws
IllegalArgumentException,
+ UriBuilderException {
+ // see buildFromEncoded() comment
+ Map<String, String> decodedMap = new HashMap<String,
String>(map.size());
+ for (Map.Entry<String, ? extends Object> entry : map.entrySet()) {
+ decodedMap.put(entry.getKey(),
decodePartiallyEncoded(entry.getValue().toString()));
+ }
+ return buildFromMap(decodedMap);
+ }
+
// CHECKSTYLE:OFF
@Override
public UriBuilder clone() {
@@ -96,6 +179,7 @@
return path(((Path)ann).value());
}
+ @SuppressWarnings("unchecked")
@Override
public UriBuilder path(Class resource, String method) throws
IllegalArgumentException {
if (resource == null) {
@@ -186,6 +270,9 @@
}
private void setUriParts(URI uri) {
+ if (uri == null) {
+ throw new IllegalArgumentException("uri is null");
+ }
scheme = uri.getScheme();
port = uri.getPort();
host = uri.getHost();
@@ -197,15 +284,17 @@
private String buildPath() {
StringBuilder sb = new StringBuilder();
- for (PathSegment ps : paths) {
- String p = ps.getPath();
- if (!p.startsWith("/") && (sb.length() == 0 ||
sb.charAt(sb.length() - 1) != '/')) {
- sb.append('/');
+ Iterator<PathSegment> iter = paths.iterator();
+ while (iter.hasNext()) {
+ String p = iter.next().getPath();
+ if (p.length() != 0 || !iter.hasNext()) {
+ if (!p.startsWith("/")) {
+ sb.append('/');
+ }
+ sb.append(p);
}
- sb.append(p);
}
return sb.toString();
-
}
private String buildQuery() {
@@ -221,29 +310,6 @@
}
@Override
- public URI buildFromEncoded(Object... values) throws
IllegalArgumentException, UriBuilderException {
- try {
- return new URI(scheme, userInfo, host, port, buildPath(),
buildQuery(), fragment);
- } catch (URISyntaxException ex) {
- throw new UriBuilderException("URI can not be built", ex);
- }
- }
-
- @Override
- public URI buildFromEncodedMap(Map<String, ? extends Object> arg0) throws
IllegalArgumentException,
- UriBuilderException {
- // TODO Auto-generated method stub
- throw new UnsupportedOperationException("Not implemented :/");
- }
-
- @Override
- public URI buildFromMap(Map<String, ? extends Object> arg0) throws
IllegalArgumentException,
- UriBuilderException {
- // TODO Auto-generated method stub
- throw new UnsupportedOperationException("Not implemented :/");
- }
-
- @Override
public UriBuilder matrixParam(String name, Object... values) throws
IllegalArgumentException {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Not implemented :/");
@@ -297,4 +363,21 @@
throw new UnsupportedOperationException("Not implemented :/");
}
+ /**
+ * Decode partially encoded string. Decode only values that matches patter
"percent char followed by two
+ * hexadecimal digits".
+ *
+ * @param encoded fully or partially encoded string.
+ * @return decoded string
+ */
+ private String decodePartiallyEncoded(String encoded) {
+ Matcher m = DECODE_PATTERN.matcher(encoded);
+ StringBuffer sb = new StringBuffer();
+ while (m.find()) {
+ String found = m.group();
+ m.appendReplacement(sb, JAXRSUtils.uriDecode(found));
+ }
+ m.appendTail(sb);
+ return sb.toString();
+ }
}
Modified:
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/UriInfoImpl.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/UriInfoImpl.java?rev=738937&r1=738936&r2=738937&view=diff
==============================================================================
---
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/UriInfoImpl.java
(original)
+++
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/UriInfoImpl.java
Thu Jan 29 17:45:43 2009
@@ -146,6 +146,7 @@
public List<String> getMatchedURIs(boolean decode) {
if (stack != null) {
+ List<String> objects = new ArrayList<String>();
List<String> uris = new ArrayList<String>(stack.size());
String sum = "";
for (MethodInvocationInfo invocation : stack) {
@@ -162,7 +163,8 @@
}
}
UriBuilder ub = UriBuilder.fromPath(sum);
- uris.add(ub.build().normalize().getPath());
+ objects.addAll(invocation.getTemplateValues());
+ uris.add(ub.build(objects.toArray()).normalize().getPath());
}
return uris;
}
Modified:
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/JAXRSInInterceptor.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/JAXRSInInterceptor.java?rev=738937&r1=738936&r2=738937&view=diff
==============================================================================
---
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/JAXRSInInterceptor.java
(original)
+++
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/JAXRSInInterceptor.java
Thu Jan 29 17:45:43 2009
@@ -67,7 +67,7 @@
try {
processRequest(message, originalAddress);
} catch (RuntimeException ex) {
- Response excResponse = JAXRSUtils.convertFaultToResponse(ex,
originalAddress);
+ Response excResponse = JAXRSUtils.convertFaultToResponse(ex,
originalAddress, message);
if (excResponse == null) {
ProviderFactory.getInstance(originalAddress).clearThreadLocalProxies();
throw ex;
Modified:
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/MethodInvocationInfo.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/MethodInvocationInfo.java?rev=738937&r1=738936&r2=738937&view=diff
==============================================================================
---
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/MethodInvocationInfo.java
(original)
+++
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/MethodInvocationInfo.java
Thu Jan 29 17:45:43 2009
@@ -18,17 +18,23 @@
*/
package org.apache.cxf.jaxrs.model;
+import java.util.Collections;
+import java.util.List;
+
/**
- * A pair of {...@link OperationResourceInfo} representing a resource method
being invoked
- * and actual {...@link Class} of the object this method is invoked upon.
+ * A triple of {...@link OperationResourceInfo} representing a resource method
being invoked,
+ * actual {...@link Class} of the object this method is invoked upon, and a
list of template variable values
+ * matched during the selection of this method
*/
public class MethodInvocationInfo {
private OperationResourceInfo ori;
private Class<?> realClass;
+ private List<String> templateValues;
- public MethodInvocationInfo(OperationResourceInfo ori, Class<?> realClass)
{
+ public MethodInvocationInfo(OperationResourceInfo ori, Class<?> realClass,
List<String> templateValues) {
this.ori = ori;
this.realClass = realClass;
+ this.templateValues = Collections.unmodifiableList(templateValues);
}
public OperationResourceInfo getMethodInfo() {
@@ -38,4 +44,8 @@
public Class<?> getRealClass() {
return realClass;
}
+
+ public List<String> getTemplateValues() {
+ return templateValues;
+ }
}
Modified:
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/URITemplate.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/URITemplate.java?rev=738937&r1=738936&r2=738937&view=diff
==============================================================================
---
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/URITemplate.java
(original)
+++
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/URITemplate.java
Thu Jan 29 17:45:43 2009
@@ -19,9 +19,11 @@
package org.apache.cxf.jaxrs.model;
-
import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
import java.util.List;
+import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -33,40 +35,38 @@
import org.apache.cxf.jaxrs.utils.JAXRSUtils;
public final class URITemplate {
-
+
public static final String TEMPLATE_PARAMETERS =
"jaxrs.template.parameters";
public static final String LIMITED_REGEX_SUFFIX = "(/.*)?";
public static final String FINAL_MATCH_GROUP = "FINAL_MATCH_GROUP";
-
+
/**
* The regular expression for matching URI templates and names.
*/
- private static final Pattern TEMPLATE_NAMES_PATTERN =
- Pattern.compile("\\{(\\w[-\\w\\.]*)(\\:(.+?))?\\}");
+ private static final Pattern TEMPLATE_NAMES_PATTERN =
Pattern.compile("\\{(\\w[-\\w\\.]*)(\\:(.+?))?\\}");
private static final String DEFAULT_PATH_VARIABLE_REGEX = "([^/]+?)";
private static final String CHARACTERS_TO_ESCAPE = ".";
-
+
private final String template;
private final List<String> templateVariables = new ArrayList<String>();
private final List<String> customTemplateVariables = new
ArrayList<String>();
private final Pattern templateRegexPattern;
private final String literals;
-
public URITemplate(String theTemplate) {
-
+
this.template = theTemplate;
-
+
StringBuilder literalChars = new StringBuilder();
StringBuilder patternBuilder = new StringBuilder();
-
+
// compute a regular expression from URI template
Matcher matcher = TEMPLATE_NAMES_PATTERN.matcher(template);
int i = 0;
while (matcher.find()) {
templateVariables.add(matcher.group(1).trim());
-
+
String substr = escapeCharacters(template.substring(i,
matcher.start()));
literalChars.append(substr);
patternBuilder.append(substr);
@@ -78,42 +78,42 @@
customTemplateVariables.add(matcher.group(1).trim());
} else {
patternBuilder.append(DEFAULT_PATH_VARIABLE_REGEX);
- }
+ }
}
String substr = escapeCharacters(template.substring(i,
template.length()));
literalChars.append(substr);
patternBuilder.append(substr);
literals = literalChars.toString();
-
+
int endPos = patternBuilder.length() - 1;
boolean endsWithSlash = (endPos >= 0) ? patternBuilder.charAt(endPos)
== '/' : false;
if (endsWithSlash) {
patternBuilder.deleteCharAt(endPos);
}
patternBuilder.append(LIMITED_REGEX_SUFFIX);
-
+
templateRegexPattern = Pattern.compile(patternBuilder.toString());
}
public String getLiteralChars() {
return literals;
}
-
+
public String getValue() {
return template;
}
-
- public int getNumberOfGroups() {
- return templateVariables.size();
- }
-
- public int getNumberOfGroupsWithCustomExpression() {
- return customTemplateVariables.size();
+
+ public List<String> getVariables() {
+ return Collections.unmodifiableList(templateVariables);
+ }
+
+ public List<String> getCustomVariables() {
+ return Collections.unmodifiableList(customTemplateVariables);
}
-
+
private static String escapeCharacters(String expression) {
-
+
StringBuilder sb = new StringBuilder();
for (int i = 0; i < expression.length(); i++) {
char ch = expression.charAt(i);
@@ -121,11 +121,11 @@
}
return sb.toString();
}
-
+
private static boolean isReservedCharacter(char ch) {
return CHARACTERS_TO_ESCAPE.indexOf(ch) != -1;
}
-
+
public boolean match(String uri, MultivaluedMap<String, String>
templateVariableToValue) {
if (uri == null) {
@@ -170,46 +170,124 @@
}
// The right hand side value, might be used to further resolve
sub-resources.
-
+
String finalGroup = m.group(i);
templateVariableToValue.putSingle(FINAL_MATCH_GROUP, finalGroup ==
null ? "/" : finalGroup);
-
return true;
}
-
- public static URITemplate createTemplate(ClassResourceInfo cri,
- Path path) {
-
+
+ /**
+ * Substitutes template variables with listed values. List of values is
counterpart for
+ * {...@link #getVariables() list of variables}. When list of value is
shorter than variables substitution
+ * is partial. When variable has pattern, value must fit to pattern,
otherwise
+ * {...@link IllegalArgumentException} is thrown.
+ * <p>
+ * Example1: for template "/{a}/{b}/{a}" {...@link #getVariables()}
returns "[a, b, a]"; providing here list
+ * of value "[foo, bar, baz]" results with "/foo/bar/baz".
+ * <p>
+ * Example2: for template "/{a}/{b}/{a}" providing list of values "[foo]"
results with "/foo/{b}/{a}".
+ *
+ * @param values values for variables
+ * @return template with bound variables.
+ * @throws IllegalArgumentException when values is null, any value does
not match pattern etc.
+ */
+ public String substitute(List<String> values) throws
IllegalArgumentException {
+ if (values == null) {
+ throw new IllegalArgumentException("values is null");
+ }
+ Matcher m = TEMPLATE_NAMES_PATTERN.matcher(template);
+ Iterator<String> valIter = values.iterator();
+ StringBuffer sb = new StringBuffer();
+ while (m.find() && valIter.hasNext()) {
+ String value = valIter.next();
+ String varPattern = m.group(2);
+ if (varPattern != null) {
+ // variable has pattern, matching formats e.g.
+ // for "{a:\d\d}" variable value must have two digits etc.
+ Pattern p = Pattern.compile(varPattern);
+ if (!p.matcher(":" + value).matches()) {
+ throw new IllegalArgumentException("Value '" + value + "'
does not match variable "
+ + m.group());
+ }
+ }
+ m.appendReplacement(sb, value);
+ }
+ m.appendTail(sb);
+ return sb.toString();
+ }
+
+ /**
+ * Substitutes template variables with mapped values. Variables are mapped
to values; if not all variables
+ * are bound result will still contain variables. Note that all variables
with the same name are replaced
+ * by one value.
+ * <p>
+ * Example: for template "/{a}/{b}/{a}" {...@link #getVariables()} returns
"[a, b, a]"; providing here
+ * mapping "[a: foo, b: bar]" results with "/foo/bar/foo" (full
substitution) and for mapping "[b: baz]"
+ * result is "{a}/baz/{a}" (partial substitution).
+ *
+ * @param valuesMap map variables to their values; on each value
Object.toString() is called.
+ * @return template with bound variables.
+ * @throws IllegalArgumentException when size of list of values differs
from list of variables or list
+ * contains nulls.
+ */
+ public String substitute(Map<String, ? extends Object> valuesMap) throws
IllegalArgumentException {
+ if (valuesMap == null) {
+ throw new IllegalArgumentException("valuesMap is null");
+ }
+ Matcher m = TEMPLATE_NAMES_PATTERN.matcher(template);
+ StringBuffer sb = new StringBuffer();
+ while (m.find()) {
+ Object value = valuesMap.get(m.group(1));
+ if (value == null) {
+ continue;
+ }
+ String sval = value.toString();
+ String varPattern = m.group(2);
+ if (varPattern != null) {
+ Pattern p = Pattern.compile(varPattern);
+ if (!p.matcher(":" + sval).matches()) {
+ throw new IllegalArgumentException("Value '" + sval + "'
does not match variable "
+ + m.group());
+ }
+ }
+ m.appendReplacement(sb, sval);
+ }
+ m.appendTail(sb);
+ return sb.toString();
+ }
+
+ public static URITemplate createTemplate(ClassResourceInfo cri, Path path)
{
+
if (path == null) {
return new URITemplate("/");
}
-
+
String pathValue = path.value();
if (!pathValue.startsWith("/")) {
pathValue = "/" + pathValue;
}
-
+
return new URITemplate(pathValue);
}
-
+
public static int compareTemplates(URITemplate t1, URITemplate t2) {
String l1 = t1.getLiteralChars();
String l2 = t2.getLiteralChars();
if (!l1.equals(l2)) {
- // descending order
- return l1.length() < l2.length() ? 1 : -1;
+ // descending order
+ return l1.length() < l2.length() ? 1 : -1;
}
-
- int g1 = t1.getNumberOfGroups();
- int g2 = t2.getNumberOfGroups();
- // descending order
+
+ int g1 = t1.templateVariables.size();
+ int g2 = t2.templateVariables.size();
+ // descending order
int result = g1 < g2 ? 1 : g1 > g2 ? -1 : 0;
if (result == 0) {
- int gCustom1 = t1.getNumberOfGroupsWithCustomExpression();
- int gCustom2 = t2.getNumberOfGroupsWithCustomExpression();
+ int gCustom1 = t1.customTemplateVariables.size();
+ int gCustom2 = t2.customTemplateVariables.size();
if (gCustom1 != gCustom2) {
- // descending order
+ // descending order
return gCustom1 < gCustom2 ? 1 : -1;
}
}
Modified:
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java?rev=738937&r1=738936&r2=738937&view=diff
==============================================================================
---
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java
(original)
+++
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java
Thu Jan 29 17:45:43 2009
@@ -91,7 +91,6 @@
import org.apache.cxf.jaxrs.provider.AbstractConfigurableProvider;
import org.apache.cxf.jaxrs.provider.ProviderFactory;
import org.apache.cxf.message.Message;
-import org.apache.cxf.message.MessageImpl;
import org.apache.cxf.transport.http.AbstractHTTPDestination;
public final class JAXRSUtils {
@@ -931,11 +930,10 @@
}
@SuppressWarnings("unchecked")
- public static Response convertFaultToResponse(Throwable ex, String
baseAddress) {
+ public static Response convertFaultToResponse(Throwable ex, String
baseAddress, Message inMessage) {
ExceptionMapper mapper =
-
ProviderFactory.getInstance(baseAddress).createExceptionMapper(ex.getClass(),
- new
MessageImpl());
+
ProviderFactory.getInstance(baseAddress).createExceptionMapper(ex.getClass(),
inMessage);
if (mapper != null) {
Response excResponse = mapper.toResponse(ex);
if (excResponse != null) {
Modified:
cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/impl/UriBuilderImplTest.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/impl/UriBuilderImplTest.java?rev=738937&r1=738936&r2=738937&view=diff
==============================================================================
---
cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/impl/UriBuilderImplTest.java
(original)
+++
cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/impl/UriBuilderImplTest.java
Thu Jan 29 17:45:43 2009
@@ -21,6 +21,9 @@
import java.lang.reflect.Method;
import java.net.URI;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
import org.apache.cxf.jaxrs.resources.Book;
import org.apache.cxf.jaxrs.resources.BookStore;
@@ -31,14 +34,122 @@
public class UriBuilderImplTest extends Assert {
+ @Test(expected = IllegalArgumentException.class)
+ public void testCtorNull() throws Exception {
+ new UriBuilderImpl(null);
+ }
+
+ @Test
+ public void testCtorAndBuild() throws Exception {
+ URI uri = new URI("http://foo/bar/baz?query=1#fragment");
+ URI newUri = new UriBuilderImpl(uri).build();
+ assertEquals("URI is not built correctly", uri, newUri);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testUriNull() throws Exception {
+ new UriBuilderImpl().uri(null);
+ }
+
@Test
public void testUri() throws Exception {
URI uri = new URI("http://foo/bar/baz?query=1#fragment");
URI newUri = new UriBuilderImpl().uri(uri).build();
- assertEquals("URI is not built correctly", newUri, uri);
+ assertEquals("URI is not built correctly", uri, newUri);
+ }
+
+ @Test
+ public void testBuildValues() throws Exception {
+ URI uri = new URI("http://zzz");
+ URI newUri = new UriBuilderImpl(uri).path("/{b}/{a}/{b}").build("foo",
"bar", "baz");
+ assertEquals("URI is not built correctly", new
URI("http://zzz/foo/bar/foo"), newUri);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testBuildMissingValues() throws Exception {
+ URI uri = new URI("http://zzz");
+ new UriBuilderImpl(uri).path("/{b}/{a}/{b}").build("foo");
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testBuildMissingValues2() throws Exception {
+ URI uri = new URI("http://zzz");
+ new UriBuilderImpl(uri).path("/{b}").build();
+ }
+
+ @Test
+ public void testBuildValueWithBrackets() throws Exception {
+ URI uri = new URI("http://zzz");
+ URI newUri = new UriBuilderImpl(uri).path("/{a}").build("{foo}");
+ assertEquals("URI is not built correctly", new
URI("http://zzz/%7Bfoo%7D"), newUri);
+ }
+
+ @Test
+ public void testBuildValuesPct() throws Exception {
+ URI uri = new URI("http://zzz");
+ URI newUri = new UriBuilderImpl(uri).path("/{a}").build("foo%25/bar%");
+ assertEquals("URI is not built correctly", new
URI("http://zzz/foo%2525/bar%25"), newUri);
}
@Test
+ public void testBuildValuesPctEncoded() throws Exception {
+ URI uri = new URI("http://zzz");
+ URI newUri = new
UriBuilderImpl(uri).path("/{a}/{b}").buildFromEncoded("foo%25", "bar%");
+ assertEquals("URI is not built correctly", new
URI("http://zzz/foo%25/bar%25"), newUri);
+ }
+
+ @Test
+ public void testBuildFromMapValues() throws Exception {
+ URI uri = new URI("http://zzz");
+ Map<String, String> map = new HashMap<String, String>();
+ map.put("b", "foo");
+ map.put("a", "bar");
+ Map<String, String> immutable = Collections.unmodifiableMap(map);
+ URI newUri = new
UriBuilderImpl(uri).path("/{b}/{a}/{b}").buildFromMap(immutable);
+ assertEquals("URI is not built correctly", new
URI("http://zzz/foo/bar/foo"), newUri);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testBuildFromMapMissingValues() throws Exception {
+ URI uri = new URI("http://zzz");
+ Map<String, String> map = new HashMap<String, String>();
+ map.put("b", "foo");
+ Map<String, String> immutable = Collections.unmodifiableMap(map);
+ new UriBuilderImpl(uri).path("/{b}/{a}/{b}").buildFromMap(immutable);
+ }
+
+ @Test
+ public void testBuildFromMapValueWithBrackets() throws Exception {
+ URI uri = new URI("http://zzz");
+ Map<String, String> map = new HashMap<String, String>();
+ map.put("a", "{foo}");
+ Map<String, String> immutable = Collections.unmodifiableMap(map);
+ URI newUri = new
UriBuilderImpl(uri).path("/{a}").buildFromMap(immutable);
+ assertEquals("URI is not built correctly", new
URI("http://zzz/%7Bfoo%7D"), newUri);
+ }
+
+ @Test
+ public void testBuildFromMapValuesPct() throws Exception {
+ URI uri = new URI("http://zzz");
+ Map<String, String> map = new HashMap<String, String>();
+ map.put("a", "foo%25/bar%");
+ Map<String, String> immutable = Collections.unmodifiableMap(map);
+ URI newUri = new
UriBuilderImpl(uri).path("/{a}").buildFromMap(immutable);
+ assertEquals("URI is not built correctly", new
URI("http://zzz/foo%2525/bar%25"), newUri);
+ }
+
+ @Test
+ public void testBuildFromMapValuesPctEncoded() throws Exception {
+ URI uri = new URI("http://zzz");
+ Map<String, String> map = new HashMap<String, String>();
+ map.put("a", "foo%25");
+ map.put("b", "bar%");
+ Map<String, String> immutable = Collections.unmodifiableMap(map);
+ URI newUri = new
UriBuilderImpl(uri).path("/{a}/{b}").buildFromEncodedMap(immutable);
+ assertEquals("URI is not built correctly", new
URI("http://zzz/foo%25/bar%25"), newUri);
+ }
+
+ @Test
public void testAddPath() throws Exception {
URI uri = new URI("http://foo/bar");
URI newUri = new UriBuilderImpl().uri(uri).path("baz").build();
@@ -55,10 +166,24 @@
}
@Test
+ public void testAddPathSlashes2() throws Exception {
+ URI uri = new URI("http://foo/");
+ URI newUri = new
UriBuilderImpl().uri(uri).path("/bar///baz").path("blah//").build();
+ assertEquals("URI is not built correctly", new
URI("http://foo/bar/baz/blah/"), newUri);
+ }
+
+ @Test
+ public void testAddPathSlashes3() throws Exception {
+ URI uri = new URI("http://foo/");
+ URI newUri = new
UriBuilderImpl().uri(uri).path("/bar/").path("").path("baz").build();
+ assertEquals("URI is not built correctly", new
URI("http://foo/bar/baz"), newUri);
+ }
+
+ @Test
public void testAddPathClass() throws Exception {
URI uri = new URI("http://foo/");
- URI newUri = new
UriBuilderImpl().uri(uri).path(BookStore.class).path("bar").build();
- assertEquals("URI is not built correctly", new
URI("http://foo/bookstore/bar"), newUri);
+ URI newUri = new
UriBuilderImpl().uri(uri).path(BookStore.class).path("/").build();
+ assertEquals("URI is not built correctly", new
URI("http://foo/bookstore/"), newUri);
}
@Test(expected = IllegalArgumentException.class)
Modified:
cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/model/URITemplateTest.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/model/URITemplateTest.java?rev=738937&r1=738936&r2=738937&view=diff
==============================================================================
---
cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/model/URITemplateTest.java
(original)
+++
cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/model/URITemplateTest.java
Thu Jan 29 17:45:43 2009
@@ -18,10 +18,15 @@
*/
package org.apache.cxf.jaxrs.model;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
import javax.ws.rs.core.MultivaluedMap;
import org.apache.cxf.jaxrs.impl.MetadataMap;
+
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
@@ -37,69 +42,69 @@
public void testMatchBasic() throws Exception {
URITemplate uriTemplate = new URITemplate("/customers/{id}");
MultivaluedMap<String, String> values = new MetadataMap<String,
String>();
-
+
boolean match = uriTemplate.match("/customers/123/", values);
assertTrue(match);
String value = values.getFirst("id");
assertEquals("123", value);
}
-
+
@Test
public void testMatchWithMatrixAndTemplate() throws Exception {
URITemplate uriTemplate = new URITemplate("/customers/{id}");
MultivaluedMap<String, String> values = new MetadataMap<String,
String>();
-
+
boolean match = uriTemplate.match("/customers/123;123456/", values);
assertTrue(match);
String value = values.getFirst("id");
assertEquals("123;123456", value);
}
-
+
@Test
public void testMatchWithMatrixOnClearPath1() throws Exception {
URITemplate uriTemplate = new URITemplate("/customers/{id}");
MultivaluedMap<String, String> values = new MetadataMap<String,
String>();
-
+
boolean match = uriTemplate.match("/customers;123456/123/", values);
assertTrue(match);
String value = values.getFirst("id");
assertEquals("123", value);
}
-
+
@Test
public void testMatchWithMatrixOnClearPath2() throws Exception {
URITemplate uriTemplate = new
URITemplate("/customers/{id}/orders/{order}");
MultivaluedMap<String, String> values = new MetadataMap<String,
String>();
-
+
assertTrue(uriTemplate.match("/customers;123456/123/orders;456/3",
values));
assertEquals("123", values.getFirst("id"));
assertEquals("3", values.getFirst("order"));
}
-
+
@Test
public void testMatchWithMatrixOnClearPath3() throws Exception {
URITemplate uriTemplate = new URITemplate("/{id}/customers/");
MultivaluedMap<String, String> values = new MetadataMap<String,
String>();
-
+
boolean match = uriTemplate.match("/123/customers;123456/", values);
assertTrue(match);
String value = values.getFirst("id");
assertEquals("123", value);
}
-
+
@Test
public void testMatchWithMatrixOnClearPath4() throws Exception {
URITemplate uriTemplate = new URITemplate("/customers");
MultivaluedMap<String, String> values = new MetadataMap<String,
String>();
-
+
assertTrue(uriTemplate.match("/customers;123456/123/orders;456/3",
values));
}
-
+
@Test
public void testMatchBasicTwoParametersVariation1() throws Exception {
URITemplate uriTemplate = new
URITemplate("/customers/{name}/{department}");
MultivaluedMap<String, String> values = new MetadataMap<String,
String>();
-
+
boolean match = uriTemplate.match("/customers/john/CS", values);
assertTrue(match);
String name = values.getFirst("name");
@@ -107,111 +112,111 @@
assertEquals("john", name);
assertEquals("CS", department);
}
-
+
@Test
public void testMatchBasicTwoParametersVariation2() throws Exception {
URITemplate uriTemplate = new
URITemplate("/customers/name/{name}/dep/{department}");
MultivaluedMap<String, String> values = new MetadataMap<String,
String>();
-
+
boolean match = uriTemplate.match("/customers/name/john/dep/CS",
values);
assertTrue(match);
String name = values.getFirst("name");
String department = values.getFirst("department");
assertEquals("john", name);
assertEquals("CS", department);
- }
-
+ }
+
@Test
public void testURITemplateWithSubResource() throws Exception {
- //So "/customers" is the URITemplate for the root resource class
+ // So "/customers" is the URITemplate for the root resource class
URITemplate uriTemplate = new URITemplate("/customers");
MultivaluedMap<String, String> values = new MetadataMap<String,
String>();
-
+
boolean match = uriTemplate.match("/customers/123", values);
assertTrue(match);
String subResourcePath =
values.getFirst(URITemplate.FINAL_MATCH_GROUP);
assertEquals("/123", subResourcePath);
}
-
+
@Test
public void testURITemplateWithSubResourceVariation2() throws Exception {
- //So "/customers" is the URITemplate for the root resource class
+ // So "/customers" is the URITemplate for the root resource class
URITemplate uriTemplate = new URITemplate("/customers");
MultivaluedMap<String, String> values = new MetadataMap<String,
String>();
-
+
boolean match = uriTemplate.match("/customers/name/john/dep/CS",
values);
assertTrue(match);
String subResourcePath =
values.getFirst(URITemplate.FINAL_MATCH_GROUP);
assertEquals("/name/john/dep/CS", subResourcePath);
}
-
+
@Test
- /* Test a sub-resource locator method like this
- * @HttpMethod("GET") @UriTemplate("/books/{bookId}/")
- * public Book getBook(@UriParam("bookId") String id)
+ /*
+ * Test a sub-resource locator method like this @HttpMethod("GET")
@UriTemplate("/books/{bookId}/") public
+ * Book getBook(@UriParam("bookId") String id)
*/
public void testURITemplateWithSubResourceVariation3() throws Exception {
URITemplate uriTemplate = new URITemplate("/books/{bookId}/");
MultivaluedMap<String, String> values = new MetadataMap<String,
String>();
-
+
boolean match = uriTemplate.match("/books/123/chapter/1", values);
assertTrue(match);
String subResourcePath =
values.getFirst(URITemplate.FINAL_MATCH_GROUP);
assertEquals("/chapter/1", subResourcePath);
}
-
+
@Test
public void testBasicCustomExpression() throws Exception {
URITemplate uriTemplate = new URITemplate("/books/{bookId:[^/]+?}");
MultivaluedMap<String, String> values = new MetadataMap<String,
String>();
-
+
boolean match = uriTemplate.match("/books/123/chapter/1", values);
assertTrue(match);
assertEquals("123", values.getFirst("bookId"));
String subResourcePath =
values.getFirst(URITemplate.FINAL_MATCH_GROUP);
assertEquals("/chapter/1", subResourcePath);
}
-
+
@Test
public void testBasicCustomExpression2() throws Exception {
URITemplate uriTemplate = new URITemplate("/books/{bookId:123}");
MultivaluedMap<String, String> values = new MetadataMap<String,
String>();
-
+
boolean match = uriTemplate.match("/books/123/chapter/1", values);
assertTrue(match);
assertEquals("123", values.getFirst("bookId"));
String subResourcePath =
values.getFirst(URITemplate.FINAL_MATCH_GROUP);
assertEquals("/chapter/1", subResourcePath);
}
-
+
@Test
public void testBasicCustomExpression3() throws Exception {
URITemplate uriTemplate = new URITemplate("/books/{bookId:\\d\\d\\d}");
MultivaluedMap<String, String> values = new MetadataMap<String,
String>();
-
+
boolean match = uriTemplate.match("/books/123/chapter/1", values);
assertTrue(match);
assertEquals("123", values.getFirst("bookId"));
String subResourcePath =
values.getFirst(URITemplate.FINAL_MATCH_GROUP);
assertEquals("/chapter/1", subResourcePath);
}
-
+
@Test
public void testEscaping() throws Exception {
URITemplate uriTemplate = new URITemplate("/books/a.db");
MultivaluedMap<String, String> values = new MetadataMap<String,
String>();
-
+
assertTrue(uriTemplate.match("/books/a.db", values));
assertFalse(uriTemplate.match("/books/adbc", values));
assertFalse(uriTemplate.match("/books/acdb", values));
}
-
+
@Test
public void testBasicCustomExpression4() throws Exception {
URITemplate uriTemplate = new URITemplate("/books/{bookId:...\\.}");
MultivaluedMap<String, String> values = new MetadataMap<String,
String>();
-
+
assertTrue(uriTemplate.match("/books/123.", values));
assertEquals("123.", values.getFirst("bookId"));
values.clear();
@@ -220,12 +225,12 @@
assertFalse(uriTemplate.match("/books/abcd", values));
assertFalse(uriTemplate.match("/books/abc", values));
}
-
+
@Test
public void testMultipleExpression2() throws Exception {
URITemplate uriTemplate = new
URITemplate("/books/{bookId:123}/chapter/{id}");
MultivaluedMap<String, String> values = new MetadataMap<String,
String>();
-
+
boolean match = uriTemplate.match("/books/123/chapter/1", values);
assertTrue(match);
assertEquals("123", values.getFirst("bookId"));
@@ -233,16 +238,16 @@
String subResourcePath =
values.getFirst(URITemplate.FINAL_MATCH_GROUP);
assertEquals("/", subResourcePath);
}
-
+
@Test
public void testFailCustomExpression() throws Exception {
URITemplate uriTemplate = new URITemplate("/books/{bookId:124}");
MultivaluedMap<String, String> values = new MetadataMap<String,
String>();
-
+
boolean match = uriTemplate.match("/books/123/chapter/1", values);
assertFalse(match);
}
-
+
@Test
public void testBaseTail1() {
URITemplate uriTemplate = new URITemplate("/{base:base.+}/{tail}");
@@ -252,7 +257,7 @@
assertEquals("base1", values.getFirst("base"));
assertEquals("tails", values.getFirst("tail"));
}
-
+
@Test
public void testBaseTail2() {
URITemplate uriTemplate = new URITemplate("/{base:.+base}/{tail}");
@@ -263,7 +268,7 @@
assertEquals("1base", values.getFirst("base"));
assertEquals("tails", values.getFirst("tail"));
}
-
+
@Test
public void testBaseTail3() {
URITemplate uriTemplate = new
URITemplate("/{base:base.+suffix}/{tail}");
@@ -274,4 +279,100 @@
assertEquals("base1suffix", values.getFirst("base"));
assertEquals("tails", values.getFirst("tail"));
}
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testSubstituteListNull() throws Exception {
+ new URITemplate("anything").substitute((List<String>)null);
+ }
+
+ @Test
+ public void testSubstituteList() throws Exception {
+ URITemplate ut = new URITemplate("/foo/{a}/{b:\\d\\d}/{c}");
+ List<String> list = Arrays.asList("foo", "99", "baz");
+ assertEquals("Wrong substitution", "/foo/foo/99/baz",
ut.substitute(list));
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testSubstituteListWrongPattern() throws Exception {
+ URITemplate ut = new URITemplate("/foo/{b:\\d\\d}");
+ List<String> list = Arrays.asList("foo", "not-two-digits");
+ ut.substitute(list);
+ }
+
+ @Test
+ public void testSubstituteListSameVars() throws Exception {
+ URITemplate ut = new URITemplate("/foo/{a}/{a}/{a}");
+ List<String> list = Arrays.asList("bar", "baz", "blah");
+ assertEquals("Wrong substitution", "/foo/bar/baz/blah",
ut.substitute(list));
+ }
+
+ @Test
+ public void testSubstituteListIncomplete() throws Exception {
+ URITemplate ut = new URITemplate("/foo/{a}/{c}/{b}");
+ List<String> list = Arrays.asList("bar", "baz");
+ assertEquals("Wrong substitution", "/foo/bar/baz/{b}",
ut.substitute(list));
+ }
+
+ @Test
+ public void testSubstituteListExceeding() throws Exception {
+ URITemplate ut = new URITemplate("/foo/{a}/{b}");
+ List<String> list = Arrays.asList("bar", "baz", "blah");
+ assertEquals("Wrong substitution", "/foo/bar/baz",
ut.substitute(list));
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testSubstituteMapNull() throws Exception {
+ new URITemplate("anything").substitute((Map<String, String>)null);
+ }
+
+ @Test
+ public void testSubstituteMap() throws Exception {
+ URITemplate ut = new URITemplate("/foo/{a}/{b:\\d\\d}/{c}");
+ Map<String, String> map = new HashMap<String, String>();
+ map.put("c", "foo");
+ map.put("b", "11");
+ map.put("a", "bar");
+ assertEquals("Wrong substitution", "/foo/bar/11/foo",
ut.substitute(map));
+ }
+
+ @Test
+ public void testSubstituteMapSameVars() throws Exception {
+ URITemplate ut = new URITemplate("/foo/{a}/{a}/{a}");
+ Map<String, String> map = new HashMap<String, String>();
+ map.put("a", "bar");
+ assertEquals("Wrong substitution", "/foo/bar/bar/bar",
ut.substitute(map));
+ }
+
+ @Test
+ public void testSubstituteMapIncomplete() throws Exception {
+ URITemplate ut = new URITemplate("/foo/{a}/{b}/{a:\\d}");
+ Map<String, String> map = new HashMap<String, String>();
+ map.put("b", "bar");
+ assertEquals("Wrong substitution", "/foo/{a}/bar/{a:\\d}",
ut.substitute(map));
+ }
+
+ @Test
+ public void testSubstituteMapSameVarWithPattern() throws Exception {
+ URITemplate ut = new URITemplate("/foo/{a}/{a:\\d}");
+ Map<String, String> map = new HashMap<String, String>();
+ map.put("a", "0");
+ assertEquals("Wrong substitution", "/foo/0/0", ut.substitute(map));
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testSubstituteMapSameVarWithPatternFail() throws Exception {
+ URITemplate ut = new URITemplate("/foo/{a}/{a:\\d}");
+ Map<String, String> map = new HashMap<String, String>();
+ map.put("a", "not-a-digit");
+ ut.substitute(map);
+ }
+
+ @Test
+ public void testSubstituteMapExceeding() throws Exception {
+ URITemplate ut = new URITemplate("/foo/{a}");
+ Map<String, String> map = new HashMap<String, String>();
+ map.put("b", "baz");
+ map.put("a", "blah");
+ assertEquals("Wrong substitution", "/foo/blah", ut.substitute(map));
+ }
}
Modified:
cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java?rev=738937&r1=738936&r2=738937&view=diff
==============================================================================
---
cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java
(original)
+++
cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java
Thu Jan 29 17:45:43 2009
@@ -703,9 +703,9 @@
@Test
public void testUriInfoMatchedUrisDecode() throws Exception {
- String expected = "[/bookstore/booksubresource/{bookId}/, "
- +
"/bookstore/booksubresource/{bookId}/chapters/sub/{chapterid}/, "
- +
"/bookstore/booksubresource/{bookId}/chapters/sub/{chapterid}/matched!uris]";
+ String expected = "[/bookstore/booksubresource/123/, "
+ + "/bookstore/booksubresource/123/chapters/sub/1/, "
+ +
"/bookstore/booksubresource/123/chapters/sub/1/matched!uris]";
getAndCompare("http://localhost:9080/bookstore/"
+
"booksubresource/123/chapters/sub/1/matched%21uris?decode=true",
expected,
@@ -715,9 +715,9 @@
@Test
public void testUriInfoMatchedUrisNoDecode() throws Exception {
//note '%21' instead of '!'
- String expected = "[/bookstore/booksubresource/{bookId}/, "
- + "/bookstore/booksubresource/{bookId}/chapters/sub/{chapterid}/, "
- +
"/bookstore/booksubresource/{bookId}/chapters/sub/{chapterid}/matched%21uris]";
+ String expected = "[/bookstore/booksubresource/123/, "
+ + "/bookstore/booksubresource/123/chapters/sub/1/, "
+ + "/bookstore/booksubresource/123/chapters/sub/1/matched%21uris]";
getAndCompare("http://localhost:9080/bookstore/"
+
"booksubresource/123/chapters/sub/1/matched%21uris?decode=false",
expected,