/** * 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.microblogs.service.impl; import com.liferay.asset.kernel.AssetRendererFactoryRegistryUtil; import com.liferay.asset.kernel.model.AssetRenderer; import com.liferay.asset.kernel.model.AssetRendererFactory; import com.liferay.microblogs.constants.MicroblogsPortletKeys; import com.liferay.microblogs.exception.UnsupportedMicroblogsEntryException; import com.liferay.microblogs.internal.social.MicroblogsActivityKeys; import com.liferay.microblogs.model.MicroblogsEntry; import com.liferay.microblogs.model.MicroblogsEntryConstants; import com.liferay.microblogs.service.base.MicroblogsEntryLocalServiceBaseImpl; import com.liferay.microblogs.util.MicroblogsUtil; import com.liferay.microblogs.util.comparator.EntryCreateDateComparator; import com.liferay.portal.kernel.exception.PortalException; 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.MessageBusUtil; import com.liferay.portal.kernel.model.Group; import com.liferay.portal.kernel.model.User; import com.liferay.portal.kernel.model.UserNotificationDeliveryConstants; import com.liferay.portal.kernel.process.ProcessCallable; import com.liferay.portal.kernel.process.ProcessException; import com.liferay.portal.kernel.search.Indexer; import com.liferay.portal.kernel.service.ServiceContext; import com.liferay.portal.kernel.transaction.TransactionCommitCallbackUtil; import com.liferay.portal.kernel.util.OrderByComparator; import com.liferay.portal.kernel.util.StringPool; import com.liferay.portal.kernel.util.StringUtil; import com.liferay.portal.spring.extender.service.ServiceReference; import com.liferay.subscription.model.Subscription; import com.liferay.subscription.service.SubscriptionLocalService; import java.io.Serializable; import java.util.Date; import java.util.List; import java.util.concurrent.Callable; /** * @author Jonathan Lee */ public class MicroblogsEntryLocalServiceImpl extends MicroblogsEntryLocalServiceBaseImpl { @Override public MicroblogsEntry addMicroblogsEntry( long userId, long creatorClassNameId, long creatorClassPK, String content, int type, long parentMicroblogsEntryId, int socialRelationType, ServiceContext serviceContext) throws PortalException { // Microblogs entry User user = userLocalService.getUser(userId); Date now = new Date(); validate(type, parentMicroblogsEntryId); long microblogsEntryId = counterLocalService.increment(); if (parentMicroblogsEntryId == 0) { parentMicroblogsEntryId = microblogsEntryId; } MicroblogsEntry microblogsEntry = microblogsEntryPersistence.create( microblogsEntryId); microblogsEntry.setCompanyId(user.getCompanyId()); microblogsEntry.setUserId(user.getUserId()); microblogsEntry.setUserName(user.getFullName()); microblogsEntry.setCreateDate(now); microblogsEntry.setModifiedDate(now); microblogsEntry.setCreatorClassNameId(creatorClassNameId); microblogsEntry.setCreatorClassPK(creatorClassPK); microblogsEntry.setContent(content); microblogsEntry.setType(type); microblogsEntry.setParentMicroblogsEntryId(parentMicroblogsEntryId); microblogsEntry.setSocialRelationType(socialRelationType); microblogsEntryPersistence.update(microblogsEntry); // Resources resourceLocalService.addModelResources(microblogsEntry, serviceContext); // Asset updateAsset( microblogsEntry, serviceContext.getAssetCategoryIds(), serviceContext.getAssetTagNames()); return microblogsEntry; } @Override public MicroblogsEntry addMicroblogsEntry( long userId, String content, int type, long parentMicroblogsEntryId, int socialRelationType, ServiceContext serviceContext) throws PortalException { // Microblogs entry User user = userLocalService.getUser(userId); Date now = new Date(); validate(type, parentMicroblogsEntryId); long microblogsEntryId = counterLocalService.increment(); if (parentMicroblogsEntryId == 0) { parentMicroblogsEntryId = microblogsEntryId; } MicroblogsEntry microblogsEntry = microblogsEntryPersistence.create( microblogsEntryId); microblogsEntry.setCompanyId(user.getCompanyId()); microblogsEntry.setUserId(user.getUserId()); microblogsEntry.setUserName(user.getFullName()); microblogsEntry.setCreateDate(now); microblogsEntry.setModifiedDate(now); microblogsEntry.setCreatorClassNameId( classNameLocalService.getClassNameId(User.class)); microblogsEntry.setCreatorClassPK(user.getUserId()); microblogsEntry.setContent(content); microblogsEntry.setType(type); microblogsEntry.setParentMicroblogsEntryId(parentMicroblogsEntryId); microblogsEntry.setSocialRelationType(socialRelationType); microblogsEntryPersistence.update(microblogsEntry); // Resources resourceLocalService.addModelResources(microblogsEntry, serviceContext); // Asset updateAsset( microblogsEntry, serviceContext.getAssetCategoryIds(), serviceContext.getAssetTagNames()); // Social int activityKey = MicroblogsActivityKeys.ADD_ENTRY; if (type == MicroblogsEntryConstants.TYPE_REPLY) { activityKey = MicroblogsActivityKeys.REPLY_ENTRY; } else if (type == MicroblogsEntryConstants.TYPE_REPOST) { activityKey = MicroblogsActivityKeys.REPOST_ENTRY; } JSONObject extraDataJSONObject = JSONFactoryUtil.createJSONObject(); extraDataJSONObject.put("content", microblogsEntry.getContent()); extraDataJSONObject.put( "parentMicroblogsEntryId", parentMicroblogsEntryId); socialActivityLocalService.addActivity( userId, 0, MicroblogsEntry.class.getName(), microblogsEntryId, activityKey, extraDataJSONObject.toString(), microblogsEntry.getParentMicroblogsEntryUserId()); // Notification subscribeUsers(microblogsEntry, serviceContext); sendNotificationEvent(microblogsEntry, serviceContext); return microblogsEntry; } @Override public void deleteMicroblogsEntries( long creatorClassNameId, long creatorClassPK) throws PortalException { microblogsEntryPersistence.removeByCCNI_CCPK( creatorClassNameId, creatorClassPK); } @Override public MicroblogsEntry deleteMicroblogsEntry(long microblogsEntryId) throws PortalException { MicroblogsEntry microblogsEntry = microblogsEntryPersistence.findByPrimaryKey(microblogsEntryId); return deleteMicroblogsEntry(microblogsEntry); } @Override public MicroblogsEntry deleteMicroblogsEntry( MicroblogsEntry microblogsEntry) throws PortalException { // Microblogs entry microblogsEntryPersistence.remove(microblogsEntry); // Asset assetEntryLocalService.deleteEntry( MicroblogsEntry.class.getName(), microblogsEntry.getMicroblogsEntryId()); // Social socialActivityLocalService.deleteActivities( MicroblogsEntry.class.getName(), microblogsEntry.getMicroblogsEntryId()); return microblogsEntry; } @Override public void deleteUserMicroblogsEntries(long userId) throws PortalException { List<MicroblogsEntry> microblogsEntries = microblogsEntryPersistence.findByUserId(userId); for (MicroblogsEntry microblogsEntry : microblogsEntries) { deleteMicroblogsEntry(microblogsEntry); } } @Override public List<MicroblogsEntry> getCompanyMicroblogsEntries( long companyId, int start, int end) { return microblogsEntryPersistence.findByCompanyId( companyId, start, end); } @Override public int getCompanyMicroblogsEntriesCount(long companyId) { return microblogsEntryPersistence.countByCompanyId(companyId); } /** * @deprecated As of 2.1.0 */ @Deprecated @Override public List<MicroblogsEntry> getMicroblogsEntries( long creatorClassNameId, int type, int start, int end, OrderByComparator obc) { return microblogsEntryPersistence.findByCCNI_T( creatorClassNameId, type, start, end, obc); } /** * @deprecated As of 2.1.0 */ @Deprecated @Override public List<MicroblogsEntry> getMicroblogsEntries( long creatorClassNameId, long creatorClassPK, int start, int end) { return microblogsEntryPersistence.findByCCNI_CCPK( creatorClassNameId, creatorClassPK, start, end); } /** * @deprecated As of 2.1.0 */ @Deprecated @Override public List<MicroblogsEntry> getMicroblogsEntries( long creatorClassNameId, long creatorClassPK, int type, int start, int end) { return microblogsEntryPersistence.findByCCNI_CCPK_T( creatorClassNameId, creatorClassPK, type, start, end); } @Override public List<MicroblogsEntry> getMicroblogsEntries( long companyId, long creatorClassNameId, int type, int start, int end, OrderByComparator obc) { return microblogsEntryPersistence.findByC_CCNI_T( companyId, creatorClassNameId, type, start, end, obc); } @Override public List<MicroblogsEntry> getMicroblogsEntries( long companyId, long creatorClassNameId, long creatorClassPK, int start, int end) { return microblogsEntryPersistence.findByC_CCNI_CCPK( companyId, creatorClassNameId, creatorClassPK, start, end); } @Override public List<MicroblogsEntry> getMicroblogsEntries( long companyId, long creatorClassNameId, long creatorClassPK, int type, int start, int end) { return microblogsEntryPersistence.findByC_CCNI_CCPK_T( companyId, creatorClassNameId, creatorClassPK, type, start, end); } @Override public List<MicroblogsEntry> getMicroblogsEntries( long companyId, long creatorClassNameId, long creatorClassPK, String assetTagName, boolean andOperator, int start, int end) { return microblogsEntryFinder.findByC_CCNI_CCPK_ATN( companyId, creatorClassNameId, creatorClassPK, assetTagName, andOperator, start, end); } /** * @deprecated As of 2.1.0 */ @Deprecated @Override public List<MicroblogsEntry> getMicroblogsEntries( long creatorClassNameId, long creatorClassPK, String assetTagName, boolean andOperator, int start, int end) { return microblogsEntryFinder.findByCCNI_CCPK_ATN( creatorClassNameId, creatorClassPK, assetTagName, andOperator, start, end); } @Override public List<MicroblogsEntry> getMicroblogsEntries( long companyId, long creatorClassNameId, String assetTagName, int start, int end) { return microblogsEntryFinder.findByC_CCNI_ATN( companyId, creatorClassNameId, assetTagName, start, end); } /** * @deprecated As of 2.1.0 */ @Deprecated @Override public List<MicroblogsEntry> getMicroblogsEntries( long creatorClassNameId, String assetTagName, int start, int end) { return microblogsEntryFinder.findByCCNI_ATN( creatorClassNameId, assetTagName, start, end); } /** * @deprecated As of 2.1.0 */ @Deprecated @Override public int getMicroblogsEntriesCount( long creatorClassNameId, long creatorClassPK) { return microblogsEntryPersistence.countByCCNI_CCPK( creatorClassNameId, creatorClassPK); } /** * @deprecated As of 2.1.0 */ @Deprecated @Override public int getMicroblogsEntriesCount( long creatorClassNameId, long creatorClassPK, int type) { return microblogsEntryPersistence.countByCCNI_CCPK_T( creatorClassNameId, creatorClassPK, type); } @Override public int getMicroblogsEntriesCount( long companyId, long creatorClassNameId, long creatorClassPK) { return microblogsEntryPersistence.countByC_CCNI_CCPK( companyId, creatorClassNameId, creatorClassPK); } @Override public int getMicroblogsEntriesCount( long companyId, long creatorClassNameId, long creatorClassPK, int type) { return microblogsEntryPersistence.countByC_CCNI_CCPK_T( companyId, creatorClassNameId, creatorClassPK, type); } @Override public int getMicroblogsEntriesCount( long companyId, long creatorClassNameId, long creatorClassPK, String assetTagName, boolean andOperator) { return microblogsEntryFinder.countByC_CCNI_CCPK_ATN( companyId, creatorClassNameId, creatorClassPK, assetTagName, andOperator); } @Override public int getMicroblogsEntriesCount( long companyId, long creatorClassNameId, String assetTagName) { return microblogsEntryFinder.countByC_CCNI_ATN( companyId, creatorClassNameId, assetTagName); } /** * @deprecated As of 2.1.0 */ @Deprecated @Override public int getMicroblogsEntriesCount( long creatorClassNameId, long creatorClassPK, String assetTagName, boolean andOperator) { return microblogsEntryFinder.countByCCNI_CCPK_ATN( creatorClassNameId, creatorClassPK, assetTagName, andOperator); } /** * @deprecated As of 2.1.0 */ @Deprecated @Override public int getMicroblogsEntriesCount( long creatorClassNameId, String assetTagName) { return microblogsEntryFinder.countByCCNI_ATN( creatorClassNameId, assetTagName); } @Override public MicroblogsEntry getMicroblogsEntry(long microblogsEntryId) throws PortalException { return microblogsEntryPersistence.findByPrimaryKey(microblogsEntryId); } @Override public List<MicroblogsEntry> getParentMicroblogsEntryMicroblogsEntries( int type, long parentMicroblogsEntryId, int start, int end) { return microblogsEntryPersistence.findByT_P( type, parentMicroblogsEntryId, start, end, new EntryCreateDateComparator(true)); } @Override public List<MicroblogsEntry> getParentMicroblogsEntryMicroblogsEntries( int type, long parentMicroblogsEntryId, int start, int end, OrderByComparator<MicroblogsEntry> orderByComparator) { return microblogsEntryPersistence.findByT_P( type, parentMicroblogsEntryId, start, end, orderByComparator); } @Override public int getParentMicroblogsEntryMicroblogsEntriesCount( int type, long parentMicroblogsEntryId) { return microblogsEntryPersistence.countByT_P( type, parentMicroblogsEntryId); } @Override public List<MicroblogsEntry> getUserMicroblogsEntries( long userId, int start, int end) { return microblogsEntryPersistence.findByUserId(userId, start, end); } @Override public List<MicroblogsEntry> getUserMicroblogsEntries( long userId, int type, int start, int end) { return microblogsEntryPersistence.findByU_T(userId, type, start, end); } @Override public int getUserMicroblogsEntriesCount(long userId) { return microblogsEntryPersistence.countByUserId(userId); } @Override public int getUserMicroblogsEntriesCount(long userId, int type) { return microblogsEntryPersistence.countByU_T(userId, type); } @Override public void updateAsset( MicroblogsEntry microblogsEntry, long[] assetCategoryIds, String[] assetTagNames) throws PortalException { Group group = groupLocalService.getCompanyGroup( microblogsEntry.getCompanyId()); assetEntryLocalService.updateEntry( microblogsEntry.getUserId(), group.getGroupId(), MicroblogsEntry.class.getName(), microblogsEntry.getMicroblogsEntryId(), assetCategoryIds, assetTagNames); } @Override public MicroblogsEntry updateMicroblogsEntry( long microblogsEntryId, String content, int socialRelationType, ServiceContext serviceContext) throws PortalException { // Microblogs entry MicroblogsEntry microblogsEntry = microblogsEntryPersistence.findByPrimaryKey(microblogsEntryId); microblogsEntry.setModifiedDate(new Date()); microblogsEntry.setContent(content); microblogsEntry.setSocialRelationType(socialRelationType); microblogsEntryPersistence.update(microblogsEntry); // Asset updateAsset( microblogsEntry, serviceContext.getAssetCategoryIds(), serviceContext.getAssetTagNames()); return microblogsEntry; } protected long getSubscriptionId( long userId, MicroblogsEntry microblogsEntry) { try { Subscription subscription = subscriptionLocalService.getSubscription( microblogsEntry.getCompanyId(), userId, MicroblogsEntry.class.getName(), microblogsEntry.getParentMicroblogsEntryId()); return subscription.getSubscriptionId(); } catch (PortalException pe) { if (_log.isDebugEnabled()) { _log.debug(pe, pe); } } return 0; } protected void sendNotificationEvent( final MicroblogsEntry microblogsEntry, ServiceContext serviceContext) throws PortalException { final JSONObject notificationEventJSONObject = JSONFactoryUtil.createJSONObject(); notificationEventJSONObject.put( "className", MicroblogsEntry.class.getName()); notificationEventJSONObject.put( "classPK", microblogsEntry.getMicroblogsEntryId()); notificationEventJSONObject.put( "entryTitle", MicroblogsUtil.getProcessedContent( StringUtil.shorten(microblogsEntry.getContent(), 50), serviceContext)); AssetRendererFactory<MicroblogsEntry> assetRendererFactory = AssetRendererFactoryRegistryUtil.getAssetRendererFactoryByClass( MicroblogsEntry.class); AssetRenderer<MicroblogsEntry> assetRenderer = assetRendererFactory.getAssetRenderer( microblogsEntry.getMicroblogsEntryId()); String entryURL = StringPool.BLANK; try { entryURL = assetRenderer.getURLViewInContext( serviceContext.getLiferayPortletRequest(), serviceContext.getLiferayPortletResponse(), null); } catch (Exception e) { if (_log.isDebugEnabled()) { _log.debug(e, e); } } notificationEventJSONObject.put("entryURL", entryURL); notificationEventJSONObject.put("userId", microblogsEntry.getUserId()); final List<Long> receiverUserIds = MicroblogsUtil.getSubscriberUserIds( microblogsEntry); Callable<Void> callable = new Callable<Void>() { @Override public Void call() throws Exception { MessageBusUtil.sendMessage( DestinationNames.ASYNC_SERVICE, new NotificationProcessCallable( receiverUserIds, microblogsEntry, notificationEventJSONObject)); return null; } }; TransactionCommitCallbackUtil.registerCallback(callable); } protected void subscribeUsers( MicroblogsEntry microblogsEntry, ServiceContext serviceContext) throws PortalException { long rootMicroblogsEntryId = MicroblogsUtil.getRootMicroblogsEntryId( microblogsEntry); subscriptionLocalService.addSubscription( microblogsEntry.getUserId(), serviceContext.getScopeGroupId(), MicroblogsEntry.class.getName(), rootMicroblogsEntryId); List<String> screenNames = MicroblogsUtil.getScreenNames( microblogsEntry.getContent()); for (String screenName : screenNames) { long userId = userLocalService.getUserIdByScreenName( serviceContext.getCompanyId(), screenName); subscriptionLocalService.addSubscription( userId, serviceContext.getScopeGroupId(), MicroblogsEntry.class.getName(), rootMicroblogsEntryId); } } protected void validate(int type, long parentMicroblogsEntryId) throws PortalException { if (parentMicroblogsEntryId == 0) { return; } MicroblogsEntry microblogsEntry = microblogsEntryPersistence.findByPrimaryKey( parentMicroblogsEntryId); if (microblogsEntry.getSocialRelationType() == MicroblogsEntryConstants.TYPE_EVERYONE) { return; } if (type == MicroblogsEntryConstants.TYPE_REPOST) { throw new UnsupportedMicroblogsEntryException(); } } @ServiceReference(type = SubscriptionLocalService.class) protected SubscriptionLocalService subscriptionLocalService; private static final Log _log = LogFactoryUtil.getLog( MicroblogsEntryLocalServiceImpl.class); private class NotificationProcessCallable implements ProcessCallable<Serializable> { public NotificationProcessCallable( List<Long> receiverUserIds, MicroblogsEntry microblogsEntry, JSONObject notificationEventJSONObject) { _receiverUserIds = receiverUserIds; _microblogsEntry = microblogsEntry; _notificationEventJSONObject = notificationEventJSONObject; } @Override public Serializable call() throws ProcessException { try { sendUserNotifications( _receiverUserIds, _microblogsEntry, _notificationEventJSONObject); } catch (Exception e) { throw new ProcessException(e); } return null; } protected void sendUserNotifications( List<Long> receiverUserIds, MicroblogsEntry microblogsEntry, JSONObject notificationEventJSONObject) throws PortalException { int count = receiverUserIds.size(); int pages = count / Indexer.DEFAULT_INTERVAL; for (int i = 0; i <= pages; i++) { int start = i * Indexer.DEFAULT_INTERVAL; int end = start + Indexer.DEFAULT_INTERVAL; if (count < end) { end = count; } for (int j = start; j < end; j++) { long subscriptionId = getSubscriptionId( receiverUserIds.get(j), microblogsEntry); notificationEventJSONObject.put( "subscriptionId", subscriptionId); int notificationType = MicroblogsUtil.getNotificationType( microblogsEntry, receiverUserIds.get(j), UserNotificationDeliveryConstants.TYPE_PUSH); if (notificationType != MicroblogsEntryConstants. NOTIFICATION_TYPE_UNKNOWN) { notificationEventJSONObject.put( "notificationType", notificationType); userNotificationEventLocalService. sendUserNotificationEvents( receiverUserIds.get(j), MicroblogsPortletKeys.MICROBLOGS, UserNotificationDeliveryConstants.TYPE_PUSH, notificationEventJSONObject); } notificationType = MicroblogsUtil.getNotificationType( microblogsEntry, receiverUserIds.get(j), UserNotificationDeliveryConstants.TYPE_WEBSITE); if (notificationType != MicroblogsEntryConstants. NOTIFICATION_TYPE_UNKNOWN) { notificationEventJSONObject.put( "notificationType", notificationType); userNotificationEventLocalService. sendUserNotificationEvents( receiverUserIds.get(j), MicroblogsPortletKeys.MICROBLOGS, UserNotificationDeliveryConstants.TYPE_WEBSITE, notificationEventJSONObject); } } } } private static final long serialVersionUID = 1L; private final MicroblogsEntry _microblogsEntry; private final JSONObject _notificationEventJSONObject; private final List<Long> _receiverUserIds; } }