Permalink
Browse files

uriInfo optimizations

  • Loading branch information...
1 parent ce2670f commit 237f69b90a568c24c883c007fa1dee415d25e9f7 @patriot1burke patriot1burke committed Jan 26, 2014
View
12 .../profiling-tests/src/test/java/org/jboss/resteasy/test/profiling/MockedProfilingTest.java
@@ -15,6 +15,7 @@
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import java.io.ByteArrayInputStream;
+import java.net.URI;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
@@ -38,6 +39,17 @@ public String create(String cust)
}
+ @Test
+ public void testUri() throws Exception
+ {
+ URI uri = URI.create("/foo");
+ System.out.println(uri);
+ System.out.println(uri.getRawPath());
+ System.out.println("---");
+ uri = URI.create("foo");
+ System.out.println(uri);
+ System.out.println(uri.getRawPath());
+ }
@Test
public void testCleartext() throws Exception
View
3 ...s/resteasy-jaxrs/src/main/java/org/jboss/resteasy/plugins/server/servlet/ServletUtil.java 100644 → 100755
@@ -38,6 +38,8 @@ public static ResteasyUriInfo extractUriInfo(HttpServletRequest request, String
contextPath += "/";
contextPath += servletPrefix;
}
+ return new ResteasyUriInfo(request.getRequestURL().toString(), request.getQueryString(), contextPath);
+ /*
URI absolutePath = null;
try
{
@@ -70,6 +72,7 @@ public static ResteasyUriInfo extractUriInfo(HttpServletRequest request, String
//System.out.println("query string: " + request.getQueryString());
ResteasyUriInfo uriInfo = new ResteasyUriInfo(baseURI, relativeURI);
return uriInfo;
+ */
}
public static ResteasyHttpHeaders extractHttpHeaders(HttpServletRequest request)
View
45 jaxrs/resteasy-jaxrs/src/main/java/org/jboss/resteasy/specimpl/PathSegmentImpl.java
@@ -15,7 +15,8 @@
{
private String path;
private String original;
- private MultivaluedMap<String, String> matrixParameters = new MultivaluedMapImpl<String, String>();
+ private MultivaluedMap<String, String> matrixParameters;
+ private boolean hasMatrixParams;
/**
* @param segment encoded path segment
@@ -28,6 +29,8 @@ public PathSegmentImpl(String segment, boolean decode)
int semicolon = segment.indexOf(';');
if (semicolon >= 0)
{
+ matrixParameters = new MultivaluedMapImpl<String, String>();
+ hasMatrixParams = true;
if (semicolon > 0) this.path = segment.substring(0, semicolon);
else this.path = "";
String matrixParams = segment.substring(semicolon + 1);
@@ -52,6 +55,15 @@ public PathSegmentImpl(String segment, boolean decode)
if (decode) this.path = Encode.decodePath(this.path);
}
+ /**
+ * NOTE: Used for optimization in ResteasyUriInfo
+ * @return
+ */
+ public boolean hasMatrixParams()
+ {
+ return hasMatrixParams;
+ }
+
public String getOriginal()
{
return original;
@@ -64,6 +76,10 @@ public String getPath()
public MultivaluedMap<String, String> getMatrixParameters()
{
+ if (matrixParameters == null)
+ {
+ matrixParameters = new MultivaluedMapImpl<String, String>();
+ }
return matrixParameters;
}
@@ -84,15 +100,34 @@ public String toString()
return buf.toString();
}
+ public static List<PathSegment> parseSegments(String path, boolean decode)
+ {
+ return parseSegmentsOptimization(path, decode).segments;
+ }
+
+ /**
+ * Used when creating the matching path in ResteasyUriInfo
+ *
+ */
+ public static class SegmentParse
+ {
+ public List<PathSegment> segments;
+ public boolean hasMatrixParams;
+
+
+ }
+
/**
*
* @param path encoded full path
* @param decode whether or not to decode each segment
* @return
*/
- public static List<PathSegment> parseSegments(String path, boolean decode)
+ public static SegmentParse parseSegmentsOptimization(String path, boolean decode)
{
+ SegmentParse parse = new SegmentParse();
List<PathSegment> pathSegments = new ArrayList<PathSegment>();
+ parse.segments = pathSegments;
int start = 0;
if (path.startsWith("/")) start++;
int length = path.length();
@@ -110,9 +145,11 @@ public String toString()
p = path.substring(start, slash);
start = slash + 1;
}
- pathSegments.add(new PathSegmentImpl(p, decode));
+ PathSegmentImpl pathSegment = new PathSegmentImpl(p, decode);
+ parse.hasMatrixParams |= pathSegment.hasMatrixParams();
+ pathSegments.add(pathSegment);
} while (start < length);
- return pathSegments;
+ return parse;
}
}
View
314 jaxrs/resteasy-jaxrs/src/main/java/org/jboss/resteasy/specimpl/ResteasyHttpHeaders.java 100644 → 100755
@@ -1,157 +1,157 @@
-package org.jboss.resteasy.specimpl;
-
-import org.jboss.resteasy.util.CaseInsensitiveMap;
-import org.jboss.resteasy.util.DateUtil;
-import org.jboss.resteasy.util.LocaleHelper;
-import org.jboss.resteasy.util.MediaTypeHelper;
-import org.jboss.resteasy.util.WeightedLanguage;
-
-import javax.ws.rs.core.Cookie;
-import javax.ws.rs.core.HttpHeaders;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.MultivaluedMap;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Date;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.StringTokenizer;
-
-/**
- * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
- * @version $Revision: 1 $
- */
-public class ResteasyHttpHeaders implements HttpHeaders
-{
-
- private MultivaluedMap<String, String> requestHeaders = new CaseInsensitiveMap<String>();
- private Map<String, Cookie> cookies = Collections.emptyMap();
-
- public ResteasyHttpHeaders(MultivaluedMap<String, String> requestHeaders)
- {
- this.requestHeaders = requestHeaders;
- }
-
- @Override
- public MultivaluedMap<String, String> getRequestHeaders()
- {
- return requestHeaders;
- }
-
- public MultivaluedMap<String, String> getMutableHeaders()
- {
- return requestHeaders;
- }
-
- public void testParsing()
- {
- // test parsing should throw an exception on error
- getAcceptableMediaTypes();
- getMediaType();
- getLanguage();
- getAcceptableLanguages();
-
- }
-
- @Override
- public List<String> getRequestHeader(String name)
- {
- List<String> vals = requestHeaders.get(name);
- if (vals == null) return Collections.EMPTY_LIST;
- return Collections.unmodifiableList(vals);
- }
-
- @Override
- public Map<String, Cookie> getCookies()
- {
- return cookies;
- }
-
- public void setCookies(Map<String, Cookie> cookies)
- {
- this.cookies = Collections.unmodifiableMap(cookies);
- }
-
- @Override
- public Date getDate()
- {
- String date = requestHeaders.getFirst(DATE);
- if (date == null) return null;
- return DateUtil.parseDate(date);
- }
-
- @Override
- public String getHeaderString(String name)
- {
- List<String> vals = requestHeaders.get(name);
- if (vals == null) return null;
- StringBuilder builder = new StringBuilder();
- boolean first = true;
- for (String val : vals)
- {
- if (first) first = false;
- else builder.append(",");
- builder.append(val);
- }
- return builder.toString();
- }
-
- @Override
- public Locale getLanguage()
- {
- String obj = requestHeaders.getFirst(HttpHeaders.CONTENT_LANGUAGE);
- if (obj == null) return null;
- return new Locale(obj);
- }
-
- @Override
- public int getLength()
- {
- String obj = requestHeaders.getFirst(HttpHeaders.CONTENT_LENGTH);
- if (obj == null) return -1;
- return Integer.parseInt(obj);
- }
-
- @Override
- public MediaType getMediaType()
- {
- String obj = requestHeaders.getFirst(HttpHeaders.CONTENT_TYPE);
- if (obj == null) return null;
- return MediaType.valueOf(obj);
- }
-
- @Override
- public List<MediaType> getAcceptableMediaTypes()
- {
- String accepts = getHeaderString(ACCEPT);
- if (accepts == null) return Collections.emptyList();
- List<MediaType> list = new ArrayList<MediaType>();
- StringTokenizer tokenizer = new StringTokenizer(accepts, ",");
- while (tokenizer.hasMoreElements())
- {
- String item = tokenizer.nextToken().trim();
- list.add(MediaType.valueOf(item));
- }
- MediaTypeHelper.sortByWeight(list);
- return Collections.unmodifiableList(list);
- }
-
- @Override
- public List<Locale> getAcceptableLanguages()
- {
- String accepts = getHeaderString(ACCEPT_LANGUAGE);
- if (accepts == null) return Collections.emptyList();
- List<Locale> list = new ArrayList<Locale>();
- List<WeightedLanguage> languages = new ArrayList<WeightedLanguage>();
- StringTokenizer tokenizer = new StringTokenizer(accepts, ",");
- while (tokenizer.hasMoreElements())
- {
- String item = tokenizer.nextToken().trim();
- languages.add(WeightedLanguage.parse(item));
- }
- Collections.sort(languages);
- for (WeightedLanguage language : languages) list.add(language.getLocale());
- return Collections.unmodifiableList(list);
- }
-}
+package org.jboss.resteasy.specimpl;
+
+import org.jboss.resteasy.util.CaseInsensitiveMap;
+import org.jboss.resteasy.util.DateUtil;
+import org.jboss.resteasy.util.LocaleHelper;
+import org.jboss.resteasy.util.MediaTypeHelper;
+import org.jboss.resteasy.util.WeightedLanguage;
+
+import javax.ws.rs.core.Cookie;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class ResteasyHttpHeaders implements HttpHeaders
+{
+
+ private MultivaluedMap<String, String> requestHeaders = new CaseInsensitiveMap<String>();
+ private Map<String, Cookie> cookies = Collections.emptyMap();
+
+ public ResteasyHttpHeaders(MultivaluedMap<String, String> requestHeaders)
+ {
+ this.requestHeaders = requestHeaders;
+ }
+
+ @Override
+ public MultivaluedMap<String, String> getRequestHeaders()
+ {
+ return requestHeaders;
+ }
+
+ public MultivaluedMap<String, String> getMutableHeaders()
+ {
+ return requestHeaders;
+ }
+
+ public void testParsing()
+ {
+ // test parsing should throw an exception on error
+ getAcceptableMediaTypes();
+ getMediaType();
+ getLanguage();
+ getAcceptableLanguages();
+
+ }
+
+ @Override
+ public List<String> getRequestHeader(String name)
+ {
+ List<String> vals = requestHeaders.get(name);
+ if (vals == null) return Collections.EMPTY_LIST;
+ return Collections.unmodifiableList(vals);
+ }
+
+ @Override
+ public Map<String, Cookie> getCookies()
+ {
+ return cookies;
+ }
+
+ public void setCookies(Map<String, Cookie> cookies)
+ {
+ this.cookies = Collections.unmodifiableMap(cookies);
+ }
+
+ @Override
+ public Date getDate()
+ {
+ String date = requestHeaders.getFirst(DATE);
+ if (date == null) return null;
+ return DateUtil.parseDate(date);
+ }
+
+ @Override
+ public String getHeaderString(String name)
+ {
+ List<String> vals = requestHeaders.get(name);
+ if (vals == null) return null;
+ StringBuilder builder = new StringBuilder();
+ boolean first = true;
+ for (String val : vals)
+ {
+ if (first) first = false;
+ else builder.append(",");
+ builder.append(val);
+ }
+ return builder.toString();
+ }
+
+ @Override
+ public Locale getLanguage()
+ {
+ String obj = requestHeaders.getFirst(HttpHeaders.CONTENT_LANGUAGE);
+ if (obj == null) return null;
+ return new Locale(obj);
+ }
+
+ @Override
+ public int getLength()
+ {
+ String obj = requestHeaders.getFirst(HttpHeaders.CONTENT_LENGTH);
+ if (obj == null) return -1;
+ return Integer.parseInt(obj);
+ }
+
+ @Override
+ public MediaType getMediaType()
+ {
+ String obj = requestHeaders.getFirst(HttpHeaders.CONTENT_TYPE);
+ if (obj == null) return null;
+ return MediaType.valueOf(obj);
+ }
+
+ @Override
+ public List<MediaType> getAcceptableMediaTypes()
+ {
+ String accepts = getHeaderString(ACCEPT);
+ if (accepts == null) return Collections.emptyList();
+ List<MediaType> list = new ArrayList<MediaType>();
+ StringTokenizer tokenizer = new StringTokenizer(accepts, ",");
+ while (tokenizer.hasMoreElements())
+ {
+ String item = tokenizer.nextToken().trim();
+ list.add(MediaType.valueOf(item));
+ }
+ MediaTypeHelper.sortByWeight(list);
+ return Collections.unmodifiableList(list);
+ }
+
+ @Override
+ public List<Locale> getAcceptableLanguages()
+ {
+ String accepts = getHeaderString(ACCEPT_LANGUAGE);
+ if (accepts == null) return Collections.emptyList();
+ List<Locale> list = new ArrayList<Locale>();
+ List<WeightedLanguage> languages = new ArrayList<WeightedLanguage>();
+ StringTokenizer tokenizer = new StringTokenizer(accepts, ",");
+ while (tokenizer.hasMoreElements())
+ {
+ String item = tokenizer.nextToken().trim();
+ languages.add(WeightedLanguage.parse(item));
+ }
+ Collections.sort(languages);
+ for (WeightedLanguage language : languages) list.add(language.getLocale());
+ return Collections.unmodifiableList(list);
+ }
+}
View
55 jaxrs/resteasy-jaxrs/src/main/java/org/jboss/resteasy/spi/ResteasyUriInfo.java
@@ -4,13 +4,17 @@
import org.jboss.resteasy.specimpl.PathSegmentImpl;
import org.jboss.resteasy.specimpl.ResteasyUriBuilder;
import org.jboss.resteasy.util.Encode;
+import org.jboss.resteasy.util.PathHelper;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.PathSegment;
import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.UriInfo;
import java.io.UnsupportedEncodingException;
+import java.net.MalformedURLException;
import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.LinkedList;
@@ -45,6 +49,31 @@
private List<Object> ancestors;
+ public ResteasyUriInfo(String absoluteUri, String queryString, String contextPath)
+ {
+ ResteasyUriBuilder absoluteBuilder = (ResteasyUriBuilder)UriBuilder.fromUri(absoluteUri).replaceQuery(queryString);
+ requestURI = absoluteBuilder.build();
+ absolutePath = URI.create(absoluteUri);
+ encodedPath = PathHelper.getEncodedPathInfo(absolutePath.getRawPath(), contextPath);
+ baseURI = absolutePath;
+ if (!encodedPath.trim().equals(""))
+ {
+ String tmpContextPath = contextPath;
+ if (!tmpContextPath.endsWith("/")) tmpContextPath += "/";
+ baseURI = absoluteBuilder.clone().replacePath(tmpContextPath).replaceQuery(null).build();
+ }
+ // make sure there is no trailing '/'
+ if (encodedPath.length() > 1 && encodedPath.endsWith("/")) encodedPath = encodedPath.substring(0, encodedPath.length() - 1);
+
+ // make sure path starts with '/'
+ if (encodedPath.length() == 0 || encodedPath.charAt(0) != '/')
+ {
+ encodedPath = "/" + encodedPath;
+ }
+ path = UriBuilder.fromPath(encodedPath).build().getPath();
+ processPath();
+ }
+
public ResteasyUriInfo(URI base, URI relative)
{
String b = base.toString();
@@ -60,18 +89,26 @@ public ResteasyUriInfo(URI base, URI relative)
encodedPath = "/" + r;
path = "/" + relative.getPath();
}
- requestURI = UriBuilder.fromUri(base).path(relative.getRawPath()).replaceQuery(relative.getRawQuery()).build();
+ UriBuilder requestUriBuilder = UriBuilder.fromUri(base).path(relative.getRawPath()).replaceQuery(relative.getRawQuery());
+ requestURI = requestUriBuilder.build();
+ absolutePath = requestUriBuilder.replaceQuery(null).build();
baseURI = base;
- encodedPathSegments = PathSegmentImpl.parseSegments(encodedPath, false);
+ processPath();
+ }
+
+ protected void processPath()
+ {
+ PathSegmentImpl.SegmentParse parse = PathSegmentImpl.parseSegmentsOptimization(encodedPath, false);
+ encodedPathSegments = parse.segments;
this.pathSegments = new ArrayList<PathSegment>(encodedPathSegments.size());
for (PathSegment segment : encodedPathSegments)
{
pathSegments.add(new PathSegmentImpl(((PathSegmentImpl) segment).getOriginal(), true));
}
extractParameters(requestURI.getRawQuery());
- extractMatchingPath(encodedPathSegments);
+ if (parse.hasMatrixParams) extractMatchingPath(encodedPathSegments);
+ else matchingPath = encodedPath;
- absolutePath = UriBuilder.fromUri(requestURI).replaceQuery(null).build();
}
public ResteasyUriInfo(URI requestURI)
@@ -89,16 +126,8 @@ public ResteasyUriInfo(URI requestURI)
}
this.requestURI = requestURI;
baseURI = UriBuilder.fromUri(requestURI).replacePath("").build();
- encodedPathSegments = PathSegmentImpl.parseSegments(encodedPath, false);
- this.pathSegments = new ArrayList<PathSegment>(encodedPathSegments.size());
- for (PathSegment segment : encodedPathSegments)
- {
- pathSegments.add(new PathSegmentImpl(((PathSegmentImpl) segment).getOriginal(), true));
- }
- extractParameters(requestURI.getRawQuery());
- extractMatchingPath(encodedPathSegments);
-
absolutePath = UriBuilder.fromUri(requestURI).replaceQuery(null).build();
+ processPath();
}
View
1 jaxrs/resteasy-jaxrs/src/main/java/org/jboss/resteasy/util/CaseInsensitiveMap.java
@@ -30,6 +30,7 @@
public int compare(String s1, String s2) {
if (s1 == s2) return 0;
int n1 = 0;
+ // null check is different than JDK version of this method
if (s1 != null) n1 = s1.length();
int n2 = 0;
if (s2 != null) n2 = s2.length();

0 comments on commit 237f69b

Please sign in to comment.