/* 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.portals.samples; | |
import java.io.IOException; | |
import java.io.PrintWriter; | |
import java.util.ArrayList; | |
import java.util.logging.Logger; | |
import javax.inject.Inject; | |
import javax.portlet.PortletException; | |
import javax.portlet.ResourceRequest; | |
import javax.portlet.ResourceResponse; | |
import javax.portlet.ResourceURL; | |
import javax.portlet.annotations.Namespace; | |
import javax.portlet.annotations.RenderMethod; | |
import javax.portlet.annotations.ServeResourceMethod; | |
import javax.portlet.annotations.URLFactory; | |
import javax.servlet.AsyncContext; | |
import javax.servlet.http.HttpServletRequest; | |
import javax.servlet.http.HttpServletResponse; | |
/** | |
* Resource portlet for viewing path information. | |
*/ | |
public class AsyncHackPortlet { | |
private static final Logger LOGGER = Logger.getLogger(AsyncHackPortlet.class.getName()); | |
public static final String RESPARAM_DISPLAY = "display"; | |
private AsyncContext context; | |
private static final String jsp = "/WEB-INF/jsp/pathinfo.jsp"; | |
// private static final String jsp = "/ais"; | |
private class AsyncHackRunnable implements Runnable { | |
@Override | |
public void run() { | |
try { | |
Thread.sleep(1000); | |
} catch (InterruptedException e) {} | |
LOGGER.fine("Slept, now dispatching."); | |
HttpServletRequest hreq = (HttpServletRequest) context.getRequest(); | |
context.dispatch(hreq.getServletContext(), jsp); | |
// context.dispatch(jsp); | |
} | |
} | |
// Injecting the namespace & URLFactory | |
@Inject | |
@Namespace | |
private String pid; | |
@Inject | |
private URLFactory uf; | |
@RenderMethod(portletNames = { "AsyncHackPortlet" }, ordinal = 100) | |
public String getImageInclude() { | |
LOGGER.fine("Rendering async hack portlet"); | |
StringBuilder txt = new StringBuilder(128); | |
txt.append("<h3>Async Hack Portlet</h3>"); | |
ResourceURL resurl = uf.createResourceURL(); | |
txt.append("<div class='infobox' id='").append(pid).append("-putResourceHere'></div>\n"); | |
txt.append("<script>\n"); | |
txt.append("(function () {\n"); | |
txt.append(" var xhr = new XMLHttpRequest();\n"); | |
txt.append(" xhr.onreadystatechange=function() {\n"); | |
txt.append(" if (xhr.readyState==4 && xhr.status==200) {\n"); | |
txt.append(" document.getElementById('").append(pid) | |
.append("-putResourceHere').innerHTML=xhr.responseText;\n"); | |
txt.append(" }\n"); | |
txt.append(" };\n"); | |
txt.append(" xhr.open(\"GET\",\"").append(resurl.toString()).append("\",true);\n"); | |
txt.append(" xhr.send();\n"); | |
txt.append("})();\n"); | |
txt.append("</script>\n"); | |
return txt.toString(); | |
} | |
/** | |
* This resource method generates some output directly, then includes output from a JSP as specified in the | |
* annotation. | |
* | |
* @return The string for inclusion in the output. | |
* @throws IOException | |
* @throws PortletException | |
*/ | |
@ServeResourceMethod(portletNames = { "AsyncHackPortlet" }, asyncSupported = true) | |
public void getPathInfo(ResourceRequest req, ResourceResponse resp) throws IOException, PortletException { | |
LOGGER.fine("Doing async hack resource request"); | |
@SuppressWarnings("unchecked") | |
ArrayList<String> pathInfo = (ArrayList<String>) req.getAttribute("pathInfo"); | |
if (pathInfo == null) { | |
pathInfo = new ArrayList<String>(); | |
} | |
HttpServletRequest hreq = (HttpServletRequest) req.getAttribute("javax.portlet.debug.ServletRequest"); | |
HttpServletResponse hresp = (HttpServletResponse) req.getAttribute("javax.portlet.debug.ServletResponse"); | |
PathDisplay pd; | |
if (hreq != null) { | |
pd = new PathDisplay(hreq, "Resource Method (Servlet)"); | |
hreq.setAttribute("pathInfo", pathInfo); | |
} else { | |
pd = new PathDisplay(req, "Resource Method (Resource)"); | |
req.setAttribute("pathInfo", pathInfo); | |
} | |
pathInfo.add(pd.toMarkup()); | |
PrintWriter writer = resp.getWriter(); | |
writer.append("<h5>Async Hack Resource Request</h5>"); | |
StringBuilder txt = new StringBuilder(128); | |
txt.append("Trying to start async. Servlet context: ").append(hreq.getServletContext().getContextPath()); | |
// RequestDispatcher rd = null; | |
// rd = hreq.getRequestDispatcher(jsp); | |
// txt.append("Request dispatcher: ").append(rd); | |
LOGGER.fine(txt.toString()); | |
txt.setLength(0); | |
if (hreq != null && hresp != null) { | |
try { | |
context = hreq.startAsync(hreq, hresp); | |
context.setTimeout(4000); | |
txt.append("Async context: ").append((context == null) ? "null." : "not null."); | |
txt.append(" Now starting thread ... "); | |
AsyncHackRunnable ahr = new AsyncHackRunnable(); | |
context.start(ahr); | |
txt.append(" done. "); | |
} catch (Exception e) { | |
txt.append(" ... didn't work. Exception: ").append(e.toString()); | |
} | |
LOGGER.fine(txt.toString()); | |
txt.setLength(0); | |
} | |
} | |
} |