001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.pluto.testsuite;
018:
019: import javax.portlet.ActionRequest;
020: import javax.portlet.ActionResponse;
021: import javax.portlet.GenericPortlet;
022: import javax.portlet.PortletException;
023: import javax.portlet.PortletRequest;
024: import javax.portlet.PortletRequestDispatcher;
025: import javax.portlet.PortletSession;
026: import javax.portlet.RenderRequest;
027: import javax.portlet.RenderResponse;
028:
029: import org.apache.commons.logging.Log;
030: import org.apache.commons.logging.LogFactory;
031:
032: import java.io.IOException;
033: import java.io.InputStream;
034: import java.util.HashMap;
035: import java.util.Iterator;
036: import java.util.List;
037: import java.util.Map;
038:
039: /**
040: * Pluto testsuite's test portlet.
041: *
042: * @see TestConfig
043: * @see PortletTest
044: * @version 1.0
045: */
046: public class TestPortlet extends GenericPortlet {
047:
048: /** Internal logger. */
049: private static final Log LOG = LogFactory.getLog(TestPortlet.class);
050:
051: // Private Member Variables ------------------------------------------------
052:
053: /** List of test configurations. */
054: private List testConfigs;
055:
056: /**
057: * Map of test instances: key is an integer ID (as a string), and value is
058: * the <code>PortletTest</code> instances.
059: */
060: private Map tests;
061:
062: // GenericPortlet Impl -----------------------------------------------------
063:
064: /**
065: * Initialize the test portlet. This method reads the testsuite's config
066: * files, constructs and initializes all <code>PortletTest</code> instances.
067: * @throws PortletException if fail to read the configuration file.
068: */
069: public void init() throws PortletException {
070:
071: // Get configuration file name.
072: String configFile = getInitParameter("config");
073: if (configFile == null) {
074: configFile = "/WEB-INF/testsuite-config.xml";
075: }
076:
077: // Get configuration file as an input stream.
078: InputStream is = getPortletContext().getResourceAsStream(
079: configFile);
080: if (is == null) {
081: String message = "Testsuite configuration file not found.";
082: LOG.error(message);
083: throw new PortletException(message);
084: }
085:
086: // Load PortletTest instances: constructing and initializing.
087: TestConfigFactory factory = new TestConfigFactory();
088: try {
089: testConfigs = factory.createTestConfigs(is);
090: tests = new HashMap();
091: int i = 0;
092: for (Iterator it = testConfigs.iterator(); it.hasNext();) {
093: TestConfig testConfig = (TestConfig) it.next();
094: String name = testConfig.getTestClassName();
095: PortletTest test = null;
096: if (name != null) {
097: if (LOG.isDebugEnabled()) {
098: LOG.debug("Loading test: " + name);
099: }
100: Class clazz = Class.forName(testConfig
101: .getTestClassName());
102: test = (PortletTest) clazz.newInstance();
103: } else {
104: if (LOG.isDebugEnabled()) {
105: LOG
106: .debug("Loading NoOpTest (test with no name).");
107: }
108: test = new NoOpTest();
109: }
110: test.init(testConfig);
111: tests.put(String.valueOf(i++), test);
112: }
113: } catch (Throwable th) {
114: String message = "Unable to read testsuite configuration.";
115: LOG.error(message, th);
116: throw new PortletException(message, th);
117: }
118: }
119:
120: public void processAction(ActionRequest request,
121: ActionResponse response) throws PortletException,
122: IOException {
123:
124: String testId = getTestId(request);
125: PortletTest test = (PortletTest) tests.get(testId);
126:
127: // For ActionTest, run test and save results in session.
128: if (test != null && test instanceof ActionTest) {
129: TestResults results = test.doTest(getPortletConfig(),
130: getPortletContext(), request, response);
131: PortletSession session = request.getPortletSession();
132: session.setAttribute(test.getClass().getName(), results);
133: }
134:
135: Map renderParameters = null;
136: if (test != null) {
137: renderParameters = test.getRenderParameters(request);
138: }
139: if (renderParameters == null) {
140: renderParameters = new HashMap();
141: }
142: renderParameters.put("testId", new String[] { testId });
143: response.setRenderParameters(renderParameters);
144: }
145:
146: /**
147: * Serves up the <code>view</code> mode.
148: * TODO: more javadoc.
149: *
150: * @param request the protlet request.
151: * @param response the portlet response.
152: */
153: public void doView(RenderRequest request, RenderResponse response)
154: throws PortletException, IOException {
155:
156: // Get the current test ID, the test instance and its config.
157: String testId = getTestId(request);
158: TestConfig testConfig = null;
159: PortletTest test = null;
160: if (testId != null) {
161: testConfig = (TestConfig) testConfigs.get(Integer
162: .parseInt(testId));
163: test = (PortletTest) tests.get(testId);
164: }
165:
166: // For non-ActionTest, run test and save results in request.
167: if (test != null && !(test instanceof ActionTest)) {
168: TestResults results = test.doTest(getPortletConfig(),
169: getPortletContext(), request, response);
170: request.setAttribute("results", results);
171: }
172: // For ActionTest, retrieve results from session and save in request.
173: else if (test != null) {
174: PortletSession session = request.getPortletSession();
175: TestResults results = (TestResults) session
176: .getAttribute(test.getClass().getName());
177: request.setAttribute("results", results);
178: }
179:
180: if (testId == null) {
181: // FIXME: update attribute name from tests to testConfigs.
182: request.setAttribute("tests", testConfigs);
183: } else {
184: TestConfig nextTestConfig = null;
185: TestConfig prevTestConfig = null;
186: int index = testConfigs.indexOf(test.getConfig());
187: if (index == 0) {
188: prevTestConfig = (TestConfig) testConfigs
189: .get(testConfigs.size() - 1);
190: nextTestConfig = (TestConfig) testConfigs
191: .get(index + 1);
192: } else if (index == testConfigs.size() - 1) {
193: prevTestConfig = (TestConfig) testConfigs
194: .get(index - 1);
195: nextTestConfig = (TestConfig) testConfigs.get(0);
196: } else {
197: prevTestConfig = (TestConfig) testConfigs
198: .get(index - 1);
199: nextTestConfig = (TestConfig) testConfigs
200: .get(index + 1);
201: }
202: request.setAttribute("prevTest", prevTestConfig);
203: request.setAttribute("nextTest", nextTestConfig);
204: }
205:
206: // Set content type for render response, and dispatch to JSP.
207: response.setContentType("text/html");
208: String displayUri = null;
209: if (testConfig != null) {
210: displayUri = testConfig.getDisplayURI();
211: } else {
212: displayUri = "/jsp/introduction.jsp";
213: }
214: PortletRequestDispatcher dispatcher = getPortletContext()
215: .getRequestDispatcher(displayUri);
216: dispatcher.include(request, response);
217: }
218:
219: /**
220: * Serves up the <code>edit</code> mode. This method dispatches the request
221: * and response to the edit JSP page (<code>/jsp/edit.jsp</code>).
222: * @param request the portlet request.
223: * @param response the portlet response.
224: */
225: protected void doEdit(RenderRequest request, RenderResponse response)
226: throws PortletException, IOException {
227: PortletRequestDispatcher dispatcher = getPortletContext()
228: .getRequestDispatcher("/jsp/edit.jsp");
229: dispatcher.include(request, response);
230: }
231:
232: /**
233: * Serves up the <code>help</code> mode. This method dispatches the request
234: * and response to the help JSP page (<code>/jsp/help.jsp</code>).
235: * @param request the portlet request.
236: * @param response the portlet response.
237: */
238: protected void doHelp(RenderRequest request, RenderResponse response)
239: throws PortletException, IOException {
240: PortletRequestDispatcher dispatcher = getPortletContext()
241: .getRequestDispatcher("/jsp/help.jsp");
242: dispatcher.include(request, response);
243: }
244:
245: // Private Methods ---------------------------------------------------------
246:
247: /**
248: * Returns the current test ID.
249: * @param request the portlet request.
250: * @return the current test ID.
251: */
252: private String getTestId(PortletRequest request) {
253:
254: String testId = request.getParameter("testId");
255: String prevTestId = request.getParameter("previousTestId");
256: String nextTestId = request.getParameter("nextTestId");
257:
258: // If none of the parameters are available, return null.
259: if ((testId == null || testId.trim().length() == 0)
260: && nextTestId == null && prevTestId == null
261: && tests.size() > 0) {
262: return null;
263: }
264:
265: // Retrieve the test which is next to the previous test.
266: else if (testId == null && prevTestId != null) {
267: int previousTestIdInt = Integer.parseInt(prevTestId);
268: if (previousTestIdInt >= testConfigs.size() - 1) {
269: testId = "0";
270: } else {
271: testId = String.valueOf(previousTestIdInt + 1);
272: }
273: }
274:
275: // Retrieve the test which is previous to the next test.
276: else if (testId == null && nextTestId != null) {
277: int nextTestIdInt = Integer.parseInt(nextTestId);
278: if (nextTestIdInt <= 0) {
279: testId = String.valueOf(testConfigs.size() - 1);
280: } else {
281: testId = String.valueOf(nextTestIdInt - 1);
282: }
283: }
284:
285: // Return the current test ID.
286: return testId;
287: }
288: }
|