1 package com.atlassian.servlet;
2
3 import java.io.IOException;
4 import java.util.Collection;
5 import java.util.Enumeration;
6 import java.util.HashMap;
7 import java.util.Iterator;
8 import java.util.Set;
9 import java.util.TreeSet;
10
11 import javax.servlet.ServletConfig;
12 import javax.servlet.ServletException;
13 import javax.servlet.http.HttpServlet;
14 import javax.servlet.http.HttpServletRequest;
15 import javax.servlet.http.HttpServletResponse;
16
17 import org.apache.commons.collections.MultiHashMap;
18 import org.apache.commons.collections.MultiMap;
19 import org.apache.log4j.Category;
20
21 import com.atlassian.cache.servlet.handler.CacheExpirationHandler;
22 import com.atlassian.cache.servlet.resolver.ContentResolver;
23
24
25
26
27
28
29
30
31
32
33 public class CombinedServlet extends HttpServlet {
34
35
36 private static final long serialVersionUID = 1L;
37
38 public static final String DEFAULT_ENCODING = "UTF-8";
39
40 private static final String DEFAULT_CONTENT_TYPE = "text/javascript";
41
42 private static final String CONTENT_RESOLVER_PREFIX = "content.resolver";
43
44 protected final Category log = Category.getInstance(getClass());
45
46 private String data = null;
47
48 private CacheExpirationHandler cacheExpirationHandler;
49
50 private String contentType;
51
52 private HashMap contentResolvers;
53
54 private MultiMap contentByResolver;
55
56 public synchronized void init(ServletConfig servletConfig) throws ServletException {
57 super.init(servletConfig);
58
59
60 initializeContentType(servletConfig.getInitParameter("content.type"));
61 initializeContentResolvers(servletConfig);
62 initializeContentParams();
63 }
64
65 protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
66
67 response.setContentType(contentType);
68
69
70
71
72
73
74 response.getWriter().write(getDataToSend(request, response));
75 response.getWriter().flush();
76 }
77
78 protected String getDataToSend(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
79
80 return makeData(request, response);
81
82
83 }
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103 protected String makeData(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
104 try {
105 StringBuffer buffer = new StringBuffer();
106
107
108 for (Iterator iterator = contentResolvers.keySet().iterator(); iterator.hasNext();) {
109 String resolverKey = (String) iterator.next();
110
111 if (contentByResolver.containsKey(resolverKey)) {
112
113 for (Iterator iterator1 = ((Collection) contentByResolver.get(resolverKey)).iterator(); iterator1.hasNext();) {
114 String path = (String) iterator1.next();
115 ContentResolver resolver = (ContentResolver) contentResolvers.get(resolverKey);
116 buffer.append(resolver.getContent(path, request, response));
117 }
118 }
119 }
120 return buffer.toString();
121 } catch (IOException e) {
122 log.error("Error building combined cached servlet data: " + request.getRequestURI() + " - " + e.toString(), e);
123 throw e;
124 } catch (ServletException e) {
125 log.error("Error building combined cached servlet data: " + request.getRequestURI() + " - " + e.toString(), e);
126 throw e;
127 }
128 }
129
130
131
132
133
134
135
136
137 private void initializeContentParams() {
138 contentByResolver = new MultiHashMap();
139
140 Enumeration e = getInitParameterNames();
141 Set sortedNames = new TreeSet();
142 while (e.hasMoreElements()) {
143 sortedNames.add(e.nextElement());
144 }
145
146 for (Iterator iterator = contentResolvers.keySet().iterator(); iterator.hasNext();) {
147 String resolverKey = (String) iterator.next();
148
149 for (Iterator i = sortedNames.iterator(); i.hasNext();) {
150 String name = (String) i.next();
151 if (name.startsWith(resolverKey)) {
152
153 contentByResolver.put(resolverKey, getInitParameter(name));
154 }
155 }
156
157 }
158 }
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173 private void initializeContentResolvers(ServletConfig config) throws ServletException {
174 contentResolvers = new HashMap();
175
176 for (Enumeration e = getInitParameterNames(); e.hasMoreElements();) {
177 String name = (String) e.nextElement();
178 if (name.startsWith(CONTENT_RESOLVER_PREFIX)) {
179 Object objResolver = getObjectForClass(getInitParameter(name));
180 if (objResolver != null && objResolver instanceof ContentResolver) {
181 ContentResolver resolver = (ContentResolver) objResolver;
182
183 resolver.init(config);
184
185
186 String key = name.substring(CONTENT_RESOLVER_PREFIX.length() + 1);
187 contentResolvers.put(key, resolver);
188 } else {
189 log.warn("The class " + getInitParameter(name) + " does not implement ContentResolver.");
190 }
191 }
192 }
193 }
194
195 private void initializeContentType(String initParameter) {
196 if (initParameter == null) {
197 contentType = DEFAULT_CONTENT_TYPE;
198 } else {
199 contentType = initParameter;
200 }
201 }
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216 private Object getObjectForClass(String clazz) {
217 Object obj = null;
218 try {
219 if (clazz != null) {
220 obj = Class.forName(clazz).newInstance();
221 }
222 } catch (Exception e) {
223 log.warn("Unable to resolve class for className: " + clazz);
224 }
225 return obj;
226 }
227 }