001 /**
002 * Copyright (C) 2009-2011 the original author or authors.
003 * See the notice.md file distributed with this work for additional
004 * information regarding copyright ownership.
005 *
006 * Licensed under the Apache License, Version 2.0 (the "License");
007 * you may not use this file except in compliance with the License.
008 * You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018
019 package org.fusesource.restygwt.client;
020
021 import java.util.Map;
022
023 import com.google.gwt.http.client.URL;
024
025 /**
026 *
027 * @author <a href="http://hiramchirino.com">Hiram Chirino</a>
028 */
029 public class Resource {
030
031 public static final String CONTENT_TYPE_TEXT = "text/plain";
032 public static final String CONTENT_TYPE_JSON = "application/json";
033 public static final String CONTENT_TYPE_XML = "application/xml";
034 public static final String CONTENT_TYPE_RSS = "application/rss+xml";
035 public static final String CONTENT_TYPE_ATOM = "application/atom+xml";
036 public static final String HEADER_ACCEPT = "Accept";
037 public static final String HEADER_CONTENT_TYPE = "Content-Type";
038
039 final String path;
040 final String query;
041 final Map<String, String> headers;
042
043 public Resource(String uri) {
044 this (uri, (Map<String, String>) null);
045 }
046
047 public Resource(String uri, String query) {
048 this(uri, query, null);
049 }
050
051 public Resource(final String uri, final Map<String, String> headers) {
052 int pos = uri.indexOf('?');
053 if (pos >= 0) {
054 this.path = uri.substring(0, pos);
055 this.query = uri.substring(pos + 1);
056 } else {
057 // Strip off trailing "/" so we have a known format to work off of when concatenating paths
058 this.path = uri.endsWith("/") ? uri.substring(0, uri.length() - 1) : uri;
059 this.query = null;
060 }
061 this.headers = (headers != null) ? headers : defaultHeaders();
062 }
063
064 public Resource(final String uri, final String query, final Map<String, String> headers) {
065 // Strip off trailing "/" so we have a known format to work off of when concatenating paths
066 this.path = uri.endsWith("/") ? uri.substring(0, uri.length() - 1) : uri;
067 this.query = query;
068 this.headers = (headers != null) ? headers : defaultHeaders();
069 }
070
071 public Method head() {
072 return new Method(this, "HEAD").headers(headers);
073 }
074
075 public Method get() {
076 return new Method(this, "GET").headers(headers);
077 }
078
079 public Method put() {
080 return new Method(this, "PUT").headers(headers);
081 }
082
083 public Method post() {
084 return new Method(this, "POST").headers(headers);
085 }
086
087 public Method delete() {
088 return new Method(this, "DELETE").headers(headers);
089 }
090
091 public Method options() {
092 return new Method(this, "OPTIONS").headers(headers);
093 }
094
095 public JsonpMethod jsonp() {
096 return new JsonpMethod(this);
097 }
098
099 public String getPath() {
100 return path;
101 }
102
103 public String getQuery() {
104 return query;
105 }
106
107 public String getUri() {
108 if (query != null) {
109 return path + "?" + query;
110 }
111 return path;
112 }
113
114 public Map<String, String> getHeaders() {
115 return headers;
116 }
117
118 protected Map<String, String> defaultHeaders() {
119 return null;
120 }
121
122 // TODO: support fancier resolutions
123 public Resource resolve(String path) {
124
125 // it might be an absolute path...
126 if (path.startsWith("http:") || path.startsWith("https:") || path.startsWith("file:")) {
127 return new Resource(path);
128 }
129
130 // strip prefix / if needed...
131 if (path.startsWith("/")) {
132 path = path.substring(1);
133 }
134 return new Resource(this.path + "/" + path);
135 }
136
137 public Resource addQueryParam(String key, String value) {
138 key = URL.encodeComponent(key);
139 value = URL.encodeComponent(value);
140 String q = query == null ? "" : query + "&";
141 return new Resource(path, q + key + "=" + value, headers);
142 }
143
144 public Resource addQueryParams(String key, Iterable<String> values) {
145 key = URL.encodeComponent(key);
146 StringBuilder q = new StringBuilder(query == null ? "" : query + "&");
147 boolean ampersand = false;
148 for (String value : values) {
149 if (ampersand) {
150 q.append('&');
151 } else {
152 ampersand = true;
153 }
154 value = URL.encodeComponent(value);
155 q.append(key).append("=").append(value);
156 }
157
158 return new Resource(path, q.toString(), headers);
159 }
160
161
162 }