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.util.FileUtil; 023 import com.liferay.portal.kernel.util.StringPool; 024 import com.liferay.portlet.documentlibrary.NoSuchFileException; 025 026 import java.io.File; 027 import java.io.FileInputStream; 028 import java.io.FileNotFoundException; 029 import java.io.IOException; 030 import java.io.InputStream; 031 032 /** 033 * The abstract base class for all file store implementations. Most, if not all 034 * implementations should extend this class. 035 * 036 * @author Brian Wing Shun Chan 037 * @author Alexander Chow 038 * @author Edward Han 039 */ 040 public abstract class BaseStore implements Store { 041 042 /** 043 * Adds a directory. 044 * 045 * @param companyId the primary key of the company 046 * @param repositoryId the primary key of the data repository (optionally 047 * {@link CompanyConstants#SYSTEM}) 048 * @param dirName the directory's name 049 * @throws PortalException if the directory's information was invalid 050 * @throws SystemException if a system exception occurred 051 */ 052 @Override 053 public abstract void addDirectory( 054 long companyId, long repositoryId, String dirName) 055 throws PortalException, SystemException; 056 057 /** 058 * Adds a file based on a byte array. 059 * 060 * @param companyId the primary key of the company 061 * @param repositoryId the primary key of the data repository (optionally 062 * {@link CompanyConstants#SYSTEM}) 063 * @param fileName the file name 064 * @param bytes the files's data 065 * @throws PortalException if the file's information was invalid 066 * @throws SystemException if a system exception occurred 067 */ 068 @Override 069 public void addFile( 070 long companyId, long repositoryId, String fileName, byte[] bytes) 071 throws PortalException, SystemException { 072 073 File file = null; 074 075 try { 076 file = FileUtil.createTempFile(bytes); 077 078 addFile(companyId, repositoryId, fileName, file); 079 } 080 catch (IOException ioe) { 081 throw new SystemException("Unable to write temporary file", ioe); 082 } 083 finally { 084 FileUtil.delete(file); 085 } 086 } 087 088 /** 089 * Adds a file based on a {@link File} object. 090 * 091 * @param companyId the primary key of the company 092 * @param repositoryId the primary key of the data repository (optionally 093 * {@link CompanyConstants#SYSTEM}) 094 * @param fileName the file name 095 * @param file Name the file name 096 * @throws PortalException if the file's information was invalid 097 * @throws SystemException if a system exception occurred 098 */ 099 @Override 100 public void addFile( 101 long companyId, long repositoryId, String fileName, File file) 102 throws PortalException, SystemException { 103 104 InputStream is = null; 105 106 try { 107 is = new FileInputStream(file); 108 109 addFile(companyId, repositoryId, fileName, is); 110 } 111 catch (FileNotFoundException fnfe) { 112 throw new NoSuchFileException(fileName); 113 } 114 finally { 115 try { 116 if (is != null) { 117 is.close(); 118 } 119 } 120 catch (IOException ioe) { 121 _log.error(ioe); 122 } 123 } 124 } 125 126 /** 127 * Adds a file based on an {@link InputStream} object. 128 * 129 * @param companyId the primary key of the company 130 * @param repositoryId the primary key of the data repository (optionally 131 * {@link CompanyConstants#SYSTEM}) 132 * @param fileName the file name 133 * @param is the files's data 134 * @throws PortalException if the file's information was invalid 135 * @throws SystemException if a system exception occurred 136 */ 137 @Override 138 public abstract void addFile( 139 long companyId, long repositoryId, String fileName, InputStream is) 140 throws PortalException, SystemException; 141 142 /** 143 * Ensures company's root directory exists. Only implemented by {@link 144 * JCRStore#checkRoot(long)}. 145 * 146 * @param companyId the primary key of the company 147 * @throws SystemException if a system exception occurred 148 */ 149 @Override 150 public abstract void checkRoot(long companyId) throws SystemException; 151 152 /** 153 * Creates a new copy of the file version. 154 * 155 * <p> 156 * This method should be overrided if a more optimized approach can be used 157 * (e.g., {@link FileSystemStore#copyFileVersion(long, long, String, String, 158 * String, String)}). 159 * </p> 160 * 161 * @param companyId the primary key of the company 162 * @param repositoryId the primary key of the data repository (optionally 163 * {@link CompanyConstants#SYSTEM}) 164 * @param fileName the original's file name 165 * @param fromVersionLabel the original file's version label 166 * @param toVersionLabel the new version label 167 * @throws PortalException if the file's information was invalid 168 * @throws SystemException if a system exception occurred 169 */ 170 @Override 171 public void copyFileVersion( 172 long companyId, long repositoryId, String fileName, 173 String fromVersionLabel, String toVersionLabel) 174 throws PortalException, SystemException { 175 176 InputStream is = getFileAsStream( 177 companyId, repositoryId, fileName, fromVersionLabel); 178 179 if (is == null) { 180 is = new UnsyncByteArrayInputStream(new byte[0]); 181 } 182 183 updateFile(companyId, repositoryId, fileName, toVersionLabel, is); 184 } 185 186 /** 187 * Deletes a directory. 188 * 189 * @param companyId the primary key of the company 190 * @param repositoryId the primary key of the data repository (optionally 191 * {@link CompanyConstants#SYSTEM}) 192 * @param dirName the directory's name 193 * @throws PortalException if the directory's information was invalid 194 * @throws SystemException if a system exception occurred 195 */ 196 @Override 197 public abstract void deleteDirectory( 198 long companyId, long repositoryId, String dirName) 199 throws PortalException, SystemException; 200 201 /** 202 * Deletes a file. If a file has multiple versions, all versions will be 203 * deleted. 204 * 205 * @param companyId the primary key of the company 206 * @param repositoryId the primary key of the data repository (optionally 207 * {@link CompanyConstants#SYSTEM}) 208 * @param fileName the file's name 209 * @throws PortalException if the file's information was invalid 210 * @throws SystemException if a system exception occurred 211 */ 212 @Override 213 public abstract void deleteFile( 214 long companyId, long repositoryId, String fileName) 215 throws PortalException, SystemException; 216 217 /** 218 * Deletes a file at a particular version. 219 * 220 * @param companyId the primary key of the company 221 * @param repositoryId the primary key of the data repository (optionally 222 * {@link CompanyConstants#SYSTEM}) 223 * @param fileName the file's name 224 * @param versionLabel the file's version label 225 * @throws PortalException if the file's information was invalid 226 * @throws SystemException if a system exception occurred 227 */ 228 @Override 229 public abstract void deleteFile( 230 long companyId, long repositoryId, String fileName, 231 String versionLabel) 232 throws PortalException, SystemException; 233 234 /** 235 * Returns the file as a {@link File} object. 236 * 237 * <p> 238 * This method is useful when optimizing low-level file operations like 239 * copy. The client must not delete or change the returned {@link File} 240 * object in any way. This method is only supported in certain stores. If 241 * not supported, this method will throw an {@link 242 * UnsupportedOperationException}. 243 * </p> 244 * 245 * @param companyId the primary key of the company 246 * @param repositoryId the primary key of the data repository (optionally 247 * {@link CompanyConstants#SYSTEM}) 248 * @param fileName the file's name 249 * @return Returns the {@link File} object with the file's name 250 * @throws PortalException if the file's information was invalid 251 * @throws SystemException if a system exception occurred 252 */ 253 @Override 254 public File getFile(long companyId, long repositoryId, String fileName) 255 throws PortalException, SystemException { 256 257 return getFile(companyId, repositoryId, fileName, StringPool.BLANK); 258 } 259 260 /** 261 * Returns the file as a {@link File} object. 262 * 263 * <p> 264 * This method is useful when optimizing low-level file operations like 265 * copy. The client must not delete or change the returned {@link File} 266 * object in any way. This method is only supported in certain stores. If 267 * not supported, this method will throw an {@link 268 * UnsupportedOperationException}. 269 * </p> 270 * 271 * <p> 272 * This method should be overrided if a more optimized approach can be used 273 * (e.g., {@link FileSystemStore#getFile(long, long, String, String)}). 274 * </p> 275 * 276 * @param companyId the primary key of the company 277 * @param repositoryId the primary key of the data repository (optionally 278 * {@link CompanyConstants#SYSTEM}) 279 * @param fileName the file's name 280 * @param versionLabel the file's version label 281 * @return Returns the {@link File} object with the file's name 282 * @throws PortalException if the file's information was invalid 283 * @throws SystemException if a system exception occurred 284 */ 285 @Override 286 public File getFile( 287 long companyId, long repositoryId, String fileName, 288 String versionLabel) 289 throws PortalException, SystemException { 290 291 throw new UnsupportedOperationException(); 292 } 293 294 /** 295 * Returns the file as a byte array. 296 * 297 * @param companyId the primary key of the company 298 * @param repositoryId the primary key of the data repository (optionally 299 * {@link CompanyConstants#SYSTEM}) 300 * @param fileName the file's name 301 * @return Returns the byte array with the file's name 302 * @throws PortalException if the file's information was invalid 303 * @throws SystemException if a system exception occurred 304 */ 305 @Override 306 public byte[] getFileAsBytes( 307 long companyId, long repositoryId, String fileName) 308 throws PortalException, SystemException { 309 310 byte[] bytes = null; 311 312 try { 313 InputStream is = getFileAsStream(companyId, repositoryId, fileName); 314 315 bytes = FileUtil.getBytes(is); 316 } 317 catch (IOException ioe) { 318 throw new SystemException(ioe); 319 } 320 321 return bytes; 322 } 323 324 /** 325 * Returns the file as a byte array. 326 * 327 * @param companyId the primary key of the company 328 * @param repositoryId the primary key of the data repository (optionally 329 * {@link CompanyConstants#SYSTEM}) 330 * @param fileName the file's name 331 * @param versionLabel the file's version label 332 * @return Returns the byte array with the file's name 333 * @throws PortalException if the file's information was invalid 334 * @throws SystemException if a system exception occurred 335 */ 336 @Override 337 public byte[] getFileAsBytes( 338 long companyId, long repositoryId, String fileName, 339 String versionLabel) 340 throws PortalException, SystemException { 341 342 byte[] bytes = null; 343 344 try { 345 InputStream is = getFileAsStream( 346 companyId, repositoryId, fileName, versionLabel); 347 348 bytes = FileUtil.getBytes(is); 349 } 350 catch (IOException ioe) { 351 throw new SystemException(ioe); 352 } 353 354 return bytes; 355 } 356 357 /** 358 * Returns the file as an {@link InputStream} object. 359 * 360 * @param companyId the primary key of the company 361 * @param repositoryId the primary key of the data repository (optionally 362 * {@link CompanyConstants#SYSTEM}) 363 * @param fileName the file's name 364 * @return Returns the {@link InputStream} object with the file's name 365 * @throws PortalException if the file's information was invalid 366 * @throws SystemException if a system exception occurred 367 */ 368 @Override 369 public InputStream getFileAsStream( 370 long companyId, long repositoryId, String fileName) 371 throws PortalException, SystemException { 372 373 return getFileAsStream( 374 companyId, repositoryId, fileName, StringPool.BLANK); 375 } 376 377 /** 378 * Returns the file as an {@link InputStream} object. 379 * 380 * @param companyId the primary key of the company 381 * @param repositoryId the primary key of the data repository (optionally 382 * {@link CompanyConstants#SYSTEM}) 383 * @param fileName the file's name 384 * @param versionLabel the file's version label 385 * @return Returns the {@link InputStream} object with the file's name 386 * @throws PortalException if the file's information was invalid 387 * @throws SystemException if a system exception occurred 388 */ 389 @Override 390 public abstract InputStream getFileAsStream( 391 long companyId, long repositoryId, String fileName, 392 String versionLabel) 393 throws PortalException, SystemException; 394 395 /** 396 * Returns all files of the directory. 397 * 398 * @param companyId the primary key of the company 399 * @param repositoryId the primary key of the data repository (optionally 400 * {@link CompanyConstants#SYSTEM}) 401 * @param dirName the directory's name 402 * @return Returns all files of the directory 403 * @throws PortalException if the directory's information was invalid 404 * @throws SystemException if a system exception occurred 405 */ 406 @Override 407 public abstract String[] getFileNames( 408 long companyId, long repositoryId, String dirName) 409 throws PortalException, SystemException; 410 411 /** 412 * Returns the size of the file. 413 * 414 * @param companyId the primary key of the company 415 * @param repositoryId the primary key of the data repository (optionally 416 * {@link CompanyConstants#SYSTEM}) 417 * @param fileName the file's name 418 * @return Returns the size of the file 419 * @throws PortalException if the file's information was invalid 420 * @throws SystemException if a system exception occurred 421 */ 422 @Override 423 public abstract long getFileSize( 424 long companyId, long repositoryId, String fileName) 425 throws PortalException, SystemException; 426 427 /** 428 * Returns <code>true</code> if the directory exists. 429 * 430 * @param companyId the primary key of the company 431 * @param repositoryId the primary key of the data repository (optionally 432 * {@link CompanyConstants#SYSTEM}) 433 * @param dirName the directory's name 434 * @return <code>true</code> if the directory exists; <code>false</code> 435 * otherwise 436 * @throws PortalException if the directory's information was invalid 437 * @throws SystemException if a system exception occurred 438 */ 439 @Override 440 public abstract boolean hasDirectory( 441 long companyId, long repositoryId, String dirName) 442 throws PortalException, SystemException; 443 444 /** 445 * Returns <code>true</code> if the file exists. 446 * 447 * @param companyId the primary key of the company 448 * @param repositoryId the primary key of the data repository (optionally 449 * {@link CompanyConstants#SYSTEM}) 450 * @param fileName the file's name 451 * @return <code>true</code> if the file exists; <code>false</code> 452 * otherwise 453 * @throws PortalException if the file's information was invalid 454 * @throws SystemException if a system exception occurred 455 */ 456 @Override 457 public boolean hasFile(long companyId, long repositoryId, String fileName) 458 throws PortalException, SystemException { 459 460 return hasFile(companyId, repositoryId, fileName, VERSION_DEFAULT); 461 } 462 463 /** 464 * Returns <code>true</code> if the file exists. 465 * 466 * @param companyId the primary key of the company 467 * @param repositoryId the primary key of the data repository (optionally 468 * {@link CompanyConstants#SYSTEM}) 469 * @param fileName the file's name 470 * @param versionLabel the file's version label 471 * @return <code>true</code> if the file exists; <code>false</code> 472 * otherwise 473 * @throws PortalException if the file's information was invalid 474 * @throws SystemException if a system exception occurred 475 */ 476 @Override 477 public abstract boolean hasFile( 478 long companyId, long repositoryId, String fileName, 479 String versionLabel) 480 throws PortalException, SystemException; 481 482 /** 483 * Moves an existing directory. Only implemented by {@link 484 * JCRStore#move(String, String)}. 485 * 486 * @param srcDir the original directory's name 487 * @param destDir the new directory's name 488 * @throws SystemException if a system exception occurred 489 */ 490 @Override 491 public abstract void move(String srcDir, String destDir) 492 throws SystemException; 493 494 /** 495 * Moves a file to a new data repository. 496 * 497 * @param companyId the primary key of the company 498 * @param repositoryId the primary key of the data repository 499 * @param newRepositoryId the primary key of the new data repository 500 * @param fileName the file's name 501 * @throws PortalException if the file's information was invalid 502 * @throws SystemException if a system exception occurred 503 */ 504 @Override 505 public abstract void updateFile( 506 long companyId, long repositoryId, long newRepositoryId, 507 String fileName) 508 throws PortalException, SystemException; 509 510 /** 511 * Updates a file based on a byte array. 512 * 513 * @param companyId the primary key of the company 514 * @param repositoryId the primary key of the data repository (optionally 515 * {@link CompanyConstants#SYSTEM}) 516 * @param fileName the file name 517 * @param versionLabel the file's new version label 518 * @param bytes the new file's data 519 * @throws PortalException if the file's information was invalid 520 * @throws SystemException if a system exception occurred 521 */ 522 @Override 523 public void updateFile( 524 long companyId, long repositoryId, String fileName, 525 String versionLabel, byte[] bytes) 526 throws PortalException, SystemException { 527 528 File file = null; 529 530 try { 531 file = FileUtil.createTempFile(bytes); 532 533 updateFile(companyId, repositoryId, fileName, versionLabel, file); 534 } 535 catch (IOException ioe) { 536 throw new SystemException("Unable to write temporary file", ioe); 537 } 538 finally { 539 FileUtil.delete(file); 540 } 541 } 542 543 /** 544 * Updates a file based on a {@link File} object. 545 * 546 * @param companyId the primary key of the company 547 * @param repositoryId the primary key of the data repository (optionally 548 * {@link CompanyConstants#SYSTEM}) 549 * @param fileName the file name 550 * @param versionLabel the file's new version label 551 * @param file Name the file name 552 * @throws PortalException if the file's information was invalid 553 * @throws SystemException if a system exception occurred 554 */ 555 @Override 556 public void updateFile( 557 long companyId, long repositoryId, String fileName, 558 String versionLabel, File file) 559 throws PortalException, SystemException { 560 561 InputStream is = null; 562 563 try { 564 is = new FileInputStream(file); 565 566 updateFile(companyId, repositoryId, fileName, versionLabel, is); 567 } 568 catch (FileNotFoundException fnfe) { 569 throw new NoSuchFileException(fileName); 570 } 571 finally { 572 try { 573 if (is != null) { 574 is.close(); 575 } 576 } 577 catch (IOException ioe) { 578 _log.error(ioe); 579 } 580 } 581 } 582 583 /** 584 * Updates a file based on an {@link InputStream} object. 585 * 586 * @param companyId the primary key of the company 587 * @param repositoryId the primary key of the data repository (optionally 588 * {@link CompanyConstants#SYSTEM}) 589 * @param fileName the file name 590 * @param versionLabel the file's new version label 591 * @param is the new file's data 592 * @throws PortalException if the file's information was invalid 593 * @throws SystemException if a system exception occurred 594 */ 595 @Override 596 public abstract void updateFile( 597 long companyId, long repositoryId, String fileName, 598 String versionLabel, InputStream is) 599 throws PortalException, SystemException; 600 601 /** 602 * Update's a file version label. Similar to {@link #copyFileVersion(long, 603 * long, String, String, String, String)} except that the old file version 604 * is deleted. 605 * 606 * @param companyId the primary key of the company 607 * @param repositoryId the primary key of the data repository (optionally 608 * {@link CompanyConstants#SYSTEM}) 609 * @param fileName the file's name 610 * @param fromVersionLabel the file's version label 611 * @param toVersionLabel the file's new version label 612 * @throws PortalException if the file's information was invalid 613 * @throws SystemException if a system exception occurred 614 */ 615 @Override 616 public void updateFileVersion( 617 long companyId, long repositoryId, String fileName, 618 String fromVersionLabel, String toVersionLabel) 619 throws PortalException, SystemException { 620 621 InputStream is = getFileAsStream( 622 companyId, repositoryId, fileName, fromVersionLabel); 623 624 if (is == null) { 625 is = new UnsyncByteArrayInputStream(new byte[0]); 626 } 627 628 updateFile(companyId, repositoryId, fileName, toVersionLabel, is); 629 630 deleteFile(companyId, repositoryId, fileName, fromVersionLabel); 631 } 632 633 private static Log _log = LogFactoryUtil.getLog(BaseStore.class); 634 635 }