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.portal.kernel.messaging.DestinationNames;
018    import com.liferay.portal.kernel.messaging.Message;
019    import com.liferay.portal.kernel.messaging.MessageBusUtil;
020    import com.liferay.portal.kernel.repository.capabilities.SyncCapability;
021    import com.liferay.portal.kernel.repository.event.RepositoryEventAware;
022    import com.liferay.portal.kernel.repository.event.RepositoryEventListener;
023    import com.liferay.portal.kernel.repository.event.RepositoryEventType;
024    import com.liferay.portal.kernel.repository.event.TrashRepositoryEventType;
025    import com.liferay.portal.kernel.repository.event.WorkflowRepositoryEventType;
026    import com.liferay.portal.kernel.repository.model.FileEntry;
027    import com.liferay.portal.kernel.repository.model.Folder;
028    import com.liferay.portal.kernel.repository.registry.RepositoryEventRegistry;
029    import com.liferay.portal.kernel.transaction.TransactionCommitCallbackUtil;
030    import com.liferay.portal.model.Group;
031    import com.liferay.portal.repository.capabilities.util.GroupServiceAdapter;
032    import com.liferay.portal.repository.liferayrepository.model.LiferayFileEntry;
033    import com.liferay.portal.repository.liferayrepository.model.LiferayFolder;
034    import com.liferay.portlet.documentlibrary.model.DLSyncConstants;
035    import com.liferay.portlet.documentlibrary.model.DLSyncEvent;
036    import com.liferay.portlet.documentlibrary.service.DLSyncEventLocalService;
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    
171            private final RepositoryEventListener
172                    <RepositoryEventType.Add, Folder> _ADD_FOLDER_EVENT_LISTENER =
173                            new SyncFolderRepositoryEventListener<>(DLSyncConstants.EVENT_ADD);
174    
175            private final RepositoryEventListener
176                    <RepositoryEventType.Delete, FileEntry>
177                            _DELETE_FILE_ENTRY_EVENT_LISTENER =
178                                    new SyncFileEntryRepositoryEventListener<>(
179                                            DLSyncConstants.EVENT_DELETE);
180    
181            private final RepositoryEventListener
182                    <RepositoryEventType.Delete, Folder> _DELETE_FOLDER_EVENT_LISTENER =
183                            new SyncFolderRepositoryEventListener<>(
184                                    DLSyncConstants.EVENT_DELETE);
185    
186            private final RepositoryEventListener
187                    <RepositoryEventType.Move, FileEntry> _MOVE_FILE_ENTRY_EVENT_LISTENER =
188                            new SyncFileEntryRepositoryEventListener<>(
189                                    DLSyncConstants.EVENT_MOVE);
190    
191            private final RepositoryEventListener
192                    <RepositoryEventType.Move, Folder> _MOVE_FOLDER_EVENT_LISTENER =
193                            new SyncFolderRepositoryEventListener<>(DLSyncConstants.EVENT_MOVE);
194    
195            private final RepositoryEventListener
196                    <TrashRepositoryEventType.EntryRestored, FileEntry>
197                            _RESTORE_FILE_ENTRY_EVENT_LISTENER =
198                                    new SyncFileEntryRepositoryEventListener<>(
199                                            DLSyncConstants.EVENT_RESTORE);
200    
201            private final RepositoryEventListener
202                    <TrashRepositoryEventType.EntryRestored, Folder>
203                            _RESTORE_FOLDER_EVENT_LISTENER =
204                                    new SyncFolderRepositoryEventListener<>(
205                                            DLSyncConstants.EVENT_RESTORE);
206    
207            private final RepositoryEventListener
208                    <TrashRepositoryEventType.EntryTrashed, FileEntry>
209                            _TRASH_FILE_ENTRY_EVENT_LISTENER =
210                                    new SyncFileEntryRepositoryEventListener<>(
211                                            DLSyncConstants.EVENT_TRASH);
212    
213            private final RepositoryEventListener
214                    <TrashRepositoryEventType.EntryTrashed, Folder>
215                            _TRASH_FOLDER_EVENT_LISTENER =
216                                    new SyncFolderRepositoryEventListener<>(
217                                            DLSyncConstants.EVENT_TRASH);
218    
219            private final RepositoryEventListener
220                    <RepositoryEventType.Update, FileEntry>
221                            _UPDATE_FILE_ENTRY_EVENT_LISTENER =
222                                    new SyncFileEntryRepositoryEventListener<>(
223                                            DLSyncConstants.EVENT_UPDATE);
224    
225            private final RepositoryEventListener
226                    <RepositoryEventType.Update, Folder> _UPDATE_FOLDER_EVENT_LISTENER =
227                            new SyncFolderRepositoryEventListener<>(
228                                    DLSyncConstants.EVENT_UPDATE);
229    
230            private final RepositoryEventListener
231                    <WorkflowRepositoryEventType.Add, FileEntry>
232                            _WORKFLOW_ADD_FILE_ENTRY_EVENT_LISTENER =
233                                    new SyncFileEntryRepositoryEventListener<>(
234                                            DLSyncConstants.EVENT_ADD);
235    
236            private final RepositoryEventListener
237                    <WorkflowRepositoryEventType.Update, FileEntry>
238                            _WORKFLOW_UPDATE_FILE_ENTRY_EVENT_LISTENER =
239                                    new SyncFileEntryRepositoryEventListener<>(
240                                            DLSyncConstants.EVENT_UPDATE);
241    
242            private final DLSyncEventLocalService _dlSyncEventLocalService;
243            private final GroupServiceAdapter _groupServiceAdapter;
244    
245            private class SyncFileEntryRepositoryEventListener
246                    <S extends RepositoryEventType>
247                            implements RepositoryEventListener<S, FileEntry> {
248    
249                    public SyncFileEntryRepositoryEventListener(String syncEvent) {
250                            _syncEvent = syncEvent;
251                    }
252    
253                    @Override
254                    public void execute(FileEntry fileEntry) {
255                            registerDLSyncEventCallback(_syncEvent, fileEntry);
256                    }
257    
258                    private final String _syncEvent;
259    
260            }
261    
262            private class SyncFolderRepositoryEventListener
263                    <S extends RepositoryEventType>
264                            implements RepositoryEventListener<S, Folder> {
265    
266                    public SyncFolderRepositoryEventListener(String syncEvent) {
267                            _syncEvent = syncEvent;
268                    }
269    
270                    @Override
271                    public void execute(Folder folder) {
272                            registerDLSyncEventCallback(_syncEvent, folder);
273                    }
274    
275                    private final String _syncEvent;
276    
277            }
278    
279    }