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