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.portlet.documentlibrary.util;
016    
017    import com.liferay.portal.kernel.log.Log;
018    import com.liferay.portal.kernel.log.LogFactoryUtil;
019    import com.liferay.portal.kernel.repository.model.FileEntry;
020    import com.liferay.portal.kernel.repository.model.FileVersion;
021    import com.liferay.portal.kernel.security.pacl.DoPrivileged;
022    import com.liferay.portal.kernel.util.ClassLoaderUtil;
023    import com.liferay.portal.kernel.util.InstanceFactory;
024    import com.liferay.portal.kernel.util.PropsKeys;
025    import com.liferay.portal.kernel.util.PropsUtil;
026    import com.liferay.portal.kernel.xml.Element;
027    import com.liferay.portal.util.PrefsPropsUtil;
028    import com.liferay.portal.util.PropsValues;
029    import com.liferay.portlet.exportimport.lar.PortletDataContext;
030    import com.liferay.registry.Registry;
031    import com.liferay.registry.RegistryUtil;
032    import com.liferay.registry.ServiceReference;
033    import com.liferay.registry.ServiceRegistration;
034    import com.liferay.registry.collections.ServiceReferenceMapper;
035    import com.liferay.registry.collections.ServiceTrackerCollections;
036    import com.liferay.registry.collections.ServiceTrackerMap;
037    import com.liferay.registry.collections.StringServiceRegistrationMap;
038    import com.liferay.registry.collections.StringServiceRegistrationMapImpl;
039    
040    /**
041     * @author Mika Koivisto
042     */
043    @DoPrivileged
044    public class DLProcessorRegistryImpl implements DLProcessorRegistry {
045    
046            public void afterPropertiesSet() throws Exception {
047                    _dlProcessorServiceTrackerMap.open();
048    
049                    ClassLoader classLoader = ClassLoaderUtil.getPortalClassLoader();
050    
051                    for (String dlProcessorClassName : _DL_FILE_ENTRY_PROCESSORS) {
052                            DLProcessor dlProcessor = (DLProcessor)InstanceFactory.newInstance(
053                                    classLoader, dlProcessorClassName);
054    
055                            dlProcessor.afterPropertiesSet();
056    
057                            register(dlProcessor);
058                    }
059            }
060    
061            @Override
062            public void cleanUp(FileEntry fileEntry) {
063                    if (!DLProcessorThreadLocal.isEnabled()) {
064                            return;
065                    }
066    
067                    Iterable<String> dlProcessorTypes =
068                            _dlProcessorServiceTrackerMap.keySet();
069    
070                    for (String dlProcessorType : dlProcessorTypes) {
071                            DLProcessor dlProcessor = _dlProcessorServiceTrackerMap.getService(
072                                    dlProcessorType);
073    
074                            if (dlProcessor.isSupported(fileEntry.getMimeType())) {
075                                    dlProcessor.cleanUp(fileEntry);
076                            }
077                    }
078            }
079    
080            @Override
081            public void cleanUp(FileVersion fileVersion) {
082                    if (!DLProcessorThreadLocal.isEnabled()) {
083                            return;
084                    }
085    
086                    Iterable<String> dlProcessorTypes =
087                            _dlProcessorServiceTrackerMap.keySet();
088    
089                    for (String dlProcessorType : dlProcessorTypes) {
090                            DLProcessor dlProcessor = _dlProcessorServiceTrackerMap.getService(
091                                    dlProcessorType);
092    
093                            if (dlProcessor.isSupported(fileVersion)) {
094                                    dlProcessor.cleanUp(fileVersion);
095                            }
096                    }
097            }
098    
099            @Override
100            public void exportGeneratedFiles(
101                            PortletDataContext portletDataContext, FileEntry fileEntry,
102                            Element fileEntryElement)
103                    throws Exception {
104    
105                    if ((fileEntry == null) || (fileEntry.getSize() == 0)) {
106                            return;
107                    }
108    
109                    FileVersion latestFileVersion = _getLatestFileVersion(fileEntry, true);
110    
111                    if (latestFileVersion == null) {
112                            return;
113                    }
114    
115                    Iterable<String> dlProcessorTypes =
116                            _dlProcessorServiceTrackerMap.keySet();
117    
118                    for (String dlProcessorType : dlProcessorTypes) {
119                            DLProcessor dlProcessor = _dlProcessorServiceTrackerMap.getService(
120                                    dlProcessorType);
121    
122                            if (dlProcessor.isSupported(latestFileVersion)) {
123                                    dlProcessor.exportGeneratedFiles(
124                                            portletDataContext, fileEntry, fileEntryElement);
125                            }
126                    }
127            }
128    
129            @Override
130            public DLProcessor getDLProcessor(String dlProcessorType) {
131                    return _dlProcessorServiceTrackerMap.getService(dlProcessorType);
132            }
133    
134            @Override
135            public void importGeneratedFiles(
136                            PortletDataContext portletDataContext, FileEntry fileEntry,
137                            FileEntry importedFileEntry, Element fileEntryElement)
138                    throws Exception {
139    
140                    if ((importedFileEntry == null) || (importedFileEntry.getSize() == 0)) {
141                            return;
142                    }
143    
144                    FileVersion fileVersion = importedFileEntry.getFileVersion();
145    
146                    if (fileVersion == null) {
147                            return;
148                    }
149    
150                    Iterable<String> dlProcessorTypes =
151                            _dlProcessorServiceTrackerMap.keySet();
152    
153                    for (String dlProcessorType : dlProcessorTypes) {
154                            DLProcessor dlProcessor = _dlProcessorServiceTrackerMap.getService(
155                                    dlProcessorType);
156    
157                            if (dlProcessor.isSupported(fileVersion)) {
158                                    dlProcessor.importGeneratedFiles(
159                                            portletDataContext, fileEntry, importedFileEntry,
160                                            fileEntryElement);
161                            }
162                    }
163            }
164    
165            @Override
166            public boolean isPreviewableSize(FileVersion fileVersion) {
167                    long fileEntryPreviewableProcessorMaxSize =
168                            PropsValues.DL_FILE_ENTRY_PREVIEWABLE_PROCESSOR_MAX_SIZE;
169    
170                    try {
171                            fileEntryPreviewableProcessorMaxSize = PrefsPropsUtil.getLong(
172                                    PropsKeys.DL_FILE_ENTRY_PREVIEWABLE_PROCESSOR_MAX_SIZE);
173                    }
174                    catch (Exception e) {
175                            _log.error(e, e);
176                    }
177    
178                    if (fileEntryPreviewableProcessorMaxSize == 0) {
179                            return false;
180                    }
181    
182                    if ((fileEntryPreviewableProcessorMaxSize > 0) &&
183                            (fileVersion.getSize() > fileEntryPreviewableProcessorMaxSize)) {
184    
185                            return false;
186                    }
187    
188                    return true;
189            }
190    
191            @Override
192            public void register(DLProcessor dlProcessor) {
193                    Registry registry = RegistryUtil.getRegistry();
194    
195                    ServiceRegistration<DLProcessor> previousServiceRegistration =
196                            _serviceRegistrations.remove(dlProcessor.getType());
197    
198                    if (previousServiceRegistration != null) {
199                            previousServiceRegistration.unregister();
200                    }
201    
202                    ServiceRegistration<DLProcessor> serviceRegistration =
203                            registry.registerService(DLProcessor.class, dlProcessor);
204    
205                    _serviceRegistrations.put(dlProcessor.getType(), serviceRegistration);
206            }
207    
208            @Override
209            public void trigger(FileEntry fileEntry, FileVersion fileVersion) {
210                    trigger(fileEntry, fileVersion, false);
211            }
212    
213            @Override
214            public void trigger(
215                    FileEntry fileEntry, FileVersion fileVersion, boolean trusted) {
216    
217                    if (!DLProcessorThreadLocal.isEnabled()) {
218                            return;
219                    }
220    
221                    if ((fileEntry == null) || (fileEntry.getSize() == 0)) {
222                            return;
223                    }
224    
225                    FileVersion latestFileVersion = _getLatestFileVersion(
226                            fileEntry, trusted);
227    
228                    if (latestFileVersion == null) {
229                            return;
230                    }
231    
232                    Iterable<String> dlProcessorTypes =
233                            _dlProcessorServiceTrackerMap.keySet();
234    
235                    for (String dlProcessorType : dlProcessorTypes) {
236                            DLProcessor dlProcessor = _dlProcessorServiceTrackerMap.getService(
237                                    dlProcessorType);
238    
239                            if (dlProcessor.isSupported(latestFileVersion)) {
240                                    dlProcessor.trigger(fileVersion, latestFileVersion);
241                            }
242                    }
243            }
244    
245            @Override
246            public void unregister(DLProcessor dlProcessor) {
247                    ServiceRegistration<DLProcessor> serviceRegistration =
248                            _serviceRegistrations.remove(dlProcessor.getType());
249    
250                    serviceRegistration.unregister();
251            }
252    
253            private FileVersion _getLatestFileVersion(
254                    FileEntry fileEntry, boolean trusted) {
255    
256                    try {
257                            return fileEntry.getLatestFileVersion(trusted);
258                    }
259                    catch (Exception e) {
260                            _log.error(e, e);
261    
262                            return null;
263                    }
264            }
265    
266            private static final String[] _DL_FILE_ENTRY_PROCESSORS =
267                    PropsUtil.getArray(PropsKeys.DL_FILE_ENTRY_PROCESSORS);
268    
269            private static final Log _log = LogFactoryUtil.getLog(
270                    DLProcessorRegistryImpl.class);
271    
272            private final ServiceTrackerMap<String, DLProcessor>
273                    _dlProcessorServiceTrackerMap =
274                            ServiceTrackerCollections.singleValueMap(
275                                    DLProcessor.class, null,
276                                    new ServiceReferenceMapper<String, DLProcessor>() {
277    
278                                            @Override
279                                            public void map(
280                                                    ServiceReference<DLProcessor> serviceReference,
281                                                    Emitter<String> emitter) {
282    
283                                                    Registry registry = RegistryUtil.getRegistry();
284    
285                                                    DLProcessor dlProcessor = registry.getService(
286                                                            serviceReference);
287    
288                                                    try {
289                                                            emitter.emit(dlProcessor.getType());
290                                                    }
291                                                    finally {
292                                                            registry.ungetService(serviceReference);
293                                                    }
294                                            }
295    
296                            });
297    
298            private final StringServiceRegistrationMap<DLProcessor>
299                    _serviceRegistrations = new StringServiceRegistrationMapImpl<>();
300    
301    }