All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.liferay.portal.poller.PollerRequestHandlerImpl Maven / Gradle / Ivy

There is a newer version: 7.0.0-nightly
Show newest version
/**
 * Copyright (c) 2000-2013 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.portal.poller;

import com.liferay.portal.kernel.exception.SystemException;
import com.liferay.portal.kernel.json.JSONFactoryUtil;
import com.liferay.portal.kernel.json.JSONObject;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.messaging.DestinationNames;
import com.liferay.portal.kernel.messaging.Message;
import com.liferay.portal.kernel.messaging.MessageBusUtil;
import com.liferay.portal.kernel.messaging.MessageListener;
import com.liferay.portal.kernel.poller.DefaultPollerResponse;
import com.liferay.portal.kernel.poller.PollerHeader;
import com.liferay.portal.kernel.poller.PollerProcessor;
import com.liferay.portal.kernel.poller.PollerRequest;
import com.liferay.portal.kernel.poller.PollerResponse;
import com.liferay.portal.kernel.util.GetterUtil;
import com.liferay.portal.kernel.util.StringPool;
import com.liferay.portal.kernel.util.StringUtil;
import com.liferay.portal.kernel.util.Validator;
import com.liferay.portal.kernel.uuid.PortalUUIDUtil;
import com.liferay.portal.model.BrowserTracker;
import com.liferay.portal.model.Company;
import com.liferay.portal.service.BrowserTrackerLocalServiceUtil;
import com.liferay.portal.service.CompanyLocalServiceUtil;
import com.liferay.util.Encryptor;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;

/**
 * @author Michael C. Han
 * @author Brian Wing Shun Chan
 * @author Edward Han
 */
public class PollerRequestHandlerImpl
	implements PollerRequestHandler, MessageListener {

	@Override
	public PollerHeader getPollerHeader(String pollerRequestString) {
		if (Validator.isNull(pollerRequestString)) {
			return null;
		}

		Map[] pollerRequestChunks =
			parsePollerRequestParameters(pollerRequestString);

		return parsePollerRequestHeader(pollerRequestChunks);
	}

	@Override
	public JSONObject processRequest(
			HttpServletRequest request, String pollerRequestString)
		throws Exception {

		if (Validator.isNull(pollerRequestString)) {
			return null;
		}

		Map[] pollerRequestChunks =
			parsePollerRequestParameters(pollerRequestString);

		PollerHeader pollerHeader = parsePollerRequestHeader(
			pollerRequestChunks);

		if (!isValidPollerHeader(pollerHeader)) {
			if (_log.isWarnEnabled()) {
				_log.warn(
					"Invalid poller header for request " +
						pollerRequestString);
			}

			return null;
		}

		boolean receiveRequest = isReceiveRequest(request.getPathInfo());

		String pollerSessionId = getPollerSessionId(pollerHeader);

		PollerSession pollerSession = null;

		synchronized (_pollerSessions) {
			pollerSession = _pollerSessions.get(pollerSessionId);

			if ((pollerSession == null) && receiveRequest) {
				pollerSession = new PollerSession(pollerSessionId);

				_pollerSessions.put(pollerSessionId, pollerSession);
			}
		}

		List pollerRequests = createPollerRequests(
			request, pollerHeader, pollerRequestChunks, receiveRequest);

		executePollerRequests(pollerSession, pollerRequests);

		if (receiveRequest) {
			return createPollerResponseHeader(pollerHeader);
		}
		else {
			return null;
		}
	}

	@Override
	public void receive(Message message) {
		Object messagePayload = message.getPayload();

		if (!(messagePayload instanceof PollerResponse)) {
			return;
		}

		PollerResponse pollerResponse = (PollerResponse)messagePayload;

		PollerHeader pollerHeader = pollerResponse.getPollerHeader();

		String pollerSessionId = getPollerSessionId(pollerHeader);

		synchronized (_pollerSessions) {
			PollerSession pollerSession = _pollerSessions.get(pollerSessionId);

			if ((pollerSession != null) &&
				pollerSession.completePortletProcessing(
					pollerResponse.getPortletId(), message.getResponseId())) {

				_pollerSessions.remove(pollerSessionId);
			}
		}
	}

	protected PollerRequest createPollerRequest(
			HttpServletRequest request, boolean receiveRequest,
			PollerHeader pollerHeader, String portletId)
		throws Exception {

		return createPollerRequest(
			request, receiveRequest, pollerHeader, portletId,
			new HashMap(), null);
	}

	protected PollerRequest createPollerRequest(
			HttpServletRequest request, boolean receiveRequest,
			PollerHeader pollerHeader, String portletId,
			Map parameterMap, String chunkId)
		throws Exception {

		PollerProcessor pollerProcessor =
			PollerProcessorUtil.getPollerProcessor(portletId);

		if (pollerProcessor == null) {
			if (_log.isWarnEnabled()) {
				_log.warn(
					"Poller processor not found for portlet " + portletId);
			}

			return null;
		}

		return new PollerRequest(
			request, pollerHeader, portletId, parameterMap, chunkId,
			receiveRequest);
	}

	protected List createPollerRequests(
			HttpServletRequest request, PollerHeader pollerHeader,
			Map[] pollerRequestChunks, boolean receiveRequest)
		throws Exception {

		Map portletIdsMap = pollerHeader.getPortletIdsMap();

		List pollerRequests = new ArrayList(
			portletIdsMap.size());

		Set receiveRequestPortletIds = null;

		if (receiveRequest) {
			receiveRequestPortletIds = new HashSet(
				(int)(pollerRequestChunks.length / 0.75) + 1);
		}

		for (int i = 1; i < pollerRequestChunks.length; i++) {
			Map pollerRequestChunk = pollerRequestChunks[i];

			String portletId = (String)pollerRequestChunk.get("portletId");
			Map parameterMap = parseData(pollerRequestChunk);
			String chunkId = (String)pollerRequestChunk.get("chunkId");

			try {
				PollerRequest pollerRequest = createPollerRequest(
					request, receiveRequest, pollerHeader, portletId,
					parameterMap, chunkId);

				pollerRequests.add(pollerRequest);

				if (receiveRequest) {
					receiveRequestPortletIds.add(portletId);
				}
			}
			catch (Exception e) {
				_log.error(e, e);
			}
		}

		if (receiveRequest) {
			Set portletIds = portletIdsMap.keySet();

			for (String portletId : portletIds) {
				if (receiveRequestPortletIds.contains(portletId)) {
					continue;
				}

				try {
					PollerRequest pollerRequest = createPollerRequest(
						request, receiveRequest, pollerHeader, portletId);

					pollerRequests.add(pollerRequest);
				}
				catch (Exception e) {
					_log.error(e, e);
				}
			}
		}

		return pollerRequests;
	}

	protected JSONObject createPollerResponseHeader(PollerHeader pollerHeader)
		throws SystemException {

		if (pollerHeader == null) {
			return null;
		}

		boolean suspendPolling = false;

		if (pollerHeader.isStartPolling()) {
			BrowserTrackerLocalServiceUtil.updateBrowserTracker(
				pollerHeader.getUserId(), pollerHeader.getBrowserKey());
		}
		else {
			BrowserTracker browserTracker =
				BrowserTrackerLocalServiceUtil.getBrowserTracker(
					pollerHeader.getUserId(), pollerHeader.getBrowserKey());

			if (browserTracker.getBrowserKey() !=
					pollerHeader.getBrowserKey()) {

				suspendPolling = true;
			}
		}

		JSONObject pollerResponseHeaderJSONObject =
			JSONFactoryUtil.createJSONObject();

		pollerResponseHeaderJSONObject.put("userId", pollerHeader.getUserId());
		pollerResponseHeaderJSONObject.put("suspendPolling", suspendPolling);

		return pollerResponseHeaderJSONObject;
	}

	protected void executePollerRequests(
		PollerSession pollerSession, List pollerRequests) {

		for (PollerRequest pollerRequest : pollerRequests) {
			PollerRequestResponsePair pollerRequestResponsePair =
				new PollerRequestResponsePair(pollerRequest);

			String responseId = null;

			if (pollerRequest.isReceiveRequest()) {
				responseId = PortalUUIDUtil.generate();

				PollerResponse pollerResponse = new DefaultPollerResponse(
					pollerRequest.getPollerHeader(),
					pollerRequest.getPortletId(), pollerRequest.getChunkId());

				pollerRequestResponsePair.setPollerResponse(pollerResponse);

				if (!pollerSession.beginPortletProcessing(
						pollerRequestResponsePair, responseId)) {

					continue;
				}
			}

			Message message = new Message();

			message.setPayload(pollerRequestResponsePair);

			if (pollerRequest.isReceiveRequest()) {
				message.setResponseId(responseId);

				message.setResponseDestinationName(
					DestinationNames.POLLER_RESPONSE);
			}

			MessageBusUtil.sendMessage(DestinationNames.POLLER, message);
		}
	}

	protected String fixPollerRequestString(String pollerRequestString) {
		if (Validator.isNull(pollerRequestString)) {
			return null;
		}

		return StringUtil.replace(
			pollerRequestString,
			new String[] {
				StringPool.OPEN_CURLY_BRACE, StringPool.CLOSE_CURLY_BRACE,
				_ESCAPED_OPEN_CURLY_BRACE, _ESCAPED_CLOSE_CURLY_BRACE
			},
			new String[] {
				_OPEN_HASH_MAP_WRAPPER, StringPool.DOUBLE_CLOSE_CURLY_BRACE,
				StringPool.OPEN_CURLY_BRACE, StringPool.CLOSE_CURLY_BRACE
			});
	}

	protected String getPollerSessionId(PollerHeader pollerHeader) {
		return String.valueOf(pollerHeader.getUserId());
	}

	protected long getUserId(long companyId, String userIdString) {
		long userId = 0;

		try {
			Company company = CompanyLocalServiceUtil.getCompany(companyId);

			userId = GetterUtil.getLong(
				Encryptor.decrypt(company.getKeyObj(), userIdString));
		}
		catch (Exception e) {
			_log.error(
				"Invalid credentials for company id " + companyId +
					" and user id " + userIdString);
		}

		return userId;
	}

	protected boolean isReceiveRequest(String path) {
		if ((path != null) && path.endsWith(_PATH_RECEIVE)) {
			return true;
		}
		else {
			return false;
		}
	}

	protected boolean isValidPollerHeader(PollerHeader pollerHeader) {
		if (pollerHeader == null) {
			return false;
		}

		Map portletIdsMap = pollerHeader.getPortletIdsMap();

		if ((portletIdsMap == null) || portletIdsMap.isEmpty()) {
			return false;
		}

		return true;
	}

	protected Map parseData(
			Map pollerRequestChunk)
		throws Exception {

		Map oldParameterMap =
			(Map)pollerRequestChunk.get("data");

		Map newParameterMap = new HashMap();

		if (oldParameterMap == null) {
			return newParameterMap;
		}

		for (Map.Entry entry : oldParameterMap.entrySet()) {
			newParameterMap.put(
				entry.getKey(), String.valueOf(entry.getValue()));
		}

		return newParameterMap;
	}

	protected PollerHeader parsePollerRequestHeader(
		Map[] pollerRequestChunks) {

		if ((pollerRequestChunks == null) || (pollerRequestChunks.length < 1)) {
			return null;
		}

		Map pollerRequestChunk = pollerRequestChunks[0];

		long browserKey = GetterUtil.getLong(
			String.valueOf(pollerRequestChunk.get("browserKey")));
		long companyId = GetterUtil.getLong(
			String.valueOf(pollerRequestChunk.get("companyId")));
		Map portletIdsMap =
			(Map)pollerRequestChunk.get("portletIdsMap");
		boolean startPolling = GetterUtil.getBoolean(
			String.valueOf(pollerRequestChunk.get("startPolling")));
		String userIdString = GetterUtil.getString(
			String.valueOf(pollerRequestChunk.get("userId")));

		long userId = getUserId(companyId, userIdString);

		if (userId == 0) {
			return null;
		}

		return new PollerHeader(
			companyId, userId, browserKey, portletIdsMap, startPolling);
	}

	protected Map[] parsePollerRequestParameters(
		String pollerRequestString) {

		String fixedPollerRequestString = fixPollerRequestString(
			pollerRequestString);

		return (Map[])JSONFactoryUtil.deserialize(
			fixedPollerRequestString);
	}

	private static final String _ESCAPED_CLOSE_CURLY_BRACE =
		"[$CLOSE_CURLY_BRACE$]";

	private static final String _ESCAPED_OPEN_CURLY_BRACE =
		"[$OPEN_CURLY_BRACE$]";

	private static final String _OPEN_HASH_MAP_WRAPPER =
		"{\"javaClass\":\"java.util.HashMap\",\"map\":{";

	private static final String _PATH_RECEIVE = "/receive";

	private static Log _log = LogFactoryUtil.getLog(
		PollerRequestHandlerImpl.class);

	private Map _pollerSessions =
		new HashMap();

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy