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