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