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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373
  1. /*
  2. * Copyright 2000-2014 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 getPortalProperty(VaadinRequest request, String propertyName) {
  64. return ((VaadinPortletRequest) request).getPortalProperty(propertyName);
  65. }
  66. private String getParameter(VaadinRequest request, String name,
  67. String defaultValue) {
  68. VaadinPortletRequest portletRequest = (VaadinPortletRequest) request;
  69. String preference = portletRequest.getPortletPreference(name);
  70. if (preference != null) {
  71. return preference;
  72. }
  73. String appOrSystemProperty = getAppOrSystemProperty(name, null);
  74. if (appOrSystemProperty != null) {
  75. return appOrSystemProperty;
  76. }
  77. String portalProperty = portletRequest.getPortalProperty(name);
  78. if (portalProperty != null) {
  79. // For backwards compatibility - automatically map old portal
  80. // default widget set to default widget set
  81. if (name.equals(Constants.PORTAL_PARAMETER_VAADIN_WIDGETSET)) {
  82. return mapDefaultWidgetset(portalProperty);
  83. }
  84. return portalProperty;
  85. }
  86. return defaultValue;
  87. }
  88. private String getAppOrSystemProperty(String name, String defaultValue) {
  89. DeploymentConfiguration deploymentConfiguration = getDeploymentConfiguration();
  90. return deploymentConfiguration.getApplicationOrSystemProperty(name,
  91. defaultValue);
  92. }
  93. @Override
  94. public String getConfiguredWidgetset(VaadinRequest request) {
  95. String widgetset = getDeploymentConfiguration().getWidgetset(null);
  96. if (widgetset == null) {
  97. widgetset = getParameter(request,
  98. Constants.PORTAL_PARAMETER_VAADIN_WIDGETSET,
  99. Constants.DEFAULT_WIDGETSET);
  100. }
  101. return widgetset;
  102. }
  103. private String mapDefaultWidgetset(String widgetset) {
  104. if ("com.vaadin.portal.gwt.PortalDefaultWidgetSet".equals(widgetset)) {
  105. return Constants.DEFAULT_WIDGETSET;
  106. }
  107. return widgetset;
  108. }
  109. @Override
  110. public String getConfiguredTheme(VaadinRequest request) {
  111. return getParameter(request, Constants.PORTAL_PARAMETER_VAADIN_THEME,
  112. Constants.DEFAULT_THEME_NAME);
  113. }
  114. @Override
  115. public boolean isStandalone(VaadinRequest request) {
  116. return false;
  117. }
  118. @Override
  119. public String getStaticFileLocation(VaadinRequest request) {
  120. // /html is default for Liferay
  121. String staticFileLocation = getParameter(request,
  122. Constants.PORTAL_PARAMETER_VAADIN_RESOURCE_PATH, "/html");
  123. if (Constants.PORTLET_CONTEXT.equals(staticFileLocation)) {
  124. return request.getContextPath();
  125. } else {
  126. return trimTrailingSlashes(staticFileLocation);
  127. }
  128. }
  129. private PortletContext getPortletContext() {
  130. return getPortlet().getPortletContext();
  131. }
  132. @Override
  133. public String getMimeType(String resourceName) {
  134. return getPortletContext().getMimeType(resourceName);
  135. }
  136. @Override
  137. public File getBaseDirectory() {
  138. PortletContext context = getPortletContext();
  139. String resultPath = context.getRealPath("/");
  140. if (resultPath != null) {
  141. return new File(resultPath);
  142. } else {
  143. try {
  144. final URL url = context.getResource("/");
  145. return new File(url.getFile());
  146. } catch (final Exception e) {
  147. // FIXME: Handle exception
  148. getLogger()
  149. .log(Level.INFO,
  150. "Cannot access base directory, possible security issue "
  151. + "with Application Server or Servlet Container",
  152. e);
  153. }
  154. }
  155. return null;
  156. }
  157. private static final Logger getLogger() {
  158. return Logger.getLogger(VaadinPortletService.class.getName());
  159. }
  160. @Override
  161. protected boolean requestCanCreateSession(VaadinRequest request) {
  162. if (!(request instanceof VaadinPortletRequest)) {
  163. throw new IllegalArgumentException(
  164. "Request is not a VaadinPortletRequest");
  165. }
  166. PortletRequest portletRequest = ((VaadinPortletRequest) request)
  167. .getPortletRequest();
  168. if (portletRequest instanceof RenderRequest) {
  169. // In most cases the first request is a render request that
  170. // renders the HTML fragment. This should create a Vaadin
  171. // session unless there is already one.
  172. return true;
  173. } else if (portletRequest instanceof EventRequest) {
  174. // A portlet can also be sent an event even though it has not
  175. // been rendered, e.g. portlet on one page sends an event to a
  176. // portlet on another page and then moves the user to that page.
  177. return true;
  178. } else if (PortletUIInitHandler.isUIInitRequest(request)) {
  179. // In some cases, the RenderRequest seems to be cached, causing the
  180. // first request be the one triggered by vaadinBootstrap.js.
  181. return true;
  182. }
  183. return false;
  184. }
  185. /**
  186. * Gets the request type for the request.
  187. *
  188. * @param request
  189. * the request to get a request type for
  190. * @return the request type
  191. *
  192. * @deprecated As of 7.0. Will likely change or be removed in a future
  193. * version
  194. */
  195. @Deprecated
  196. protected RequestType getRequestType(VaadinRequest request) {
  197. RequestType type = (RequestType) request.getAttribute(RequestType.class
  198. .getName());
  199. if (type == null) {
  200. type = getPortlet().getRequestType((VaadinPortletRequest) request);
  201. request.setAttribute(RequestType.class.getName(), type);
  202. }
  203. return type;
  204. }
  205. /**
  206. * Gets the currently processed portlet request. The current portlet request
  207. * is automatically defined when the request is started. The current portlet
  208. * request can not be used in e.g. background threads because of the way
  209. * server implementations reuse request instances.
  210. *
  211. * @return the current portlet request instance if available, otherwise
  212. * <code>null</code>
  213. *
  214. */
  215. public static PortletRequest getCurrentPortletRequest() {
  216. VaadinPortletRequest currentRequest = getCurrentRequest();
  217. if (currentRequest != null) {
  218. return currentRequest.getPortletRequest();
  219. } else {
  220. return null;
  221. }
  222. }
  223. /**
  224. * Gets the currently processed Vaadin portlet request. The current request
  225. * is automatically defined when the request is started. The current request
  226. * can not be used in e.g. background threads because of the way server
  227. * implementations reuse request instances.
  228. *
  229. * @return the current Vaadin portlet request instance if available,
  230. * otherwise <code>null</code>
  231. *
  232. */
  233. public static VaadinPortletRequest getCurrentRequest() {
  234. return (VaadinPortletRequest) VaadinService.getCurrentRequest();
  235. }
  236. /**
  237. * Gets the currently processed Vaadin portlet response. The current
  238. * response is automatically defined when the request is started. The
  239. * current response can not be used in e.g. background threads because of
  240. * the way server implementations reuse response instances.
  241. *
  242. * @return the current Vaadin portlet response instance if available,
  243. * otherwise <code>null</code>
  244. *
  245. */
  246. public static VaadinPortletResponse getCurrentResponse() {
  247. return (VaadinPortletResponse) VaadinService.getCurrentResponse();
  248. }
  249. @Override
  250. protected VaadinSession createVaadinSession(VaadinRequest request)
  251. throws ServiceException {
  252. return new VaadinPortletSession(this);
  253. }
  254. @Override
  255. public String getServiceName() {
  256. return getPortlet().getPortletName();
  257. }
  258. /**
  259. * Always preserve UIs in portlets to make portlet actions work.
  260. */
  261. @Override
  262. public boolean preserveUIOnRefresh(UIProvider provider, UICreateEvent event) {
  263. return true;
  264. }
  265. @Override
  266. public InputStream getThemeResourceAsStream(UI uI, String themeName,
  267. String resource) {
  268. VaadinPortletSession session = (VaadinPortletSession) uI.getSession();
  269. PortletContext portletContext = session.getPortletSession()
  270. .getPortletContext();
  271. return portletContext.getResourceAsStream("/"
  272. + VaadinPortlet.THEME_DIR_PATH + '/' + themeName + "/"
  273. + resource);
  274. }
  275. @Override
  276. public String getMainDivId(VaadinSession session, VaadinRequest request,
  277. Class<? extends UI> uiClass) {
  278. PortletRequest portletRequest = ((VaadinPortletRequest) request)
  279. .getPortletRequest();
  280. /*
  281. * We need to generate a unique ID because some portals already create a
  282. * DIV with the portlet's Window ID as the DOM ID.
  283. */
  284. return "v-" + portletRequest.getWindowID();
  285. }
  286. /*
  287. * (non-Javadoc)
  288. *
  289. * @see
  290. * com.vaadin.server.VaadinService#handleSessionExpired(com.vaadin.server
  291. * .VaadinRequest, com.vaadin.server.VaadinResponse)
  292. */
  293. @Override
  294. protected void handleSessionExpired(VaadinRequest request,
  295. VaadinResponse response) {
  296. // TODO Figure out a better way to deal with
  297. // SessionExpiredExceptions
  298. getLogger().finest("A user session has expired");
  299. }
  300. private WrappedPortletSession getWrappedPortletSession(
  301. WrappedSession wrappedSession) {
  302. return (WrappedPortletSession) wrappedSession;
  303. }
  304. @Override
  305. protected void writeToHttpSession(WrappedSession wrappedSession,
  306. VaadinSession session) {
  307. getWrappedPortletSession(wrappedSession).setAttribute(
  308. getSessionAttributeName(), session,
  309. PortletSession.APPLICATION_SCOPE);
  310. }
  311. @Override
  312. protected VaadinSession readFromHttpSession(WrappedSession wrappedSession) {
  313. return (VaadinSession) getWrappedPortletSession(wrappedSession)
  314. .getAttribute(getSessionAttributeName(),
  315. PortletSession.APPLICATION_SCOPE);
  316. }
  317. @Override
  318. protected void removeFromHttpSession(WrappedSession wrappedSession) {
  319. getWrappedPortletSession(wrappedSession).removeAttribute(
  320. getSessionAttributeName(), PortletSession.APPLICATION_SCOPE);
  321. }
  322. }