001
014
015 package com.liferay.documentlibrary.util;
016
017 import com.liferay.documentlibrary.NoSuchFileException;
018 import com.liferay.documentlibrary.model.FileModel;
019 import com.liferay.portal.kernel.exception.PortalException;
020 import com.liferay.portal.kernel.exception.SystemException;
021 import com.liferay.portal.kernel.log.Log;
022 import com.liferay.portal.kernel.log.LogFactoryUtil;
023 import com.liferay.portal.kernel.search.Document;
024 import com.liferay.portal.kernel.search.Indexer;
025 import com.liferay.portal.kernel.search.IndexerRegistryUtil;
026 import com.liferay.portal.kernel.search.SearchEngineUtil;
027 import com.liferay.portal.kernel.search.SearchException;
028 import com.liferay.portal.kernel.util.FileUtil;
029 import com.liferay.portal.kernel.util.GetterUtil;
030 import com.liferay.portal.kernel.util.PropsKeys;
031 import com.liferay.portal.kernel.util.StringBundler;
032 import com.liferay.portal.kernel.util.StringPool;
033 import com.liferay.portal.kernel.util.Validator;
034 import com.liferay.portal.kernel.uuid.PortalUUIDUtil;
035 import com.liferay.portal.service.ServiceContext;
036 import com.liferay.portal.util.PropsUtil;
037 import com.liferay.util.SystemProperties;
038
039 import java.io.File;
040 import java.io.FileInputStream;
041 import java.io.IOException;
042 import java.io.InputStream;
043
044 import java.util.ArrayList;
045 import java.util.Arrays;
046 import java.util.Collection;
047 import java.util.Date;
048 import java.util.HashSet;
049 import java.util.Iterator;
050 import java.util.List;
051 import java.util.Set;
052
053 import org.jets3t.service.S3Service;
054 import org.jets3t.service.S3ServiceException;
055 import org.jets3t.service.impl.rest.httpclient.RestS3Service;
056 import org.jets3t.service.model.S3Bucket;
057 import org.jets3t.service.model.S3Object;
058 import org.jets3t.service.security.AWSCredentials;
059
060
064 public class S3Hook extends BaseHook {
065
066 public S3Hook() {
067 try {
068 _s3Service = getS3Service();
069 _s3Bucket = getS3Bucket();
070 }
071 catch (S3ServiceException s3se) {
072 _log.error(s3se.getMessage());
073 }
074 }
075
076 public void addDirectory(
077 long companyId, long repositoryId, String dirName) {
078 }
079
080 public void addFile(
081 long companyId, String portletId, long groupId, long repositoryId,
082 String fileName, long fileEntryId, String properties,
083 Date modifiedDate, ServiceContext serviceContext, InputStream is)
084 throws PortalException, SystemException {
085
086 try {
087 S3Object s3Object = new S3Object(
088 _s3Bucket,
089 getKey(companyId, repositoryId, fileName, DEFAULT_VERSION));
090
091 s3Object.setDataInputStream(is);
092
093 _s3Service.putObject(_s3Bucket, s3Object);
094
095 Indexer indexer = IndexerRegistryUtil.getIndexer(
096 FileModel.class);
097
098 FileModel fileModel = new FileModel();
099
100 fileModel.setAssetCategoryIds(serviceContext.getAssetCategoryIds());
101 fileModel.setAssetTagNames(serviceContext.getAssetTagNames());
102 fileModel.setCompanyId(companyId);
103 fileModel.setFileEntryId(fileEntryId);
104 fileModel.setFileName(fileName);
105 fileModel.setGroupId(groupId);
106 fileModel.setModifiedDate(modifiedDate);
107 fileModel.setPortletId(portletId);
108 fileModel.setProperties(properties);
109 fileModel.setRepositoryId(repositoryId);
110
111 indexer.reindex(fileModel);
112 }
113 catch (S3ServiceException s3se) {
114 throw new SystemException(s3se);
115 }
116 }
117
118 public void checkRoot(long companyId) {
119 }
120
121 public void deleteDirectory(
122 long companyId, String portletId, long repositoryId, String dirName)
123 throws SystemException {
124
125 try {
126 S3Object[] s3Objects = _s3Service.listObjects(
127 _s3Bucket, getKey(companyId, repositoryId, dirName), null);
128
129 for (int i = 0; i < s3Objects.length; i++) {
130 S3Object s3Object = s3Objects[i];
131
132 _s3Service.deleteObject(_s3Bucket, s3Object.getKey());
133 }
134 }
135 catch (S3ServiceException s3se) {
136 throw new SystemException(s3se);
137 }
138 }
139
140 public void deleteFile(
141 long companyId, String portletId, long repositoryId,
142 String fileName)
143 throws PortalException, SystemException {
144
145 try {
146 S3Object[] s3Objects = _s3Service.listObjects(
147 _s3Bucket, getKey(companyId, repositoryId, fileName), null);
148
149 for (int i = 0; i < s3Objects.length; i++) {
150 S3Object s3Object = s3Objects[i];
151
152 _s3Service.deleteObject(_s3Bucket, s3Object.getKey());
153 }
154
155 FileModel fileModel = new FileModel();
156
157 fileModel.setCompanyId(companyId);
158 fileModel.setFileName(fileName);
159 fileModel.setPortletId(portletId);
160 fileModel.setRepositoryId(repositoryId);
161
162 Indexer indexer = IndexerRegistryUtil.getIndexer(FileModel.class);
163
164 indexer.delete(fileModel);
165 }
166 catch (S3ServiceException s3se) {
167 throw new SystemException(s3se);
168 }
169 }
170
171 public void deleteFile(
172 long companyId, String portletId, long repositoryId,
173 String fileName, String versionNumber)
174 throws SystemException {
175
176 try {
177 _s3Service.deleteObject(
178 _s3Bucket,
179 getKey(companyId, repositoryId, fileName, versionNumber));
180 }
181 catch (S3ServiceException s3se) {
182 throw new SystemException(s3se);
183 }
184 }
185
186 public InputStream getFileAsStream(
187 long companyId, long repositoryId, String fileName,
188 String versionNumber)
189 throws PortalException, SystemException {
190
191 try {
192 if (Validator.isNull(versionNumber)) {
193 versionNumber = getHeadVersionNumber(
194 companyId, repositoryId, fileName);
195 }
196
197 S3Object s3Object = _s3Service.getObject(
198 _s3Bucket,
199 getKey(companyId, repositoryId, fileName, versionNumber));
200
201 return s3Object.getDataInputStream();
202 }
203 catch (S3ServiceException s3se) {
204 throw new SystemException(s3se);
205 }
206 }
207
208 public String[] getFileNames(
209 long companyId, long repositoryId, String dirName)
210 throws SystemException {
211
212 try {
213 List<String> list = new ArrayList<String>();
214
215 S3Object[] s3Objects = _s3Service.listObjects(
216 _s3Bucket, getKey(companyId, repositoryId, dirName), null);
217
218 for (int i = 0; i < s3Objects.length; i++) {
219 S3Object s3Object = s3Objects[i];
220
221
222
223
224 String key = s3Object.getKey();
225
226 int x = key.indexOf(StringPool.SLASH);
227
228 x = key.indexOf(StringPool.SLASH, x + 1);
229
230 int y = key.lastIndexOf(StringPool.SLASH);
231
232 list.add(key.substring(x, y));
233 }
234
235 return list.toArray(new String[list.size()]);
236 }
237 catch (S3ServiceException s3se) {
238 throw new SystemException(s3se);
239 }
240 }
241
242 public long getFileSize(
243 long companyId, long repositoryId, String fileName)
244 throws PortalException, SystemException {
245
246 try {
247 String versionNumber = getHeadVersionNumber(
248 companyId, repositoryId, fileName);
249
250 S3Object objectDetails = _s3Service.getObjectDetails(
251 _s3Bucket,
252 getKey(companyId, repositoryId, fileName, versionNumber));
253
254 return objectDetails.getContentLength();
255 }
256 catch (S3ServiceException s3se) {
257 throw new SystemException(s3se);
258 }
259 }
260
261 public boolean hasFile(
262 long companyId, long repositoryId, String fileName,
263 String versionNumber)
264 throws SystemException {
265
266 try {
267 S3Object[] s3Objects = _s3Service.listObjects(
268 _s3Bucket,
269 getKey(companyId, repositoryId, fileName, versionNumber), null);
270
271 if (s3Objects.length == 0) {
272 return false;
273 }
274 else {
275 return true;
276 }
277 }
278 catch (S3ServiceException s3se) {
279 throw new SystemException(s3se);
280 }
281 }
282
283 public void move(String srcDir, String destDir) {
284 }
285
286 public void reindex(String[] ids) throws SearchException {
287 long companyId = GetterUtil.getLong(ids[0]);
288 String portletId = ids[1];
289 long groupId = GetterUtil.getLong(ids[2]);
290 long repositoryId = GetterUtil.getLong(ids[3]);
291
292 Collection<Document> documents = new ArrayList<Document>();
293
294 try {
295 S3Object[] searchObjects = _s3Service.listObjects(
296 _s3Bucket, getKey(companyId, repositoryId), null);
297
298 Set<String> fileNameSet = new HashSet<String>();
299
300 for (int i = 0; i < searchObjects.length; i++) {
301 S3Object currentObject = searchObjects[i];
302
303 String fileName = getFileName(currentObject.getKey());
304
305 fileNameSet.add(fileName);
306 }
307
308 Iterator<String> itr = fileNameSet.iterator();
309
310 while (itr.hasNext()) {
311 String fileName = itr.next();
312
313 Indexer indexer = IndexerRegistryUtil.getIndexer(
314 FileModel.class);
315
316 FileModel fileModel = new FileModel();
317
318 fileModel.setCompanyId(companyId);
319 fileModel.setFileName(fileName);
320 fileModel.setGroupId(groupId);
321 fileModel.setPortletId(portletId);
322 fileModel.setRepositoryId(repositoryId);
323
324 Document document = indexer.getDocument(fileModel);
325
326 if (document == null) {
327 continue;
328 }
329
330 documents.add(document);
331 }
332 }
333 catch (S3ServiceException s3se) {
334 throw new SearchException(s3se);
335 }
336
337 SearchEngineUtil.updateDocuments(companyId, documents);
338 }
339
340 public void updateFile(
341 long companyId, String portletId, long groupId, long repositoryId,
342 long newRepositoryId, String fileName, long fileEntryId)
343 throws PortalException, SystemException {
344
345 try {
346 S3Object[] s3Objects = _s3Service.listObjects(
347 _s3Bucket, getKey(companyId, repositoryId, fileName), null);
348
349 for (int i = 0; i < s3Objects.length; i++) {
350 S3Object oldS3Object = s3Objects[i];
351
352 String oldKey = oldS3Object.getKey();
353
354 oldS3Object = _s3Service.getObject(_s3Bucket, oldKey);
355
356 File tempFile = new File(
357 SystemProperties.get(SystemProperties.TMP_DIR) +
358 File.separator + PortalUUIDUtil.generate());
359
360 FileUtil.write(tempFile, oldS3Object.getDataInputStream());
361
362 InputStream is = new FileInputStream(tempFile);
363
364 String newPrefix = getKey(companyId, newRepositoryId);
365
366 int x = oldKey.indexOf(StringPool.SLASH);
367
368 x = oldKey.indexOf(StringPool.SLASH, x + 1);
369
370 String newKey =
371 newPrefix + oldKey.substring(x + 1, oldKey.length());
372
373 S3Object newS3Object = new S3Object(
374 _s3Bucket, newKey);
375
376 newS3Object.setDataInputStream(is);
377
378 _s3Service.putObject(_s3Bucket, newS3Object);
379 _s3Service.deleteObject(_s3Bucket, oldKey);
380
381 FileUtil.delete(tempFile);
382 }
383
384 Indexer indexer = IndexerRegistryUtil.getIndexer(
385 FileModel.class);
386
387 FileModel fileModel = new FileModel();
388
389 fileModel.setCompanyId(companyId);
390 fileModel.setFileName(fileName);
391 fileModel.setPortletId(portletId);
392 fileModel.setRepositoryId(repositoryId);
393
394 indexer.delete(fileModel);
395
396 fileModel.setRepositoryId(newRepositoryId);
397 fileModel.setGroupId(groupId);
398
399 indexer.reindex(fileModel);
400 }
401 catch (IOException ioe) {
402 throw new SystemException(ioe);
403 }
404 catch (S3ServiceException s3se) {
405 throw new SystemException(s3se);
406 }
407 }
408
409 public void updateFile(
410 long companyId, String portletId, long groupId, long repositoryId,
411 String fileName, String newFileName, boolean reindex)
412 throws PortalException, SystemException {
413
414 try {
415 S3Object[] s3Objects = _s3Service.listObjects(
416 _s3Bucket, getKey(companyId, repositoryId, fileName), null);
417
418 for (int i = 0; i < s3Objects.length; i++) {
419 S3Object oldS3Object = s3Objects[i];
420
421 String oldKey = oldS3Object.getKey();
422
423 oldS3Object = _s3Service.getObject(_s3Bucket, oldKey);
424
425 File tempFile = new File(
426 SystemProperties.get(SystemProperties.TMP_DIR) +
427 File.separator + PortalUUIDUtil.generate());
428
429 FileUtil.write(tempFile, oldS3Object.getDataInputStream());
430
431 InputStream is = new FileInputStream(tempFile);
432
433 String newPrefix = getKey(companyId, repositoryId, newFileName);
434
435 int x = oldKey.indexOf(StringPool.SLASH);
436
437 x = oldKey.indexOf(StringPool.SLASH, x + 1);
438
439 x = oldKey.indexOf(StringPool.SLASH, x + 1);
440
441 String newKey =
442 newPrefix + oldKey.substring(x + 1, oldKey.length());
443
444 S3Object newS3Object = new S3Object(
445 _s3Bucket, newKey);
446
447 newS3Object.setDataInputStream(is);
448
449 _s3Service.putObject(_s3Bucket, newS3Object);
450 _s3Service.deleteObject(_s3Bucket, oldKey);
451
452 FileUtil.delete(tempFile);
453 }
454
455 if (reindex) {
456 Indexer indexer = IndexerRegistryUtil.getIndexer(
457 FileModel.class);
458
459 FileModel fileModel = new FileModel();
460
461 fileModel.setCompanyId(companyId);
462 fileModel.setFileName(fileName);
463 fileModel.setPortletId(portletId);
464 fileModel.setRepositoryId(repositoryId);
465
466 indexer.delete(fileModel);
467
468 fileModel.setFileName(newFileName);
469 fileModel.setGroupId(groupId);
470
471 indexer.reindex(fileModel);
472 }
473 }
474 catch (IOException ioe) {
475 throw new SystemException(ioe);
476 }
477 catch (S3ServiceException s3se) {
478 throw new SystemException(s3se);
479 }
480 }
481
482 public void updateFile(
483 long companyId, String portletId, long groupId, long repositoryId,
484 String fileName, String versionNumber, String sourceFileName,
485 long fileEntryId, String properties, Date modifiedDate,
486 ServiceContext serviceContext, InputStream is)
487 throws PortalException, SystemException {
488
489 try {
490 S3Object s3Object = new S3Object(
491 _s3Bucket,
492 getKey(companyId, repositoryId, fileName, versionNumber));
493
494 s3Object.setDataInputStream(is);
495
496 _s3Service.putObject(_s3Bucket, s3Object);
497
498 Indexer indexer = IndexerRegistryUtil.getIndexer(
499 FileModel.class);
500
501 FileModel fileModel = new FileModel();
502
503 fileModel.setAssetCategoryIds(serviceContext.getAssetCategoryIds());
504 fileModel.setAssetTagNames(serviceContext.getAssetTagNames());
505 fileModel.setCompanyId(companyId);
506 fileModel.setFileEntryId(fileEntryId);
507 fileModel.setFileName(fileName);
508 fileModel.setGroupId(groupId);
509 fileModel.setModifiedDate(modifiedDate);
510 fileModel.setPortletId(portletId);
511 fileModel.setProperties(properties);
512 fileModel.setRepositoryId(repositoryId);
513
514 indexer.reindex(fileModel);
515 }
516 catch (S3ServiceException s3se) {
517 throw new SystemException(s3se);
518 }
519 }
520
521 protected AWSCredentials getAWSCredentials() throws S3ServiceException {
522 if (Validator.isNull(_ACCESS_KEY) || Validator.isNull(_SECRET_KEY)) {
523 throw new S3ServiceException(
524 "S3 access and secret keys are not set");
525 }
526 else {
527 return new AWSCredentials(_ACCESS_KEY, _SECRET_KEY);
528 }
529 }
530
531 protected String getFileName(String key) {
532 int x = key.indexOf(StringPool.SLASH);
533
534 x = key.indexOf(StringPool.SLASH, x + 1);
535
536 int y = key.lastIndexOf(StringPool.SLASH);
537
538 return key.substring(x + 1, y);
539 }
540
541 protected String getHeadVersionNumber(
542 long companyId, long repositoryId, String fileName)
543 throws PortalException, S3ServiceException {
544
545 S3Object[] s3Objects = _s3Service.listObjects(
546 _s3Bucket, getKey(companyId, repositoryId, fileName), null);
547
548 String[] keys = new String[s3Objects.length];
549
550 for (int i = 0; i < s3Objects.length; i++) {
551 S3Object s3Object = s3Objects[i];
552
553 keys[i] = s3Object.getKey();
554 }
555
556 if (keys.length > 0) {
557 Arrays.sort(keys);
558
559 String headKey = keys[keys.length - 1];
560
561 int x = headKey.lastIndexOf(StringPool.SLASH);
562
563 return headKey.substring(x + 1, headKey.length());
564 }
565 else {
566 throw new NoSuchFileException(fileName);
567 }
568 }
569
570 protected String getKey(long companyId, long repositoryId) {
571 StringBundler sb = new StringBundler(4);
572
573 sb.append(companyId);
574 sb.append(StringPool.SLASH);
575 sb.append(repositoryId);
576 sb.append(StringPool.SLASH);
577
578 return sb.toString();
579 }
580
581 protected String getKey(
582 long companyId, long repositoryId, String fileName) {
583
584 StringBundler sb = new StringBundler(6);
585
586 sb.append(companyId);
587 sb.append(StringPool.SLASH);
588 sb.append(repositoryId);
589 sb.append(StringPool.SLASH);
590 sb.append(fileName);
591 sb.append(StringPool.SLASH);
592
593 return sb.toString();
594 }
595
596 protected String getKey(
597 long companyId, long repositoryId, String fileName,
598 String versionNumber) {
599
600 StringBundler sb = new StringBundler(7);
601
602 sb.append(companyId);
603 sb.append(StringPool.SLASH);
604 sb.append(repositoryId);
605 sb.append(StringPool.SLASH);
606 sb.append(fileName);
607 sb.append(StringPool.SLASH);
608 sb.append(versionNumber);
609
610 return sb.toString();
611 }
612
613 protected S3Bucket getS3Bucket() throws S3ServiceException {
614 if (Validator.isNull(_BUCKET_NAME)) {
615 throw new S3ServiceException("S3 bucket name is not set");
616 }
617 else {
618 return getS3Service().createBucket(_BUCKET_NAME);
619 }
620 }
621
622 protected S3Service getS3Service() throws S3ServiceException {
623 AWSCredentials credentials = getAWSCredentials();
624
625 return new RestS3Service(credentials);
626 }
627
628 private static final String _ACCESS_KEY = PropsUtil.get(
629 PropsKeys.DL_HOOK_S3_ACCESS_KEY);
630
631 private static final String _BUCKET_NAME = PropsUtil.get(
632 PropsKeys.DL_HOOK_S3_BUCKET_NAME);
633
634 private static final String _SECRET_KEY = PropsUtil.get(
635 PropsKeys.DL_HOOK_S3_SECRET_KEY);
636
637 private static Log _log = LogFactoryUtil.getLog(S3Hook.class);
638
639 private S3Bucket _s3Bucket;
640 private S3Service _s3Service;
641
642 }