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.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 {
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 {
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 {
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    
092                    DLContentLocalServiceUtil.deleteContentsByDirectory(
093                            companyId, repositoryId, dirName);
094            }
095    
096            @Override
097            public void deleteFile(long companyId, long repositoryId, String fileName) {
098                    DLContentLocalServiceUtil.deleteContents(
099                            companyId, repositoryId, fileName);
100            }
101    
102            @Override
103            public void deleteFile(
104                            long companyId, long repositoryId, String fileName,
105                            String versionLabel)
106                    throws PortalException {
107    
108                    DLContentLocalServiceUtil.deleteContent(
109                            companyId, repositoryId, fileName, versionLabel);
110            }
111    
112            @Override
113            @Transactional(propagation = Propagation.REQUIRED)
114            public InputStream getFileAsStream(
115                            long companyId, long repositoryId, String fileName)
116                    throws PortalException {
117    
118                    DLContent dlContent = DLContentLocalServiceUtil.getContent(
119                            companyId, repositoryId, fileName);
120    
121                    dlContent.resetOriginalValues();
122    
123                    Blob blobData = dlContent.getData();
124    
125                    if (blobData == null) {
126                            if (_log.isWarnEnabled()) {
127                                    StringBundler sb = new StringBundler(9);
128    
129                                    sb.append("No blob data found for file {companyId=");
130                                    sb.append(companyId);
131                                    sb.append(", repositoryId=");
132                                    sb.append(repositoryId);
133                                    sb.append(", fileName=");
134                                    sb.append(fileName);
135                                    sb.append("}");
136    
137                                    _log.warn(sb.toString());
138                            }
139    
140                            return null;
141                    }
142    
143                    try {
144                            return blobData.getBinaryStream();
145                    }
146                    catch (SQLException sqle) {
147                            StringBundler sb = new StringBundler(7);
148    
149                            sb.append("Unable to load data binary stream for file {companyId=");
150                            sb.append(companyId);
151                            sb.append(", repositoryId=");
152                            sb.append(repositoryId);
153                            sb.append(", fileName=");
154                            sb.append(fileName);
155                            sb.append("}");
156    
157                            throw new SystemException(sb.toString(), sqle);
158                    }
159            }
160    
161            @Override
162            @Transactional(propagation = Propagation.REQUIRED)
163            public InputStream getFileAsStream(
164                            long companyId, long repositoryId, String fileName,
165                            String versionLabel)
166                    throws PortalException {
167    
168                    DLContent dlContent = DLContentLocalServiceUtil.getContent(
169                            companyId, repositoryId, fileName, versionLabel);
170    
171                    Blob blobData = dlContent.getData();
172    
173                    if (blobData == null) {
174                            if (_log.isWarnEnabled()) {
175                                    StringBundler sb = new StringBundler(9);
176    
177                                    sb.append("No blob data found for file {companyId=");
178                                    sb.append(companyId);
179                                    sb.append(", repositoryId=");
180                                    sb.append(repositoryId);
181                                    sb.append(", fileName=");
182                                    sb.append(fileName);
183                                    sb.append(", versionLabel=");
184                                    sb.append(versionLabel);
185                                    sb.append("}");
186    
187                                    _log.warn(sb.toString());
188                            }
189    
190                            return null;
191                    }
192    
193                    try {
194                            return blobData.getBinaryStream();
195                    }
196                    catch (SQLException sqle) {
197                            StringBundler sb = new StringBundler(9);
198    
199                            sb.append("Unable to load data binary stream for file {companyId=");
200                            sb.append(companyId);
201                            sb.append(", repositoryId=");
202                            sb.append(repositoryId);
203                            sb.append(", fileName=");
204                            sb.append(fileName);
205                            sb.append(", versionLabel=");
206                            sb.append(versionLabel);
207                            sb.append("}");
208    
209                            throw new SystemException(sb.toString(), sqle);
210                    }
211            }
212    
213            @Override
214            public String[] getFileNames(long companyId, long repositoryId) {
215                    List<DLContent> dlContents = DLContentLocalServiceUtil.getContents(
216                            companyId, repositoryId);
217    
218                    String[] fileNames = new String[dlContents.size()];
219    
220                    for (int i = 0; i < dlContents.size(); i++) {
221                            DLContent dlContent = dlContents.get(i);
222    
223                            fileNames[i] = dlContent.getPath();
224                    }
225    
226                    return fileNames;
227            }
228    
229            @Override
230            public String[] getFileNames(
231                    long companyId, long repositoryId, String dirName) {
232    
233                    List<DLContent> dlContents =
234                            DLContentLocalServiceUtil.getContentsByDirectory(
235                                    companyId, repositoryId, dirName);
236    
237                    String[] fileNames = new String[dlContents.size()];
238    
239                    for (int i = 0; i < dlContents.size(); i++) {
240                            DLContent dlContent = dlContents.get(i);
241    
242                            fileNames[i] = dlContent.getPath();
243                    }
244    
245                    return fileNames;
246            }
247    
248            @Override
249            public long getFileSize(long companyId, long repositoryId, String fileName)
250                    throws PortalException {
251    
252                    DLContent dlContent = DLContentLocalServiceUtil.getContent(
253                            companyId, repositoryId, fileName);
254    
255                    return dlContent.getSize();
256            }
257    
258            @Override
259            public boolean hasDirectory(
260                    long companyId, long repositoryId, String dirName) {
261    
262                    return true;
263            }
264    
265            @Override
266            public boolean hasFile(
267                    long companyId, long repositoryId, String fileName,
268                    String versionLabel) {
269    
270                    return DLContentLocalServiceUtil.hasContent(
271                            companyId, repositoryId, fileName, versionLabel);
272            }
273    
274            @Override
275            public void move(String srcDir, String destDir) {
276            }
277    
278            @Override
279            public void updateFile(
280                    long companyId, long repositoryId, long newRepositoryId,
281                    String fileName) {
282    
283                    DLContentLocalServiceUtil.updateDLContent(
284                            companyId, repositoryId, newRepositoryId, fileName, fileName);
285            }
286    
287            @Override
288            public void updateFile(
289                    long companyId, long repositoryId, String fileName,
290                    String newFileName) {
291    
292                    DLContentLocalServiceUtil.updateDLContent(
293                            companyId, repositoryId, repositoryId, fileName, newFileName);
294            }
295    
296            @Override
297            public void updateFile(
298                            long companyId, long repositoryId, String fileName,
299                            String versionLabel, byte[] bytes)
300                    throws PortalException {
301    
302                    if (DLContentLocalServiceUtil.hasContent(
303                                    companyId, repositoryId, fileName, versionLabel)) {
304    
305                            throw new DuplicateFileException(fileName);
306                    }
307    
308                    DLContentLocalServiceUtil.addContent(
309                            companyId, repositoryId, fileName, versionLabel, bytes);
310            }
311    
312            @Override
313            public void updateFile(
314                            long companyId, long repositoryId, String fileName,
315                            String versionLabel, File file)
316                    throws PortalException {
317    
318                    if (DLContentLocalServiceUtil.hasContent(
319                                    companyId, repositoryId, fileName, versionLabel)) {
320    
321                            throw new DuplicateFileException(fileName);
322                    }
323    
324                    InputStream inputStream = null;
325    
326                    try {
327                            inputStream = new FileInputStream(file);
328                    }
329                    catch (FileNotFoundException fnfe) {
330                            throw new SystemException(fnfe);
331                    }
332    
333                    DLContentLocalServiceUtil.addContent(
334                            companyId, repositoryId, fileName, versionLabel, inputStream,
335                            file.length());
336            }
337    
338            @Override
339            public void updateFile(
340                            long companyId, long repositoryId, String fileName,
341                            String versionLabel, InputStream inputStream)
342                    throws PortalException {
343    
344                    if (DLContentLocalServiceUtil.hasContent(
345                                    companyId, repositoryId, fileName, versionLabel)) {
346    
347                            throw new DuplicateFileException(fileName);
348                    }
349    
350                    long length = -1;
351    
352                    if (inputStream instanceof ByteArrayInputStream) {
353                            ByteArrayInputStream byteArrayInputStream =
354                                    (ByteArrayInputStream)inputStream;
355    
356                            length = byteArrayInputStream.available();
357                    }
358                    else if (inputStream instanceof FileInputStream) {
359                            FileInputStream fileInputStream = (FileInputStream)inputStream;
360    
361                            FileChannel fileChannel = fileInputStream.getChannel();
362    
363                            try {
364                                    length = fileChannel.size();
365                            }
366                            catch (IOException ioe) {
367                                    if (_log.isWarnEnabled()) {
368                                            _log.warn(
369                                                    "Unable to detect file size from file channel", ioe);
370                                    }
371                            }
372                    }
373                    else if (inputStream instanceof UnsyncByteArrayInputStream) {
374                            UnsyncByteArrayInputStream unsyncByteArrayInputStream =
375                                    (UnsyncByteArrayInputStream)inputStream;
376    
377                            length = unsyncByteArrayInputStream.available();
378                    }
379    
380                    if (length >= 0) {
381                            DLContentLocalServiceUtil.addContent(
382                                    companyId, repositoryId, fileName, versionLabel, inputStream,
383                                    length);
384                    }
385                    else {
386                            if (_log.isWarnEnabled()) {
387                                    _log.warn(
388                                            "Unable to detect length from input stream. Reading " +
389                                                    "entire input stream into memory as a last resort.");
390                            }
391    
392                            byte[] bytes = null;
393    
394                            try {
395                                    bytes = FileUtil.getBytes(inputStream);
396                            }
397                            catch (IOException ioe) {
398                                    throw new SystemException(ioe);
399                            }
400    
401                            DLContentLocalServiceUtil.addContent(
402                                    companyId, repositoryId, fileName, versionLabel, bytes);
403                    }
404            }
405    
406            private static Log _log = LogFactoryUtil.getLog(DBStore.class);
407    
408    }