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