Java tutorial
/* * Copyright 2011 Vaadin Ltd. * * Licensed 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 com.vaadin.terminal.gwt.server; import java.io.IOException; import java.io.OutputStream; import java.io.PrintWriter; import java.io.Serializable; import java.util.logging.Level; import java.util.logging.Logger; import javax.portlet.ActionRequest; import javax.portlet.ActionResponse; import javax.portlet.PortalContext; import javax.portlet.Portlet; import javax.portlet.PortletConfig; import javax.portlet.PortletException; import javax.portlet.PortletRequestDispatcher; import javax.portlet.PortletSession; import javax.portlet.RenderRequest; import javax.portlet.RenderResponse; import com.liferay.portal.kernel.util.PropsUtil; import com.vaadin.Application; /** * Portlet main class for Portlet 1.0 (JSR-168) portlets which consist of a * portlet and a servlet. For Portlet 2.0 (JSR-286, no servlet required), use * {@link ApplicationPortlet2} instead. */ @SuppressWarnings("serial") public class ApplicationPortlet implements Portlet, Serializable { // portlet configuration parameters private static final String PORTLET_PARAMETER_APPLICATION = "application"; private static final String PORTLET_PARAMETER_STYLE = "style"; private static final String PORTLET_PARAMETER_WIDGETSET = "widgetset"; // The application to show protected String app = null; // some applications might require forced height (and, more seldom, width) protected String style = null; // e.g "height:500px;" // force the portlet to use this widgetset - portlet level setting protected String portletWidgetset = null; public void destroy() { } public void init(PortletConfig config) throws PortletException { app = config.getInitParameter(PORTLET_PARAMETER_APPLICATION); if (app == null) { throw new PortletException("No porlet application url defined in portlet.xml. Define the '" + PORTLET_PARAMETER_APPLICATION + "' init parameter to be the servlet deployment path."); } style = config.getInitParameter(PORTLET_PARAMETER_STYLE); // enable forcing the selection of the widgetset in portlet // configuration for a single portlet (backwards compatibility) portletWidgetset = config.getInitParameter(PORTLET_PARAMETER_WIDGETSET); } public void processAction(ActionRequest request, ActionResponse response) throws PortletException, IOException { PortletApplicationContext.dispatchRequest(this, request, response); } public void render(RenderRequest request, RenderResponse response) throws PortletException, IOException { // display the Vaadin application writeAjaxWindow(request, response); } protected void writeAjaxWindow(RenderRequest request, RenderResponse response) throws IOException { response.setContentType("text/html"); if (app != null) { PortletSession sess = request.getPortletSession(); PortletApplicationContext ctx = PortletApplicationContext.getApplicationContext(sess); PortletRequestDispatcher dispatcher = sess.getPortletContext().getRequestDispatcher("/" + app); try { // portal-wide settings PortalContext portalCtx = request.getPortalContext(); boolean isLifeRay = portalCtx.getPortalInfo().toLowerCase().contains("liferay"); request.setAttribute(ApplicationServlet.REQUEST_FRAGMENT, "true"); // fixed base theme to use - all portal pages with Vaadin // applications will load this exactly once String portalTheme = getPortalProperty(Constants.PORTAL_PARAMETER_VAADIN_THEME, portalCtx); String portalWidgetset = getPortalProperty(Constants.PORTAL_PARAMETER_VAADIN_WIDGETSET, portalCtx); // location of the widgetset(s) and default theme (to which // /VAADIN/widgetsets/... // is appended) String portalResourcePath = getPortalProperty(Constants.PORTAL_PARAMETER_VAADIN_RESOURCE_PATH, portalCtx); if (portalResourcePath != null) { // if portalResourcePath is defined, set it as a request // parameter which will override the default location in // servlet request.setAttribute(ApplicationServlet.REQUEST_VAADIN_STATIC_FILE_PATH, portalResourcePath); } // - if the user has specified a widgetset for this portlet, use // it from the portlet (not fully supported) // - otherwise, if specified, use the portal-wide widgetset // and widgetset path settings (recommended) // - finally, default to use the default widgetset if nothing // else is found if (portletWidgetset != null) { request.setAttribute(ApplicationServlet.REQUEST_WIDGETSET, portletWidgetset); } if (portalWidgetset != null) { request.setAttribute(ApplicationServlet.REQUEST_SHARED_WIDGETSET, portalWidgetset); } if (style != null) { request.setAttribute(ApplicationServlet.REQUEST_APPSTYLE, style); } // portalTheme is only used if the shared portal resource // directory is defined if (portalTheme != null && portalResourcePath != null) { request.setAttribute(ApplicationServlet.REQUEST_DEFAULT_THEME, portalTheme); String defaultThemeUri = null; defaultThemeUri = portalResourcePath + "/" + AbstractApplicationServlet.THEME_DIRECTORY_PATH + portalTheme; /* * Make sure portal default Vaadin theme is included in DOM. * Vaadin portlet themes do not "inherit" base theme, so we * need to force loading of the common base theme. */ OutputStream out = response.getPortletOutputStream(); // Using portal-wide theme String loadDefaultTheme = ("<script type=\"text/javascript\">\n" + "if(!vaadin) { var vaadin = {} } \n" + "if(!vaadin.themesLoaded) { vaadin.themesLoaded = {} } \n" + "if(!vaadin.themesLoaded['" + portalTheme + "']) {\n" + "var stylesheet = document.createElement('link');\n" + "stylesheet.setAttribute('rel', 'stylesheet');\n" + "stylesheet.setAttribute('type', 'text/css');\n" + "stylesheet.setAttribute('href', '" + defaultThemeUri + "/styles.css');\n" + "document.getElementsByTagName('head')[0].appendChild(stylesheet);\n" + "vaadin.themesLoaded['" + portalTheme + "'] = true;\n}\n" + "</script>\n"); out.write(loadDefaultTheme.getBytes()); } dispatcher.include(request, response); if (isLifeRay) { /* * Temporary support to heartbeat Liferay session when using * Vaadin based portlet. We hit an extra xhr to liferay * servlet to extend the session lifetime after each Vaadin * request. This hack can be removed when supporting portlet * 2.0 and resourceRequests. * * TODO make this configurable, this is not necessary with * some custom session configurations. */ OutputStream out = response.getPortletOutputStream(); String lifeRaySessionHearbeatHack = ("<script type=\"text/javascript\">" + "if(!vaadin.postRequestHooks) {" + " vaadin.postRequestHooks = {};" + "}" + "vaadin.postRequestHooks.liferaySessionHeartBeat = function() {" + " if (Liferay && Liferay.Session && Liferay.Session.setCookie) {" + " Liferay.Session.setCookie();" + " }" + "};" + "</script>"); out.write(lifeRaySessionHearbeatHack.getBytes()); } } catch (PortletException e) { PrintWriter out = response.getWriter(); out.print("<h1>Servlet include failed!</h1>"); Logger.getLogger(AbstractApplicationPortlet.class.getName()).log(Level.WARNING, "Servlet include failed", e); ctx.setPortletApplication(this, null); return; } Application app = (Application) request.getAttribute(Application.class.getName()); ctx.setPortletApplication(this, app); ctx.firePortletRenderRequest(this, request, response); } } private String getPortalProperty(String name, PortalContext context) { boolean isLifeRay = context.getPortalInfo().toLowerCase().contains("liferay"); // TODO test on non-LifeRay platforms String value; if (isLifeRay) { value = getLifeRayPortalProperty(name); } else { value = context.getProperty(name); } return value; } private String getLifeRayPortalProperty(String name) { String value; try { value = PropsUtil.get(name); } catch (Exception e) { value = null; } return value; } }