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