View Javadoc

1   /*
2    * $Id$
3    *
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *  http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  package org.apache.struts2;
22  
23  import com.opensymphony.xwork2.ActionContext;
24  import com.opensymphony.xwork2.conversion.impl.XWorkConverter;
25  import com.opensymphony.xwork2.inject.Container;
26  import com.opensymphony.xwork2.util.ValueStack;
27  import com.opensymphony.xwork2.util.finder.ClassLoaderInterface;
28  import com.opensymphony.xwork2.util.finder.ClassLoaderInterfaceDelegate;
29  import junit.framework.TestCase;
30  import org.apache.commons.lang.xwork.StringUtils;
31  import org.easymock.EasyMock;
32  import org.easymock.IAnswer;
33  import org.springframework.mock.web.MockHttpServletResponse;
34  import org.springframework.mock.web.MockServletContext;
35  
36  import javax.servlet.Servlet;
37  import javax.servlet.http.HttpServletRequest;
38  import javax.servlet.http.HttpSession;
39  import java.io.InputStream;
40  import java.util.ArrayList;
41  import java.util.HashMap;
42  import java.util.List;
43  import java.util.Map;
44  import java.util.concurrent.BrokenBarrierException;
45  import java.util.concurrent.CyclicBarrier;
46  
47  public class EmbeddedJSPResultTest extends TestCase {
48      private HttpServletRequest request;
49      private MockHttpServletResponse response;
50      private MockServletContext context;
51      private EmbeddedJSPResult result;
52  
53      public void testScriptlet() throws Exception {
54          result.setLocation("org/apache/struts2/scriptlet.jsp");
55          result.execute(null);
56  
57          assertEquals("Saynotoscriptlets", StringUtils.deleteWhitespace(response.getContentAsString()));
58      }
59  
60      public void testEmbedded() throws Exception {
61          //the jsp is inside jsps.jar
62          result.setLocation("dir/all.jsp");
63          result.execute(null);
64  
65          assertEquals("helloJGWhoamI?XXXXXXXXXXXYThissessionisnotsecure.", StringUtils.deleteWhitespace(response.getContentAsString()));
66      }
67  
68      public void testFilesAreReadOnlyOnce() throws Exception {
69          //make sure that files are not read multiple times
70          String jsp = "org/apache/struts2/dont-use.jsp";
71  
72          CountingClassLoaderInterface classLoaderInterface = new CountingClassLoaderInterface(this.getClass().getClassLoader());
73          context.setAttribute(ClassLoaderInterface.CLASS_LOADER_INTERFACE, classLoaderInterface);
74          result.setLocation(jsp);
75  
76          result.execute(null);
77          Integer counter0 = classLoaderInterface.counters.get(jsp);
78          assertNotNull(counter0);
79  
80          result.execute(null);
81          Integer counter1 = classLoaderInterface.counters.get(jsp);
82          assertNotNull(counter1);
83  
84          assertEquals(counter0, counter1);
85      }
86  
87      public void testEmbeddedAbsolutePath() throws Exception {
88          //the jsp is inside jsps.jar
89          result.setLocation("/dir/all.jsp");
90          result.execute(null);
91  
92          assertEquals("helloJGWhoamI?XXXXXXXXXXXYThissessionisnotsecure.", StringUtils.deleteWhitespace(response.getContentAsString()));
93      }
94  
95      public void testSimple() throws Exception {
96          result.setLocation("org/apache/struts2/simple0.jsp");
97          result.execute(null);
98  
99          assertEquals("hello", response.getContentAsString());
100     }
101 
102     public void testEL() throws Exception {
103         result.setLocation("org/apache/struts2/el.jsp");
104         result.execute(null);
105 
106         assertEquals("somethingelseText", response.getContentAsString());
107     }
108 
109     public void tesAbsolutePatht() throws Exception {
110         result.setLocation("/org/apache/struts2/simple0.jsp");
111         result.execute(null);
112 
113         assertEquals("hello", response.getContentAsString());
114     }
115 
116     public void testTag0() throws Exception {
117         result.setLocation("org/apache/struts2/tag0.jsp");
118         result.execute(null);
119 
120         assertEquals("Thissessionisnotsecure.OtherText", StringUtils.deleteWhitespace(response.getContentAsString()));
121     }
122 
123     public void testIncludeSimple() throws Exception {
124         result.setLocation("org/apache/struts2/includes0.jsp");
125         result.execute(null);
126 
127         assertEquals("helloTest", StringUtils.deleteWhitespace(response.getContentAsString()));
128     }
129 
130     public void testIncludeSimpleWithDirective() throws Exception {
131         result.setLocation("org/apache/struts2/includes3.jsp");
132         result.execute(null);
133 
134         assertEquals("helloTest", StringUtils.deleteWhitespace(response.getContentAsString()));
135     }
136 
137     public void testIncludeWithSubdir() throws Exception {
138         result.setLocation("org/apache/struts2/includes1.jsp");
139         result.execute(null);
140 
141         assertEquals("subTest", StringUtils.deleteWhitespace(response.getContentAsString()));
142     }
143 
144     public void testIncludeWithParam() throws Exception {
145         result.setLocation("org/apache/struts2/includes2.jsp");
146         result.execute(null);
147 
148         assertEquals("JGTest", StringUtils.deleteWhitespace(response.getContentAsString()));
149     }
150 
151     public void testBroken0() throws Exception {
152         try {
153             result.setLocation("org/apache/struts2/broken0.jsp");
154             result.execute(null);
155             fail("should have failed with broken jsp");
156         } catch (IllegalStateException ex) {
157             //ok
158         }
159     }
160 
161     public void testJSTL() throws Exception {
162         result.setLocation("org/apache/struts2/jstl.jsp");
163         result.execute(null);
164 
165         assertEquals("XXXXXXXXXXXY", StringUtils.deleteWhitespace(response.getContentAsString()));
166     }
167 
168 
169     public void testCachedInstances() throws InterruptedException {
170         ServletCache cache = new ServletCache();
171         Servlet servlet1 = cache.get("org/apache/struts2/simple0.jsp");
172         Servlet servlet2 = cache.get("org/apache/struts2/simple0.jsp");
173 
174         assertSame(servlet1, servlet2);
175     }
176 
177     public void testCacheInstanceWithManyThreads() throws BrokenBarrierException, InterruptedException {
178         //start a bunch of thread at the same time using CyclicBarrier and hit the cache
179         //then wait for all the threads to end and check that they all got a reference to the same object
180         //and the cache size should be 1
181 
182         DummyServletCache cache = new DummyServletCache();
183         int numThreads = 70;
184 
185         CyclicBarrier startBarrier = new CyclicBarrier(numThreads + 1);
186         CyclicBarrier endBarrier = new CyclicBarrier(numThreads + 1);
187 
188         List<ServletGetRunnable> runnables = new ArrayList<ServletGetRunnable>(numThreads);
189 
190         //create the threads
191         for (int i = 0; i < numThreads; i++) {
192             ServletGetRunnable runnable = new ServletGetRunnable(cache, startBarrier, endBarrier, ActionContext.getContext());
193             Thread thread = new Thread(runnable);
194             runnables.add(runnable);
195             thread.start();
196         }
197 
198         startBarrier.await();
199         endBarrier.await();
200         Object servlet = cache.get("org/apache/struts2/simple0.jsp");
201         assertEquals(1, cache.size());
202 
203         for (ServletGetRunnable runnable : runnables) {
204             assertSame(servlet, runnable.getObject());
205         }
206     }
207 
208     public void testBeans() throws Exception {
209         result.setLocation("org/apache/struts2/beans.jsp");
210         result.execute(null);
211 
212         assertEquals("WhoamI?", StringUtils.deleteWhitespace(response.getContentAsString()));
213     }
214 
215     @Override
216     protected void setUp() throws Exception {
217         super.setUp();
218 
219         result = new EmbeddedJSPResult();
220 
221         request = EasyMock.createNiceMock(HttpServletRequest.class);
222         response = new MockHttpServletResponse();
223         context = new MockServletContext();
224 
225         final Map params = new HashMap();
226 
227         HttpSession session = EasyMock.createNiceMock(HttpSession.class);
228         EasyMock.replay(session);
229 
230         EasyMock.expect(request.getSession()).andReturn(session).anyTimes();
231         EasyMock.expect(request.getParameterMap()).andReturn(params).anyTimes();
232         EasyMock.expect(request.getParameter("username")).andAnswer(new IAnswer<String>() {
233             public String answer() throws Throwable {
234                 return ((String[]) params.get("username"))[0];
235             }
236         });
237         EasyMock.expect(request.getAttribute("something")).andReturn("somethingelse").anyTimes();
238 
239         EasyMock.replay(request);
240 
241         ActionContext actionContext = new ActionContext(new HashMap<String, Object>());
242         ActionContext.setContext(actionContext);
243         actionContext.setParameters(params);
244         ServletActionContext.setRequest(request);
245         ServletActionContext.setResponse(response);
246         ServletActionContext.setServletContext(context);
247 
248         //mock value stack
249         Map stackContext = new HashMap();
250         ValueStack valueStack = EasyMock.createNiceMock(ValueStack.class);
251         EasyMock.expect(valueStack.getContext()).andReturn(stackContext).anyTimes();
252         EasyMock.replay(valueStack);
253 
254         //mock converter
255         XWorkConverter converter = new DummyConverter();
256 
257         //mock container
258         Container container = EasyMock.createNiceMock(Container.class);
259         EasyMock.expect(container.getInstance(XWorkConverter.class)).andReturn(converter).anyTimes();
260         EasyMock.replay(container);
261         stackContext.put(ActionContext.CONTAINER, container);
262         actionContext.setContainer(container);
263 
264         actionContext.setValueStack(valueStack);
265     }
266 }
267 
268 //converter has a protected default constructor...meh
269 class DummyConverter extends XWorkConverter {
270 
271 }
272 
273 class DummyServletCache extends ServletCache {
274     public int size() {
275         return cache.size();
276     }
277 }
278 
279 class ServletGetRunnable implements Runnable {
280     private ServletCache servletCache;
281     private Object object;
282     private CyclicBarrier startBarrier;
283     private ActionContext actionContext;
284     private CyclicBarrier endBarrier;
285 
286     ServletGetRunnable(ServletCache servletCache, CyclicBarrier startBarrier, CyclicBarrier endBarrier, ActionContext actionContext) {
287         this.servletCache = servletCache;
288         this.startBarrier = startBarrier;
289         this.endBarrier = endBarrier;
290         this.actionContext = actionContext;
291     }
292 
293     public void run() {
294         ActionContext.setContext(actionContext);
295         //wait to start all therads at once..or try at least
296         try {
297             startBarrier.await();
298             object = servletCache.get("org/apache/struts2/simple0.jsp");
299 
300             for (int i = 0; i < 10; i++) {
301                 Object object2 = servletCache.get("org/apache/struts2/simple0.jsp");
302                 if (object2 != object)
303                     throw new RuntimeException("got different object from cache");
304             }
305 
306             endBarrier.await();
307         } catch (Exception e) {
308             throw new RuntimeException(e);
309         }
310     }
311 
312     public Object getObject() {
313         return object;
314     }
315 }
316 
317 class CountingClassLoaderInterface extends ClassLoaderInterfaceDelegate {
318     public Map<String, Integer> counters = new HashMap<String, Integer>();
319 
320     public CountingClassLoaderInterface(ClassLoader classLoader) {
321         super(classLoader);
322     }
323 
324     @Override
325     public InputStream getResourceAsStream(String name) {
326         Integer counter = counters.get(name);
327         counter = counter == null ? 1 : counter + 1;
328         counters.put(name, counter);
329 
330         return super.getResourceAsStream(name);
331     }
332 }