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