001
014
015 package com.liferay.portlet.documentlibrary.store;
016
017 import com.liferay.portal.kernel.exception.PortalException;
018 import com.liferay.portal.kernel.util.CharPool;
019 import com.liferay.portal.kernel.util.ContentTypes;
020 import com.liferay.portal.kernel.util.LocaleUtil;
021 import com.liferay.portal.kernel.util.StringPool;
022 import com.liferay.portal.kernel.util.StringUtil;
023 import com.liferay.portal.kernel.util.Validator;
024 import com.liferay.portal.repository.cmis.CMISRepositoryUtil;
025 import com.liferay.portal.util.PropsValues;
026 import com.liferay.portlet.documentlibrary.DuplicateFileException;
027 import com.liferay.portlet.documentlibrary.NoSuchFileException;
028 import com.liferay.portlet.documentlibrary.util.DLUtil;
029
030 import java.io.InputStream;
031
032 import java.util.ArrayList;
033 import java.util.HashMap;
034 import java.util.List;
035 import java.util.Locale;
036 import java.util.Map;
037
038 import org.apache.chemistry.opencmis.client.api.CmisObject;
039 import org.apache.chemistry.opencmis.client.api.Document;
040 import org.apache.chemistry.opencmis.client.api.Folder;
041 import org.apache.chemistry.opencmis.client.api.ItemIterable;
042 import org.apache.chemistry.opencmis.client.api.ObjectId;
043 import org.apache.chemistry.opencmis.client.api.Repository;
044 import org.apache.chemistry.opencmis.client.api.Session;
045 import org.apache.chemistry.opencmis.client.api.SessionFactory;
046 import org.apache.chemistry.opencmis.client.runtime.ObjectIdImpl;
047 import org.apache.chemistry.opencmis.commons.PropertyIds;
048 import org.apache.chemistry.opencmis.commons.SessionParameter;
049 import org.apache.chemistry.opencmis.commons.data.ContentStream;
050 import org.apache.chemistry.opencmis.commons.enums.BaseTypeId;
051 import org.apache.chemistry.opencmis.commons.enums.BindingType;
052 import org.apache.chemistry.opencmis.commons.enums.UnfileObject;
053 import org.apache.chemistry.opencmis.commons.impl.dataobjects.ContentStreamImpl;
054
055
059 public class CMISStore extends BaseStore {
060
061 public CMISStore() {
062 _systemRootDir = getFolder(
063 SessionHolder.session.getRootFolder(),
064 PropsValues.DL_STORE_CMIS_SYSTEM_ROOT_DIR);
065
066 if (_systemRootDir == null) {
067 _systemRootDir = createFolder(
068 SessionHolder.session.getRootFolder(),
069 PropsValues.DL_STORE_CMIS_SYSTEM_ROOT_DIR);
070 }
071 }
072
073 @Override
074 public void addDirectory(
075 long companyId, long repositoryId, String dirName) {
076
077 Folder folder = getRepositoryFolder(companyId, repositoryId);
078
079 String[] dirNames = StringUtil.split(dirName, CharPool.SLASH);
080
081 for (String curDirName : dirNames) {
082 Folder subFolder = getFolder(folder, curDirName);
083
084 if (subFolder == null) {
085 subFolder = createFolder(folder, curDirName);
086 }
087
088 folder = subFolder;
089 }
090 }
091
092 @Override
093 public void addFile(
094 long companyId, long repositoryId, String fileName, InputStream is)
095 throws PortalException {
096
097 updateFile(companyId, repositoryId, fileName, VERSION_DEFAULT, is);
098 }
099
100 @Override
101 public void checkRoot(long companyId) {
102 }
103
104 @Override
105 public void copyFileVersion(
106 long companyId, long repositoryId, String fileName,
107 String fromVersionLabel, String toVersionLabel)
108 throws PortalException {
109
110 if (fromVersionLabel.equals(toVersionLabel)) {
111 throw new DuplicateFileException(
112 String.format(
113 "{companyId=%s, fileName=%s, repositoryId=%s, version=%s}",
114 companyId, fileName, repositoryId, toVersionLabel));
115 }
116
117 Folder versioningFolder = getVersioningFolder(
118 companyId, repositoryId, fileName, false);
119
120 ObjectId versioningFolderObjectId = new ObjectIdImpl(
121 versioningFolder.getId());
122
123 Map<String, Object> documentProperties = new HashMap<String, Object>();
124
125 String title = String.valueOf(toVersionLabel);
126
127 documentProperties.put(PropertyIds.NAME, title);
128
129 documentProperties.put(
130 PropertyIds.OBJECT_TYPE_ID, BaseTypeId.CMIS_DOCUMENT.value());
131
132 Document document = getVersionedDocument(
133 companyId, repositoryId, fileName, fromVersionLabel);
134
135 document.copy(
136 versioningFolderObjectId, documentProperties, null,
137 document.getPolicies(), null, null, null);
138 }
139
140 @Override
141 public void deleteDirectory(
142 long companyId, long repositoryId, String dirName) {
143
144 Folder repositoryFolder = getRepositoryFolder(companyId, repositoryId);
145
146 Folder directory = getFolder(repositoryFolder, dirName);
147
148 if (directory != null) {
149 directory.deleteTree(true, UnfileObject.DELETE, false);
150 }
151 }
152
153 @Override
154 public void deleteFile(long companyId, long repositoryId, String fileName)
155 throws PortalException {
156
157 Folder versioningFolder = getVersioningFolder(
158 companyId, repositoryId, fileName, false);
159
160 if (versioningFolder == null) {
161 throw new NoSuchFileException();
162 }
163
164 versioningFolder.deleteTree(true, UnfileObject.DELETE, false);
165 }
166
167 @Override
168 public void deleteFile(
169 long companyId, long repositoryId, String fileName,
170 String versionLabel)
171 throws PortalException {
172
173 Document document = getVersionedDocument(
174 companyId, repositoryId, fileName, versionLabel);
175
176 document.delete(true);
177 }
178
179 @Override
180 public InputStream getFileAsStream(
181 long companyId, long repositoryId, String fileName,
182 String versionLabel)
183 throws PortalException {
184
185 if (Validator.isNull(versionLabel)) {
186 versionLabel = getHeadVersionLabel(
187 companyId, repositoryId, fileName);
188 }
189
190 Document document = getVersionedDocument(
191 companyId, repositoryId, fileName, versionLabel);
192
193 return document.getContentStream().getStream();
194 }
195
196 @Override
197 public String[] getFileNames(long companyId, long repositoryId) {
198 Folder folder = getRepositoryFolder(companyId, repositoryId);
199
200 List<Folder> folders = getFolders(folder);
201
202 String[] fileNames = new String[folders.size()];
203
204 for (int i = 0; i < folders.size(); i++) {
205 Folder curFolder = folders.get(i);
206
207 fileNames[i] = curFolder.getName();
208 }
209
210 return fileNames;
211 }
212
213 @Override
214 public String[] getFileNames(
215 long companyId, long repositoryId, String dirName) {
216
217 Folder folder = getRepositoryFolder(companyId, repositoryId);
218
219 String[] dirNames = StringUtil.split(dirName, CharPool.SLASH);
220
221 for (String curDirName : dirNames) {
222 Folder subFolder = getFolder(folder, curDirName);
223
224 if (subFolder == null) {
225 subFolder = createFolder(folder, curDirName);
226 }
227
228 folder = subFolder;
229 }
230
231 List<Folder> folders = getFolders(folder);
232
233 String[] fileNames = new String[folders.size()];
234
235 for (int i = 0; i < folders.size(); i++) {
236 Folder curFolder = folders.get(i);
237
238 String fileName = curFolder.getName();
239
240 fileNames[i] = dirName.concat(StringPool.SLASH).concat(fileName);
241 }
242
243 return fileNames;
244 }
245
246 @Override
247 public long getFileSize(long companyId, long repositoryId, String fileName)
248 throws PortalException {
249
250 String versionLabel = getHeadVersionLabel(
251 companyId, repositoryId, fileName);
252
253 Document document = getVersionedDocument(
254 companyId, repositoryId, fileName, versionLabel);
255
256 return document.getContentStreamLength();
257 }
258
259 public String getHeadVersionLabel(
260 long companyId, long repositoryId, String dirName)
261 throws NoSuchFileException {
262
263 Folder versioningFolder = getVersioningFolder(
264 companyId, repositoryId, dirName, false);
265
266 if (versioningFolder == null) {
267 throw new NoSuchFileException();
268 }
269
270 List<Folder> folders = getFolders(versioningFolder);
271
272 String headVersionLabel = VERSION_DEFAULT;
273
274 for (Folder folder : folders) {
275 String versionLabel = folder.getName();
276
277 if (DLUtil.compareVersions(versionLabel, headVersionLabel) > 0) {
278 headVersionLabel = versionLabel;
279 }
280 }
281
282 return headVersionLabel;
283 }
284
285 @Override
286 public boolean hasDirectory(
287 long companyId, long repositoryId, String dirName) {
288
289 Folder folder = getRepositoryFolder(companyId, repositoryId);
290
291 String[] dirNames = StringUtil.split(dirName, CharPool.SLASH);
292
293 for (String subdirName : dirNames) {
294 Folder subfolder = getFolder(folder, subdirName);
295
296 if (subfolder == null) {
297 return false;
298 }
299 }
300
301 return true;
302 }
303
304 @Override
305 public boolean hasFile(
306 long companyId, long repositoryId, String fileName,
307 String versionLabel) {
308
309 Folder versioningFolder = getVersioningFolder(
310 companyId, repositoryId, fileName, true);
311
312 Document document = getDocument(versioningFolder, versionLabel);
313
314 if (document == null) {
315 return false;
316 }
317 else {
318 return true;
319 }
320 }
321
322 @Override
323 public void move(String srcDir, String destDir) {
324 }
325
326 @Override
327 public void updateFile(
328 long companyId, long repositoryId, long newRepositoryId,
329 String fileName)
330 throws PortalException {
331
332 if (repositoryId == newRepositoryId) {
333 throw new DuplicateFileException(
334 String.format(
335 "{companyId=%s, fileName=%s, repositoryId=%s}", companyId,
336 fileName, repositoryId));
337 }
338
339 Folder oldVersioningFolderEntry = getVersioningFolder(
340 companyId, repositoryId, fileName, true);
341 Folder newVersioningFolderEntry = getVersioningFolder(
342 companyId, newRepositoryId, fileName, true);
343
344 List<Folder> folders = getFolders(oldVersioningFolderEntry);
345
346 for (Folder folder : folders) {
347 String curFileName = folder.getName();
348
349 Document document = getDocument(
350 oldVersioningFolderEntry, curFileName);
351
352 InputStream is = document.getContentStream().getStream();
353
354 createDocument(newVersioningFolderEntry, curFileName, is);
355 }
356
357 oldVersioningFolderEntry.deleteTree(true, UnfileObject.DELETE, false);
358 }
359
360 @Override
361 public void updateFile(
362 long companyId, long repositoryId, String fileName,
363 String newFileName)
364 throws PortalException {
365
366 if (fileName.equals(newFileName)) {
367 throw new DuplicateFileException(
368 String.format(
369 "{companyId=%s, fileName=%s, repositoryId=%s}", companyId,
370 fileName, repositoryId));
371 }
372
373 Folder oldVersioningFolderEntry = getVersioningFolder(
374 companyId, repositoryId, fileName, true);
375 Folder newVersioningFolderEntry = getVersioningFolder(
376 companyId, repositoryId, newFileName, true);
377
378 List<Folder> folders = getFolders(oldVersioningFolderEntry);
379
380 for (Folder folder : folders) {
381 String curFileName = folder.getName();
382
383 Document document = getDocument(
384 oldVersioningFolderEntry, curFileName);
385
386 InputStream is = document.getContentStream().getStream();
387
388 createDocument(newVersioningFolderEntry, curFileName, is);
389 }
390
391 oldVersioningFolderEntry.deleteTree(true, UnfileObject.DELETE, false);
392 }
393
394 @Override
395 public void updateFile(
396 long companyId, long repositoryId, String fileName,
397 String versionLabel, InputStream is)
398 throws PortalException {
399
400 Folder versioningFolder = getVersioningFolder(
401 companyId, repositoryId, fileName, true);
402
403 String title = String.valueOf(versionLabel);
404
405 Document document = getDocument(versioningFolder, title);
406
407 if (document != null) {
408 throw new DuplicateFileException();
409 }
410
411 createDocument(versioningFolder, title, is);
412 }
413
414 @Override
415 public void updateFileVersion(
416 long companyId, long repositoryId, String fileName,
417 String fromVersionLabel, String toVersionLabel)
418 throws PortalException {
419
420 Folder versioningFolder = getVersioningFolder(
421 companyId, repositoryId, fileName, false);
422
423 String title = String.valueOf(toVersionLabel);
424
425 Document document = getDocument(versioningFolder, title);
426
427 if (document != null) {
428 throw new DuplicateFileException();
429 }
430
431 document = getVersionedDocument(
432 companyId, repositoryId, fileName, fromVersionLabel);
433
434 Map<String, Object> documentProperties = new HashMap<String, Object>();
435
436 documentProperties.put(PropertyIds.NAME, title);
437
438 document.updateProperties(documentProperties);
439 }
440
441 protected Document createDocument(
442 Folder versioningFolder, String title, InputStream is) {
443
444 Map<String, Object> documentProperties = new HashMap<String, Object>();
445
446 documentProperties.put(PropertyIds.NAME, title);
447 documentProperties.put(
448 PropertyIds.OBJECT_TYPE_ID, BaseTypeId.CMIS_DOCUMENT.value());
449
450 ContentStream contentStream = new ContentStreamImpl(
451 null, null, ContentTypes.APPLICATION_OCTET_STREAM, is);
452
453 return versioningFolder.createDocument(
454 documentProperties, contentStream, null);
455 }
456
457 protected Folder createFolder(ObjectId parentFolderId, String name) {
458 Map<String, Object> properties = new HashMap<String, Object>();
459
460 properties.put(PropertyIds.NAME, name);
461 properties.put(
462 PropertyIds.OBJECT_TYPE_ID, BaseTypeId.CMIS_FOLDER.value());
463
464 ObjectId objectId = SessionHolder.session.createFolder(
465 properties, parentFolderId);
466
467 return (Folder)SessionHolder.session.getObject(objectId);
468 }
469
470 protected Folder getCompanyFolder(long companyId) {
471 String name = String.valueOf(companyId);
472
473 Folder companyFolder = getFolder(_systemRootDir, name);
474
475 if (companyFolder == null) {
476 companyFolder = createFolder(_systemRootDir, name);
477 }
478
479 return companyFolder;
480 }
481
482 protected Document getDocument(Folder parentFolder, String name) {
483 ItemIterable<CmisObject> cmisObjects = parentFolder.getChildren();
484
485 for (CmisObject cmisObject : cmisObjects) {
486 if (name.equals(cmisObject.getName()) &&
487 cmisObject instanceof Document) {
488
489 return (Document)cmisObject;
490 }
491 }
492
493 return null;
494 }
495
496 protected Folder getFolder(Folder parentFolder, String name) {
497 ItemIterable<CmisObject> cmisObjects = parentFolder.getChildren();
498
499 for (CmisObject cmisObject : cmisObjects) {
500 if (name.equals(cmisObject.getName()) &&
501 cmisObject instanceof Folder) {
502
503 return (Folder)cmisObject;
504 }
505 }
506
507 return null;
508 }
509
510 protected List<Folder> getFolders(Folder folder) {
511 List<Folder> folders = new ArrayList<Folder>();
512
513 ItemIterable<CmisObject> cmisObjects = folder.getChildren();
514
515 for (CmisObject cmisObject : cmisObjects) {
516 if (cmisObject instanceof Folder) {
517 folders.add((Folder)cmisObject);
518 }
519 }
520
521 return folders;
522 }
523
524 protected Folder getRepositoryFolder(long companyId, long repositoryId) {
525 Folder companyFolder = getCompanyFolder(companyId);
526
527 String name = String.valueOf(repositoryId);
528
529 Folder repositoryFolder = getFolder(companyFolder, name);
530
531 if (repositoryFolder == null) {
532 repositoryFolder = createFolder(companyFolder, name);
533 }
534
535 return repositoryFolder;
536 }
537
538 protected Document getVersionedDocument(
539 long companyId, long repositoryId, String fileName,
540 String versionLabel)
541 throws NoSuchFileException {
542
543 Folder versioningFolder = getVersioningFolder(
544 companyId, repositoryId, fileName, false);
545
546 if (versioningFolder == null) {
547 throw new NoSuchFileException();
548 }
549
550 Document document = getDocument(versioningFolder, versionLabel);
551
552 if (document == null) {
553 throw new NoSuchFileException();
554 }
555
556 return document;
557 }
558
559 protected Folder getVersioningFolder(
560 long companyId, long repositoryId, String fileName, boolean create) {
561
562 Folder repositoryFolder = getRepositoryFolder(companyId, repositoryId);
563
564 Folder versioningFolder = repositoryFolder;
565
566 String[] dirNames = StringUtil.split(fileName, CharPool.SLASH);
567
568 for (String dirName : dirNames) {
569 Folder subFolder = getFolder(versioningFolder, dirName);
570
571 if (create && (subFolder == null)) {
572 subFolder = createFolder(versioningFolder, dirName);
573 }
574
575 versioningFolder = subFolder;
576 }
577
578 return versioningFolder;
579 }
580
581 private static Folder _systemRootDir;
582
583 private static class SessionHolder {
584
585 private final static Session session;
586
587 static {
588 Map<String, String> parameters = new HashMap<String, String>();
589
590 parameters.put(
591 SessionParameter.ATOMPUB_URL,
592 PropsValues.DL_STORE_CMIS_REPOSITORY_URL);
593 parameters.put(
594 SessionParameter.BINDING_TYPE, BindingType.ATOMPUB.value());
595 parameters.put(
596 SessionParameter.COMPRESSION, Boolean.TRUE.toString());
597
598 Locale locale = LocaleUtil.getDefault();
599
600 parameters.put(
601 SessionParameter.LOCALE_ISO3166_COUNTRY, locale.getCountry());
602 parameters.put(
603 SessionParameter.LOCALE_ISO639_LANGUAGE, locale.getLanguage());
604 parameters.put(
605 SessionParameter.PASSWORD,
606 PropsValues.DL_STORE_CMIS_CREDENTIALS_PASSWORD);
607 parameters.put(
608 SessionParameter.USER,
609 PropsValues.DL_STORE_CMIS_CREDENTIALS_USERNAME);
610
611 SessionFactory sessionFactory =
612 CMISRepositoryUtil.getSessionFactory();
613
614 List<Repository> repositories = sessionFactory.getRepositories(
615 parameters);
616
617 Repository repository = repositories.get(0);
618
619 session = repository.createSession();
620
621 session.setDefaultContext(CMISRepositoryUtil.getOperationContext());
622 }
623
624 }
625
626 }