001: /**
002: * Copyright (c) 2000-2008 Liferay, Inc. All rights reserved.
003: *
004: * Permission is hereby granted, free of charge, to any person obtaining a copy
005: * of this software and associated documentation files (the "Software"), to deal
006: * in the Software without restriction, including without limitation the rights
007: * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
008: * copies of the Software, and to permit persons to whom the Software is
009: * furnished to do so, subject to the following conditions:
010: *
011: * The above copyright notice and this permission notice shall be included in
012: * all copies or substantial portions of the Software.
013: *
014: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
015: * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
016: * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
017: * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
018: * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
019: * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
020: * SOFTWARE.
021: */package com.liferay.documentlibrary.util;
022:
023: import com.liferay.documentlibrary.DuplicateDirectoryException;
024: import com.liferay.documentlibrary.DuplicateFileException;
025: import com.liferay.documentlibrary.NoSuchDirectoryException;
026: import com.liferay.documentlibrary.NoSuchFileException;
027: import com.liferay.portal.PortalException;
028: import com.liferay.portal.SystemException;
029: import com.liferay.portal.jcr.JCRConstants;
030: import com.liferay.portal.jcr.JCRFactory;
031: import com.liferay.portal.jcr.JCRFactoryUtil;
032: import com.liferay.portal.kernel.search.SearchException;
033: import com.liferay.portal.kernel.util.GetterUtil;
034: import com.liferay.portal.kernel.util.StringUtil;
035: import com.liferay.portal.kernel.util.Validator;
036: import com.liferay.portal.lucene.LuceneUtil;
037:
038: import java.io.BufferedInputStream;
039: import java.io.IOException;
040: import java.io.InputStream;
041:
042: import java.util.ArrayList;
043: import java.util.Calendar;
044: import java.util.List;
045:
046: import javax.jcr.Node;
047: import javax.jcr.NodeIterator;
048: import javax.jcr.PathNotFoundException;
049: import javax.jcr.Property;
050: import javax.jcr.RepositoryException;
051: import javax.jcr.Session;
052: import javax.jcr.version.Version;
053: import javax.jcr.version.VersionHistory;
054: import javax.jcr.version.VersionIterator;
055:
056: import org.apache.commons.lang.StringUtils;
057: import org.apache.commons.logging.Log;
058: import org.apache.commons.logging.LogFactory;
059: import org.apache.lucene.document.Document;
060: import org.apache.lucene.index.IndexWriter;
061:
062: /**
063: * <a href="JCRHook.java.html"><b><i>View Source</i></b></a>
064: *
065: * @author Michael Young
066: * @author Brian Wing Shun Chan
067: *
068: */
069: public class JCRHook extends BaseHook {
070:
071: public void addDirectory(long companyId, long repositoryId,
072: String dirName) throws PortalException, SystemException {
073:
074: Session session = null;
075:
076: try {
077: session = JCRFactoryUtil.createSession();
078:
079: Node rootNode = getRootNode(session, companyId);
080: Node repositoryNode = getFolderNode(rootNode, repositoryId);
081:
082: if (repositoryNode.hasNode(dirName)) {
083: throw new DuplicateDirectoryException(dirName);
084: } else {
085: String[] dirNameArray = StringUtil.split(dirName, "/");
086:
087: Node dirNode = repositoryNode;
088:
089: for (int i = 0; i < dirNameArray.length; i++) {
090: if (Validator.isNotNull(dirNameArray[i])) {
091: if (dirNode.hasNode(dirNameArray[i])) {
092: dirNode = dirNode.getNode(dirNameArray[i]);
093: } else {
094: dirNode = dirNode.addNode(dirNameArray[i],
095: JCRConstants.NT_FOLDER);
096: }
097: }
098: }
099:
100: session.save();
101: }
102: } catch (RepositoryException re) {
103: throw new SystemException(re);
104: } finally {
105: if (session != null) {
106: session.logout();
107: }
108: }
109: }
110:
111: public void addFile(long companyId, String portletId, long groupId,
112: long repositoryId, String fileName, String properties,
113: String[] tagsEntries, InputStream is)
114: throws PortalException, SystemException {
115:
116: Session session = null;
117:
118: try {
119: session = JCRFactoryUtil.createSession();
120:
121: Node rootNode = getRootNode(session, companyId);
122: Node repositoryNode = getFolderNode(rootNode, repositoryId);
123:
124: if (repositoryNode.hasNode(fileName)) {
125: throw new DuplicateFileException(fileName);
126: } else {
127: Node fileNode = repositoryNode.addNode(fileName,
128: JCRConstants.NT_FILE);
129:
130: Node contentNode = fileNode.addNode(
131: JCRConstants.JCR_CONTENT,
132: JCRConstants.NT_RESOURCE);
133:
134: contentNode.addMixin(JCRConstants.MIX_VERSIONABLE);
135: contentNode.setProperty(JCRConstants.JCR_MIME_TYPE,
136: "text/plain");
137: contentNode.setProperty(JCRConstants.JCR_DATA, is);
138: contentNode.setProperty(JCRConstants.JCR_LAST_MODIFIED,
139: Calendar.getInstance());
140:
141: session.save();
142:
143: Version version = contentNode.checkin();
144:
145: contentNode.getVersionHistory().addVersionLabel(
146: version.getName(),
147: String.valueOf(DEFAULT_VERSION), false);
148:
149: Indexer
150: .addFile(companyId, portletId, groupId,
151: repositoryId, fileName, properties,
152: tagsEntries);
153: }
154: } catch (IOException ioe) {
155: throw new SystemException(ioe);
156: } catch (RepositoryException re) {
157: throw new SystemException(re);
158: } finally {
159: if (session != null) {
160: session.logout();
161: }
162: }
163: }
164:
165: public void checkRoot(long companyId) throws SystemException {
166: Session session = null;
167:
168: try {
169: session = JCRFactoryUtil.createSession();
170:
171: getRootNode(session, companyId);
172:
173: session.save();
174: } catch (RepositoryException re) {
175: throw new SystemException(re);
176: } finally {
177: if (session != null) {
178: session.logout();
179: }
180: }
181: }
182:
183: public void deleteDirectory(long companyId, String portletId,
184: long repositoryId, String dirName) throws PortalException,
185: SystemException {
186:
187: Session session = null;
188:
189: try {
190: session = JCRFactoryUtil.createSession();
191:
192: Node rootNode = getRootNode(session, companyId);
193: Node repositoryNode = getFolderNode(rootNode, repositoryId);
194: Node dirNode = repositoryNode.getNode(dirName);
195:
196: deleteDirectory(companyId, portletId, repositoryId, dirNode);
197:
198: dirNode.remove();
199:
200: session.save();
201: } catch (IOException ioe) {
202: throw new SystemException(ioe);
203: } catch (PathNotFoundException pnfe) {
204: throw new NoSuchDirectoryException(dirName);
205: } catch (RepositoryException e) {
206: throw new PortalException(e);
207: } finally {
208: if (session != null) {
209: session.logout();
210: }
211: }
212: }
213:
214: public void deleteFile(long companyId, String portletId,
215: long repositoryId, String fileName) throws PortalException,
216: SystemException {
217:
218: Session session = null;
219:
220: // A bug in Jackrabbit requires us to create a dummy node and delete the
221: // version tree manually to successfully delete a file
222:
223: // Create a dummy node
224:
225: try {
226: session = JCRFactoryUtil.createSession();
227:
228: Node rootNode = getRootNode(session, companyId);
229: Node repositoryNode = getFolderNode(rootNode, repositoryId);
230: Node fileNode = repositoryNode.getNode(fileName);
231: Node contentNode = fileNode
232: .getNode(JCRConstants.JCR_CONTENT);
233:
234: contentNode.checkout();
235:
236: contentNode.setProperty(JCRConstants.JCR_MIME_TYPE,
237: "text/plain");
238: contentNode.setProperty(JCRConstants.JCR_DATA, "");
239: contentNode.setProperty(JCRConstants.JCR_LAST_MODIFIED,
240: Calendar.getInstance());
241:
242: session.save();
243:
244: Version version = contentNode.checkin();
245:
246: contentNode.getVersionHistory().addVersionLabel(
247: version.getName(), "0.0", false);
248: } catch (PathNotFoundException pnfe) {
249: throw new NoSuchFileException(fileName);
250: } catch (RepositoryException re) {
251: throw new SystemException(re);
252: } finally {
253: if (session != null) {
254: session.logout();
255: }
256: }
257:
258: // Delete version tree
259:
260: try {
261: session = JCRFactoryUtil.createSession();
262:
263: Node rootNode = getRootNode(session, companyId);
264: Node repositoryNode = getFolderNode(rootNode, repositoryId);
265: Node fileNode = repositoryNode.getNode(fileName);
266: Node contentNode = fileNode
267: .getNode(JCRConstants.JCR_CONTENT);
268:
269: VersionHistory versionHistory = contentNode
270: .getVersionHistory();
271:
272: VersionIterator itr = versionHistory.getAllVersions();
273:
274: while (itr.hasNext()) {
275: Version version = itr.nextVersion();
276:
277: if (itr.getPosition() == itr.getSize()) {
278: break;
279: } else {
280: if (!StringUtils.equals(
281: JCRConstants.JCR_ROOT_VERSION, version
282: .getName())) {
283:
284: versionHistory.removeVersion(version.getName());
285: }
286: }
287: }
288:
289: session.save();
290: } catch (PathNotFoundException pnfe) {
291: throw new NoSuchFileException(fileName);
292: } catch (RepositoryException re) {
293: throw new SystemException(re);
294: } finally {
295: if (session != null) {
296: session.logout();
297: }
298: }
299:
300: // Delete file
301:
302: try {
303: session = JCRFactoryUtil.createSession();
304:
305: Node rootNode = getRootNode(session, companyId);
306: Node repositoryNode = getFolderNode(rootNode, repositoryId);
307: Node fileNode = repositoryNode.getNode(fileName);
308:
309: Indexer.deleteFile(companyId, portletId, repositoryId,
310: fileName);
311:
312: fileNode.remove();
313:
314: session.save();
315: } catch (IOException ioe) {
316: throw new SystemException(ioe);
317: } catch (PathNotFoundException pnfe) {
318: throw new NoSuchFileException(fileName);
319: } catch (RepositoryException re) {
320: throw new SystemException(re);
321: } finally {
322: if (session != null) {
323: session.logout();
324: }
325: }
326: }
327:
328: public void deleteFile(long companyId, String portletId,
329: long repositoryId, String fileName, double versionNumber)
330: throws PortalException, SystemException {
331:
332: String versionLabel = String.valueOf(versionNumber);
333:
334: Session session = null;
335:
336: try {
337: session = JCRFactoryUtil.createSession();
338:
339: Node rootNode = getRootNode(session, companyId);
340: Node repositoryNode = getFolderNode(rootNode, repositoryId);
341: Node fileNode = repositoryNode.getNode(fileName);
342: Node contentNode = fileNode
343: .getNode(JCRConstants.JCR_CONTENT);
344:
345: VersionHistory versionHistory = contentNode
346: .getVersionHistory();
347:
348: Version version = versionHistory
349: .getVersionByLabel(versionLabel);
350:
351: versionHistory.removeVersion(version.getName());
352:
353: session.save();
354: } catch (PathNotFoundException pnfe) {
355: throw new NoSuchFileException(fileName);
356: } catch (RepositoryException re) {
357: throw new SystemException(re);
358: } finally {
359: if (session != null) {
360: session.logout();
361: }
362: }
363: }
364:
365: public InputStream getFileAsStream(long companyId,
366: long repositoryId, String fileName, double versionNumber)
367: throws PortalException, SystemException {
368:
369: InputStream is = null;
370:
371: Session session = null;
372:
373: try {
374: session = JCRFactoryUtil.createSession();
375:
376: Node contentNode = getFileContentNode(session, companyId,
377: repositoryId, fileName, versionNumber);
378:
379: Property data = contentNode
380: .getProperty(JCRConstants.JCR_DATA);
381:
382: is = new BufferedInputStream(data.getStream());
383: } catch (RepositoryException re) {
384: throw new SystemException(re);
385: } finally {
386: if (session != null) {
387: session.logout();
388: }
389: }
390:
391: return is;
392: }
393:
394: public String[] getFileNames(long companyId, long repositoryId,
395: String dirName) throws PortalException, SystemException {
396:
397: List fileNames = new ArrayList();
398:
399: Session session = null;
400:
401: try {
402: session = JCRFactoryUtil.createSession();
403:
404: Node rootNode = getRootNode(session, companyId);
405: Node repositoryNode = getFolderNode(rootNode, repositoryId);
406: Node dirNode = repositoryNode.getNode(dirName);
407:
408: NodeIterator itr = dirNode.getNodes();
409:
410: while (itr.hasNext()) {
411: Node node = (Node) itr.next();
412:
413: if (node.getPrimaryNodeType().getName().equals(
414: JCRConstants.NT_FILE)) {
415:
416: fileNames.add(dirName + "/" + node.getName());
417: }
418: }
419: } catch (PathNotFoundException pnfe) {
420: throw new NoSuchDirectoryException(dirName);
421: } catch (RepositoryException re) {
422: throw new SystemException(re);
423: } finally {
424: if (session != null) {
425: session.logout();
426: }
427: }
428:
429: return (String[]) fileNames.toArray(new String[0]);
430: }
431:
432: public long getFileSize(long companyId, long repositoryId,
433: String fileName) throws PortalException, SystemException {
434:
435: long size;
436:
437: Session session = null;
438:
439: try {
440: session = JCRFactoryUtil.createSession();
441:
442: Node contentNode = getFileContentNode(session, companyId,
443: repositoryId, fileName, 0);
444:
445: size = contentNode.getProperty(JCRConstants.JCR_DATA)
446: .getLength();
447: } catch (RepositoryException re) {
448: throw new SystemException(re);
449: } finally {
450: if (session != null) {
451: session.logout();
452: }
453: }
454:
455: return size;
456: }
457:
458: public boolean hasFile(long companyId, long repositoryId,
459: String fileName, double versionNumber)
460: throws PortalException, SystemException {
461:
462: try {
463: getFileContentNode(companyId, repositoryId, fileName,
464: versionNumber);
465: } catch (NoSuchFileException nsfe) {
466: return false;
467: }
468:
469: return true;
470: }
471:
472: public void move(String srcDir, String destDir)
473: throws SystemException {
474: Session session = null;
475:
476: try {
477: session = JCRFactoryUtil.createSession();
478:
479: session.move(srcDir, destDir);
480:
481: session.save();
482: } catch (RepositoryException re) {
483: throw new SystemException(re);
484: } finally {
485: if (session != null) {
486: session.logout();
487: }
488: }
489: }
490:
491: public void reIndex(String[] ids) throws SearchException {
492: long companyId = GetterUtil.getLong(ids[0]);
493: String portletId = ids[1];
494: long groupId = GetterUtil.getLong(ids[2]);
495: long repositoryId = GetterUtil.getLong(ids[3]);
496:
497: IndexWriter writer = null;
498:
499: Session session = null;
500:
501: try {
502: writer = LuceneUtil.getWriter(companyId);
503:
504: session = JCRFactoryUtil.createSession();
505:
506: Node rootNode = getRootNode(session, companyId);
507: Node repositoryNode = getFolderNode(rootNode, repositoryId);
508:
509: NodeIterator itr = repositoryNode.getNodes();
510:
511: while (itr.hasNext()) {
512: Node node = (Node) itr.next();
513:
514: if (node.getPrimaryNodeType().getName().equals(
515: JCRConstants.NT_FILE)) {
516:
517: try {
518: Document doc = Indexer.getAddFileDocument(
519: companyId, portletId, groupId,
520: repositoryId, node.getName());
521:
522: writer.addDocument(doc);
523: } catch (Exception e1) {
524: _log.error("Reindexing " + node.getName(), e1);
525: }
526: }
527: }
528: } catch (Exception e2) {
529: throw new SearchException(e2);
530: } finally {
531: try {
532: if (session != null) {
533: session.logout();
534: }
535: } catch (Exception e) {
536: _log.error(e);
537: }
538:
539: try {
540: if (writer != null) {
541: LuceneUtil.write(companyId);
542: }
543: } catch (Exception e) {
544: _log.error(e);
545: }
546: }
547: }
548:
549: public void updateFile(long companyId, String portletId,
550: long groupId, long repositoryId, String fileName,
551: double versionNumber, String sourceFileName,
552: String properties, String[] tagsEntries, InputStream is)
553: throws PortalException, SystemException {
554:
555: String versionLabel = String.valueOf(versionNumber);
556:
557: Session session = null;
558:
559: try {
560: session = JCRFactoryUtil.createSession();
561:
562: Node rootNode = getRootNode(session, companyId);
563: Node repositoryNode = getFolderNode(rootNode, repositoryId);
564: Node fileNode = repositoryNode.getNode(fileName);
565: Node contentNode = fileNode
566: .getNode(JCRConstants.JCR_CONTENT);
567:
568: contentNode.checkout();
569:
570: contentNode.setProperty(JCRConstants.JCR_MIME_TYPE,
571: "text/plain");
572: contentNode.setProperty(JCRConstants.JCR_DATA, is);
573: contentNode.setProperty(JCRConstants.JCR_LAST_MODIFIED,
574: Calendar.getInstance());
575:
576: session.save();
577:
578: Version version = contentNode.checkin();
579:
580: contentNode.getVersionHistory().addVersionLabel(
581: version.getName(), versionLabel, false);
582:
583: Indexer.updateFile(companyId, portletId, groupId,
584: repositoryId, fileName, properties, tagsEntries);
585: } catch (IOException ioe) {
586: throw new SystemException(ioe);
587: } catch (PathNotFoundException pnfe) {
588: throw new NoSuchFileException(fileName);
589: } catch (RepositoryException re) {
590: throw new SystemException(re);
591: } finally {
592: if (session != null) {
593: session.logout();
594: }
595: }
596: }
597:
598: public void updateFile(long companyId, String portletId,
599: long groupId, long repositoryId, long newRepositoryId,
600: String fileName) throws PortalException, SystemException {
601:
602: Session session = null;
603:
604: try {
605: session = JCRFactoryUtil.createSession();
606:
607: Node rootNode = getRootNode(session, companyId);
608: Node repositoryNode = getFolderNode(rootNode, repositoryId);
609: Node fileNode = repositoryNode.getNode(fileName);
610: Node contentNode = fileNode
611: .getNode(JCRConstants.JCR_CONTENT);
612:
613: Node newRepositoryNode = getFolderNode(rootNode,
614: newRepositoryId);
615:
616: if (newRepositoryNode.hasNode(fileName)) {
617: throw new DuplicateFileException(fileName);
618: } else {
619: Node newFileNode = newRepositoryNode.addNode(fileName,
620: JCRConstants.NT_FILE);
621:
622: Node newContentNode = newFileNode.addNode(
623: JCRConstants.JCR_CONTENT,
624: JCRConstants.NT_RESOURCE);
625:
626: VersionHistory versionHistory = contentNode
627: .getVersionHistory();
628:
629: String[] versionLabels = versionHistory
630: .getVersionLabels();
631:
632: for (int i = (versionLabels.length - 1); i >= 0; i--) {
633: Version version = versionHistory
634: .getVersionByLabel(versionLabels[i]);
635:
636: Node frozenContentNode = version
637: .getNode(JCRConstants.JCR_FROZEN_NODE);
638:
639: if (i == (versionLabels.length - 1)) {
640: newContentNode
641: .addMixin(JCRConstants.MIX_VERSIONABLE);
642: } else {
643: newContentNode.checkout();
644: }
645:
646: newContentNode.setProperty(
647: JCRConstants.JCR_MIME_TYPE, "text/plain");
648: newContentNode.setProperty(JCRConstants.JCR_DATA,
649: frozenContentNode.getProperty(
650: JCRConstants.JCR_DATA).getStream());
651: newContentNode.setProperty(
652: JCRConstants.JCR_LAST_MODIFIED, Calendar
653: .getInstance());
654:
655: session.save();
656:
657: Version newVersion = newContentNode.checkin();
658:
659: newContentNode.getVersionHistory().addVersionLabel(
660: newVersion.getName(), versionLabels[i],
661: false);
662: }
663:
664: fileNode.remove();
665:
666: session.save();
667:
668: try {
669: Indexer.deleteFile(companyId, portletId,
670: repositoryId, fileName);
671: } catch (IOException ioe) {
672: }
673:
674: Indexer.addFile(companyId, portletId, groupId,
675: newRepositoryId, fileName);
676: }
677: } catch (IOException ioe) {
678: throw new SystemException(ioe);
679: } catch (PathNotFoundException pnfe) {
680: throw new NoSuchFileException(fileName);
681: } catch (RepositoryException re) {
682: throw new SystemException(re);
683: } finally {
684: if (session != null) {
685: session.logout();
686: }
687: }
688: }
689:
690: protected void deleteDirectory(long companyId, String portletId,
691: long repositoryId, Node dirNode) throws IOException {
692:
693: try {
694: NodeIterator itr = dirNode.getNodes();
695:
696: while (itr.hasNext()) {
697: Node node = (Node) itr.next();
698:
699: String primaryNodeTypeName = node.getPrimaryNodeType()
700: .getName();
701:
702: if (primaryNodeTypeName.equals(JCRConstants.NT_FOLDER)) {
703: deleteDirectory(companyId, portletId, repositoryId,
704: node);
705: } else if (primaryNodeTypeName
706: .equals(JCRConstants.NT_FILE)) {
707: Indexer.deleteFile(companyId, portletId,
708: repositoryId, node.getName());
709: }
710: }
711:
712: Indexer.deleteFile(companyId, portletId, repositoryId,
713: dirNode.getName());
714: } catch (RepositoryException e) {
715: _log.error(e);
716: }
717: }
718:
719: protected Node getFileContentNode(long companyId,
720: long repositoryId, String fileName, double versionNumber)
721: throws PortalException, SystemException {
722:
723: Node contentNode = null;
724:
725: Session session = null;
726:
727: try {
728: session = JCRFactoryUtil.createSession();
729:
730: contentNode = getFileContentNode(session, companyId,
731: repositoryId, fileName, versionNumber);
732: } catch (RepositoryException re) {
733: throw new SystemException(re);
734: } finally {
735: if (session != null) {
736: session.logout();
737: }
738: }
739:
740: return contentNode;
741: }
742:
743: protected Node getFileContentNode(Session session, long companyId,
744: long repositoryId, String fileName, double versionNumber)
745: throws PortalException, SystemException {
746:
747: String versionLabel = String.valueOf(versionNumber);
748:
749: Node contentNode = null;
750:
751: try {
752: Node rootNode = getRootNode(session, companyId);
753: Node repositoryNode = getFolderNode(rootNode, repositoryId);
754: Node fileNode = repositoryNode.getNode(fileName);
755: contentNode = fileNode.getNode(JCRConstants.JCR_CONTENT);
756:
757: if (versionNumber > 0) {
758: VersionHistory versionHistory = contentNode
759: .getVersionHistory();
760:
761: Version version = versionHistory
762: .getVersionByLabel(versionLabel);
763:
764: contentNode = version
765: .getNode(JCRConstants.JCR_FROZEN_NODE);
766: }
767: } catch (PathNotFoundException pnfe) {
768: throw new NoSuchFileException(fileName);
769: } catch (RepositoryException re) {
770: throw new SystemException(re);
771: }
772:
773: return contentNode;
774: }
775:
776: protected Node getFolderNode(Node node, long name)
777: throws RepositoryException {
778:
779: return getFolderNode(node, String.valueOf(name));
780: }
781:
782: protected Node getFolderNode(Node node, String name)
783: throws RepositoryException {
784:
785: Node folderNode = null;
786:
787: if (node.hasNode(name)) {
788: folderNode = node.getNode(name);
789: } else {
790: folderNode = node.addNode(name, JCRConstants.NT_FOLDER);
791: }
792:
793: return folderNode;
794: }
795:
796: protected Node getRootNode(Session session, long companyId)
797: throws RepositoryException {
798:
799: Node companyNode = getFolderNode(session.getRootNode(),
800: companyId);
801:
802: return getFolderNode(companyNode,
803: JCRFactory.NODE_DOCUMENTLIBRARY);
804: }
805:
806: private static Log _log = LogFactory.getLog(JCRHook.class);
807:
808: }
|