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