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