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 Folder versioningFolder = getVersioningFolder(
111 companyId, repositoryId, fileName, false);
112
113 ObjectId versioningFolderObjectId = new ObjectIdImpl(
114 versioningFolder.getId());
115
116 Map<String, Object> documentProperties = new HashMap<String, Object>();
117
118 String title = String.valueOf(toVersionLabel);
119
120 documentProperties.put(PropertyIds.NAME, title);
121
122 documentProperties.put(
123 PropertyIds.OBJECT_TYPE_ID, BaseTypeId.CMIS_DOCUMENT.value());
124
125 Document document = getVersionedDocument(
126 companyId, repositoryId, fileName, fromVersionLabel);
127
128 document.copy(
129 versioningFolderObjectId, documentProperties, null,
130 document.getPolicies(), null, null, null);
131 }
132
133 @Override
134 public void deleteDirectory(
135 long companyId, long repositoryId, String dirName) {
136
137 Folder repositoryFolder = getRepositoryFolder(companyId, repositoryId);
138
139 Folder directory = getFolder(repositoryFolder, dirName);
140
141 if (directory != null) {
142 directory.deleteTree(true, UnfileObject.DELETE, false);
143 }
144 }
145
146 @Override
147 public void deleteFile(long companyId, long repositoryId, String fileName)
148 throws PortalException {
149
150 Folder versioningFolder = getVersioningFolder(
151 companyId, repositoryId, fileName, false);
152
153 if (versioningFolder == null) {
154 throw new NoSuchFileException();
155 }
156
157 versioningFolder.deleteTree(true, UnfileObject.DELETE, false);
158 }
159
160 @Override
161 public void deleteFile(
162 long companyId, long repositoryId, String fileName,
163 String versionLabel)
164 throws PortalException {
165
166 Document document = getVersionedDocument(
167 companyId, repositoryId, fileName, versionLabel);
168
169 document.delete(true);
170 }
171
172 @Override
173 public InputStream getFileAsStream(
174 long companyId, long repositoryId, String fileName,
175 String versionLabel)
176 throws PortalException {
177
178 if (Validator.isNull(versionLabel)) {
179 versionLabel = getHeadVersionLabel(
180 companyId, repositoryId, fileName);
181 }
182
183 Document document = getVersionedDocument(
184 companyId, repositoryId, fileName, versionLabel);
185
186 return document.getContentStream().getStream();
187 }
188
189 @Override
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 @Override
346 public void updateFile(
347 long companyId, long repositoryId, String fileName,
348 String newFileName) {
349
350 Folder oldVersioningFolderEntry = getVersioningFolder(
351 companyId, repositoryId, fileName, true);
352 Folder newVersioningFolderEntry = getVersioningFolder(
353 companyId, repositoryId, newFileName, true);
354
355 List<Folder> folders = getFolders(oldVersioningFolderEntry);
356
357 for (Folder folder : folders) {
358 String curFileName = folder.getName();
359
360 Document document = getDocument(
361 oldVersioningFolderEntry, curFileName);
362
363 InputStream is = document.getContentStream().getStream();
364
365 createDocument(newVersioningFolderEntry, curFileName, is);
366 }
367
368 oldVersioningFolderEntry.deleteTree(true, UnfileObject.DELETE, false);
369 }
370
371 @Override
372 public void updateFile(
373 long companyId, long repositoryId, String fileName,
374 String versionLabel, InputStream is)
375 throws PortalException {
376
377 Folder versioningFolder = getVersioningFolder(
378 companyId, repositoryId, fileName, true);
379
380 String title = String.valueOf(versionLabel);
381
382 Document document = getDocument(versioningFolder, title);
383
384 if (document != null) {
385 throw new DuplicateFileException();
386 }
387
388 createDocument(versioningFolder, title, is);
389 }
390
391 @Override
392 public void updateFileVersion(
393 long companyId, long repositoryId, String fileName,
394 String fromVersionLabel, String toVersionLabel)
395 throws PortalException {
396
397 Folder versioningFolder = getVersioningFolder(
398 companyId, repositoryId, fileName, false);
399
400 String title = String.valueOf(toVersionLabel);
401
402 Document document = getDocument(versioningFolder, title);
403
404 if (document != null) {
405 throw new DuplicateFileException();
406 }
407
408 document = getVersionedDocument(
409 companyId, repositoryId, fileName, fromVersionLabel);
410
411 Map<String, Object> documentProperties = new HashMap<String, Object>();
412
413 documentProperties.put(PropertyIds.NAME, title);
414
415 document.updateProperties(documentProperties);
416 }
417
418 protected Document createDocument(
419 Folder versioningFolder, String title, InputStream is) {
420
421 Map<String, Object> documentProperties = new HashMap<String, Object>();
422
423 documentProperties.put(PropertyIds.NAME, title);
424 documentProperties.put(
425 PropertyIds.OBJECT_TYPE_ID, BaseTypeId.CMIS_DOCUMENT.value());
426
427 ContentStream contentStream = new ContentStreamImpl(
428 null, null, ContentTypes.APPLICATION_OCTET_STREAM, is);
429
430 return versioningFolder.createDocument(
431 documentProperties, contentStream, null);
432 }
433
434 protected Folder createFolder(ObjectId parentFolderId, String name) {
435 Map<String, Object> properties = new HashMap<String, Object>();
436
437 properties.put(PropertyIds.NAME, name);
438 properties.put(
439 PropertyIds.OBJECT_TYPE_ID, BaseTypeId.CMIS_FOLDER.value());
440
441 ObjectId objectId = SessionHolder.session.createFolder(
442 properties, parentFolderId);
443
444 return (Folder)SessionHolder.session.getObject(objectId);
445 }
446
447 protected Folder getCompanyFolder(long companyId) {
448 String name = String.valueOf(companyId);
449
450 Folder companyFolder = getFolder(_systemRootDir, name);
451
452 if (companyFolder == null) {
453 companyFolder = createFolder(_systemRootDir, name);
454 }
455
456 return companyFolder;
457 }
458
459 protected Document getDocument(Folder parentFolder, String name) {
460 ItemIterable<CmisObject> cmisObjects = parentFolder.getChildren();
461
462 for (CmisObject cmisObject : cmisObjects) {
463 if (name.equals(cmisObject.getName()) &&
464 cmisObject instanceof Document) {
465
466 return (Document)cmisObject;
467 }
468 }
469
470 return null;
471 }
472
473 protected Folder getFolder(Folder parentFolder, String name) {
474 ItemIterable<CmisObject> cmisObjects = parentFolder.getChildren();
475
476 for (CmisObject cmisObject : cmisObjects) {
477 if (name.equals(cmisObject.getName()) &&
478 cmisObject instanceof Folder) {
479
480 return (Folder)cmisObject;
481 }
482 }
483
484 return null;
485 }
486
487 protected List<Folder> getFolders(Folder folder) {
488 List<Folder> folders = new ArrayList<Folder>();
489
490 ItemIterable<CmisObject> cmisObjects = folder.getChildren();
491
492 for (CmisObject cmisObject : cmisObjects) {
493 if (cmisObject instanceof Folder) {
494 folders.add((Folder)cmisObject);
495 }
496 }
497
498 return folders;
499 }
500
501 protected Folder getRepositoryFolder(long companyId, long repositoryId) {
502 Folder companyFolder = getCompanyFolder(companyId);
503
504 String name = String.valueOf(repositoryId);
505
506 Folder repositoryFolder = getFolder(companyFolder, name);
507
508 if (repositoryFolder == null) {
509 repositoryFolder = createFolder(companyFolder, name);
510 }
511
512 return repositoryFolder;
513 }
514
515 protected Document getVersionedDocument(
516 long companyId, long repositoryId, String fileName,
517 String versionLabel)
518 throws NoSuchFileException {
519
520 Folder versioningFolder = getVersioningFolder(
521 companyId, repositoryId, fileName, false);
522
523 if (versioningFolder == null) {
524 throw new NoSuchFileException();
525 }
526
527 Document document = getDocument(versioningFolder, versionLabel);
528
529 if (document == null) {
530 throw new NoSuchFileException();
531 }
532
533 return document;
534 }
535
536 protected Folder getVersioningFolder(
537 long companyId, long repositoryId, String fileName, boolean create) {
538
539 Folder repositoryFolder = getRepositoryFolder(companyId, repositoryId);
540
541 Folder versioningFolder = repositoryFolder;
542
543 String[] dirNames = StringUtil.split(fileName, CharPool.SLASH);
544
545 for (String dirName : dirNames) {
546 Folder subFolder = getFolder(versioningFolder, dirName);
547
548 if (create && (subFolder == null)) {
549 subFolder = createFolder(versioningFolder, dirName);
550 }
551
552 versioningFolder = subFolder;
553 }
554
555 return versioningFolder;
556 }
557
558 private static Folder _systemRootDir;
559
560 private static class SessionHolder {
561
562 private final static Session session;
563
564 static {
565 Map<String, String> parameters = new HashMap<String, String>();
566
567 parameters.put(
568 SessionParameter.ATOMPUB_URL,
569 PropsValues.DL_STORE_CMIS_REPOSITORY_URL);
570 parameters.put(
571 SessionParameter.BINDING_TYPE, BindingType.ATOMPUB.value());
572 parameters.put(
573 SessionParameter.COMPRESSION, Boolean.TRUE.toString());
574
575 Locale locale = LocaleUtil.getDefault();
576
577 parameters.put(
578 SessionParameter.LOCALE_ISO3166_COUNTRY, locale.getCountry());
579 parameters.put(
580 SessionParameter.LOCALE_ISO639_LANGUAGE, locale.getLanguage());
581 parameters.put(
582 SessionParameter.PASSWORD,
583 PropsValues.DL_STORE_CMIS_CREDENTIALS_PASSWORD);
584 parameters.put(
585 SessionParameter.USER,
586 PropsValues.DL_STORE_CMIS_CREDENTIALS_USERNAME);
587
588 SessionFactory sessionFactory =
589 CMISRepositoryUtil.getSessionFactory();
590
591 List<Repository> repositories = sessionFactory.getRepositories(
592 parameters);
593
594 Repository repository = repositories.get(0);
595
596 session = repository.createSession();
597
598 session.setDefaultContext(CMISRepositoryUtil.getOperationContext());
599 }
600
601 }
602
603 }