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