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 @Override
191 public String[] getFileNames(long companyId, long repositoryId) {
192 Folder folder = getRepositoryFolder(companyId, repositoryId);
193
194 List<Folder> folders = getFolders(folder);
195
196 String[] fileNames = new String[folders.size()];
197
198 for (int i = 0; i < folders.size(); i++) {
199 Folder curFolder = folders.get(i);
200
201 fileNames[i] = curFolder.getName();
202 }
203
204 return fileNames;
205 }
206
207 @Override
208 public String[] getFileNames(
209 long companyId, long repositoryId, String dirName) {
210
211 Folder folder = getRepositoryFolder(companyId, repositoryId);
212
213 String[] dirNames = StringUtil.split(dirName, CharPool.SLASH);
214
215 for (String curDirName : dirNames) {
216 Folder subFolder = getFolder(folder, curDirName);
217
218 if (subFolder == null) {
219 subFolder = createFolder(folder, curDirName);
220 }
221
222 folder = subFolder;
223 }
224
225 List<Folder> folders = getFolders(folder);
226
227 String[] fileNames = new String[folders.size()];
228
229 for (int i = 0; i < folders.size(); i++) {
230 Folder curFolder = folders.get(i);
231
232 String fileName = curFolder.getName();
233
234 fileNames[i] = dirName.concat(StringPool.SLASH).concat(fileName);
235 }
236
237 return fileNames;
238 }
239
240 @Override
241 public long getFileSize(long companyId, long repositoryId, String fileName)
242 throws PortalException {
243
244 String versionLabel = getHeadVersionLabel(
245 companyId, repositoryId, fileName);
246
247 Document document = getVersionedDocument(
248 companyId, repositoryId, fileName, versionLabel);
249
250 return document.getContentStreamLength();
251 }
252
253 public String getHeadVersionLabel(
254 long companyId, long repositoryId, String dirName)
255 throws NoSuchFileException {
256
257 Folder versioningFolder = getVersioningFolder(
258 companyId, repositoryId, dirName, false);
259
260 if (versioningFolder == null) {
261 throw new NoSuchFileException();
262 }
263
264 List<Folder> folders = getFolders(versioningFolder);
265
266 String headVersionLabel = VERSION_DEFAULT;
267
268 for (Folder folder : folders) {
269 String versionLabel = folder.getName();
270
271 if (DLUtil.compareVersions(versionLabel, headVersionLabel) > 0) {
272 headVersionLabel = versionLabel;
273 }
274 }
275
276 return headVersionLabel;
277 }
278
279 @Override
280 public boolean hasDirectory(
281 long companyId, long repositoryId, String dirName) {
282
283 Folder folder = getRepositoryFolder(companyId, repositoryId);
284
285 String[] dirNames = StringUtil.split(dirName, CharPool.SLASH);
286
287 for (String subdirName : dirNames) {
288 Folder subfolder = getFolder(folder, subdirName);
289
290 if (subfolder == null) {
291 return false;
292 }
293 }
294
295 return true;
296 }
297
298 @Override
299 public boolean hasFile(
300 long companyId, long repositoryId, String fileName,
301 String versionLabel) {
302
303 Folder versioningFolder = getVersioningFolder(
304 companyId, repositoryId, fileName, true);
305
306 Document document = getDocument(versioningFolder, versionLabel);
307
308 if (document == null) {
309 return false;
310 }
311 else {
312 return true;
313 }
314 }
315
316 @Override
317 public void move(String srcDir, String destDir) {
318 }
319
320 @Override
321 public void updateFile(
322 long companyId, long repositoryId, long newRepositoryId,
323 String fileName) {
324
325 Folder oldVersioningFolderEntry = getVersioningFolder(
326 companyId, repositoryId, fileName, true);
327 Folder newVersioningFolderEntry = getVersioningFolder(
328 companyId, newRepositoryId, fileName, true);
329
330 List<Folder> folders = getFolders(oldVersioningFolderEntry);
331
332 for (Folder folder : folders) {
333 String curFileName = folder.getName();
334
335 Document document = getDocument(
336 oldVersioningFolderEntry, curFileName);
337
338 InputStream is = document.getContentStream().getStream();
339
340 createDocument(newVersioningFolderEntry, curFileName, is);
341 }
342
343 oldVersioningFolderEntry.deleteTree(true, UnfileObject.DELETE, false);
344 }
345
346 @Override
347 public void updateFile(
348 long companyId, long repositoryId, String fileName,
349 String newFileName) {
350
351 Folder oldVersioningFolderEntry = getVersioningFolder(
352 companyId, repositoryId, fileName, true);
353 Folder newVersioningFolderEntry = getVersioningFolder(
354 companyId, repositoryId, newFileName, true);
355
356 List<Folder> folders = getFolders(oldVersioningFolderEntry);
357
358 for (Folder folder : folders) {
359 String curFileName = folder.getName();
360
361 Document document = getDocument(
362 oldVersioningFolderEntry, curFileName);
363
364 InputStream is = document.getContentStream().getStream();
365
366 createDocument(newVersioningFolderEntry, curFileName, is);
367 }
368
369 oldVersioningFolderEntry.deleteTree(true, UnfileObject.DELETE, false);
370 }
371
372 @Override
373 public void updateFile(
374 long companyId, long repositoryId, String fileName,
375 String versionLabel, InputStream is)
376 throws PortalException {
377
378 Folder versioningFolder = getVersioningFolder(
379 companyId, repositoryId, fileName, true);
380
381 String title = String.valueOf(versionLabel);
382
383 Document document = getDocument(versioningFolder, title);
384
385 if (document != null) {
386 throw new DuplicateFileException();
387 }
388
389 createDocument(versioningFolder, title, is);
390 }
391
392 @Override
393 public void updateFileVersion(
394 long companyId, long repositoryId, String fileName,
395 String fromVersionLabel, String toVersionLabel)
396 throws PortalException {
397
398 Folder versioningFolder = getVersioningFolder(
399 companyId, repositoryId, fileName, false);
400
401 String title = String.valueOf(toVersionLabel);
402
403 Document document = getDocument(versioningFolder, title);
404
405 if (document != null) {
406 throw new DuplicateFileException();
407 }
408
409 document = getVersionedDocument(
410 companyId, repositoryId, fileName, fromVersionLabel);
411
412 Map<String, Object> documentProperties = new HashMap<String, Object>();
413
414 documentProperties.put(PropertyIds.NAME, title);
415
416 document.updateProperties(documentProperties);
417 }
418
419 protected Document createDocument(
420 Folder versioningFolder, String title, InputStream is) {
421
422 Map<String, Object> documentProperties = new HashMap<String, Object>();
423
424 documentProperties.put(PropertyIds.NAME, title);
425 documentProperties.put(
426 PropertyIds.OBJECT_TYPE_ID, BaseTypeId.CMIS_DOCUMENT.value());
427
428 ContentStream contentStream = new ContentStreamImpl(
429 null, null, ContentTypes.APPLICATION_OCTET_STREAM, is);
430
431 return versioningFolder.createDocument(
432 documentProperties, contentStream, null);
433 }
434
435 protected Folder createFolder(ObjectId parentFolderId, String name) {
436 Map<String, Object> properties = new HashMap<String, Object>();
437
438 properties.put(PropertyIds.NAME, name);
439 properties.put(
440 PropertyIds.OBJECT_TYPE_ID, BaseTypeId.CMIS_FOLDER.value());
441
442 ObjectId objectId = SessionHolder.session.createFolder(
443 properties, parentFolderId);
444
445 return (Folder)SessionHolder.session.getObject(objectId);
446 }
447
448 protected Folder getCompanyFolder(long companyId) {
449 String name = String.valueOf(companyId);
450
451 Folder companyFolder = getFolder(_systemRootDir, name);
452
453 if (companyFolder == null) {
454 companyFolder = createFolder(_systemRootDir, name);
455 }
456
457 return companyFolder;
458 }
459
460 protected Document getDocument(Folder parentFolder, String name) {
461 ItemIterable<CmisObject> cmisObjects = parentFolder.getChildren();
462
463 Iterator<CmisObject> itr = cmisObjects.iterator();
464
465 while (itr.hasNext()) {
466 CmisObject cmisObject = itr.next();
467
468 if (name.equals(cmisObject.getName()) &&
469 cmisObject instanceof Document) {
470
471 return (Document)cmisObject;
472 }
473 }
474
475 return null;
476 }
477
478 protected Folder getFolder(Folder parentFolder, String name) {
479 ItemIterable<CmisObject> cmisObjects = parentFolder.getChildren();
480
481 Iterator<CmisObject> itr = cmisObjects.iterator();
482
483 while (itr.hasNext()) {
484 CmisObject cmisObject = itr.next();
485
486 if (name.equals(cmisObject.getName()) &&
487 cmisObject instanceof Folder) {
488
489 return (Folder)cmisObject;
490 }
491 }
492
493 return null;
494 }
495
496 protected List<Folder> getFolders(Folder folder) {
497 List<Folder> folders = new ArrayList<Folder>();
498
499 ItemIterable<CmisObject> cmisObjects = folder.getChildren();
500
501 Iterator<CmisObject> itr = cmisObjects.iterator();
502
503 while (itr.hasNext()) {
504 CmisObject cmisObject = itr.next();
505
506 if (cmisObject instanceof Folder) {
507 folders.add((Folder)cmisObject);
508 }
509 }
510
511 return folders;
512 }
513
514 protected Folder getRepositoryFolder(long companyId, long repositoryId) {
515 Folder companyFolder = getCompanyFolder(companyId);
516
517 String name = String.valueOf(repositoryId);
518
519 Folder repositoryFolder = getFolder(companyFolder, name);
520
521 if (repositoryFolder == null) {
522 repositoryFolder = createFolder(companyFolder, name);
523 }
524
525 return repositoryFolder;
526 }
527
528 protected Document getVersionedDocument(
529 long companyId, long repositoryId, String fileName,
530 String versionLabel)
531 throws NoSuchFileException {
532
533 Folder versioningFolder = getVersioningFolder(
534 companyId, repositoryId, fileName, false);
535
536 if (versioningFolder == null) {
537 throw new NoSuchFileException();
538 }
539
540 Document document = getDocument(versioningFolder, versionLabel);
541
542 if (document == null) {
543 throw new NoSuchFileException();
544 }
545
546 return document;
547 }
548
549 protected Folder getVersioningFolder(
550 long companyId, long repositoryId, String fileName, boolean create) {
551
552 Folder repositoryFolder = getRepositoryFolder(companyId, repositoryId);
553
554 Folder versioningFolder = repositoryFolder;
555
556 String[] dirNames = StringUtil.split(fileName, CharPool.SLASH);
557
558 for (String dirName : dirNames) {
559 Folder subFolder = getFolder(versioningFolder, dirName);
560
561 if (create && (subFolder == null)) {
562 subFolder = createFolder(versioningFolder, dirName);
563 }
564
565 versioningFolder = subFolder;
566 }
567
568 return versioningFolder;
569 }
570
571 private static Folder _systemRootDir;
572
573 private static class SessionHolder {
574
575 private final static Session session;
576
577 static {
578 Map<String, String> parameters = new HashMap<String, String>();
579
580 parameters.put(
581 SessionParameter.ATOMPUB_URL,
582 PropsValues.DL_STORE_CMIS_REPOSITORY_URL);
583 parameters.put(
584 SessionParameter.BINDING_TYPE, BindingType.ATOMPUB.value());
585 parameters.put(
586 SessionParameter.COMPRESSION, Boolean.TRUE.toString());
587
588 Locale locale = LocaleUtil.getDefault();
589
590 parameters.put(
591 SessionParameter.LOCALE_ISO3166_COUNTRY, locale.getCountry());
592 parameters.put(
593 SessionParameter.LOCALE_ISO639_LANGUAGE, locale.getLanguage());
594 parameters.put(
595 SessionParameter.PASSWORD,
596 PropsValues.DL_STORE_CMIS_CREDENTIALS_PASSWORD);
597 parameters.put(
598 SessionParameter.USER,
599 PropsValues.DL_STORE_CMIS_CREDENTIALS_USERNAME);
600
601 SessionFactory sessionFactory =
602 CMISRepositoryUtil.getSessionFactory();
603
604 List<Repository> repositories = sessionFactory.getRepositories(
605 parameters);
606
607 Repository repository = repositories.get(0);
608
609 session = repository.createSession();
610
611 session.setDefaultContext(CMISRepositoryUtil.getOperationContext());
612 }
613
614 }
615
616 }