001: /**
002: * @author <a href="mailto:novotny@gridsphere.org">Jason Novotny</a>
003: * @version $Id: PortletLayoutEngine.java 6385 2007-10-25 14:02:26Z wehrens $
004: */package org.gridsphere.layout;
005:
006: import org.apache.commons.logging.Log;
007: import org.apache.commons.logging.LogFactory;
008: import org.gridsphere.portlet.impl.SportletProperties;
009: import org.gridsphere.portletcontainer.GridSphereEvent;
010:
011: import javax.portlet.PortletRequest;
012: import javax.portlet.RenderResponse;
013: import javax.servlet.ServletContext;
014: import javax.servlet.http.HttpServletRequest;
015: import javax.servlet.http.HttpServletResponse;
016: import java.io.IOException;
017: import java.io.PrintWriter;
018: import java.io.UnsupportedEncodingException;
019: import java.security.Principal;
020: import java.util.ArrayList;
021: import java.util.zip.GZIPOutputStream;
022:
023: /**
024: * The <code>PortletLayoutEngine</code> is a singleton that is responsible for managing
025: * user's layouts. It also manages portlet web application default layout
026: * configurations that can be potentially added to a user layout
027: * via the PortletLayout Service.
028: * <p/>
029: * The portlet layout engine is a higher level manager of portlet containers
030: * that represent a users customized layout. The portlet layout engine is used
031: * by the {@link org.gridsphere.servlets.GridSphereServlet}
032: * Expect the PortletLayoutEngine methods to change possibly....
033: */
034: public class PortletLayoutEngine {
035:
036: protected Log log = LogFactory.getLog(PortletLayoutEngine.class);
037: private static PortletLayoutEngine instance = new PortletLayoutEngine();
038:
039: private PortletPageFactory pageFactory = PortletPageFactory
040: .getInstance();
041:
042: private PortletFrameRegistry registry = PortletFrameRegistry
043: .getInstance();
044:
045: private boolean inited = false;
046:
047: public static final String DEFAULT_THEME = "default";
048: public static final String DEFAULT_RENDERKIT = "brush";
049:
050: /**
051: * Constructs a concrete instance of the PortletLayoutEngine
052: */
053: private PortletLayoutEngine() {
054: }
055:
056: public void init(ServletContext ctx) {
057: if (!inited) {
058: pageFactory.init(ctx);
059: inited = true;
060: }
061: }
062:
063: /**
064: * Returns the single instance of the PortletLayoutEngine
065: *
066: * @return the PortletLayoutEngine instance
067: */
068: public static PortletLayoutEngine getInstance() {
069: return instance;
070: }
071:
072: public PortletPage getPortletPage(GridSphereEvent event) {
073:
074: PortletRequest req = event.getRenderRequest();
075:
076: // Check for framework errors
077: Exception portletException = (Exception) req
078: .getAttribute(SportletProperties.ERROR);
079: if (portletException != null) {
080: PortletPage errorPage = pageFactory.createErrorPage();
081: errorPage.init(req, new ArrayList<ComponentIdentifier>());
082: return errorPage;
083: }
084:
085: return pageFactory.getPortletPage(event);
086: }
087:
088: public void setHeaders(GridSphereEvent event) {
089: HttpServletRequest req = event.getHttpServletRequest();
090: HttpServletResponse res = event.getHttpServletResponse();
091: res.setContentType("text/html; charset=utf-8"); // Necessary to display UTF-8 encoded characters
092: res.setHeader("Cache-Control", "no-cache"); //Forces caches to obtain a new copy of the page from the origin server
093: res.setHeader("Cache-Control", "no-store"); //Directs caches not to store the page under any circumstance
094: res.setHeader("Expires", "0"); //Causes the proxy cache to see the page as "stale"
095: res.setHeader("Pragma", "no-cache"); //HTTP 1.0 backward compatibility
096: String ae = req.getHeader("accept-encoding");
097: if (ae != null && ae.indexOf("gzip") != -1) {
098: res.setHeader("Content-Encoding", "gzip");
099: }
100: }
101:
102: /**
103: * Services a portlet container instance by rendering its presentation
104: *
105: * @param event the gridsphere event
106: */
107: public void service(GridSphereEvent event) {
108: HttpServletRequest req = event.getHttpServletRequest();
109: HttpServletResponse res = event.getHttpServletResponse();
110: // set content to UTF-8 for il8n and compression if supported
111: try {
112: req.setCharacterEncoding("utf-8");
113: } catch (UnsupportedEncodingException e) {
114: log.error("UTF-8 is unsupported?!?", e);
115: }
116: PortletPage page = getPortletPage(event);
117: setHeaders(event);
118: StringBuffer pageBuffer = new StringBuffer();
119: if (req.getParameter("ajax") != null) {
120:
121: String portlet = req.getParameter("portlet");
122: System.err.println("it's ajax: " + portlet);
123: String cid = event.getComponentID();
124: if ((cid != null) && (cid.startsWith("portlet"))) {
125: portlet = cid.substring("portlet".length() + 1);
126: }
127: if (portlet != null) {
128: PortletFrameRegistry registry = PortletFrameRegistry
129: .getInstance();
130: int idx = portlet.indexOf("#");
131: String portletName = portlet.substring(idx + 1, portlet
132: .length());
133: PortletFrame frame = registry.getPortletFrame(
134: portletName, portlet, event);
135: frame.setInnerPadding("");
136: frame.setOuterPadding("");
137: frame.setTransparent(false);
138:
139: req.getSession().setAttribute(
140: SportletProperties.LAYOUT_THEME, DEFAULT_THEME);
141: req.getSession().setAttribute(
142: SportletProperties.LAYOUT_RENDERKIT,
143: DEFAULT_RENDERKIT);
144:
145: req.setAttribute(SportletProperties.USE_AJAX, "true");
146: req.setAttribute(SportletProperties.PORTLET_NAME,
147: portlet);
148: String compName = req.getParameter("compname");
149:
150: System.err.println("compname= " + compName);
151:
152: req.setAttribute(SportletProperties.COMPONENT_NAME,
153: compName);
154:
155: if (event.hasAction()) {
156: frame.actionPerformed(event);
157: }
158: frame.doRender(event);
159: pageBuffer = frame.getBufferedOutput(event
160: .getRenderRequest());
161: res.setContentType("text/html");
162: } else {
163: PortletComponent comp = page.getActiveComponent(cid);
164: if (comp != null) {
165: String reqRole = comp.getRequiredRole();
166: Principal user = event.getRenderRequest()
167: .getUserPrincipal();
168: if (user != null) {
169: if (req.isUserInRole(reqRole))
170: comp.doRender(event);
171: } else {
172: if (reqRole.equals(""))
173: comp.doRender(event);
174: }
175: pageBuffer = comp.getBufferedOutput(event
176: .getRenderRequest());
177: res.setContentType("text/html");
178: }
179: }
180: } else {
181: page.doRender(event);
182: pageBuffer = page.getBufferedOutput(event
183: .getRenderRequest());
184: }
185:
186: log.info("\twriting page to output");
187: try {
188: String ae = req.getHeader("accept-encoding");
189: if (ae != null && ae.indexOf("gzip") != -1) {
190: GZIPOutputStream gzos = new GZIPOutputStream(res
191: .getOutputStream());
192: gzos.write(pageBuffer.toString().getBytes(
193: req.getCharacterEncoding()));
194: gzos.close();
195: } else {
196: PrintWriter out = res.getWriter();
197: out.print(pageBuffer.toString());
198: }
199: } catch (IOException e) {
200: // means the writer has already been obtained
201: log.error("Error writing page!", e);
202: }
203: }
204:
205: public void doAction(GridSphereEvent event) {
206: String cid = event.getComponentID();
207: if (!cid.equals("")) {
208: PortletFrame frame = registry.getPortletFrame(cid, null,
209: event);
210: if (frame != null) {
211: try {
212: frame.actionPerformed(event);
213: } catch (Exception e) {
214: e.printStackTrace();
215: }
216: }
217: }
218: }
219:
220: /**
221: * Performs an action on the portlet container referenced by the
222: * gridsphere event
223: *
224: * @param event a gridsphere event
225: */
226: public void actionPerformed(GridSphereEvent event) {
227: log.info("\tstart actionPerformed");
228: PortletPage page = getPortletPage(event);
229:
230: if (!event.getComponentID().equals("")) {
231: page.actionPerformed(event);
232:
233: // sometimes the page needs reinitializing
234: if (event.getActionRequest().getAttribute(
235: SportletProperties.INIT_PAGE) != null) {
236: log
237: .info("\n\n\n\n\nreiniting and saving page!!!!!\n\n\n\n\n\n");
238: page.init(event.getActionRequest(),
239: new ArrayList<ComponentIdentifier>());
240: PortletTabbedPane pane = pageFactory
241: .getUserTabbedPane(event.getActionRequest());
242: if (pane != null) {
243: try {
244: pane.save();
245: } catch (IOException e) {
246: log.error("Unable to save tab pane", e);
247: }
248: }
249: }
250: }
251:
252: log.info("\tend actionPerformed");
253: }
254:
255: public void doRenderError(RenderResponse res, Throwable t) {
256: PrintWriter out = null;
257: try {
258: out = res.getWriter();
259: } catch (IOException e) {
260: log.error("in doRenderError: ", e);
261: }
262: out.println("<html><body>");
263: out.println("<b>An error occurred: " + t.getMessage() + "</b>");
264: t.printStackTrace(out);
265: out.println("</body></html>");
266: }
267:
268: }
|