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