1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.apache.struts2.rest;
23
24 import javax.servlet.http.HttpServletRequest;
25 import javax.servlet.http.HttpServletResponse;
26 import static javax.servlet.http.HttpServletResponse.*;
27 import java.util.Date;
28
29 /***
30 * Default implementation of rest info that uses fluent-style construction
31 */
32 public class DefaultHttpHeaders implements HttpHeaders {
33 String resultCode;
34 int status = SC_OK;
35 Object etag;
36 Object locationId;
37 String location;
38 boolean disableCaching;
39 boolean noETag = false;
40 Date lastModified;
41
42 public DefaultHttpHeaders() {}
43
44 public DefaultHttpHeaders(String result) {
45 resultCode = result;
46 }
47
48 public DefaultHttpHeaders renderResult(String code) {
49 this.resultCode = code;
50 return this;
51 }
52
53 public DefaultHttpHeaders withStatus(int code) {
54 this.status = code;
55 return this;
56 }
57
58 public DefaultHttpHeaders withETag(Object etag) {
59 this.etag = etag;
60 return this;
61 }
62
63 public DefaultHttpHeaders withNoETag() {
64 this.noETag = true;
65 return this;
66 }
67
68 public DefaultHttpHeaders setLocationId(Object id) {
69 this.locationId = id;
70 return this;
71 }
72
73 public DefaultHttpHeaders setLocation(String loc) {
74 this.location = loc;
75 return this;
76 }
77
78 public DefaultHttpHeaders lastModified(Date date) {
79 this.lastModified = date;
80 return this;
81 }
82
83 public DefaultHttpHeaders disableCaching() {
84 this.disableCaching = true;
85 return this;
86 }
87
88
89
90
91 public String apply(HttpServletRequest request, HttpServletResponse response, Object target) {
92
93 if (disableCaching) {
94 response.setHeader("Cache-Control", "no-cache");
95 }
96 if (lastModified != null) {
97 response.setDateHeader("Last-Modified", lastModified.getTime());
98 }
99 if (etag == null && !noETag && target != null) {
100 etag = String.valueOf(target.hashCode());
101 }
102 if (etag != null) {
103 response.setHeader("ETag", etag.toString());
104 }
105
106 if (locationId != null) {
107 String url = request.getRequestURL().toString();
108 int lastSlash = url.lastIndexOf("/");
109 int lastDot = url.lastIndexOf(".");
110 if (lastDot > lastSlash && lastDot > -1) {
111 url = url.substring(0, lastDot)+"/"+locationId+url.substring(lastDot);
112 } else {
113 url += "/"+locationId;
114 }
115 response.setHeader("Location", url);
116 status = SC_CREATED;
117 } else if (location != null) {
118 response.setHeader("Location", location);
119 status = SC_CREATED;
120 }
121
122 if (status == SC_OK && !disableCaching) {
123 boolean etagNotChanged = false;
124 boolean lastModifiedNotChanged = false;
125 String reqETag = request.getHeader("If-None-Match");
126 if (etag != null) {
127 if (etag.equals(reqETag)) {
128 etagNotChanged = true;
129 }
130 }
131
132 String reqLastModified = request.getHeader("If-Modified-Since");
133 if (lastModified != null) {
134 if (String.valueOf(lastModified.getTime()).equals(reqLastModified)) {
135 lastModifiedNotChanged = true;
136 }
137
138 }
139
140 if ((etagNotChanged && lastModifiedNotChanged) ||
141 (etagNotChanged && reqLastModified == null) ||
142 (lastModifiedNotChanged && reqETag == null)) {
143 status = SC_NOT_MODIFIED;
144 }
145 }
146
147 response.setStatus(status);
148 return resultCode;
149 }
150
151 public int getStatus() {
152 return status;
153 }
154
155
156
157
158 }