You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ApplicationPortlet.java 10KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. /*
  2. @ITMillApache2LicenseForJavaFiles@
  3. */
  4. package com.vaadin.terminal.gwt.server;
  5. import java.io.IOException;
  6. import java.io.OutputStream;
  7. import java.io.PrintWriter;
  8. import java.io.Serializable;
  9. import javax.portlet.ActionRequest;
  10. import javax.portlet.ActionResponse;
  11. import javax.portlet.PortalContext;
  12. import javax.portlet.Portlet;
  13. import javax.portlet.PortletConfig;
  14. import javax.portlet.PortletException;
  15. import javax.portlet.PortletRequestDispatcher;
  16. import javax.portlet.PortletSession;
  17. import javax.portlet.RenderRequest;
  18. import javax.portlet.RenderResponse;
  19. import com.liferay.portal.kernel.util.PropsUtil;
  20. import com.vaadin.Application;
  21. /**
  22. * Portlet main class for Portlet 1.0 (JSR-168) portlets which consist of a
  23. * portlet and a servlet. For Portlet 2.0 (JSR-286, no servlet required), use
  24. * {@link ApplicationPortlet2} instead.
  25. */
  26. @SuppressWarnings("serial")
  27. public class ApplicationPortlet implements Portlet, Serializable {
  28. // portlet configuration parameters
  29. private static final String PORTLET_PARAMETER_APPLICATION = "application";
  30. private static final String PORTLET_PARAMETER_STYLE = "style";
  31. private static final String PORTLET_PARAMETER_WIDGETSET = "widgetset";
  32. // The application to show
  33. protected String app = null;
  34. // some applications might require forced height (and, more seldom, width)
  35. protected String style = null; // e.g "height:500px;"
  36. // force the portlet to use this widgetset - portlet level setting
  37. protected String portletWidgetset = null;
  38. public void destroy() {
  39. }
  40. public void init(PortletConfig config) throws PortletException {
  41. app = config.getInitParameter(PORTLET_PARAMETER_APPLICATION);
  42. if (app == null) {
  43. throw new PortletException(
  44. "No porlet application url defined in portlet.xml. Define the '"
  45. + PORTLET_PARAMETER_APPLICATION
  46. + "' init parameter to be the servlet deployment path.");
  47. }
  48. style = config.getInitParameter(PORTLET_PARAMETER_STYLE);
  49. // enable forcing the selection of the widgetset in portlet
  50. // configuration for a single portlet (backwards compatibility)
  51. portletWidgetset = config.getInitParameter(PORTLET_PARAMETER_WIDGETSET);
  52. }
  53. public void processAction(ActionRequest request, ActionResponse response)
  54. throws PortletException, IOException {
  55. PortletApplicationContext.dispatchRequest(this, request, response);
  56. }
  57. public void render(RenderRequest request, RenderResponse response)
  58. throws PortletException, IOException {
  59. // display the Vaadin application
  60. writeAjaxWindow(request, response);
  61. }
  62. protected void writeAjaxWindow(RenderRequest request,
  63. RenderResponse response) throws IOException {
  64. response.setContentType("text/html");
  65. if (app != null) {
  66. PortletSession sess = request.getPortletSession();
  67. PortletApplicationContext ctx = PortletApplicationContext
  68. .getApplicationContext(sess);
  69. PortletRequestDispatcher dispatcher = sess.getPortletContext()
  70. .getRequestDispatcher("/" + app);
  71. try {
  72. // portal-wide settings
  73. PortalContext portalCtx = request.getPortalContext();
  74. boolean isLifeRay = portalCtx.getPortalInfo().toLowerCase()
  75. .contains("liferay");
  76. request.setAttribute(ApplicationServlet.REQUEST_FRAGMENT,
  77. "true");
  78. // fixed base theme to use - all portal pages with Vaadin
  79. // applications will load this exactly once
  80. String portalTheme = getPortalProperty(
  81. Constants.PORTAL_PARAMETER_VAADIN_THEME, portalCtx);
  82. String portalWidgetset = getPortalProperty(
  83. Constants.PORTAL_PARAMETER_VAADIN_WIDGETSET, portalCtx);
  84. // location of the widgetset(s) and default theme (to which
  85. // /VAADIN/widgetsets/...
  86. // is appended)
  87. String portalResourcePath = getPortalProperty(
  88. Constants.PORTAL_PARAMETER_VAADIN_RESOURCE_PATH,
  89. portalCtx);
  90. if (portalResourcePath != null) {
  91. // if portalResourcePath is defined, set it as a request
  92. // parameter which will override the default location in
  93. // servlet
  94. request.setAttribute(
  95. ApplicationServlet.REQUEST_VAADIN_STATIC_FILE_PATH,
  96. portalResourcePath);
  97. }
  98. // - if the user has specified a widgetset for this portlet, use
  99. // it from the portlet (not fully supported)
  100. // - otherwise, if specified, use the portal-wide widgetset
  101. // and widgetset path settings (recommended)
  102. // - finally, default to use the default widgetset if nothing
  103. // else is found
  104. if (portletWidgetset != null) {
  105. request.setAttribute(ApplicationServlet.REQUEST_WIDGETSET,
  106. portletWidgetset);
  107. }
  108. if (portalWidgetset != null) {
  109. request.setAttribute(
  110. ApplicationServlet.REQUEST_SHARED_WIDGETSET,
  111. portalWidgetset);
  112. }
  113. if (style != null) {
  114. request.setAttribute(ApplicationServlet.REQUEST_APPSTYLE,
  115. style);
  116. }
  117. // portalTheme is only used if the shared portal resource
  118. // directory is defined
  119. if (portalTheme != null && portalResourcePath != null) {
  120. request.setAttribute(
  121. ApplicationServlet.REQUEST_DEFAULT_THEME,
  122. portalTheme);
  123. String defaultThemeUri = null;
  124. defaultThemeUri = portalResourcePath + "/"
  125. + AbstractApplicationServlet.THEME_DIRECTORY_PATH
  126. + portalTheme;
  127. /*
  128. * Make sure portal default Vaadin theme is included in DOM.
  129. * Vaadin portlet themes do not "inherit" base theme, so we
  130. * need to force loading of the common base theme.
  131. */
  132. OutputStream out = response.getPortletOutputStream();
  133. // Using portal-wide theme
  134. String loadDefaultTheme = ("<script type=\"text/javascript\">\n"
  135. + "if(!vaadin) { var vaadin = {} } \n"
  136. + "if(!vaadin.themesLoaded) { vaadin.themesLoaded = {} } \n"
  137. + "if(!vaadin.themesLoaded['"
  138. + portalTheme
  139. + "']) {\n"
  140. + "var stylesheet = document.createElement('link');\n"
  141. + "stylesheet.setAttribute('rel', 'stylesheet');\n"
  142. + "stylesheet.setAttribute('type', 'text/css');\n"
  143. + "stylesheet.setAttribute('href', '"
  144. + defaultThemeUri
  145. + "/styles.css');\n"
  146. + "document.getElementsByTagName('head')[0].appendChild(stylesheet);\n"
  147. + "vaadin.themesLoaded['"
  148. + portalTheme
  149. + "'] = true;\n}\n" + "</script>\n");
  150. out.write(loadDefaultTheme.getBytes());
  151. }
  152. dispatcher.include(request, response);
  153. if (isLifeRay) {
  154. /*
  155. * Temporary support to heartbeat Liferay session when using
  156. * Vaadin based portlet. We hit an extra xhr to liferay
  157. * servlet to extend the session lifetime after each Vaadin
  158. * request. This hack can be removed when supporting portlet
  159. * 2.0 and resourceRequests.
  160. *
  161. * TODO make this configurable, this is not necessary with
  162. * some custom session configurations.
  163. */
  164. OutputStream out = response.getPortletOutputStream();
  165. String lifeRaySessionHearbeatHack = ("<script type=\"text/javascript\">"
  166. + "if(!vaadin.postRequestHooks) {"
  167. + " vaadin.postRequestHooks = {};"
  168. + "}"
  169. + "vaadin.postRequestHooks.liferaySessionHeartBeat = function() {"
  170. + " if (Liferay && Liferay.Session && Liferay.Session.setCookie) {"
  171. + " Liferay.Session.setCookie();"
  172. + " }"
  173. + "};" + "</script>");
  174. out.write(lifeRaySessionHearbeatHack.getBytes());
  175. }
  176. } catch (PortletException e) {
  177. PrintWriter out = response.getWriter();
  178. out.print("<h1>Servlet include failed!</h1>");
  179. out.print("<div>" + e + "</div>");
  180. ctx.setPortletApplication(this, null);
  181. return;
  182. }
  183. Application app = (Application) request
  184. .getAttribute(Application.class.getName());
  185. ctx.setPortletApplication(this, app);
  186. ctx.firePortletRenderRequest(this, request, response);
  187. }
  188. }
  189. private String getPortalProperty(String name, PortalContext context) {
  190. boolean isLifeRay = context.getPortalInfo().toLowerCase()
  191. .contains("liferay");
  192. // TODO test on non-LifeRay platforms
  193. String value;
  194. if (isLifeRay) {
  195. value = getLifeRayPortalProperty(name);
  196. } else {
  197. value = context.getProperty(name);
  198. }
  199. return value;
  200. }
  201. private String getLifeRayPortalProperty(String name) {
  202. String value;
  203. try {
  204. value = PropsUtil.get(name);
  205. } catch (Exception e) {
  206. value = null;
  207. }
  208. return value;
  209. }
  210. }