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