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            public String[] getFileNames(long companyId, long repositoryId)
217                    throws SystemException {
218    
219                    List<DLContent> dlContents = DLContentLocalServiceUtil.getContents(
220                            companyId, repositoryId);
221    
222                    String[] fileNames = new String[dlContents.size()];
223    
224                    for (int i = 0; i < dlContents.size(); i++) {
225                            DLContent dlContent = dlContents.get(i);
226    
227                            fileNames[i] = dlContent.getPath();
228                    }
229    
230                    return fileNames;
231            }
232    
233            @Override
234            public String[] getFileNames(
235                            long companyId, long repositoryId, String dirName)
236                    throws SystemException {
237    
238                    List<DLContent> dlContents =
239                            DLContentLocalServiceUtil.getContentsByDirectory(
240                                    companyId, repositoryId, dirName);
241    
242                    String[] fileNames = new String[dlContents.size()];
243    
244                    for (int i = 0; i < dlContents.size(); i++) {
245                            DLContent dlContent = dlContents.get(i);
246    
247                            fileNames[i] = dlContent.getPath();
248                    }
249    
250                    return fileNames;
251            }
252    
253            @Override
254            public long getFileSize(long companyId, long repositoryId, String fileName)
255                    throws PortalException, SystemException {
256    
257                    DLContent dlContent = DLContentLocalServiceUtil.getContent(
258                            companyId, repositoryId, fileName);
259    
260                    return dlContent.getSize();
261            }
262    
263            @Override
264            public boolean hasDirectory(
265                    long companyId, long repositoryId, String dirName) {
266    
267                    return true;
268            }
269    
270            @Override
271            public boolean hasFile(
272                            long companyId, long repositoryId, String fileName,
273                            String versionLabel)
274                    throws SystemException {
275    
276                    return DLContentLocalServiceUtil.hasContent(
277                            companyId, repositoryId, fileName, versionLabel);
278            }
279    
280            @Override
281            public void move(String srcDir, String destDir) {
282            }
283    
284            @Override
285            public void updateFile(
286                            long companyId, long repositoryId, long newRepositoryId,
287                            String fileName)
288                    throws SystemException {
289    
290                    DLContentLocalServiceUtil.updateDLContent(
291                            companyId, repositoryId, newRepositoryId, fileName, fileName);
292            }
293    
294            public void updateFile(
295                            long companyId, long repositoryId, String fileName,
296                            String newFileName)
297                    throws SystemException {
298    
299                    DLContentLocalServiceUtil.updateDLContent(
300                            companyId, repositoryId, repositoryId, fileName, newFileName);
301            }
302    
303            @Override
304            public void updateFile(
305                            long companyId, long repositoryId, String fileName,
306                            String versionLabel, byte[] bytes)
307                    throws PortalException, SystemException {
308    
309                    if (DLContentLocalServiceUtil.hasContent(
310                                    companyId, repositoryId, fileName, versionLabel)) {
311    
312                            throw new DuplicateFileException(fileName);
313                    }
314    
315                    DLContentLocalServiceUtil.addContent(
316                            companyId, repositoryId, fileName, versionLabel, bytes);
317            }
318    
319            @Override
320            public void updateFile(
321                            long companyId, long repositoryId, String fileName,
322                            String versionLabel, File file)
323                    throws PortalException, SystemException {
324    
325                    if (DLContentLocalServiceUtil.hasContent(
326                                    companyId, repositoryId, fileName, versionLabel)) {
327    
328                            throw new DuplicateFileException(fileName);
329                    }
330    
331                    InputStream inputStream = null;
332    
333                    try {
334                            inputStream = new FileInputStream(file);
335                    }
336                    catch (FileNotFoundException fnfe) {
337                            throw new SystemException(fnfe);
338                    }
339    
340                    DLContentLocalServiceUtil.addContent(
341                            companyId, repositoryId, fileName, versionLabel, inputStream,
342                            file.length());
343            }
344    
345            @Override
346            public void updateFile(
347                            long companyId, long repositoryId, String fileName,
348                            String versionLabel, InputStream inputStream)
349                    throws PortalException, SystemException {
350    
351                    if (DLContentLocalServiceUtil.hasContent(
352                                    companyId, repositoryId, fileName, versionLabel)) {
353    
354                            throw new DuplicateFileException(fileName);
355                    }
356    
357                    long length = -1;
358    
359                    if (inputStream instanceof ByteArrayInputStream) {
360                            ByteArrayInputStream byteArrayInputStream =
361                                    (ByteArrayInputStream)inputStream;
362    
363                            length = byteArrayInputStream.available();
364                    }
365                    else if (inputStream instanceof FileInputStream) {
366                            FileInputStream fileInputStream = (FileInputStream)inputStream;
367    
368                            FileChannel fileChannel = fileInputStream.getChannel();
369    
370                            try {
371                                    length = fileChannel.size();
372                            }
373                            catch (IOException ioe) {
374                                    if (_log.isWarnEnabled()) {
375                                            _log.warn(
376                                                    "Unable to detect file size from file channel", ioe);
377                                    }
378                            }
379                    }
380                    else if (inputStream instanceof UnsyncByteArrayInputStream) {
381                            UnsyncByteArrayInputStream unsyncByteArrayInputStream =
382                                    (UnsyncByteArrayInputStream)inputStream;
383    
384                            length = unsyncByteArrayInputStream.available();
385                    }
386    
387                    if (length >= 0) {
388                            DLContentLocalServiceUtil.addContent(
389                                    companyId, repositoryId, fileName, versionLabel, inputStream,
390                                    length);
391                    }
392                    else {
393                            if (_log.isWarnEnabled()) {
394                                    _log.warn(
395                                            "Unable to detect length from input stream. Reading " +
396                                                    "entire input stream into memory as a last resort.");
397                            }
398    
399                            byte[] bytes = null;
400    
401                            try {
402                                    bytes = FileUtil.getBytes(inputStream);
403                            }
404                            catch (IOException ioe) {
405                                    throw new SystemException(ioe);
406                            }
407    
408                            DLContentLocalServiceUtil.addContent(
409                                    companyId, repositoryId, fileName, versionLabel, bytes);
410                    }
411            }
412    
413            private static Log _log = LogFactoryUtil.getLog(DBStore.class);
414    
415    }