1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * This library is free software; you can redistribute it and/or modify it under
5    * the terms of the GNU Lesser General Public License as published by the Free
6    * Software Foundation; either version 2.1 of the License, or (at your option)
7    * any later version.
8    *
9    * This library is distributed in the hope that it will be useful, but WITHOUT
10   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11   * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12   * details.
13   */
14  
15  package com.liferay.documentlibrary.util;
16  
17  import com.liferay.documentlibrary.DuplicateFileException;
18  import com.liferay.documentlibrary.NoSuchFileException;
19  import com.liferay.documentlibrary.model.FileModel;
20  import com.liferay.portal.cmis.CMISException;
21  import com.liferay.portal.cmis.CMISUtil;
22  import com.liferay.portal.cmis.model.CMISConstants;
23  import com.liferay.portal.cmis.model.CMISObject;
24  import com.liferay.portal.kernel.exception.PortalException;
25  import com.liferay.portal.kernel.log.Log;
26  import com.liferay.portal.kernel.log.LogFactoryUtil;
27  import com.liferay.portal.kernel.search.Document;
28  import com.liferay.portal.kernel.search.Indexer;
29  import com.liferay.portal.kernel.search.IndexerRegistryUtil;
30  import com.liferay.portal.kernel.search.SearchEngineUtil;
31  import com.liferay.portal.kernel.search.SearchException;
32  import com.liferay.portal.kernel.util.GetterUtil;
33  import com.liferay.portal.kernel.util.Validator;
34  import com.liferay.portal.service.ServiceContext;
35  import com.liferay.portlet.documentlibrary.util.DLUtil;
36  
37  import java.io.InputStream;
38  
39  import java.util.ArrayList;
40  import java.util.Collection;
41  import java.util.Date;
42  import java.util.List;
43  
44  import org.apache.abdera.model.Entry;
45  import org.apache.abdera.model.Link;
46  
47  /**
48   * <a href="CMISHook.java.html"><b><i>View Source</i></b></a>
49   *
50   * @author Alexander Chow
51   */
52  public class CMISHook extends BaseHook {
53  
54      public CMISHook() {
55          try {
56              String version = CMISUtil.verifyRepository();
57  
58              if (_log.isInfoEnabled()) {
59                  _log.info("CMIS Service is running version " + version);
60              }
61          }
62          catch (Exception e) {
63              _log.error(e, e);
64          }
65      }
66  
67      public void addDirectory(long companyId, long repositoryId, String dirName)
68          throws PortalException {
69  
70          Entry repositoryFolderEntry = getRepositoryFolderEntry(
71              companyId, repositoryId);
72  
73          CMISUtil.createFolder(repositoryFolderEntry, dirName);
74      }
75  
76      public void addFile(
77              long companyId, String portletId, long groupId, long repositoryId,
78              String fileName, long fileEntryId, String properties,
79              Date modifiedDate, ServiceContext serviceContext, InputStream is)
80          throws PortalException {
81  
82          updateFile(
83              companyId, portletId, groupId, repositoryId, fileName,
84              DEFAULT_VERSION, null, fileEntryId, properties, modifiedDate,
85              serviceContext, is);
86      }
87  
88      public void checkRoot(long companyId) {
89      }
90  
91      public void deleteDirectory(
92              long companyId, String portletId, long repositoryId, String dirName)
93          throws PortalException {
94  
95          Entry repositoryFolderEntry = getRepositoryFolderEntry(
96              companyId, repositoryId);
97  
98          Entry directory = CMISUtil.getFolder(repositoryFolderEntry, dirName);
99  
100         if (directory != null) {
101             CMISUtil.delete(directory);
102         }
103     }
104 
105     public void deleteFile(
106             long companyId, String portletId, long repositoryId,
107             String fileName)
108         throws PortalException {
109 
110         Entry versioningFolderEntry = getVersioningFolderEntry(
111             companyId, repositoryId, fileName, false);
112 
113         if (versioningFolderEntry == null) {
114             throw new NoSuchFileException();
115         }
116 
117         CMISUtil.delete(versioningFolderEntry);
118 
119         Indexer indexer = IndexerRegistryUtil.getIndexer(
120             FileModel.class);
121 
122         FileModel fileModel = new FileModel();
123 
124         fileModel.setCompanyId(companyId);
125         fileModel.setFileName(fileName);
126         fileModel.setPortletId(portletId);
127         fileModel.setRepositoryId(repositoryId);
128 
129         indexer.delete(fileModel);
130     }
131 
132     public void deleteFile(
133             long companyId, String portletId, long repositoryId,
134             String fileName, String versionNumber)
135         throws PortalException {
136 
137         Entry fileEntry = getVersionedFileEntry(
138             companyId, repositoryId, fileName, versionNumber);
139 
140         CMISUtil.delete(fileEntry);
141 
142         Indexer indexer = IndexerRegistryUtil.getIndexer(
143             FileModel.class);
144 
145         FileModel fileModel = new FileModel();
146 
147         fileModel.setCompanyId(companyId);
148         fileModel.setFileName(fileName);
149         fileModel.setPortletId(portletId);
150         fileModel.setRepositoryId(repositoryId);
151 
152         indexer.delete(fileModel);
153     }
154 
155     public InputStream getFileAsStream(
156             long companyId, long repositoryId, String fileName,
157             String versionNumber)
158         throws PortalException {
159 
160         if (Validator.isNull(versionNumber)) {
161             versionNumber = getHeadVersionNumber(
162                 companyId, repositoryId, fileName);
163         }
164 
165         Entry fileEntry = getVersionedFileEntry(
166             companyId, repositoryId, fileName, versionNumber);
167 
168         return CMISUtil.getInputStream(fileEntry);
169     }
170 
171     public String[] getFileNames(
172             long companyId, long repositoryId, String dirName)
173         throws PortalException {
174 
175         Entry repositoryFolderEntry = getRepositoryFolderEntry(
176             companyId, repositoryId);
177 
178         List<String> fileNames = CMISUtil.getFolders(repositoryFolderEntry);
179 
180         return fileNames.toArray(new String[fileNames.size()]);
181     }
182 
183     public long getFileSize(
184             long companyId, long repositoryId, String fileName)
185         throws PortalException {
186 
187         String versionNumber = getHeadVersionNumber(
188             companyId, repositoryId, fileName);
189 
190         Entry fileEntry = getVersionedFileEntry(
191             companyId, repositoryId, fileName, versionNumber);
192 
193         CMISObject cmisObject = fileEntry.getFirstChild(_cmisConstants.OBJECT);
194 
195         return cmisObject.getContentStreamLength();
196     }
197 
198     public String getHeadVersionNumber(
199             long companyId, long repositoryId, String dirName)
200         throws CMISException, NoSuchFileException {
201 
202         Entry versioningFolderEntry = getVersioningFolderEntry(
203             companyId, repositoryId, dirName, false);
204 
205         if (versioningFolderEntry == null) {
206             throw new NoSuchFileException();
207         }
208 
209         List<String> versionNumbers = CMISUtil.getFolders(
210             versioningFolderEntry);
211 
212         String headVersionNumber = DEFAULT_VERSION;
213 
214         for (String versionNumber : versionNumbers) {
215             if (DLUtil.compareVersions(versionNumber, headVersionNumber) > 0) {
216                 headVersionNumber = versionNumber;
217             }
218         }
219 
220         return headVersionNumber;
221     }
222 
223     public boolean hasFile(
224             long companyId, long repositoryId, String fileName,
225             String versionNumber)
226         throws PortalException {
227 
228         Entry versioningFolderEntry = getVersioningFolderEntry(
229             companyId, repositoryId, fileName, true);
230 
231         Link link = versioningFolderEntry.getLink(
232             _cmisConstants.LINK_DESCENDANTS);
233 
234         String url = link.getHref().toString();
235 
236         Entry fileEntry = CMISUtil.getEntry(
237             url, versionNumber, _cmisConstants.BASE_TYPE_DOCUMENT);
238 
239         if (fileEntry == null) {
240             return false;
241         }
242         else {
243             return true;
244         }
245     }
246 
247     public void move(String srcDir, String destDir) {
248     }
249 
250     public void reindex(String[] ids) throws SearchException {
251         long companyId = GetterUtil.getLong(ids[0]);
252         String portletId = ids[1];
253         long groupId = GetterUtil.getLong(ids[2]);
254         long repositoryId = GetterUtil.getLong(ids[3]);
255 
256         Collection<Document> documents = new ArrayList<Document>();
257 
258         try {
259             Entry repositoryFolderEntry = getRepositoryFolderEntry(
260                 companyId, repositoryId);
261 
262             List<String> fileNames = CMISUtil.getFolders(repositoryFolderEntry);
263 
264             for (String fileName : fileNames) {
265                 Indexer indexer = IndexerRegistryUtil.getIndexer(
266                     FileModel.class);
267 
268                 FileModel fileModel = new FileModel();
269 
270                 fileModel.setCompanyId(companyId);
271                 fileModel.setFileName(fileName);
272                 fileModel.setGroupId(groupId);
273                 fileModel.setPortletId(portletId);
274                 fileModel.setRepositoryId(repositoryId);
275 
276                 Document document = indexer.getDocument(fileModel);
277 
278                 if (document == null) {
279                     continue;
280                 }
281 
282                 documents.add(document);
283             }
284         }
285         catch (CMISException cmise) {
286             if (_log.isErrorEnabled()) {
287                 _log.error(cmise, cmise);
288             }
289         }
290 
291         SearchEngineUtil.updateDocuments(companyId, documents);
292     }
293 
294     public void updateFile(
295             long companyId, String portletId, long groupId, long repositoryId,
296             long newRepositoryId, String fileName, long fileEntryId)
297         throws PortalException {
298 
299         Entry oldVersioningFolderEntry = getVersioningFolderEntry(
300             companyId, repositoryId, fileName, true);
301         Entry newVersioningFolderEntry = getVersioningFolderEntry(
302             companyId, newRepositoryId, fileName, true);
303 
304         List<String> fileNames = CMISUtil.getFolders(oldVersioningFolderEntry);
305 
306         for (String curFileName : fileNames) {
307             Entry entry = CMISUtil.getDocument(
308                 oldVersioningFolderEntry, curFileName);
309 
310             InputStream is = CMISUtil.getInputStream(entry);
311 
312             CMISUtil.createDocument(newVersioningFolderEntry, curFileName, is);
313         }
314 
315         CMISUtil.delete(oldVersioningFolderEntry);
316 
317         Indexer indexer = IndexerRegistryUtil.getIndexer(FileModel.class);
318 
319         FileModel fileModel = new FileModel();
320 
321         fileModel.setCompanyId(companyId);
322         fileModel.setFileName(fileName);
323         fileModel.setPortletId(portletId);
324         fileModel.setRepositoryId(repositoryId);
325 
326         indexer.delete(fileModel);
327 
328         fileModel.setRepositoryId(newRepositoryId);
329         fileModel.setGroupId(groupId);
330 
331         indexer.reindex(fileModel);
332     }
333 
334     public void updateFile(
335             long companyId, String portletId, long groupId, long repositoryId,
336             String fileName, String newFileName, boolean reindex)
337         throws PortalException {
338 
339         Entry oldVersioningFolderEntry = getVersioningFolderEntry(
340             companyId, repositoryId, fileName, true);
341         Entry newVersioningFolderEntry = getVersioningFolderEntry(
342             companyId, repositoryId, newFileName, true);
343 
344         List<String> fileNames = CMISUtil.getFolders(oldVersioningFolderEntry);
345 
346         for (String curFileName : fileNames) {
347             Entry entry = CMISUtil.getDocument(
348                 oldVersioningFolderEntry, curFileName);
349 
350             InputStream is = CMISUtil.getInputStream(entry);
351 
352             CMISUtil.createDocument(newVersioningFolderEntry, curFileName, is);
353         }
354 
355         CMISUtil.delete(oldVersioningFolderEntry);
356 
357         if (reindex) {
358             Indexer indexer = IndexerRegistryUtil.getIndexer(FileModel.class);
359 
360             FileModel fileModel = new FileModel();
361 
362             fileModel.setCompanyId(companyId);
363             fileModel.setFileName(fileName);
364             fileModel.setPortletId(portletId);
365             fileModel.setRepositoryId(repositoryId);
366 
367             indexer.delete(fileModel);
368 
369             fileModel.setFileName(newFileName);
370             fileModel.setGroupId(groupId);
371 
372             indexer.reindex(fileModel);
373         }
374     }
375 
376     public void updateFile(
377             long companyId, String portletId, long groupId, long repositoryId,
378             String fileName, String versionNumber, String sourceFileName,
379             long fileEntryId, String properties, Date modifiedDate,
380             ServiceContext serviceContext, InputStream is)
381         throws PortalException {
382 
383         Entry versioningFolderEntry = getVersioningFolderEntry(
384             companyId, repositoryId, fileName, true);
385 
386         Link link = versioningFolderEntry.getLink(
387             _cmisConstants.LINK_DESCENDANTS);
388 
389         String url = link.getHref().toString();
390 
391         String title = String.valueOf(versionNumber);
392 
393         Entry fileEntry = CMISUtil.getEntry(
394             url, title, _cmisConstants.BASE_TYPE_DOCUMENT);
395 
396         if (fileEntry != null) {
397             throw new DuplicateFileException();
398         }
399 
400         fileEntry = CMISUtil.createDocument(url, title, is);
401 
402         Indexer indexer = IndexerRegistryUtil.getIndexer(FileModel.class);
403 
404         FileModel fileModel = new FileModel();
405 
406         fileModel.setAssetCategoryIds(serviceContext.getAssetCategoryIds());
407         fileModel.setAssetTagNames(serviceContext.getAssetTagNames());
408         fileModel.setCompanyId(companyId);
409         fileModel.setFileEntryId(fileEntryId);
410         fileModel.setFileName(fileName);
411         fileModel.setGroupId(groupId);
412         fileModel.setModifiedDate(modifiedDate);
413         fileModel.setPortletId(portletId);
414         fileModel.setProperties(properties);
415         fileModel.setRepositoryId(repositoryId);
416 
417         indexer.reindex(fileModel);
418     }
419 
420     protected Entry getCompanyFolderEntry(long companyId) throws CMISException {
421         String title = String.valueOf(companyId);
422 
423         Entry companyFolderEntry = CMISUtil.getFolder(title);
424 
425         if (companyFolderEntry == null) {
426             companyFolderEntry = CMISUtil.createFolder(title);
427         }
428 
429         return companyFolderEntry;
430     }
431 
432     protected Entry getRepositoryFolderEntry(long companyId, long repositoryId)
433         throws CMISException {
434 
435         Entry companyFolderEntry = getCompanyFolderEntry(companyId);
436 
437         Link link = companyFolderEntry.getLink(_cmisConstants.LINK_DESCENDANTS);
438 
439         String url = link.getHref().toString();
440 
441         String title = String.valueOf(repositoryId);
442 
443         Entry repositoryFolderEntry = CMISUtil.getFolder(url, title);
444 
445         if (repositoryFolderEntry == null) {
446             repositoryFolderEntry = CMISUtil.createFolder(url, title);
447         }
448 
449         return repositoryFolderEntry;
450     }
451 
452     protected Entry getVersionedFileEntry(
453             long companyId, long repositoryId, String fileName,
454             String versionNumber)
455         throws CMISException, NoSuchFileException {
456 
457         Entry versioningFolderEntry = getVersioningFolderEntry(
458             companyId, repositoryId, fileName, false);
459 
460         if (versioningFolderEntry == null) {
461             throw new NoSuchFileException();
462         }
463 
464         Link link = versioningFolderEntry.getLink(
465             _cmisConstants.LINK_DESCENDANTS);
466 
467         String url = link.getHref().toString();
468 
469         Entry fileEntry = CMISUtil.getEntry(
470             url, String.valueOf(versionNumber),
471             _cmisConstants.BASE_TYPE_DOCUMENT);
472 
473         if (fileEntry == null) {
474             throw new NoSuchFileException();
475         }
476 
477         return fileEntry;
478     }
479 
480     protected Entry getVersioningFolderEntry(
481             long companyId, long repositoryId, String fileName, boolean create)
482         throws CMISException {
483 
484         Entry repositoryFolderEntry = getRepositoryFolderEntry(
485             companyId, repositoryId);
486 
487         Link link = repositoryFolderEntry.getLink(
488             _cmisConstants.LINK_DESCENDANTS);
489 
490         String url = link.getHref().toString();
491 
492         Entry versioningFolderEntry = CMISUtil.getEntry(
493             url, fileName, _cmisConstants.BASE_TYPE_FOLDER);
494 
495         if (create && (versioningFolderEntry == null)) {
496             versioningFolderEntry = CMISUtil.createFolder(url, fileName);
497         }
498 
499         return versioningFolderEntry;
500     }
501 
502     private static Log _log = LogFactoryUtil.getLog(CMISHook.class);
503 
504     private static CMISConstants _cmisConstants = CMISConstants.getInstance();
505 
506 }