001    /**
002     * Copyright (c) 2000-2012 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.service.impl;
016    
017    import com.liferay.portal.kernel.exception.PortalException;
018    import com.liferay.portal.kernel.exception.SystemException;
019    import com.liferay.portal.kernel.io.delta.ByteChannelReader;
020    import com.liferay.portal.kernel.io.delta.ByteChannelWriter;
021    import com.liferay.portal.kernel.io.delta.DeltaUtil;
022    import com.liferay.portal.kernel.repository.model.FileEntry;
023    import com.liferay.portal.kernel.util.FileUtil;
024    import com.liferay.portal.kernel.util.StreamUtil;
025    import com.liferay.portal.service.ServiceContext;
026    import com.liferay.portlet.documentlibrary.model.DLSync;
027    import com.liferay.portlet.documentlibrary.model.DLSyncUpdate;
028    import com.liferay.portlet.documentlibrary.service.base.DLSyncServiceBaseImpl;
029    
030    import java.io.File;
031    import java.io.FileInputStream;
032    import java.io.FileOutputStream;
033    import java.io.InputStream;
034    import java.io.OutputStream;
035    
036    import java.nio.channels.Channels;
037    import java.nio.channels.FileChannel;
038    import java.nio.channels.ReadableByteChannel;
039    import java.nio.channels.WritableByteChannel;
040    
041    import java.util.List;
042    
043    /**
044     * @author Michael Young
045     */
046    public class DLSyncServiceImpl extends DLSyncServiceBaseImpl {
047    
048            public DLSyncUpdate getDLSyncUpdate(
049                            long companyId, long repositoryId, long lastAccessDate)
050                    throws PortalException, SystemException {
051    
052                    repositoryService.checkRepository(repositoryId);
053    
054                    List<DLSync> dlSyncs = dlSyncFinder.filterFindByC_M_R(
055                            companyId, lastAccessDate, repositoryId);
056    
057                    for (DLSync dlSync : dlSyncs) {
058                            if (dlSync.getModifiedDate() > lastAccessDate) {
059                                    lastAccessDate = dlSync.getModifiedDate();
060                            }
061                    }
062    
063                    return new DLSyncUpdate(dlSyncs, lastAccessDate);
064            }
065    
066            public InputStream getFileDeltaAsStream(
067                            long fileEntryId, String sourceVersion, String destinationVersion)
068                    throws PortalException, SystemException {
069    
070                    InputStream deltaInputStream = null;
071    
072                    FileEntry fileEntry = dlAppLocalService.getFileEntry(fileEntryId);
073    
074                    InputStream sourceInputStream = null;
075                    File sourceFile = FileUtil.createTempFile();
076                    FileInputStream sourceFileInputStream = null;
077                    FileChannel sourceFileChannel = null;
078                    File checksumsFile = FileUtil.createTempFile();
079                    OutputStream checksumsOutputStream = null;
080                    WritableByteChannel checksumsWritableByteChannel = null;
081    
082                    try {
083                            sourceInputStream = fileEntry.getContentStream(sourceVersion);
084    
085                            FileUtil.write(sourceFile, sourceInputStream);
086    
087                            sourceFileInputStream = new FileInputStream(sourceFile);
088    
089                            sourceFileChannel = sourceFileInputStream.getChannel();
090    
091                            checksumsOutputStream = new FileOutputStream(checksumsFile);
092    
093                            checksumsWritableByteChannel = Channels.newChannel(
094                                    checksumsOutputStream);
095    
096                            ByteChannelWriter checksumsByteChannelWriter =
097                                    new ByteChannelWriter(checksumsWritableByteChannel);
098    
099                            DeltaUtil.checksums(sourceFileChannel, checksumsByteChannelWriter);
100    
101                            checksumsByteChannelWriter.finish();
102                    }
103                    catch (Exception e) {
104                            throw new PortalException(e);
105                    }
106                    finally {
107                            StreamUtil.cleanUp(sourceFileInputStream);
108                            StreamUtil.cleanUp(sourceFileChannel);
109                            StreamUtil.cleanUp(checksumsOutputStream);
110                            StreamUtil.cleanUp(checksumsWritableByteChannel);
111    
112                            FileUtil.delete(sourceFile);
113                    }
114    
115                    InputStream destinationInputStream = null;
116                    ReadableByteChannel destinationReadableByteChannel = null;
117                    InputStream checksumsInputStream = null;
118                    ReadableByteChannel checksumsReadableByteChannel = null;
119                    OutputStream deltaOutputStream = null;
120                    WritableByteChannel deltaOutputStreamWritableByteChannel = null;
121    
122                    try {
123                            destinationInputStream = fileEntry.getContentStream(
124                                    destinationVersion);
125    
126                            destinationReadableByteChannel = Channels.newChannel(
127                                    destinationInputStream);
128    
129                            checksumsInputStream = new FileInputStream(checksumsFile);
130    
131                            checksumsReadableByteChannel = Channels.newChannel(
132                                    checksumsInputStream);
133    
134                            ByteChannelReader checksumsByteChannelReader =
135                                    new ByteChannelReader(checksumsReadableByteChannel);
136    
137                            File deltaFile = FileUtil.createTempFile();
138    
139                            deltaOutputStream = new FileOutputStream(deltaFile);
140    
141                            deltaOutputStreamWritableByteChannel = Channels.newChannel(
142                                    deltaOutputStream);
143    
144                            ByteChannelWriter deltaByteChannelWriter = new ByteChannelWriter(
145                                    deltaOutputStreamWritableByteChannel);
146    
147                            DeltaUtil.delta(
148                                    destinationReadableByteChannel, checksumsByteChannelReader,
149                                    deltaByteChannelWriter);
150    
151                            deltaByteChannelWriter.finish();
152    
153                            deltaInputStream = new FileInputStream(deltaFile);
154                    }
155                    catch (Exception e) {
156                            throw new PortalException(e);
157                    }
158                    finally {
159                            StreamUtil.cleanUp(destinationInputStream);
160                            StreamUtil.cleanUp(destinationReadableByteChannel);
161                            StreamUtil.cleanUp(checksumsInputStream);
162                            StreamUtil.cleanUp(checksumsReadableByteChannel);
163                            StreamUtil.cleanUp(deltaOutputStream);
164                            StreamUtil.cleanUp(deltaOutputStreamWritableByteChannel);
165    
166                            FileUtil.delete(checksumsFile);
167                    }
168    
169                    return deltaInputStream;
170            }
171    
172            public FileEntry updateFileEntry(
173                            long fileEntryId, String sourceFileName, String mimeType,
174                            String title, String description, String changeLog,
175                            boolean majorVersion, InputStream deltaInputStream, long size,
176                            ServiceContext serviceContext)
177                    throws PortalException, SystemException {
178    
179                    FileEntry fileEntry = dlAppLocalService.getFileEntry(fileEntryId);
180    
181                    InputStream originalInputStream = null;
182                    File patchedFile = null;
183                    InputStream patchedInputStream = null;
184    
185                    try {
186                            originalInputStream = fileEntry.getContentStream();
187    
188                            patchedFile = FileUtil.createTempFile();
189    
190                            patchFile(originalInputStream, deltaInputStream, patchedFile);
191    
192                            patchedInputStream = new FileInputStream(patchedFile);
193    
194                            return dlAppService.updateFileEntry(
195                                    fileEntryId, sourceFileName, mimeType, title, description,
196                                    changeLog, majorVersion, patchedInputStream, size,
197                                    serviceContext);
198                    }
199                    catch (Exception e) {
200                            throw new PortalException(e);
201                    }
202                    finally {
203                            StreamUtil.cleanUp(originalInputStream);
204                            StreamUtil.cleanUp(patchedInputStream);
205    
206                            FileUtil.delete(patchedFile);
207                    }
208            }
209    
210            protected void patchFile(
211                            InputStream originalInputStream, InputStream deltaInputStream,
212                            File patchedFile)
213                    throws PortalException {
214    
215                    File originalFile = null;
216                    FileInputStream originalFileInputStream = null;
217                    FileChannel originalFileChannel = null;
218                    FileOutputStream patchedFileOutputStream = null;
219                    WritableByteChannel patchedWritableByteChannel = null;
220                    ReadableByteChannel deltaReadableByteChannel = null;
221    
222                    try {
223                            originalFile = FileUtil.createTempFile();
224    
225                            FileUtil.write(originalFile, originalInputStream);
226    
227                            originalFileInputStream = new FileInputStream(originalFile);
228    
229                            originalFileChannel = originalFileInputStream.getChannel();
230    
231                            patchedFileOutputStream = new FileOutputStream(patchedFile);
232    
233                            patchedWritableByteChannel = Channels.newChannel(
234                                    patchedFileOutputStream);
235    
236                            deltaReadableByteChannel = Channels.newChannel(deltaInputStream);
237    
238                            ByteChannelReader deltaByteChannelReader = new ByteChannelReader(
239                                    deltaReadableByteChannel);
240    
241                            DeltaUtil.patch(
242                                    originalFileChannel, patchedWritableByteChannel,
243                                    deltaByteChannelReader);
244                    }
245                    catch (Exception e) {
246                            throw new PortalException(e);
247                    }
248                    finally {
249                            StreamUtil.cleanUp(originalFileInputStream);
250                            StreamUtil.cleanUp(originalFileChannel);
251                            StreamUtil.cleanUp(patchedFileOutputStream);
252                            StreamUtil.cleanUp(patchedWritableByteChannel);
253                            StreamUtil.cleanUp(deltaReadableByteChannel);
254    
255                            FileUtil.delete(originalFile);
256                    }
257            }
258    
259    }