##### Coverage Report - org.seasar.cubby.util.LinkBuilder

Classes in this File | Line Coverage | Branch Coverage | Complexity
LinkBuilder |
54% | 38/70
63% | 14/22
| 2.0476190476190474;2.048

1 |  |
     /*
2 |  |
      * Copyright 2004-2009 the Seasar Foundation and the Others.
3 |  |
      *
4 |  |
      * Licensed under the Apache License, Version 2.0 (the "License");
5 |  |
      * you may not use this file except in compliance with the License.
6 |  |
      * You may obtain a copy of the License at
7 |  |
      *
8 |  |
      *     http://www.apache.org/licenses/LICENSE-2.0
9 |  |
      *
10 |  |
      * Unless required by applicable law or agreed to in writing, software
11 |  |
      * distributed under the License is distributed on an "AS IS" BASIS,
12 |  |
      * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
13 |  |
      * either express or implied. See the License for the specific language
14 |  |
      * governing permissions and limitations under the License.
15 |  |
      */
16 |  |
     package org.seasar.cubby.util;
17 |  |
18 |  |
     import java.io.Serializable;
19 |  |
     import java.net.MalformedURLException;
20 |  |
     import java.net.URL;
21 |  |
22 |  |
     import javax.servlet.http.HttpServletRequest;
23 |  |
24 |  |
     /**
25 |  |
      * 要求の URL をベースとしたリンク文字列を構築します。
26 |  |
      *
27 |  |
      * @author baba
28 |  |
      */
29 |  |
     public class LinkBuilder implements Serializable {
30 |  |
31 |  |
             /** シリアルバージョン UID。 */
32 |  |
             private static final long serialVersionUID = 1L;
33 |  |
34 |  |
             /** プロトコル。 */
35 |  |
             private String protocol;
36 |  |
37 |  |
             /** ホスト名。 */
38 |  |
             private String host;
39 |  |
40 |  |
             /** ホスト上でのポート番号。 */
41 |  |
             private int port;
42 |  |
43 |  |
             /** ホスト上のファイル。 */
44 |  |
             private String file;
45 |  |
46 |  |
             /**
47 |  |
              * URL ビルダオブジェクトを生成します。
48 |  |
              */
49 | 66 |
             public LinkBuilder() {
50 | 66 |
                     this.clear();
51 | 66 |
             }
52 |  |
53 |  |
             /**
54 |  |
              * このインスタンスをクリアします。
55 |  |
              */
56 |  |
             public void clear() {
57 | 76 |
                     this.protocol = null;
58 | 76 |
                     this.host = null;
59 | 76 |
                     this.port = -1;
60 | 76 |
                     this.file = null;
61 | 76 |
             }
62 |  |
63 |  |
             /**
64 |  |
              * プロトコルを取得します。
65 |  |
              *
66 |  |
              * @return プロトコル
67 |  |
              */
68 |  |
             public String getProtocol() {
69 | 0 |
                     return protocol;
70 |  |
             }
71 |  |
72 |  |
             /**
73 |  |
              * プロトコルを設定します。
74 |  |
              *
75 |  |
              * @param protocol
76 |  |
              *            プロトコル
77 |  |
              * @throws NullPointerException
78 |  |
              *             指定された <code>protocol</code> が <code>null</code> の場合
79 |  |
              */
80 |  |
             public void setProtocol(final String protocol) {
81 | 4 |
                     if (protocol == null) {
82 | 0 |
                             throw new NullPointerException("No protocol");
83 |  |
                     }
84 | 4 |
                     this.protocol = protocol;
85 | 4 |
             }
86 |  |
87 |  |
             /**
88 |  |
              * ホスト名を取得します。
89 |  |
              *
90 |  |
              * @return ホスト名
91 |  |
              */
92 |  |
             public String getHost() {
93 | 0 |
                     return host;
94 |  |
             }
95 |  |
96 |  |
             /**
97 |  |
              * ホスト名を設定します。
98 |  |
              *
99 |  |
              * @param host
100 |  |
              *            ホスト名
101 |  |
              * @throws NullPointerException
102 |  |
              *             指定された <code>host</code> が <code>null</code> の場合
103 |  |
              */
104 |  |
             public void setHost(final String host) {
105 | 0 |
                     if (host == null) {
106 | 0 |
                             throw new NullPointerException("No host");
107 |  |
                     }
108 | 0 |
                     this.host = host;
109 | 0 |
             }
110 |  |
111 |  |
             /**
112 |  |
              * ホスト上のポート番号を取得します。
113 |  |
              *
114 |  |
              * @return ホスト上のポート番号
115 |  |
              */
116 |  |
             public int getPort() {
117 | 0 |
                     return port;
118 |  |
             }
119 |  |
120 |  |
             /**
121 |  |
              * ホスト上のポート番号を設定します。
122 |  |
              *
123 |  |
              * @param port
124 |  |
              *            ホスト上のポート番号
125 |  |
              * @throws IllegalArgumentException
126 |  |
              *             ポート番号が負の値の場合
127 |  |
              */
128 |  |
             public void setPort(final int port) {
129 | 1 |
                     if (port < 0) {
130 | 0 |
                             throw new IllegalArgumentException("Invalid port number :" + port);
131 |  |
                     }
132 | 1 |
                     this.port = port;
133 | 1 |
             }
134 |  |
135 |  |
             /**
136 |  |
              * ホスト上のファイルを取得します。
137 |  |
              *
138 |  |
              * @return ホスト上のファイル
139 |  |
              */
140 |  |
             public String getFile() {
141 | 0 |
                     return file;
142 |  |
             }
143 |  |
144 |  |
             /**
145 |  |
              * ホスト上のファイルを設定します。
146 |  |
              *
147 |  |
              * @param file
148 |  |
              *            ホスト上のファイル
149 |  |
              */
150 |  |
             public void setFile(final String file) {
151 | 18 |
                     this.file = file;
152 | 18 |
             }
153 |  |
154 |  |
             /**
155 |  |
              * このリンクの文字列表現を構築します。
156 |  |
              * <p>
157 |  |
              * 指定された要求とこのオブジェクトに指定されたプロトコル、ホスト名、ホスト上のポート番号が同じ場合は相対パスであるとみなして内部形式
158 |  |
              * のリンク文字列を、そうでない場合は外部形式のリンク文字列を構築します。
159 |  |
              * </p>
160 |  |
              *
161 |  |
              * @param request
162 |  |
              *            要求
163 |  |
              * @return URL の文字列表現
164 |  |
              * @throws MalformedURLException
165 |  |
              *             未知のプロトコルとして指定された場合
166 |  |
              */
167 |  |
             public String toLink(final HttpServletRequest request)
168 |  |
                             throws MalformedURLException {
169 | 18 |
                     final URL requestURL = new URL(request.getRequestURL().toString());
170 | 18 |
                     final URL newURL = new URL(getNewProtocol(requestURL.getProtocol()),
171 |  |
                                     getNewHost(requestURL.getHost()), getNewPort(requestURL
172 |  |
                                                     .getPort()), getNewFile(requestURL.getFile()));
173 | 18 |
                     if (isRelativeLink(requestURL, newURL)) {
174 | 14 |
                             return newURL.getFile();
175 |  |
                     } else {
176 | 4 |
                             return newURL.toExternalForm();
177 |  |
                     }
178 |  |
             }
179 |  |
180 |  |
             /**
181 |  |
              * 指定された 2 つの URL を比較して、相対パス形式の URL 文字列を生成するかどうかを示します。
182 |  |
              *
183 |  |
              * @param url1
184 |  |
              *            URL1
185 |  |
              * @param url2
186 |  |
              *            URL2
187 |  |
              * @return 相対パス形式の URL 文字列を生成する場合は <code>true</code>、そうでない場合は
188 |  |
              *         <code>false</code>
189 |  |
              */
190 |  |
             private boolean isRelativeLink(final URL url1, final URL url2) {
191 | 18 |
                     if (!url1.getProtocol().equals(url2.getProtocol())) {
192 | 4 |
                             return false;
193 |  |
                     }
194 | 14 |
                     if (!url1.getHost().equals(url2.getHost())) {
195 | 0 |
                             return false;
196 |  |
                     }
197 | 14 |
                     if (url1.getPort() != url2.getPort()) {
198 | 0 |
                             return false;
199 |  |
                     }
200 | 14 |
                     return true;
201 |  |
             }
202 |  |
203 |  |
             /**
204 |  |
              * 新しい URL のプロトコルを返します。
205 |  |
              *
206 |  |
              * @param requestProtocol
207 |  |
              *            要求のプロトコル
208 |  |
              * @return 新しい URL のプロトコル
209 |  |
              */
210 |  |
             private String getNewProtocol(final String requestProtocol) {
211 | 18 |
                     if (this.protocol == null) {
212 | 14 |
                             return requestProtocol;
213 |  |
                     } else {
214 | 4 |
                             return this.protocol;
215 |  |
                     }
216 |  |
             }
217 |  |
218 |  |
             /**
219 |  |
              * 新しい URL のホスト名を返します。
220 |  |
              *
221 |  |
              * @param requestHost
222 |  |
              *            要求のホスト名
223 |  |
              * @return 新しい URL のホスト名
224 |  |
              */
225 |  |
             private String getNewHost(final String requestHost) {
226 | 18 |
                     if (this.host == null) {
227 | 18 |
                             return requestHost;
228 |  |
                     } else {
229 | 0 |
                             return this.host;
230 |  |
                     }
231 |  |
             }
232 |  |
233 |  |
             /**
234 |  |
              * 新しい URL のホスト上のポート番号
235 |  |
              *
236 |  |
              * @param requestPort
237 |  |
              *            要求のホスト上のポート番号
238 |  |
              * @return 新しい URL のホスト上のポート番号
239 |  |
              */
240 |  |
             private int getNewPort(final int requestPort) {
241 | 18 |
                     if (this.port < 0) {
242 | 17 |
                             return requestPort;
243 |  |
                     } else {
244 | 1 |
                             return this.port;
245 |  |
                     }
246 |  |
             }
247 |  |
248 |  |
             /**
249 |  |
              * 新しい URL のホスト上のファイル
250 |  |
              *
251 |  |
              * @param requestPort
252 |  |
              *            要求のホスト上のファイル
253 |  |
              * @return 新しい URL のホスト上のファイル
254 |  |
              */
255 |  |
             private String getNewFile(final String currentFile) {
256 | 18 |
                     if (this.file == null) {
257 | 0 |
                             return currentFile;
258 |  |
                     } else {
259 | 18 |
                             return this.file;
260 |  |
                     }
261 |  |
             }
262 |  |
263 |  |
             /**
264 |  |
              * プロトコルを設定します。
265 |  |
              *
266 |  |
              * @param protocol
267 |  |
              *            プロトコル
268 |  |
              * @return このオブジェクト
269 |  |
              */
270 |  |
             public LinkBuilder protocol(final String protocol) {
271 | 0 |
                     this.setProtocol(protocol);
272 | 0 |
                     return this;
273 |  |
             }
274 |  |
275 |  |
             /**
276 |  |
              * ホスト名を設定します。
277 |  |
              *
278 |  |
              * @param host
279 |  |
              *            ホスト名
280 |  |
              * @return このオブジェクト
281 |  |
              */
282 |  |
             public LinkBuilder host(final String host) {
283 | 0 |
                     this.setHost(host);
284 | 0 |
                     return this;
285 |  |
             }
286 |  |
287 |  |
             /**
288 |  |
              * ホスト上のポート場号を設定します。
289 |  |
              *
290 |  |
              * @param port
291 |  |
              *            ホスト上のポート場号
292 |  |
              * @return このオブジェクト
293 |  |
              */
294 |  |
             public LinkBuilder port(final int port) {
295 | 0 |
                     this.setPort(port);
296 | 0 |
                     return this;
297 |  |
             }
298 |  |
299 |  |
             /**
300 |  |
              * ホスト上のファイルを設定します。
301 |  |
              *
302 |  |
              * @param file
303 |  |
              *            ホスト上のファイル
304 |  |
              * @return このオブジェクト
305 |  |
              */
306 |  |
             public LinkBuilder file(final String file) {
307 | 18 |
                     this.setFile(file);
308 | 18 |
                     return this;
309 |  |
             }
310 |  |
311 |  |
             /**
312 |  |
              * {@inheritDoc}
313 |  |
              */
314 |  |
             @Override
315 |  |
             public String toString() {
316 | 0 |
                     final StringBuilder builder = new StringBuilder();
317 | 0 |
                     builder.append(this);
318 | 0 |
                     builder.append(" [host=");
319 | 0 |
                     builder.append(host);
320 | 0 |
                     builder.append(",protocol=");
321 | 0 |
                     builder.append(protocol);
322 | 0 |
                     builder.append(",port=");
323 | 0 |
                     builder.append(port);
324 | 0 |
                     builder.append(",file=");
325 | 0 |
                     builder.append(file);
326 | 0 |
                     builder.append("]");
327 | 0 |
                     return builder.toString();
328 |  |
             }
329 |  |
330 |  |
     }