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.store;
016    
017    import com.liferay.portal.kernel.exception.PortalException;
018    import com.liferay.portal.kernel.exception.SystemException;
019    import com.liferay.portal.kernel.io.unsync.UnsyncByteArrayInputStream;
020    import com.liferay.portal.kernel.log.Log;
021    import com.liferay.portal.kernel.log.LogFactoryUtil;
022    import com.liferay.portal.kernel.transaction.Propagation;
023    import com.liferay.portal.kernel.transaction.Transactional;
024    import com.liferay.portal.kernel.util.FileUtil;
025    import com.liferay.portal.kernel.util.StringBundler;
026    import com.liferay.portlet.documentlibrary.DuplicateFileException;
027    import com.liferay.portlet.documentlibrary.model.DLContent;
028    import com.liferay.portlet.documentlibrary.service.DLContentLocalServiceUtil;
029    
030    import java.io.ByteArrayInputStream;
031    import java.io.File;
032    import java.io.FileInputStream;
033    import java.io.FileNotFoundException;
034    import java.io.IOException;
035    import java.io.InputStream;
036    
037    import java.nio.channels.FileChannel;
038    
039    import java.sql.Blob;
040    import java.sql.SQLException;
041    
042    import java.util.List;
043    
044    /**
045     * @author Shuyang Zhou
046     * @author Tina Tian
047     */
048    public class DBStore extends BaseStore {
049    
050            @Override
051            public void addDirectory(
052                    long companyId, long repositoryId, String dirName) {
053            }
054    
055            @Override
056            public void addFile(
057                            long companyId, long repositoryId, String fileName, byte[] bytes)
058                    throws PortalException, SystemException {
059    
060                    updateFile(
061                            companyId, repositoryId, fileName, Store.VERSION_DEFAULT, bytes);
062            }
063    
064            @Override
065            public void addFile(
066                            long companyId, long repositoryId, String fileName, File file)
067                    throws PortalException, SystemException {
068    
069                    updateFile(
070                            companyId, repositoryId, fileName, Store.VERSION_DEFAULT, file);
071            }
072    
073            @Override
074            public void addFile(
075                            long companyId, long repositoryId, String fileName,
076                            InputStream inputStream)
077                    throws PortalException, SystemException {
078    
079                    updateFile(
080                            companyId, repositoryId, fileName, Store.VERSION_DEFAULT,
081                            inputStream);
082            }
083    
084            @Override
085            public void checkRoot(long companyId) {
086            }
087    
088            @Override
089            public void deleteDirectory(
090                            long companyId, long repositoryId, String dirName)
091                    throws SystemException {
092    
093                    DLContentLocalServiceUtil.deleteContentsByDirectory(
094                            companyId, repositoryId, dirName);
095            }
096    
097            @Override
098            public void deleteFile(long companyId, long repositoryId, String fileName)
099                    throws SystemException {
100    
101                    DLContentLocalServiceUtil.deleteContents(
102                            companyId, repositoryId, fileName);
103            }
104    
105            @Override
106            public void deleteFile(
107                            long companyId, long repositoryId, String fileName,
108                            String versionLabel)
109                    throws PortalException, SystemException {
110    
111                    DLContentLocalServiceUtil.deleteContent(
112                            companyId, repositoryId, fileName, versionLabel);
113            }
114    
115            @Override
116            @Transactional(propagation = Propagation.REQUIRED)
117            public InputStream getFileAsStream(
118                            long companyId, long repositoryId, String fileName)
119                    throws PortalException, SystemException {
120    
121                    DLContent dlContent = DLContentLocalServiceUtil.getContent(
122                            companyId, repositoryId, fileName);
123    
124                    dlContent.resetOriginalValues();
125    
126                    Blob blobData = dlContent.getData();
127    
128                    if (blobData == null) {
129                            if (_log.isWarnEnabled()) {
130                                    StringBundler sb = new StringBundler(9);
131    
132                                    sb.append("No blob data found for file {companyId=");
133                                    sb.append(companyId);
134                                    sb.append(", repositoryId=");
135                                    sb.append(repositoryId);
136                                    sb.append(", fileName=");
137                                    sb.append(fileName);
138                                    sb.append("}");
139    
140                                    _log.warn(sb.toString());
141                            }
142    
143                            return null;
144                    }
145    
146                    try {
147                            return blobData.getBinaryStream();
148                    }
149                    catch (SQLException sqle) {
150                            StringBundler sb = new StringBundler(7);
151    
152                            sb.append("Unable to load data binary stream for file {companyId=");
153                            sb.append(companyId);
154                            sb.append(", repositoryId=");
155                            sb.append(repositoryId);
156                            sb.append(", fileName=");
157                            sb.append(fileName);
158                            sb.append("}");
159    
160                            throw new SystemException(sb.toString(), sqle);
161                    }
162            }
163    
164            @Override
165            @Transactional(propagation = Propagation.REQUIRED)
166            public InputStream getFileAsStream(
167                            long companyId, long repositoryId, String fileName,
168                            String versionLabel)
169                    throws PortalException, SystemException {
170    
171                    DLContent dlContent = DLContentLocalServiceUtil.getContent(
172                            companyId, repositoryId, fileName, versionLabel);
173    
174                    Blob blobData = dlContent.getData();
175    
176                    if (blobData == null) {
177                            if (_log.isWarnEnabled()) {
178                                    StringBundler sb = new StringBundler(9);
179    
180                                    sb.append("No blob data found for file {companyId=");
181                                    sb.append(companyId);
182                                    sb.append(", repositoryId=");
183                                    sb.append(repositoryId);
184                                    sb.append(", fileName=");
185                                    sb.append(fileName);
186                                    sb.append(", versionLabel=");
187                                    sb.append(versionLabel);
188                                    sb.append("}");
189    
190                                    _log.warn(sb.toString());
191                            }
192    
193                            return null;
194                    }
195    
196                    try {
197                            return blobData.getBinaryStream();
198                    }
199                    catch (SQLException sqle) {
200                            StringBundler sb = new StringBundler(9);
201    
202                            sb.append("Unable to load data binary stream for file {companyId=");
203                            sb.append(companyId);
204                            sb.append(", repositoryId=");
205                            sb.append(repositoryId);
206                            sb.append(", fileName=");
207                            sb.append(fileName);
208                            sb.append(", versionLabel=");
209                            sb.append(versionLabel);
210                            sb.append("}");
211    
212                            throw new SystemException(sb.toString(), sqle);
213                    }
214            }
215    
216            @Override
217            public String[] getFileNames(long companyId, long repositoryId)
218                    throws SystemException {
219    
220                    List<DLContent> dlContents = DLContentLocalServiceUtil.getContents(
221                            companyId, repositoryId);
222    
223                    String[] fileNames = new String[dlContents.size()];
224    
225                    for (int i = 0; i < dlContents.size(); i++) {
226                            DLContent dlContent = dlContents.get(i);
227    
228                            fileNames[i] = dlContent.getPath();
229                    }
230    
231                    return fileNames;
232            }
233    
234            @Override
235            public String[] getFileNames(
236                            long companyId, long repositoryId, String dirName)
237                    throws SystemException {
238    
239                    List<DLContent> dlContents =
240                            DLContentLocalServiceUtil.getContentsByDirectory(
241                                    companyId, repositoryId, dirName);
242    
243                    String[] fileNames = new String[dlContents.size()];
244    
245                    for (int i = 0; i < dlContents.size(); i++) {
246                            DLContent dlContent = dlContents.get(i);
247    
248                            fileNames[i] = dlContent.getPath();
249                    }
250    
251                    return fileNames;
252            }
253    
254            @Override
255            public long getFileSize(long companyId, long repositoryId, String fileName)
256                    throws PortalException, SystemException {
257    
258                    DLContent dlContent = DLContentLocalServiceUtil.getContent(
259                            companyId, repositoryId, fileName);
260    
261                    return dlContent.getSize();
262            }
263    
264            @Override
265            public boolean hasDirectory(
266                    long companyId, long repositoryId, String dirName) {
267    
268                    return true;
269            }
270    
271            @Override
272            public boolean hasFile(
273                            long companyId, long repositoryId, String fileName,
274                            String versionLabel)
275                    throws SystemException {
276    
277                    return DLContentLocalServiceUtil.hasContent(
278                            companyId, repositoryId, fileName, versionLabel);
279            }
280    
281            @Override
282            public void move(String srcDir, String destDir) {
283            }
284    
285            @Override
286            public void updateFile(
287                            long companyId, long repositoryId, long newRepositoryId,
288                            String fileName)
289                    throws SystemException {
290    
291                    DLContentLocalServiceUtil.updateDLContent(
292                            companyId, repositoryId, newRepositoryId, fileName, fileName);
293            }
294    
295            @Override
296            public void updateFile(
297                            long companyId, long repositoryId, String fileName,
298                            String newFileName)
299                    throws SystemException {
300    
301                    DLContentLocalServiceUtil.updateDLContent(
302                            companyId, repositoryId, repositoryId, fileName, newFileName);
303            }
304    
305            @Override
306            public void updateFile(
307                            long companyId, long repositoryId, String fileName,
308                            String versionLabel, byte[] bytes)
309                    throws PortalException, SystemException {
310    
311                    if (DLContentLocalServiceUtil.hasContent(
312                                    companyId, repositoryId, fileName, versionLabel)) {
313    
314                            throw new DuplicateFileException(fileName);
315                    }
316    
317                    DLContentLocalServiceUtil.addContent(
318                            companyId, repositoryId, fileName, versionLabel, bytes);
319            }
320    
321            @Override
322            public void updateFile(
323                            long companyId, long repositoryId, String fileName,
324                            String versionLabel, File file)
325                    throws PortalException, SystemException {
326    
327                    if (DLContentLocalServiceUtil.hasContent(
328                                    companyId, repositoryId, fileName, versionLabel)) {
329    
330                            throw new DuplicateFileException(fileName);
331                    }
332    
333                    InputStream inputStream = null;
334    
335                    try {
336                            inputStream = new FileInputStream(file);
337                    }
338                    catch (FileNotFoundException fnfe) {
339                            throw new SystemException(fnfe);
340                    }
341    
342                    DLContentLocalServiceUtil.addContent(
343                            companyId, repositoryId, fileName, versionLabel, inputStream,
344                            file.length());
345            }
346    
347            @Override
348            public void updateFile(
349                            long companyId, long repositoryId, String fileName,
350                            String versionLabel, InputStream inputStream)
351                    throws PortalException, SystemException {
352    
353                    if (DLContentLocalServiceUtil.hasContent(
354                                    companyId, repositoryId, fileName, versionLabel)) {
355    
356                            throw new DuplicateFileException(fileName);
357                    }
358    
359                    long length = -1;
360    
361                    if (inputStream instanceof ByteArrayInputStream) {
362                            ByteArrayInputStream byteArrayInputStream =
363                                    (ByteArrayInputStream)inputStream;
364    
365                            length = byteArrayInputStream.available();
366                    }
367                    else if (inputStream instanceof FileInputStream) {
368                            FileInputStream fileInputStream = (FileInputStream)inputStream;
369    
370                            FileChannel fileChannel = fileInputStream.getChannel();
371    
372                            try {
373                                    length = fileChannel.size();
374                            }
375                            catch (IOException ioe) {
376                                    if (_log.isWarnEnabled()) {
377                                            _log.warn(
378                                                    "Unable to detect file size from file channel", ioe);
379                                    }
380                            }
381                    }
382                    else if (inputStream instanceof UnsyncByteArrayInputStream) {
383                            UnsyncByteArrayInputStream unsyncByteArrayInputStream =
384                                    (UnsyncByteArrayInputStream)inputStream;
385    
386                            length = unsyncByteArrayInputStream.available();
387                    }
388    
389                    if (length >= 0) {
390                            DLContentLocalServiceUtil.addContent(
391                                    companyId, repositoryId, fileName, versionLabel, inputStream,
392                                    length);
393                    }
394                    else {
395                            if (_log.isWarnEnabled()) {
396                                    _log.warn(
397                                            "Unable to detect length from input stream. Reading " +
398                                                    "entire input stream into memory as a last resort.");
399                            }
400    
401                            byte[] bytes = null;
402    
403                            try {
404                                    bytes = FileUtil.getBytes(inputStream);
405                            }
406                            catch (IOException ioe) {
407                                    throw new SystemException(ioe);
408                            }
409    
410                            DLContentLocalServiceUtil.addContent(
411                                    companyId, repositoryId, fileName, versionLabel, bytes);
412                    }
413            }
414    
415            private static Log _log = LogFactoryUtil.getLog(DBStore.class);
416    
417    }