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