com.liferay.wsrp.internal.bind.V2MarkupServiceImpl Maven / Gradle / Ivy
/**
* Copyright (c) 2000-present Liferay, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*/
package com.liferay.wsrp.internal.bind;
import com.liferay.petra.string.CharPool;
import com.liferay.portal.kernel.exception.NoSuchLayoutException;
import com.liferay.portal.kernel.exception.SystemException;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.model.Layout;
import com.liferay.portal.kernel.model.LayoutConstants;
import com.liferay.portal.kernel.model.LayoutTypePortlet;
import com.liferay.portal.kernel.portlet.LiferayWindowState;
import com.liferay.portal.kernel.portlet.PortletPreferencesFactoryUtil;
import com.liferay.portal.kernel.portlet.PortletProvider;
import com.liferay.portal.kernel.portlet.PortletProviderUtil;
import com.liferay.portal.kernel.service.LayoutLocalServiceUtil;
import com.liferay.portal.kernel.servlet.HttpHeaders;
import com.liferay.portal.kernel.util.ArrayUtil;
import com.liferay.portal.kernel.util.Base64;
import com.liferay.portal.kernel.util.ContentTypes;
import com.liferay.portal.kernel.util.DigesterUtil;
import com.liferay.portal.kernel.util.Http;
import com.liferay.portal.kernel.util.HttpUtil;
import com.liferay.portal.kernel.util.PortalUtil;
import com.liferay.portal.kernel.util.PropsKeys;
import com.liferay.portal.kernel.util.PropsUtil;
import com.liferay.portal.kernel.util.StringBundler;
import com.liferay.portal.kernel.util.StringPool;
import com.liferay.portal.kernel.util.StringUtil;
import com.liferay.portal.kernel.util.URLCodec;
import com.liferay.portal.kernel.util.Validator;
import com.liferay.portlet.configuration.kernel.util.PortletConfigurationApplicationType;
import com.liferay.util.axis.ServletUtil;
import com.liferay.wsrp.internal.util.ExtensionHelperUtil;
import com.liferay.wsrp.model.WSRPProducer;
import com.liferay.wsrp.util.WebKeys;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import oasis.names.tc.wsrp.v2.intf.WSRP_v2_Markup_PortType;
import oasis.names.tc.wsrp.v2.types.BlockingInteractionResponse;
import oasis.names.tc.wsrp.v2.types.ClientData;
import oasis.names.tc.wsrp.v2.types.Extension;
import oasis.names.tc.wsrp.v2.types.GetMarkup;
import oasis.names.tc.wsrp.v2.types.GetResource;
import oasis.names.tc.wsrp.v2.types.HandleEvents;
import oasis.names.tc.wsrp.v2.types.HandleEventsResponse;
import oasis.names.tc.wsrp.v2.types.InitCookie;
import oasis.names.tc.wsrp.v2.types.InteractionParams;
import oasis.names.tc.wsrp.v2.types.MarkupContext;
import oasis.names.tc.wsrp.v2.types.MarkupResponse;
import oasis.names.tc.wsrp.v2.types.MimeRequest;
import oasis.names.tc.wsrp.v2.types.NamedString;
import oasis.names.tc.wsrp.v2.types.NavigationalContext;
import oasis.names.tc.wsrp.v2.types.PerformBlockingInteraction;
import oasis.names.tc.wsrp.v2.types.PortletContext;
import oasis.names.tc.wsrp.v2.types.ReleaseSessions;
import oasis.names.tc.wsrp.v2.types.ResourceContext;
import oasis.names.tc.wsrp.v2.types.ResourceParams;
import oasis.names.tc.wsrp.v2.types.ResourceResponse;
import oasis.names.tc.wsrp.v2.types.RuntimeContext;
import oasis.names.tc.wsrp.v2.types.UpdateResponse;
import oasis.names.tc.wsrp.v2.types.UploadContext;
import org.apache.axis.message.MessageElement;
/**
* @author Brian Wing Shun Chan
* @author Hugo Huijser
*/
public class V2MarkupServiceImpl
extends BaseServiceImpl implements WSRP_v2_Markup_PortType {
@Override
public MarkupResponse getMarkup(GetMarkup getMarkup)
throws RemoteException {
try {
return doGetMarkup(getMarkup);
}
catch (RemoteException re) {
_log.error(re, re);
throw re;
}
catch (Exception e) {
_log.error(e, e);
throw new RemoteException(e.getMessage());
}
}
@Override
public ResourceResponse getResource(GetResource getResource)
throws RemoteException {
try {
return doGetResource(getResource);
}
catch (RemoteException re) {
_log.error(re, re);
throw re;
}
catch (Exception e) {
_log.error(e, e);
throw new RemoteException(e.getMessage());
}
}
@Override
public HandleEventsResponse handleEvents(HandleEvents handleEvents)
throws RemoteException {
try {
return doHandleEvents(handleEvents);
}
catch (RemoteException re) {
_log.error(re, re);
throw re;
}
catch (Exception e) {
_log.error(e, e);
throw new RemoteException(e.getMessage());
}
}
@Override
public Extension[] initCookie(InitCookie initCookie)
throws RemoteException {
try {
return doInitCookie(initCookie);
}
catch (RemoteException re) {
_log.error(re, re);
throw re;
}
catch (Exception e) {
_log.error(e, e);
throw new RemoteException(e.getMessage());
}
}
@Override
public BlockingInteractionResponse performBlockingInteraction(
PerformBlockingInteraction performBlockingInteraction)
throws RemoteException {
try {
return doPerformBlockingInteraction(performBlockingInteraction);
}
catch (RemoteException re) {
_log.error(re, re);
throw re;
}
catch (Exception e) {
_log.error(e, e);
throw new RemoteException(e.getMessage());
}
}
@Override
public Extension[] releaseSessions(ReleaseSessions releaseSessions)
throws RemoteException {
try {
return doReleaseSessions(releaseSessions);
}
catch (RemoteException re) {
_log.error(re, re);
throw re;
}
catch (Exception e) {
_log.error(e, e);
throw new RemoteException(e.getMessage());
}
}
protected void addHeaders(
MimeRequest mimeRequest, Http.Options httpOptions) {
ClientData clientData = mimeRequest.getClientData();
Extension[] extensions = clientData.getExtensions();
MessageElement[] clientAttributes =
ExtensionHelperUtil.getMessageElements(extensions);
if (clientAttributes == null) {
return;
}
for (MessageElement clientAttribute : clientAttributes) {
String name = ExtensionHelperUtil.getNameAttribute(clientAttribute);
String value = clientAttribute.getValue();
if (StringUtil.equalsIgnoreCase(
name, HttpHeaders.ACCEPT_ENCODING) ||
StringUtil.equalsIgnoreCase(name, HttpHeaders.CONTENT_LENGTH) ||
StringUtil.equalsIgnoreCase(name, HttpHeaders.CONTENT_TYPE) ||
StringUtil.equalsIgnoreCase(name, HttpHeaders.COOKIE)) {
continue;
}
httpOptions.addHeader(name, value);
}
}
protected MarkupResponse doGetMarkup(GetMarkup getMarkup) throws Exception {
WSRPProducer wsrpProducer = getWSRPProducer();
Http.Options httpOptions = new Http.Options();
addHeaders(getMarkup.getMarkupParams(), httpOptions);
httpOptions.setLocation(getURL(getMarkup, wsrpProducer));
String rawContent = getRawContent(httpOptions);
String windowState = getWindowState(getMarkup.getMarkupParams());
String content = getContent(rawContent, windowState);
MarkupContext markupContext = new MarkupContext();
markupContext.setItemString(content);
markupContext.setMimeType(ContentTypes.TEXT_HTML_UTF8);
markupContext.setRequiresRewriting(true);
MarkupResponse markupResponse = new MarkupResponse();
markupResponse.setMarkupContext(markupContext);
return markupResponse;
}
protected ResourceResponse doGetResource(GetResource getResource)
throws Exception {
WSRPProducer wsrpProducer = getWSRPProducer();
Http.Options httpOptions = new Http.Options();
addHeaders(getResource.getResourceParams(), httpOptions);
httpOptions.setLocation(getURL(getResource, wsrpProducer));
ResourceParams resourceParams = getResource.getResourceParams();
UploadContext[] uploadContexts = resourceParams.getUploadContexts();
processUploadContexts(uploadContexts, httpOptions);
NamedString[] formParameters = resourceParams.getFormParameters();
if (formParameters != null) {
NavigationalContext navigationalContext =
resourceParams.getNavigationalContext();
PortletContext portletContext = getResource.getPortletContext();
String namespace = PortalUtil.getPortletNamespace(
getPortletId(portletContext, navigationalContext));
for (NamedString formParameter : formParameters) {
httpOptions.addPart(
namespace + formParameter.getName(),
formParameter.getValue());
}
if (formParameters.length > 0) {
httpOptions.setPost(true);
}
}
httpOptions.setFollowRedirects(false);
byte[] itemBinary = getBinaryContent(httpOptions);
ResourceContext resourceContext = new ResourceContext();
Http.Response response = httpOptions.getResponse();
String contentType = response.getContentType();
if (itemBinary != null) {
String lowerCaseContentType = StringUtil.toLowerCase(contentType);
if (Validator.isNotNull(lowerCaseContentType) &&
lowerCaseContentType.startsWith("text")) {
String content = new String(itemBinary);
resourceContext.setItemString(content);
resourceContext.setRequiresRewriting(true);
}
else {
resourceContext.setItemBinary(itemBinary);
}
}
List clientAttributes = new ArrayList<>();
String contentDisposition = response.getHeader(
HttpHeaders.CONTENT_DISPOSITION);
if (Validator.isNotNull(contentDisposition)) {
NamedString clientAttribute = new NamedString();
clientAttribute.setName(HttpHeaders.CONTENT_DISPOSITION);
clientAttribute.setValue(contentDisposition);
clientAttributes.add(clientAttribute);
}
if (Validator.isNotNull(contentType)) {
resourceContext.setMimeType(contentType);
NamedString clientAttribute = new NamedString();
clientAttribute.setName(HttpHeaders.CONTENT_TYPE);
clientAttribute.setValue(contentType);
clientAttributes.add(clientAttribute);
}
int contentLength = response.getContentLength();
if (contentLength >= 0) {
NamedString clientAttribute = new NamedString();
clientAttribute.setName(HttpHeaders.CONTENT_LENGTH);
clientAttribute.setValue(String.valueOf(contentLength));
clientAttributes.add(clientAttribute);
}
resourceContext.setClientAttributes(
clientAttributes.toArray(new NamedString[clientAttributes.size()]));
ResourceResponse resourceResponse = new ResourceResponse();
resourceResponse.setResourceContext(resourceContext);
return resourceResponse;
}
protected HandleEventsResponse doHandleEvents(HandleEvents handleEvents)
throws Exception {
HandleEventsResponse handleEventsResponse = new HandleEventsResponse();
return handleEventsResponse;
}
protected Extension[] doInitCookie(InitCookie initCookie) throws Exception {
ServletUtil.getSession();
return null;
}
protected BlockingInteractionResponse doPerformBlockingInteraction(
PerformBlockingInteraction performBlockingInteraction)
throws Exception {
WSRPProducer wsrpProducer = getWSRPProducer();
Http.Options httpOptions = new Http.Options();
addHeaders(performBlockingInteraction.getMarkupParams(), httpOptions);
httpOptions.setLocation(
getURL(performBlockingInteraction, wsrpProducer));
RuntimeContext runtimeContext =
performBlockingInteraction.getRuntimeContext();
InteractionParams interactionParams =
performBlockingInteraction.getInteractionParams();
UploadContext[] uploadContexts = interactionParams.getUploadContexts();
processUploadContexts(uploadContexts, httpOptions);
NamedString[] formParameters = interactionParams.getFormParameters();
if (formParameters != null) {
for (NamedString formParameter : formParameters) {
String name = StringUtil.replace(
formParameter.getName(),
runtimeContext.getNamespacePrefix(), StringPool.BLANK);
httpOptions.addPart(name, formParameter.getValue());
}
}
httpOptions.setFollowRedirects(false);
httpOptions.setPost(true);
String rawContent = getRawContent(httpOptions);
Http.Response response = httpOptions.getResponse();
String redirect = response.getRedirect();
String widgetPath = getWidgetPath();
BlockingInteractionResponse blockingInteractionResponse =
new BlockingInteractionResponse();
if (Validator.isNotNull(redirect) && !redirect.startsWith(widgetPath)) {
int pos = redirect.indexOf("wsrp_rewrite?");
if (pos >= 0) {
redirect = redirect.substring(pos);
}
blockingInteractionResponse.setRedirectURL(redirect);
}
else {
// Relative redirect
if (Validator.isNotNull(redirect) &&
redirect.startsWith(widgetPath)) {
httpOptions.setLocation(redirect);
rawContent = getRawContent(httpOptions);
}
String windowState = getWindowState(
performBlockingInteraction.getMarkupParams());
String content = getContent(rawContent, windowState);
MarkupContext markupContext = new MarkupContext();
markupContext.setItemString(content);
markupContext.setMimeType(ContentTypes.TEXT_HTML_UTF8);
markupContext.setRequiresRewriting(true);
UpdateResponse updateResponse = new UpdateResponse();
updateResponse.setMarkupContext(markupContext);
blockingInteractionResponse.setUpdateResponse(updateResponse);
}
return blockingInteractionResponse;
}
protected Extension[] doReleaseSessions(ReleaseSessions releaseSessions)
throws Exception {
return null;
}
protected byte[] getBinaryContent(Http.Options httpOptions)
throws Exception {
HttpSession session = ServletUtil.getSession();
Cookie[] cookies = (Cookie[])session.getAttribute(WebKeys.COOKIES);
if (cookies != null) {
httpOptions.setCookies(cookies);
}
byte[] binaryContent = HttpUtil.URLtoByteArray(httpOptions);
cookies = HttpUtil.getCookies();
if (cookies != null) {
session.setAttribute(WebKeys.COOKIES, cookies);
}
return binaryContent;
}
protected String getContent(String rawContent, String windowState)
throws Exception {
if (windowState.equals(LiferayWindowState.EXCLUSIVE.toString())) {
return rawContent;
}
String beginPortletContent = "";
String endPortletContent = " ";
int x = rawContent.indexOf(beginPortletContent);
if (x == -1) {
throw new SystemException("Unable to find ");
}
int offset = beginPortletContent.length();
int y = rawContent.indexOf(endPortletContent, x);
if (y == -1) {
throw new SystemException("Unable to find ");
}
return rawContent.substring(x + offset, y);
}
protected Layout getLayout(
PortletContext portletContext, WSRPProducer wsrpProducer)
throws Exception {
List layouts = LayoutLocalServiceUtil.getLayouts(
wsrpProducer.getGroupId(), false,
LayoutConstants.DEFAULT_PARENT_LAYOUT_ID, false, 0, 1);
if (layouts.isEmpty()) {
throw new NoSuchLayoutException();
}
Layout layout = layouts.get(0);
LayoutTypePortlet layoutTypePortlet =
(LayoutTypePortlet)layout.getLayoutType();
String portletId = getPortletId(portletContext);
if (!layoutTypePortlet.hasPortletId(portletId)) {
layoutTypePortlet.addPortletId(0, portletId, "column-1", -1, false);
LayoutLocalServiceUtil.updateLayout(
layout.getGroupId(), layout.isPrivateLayout(),
layout.getLayoutId(), layout.getTypeSettings());
PortletPreferencesFactoryUtil.getLayoutPortletSetup(
layout, portletId);
}
return layout;
}
protected String getPortletId(PortletContext portletContext)
throws Exception {
return portletContext.getPortletHandle();
}
protected String getPortletId(
PortletContext portletContext,
NavigationalContext navigationalContext)
throws Exception {
String portletId = getPortletId(portletContext);
if (navigationalContext == null) {
return portletId;
}
String opaqueValue = navigationalContext.getOpaqueValue();
if (Validator.isNotNull(opaqueValue)) {
opaqueValue = new String(
Base64.decodeFromURL(opaqueValue), StringPool.UTF8);
}
Map parameterMap = HttpUtil.parameterMapFromString(
opaqueValue);
String portletConfigurationPortletId = PortletProviderUtil.getPortletId(
PortletConfigurationApplicationType.PortletConfiguration.CLASS_NAME,
PortletProvider.Action.VIEW);
if (parameterMap.containsKey(
PortalUtil.getPortletNamespace(portletConfigurationPortletId) +
"portletConfiguration")) {
portletId = portletConfigurationPortletId;
}
return portletId;
}
protected String getPortletMode(MimeRequest mimeRequest) throws Exception {
String portletMode = mimeRequest.getMode();
return portletMode.substring(5);
}
protected String getRawContent(Http.Options httpOptions) throws Exception {
Map cookiesMap = new HashMap<>();
HttpSession session = ServletUtil.getSession();
Cookie[] sessionCookies = (Cookie[])session.getAttribute(
WebKeys.COOKIES);
if (sessionCookies != null) {
for (Cookie cookie : sessionCookies) {
cookiesMap.put(cookie.getName(), cookie);
}
}
HttpServletRequest request = ServletUtil.getRequest();
Cookie[] forwardCookies = request.getCookies();
if (forwardCookies != null) {
for (Cookie cookie : forwardCookies) {
String cookieName = cookie.getName();
if (!StringUtil.equalsIgnoreCase(
cookieName, "cookie_support") &&
!StringUtil.equalsIgnoreCase(
cookieName, "guest_language_id") &&
!StringUtil.equalsIgnoreCase(cookieName, "jsessionid")) {
if (Validator.isNull(cookie.getDomain())) {
cookie.setDomain(request.getServerName());
}
if (Validator.isNull(cookie.getPath())) {
cookie.setPath(StringPool.SLASH);
}
cookiesMap.put(cookieName, cookie);
}
}
}
if (!cookiesMap.isEmpty()) {
Collection cookiesCollection = cookiesMap.values();
httpOptions.setCookies(cookiesCollection.toArray(new Cookie[0]));
}
String rawContent = HttpUtil.URLtoString(httpOptions);
Cookie[] cookies = HttpUtil.getCookies();
if (cookies != null) {
session.setAttribute(WebKeys.COOKIES, cookies);
}
return rawContent;
}
protected String getURL(GetMarkup getMarkup, WSRPProducer wsrpProducer)
throws Exception {
return getURL(
"0", null, getMarkup.getMarkupParams(),
getMarkup.getPortletContext(), wsrpProducer);
}
protected String getURL(GetResource getResource, WSRPProducer wsrpProducer)
throws Exception {
ResourceParams resourceParams = getResource.getResourceParams();
return getURL(
"2", resourceParams.getResourceID(), resourceParams,
getResource.getPortletContext(), wsrpProducer);
}
protected String getURL(
PerformBlockingInteraction performBlockingInteraction,
WSRPProducer wsrpProducer)
throws Exception {
return getURL(
"1", null, performBlockingInteraction.getMarkupParams(),
performBlockingInteraction.getPortletContext(), wsrpProducer);
}
protected String getURL(
String lifecycle, String resourceID, MimeRequest mimeRequest,
PortletContext portletContext, WSRPProducer wsrpProducer)
throws Exception {
StringBundler sb = new StringBundler();
String[] locales = mimeRequest.getLocales();
if (locales.length > 0) {
sb.append(getWidgetPath(locales[0]));
}
else {
sb.append(getWidgetPath());
}
sb.append(StringPool.QUESTION);
String propertiesAuthenticatonTokenSharedSecret = DigesterUtil.digest(
PropsUtil.get(PropsKeys.AUTH_TOKEN_SHARED_SECRET));
sb.append("p_auth_secret=");
sb.append(URLCodec.encodeURL(propertiesAuthenticatonTokenSharedSecret));
Layout layout = getLayout(portletContext, wsrpProducer);
sb.append("&p_l_id=");
sb.append(layout.getPlid());
NavigationalContext navigationalContext =
mimeRequest.getNavigationalContext();
String portletId = getPortletId(portletContext, navigationalContext);
sb.append("&p_p_id=");
sb.append(URLCodec.encodeURL(portletId));
sb.append("&p_p_lifecycle=");
sb.append(lifecycle);
String windowState = getWindowState(mimeRequest);
sb.append("&p_p_state=");
sb.append(URLCodec.encodeURL(windowState));
String portletMode = getPortletMode(mimeRequest);
sb.append("&p_p_mode=");
sb.append(URLCodec.encodeURL(portletMode));
if (lifecycle.equals("2") && Validator.isNotNull(resourceID)) {
sb.append("&p_p_resource_id=");
sb.append(resourceID);
}
sb.append("&p_p_isolated=1");
String opaqueValue = null;
if (navigationalContext != null) {
opaqueValue = navigationalContext.getOpaqueValue();
}
if (Validator.isNotNull(opaqueValue)) {
sb.append(StringPool.AMPERSAND);
opaqueValue = new String(
Base64.decodeFromURL(opaqueValue), StringPool.UTF8);
sb.append(opaqueValue);
}
if (lifecycle.equals("0")) {
MessageElement[] formParameters =
ExtensionHelperUtil.getMessageElements(
mimeRequest.getExtensions());
if (formParameters != null) {
String namespace = PortalUtil.getPortletNamespace(portletId);
for (MessageElement formParameter : formParameters) {
sb.append(StringPool.AMPERSAND);
String name = namespace.concat(
ExtensionHelperUtil.getNameAttribute(formParameter));
sb.append(name);
sb.append(StringPool.EQUAL);
sb.append(URLCodec.encodeURL(formParameter.getValue()));
}
}
}
if (windowState.equals(LiferayWindowState.EXCLUSIVE.toString())) {
sb.append("&ensureContentLength=1");
}
sb.append("&wsrp=1");
if (_log.isInfoEnabled()) {
_log.info("URL " + sb.toString());
}
return sb.toString();
}
protected String getWidgetPath() {
return getWidgetPath(null);
}
protected String getWidgetPath(String languageId) {
HttpServletRequest request = ServletUtil.getRequest();
String portalURL = PortalUtil.getPortalURL(request);
StringBundler sb = new StringBundler(5);
sb.append(portalURL);
sb.append(PortalUtil.getPathContext());
String[] localesEnabled = PropsUtil.getArray(PropsKeys.LOCALES_ENABLED);
if (ArrayUtil.contains(localesEnabled, languageId)) {
sb.append(StringPool.SLASH);
sb.append(
StringUtil.replaceFirst(
languageId, CharPool.UNDERLINE, CharPool.DASH));
}
sb.append(_PATH_WIDGET);
return sb.toString();
}
protected String getWindowState(MimeRequest mimeRequest) throws Exception {
String windowState = mimeRequest.getWindowState();
return windowState.substring(5);
}
protected void processUploadContexts(
UploadContext[] uploadContexts, Http.Options httpOptions) {
if (uploadContexts == null) {
return;
}
for (UploadContext uploadContext : uploadContexts) {
NamedString mimeAttribute = uploadContext.getMimeAttributes(0);
String[] mimeAttributeValues = StringUtil.split(
mimeAttribute.getValue(), StringPool.SEMICOLON);
String name = StringUtil.replace(
mimeAttributeValues[1], "name=", StringPool.BLANK);
name = StringUtil.trim(name);
String fileName = StringUtil.replace(
mimeAttributeValues[2], "filename=", StringPool.BLANK);
fileName = StringUtil.trim(fileName);
String contentType = uploadContext.getMimeType();
String charSet = null;
if (contentType.contains(StringPool.SEMICOLON)) {
int pos = contentType.indexOf(StringPool.SEMICOLON);
charSet = contentType.substring(pos + 1);
charSet = StringUtil.trim(charSet);
contentType = contentType.substring(0, pos);
}
httpOptions.addFilePart(
name, fileName, uploadContext.getUploadData(), contentType,
charSet);
}
}
private static final String _PATH_WIDGET = "/widget/c/portal/layout";
private static final Log _log = LogFactoryUtil.getLog(
V2MarkupServiceImpl.class);
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy