blob: bac913abece52761011f0a8a3397fe95301ff096 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.pluto.testsuite;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.EventRequest;
import javax.portlet.EventResponse;
import javax.portlet.GenericPortlet;
import javax.portlet.PortletException;
import javax.portlet.PortletMode;
import javax.portlet.PortletRequest;
import javax.portlet.PortletRequestDispatcher;
import javax.portlet.PortletSession;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
import javax.portlet.ResourceRequest;
import javax.portlet.ResourceResponse;
import javax.portlet.StateAwareResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Pluto testsuite's test portlet.
*
* @see TestConfig
* @see PortletTest
* @version 1.0
*/
public class TestPortlet extends GenericPortlet {
/** Internal logger. */
private static final Log LOG = LogFactory.getLog(TestPortlet.class);
// Private Member Variables ------------------------------------------------
/** List of test configurations. */
private List<TestConfig> testConfigs;
/**
* Map of test instances: key is an integer ID (as a string), and value is
* the <code>PortletTest</code> instances.
*/
private Map<String, PortletTest> tests;
// GenericPortlet Impl -----------------------------------------------------
/**
* Initialize the test portlet. This method reads the testsuite's config
* files, constructs and initializes all <code>PortletTest</code> instances.
* @throws PortletException if fail to read the configuration file.
*/
@SuppressWarnings("unchecked")
public void init() throws PortletException {
// Get configuration file name.
String configFile = getInitParameter("config");
if (configFile == null) {
configFile = "/WEB-INF/testsuite-config.xml";
}
// Get configuration file as an input stream.
InputStream is = getPortletContext().getResourceAsStream(configFile);
if (is == null) {
String message = "Testsuite configuration file not found.";
LOG.error(message);
throw new PortletException(message);
}
// Load PortletTest instances: constructing and initializing.
TestConfigFactory factory = new TestConfigFactory();
try {
testConfigs = factory.createTestConfigs(is);
tests = new HashMap<String, PortletTest>();
int i = 0;
for (TestConfig testConfig : testConfigs) {
String name = testConfig.getTestClassName();
PortletTest test = null;
if (name != null) {
if (LOG.isDebugEnabled()) {
LOG.debug("Loading test: " + name);
}
Class<PortletTest> clazz = (Class<PortletTest>)
Class.forName(testConfig.getTestClassName());
test = clazz.newInstance();
} else {
if (LOG.isDebugEnabled()) {
LOG.debug("Loading NoOpTest (test with no name).");
}
test = new NoOpTest();
}
test.init(testConfig);
tests.put(String.valueOf(i++), test);
}
} catch (Throwable th) {
String message = "Unable to read testsuite configuration.";
LOG.error(message, th);
throw new PortletException(message, th);
}
}
public void processAction(ActionRequest request, ActionResponse response)
throws PortletException, IOException {
this.processStateAwarePhase(request, response);
}
protected void doHeaders(RenderRequest request, RenderResponse response) {
if (PortletMode.VIEW.equals(request.getPortletMode())) {
String testId = getTestId(request);
PortletTest test = (PortletTest) tests.get(testId);
if (test != null)
test.doHeaders( getPortletConfig(),
getPortletContext(),
request,
response);
}
}
private void processStateAwarePhase(
PortletRequest request, StateAwareResponse response) {
String testId = getTestId(request);
PortletTest test = (PortletTest) tests.get(testId);
if (test != null) {
TestResults results = test.doTest(getPortletConfig(),
getPortletContext(),
request,
response);
PortletSession session = request.getPortletSession();
TestResults existingResults = (TestResults)
session.getAttribute(test.getClass().getName());
if (existingResults != null) {
existingResults.getCollection().addAll(results.getCollection());
} else {
session.setAttribute(test.getClass().getName(), results);
}
}
Map<String, String[]> renderParameters = null;
if (test != null) {
renderParameters = test.getRenderParameters(request);
}
if (renderParameters == null) {
renderParameters = new HashMap<String, String[]>();
}
renderParameters.put("testId", new String[] { testId });
response.setRenderParameters(renderParameters);
}
public void processEvent(EventRequest request, EventResponse response)
throws PortletException, IOException {
this.processStateAwarePhase(request, response);
}
public void serveResource(ResourceRequest arg0, ResourceResponse arg1)
throws PortletException, IOException {
// TODO: Add resource serving support
super.serveResource(arg0, arg1);
}
/**
* Serves up the <code>view</code> mode.
* TODO: more javadoc.
*
* @param request the protlet request.
* @param response the portlet response.
*/
public void doView(RenderRequest request, RenderResponse response)
throws PortletException, IOException {
// Get the current test ID, the test instance and its config.
String testId = getTestId(request);
TestConfig testConfig = null;
PortletTest test = null;
if (testId != null) {
testConfig = (TestConfig) testConfigs.get(Integer.parseInt(testId));
test = (PortletTest) tests.get(testId);
}
if (LOG.isDebugEnabled()) {
for (Entry<String, String[]> e : request.getParameterMap().entrySet()) {
LOG.debug(e.getKey() + " => " + Arrays.asList(e.getValue()));
}
LOG.debug("Test ID: " + testId);
LOG.debug("Test Config: " + testConfig);
if (testConfig != null) {
LOG.debug("Test config view: " + testConfig.getDisplayURI());
}
}
// For non-ActionTest, run test and save results in request.
if (test != null) {
TestResults results = test.doTest(getPortletConfig(),
getPortletContext(),
request,
response);
PortletSession session = request.getPortletSession();
TestResults existing = (TestResults) session.getAttribute(
test.getClass().getName());
if (existing != null) {
existing.getCollection().addAll(results.getCollection());
request.setAttribute("results", existing);
session.setAttribute(test.getClass().getName(), null);
} else {
request.setAttribute("results", results);
}
}
if (testId == null) {
request.setAttribute("testConfigs", testConfigs);
} else {
TestConfig nextTestConfig = null;
TestConfig prevTestConfig = null;
int index = testConfigs.indexOf(test.getConfig());
if (index == 0) {
prevTestConfig = (TestConfig) testConfigs.get(testConfigs.size() - 1);
nextTestConfig = (TestConfig) testConfigs.get(index + 1);
} else if (index == testConfigs.size() - 1) {
prevTestConfig = (TestConfig) testConfigs.get(index - 1);
nextTestConfig = (TestConfig) testConfigs.get(0);
} else {
prevTestConfig = (TestConfig) testConfigs.get(index - 1);
nextTestConfig = (TestConfig) testConfigs.get(index + 1);
}
request.setAttribute("prevTest", prevTestConfig);
request.setAttribute("nextTest", nextTestConfig);
}
// Set content type for render response, and dispatch to JSP.
response.setContentType("text/html");
String displayUri = null;
if (testConfig != null) {
displayUri = testConfig.getDisplayURI();
} else {
displayUri = "/jsp/introduction.jsp";
}
LOG.debug("Display URI: " + displayUri);
PortletRequestDispatcher dispatcher = getPortletContext()
.getRequestDispatcher(displayUri);
LOG.debug("request dispatcher: " + dispatcher);
dispatcher.include(request, response);
}
/**
* Serves up the <code>edit</code> mode. This method dispatches the request
* and response to the edit JSP page (<code>/jsp/edit.jsp</code>).
* @param request the portlet request.
* @param response the portlet response.
*/
protected void doEdit(RenderRequest request, RenderResponse response)
throws PortletException, IOException {
response.setContentType("text/html");
PortletRequestDispatcher dispatcher = getPortletContext()
.getRequestDispatcher("/jsp/edit.jsp");
dispatcher.include(request, response);
}
/**
* Serves up the <code>help</code> mode. This method dispatches the request
* and response to the help JSP page (<code>/jsp/help.jsp</code>).
* @param request the portlet request.
* @param response the portlet response.
*/
protected void doHelp(RenderRequest request, RenderResponse response)
throws PortletException, IOException {
response.setContentType("text/html");
PortletRequestDispatcher dispatcher = getPortletContext()
.getRequestDispatcher("/jsp/help.jsp");
dispatcher.include(request, response);
}
// Private Methods ---------------------------------------------------------
/**
* Returns the current test ID.
* @param request the portlet request.
* @return the current test ID.
*/
private String getTestId(PortletRequest request) {
String testId = request.getParameter("testId");
String prevTestId = request.getParameter("previousTestId");
String nextTestId = request.getParameter("nextTestId");
// If none of the parameters are available, return null.
if ((testId == null || testId.trim().length() == 0)
&& nextTestId == null && prevTestId == null
&& tests.size() > 0) {
return null;
}
// Retrieve the test which is next to the previous test.
else if (testId == null && prevTestId != null) {
int previousTestIdInt = Integer.parseInt(prevTestId);
if (previousTestIdInt >= testConfigs.size() - 1) {
testId = "0";
} else {
testId = String.valueOf(previousTestIdInt + 1);
}
}
// Retrieve the test which is previous to the next test.
else if (testId == null && nextTestId != null) {
int nextTestIdInt = Integer.parseInt(nextTestId);
if (nextTestIdInt <= 0) {
testId = String.valueOf(testConfigs.size()-1);
} else {
testId = String.valueOf(nextTestIdInt - 1);
}
}
// Return the current test ID.
return testId;
}
}