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