1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * The contents of this file are subject to the terms of the Liferay Enterprise
5    * Subscription License ("License"). You may not use this file except in
6    * compliance with the License. You can obtain a copy of the License by
7    * contacting Liferay, Inc. See the License for the specific language governing
8    * permissions and limitations under the License, including but not limited to
9    * distribution rights of the Software.
10   *
11   *
12   * 
13   */
14  
15  package com.liferay.documentlibrary.util;
16  
17  import com.liferay.documentlibrary.DuplicateDirectoryException;
18  import com.liferay.documentlibrary.DuplicateFileException;
19  import com.liferay.documentlibrary.NoSuchDirectoryException;
20  import com.liferay.documentlibrary.NoSuchFileException;
21  import com.liferay.portal.PortalException;
22  import com.liferay.portal.SystemException;
23  import com.liferay.portal.jcr.JCRConstants;
24  import com.liferay.portal.jcr.JCRFactory;
25  import com.liferay.portal.jcr.JCRFactoryUtil;
26  import com.liferay.portal.kernel.io.unsync.UnsyncBufferedInputStream;
27  import com.liferay.portal.kernel.log.Log;
28  import com.liferay.portal.kernel.log.LogFactoryUtil;
29  import com.liferay.portal.kernel.search.Document;
30  import com.liferay.portal.kernel.search.Field;
31  import com.liferay.portal.kernel.search.SearchEngineUtil;
32  import com.liferay.portal.kernel.search.SearchException;
33  import com.liferay.portal.kernel.util.GetterUtil;
34  import com.liferay.portal.kernel.util.StringUtil;
35  import com.liferay.portal.kernel.util.Validator;
36  
37  import java.io.InputStream;
38  
39  import java.util.ArrayList;
40  import java.util.Calendar;
41  import java.util.Date;
42  import java.util.List;
43  
44  import javax.jcr.Node;
45  import javax.jcr.NodeIterator;
46  import javax.jcr.PathNotFoundException;
47  import javax.jcr.Property;
48  import javax.jcr.RepositoryException;
49  import javax.jcr.Session;
50  import javax.jcr.version.Version;
51  import javax.jcr.version.VersionHistory;
52  import javax.jcr.version.VersionIterator;
53  
54  import org.apache.commons.lang.StringUtils;
55  
56  /**
57   * <a href="JCRHook.java.html"><b><i>View Source</i></b></a>
58   *
59   * @author Michael Young
60   * @author Brian Wing Shun Chan
61   */
62  public class JCRHook extends BaseHook {
63  
64      public void addDirectory(long companyId, long repositoryId, String dirName)
65          throws PortalException, SystemException {
66  
67          Session session = null;
68  
69          try {
70              session = JCRFactoryUtil.createSession();
71  
72              Node rootNode = getRootNode(session, companyId);
73              Node repositoryNode = getFolderNode(rootNode, repositoryId);
74  
75              if (repositoryNode.hasNode(dirName)) {
76                  throw new DuplicateDirectoryException(dirName);
77              }
78              else {
79                  String[] dirNameArray = StringUtil.split(dirName, "/");
80  
81                  Node dirNode = repositoryNode;
82  
83                  for (int i = 0; i < dirNameArray.length; i++) {
84                      if (Validator.isNotNull(dirNameArray[i])) {
85                          if (dirNode.hasNode(dirNameArray[i])) {
86                              dirNode = dirNode.getNode(dirNameArray[i]);
87                          }
88                          else {
89                              dirNode = dirNode.addNode(
90                                  dirNameArray[i], JCRConstants.NT_FOLDER);
91                          }
92                      }
93                  }
94  
95                  session.save();
96              }
97          }
98          catch (RepositoryException re) {
99              throw new SystemException(re);
100         }
101         finally {
102             if (session != null) {
103                 session.logout();
104             }
105         }
106     }
107 
108     public void addFile(
109             long companyId, String portletId, long groupId, long repositoryId,
110             String fileName, String properties, Date modifiedDate,
111             String[] tagsEntries, InputStream is)
112         throws PortalException, SystemException {
113 
114         Session session = null;
115 
116         try {
117             session = JCRFactoryUtil.createSession();
118 
119             Node rootNode = getRootNode(session, companyId);
120             Node repositoryNode = getFolderNode(rootNode, repositoryId);
121 
122             if (repositoryNode.hasNode(fileName)) {
123                 throw new DuplicateFileException(fileName);
124             }
125             else {
126                 Node fileNode = repositoryNode.addNode(
127                     fileName, JCRConstants.NT_FILE);
128 
129                 Node contentNode = fileNode.addNode(
130                     JCRConstants.JCR_CONTENT, JCRConstants.NT_RESOURCE);
131 
132                 contentNode.addMixin(JCRConstants.MIX_VERSIONABLE);
133                 contentNode.setProperty(
134                     JCRConstants.JCR_MIME_TYPE, "text/plain");
135                 contentNode.setProperty(JCRConstants.JCR_DATA, is);
136                 contentNode.setProperty(
137                     JCRConstants.JCR_LAST_MODIFIED, Calendar.getInstance());
138 
139                 session.save();
140 
141                 Version version = contentNode.checkin();
142 
143                 contentNode.getVersionHistory().addVersionLabel(
144                     version.getName(), String.valueOf(DEFAULT_VERSION), false);
145 
146                 DLIndexerUtil.addFile(
147                     companyId, portletId, groupId, repositoryId, fileName,
148                     properties, modifiedDate, tagsEntries);
149             }
150         }
151         catch (RepositoryException re) {
152             throw new SystemException(re);
153         }
154         catch (SearchException se) {
155             throw new SystemException(se);
156         }
157         finally {
158             if (session != null) {
159                 session.logout();
160             }
161         }
162     }
163 
164     public void checkRoot(long companyId) throws SystemException {
165         Session session = null;
166 
167         try {
168             session = JCRFactoryUtil.createSession();
169 
170             getRootNode(session, companyId);
171 
172             session.save();
173         }
174         catch (RepositoryException re) {
175             throw new SystemException(re);
176         }
177         finally {
178             if (session != null) {
179                 session.logout();
180             }
181         }
182     }
183 
184     public void deleteDirectory(
185             long companyId, String portletId, long repositoryId, String dirName)
186         throws PortalException, SystemException {
187 
188         Session session = null;
189 
190         try {
191             session = JCRFactoryUtil.createSession();
192 
193             Node rootNode = getRootNode(session, companyId);
194             Node repositoryNode = getFolderNode(rootNode, repositoryId);
195             Node dirNode = repositoryNode.getNode(dirName);
196 
197             deleteDirectory(companyId, portletId, repositoryId, dirNode);
198 
199             dirNode.remove();
200 
201             session.save();
202         }
203         catch (PathNotFoundException pnfe) {
204             throw new NoSuchDirectoryException(dirName);
205         }
206         catch (RepositoryException re) {
207             String message = GetterUtil.getString(re.getMessage());
208 
209             if (message.contains("failed to resolve path")) {
210                 throw new NoSuchDirectoryException(dirName);
211             }
212             else {
213                 throw new PortalException(re);
214             }
215         }
216         catch (SearchException se) {
217             throw new SystemException(se);
218         }
219         finally {
220             if (session != null) {
221                 session.logout();
222             }
223         }
224     }
225 
226     public void deleteFile(
227             long companyId, String portletId, long repositoryId,
228             String fileName)
229         throws PortalException, SystemException {
230 
231         Session session = null;
232 
233         // A bug in Jackrabbit requires us to create a dummy node and delete the
234         // version tree manually to successfully delete a file
235 
236         // Create a dummy node
237 
238         try {
239             session = JCRFactoryUtil.createSession();
240 
241             Node rootNode = getRootNode(session, companyId);
242             Node repositoryNode = getFolderNode(rootNode, repositoryId);
243             Node fileNode = repositoryNode.getNode(fileName);
244             Node contentNode = fileNode.getNode(JCRConstants.JCR_CONTENT);
245 
246             contentNode.checkout();
247 
248             contentNode.setProperty(JCRConstants.JCR_MIME_TYPE, "text/plain");
249             contentNode.setProperty(JCRConstants.JCR_DATA, "");
250             contentNode.setProperty(
251                 JCRConstants.JCR_LAST_MODIFIED, Calendar.getInstance());
252 
253             session.save();
254 
255             Version version = contentNode.checkin();
256 
257             contentNode.getVersionHistory().addVersionLabel(
258                 version.getName(), "0.0", false);
259         }
260         catch (PathNotFoundException pnfe) {
261             throw new NoSuchFileException(fileName);
262         }
263         catch (RepositoryException re) {
264             throw new SystemException(re);
265         }
266         finally {
267             if (session != null) {
268                 session.logout();
269             }
270         }
271 
272         // Delete version tree
273 
274         try {
275             session = JCRFactoryUtil.createSession();
276 
277             Node rootNode = getRootNode(session, companyId);
278             Node repositoryNode = getFolderNode(rootNode, repositoryId);
279             Node fileNode = repositoryNode.getNode(fileName);
280             Node contentNode = fileNode.getNode(JCRConstants.JCR_CONTENT);
281 
282             VersionHistory versionHistory = contentNode.getVersionHistory();
283 
284             VersionIterator itr = versionHistory.getAllVersions();
285 
286             while (itr.hasNext()) {
287                 Version version = itr.nextVersion();
288 
289                 if (itr.getPosition() == itr.getSize()) {
290                     break;
291                 }
292                 else {
293                     if (!StringUtils.equals(
294                             JCRConstants.JCR_ROOT_VERSION, version.getName())) {
295 
296                         versionHistory.removeVersion(version.getName());
297                     }
298                 }
299             }
300 
301             session.save();
302         }
303         catch (PathNotFoundException pnfe) {
304             throw new NoSuchFileException(fileName);
305         }
306         catch (RepositoryException re) {
307             throw new SystemException(re);
308         }
309         finally {
310             if (session != null) {
311                 session.logout();
312             }
313         }
314 
315         // Delete file
316 
317         try {
318             session = JCRFactoryUtil.createSession();
319 
320             Node rootNode = getRootNode(session, companyId);
321             Node repositoryNode = getFolderNode(rootNode, repositoryId);
322             Node fileNode = repositoryNode.getNode(fileName);
323 
324             DLIndexerUtil.deleteFile(
325                 companyId, portletId, repositoryId, fileName);
326 
327             fileNode.remove();
328 
329             session.save();
330         }
331         catch (PathNotFoundException pnfe) {
332             throw new NoSuchFileException(fileName);
333         }
334         catch (RepositoryException re) {
335             throw new SystemException(re);
336         }
337         catch (SearchException se) {
338             throw new SystemException(se);
339         }
340         finally {
341             if (session != null) {
342                 session.logout();
343             }
344         }
345     }
346 
347     public void deleteFile(
348             long companyId, String portletId, long repositoryId,
349             String fileName, double versionNumber)
350         throws PortalException, SystemException {
351 
352         String versionLabel = String.valueOf(versionNumber);
353 
354         Session session = null;
355 
356         try {
357             session = JCRFactoryUtil.createSession();
358 
359             Node rootNode = getRootNode(session, companyId);
360             Node repositoryNode = getFolderNode(rootNode, repositoryId);
361             Node fileNode = repositoryNode.getNode(fileName);
362             Node contentNode = fileNode.getNode(JCRConstants.JCR_CONTENT);
363 
364             VersionHistory versionHistory = contentNode.getVersionHistory();
365 
366             Version version = versionHistory.getVersionByLabel(versionLabel);
367 
368             versionHistory.removeVersion(version.getName());
369 
370             session.save();
371         }
372         catch (PathNotFoundException pnfe) {
373             throw new NoSuchFileException(fileName);
374         }
375         catch (RepositoryException re) {
376             throw new SystemException(re);
377         }
378         finally {
379             if (session != null) {
380                 session.logout();
381             }
382         }
383     }
384 
385     public InputStream getFileAsStream(
386             long companyId, long repositoryId, String fileName,
387             double versionNumber)
388         throws PortalException, SystemException {
389 
390         InputStream is = null;
391 
392         Session session = null;
393 
394         try {
395             session = JCRFactoryUtil.createSession();
396 
397             Node contentNode = getFileContentNode(
398                 session, companyId, repositoryId, fileName, versionNumber);
399 
400             Property data = contentNode.getProperty(JCRConstants.JCR_DATA);
401 
402             is = new UnsyncBufferedInputStream(data.getStream());
403         }
404         catch (RepositoryException re) {
405             throw new SystemException(re);
406         }
407         finally {
408             if (session != null) {
409                 session.logout();
410             }
411         }
412 
413         return is;
414     }
415 
416     public String[] getFileNames(
417             long companyId, long repositoryId, String dirName)
418         throws PortalException, SystemException {
419 
420         List<String> fileNames = new ArrayList<String>();
421 
422         Session session = null;
423 
424         try {
425             session = JCRFactoryUtil.createSession();
426 
427             Node rootNode = getRootNode(session, companyId);
428             Node repositoryNode = getFolderNode(rootNode, repositoryId);
429             Node dirNode = repositoryNode.getNode(dirName);
430 
431             NodeIterator itr = dirNode.getNodes();
432 
433             while (itr.hasNext()) {
434                 Node node = (Node)itr.next();
435 
436                 if (node.getPrimaryNodeType().getName().equals(
437                         JCRConstants.NT_FILE)) {
438 
439                     fileNames.add(dirName + "/" + node.getName());
440                 }
441             }
442         }
443         catch (PathNotFoundException pnfe) {
444             throw new NoSuchDirectoryException(dirName);
445         }
446         catch (RepositoryException re) {
447             throw new SystemException(re);
448         }
449         finally {
450             if (session != null) {
451                 session.logout();
452             }
453         }
454 
455         return fileNames.toArray(new String[fileNames.size()]);
456     }
457 
458     public long getFileSize(
459             long companyId, long repositoryId, String fileName)
460         throws PortalException, SystemException {
461 
462         long size;
463 
464         Session session = null;
465 
466         try {
467             session = JCRFactoryUtil.createSession();
468 
469             Node contentNode = getFileContentNode(
470                 session, companyId, repositoryId, fileName, 0);
471 
472             size = contentNode.getProperty(JCRConstants.JCR_DATA).getLength();
473         }
474         catch (RepositoryException re) {
475             throw new SystemException(re);
476         }
477         finally {
478             if (session != null) {
479                 session.logout();
480             }
481         }
482 
483         return size;
484     }
485 
486     public boolean hasFile(
487             long companyId, long repositoryId, String fileName,
488             double versionNumber)
489         throws PortalException, SystemException {
490 
491         try {
492             getFileContentNode(
493                 companyId, repositoryId, fileName, versionNumber);
494         }
495         catch (NoSuchFileException nsfe) {
496             return false;
497         }
498 
499         return true;
500     }
501 
502     public void move(String srcDir, String destDir) throws SystemException {
503         Session session = null;
504 
505         try {
506             session = JCRFactoryUtil.createSession();
507 
508             session.move(srcDir, destDir);
509 
510             session.save();
511         }
512         catch (RepositoryException re) {
513             throw new SystemException(re);
514         }
515         finally {
516             if (session != null) {
517                 session.logout();
518             }
519         }
520     }
521 
522     public void reIndex(String[] ids) throws SearchException {
523         long companyId = GetterUtil.getLong(ids[0]);
524         String portletId = ids[1];
525         long groupId = GetterUtil.getLong(ids[2]);
526         long repositoryId = GetterUtil.getLong(ids[3]);
527 
528         Session session = null;
529 
530         try {
531             session = JCRFactoryUtil.createSession();
532 
533             Node rootNode = getRootNode(session, companyId);
534             Node repositoryNode = getFolderNode(rootNode, repositoryId);
535 
536             NodeIterator itr = repositoryNode.getNodes();
537 
538             while (itr.hasNext()) {
539                 Node node = (Node)itr.next();
540 
541                 if (node.getPrimaryNodeType().getName().equals(
542                         JCRConstants.NT_FILE)) {
543 
544                     try {
545                         Document doc = DLIndexerUtil.getFileDocument(
546                             companyId, portletId, groupId, repositoryId,
547                             node.getName());
548 
549                         SearchEngineUtil.updateDocument(
550                             companyId, doc.get(Field.UID), doc);
551                     }
552                     catch (Exception e1) {
553                         _log.error("Reindexing " + node.getName(), e1);
554                     }
555                 }
556             }
557         }
558         catch (Exception e2) {
559             throw new SearchException(e2);
560         }
561         finally {
562             try {
563                 if (session != null) {
564                     session.logout();
565                 }
566             }
567             catch (Exception e) {
568                 _log.error(e);
569             }
570         }
571     }
572 
573     public void updateFile(
574             long companyId, String portletId, long groupId, long repositoryId,
575             long newRepositoryId, String fileName)
576         throws PortalException, SystemException {
577 
578         Session session = null;
579 
580         try {
581             session = JCRFactoryUtil.createSession();
582 
583             Node rootNode = getRootNode(session, companyId);
584             Node repositoryNode = getFolderNode(rootNode, repositoryId);
585             Node fileNode = repositoryNode.getNode(fileName);
586             Node contentNode = fileNode.getNode(JCRConstants.JCR_CONTENT);
587 
588             Node newRepositoryNode = getFolderNode(rootNode, newRepositoryId);
589 
590             if (newRepositoryNode.hasNode(fileName)) {
591                 throw new DuplicateFileException(fileName);
592             }
593             else {
594                 Node newFileNode = newRepositoryNode.addNode(
595                     fileName, JCRConstants.NT_FILE);
596 
597                 Node newContentNode = newFileNode.addNode(
598                     JCRConstants.JCR_CONTENT, JCRConstants.NT_RESOURCE);
599 
600                 VersionHistory versionHistory = contentNode.getVersionHistory();
601 
602                 String[] versionLabels = versionHistory.getVersionLabels();
603 
604                 for (int i = (versionLabels.length - 1); i >= 0; i--) {
605                     Version version = versionHistory.getVersionByLabel(
606                         versionLabels[i]);
607 
608                     Node frozenContentNode = version.getNode(
609                         JCRConstants.JCR_FROZEN_NODE);
610 
611                     if (i == (versionLabels.length - 1)) {
612                         newContentNode.addMixin(JCRConstants.MIX_VERSIONABLE);
613                     }
614                     else {
615                         newContentNode.checkout();
616                     }
617 
618                     newContentNode.setProperty(
619                         JCRConstants.JCR_MIME_TYPE, "text/plain");
620                     newContentNode.setProperty(
621                         JCRConstants.JCR_DATA,
622                         frozenContentNode.getProperty(
623                             JCRConstants.JCR_DATA).getStream());
624                     newContentNode.setProperty(
625                         JCRConstants.JCR_LAST_MODIFIED, Calendar.getInstance());
626 
627                     session.save();
628 
629                     Version newVersion = newContentNode.checkin();
630 
631                     newContentNode.getVersionHistory().addVersionLabel(
632                         newVersion.getName(), versionLabels[i], false);
633                 }
634 
635                 fileNode.remove();
636 
637                 session.save();
638 
639                 try {
640                     DLIndexerUtil.deleteFile(
641                         companyId, portletId, repositoryId, fileName);
642                 }
643                 catch (SearchException se) {
644                 }
645 
646                 DLIndexerUtil.addFile(
647                     companyId, portletId, groupId, newRepositoryId, fileName);
648             }
649         }
650         catch (PathNotFoundException pnfe) {
651             throw new NoSuchFileException(fileName);
652         }
653         catch (RepositoryException re) {
654             throw new SystemException(re);
655         }
656         catch (SearchException se) {
657             throw new SystemException(se);
658         }
659         finally {
660             if (session != null) {
661                 session.logout();
662             }
663         }
664     }
665 
666     public void updateFile(
667             long companyId, String portletId, long groupId, long repositoryId,
668             String fileName, double versionNumber, String sourceFileName,
669             String properties, Date modifiedDate, String[] tagsEntries,
670             InputStream is)
671         throws PortalException, SystemException {
672 
673         String versionLabel = String.valueOf(versionNumber);
674 
675         Session session = null;
676 
677         try {
678             session = JCRFactoryUtil.createSession();
679 
680             Node rootNode = getRootNode(session, companyId);
681             Node repositoryNode = getFolderNode(rootNode, repositoryId);
682             Node fileNode = repositoryNode.getNode(fileName);
683             Node contentNode = fileNode.getNode(JCRConstants.JCR_CONTENT);
684 
685             contentNode.checkout();
686 
687             contentNode.setProperty(JCRConstants.JCR_MIME_TYPE, "text/plain");
688             contentNode.setProperty(JCRConstants.JCR_DATA, is);
689             contentNode.setProperty(
690                 JCRConstants.JCR_LAST_MODIFIED, Calendar.getInstance());
691 
692             session.save();
693 
694             Version version = contentNode.checkin();
695 
696             contentNode.getVersionHistory().addVersionLabel(
697                 version.getName(), versionLabel, false);
698 
699             DLIndexerUtil.updateFile(
700                 companyId, portletId, groupId, repositoryId, fileName,
701                 properties, modifiedDate, tagsEntries);
702         }
703         catch (PathNotFoundException pnfe) {
704             throw new NoSuchFileException(fileName);
705         }
706         catch (RepositoryException re) {
707             throw new SystemException(re);
708         }
709         catch (SearchException se) {
710             throw new SystemException(se);
711         }
712         finally {
713             if (session != null) {
714                 session.logout();
715             }
716         }
717     }
718 
719     protected void deleteDirectory(
720             long companyId, String portletId, long repositoryId, Node dirNode)
721         throws SearchException {
722 
723         try {
724             NodeIterator itr = dirNode.getNodes();
725 
726             while (itr.hasNext()) {
727                 Node node = (Node)itr.next();
728 
729                 String primaryNodeTypeName =
730                     node.getPrimaryNodeType().getName();
731 
732                 if (primaryNodeTypeName.equals(JCRConstants.NT_FOLDER)) {
733                     deleteDirectory(companyId, portletId, repositoryId, node);
734                 }
735                 else if (primaryNodeTypeName.equals(JCRConstants.NT_FILE)) {
736                     DLIndexerUtil.deleteFile(
737                         companyId, portletId, repositoryId, node.getName());
738                 }
739             }
740 
741             DLIndexerUtil.deleteFile(
742                 companyId, portletId, repositoryId, dirNode.getName());
743         }
744         catch (RepositoryException e) {
745             _log.error(e);
746         }
747     }
748 
749     protected Node getFileContentNode(
750             long companyId, long repositoryId, String fileName,
751             double versionNumber)
752         throws PortalException, SystemException {
753 
754         Node contentNode = null;
755 
756         Session session = null;
757 
758         try {
759             session = JCRFactoryUtil.createSession();
760 
761             contentNode = getFileContentNode(
762                 session, companyId, repositoryId, fileName, versionNumber);
763         }
764         catch (RepositoryException re) {
765             throw new SystemException(re);
766         }
767         finally {
768             if (session != null) {
769                 session.logout();
770             }
771         }
772 
773         return contentNode;
774     }
775 
776     protected Node getFileContentNode(
777             Session session, long companyId, long repositoryId,
778             String fileName, double versionNumber)
779         throws PortalException, SystemException {
780 
781         String versionLabel = String.valueOf(versionNumber);
782 
783         Node contentNode = null;
784 
785         try {
786             Node rootNode = getRootNode(session, companyId);
787             Node repositoryNode = getFolderNode(rootNode, repositoryId);
788             Node fileNode = repositoryNode.getNode(fileName);
789             contentNode = fileNode.getNode(JCRConstants.JCR_CONTENT);
790 
791             if (versionNumber > 0) {
792                 VersionHistory versionHistory =
793                     contentNode.getVersionHistory();
794 
795                 Version version = versionHistory.getVersionByLabel(
796                     versionLabel);
797 
798                 contentNode = version.getNode(JCRConstants.JCR_FROZEN_NODE);
799             }
800         }
801         catch (PathNotFoundException pnfe) {
802             throw new NoSuchFileException(fileName);
803         }
804         catch (RepositoryException re) {
805             throw new SystemException(re);
806         }
807 
808         return contentNode;
809     }
810 
811     protected Node getFolderNode(Node node, long name)
812         throws RepositoryException {
813 
814         return getFolderNode(node, String.valueOf(name));
815     }
816 
817     protected Node getFolderNode(Node node, String name)
818         throws RepositoryException {
819 
820         Node folderNode = null;
821 
822         if (node.hasNode(name)) {
823             folderNode = node.getNode(name);
824         }
825         else {
826             folderNode = node.addNode(name, JCRConstants.NT_FOLDER);
827         }
828 
829         return folderNode;
830     }
831 
832     protected Node getRootNode(Session session, long companyId)
833         throws RepositoryException {
834 
835         Node companyNode = getFolderNode(session.getRootNode(), companyId);
836 
837         return getFolderNode(companyNode, JCRFactory.NODE_DOCUMENTLIBRARY);
838     }
839 
840     private static Log _log = LogFactoryUtil.getLog(JCRHook.class);
841 
842 }