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