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