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.

VaadinPortletService.java 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369
  1. /*
  2. * Copyright 2000-2018 Vaadin Ltd.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  5. * use this file except in compliance with the License. You may obtain a copy of
  6. * the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  12. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  13. * License for the specific language governing permissions and limitations under
  14. * the License.
  15. */
  16. package com.vaadin.server;
  17. import static com.vaadin.shared.util.SharedUtil.trimTrailingSlashes;
  18. import java.io.File;
  19. import java.io.InputStream;
  20. import java.net.URL;
  21. import java.util.List;
  22. import java.util.logging.Level;
  23. import java.util.logging.Logger;
  24. import javax.portlet.EventRequest;
  25. import javax.portlet.PortletContext;
  26. import javax.portlet.PortletRequest;
  27. import javax.portlet.PortletSession;
  28. import javax.portlet.RenderRequest;
  29. import com.vaadin.server.VaadinPortlet.RequestType;
  30. import com.vaadin.server.communication.PortletBootstrapHandler;
  31. import com.vaadin.server.communication.PortletDummyRequestHandler;
  32. import com.vaadin.server.communication.PortletListenerNotifier;
  33. import com.vaadin.server.communication.PortletStateAwareRequestHandler;
  34. import com.vaadin.server.communication.PortletUIInitHandler;
  35. import com.vaadin.ui.UI;
  36. public class VaadinPortletService extends VaadinService {
  37. private final VaadinPortlet portlet;
  38. public VaadinPortletService(VaadinPortlet portlet,
  39. DeploymentConfiguration deploymentConfiguration)
  40. throws ServiceException {
  41. super(deploymentConfiguration);
  42. this.portlet = portlet;
  43. }
  44. @Override
  45. protected List<RequestHandler> createRequestHandlers()
  46. throws ServiceException {
  47. List<RequestHandler> handlers = super.createRequestHandlers();
  48. handlers.add(new PortletUIInitHandler());
  49. handlers.add(new PortletListenerNotifier());
  50. handlers.add(0, new PortletDummyRequestHandler());
  51. handlers.add(0, new PortletBootstrapHandler());
  52. handlers.add(0, new PortletStateAwareRequestHandler());
  53. return handlers;
  54. }
  55. /**
  56. * Retrieves a reference to the portlet associated with this service.
  57. *
  58. * @return A reference to the VaadinPortlet this service is using
  59. */
  60. public VaadinPortlet getPortlet() {
  61. return portlet;
  62. }
  63. private String getParameter(VaadinRequest request, String name,
  64. String defaultValue) {
  65. VaadinPortletRequest portletRequest = (VaadinPortletRequest) request;
  66. String preference = portletRequest.getPortletPreference(name);
  67. if (preference != null) {
  68. return preference;
  69. }
  70. String appOrSystemProperty = getAppOrSystemProperty(name, null);
  71. if (appOrSystemProperty != null) {
  72. return appOrSystemProperty;
  73. }
  74. String portalProperty = portletRequest.getPortalProperty(name);
  75. if (portalProperty != null) {
  76. // For backwards compatibility - automatically map old portal
  77. // default widget set to default widget set
  78. if (name.equals(Constants.PORTAL_PARAMETER_VAADIN_WIDGETSET)) {
  79. return mapDefaultWidgetset(portalProperty);
  80. }
  81. return portalProperty;
  82. }
  83. return defaultValue;
  84. }
  85. private String getAppOrSystemProperty(String name, String defaultValue) {
  86. DeploymentConfiguration deploymentConfiguration = getDeploymentConfiguration();
  87. return deploymentConfiguration.getApplicationOrSystemProperty(name,
  88. defaultValue);
  89. }
  90. @Override
  91. public String getConfiguredWidgetset(VaadinRequest request) {
  92. String widgetset = getDeploymentConfiguration().getWidgetset(null);
  93. if (widgetset == null) {
  94. widgetset = getParameter(request,
  95. Constants.PORTAL_PARAMETER_VAADIN_WIDGETSET,
  96. Constants.DEFAULT_WIDGETSET);
  97. }
  98. return widgetset;
  99. }
  100. private String mapDefaultWidgetset(String widgetset) {
  101. if ("com.vaadin.portal.gwt.PortalDefaultWidgetSet".equals(widgetset)) {
  102. return Constants.DEFAULT_WIDGETSET;
  103. }
  104. return widgetset;
  105. }
  106. @Override
  107. public String getConfiguredTheme(VaadinRequest request) {
  108. return getParameter(request, Constants.PORTAL_PARAMETER_VAADIN_THEME,
  109. Constants.DEFAULT_THEME_NAME);
  110. }
  111. @Override
  112. public boolean isStandalone(VaadinRequest request) {
  113. return false;
  114. }
  115. @Override
  116. public String getStaticFileLocation(VaadinRequest request) {
  117. // /html is default for Liferay
  118. String staticFileLocation = getParameter(request,
  119. Constants.PORTAL_PARAMETER_VAADIN_RESOURCE_PATH, "/html");
  120. if (Constants.PORTLET_CONTEXT.equals(staticFileLocation)) {
  121. return request.getContextPath();
  122. } else {
  123. return trimTrailingSlashes(staticFileLocation);
  124. }
  125. }
  126. private PortletContext getPortletContext() {
  127. return getPortlet().getPortletContext();
  128. }
  129. @Override
  130. public String getMimeType(String resourceName) {
  131. return getPortletContext().getMimeType(resourceName);
  132. }
  133. @Override
  134. public File getBaseDirectory() {
  135. PortletContext context = getPortletContext();
  136. String resultPath = context.getRealPath("/");
  137. if (resultPath != null) {
  138. return new File(resultPath);
  139. } else {
  140. try {
  141. final URL url = context.getResource("/");
  142. return new File(url.getFile());
  143. } catch (final Exception e) {
  144. // FIXME: Handle exception
  145. getLogger().log(Level.INFO,
  146. "Cannot access base directory, possible security issue "
  147. + "with Application Server or Servlet Container",
  148. e);
  149. }
  150. }
  151. return null;
  152. }
  153. private static final Logger getLogger() {
  154. return Logger.getLogger(VaadinPortletService.class.getName());
  155. }
  156. @Override
  157. protected boolean requestCanCreateSession(VaadinRequest request) {
  158. if (!(request instanceof VaadinPortletRequest)) {
  159. throw new IllegalArgumentException(
  160. "Request is not a VaadinPortletRequest");
  161. }
  162. PortletRequest portletRequest = ((VaadinPortletRequest) request)
  163. .getPortletRequest();
  164. if (portletRequest instanceof RenderRequest) {
  165. // In most cases the first request is a render request that
  166. // renders the HTML fragment. This should create a Vaadin
  167. // session unless there is already one.
  168. return true;
  169. } else if (portletRequest instanceof EventRequest) {
  170. // A portlet can also be sent an event even though it has not
  171. // been rendered, e.g. portlet on one page sends an event to a
  172. // portlet on another page and then moves the user to that page.
  173. return true;
  174. } else if (PortletUIInitHandler.isUIInitRequest(request)) {
  175. // In some cases, the RenderRequest seems to be cached, causing the
  176. // first request be the one triggered by vaadinBootstrap.js.
  177. return true;
  178. }
  179. return false;
  180. }
  181. /**
  182. * Gets the request type for the request.
  183. *
  184. * @param request
  185. * the request to get a request type for
  186. * @return the request type
  187. *
  188. * @deprecated As of 7.0. Will likely change or be removed in a future
  189. * version
  190. */
  191. @Deprecated
  192. protected RequestType getRequestType(VaadinRequest request) {
  193. RequestType type = (RequestType) request
  194. .getAttribute(RequestType.class.getName());
  195. if (type == null) {
  196. type = getPortlet().getRequestType((VaadinPortletRequest) request);
  197. request.setAttribute(RequestType.class.getName(), type);
  198. }
  199. return type;
  200. }
  201. /**
  202. * Gets the currently processed portlet request. The current portlet request
  203. * is automatically defined when the request is started. The current portlet
  204. * request can not be used in e.g. background threads because of the way
  205. * server implementations reuse request instances.
  206. *
  207. * @return the current portlet request instance if available, otherwise
  208. * <code>null</code>
  209. *
  210. */
  211. public static PortletRequest getCurrentPortletRequest() {
  212. VaadinPortletRequest currentRequest = getCurrentRequest();
  213. if (currentRequest != null) {
  214. return currentRequest.getPortletRequest();
  215. } else {
  216. return null;
  217. }
  218. }
  219. /**
  220. * Gets the currently processed Vaadin portlet request. The current request
  221. * is automatically defined when the request is started. The current request
  222. * can not be used in e.g. background threads because of the way server
  223. * implementations reuse request instances.
  224. *
  225. * @return the current Vaadin portlet request instance if available,
  226. * otherwise <code>null</code>
  227. *
  228. */
  229. public static VaadinPortletRequest getCurrentRequest() {
  230. return (VaadinPortletRequest) VaadinService.getCurrentRequest();
  231. }
  232. /**
  233. * Gets the currently processed Vaadin portlet response. The current
  234. * response is automatically defined when the request is started. The
  235. * current response can not be used in e.g. background threads because of
  236. * the way server implementations reuse response instances.
  237. *
  238. * @return the current Vaadin portlet response instance if available,
  239. * otherwise <code>null</code>
  240. *
  241. */
  242. public static VaadinPortletResponse getCurrentResponse() {
  243. return (VaadinPortletResponse) VaadinService.getCurrentResponse();
  244. }
  245. @Override
  246. protected VaadinSession createVaadinSession(VaadinRequest request)
  247. throws ServiceException {
  248. return new VaadinPortletSession(this);
  249. }
  250. @Override
  251. public String getServiceName() {
  252. return getPortlet().getPortletName();
  253. }
  254. /**
  255. * Always preserve UIs in portlets to make portlet actions work.
  256. */
  257. @Override
  258. public boolean preserveUIOnRefresh(UIProvider provider,
  259. UICreateEvent event) {
  260. return true;
  261. }
  262. @Override
  263. public InputStream getThemeResourceAsStream(UI uI, String themeName,
  264. String resource) {
  265. VaadinPortletSession session = (VaadinPortletSession) uI.getSession();
  266. PortletContext portletContext = session.getPortletSession()
  267. .getPortletContext();
  268. return portletContext
  269. .getResourceAsStream("/" + VaadinPortlet.THEME_DIR_PATH + '/'
  270. + themeName + "/" + resource);
  271. }
  272. @Override
  273. public String getMainDivId(VaadinSession session, VaadinRequest request,
  274. Class<? extends UI> uiClass) {
  275. PortletRequest portletRequest = ((VaadinPortletRequest) request)
  276. .getPortletRequest();
  277. /*
  278. * We need to generate a unique ID because some portals already create a
  279. * DIV with the portlet's Window ID as the DOM ID.
  280. */
  281. return "v-" + portletRequest.getWindowID();
  282. }
  283. /*
  284. * (non-Javadoc)
  285. *
  286. * @see
  287. * com.vaadin.server.VaadinService#handleSessionExpired(com.vaadin.server
  288. * .VaadinRequest, com.vaadin.server.VaadinResponse)
  289. */
  290. @Override
  291. protected void handleSessionExpired(VaadinRequest request,
  292. VaadinResponse response) {
  293. // TODO Figure out a better way to deal with
  294. // SessionExpiredExceptions
  295. getLogger().finest("A user session has expired");
  296. }
  297. private WrappedPortletSession getWrappedPortletSession(
  298. WrappedSession wrappedSession) {
  299. return (WrappedPortletSession) wrappedSession;
  300. }
  301. @Override
  302. protected void writeToHttpSession(WrappedSession wrappedSession,
  303. VaadinSession session) {
  304. getWrappedPortletSession(wrappedSession).setAttribute(
  305. getSessionAttributeName(), session,
  306. PortletSession.APPLICATION_SCOPE);
  307. }
  308. @Override
  309. protected VaadinSession readFromHttpSession(WrappedSession wrappedSession) {
  310. return (VaadinSession) getWrappedPortletSession(wrappedSession)
  311. .getAttribute(getSessionAttributeName(),
  312. PortletSession.APPLICATION_SCOPE);
  313. }
  314. @Override
  315. protected void removeFromHttpSession(WrappedSession wrappedSession) {
  316. getWrappedPortletSession(wrappedSession).removeAttribute(
  317. getSessionAttributeName(), PortletSession.APPLICATION_SCOPE);
  318. }
  319. }