001    /**
002     * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.repository.capabilities;
016    
017    import com.liferay.document.library.kernel.model.DLSyncConstants;
018    import com.liferay.document.library.kernel.model.DLSyncEvent;
019    import com.liferay.document.library.kernel.service.DLSyncEventLocalService;
020    import com.liferay.portal.kernel.messaging.DestinationNames;
021    import com.liferay.portal.kernel.messaging.Message;
022    import com.liferay.portal.kernel.messaging.MessageBusUtil;
023    import com.liferay.portal.kernel.model.Group;
024    import com.liferay.portal.kernel.repository.capabilities.SyncCapability;
025    import com.liferay.portal.kernel.repository.event.RepositoryEventAware;
026    import com.liferay.portal.kernel.repository.event.RepositoryEventListener;
027    import com.liferay.portal.kernel.repository.event.RepositoryEventType;
028    import com.liferay.portal.kernel.repository.event.TrashRepositoryEventType;
029    import com.liferay.portal.kernel.repository.event.WorkflowRepositoryEventType;
030    import com.liferay.portal.kernel.repository.model.FileEntry;
031    import com.liferay.portal.kernel.repository.model.Folder;
032    import com.liferay.portal.kernel.repository.registry.RepositoryEventRegistry;
033    import com.liferay.portal.kernel.transaction.TransactionCommitCallbackUtil;
034    import com.liferay.portal.repository.capabilities.util.GroupServiceAdapter;
035    import com.liferay.portal.repository.liferayrepository.model.LiferayFileEntry;
036    import com.liferay.portal.repository.liferayrepository.model.LiferayFolder;
037    
038    import java.util.HashMap;
039    import java.util.Map;
040    import java.util.concurrent.Callable;
041    
042    /**
043     * @author Adolfo P??rez
044     */
045    public class LiferaySyncCapability
046            implements RepositoryEventAware, SyncCapability {
047    
048            public LiferaySyncCapability(
049                    GroupServiceAdapter groupServiceAdapter,
050                    DLSyncEventLocalService dlSyncEventLocalService) {
051    
052                    _groupServiceAdapter = groupServiceAdapter;
053                    _dlSyncEventLocalService = dlSyncEventLocalService;
054            }
055    
056            @Override
057            public void registerRepositoryEventListeners(
058                    RepositoryEventRegistry repositoryEventRegistry) {
059    
060                    repositoryEventRegistry.registerRepositoryEventListener(
061                            RepositoryEventType.Add.class, Folder.class,
062                            _ADD_FOLDER_EVENT_LISTENER);
063                    repositoryEventRegistry.registerRepositoryEventListener(
064                            RepositoryEventType.Delete.class, FileEntry.class,
065                            _DELETE_FILE_ENTRY_EVENT_LISTENER);
066                    repositoryEventRegistry.registerRepositoryEventListener(
067                            RepositoryEventType.Delete.class, Folder.class,
068                            _DELETE_FOLDER_EVENT_LISTENER);
069                    repositoryEventRegistry.registerRepositoryEventListener(
070                            RepositoryEventType.Move.class, FileEntry.class,
071                            _MOVE_FILE_ENTRY_EVENT_LISTENER);
072                    repositoryEventRegistry.registerRepositoryEventListener(
073                            RepositoryEventType.Move.class, Folder.class,
074                            _MOVE_FOLDER_EVENT_LISTENER);
075                    repositoryEventRegistry.registerRepositoryEventListener(
076                            TrashRepositoryEventType.EntryRestored.class, FileEntry.class,
077                            _RESTORE_FILE_ENTRY_EVENT_LISTENER);
078                    repositoryEventRegistry.registerRepositoryEventListener(
079                            TrashRepositoryEventType.EntryRestored.class, Folder.class,
080                            _RESTORE_FOLDER_EVENT_LISTENER);
081                    repositoryEventRegistry.registerRepositoryEventListener(
082                            TrashRepositoryEventType.EntryTrashed.class, FileEntry.class,
083                            _TRASH_FILE_ENTRY_EVENT_LISTENER);
084                    repositoryEventRegistry.registerRepositoryEventListener(
085                            TrashRepositoryEventType.EntryTrashed.class, Folder.class,
086                            _TRASH_FOLDER_EVENT_LISTENER);
087                    repositoryEventRegistry.registerRepositoryEventListener(
088                            RepositoryEventType.Update.class, FileEntry.class,
089                            _UPDATE_FILE_ENTRY_EVENT_LISTENER);
090                    repositoryEventRegistry.registerRepositoryEventListener(
091                            RepositoryEventType.Update.class, Folder.class,
092                            _UPDATE_FOLDER_EVENT_LISTENER);
093                    repositoryEventRegistry.registerRepositoryEventListener(
094                            WorkflowRepositoryEventType.Add.class, FileEntry.class,
095                            _WORKFLOW_ADD_FILE_ENTRY_EVENT_LISTENER);
096                    repositoryEventRegistry.registerRepositoryEventListener(
097                            WorkflowRepositoryEventType.Update.class, FileEntry.class,
098                            _WORKFLOW_UPDATE_FILE_ENTRY_EVENT_LISTENER);
099            }
100    
101            protected boolean isStagingGroup(long groupId) {
102                    try {
103                            Group group = _groupServiceAdapter.getGroup(groupId);
104    
105                            return group.isStagingGroup();
106                    }
107                    catch (Exception e) {
108                            return false;
109                    }
110            }
111    
112            protected void registerDLSyncEventCallback(
113                    String event, FileEntry fileEntry) {
114    
115                    if (isStagingGroup(fileEntry.getGroupId()) ||
116                            !(fileEntry instanceof LiferayFileEntry)) {
117    
118                            return;
119                    }
120    
121                    registerDLSyncEventCallback(
122                            event, DLSyncConstants.TYPE_FILE, fileEntry.getFileEntryId());
123            }
124    
125            protected void registerDLSyncEventCallback(String event, Folder folder) {
126                    if (isStagingGroup(folder.getGroupId()) ||
127                            !(folder instanceof LiferayFolder)) {
128    
129                            return;
130                    }
131    
132                    registerDLSyncEventCallback(
133                            event, DLSyncConstants.TYPE_FOLDER, folder.getFolderId());
134            }
135    
136            protected void registerDLSyncEventCallback(
137                    final String event, final String type, final long typePK) {
138    
139                    DLSyncEvent dlSyncEvent = _dlSyncEventLocalService.addDLSyncEvent(
140                            event, type, typePK);
141    
142                    final long modifiedTime = dlSyncEvent.getModifiedTime();
143    
144                    TransactionCommitCallbackUtil.registerCallback(
145                            new Callable<Void>() {
146    
147                                    @Override
148                                    public Void call() throws Exception {
149                                            Message message = new Message();
150    
151                                            Map<String, Object> values = new HashMap<>(4);
152    
153                                            values.put("event", event);
154                                            values.put("modifiedTime", modifiedTime);
155                                            values.put("type", type);
156                                            values.put("typePK", typePK);
157    
158                                            message.setValues(values);
159    
160                                            MessageBusUtil.sendMessage(
161                                                    DestinationNames.DOCUMENT_LIBRARY_SYNC_EVENT_PROCESSOR,
162                                                    message);
163    
164                                            return null;
165                                    }
166    
167                            });
168            }
169    
170            private final RepositoryEventListener
171                    <RepositoryEventType.Add, Folder> _ADD_FOLDER_EVENT_LISTENER =
172                            new SyncFolderRepositoryEventListener<>(DLSyncConstants.EVENT_ADD);
173    
174            private final RepositoryEventListener
175                    <RepositoryEventType.Delete, FileEntry>
176                            _DELETE_FILE_ENTRY_EVENT_LISTENER =
177                                    new SyncFileEntryRepositoryEventListener<>(
178                                            DLSyncConstants.EVENT_DELETE);
179    
180            private final RepositoryEventListener
181                    <RepositoryEventType.Delete, Folder> _DELETE_FOLDER_EVENT_LISTENER =
182                            new SyncFolderRepositoryEventListener<>(
183                                    DLSyncConstants.EVENT_DELETE);
184    
185            private final RepositoryEventListener
186                    <RepositoryEventType.Move, FileEntry> _MOVE_FILE_ENTRY_EVENT_LISTENER =
187                            new SyncFileEntryRepositoryEventListener<>(
188                                    DLSyncConstants.EVENT_MOVE);
189    
190            private final RepositoryEventListener
191                    <RepositoryEventType.Move, Folder> _MOVE_FOLDER_EVENT_LISTENER =
192                            new SyncFolderRepositoryEventListener<>(DLSyncConstants.EVENT_MOVE);
193    
194            private final RepositoryEventListener
195                    <TrashRepositoryEventType.EntryRestored, FileEntry>
196                            _RESTORE_FILE_ENTRY_EVENT_LISTENER =
197                                    new SyncFileEntryRepositoryEventListener<>(
198                                            DLSyncConstants.EVENT_RESTORE);
199    
200            private final RepositoryEventListener
201                    <TrashRepositoryEventType.EntryRestored, Folder>
202                            _RESTORE_FOLDER_EVENT_LISTENER =
203                                    new SyncFolderRepositoryEventListener<>(
204                                            DLSyncConstants.EVENT_RESTORE);
205    
206            private final RepositoryEventListener
207                    <TrashRepositoryEventType.EntryTrashed, FileEntry>
208                            _TRASH_FILE_ENTRY_EVENT_LISTENER =
209                                    new SyncFileEntryRepositoryEventListener<>(
210                                            DLSyncConstants.EVENT_TRASH);
211    
212            private final RepositoryEventListener
213                    <TrashRepositoryEventType.EntryTrashed, Folder>
214                            _TRASH_FOLDER_EVENT_LISTENER =
215                                    new SyncFolderRepositoryEventListener<>(
216                                            DLSyncConstants.EVENT_TRASH);
217    
218            private final RepositoryEventListener
219                    <RepositoryEventType.Update, FileEntry>
220                            _UPDATE_FILE_ENTRY_EVENT_LISTENER =
221                                    new SyncFileEntryRepositoryEventListener<>(
222                                            DLSyncConstants.EVENT_UPDATE);
223    
224            private final RepositoryEventListener
225                    <RepositoryEventType.Update, Folder> _UPDATE_FOLDER_EVENT_LISTENER =
226                            new SyncFolderRepositoryEventListener<>(
227                                    DLSyncConstants.EVENT_UPDATE);
228    
229            private final RepositoryEventListener
230                    <WorkflowRepositoryEventType.Add, FileEntry>
231                            _WORKFLOW_ADD_FILE_ENTRY_EVENT_LISTENER =
232                                    new SyncFileEntryRepositoryEventListener<>(
233                                            DLSyncConstants.EVENT_ADD);
234    
235            private final RepositoryEventListener
236                    <WorkflowRepositoryEventType.Update, FileEntry>
237                            _WORKFLOW_UPDATE_FILE_ENTRY_EVENT_LISTENER =
238                                    new SyncFileEntryRepositoryEventListener<>(
239                                            DLSyncConstants.EVENT_UPDATE);
240    
241            private final DLSyncEventLocalService _dlSyncEventLocalService;
242            private final GroupServiceAdapter _groupServiceAdapter;
243    
244            private class SyncFileEntryRepositoryEventListener
245                    <S extends RepositoryEventType>
246                            implements RepositoryEventListener<S, FileEntry> {
247    
248                    public SyncFileEntryRepositoryEventListener(String syncEvent) {
249                            _syncEvent = syncEvent;
250                    }
251    
252                    @Override
253                    public void execute(FileEntry fileEntry) {
254                            registerDLSyncEventCallback(_syncEvent, fileEntry);
255                    }
256    
257                    private final String _syncEvent;
258    
259            }
260    
261            private class SyncFolderRepositoryEventListener
262                    <S extends RepositoryEventType>
263                            implements RepositoryEventListener<S, Folder> {
264    
265                    public SyncFolderRepositoryEventListener(String syncEvent) {
266                            _syncEvent = syncEvent;
267                    }
268    
269                    @Override
270                    public void execute(Folder folder) {
271                            registerDLSyncEventCallback(_syncEvent, folder);
272                    }
273    
274                    private final String _syncEvent;
275    
276            }
277    
278    }