001    /**
002     * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portlet.documentlibrary.store;
016    
017    import com.liferay.portal.jcr.JCRConstants;
018    import com.liferay.portal.jcr.JCRFactory;
019    import com.liferay.portal.jcr.JCRFactoryUtil;
020    import com.liferay.portal.kernel.exception.SystemException;
021    import com.liferay.portal.kernel.util.ContentTypes;
022    import com.liferay.portal.kernel.util.GetterUtil;
023    import com.liferay.portal.kernel.util.StringPool;
024    import com.liferay.portal.kernel.util.StringUtil;
025    import com.liferay.portal.kernel.util.Validator;
026    import com.liferay.portal.util.PropsValues;
027    import com.liferay.portlet.documentlibrary.DuplicateFileException;
028    import com.liferay.portlet.documentlibrary.NoSuchFileException;
029    
030    import java.io.InputStream;
031    
032    import java.util.ArrayList;
033    import java.util.Calendar;
034    import java.util.List;
035    import java.util.Map;
036    
037    import javax.jcr.Binary;
038    import javax.jcr.Node;
039    import javax.jcr.NodeIterator;
040    import javax.jcr.PathNotFoundException;
041    import javax.jcr.Property;
042    import javax.jcr.RepositoryException;
043    import javax.jcr.Session;
044    import javax.jcr.Value;
045    import javax.jcr.ValueFactory;
046    import javax.jcr.Workspace;
047    import javax.jcr.nodetype.NodeType;
048    import javax.jcr.version.Version;
049    import javax.jcr.version.VersionHistory;
050    import javax.jcr.version.VersionIterator;
051    import javax.jcr.version.VersionManager;
052    
053    import org.apache.commons.lang.StringUtils;
054    
055    /**
056     * @author Michael Young
057     * @author Brian Wing Shun Chan
058     * @author Edward Han
059     */
060    public class JCRStore extends BaseStore {
061    
062            @Override
063            public void addDirectory(
064                    long companyId, long repositoryId, String dirName) {
065    
066                    Session session = null;
067    
068                    try {
069                            session = JCRFactoryUtil.createSession();
070    
071                            Node rootNode = getRootNode(session, companyId);
072    
073                            Node repositoryNode = getFolderNode(rootNode, repositoryId);
074    
075                            if (repositoryNode.hasNode(dirName)) {
076                                    return;
077                            }
078    
079                            String[] dirNameArray = StringUtil.split(dirName, '/');
080    
081                            Node dirNode = repositoryNode;
082    
083                            for (String nodeName : dirNameArray) {
084                                    if (Validator.isNotNull(nodeName)) {
085                                            if (dirNode.hasNode(nodeName)) {
086                                                    dirNode = dirNode.getNode(nodeName);
087                                            }
088                                            else {
089                                                    dirNode = dirNode.addNode(
090                                                            nodeName, JCRConstants.NT_FOLDER);
091                                            }
092                                    }
093                            }
094    
095                            session.save();
096                    }
097                    catch (RepositoryException re) {
098                            throw new SystemException(re);
099                    }
100                    finally {
101                            JCRFactoryUtil.closeSession(session);
102                    }
103            }
104    
105            @Override
106            public void addFile(
107                            long companyId, long repositoryId, String fileName, InputStream is)
108                    throws DuplicateFileException {
109    
110                    Session session = null;
111    
112                    try {
113                            session = JCRFactoryUtil.createSession();
114    
115                            Workspace workspace = session.getWorkspace();
116    
117                            VersionManager versionManager = workspace.getVersionManager();
118    
119                            Node rootNode = getRootNode(session, companyId);
120    
121                            Node repositoryNode = getFolderNode(rootNode, repositoryId);
122    
123                            if (fileName.contains(StringPool.SLASH)) {
124                                    String path = fileName.substring(
125                                            0, fileName.lastIndexOf(StringPool.SLASH));
126    
127                                    fileName = fileName.substring(path.length() + 1);
128    
129                                    repositoryNode = getFolderNode(repositoryNode, path);
130                            }
131    
132                            if (repositoryNode.hasNode(fileName)) {
133                                    throw new DuplicateFileException(
134                                            companyId, repositoryId, fileName);
135                            }
136    
137                            Node fileNode = repositoryNode.addNode(
138                                    fileName, JCRConstants.NT_FILE);
139    
140                            Node contentNode = fileNode.addNode(
141                                    JCRConstants.JCR_CONTENT, JCRConstants.NT_RESOURCE);
142    
143                            contentNode.addMixin(JCRConstants.MIX_VERSIONABLE);
144                            contentNode.setProperty(
145                                    JCRConstants.JCR_MIME_TYPE, ContentTypes.TEXT_PLAIN);
146    
147                            ValueFactory valueFactory = session.getValueFactory();
148    
149                            Binary binary = valueFactory.createBinary(is);
150    
151                            contentNode.setProperty(JCRConstants.JCR_DATA, binary);
152    
153                            contentNode.setProperty(
154                                    JCRConstants.JCR_LAST_MODIFIED, Calendar.getInstance());
155    
156                            session.save();
157    
158                            Version version = versionManager.checkin(contentNode.getPath());
159    
160                            VersionHistory versionHistory = versionManager.getVersionHistory(
161                                    contentNode.getPath());
162    
163                            versionHistory.addVersionLabel(
164                                    version.getName(), VERSION_DEFAULT, false);
165                    }
166                    catch (RepositoryException re) {
167                            throw new SystemException(re);
168                    }
169                    finally {
170                            JCRFactoryUtil.closeSession(session);
171                    }
172            }
173    
174            @Override
175            public void checkRoot(long companyId) {
176                    Session session = null;
177    
178                    try {
179                            session = JCRFactoryUtil.createSession();
180    
181                            getRootNode(session, companyId);
182    
183                            session.save();
184                    }
185                    catch (RepositoryException re) {
186                            throw new SystemException(re);
187                    }
188                    finally {
189                            JCRFactoryUtil.closeSession(session);
190                    }
191            }
192    
193            @Override
194            public void deleteDirectory(
195                    long companyId, long repositoryId, String dirName) {
196    
197                    Session session = null;
198    
199                    try {
200                            session = JCRFactoryUtil.createSession();
201    
202                            Node rootNode = getRootNode(session, companyId);
203    
204                            Node repositoryNode = getFolderNode(rootNode, repositoryId);
205    
206                            if (dirName.equals(StringPool.SLASH)) {
207                                    dirName = StringPool.BLANK;
208                            }
209    
210                            Node dirNode = repositoryNode.getNode(dirName);
211    
212                            dirNode.remove();
213    
214                            session.save();
215                    }
216                    catch (PathNotFoundException pnfe) {
217                            logFailedDeletion(companyId, repositoryId, dirName);
218                    }
219                    catch (RepositoryException re) {
220                            String message = GetterUtil.getString(re.getMessage());
221    
222                            if (message.contains("failed to resolve path")) {
223                                    logFailedDeletion(companyId, repositoryId, dirName);
224                            }
225                            else {
226                                    throw new SystemException(re);
227                            }
228                    }
229                    finally {
230                            JCRFactoryUtil.closeSession(session);
231                    }
232            }
233    
234            @Override
235            public void deleteFile(long companyId, long repositoryId, String fileName) {
236                    Session session = null;
237    
238                    // A bug in Jackrabbit requires us to create a dummy node and delete the
239                    // version tree manually to successfully delete a file
240    
241                    // Create a dummy node
242    
243                    try {
244                            session = JCRFactoryUtil.createSession();
245    
246                            Workspace workspace = session.getWorkspace();
247    
248                            VersionManager versionManager = workspace.getVersionManager();
249    
250                            Node rootNode = getRootNode(session, companyId);
251    
252                            Node repositoryNode = getFolderNode(rootNode, repositoryId);
253    
254                            Node fileNode = repositoryNode.getNode(fileName);
255    
256                            Node contentNode = fileNode.getNode(JCRConstants.JCR_CONTENT);
257    
258                            versionManager.checkout(contentNode.getPath());
259    
260                            contentNode.setProperty(
261                                    JCRConstants.JCR_MIME_TYPE, ContentTypes.TEXT_PLAIN);
262                            contentNode.setProperty(JCRConstants.JCR_DATA, StringPool.BLANK);
263                            contentNode.setProperty(
264                                    JCRConstants.JCR_LAST_MODIFIED, Calendar.getInstance());
265    
266                            session.save();
267    
268                            Version version = versionManager.checkin(contentNode.getPath());
269    
270                            VersionHistory versionHistory = versionManager.getVersionHistory(
271                                    contentNode.getPath());
272    
273                            versionHistory.addVersionLabel(version.getName(), "0.0", false);
274                    }
275                    catch (PathNotFoundException pnfe) {
276                            logFailedDeletion(companyId, repositoryId, fileName);
277    
278                            return;
279                    }
280                    catch (RepositoryException re) {
281                            throw new SystemException(re);
282                    }
283                    finally {
284                            JCRFactoryUtil.closeSession(session);
285                    }
286    
287                    // Delete version tree
288    
289                    try {
290                            session = JCRFactoryUtil.createSession();
291    
292                            Workspace workspace = session.getWorkspace();
293    
294                            VersionManager versionManager = workspace.getVersionManager();
295    
296                            Node rootNode = getRootNode(session, companyId);
297    
298                            Node repositoryNode = getFolderNode(rootNode, repositoryId);
299    
300                            Node fileNode = repositoryNode.getNode(fileName);
301    
302                            Node contentNode = fileNode.getNode(JCRConstants.JCR_CONTENT);
303    
304                            VersionHistory versionHistory = versionManager.getVersionHistory(
305                                    contentNode.getPath());
306    
307                            VersionIterator itr = versionHistory.getAllVersions();
308    
309                            while (itr.hasNext()) {
310                                    Version version = itr.nextVersion();
311    
312                                    if (itr.getPosition() == itr.getSize()) {
313                                            break;
314                                    }
315                                    else {
316                                            if (!StringUtils.equals(
317                                                            JCRConstants.JCR_ROOT_VERSION, version.getName())) {
318    
319                                                    versionHistory.removeVersion(version.getName());
320                                            }
321                                    }
322                            }
323    
324                            session.save();
325                    }
326                    catch (PathNotFoundException pnfe) {
327                            logFailedDeletion(companyId, repositoryId, fileName);
328    
329                            return;
330                    }
331                    catch (RepositoryException re) {
332                            throw new SystemException(re);
333                    }
334                    finally {
335                            JCRFactoryUtil.closeSession(session);
336                    }
337    
338                    // Delete file
339    
340                    try {
341                            session = JCRFactoryUtil.createSession();
342    
343                            Node rootNode = getRootNode(session, companyId);
344    
345                            Node repositoryNode = getFolderNode(rootNode, repositoryId);
346    
347                            Node fileNode = repositoryNode.getNode(fileName);
348    
349                            fileNode.remove();
350    
351                            session.save();
352                    }
353                    catch (PathNotFoundException pnfe) {
354                            logFailedDeletion(companyId, repositoryId, fileName);
355                    }
356                    catch (RepositoryException re) {
357                            throw new SystemException(re);
358                    }
359                    finally {
360                            JCRFactoryUtil.closeSession(session);
361                    }
362            }
363    
364            @Override
365            public void deleteFile(
366                    long companyId, long repositoryId, String fileName,
367                    String versionLabel) {
368    
369                    Session session = null;
370    
371                    try {
372                            session = JCRFactoryUtil.createSession();
373    
374                            Workspace workspace = session.getWorkspace();
375    
376                            VersionManager versionManager = workspace.getVersionManager();
377    
378                            Node rootNode = getRootNode(session, companyId);
379    
380                            Node repositoryNode = getFolderNode(rootNode, repositoryId);
381    
382                            Node fileNode = repositoryNode.getNode(fileName);
383    
384                            Node contentNode = fileNode.getNode(JCRConstants.JCR_CONTENT);
385    
386                            VersionHistory versionHistory = versionManager.getVersionHistory(
387                                    contentNode.getPath());
388    
389                            if (!versionHistory.hasVersionLabel(versionLabel)) {
390                                    logFailedDeletion(
391                                            companyId, repositoryId, fileName, versionLabel);
392                            }
393    
394                            Version version = versionHistory.getVersionByLabel(versionLabel);
395    
396                            Version linearPredecessorVersion = version.getLinearPredecessor();
397    
398                            if (version.getLinearSuccessor() == null) {
399                                    Version restoreVersion = linearPredecessorVersion;
400    
401                                    if (Validator.equals(
402                                                    JCRConstants.JCR_ROOT_VERSION,
403                                                    linearPredecessorVersion.getName())) {
404    
405                                            versionManager.checkout(contentNode.getPath());
406    
407                                            restoreVersion = versionManager.checkin(
408                                                    contentNode.getPath());
409                                    }
410    
411                                    versionManager.restore(restoreVersion, true);
412                            }
413    
414                            versionHistory.removeVersion(version.getName());
415    
416                            session.save();
417                    }
418                    catch (PathNotFoundException pnfe) {
419                            logFailedDeletion(companyId, repositoryId, fileName, versionLabel);
420                    }
421                    catch (RepositoryException re) {
422                            throw new SystemException(re);
423                    }
424                    finally {
425                            JCRFactoryUtil.closeSession(session);
426                    }
427            }
428    
429            @Override
430            public InputStream getFileAsStream(
431                            long companyId, long repositoryId, String fileName,
432                            String versionLabel)
433                    throws NoSuchFileException {
434    
435                    Session session = null;
436    
437                    try {
438                            session = JCRFactoryUtil.createSession();
439    
440                            Node contentNode = getFileContentNode(
441                                    session, companyId, repositoryId, fileName, versionLabel);
442    
443                            Property property = contentNode.getProperty(JCRConstants.JCR_DATA);
444    
445                            Value value = property.getValue();
446    
447                            Binary binary = value.getBinary();
448    
449                            if (session instanceof Map) {
450                                    Map<String, Binary> mapSession = (Map<String, Binary>)session;
451    
452                                    mapSession.put(fileName, binary);
453                            }
454    
455                            return binary.getStream();
456                    }
457                    catch (RepositoryException re) {
458                            throw new SystemException(re);
459                    }
460                    finally {
461                            JCRFactoryUtil.closeSession(session);
462                    }
463            }
464    
465            @Override
466            public String[] getFileNames(long companyId, long repositoryId) {
467                    List<String> fileNames = new ArrayList<>();
468    
469                    Session session = null;
470    
471                    try {
472                            session = JCRFactoryUtil.createSession();
473    
474                            Node rootNode = getRootNode(session, companyId);
475    
476                            Node repositoryNode = getFolderNode(rootNode, repositoryId);
477    
478                            NodeIterator itr = repositoryNode.getNodes();
479    
480                            while (itr.hasNext()) {
481                                    Node node = itr.nextNode();
482    
483                                    NodeType primaryNodeType = node.getPrimaryNodeType();
484    
485                                    String primaryNodeTypeName = primaryNodeType.getName();
486    
487                                    if (primaryNodeTypeName.equals(JCRConstants.NT_FOLDER)) {
488                                            doGetFileNames(fileNames, node.getName(), node);
489                                    }
490                                    else if (primaryNodeTypeName.equals(JCRConstants.NT_FILE)) {
491                                            fileNames.add(node.getName());
492                                    }
493                            }
494                    }
495                    catch (RepositoryException re) {
496                            throw new SystemException(re);
497                    }
498                    finally {
499                            JCRFactoryUtil.closeSession(session);
500                    }
501    
502                    return fileNames.toArray(new String[fileNames.size()]);
503            }
504    
505            @Override
506            public String[] getFileNames(
507                    long companyId, long repositoryId, String dirName) {
508    
509                    List<String> fileNames = new ArrayList<>();
510    
511                    Session session = null;
512    
513                    try {
514                            session = JCRFactoryUtil.createSession();
515    
516                            Node rootNode = getRootNode(session, companyId);
517    
518                            Node repositoryNode = getFolderNode(rootNode, repositoryId);
519    
520                            Node dirNode = repositoryNode.getNode(dirName);
521    
522                            doGetFileNames(fileNames, dirName, dirNode);
523                    }
524                    catch (PathNotFoundException pnfe) {
525                            return new String[0];
526                    }
527                    catch (RepositoryException re) {
528                            throw new SystemException(re);
529                    }
530                    finally {
531                            JCRFactoryUtil.closeSession(session);
532                    }
533    
534                    return fileNames.toArray(new String[fileNames.size()]);
535            }
536    
537            @Override
538            public long getFileSize(long companyId, long repositoryId, String fileName)
539                    throws NoSuchFileException {
540    
541                    long size = 0;
542    
543                    Session session = null;
544    
545                    try {
546                            session = JCRFactoryUtil.createSession();
547    
548                            Node contentNode = getFileContentNode(
549                                    session, companyId, repositoryId, fileName, StringPool.BLANK);
550    
551                            Property property = contentNode.getProperty(JCRConstants.JCR_DATA);
552    
553                            size = property.getLength();
554                    }
555                    catch (RepositoryException re) {
556                            throw new SystemException(re);
557                    }
558                    finally {
559                            JCRFactoryUtil.closeSession(session);
560                    }
561    
562                    return size;
563            }
564    
565            @Override
566            public boolean hasDirectory(
567                    long companyId, long repositoryId, String dirName) {
568    
569                    Session session = null;
570    
571                    try {
572                            session = JCRFactoryUtil.createSession();
573    
574                            Node rootNode = getRootNode(session, companyId);
575    
576                            Node repositoryNode = getFolderNode(rootNode, repositoryId);
577    
578                            repositoryNode.getNode(dirName);
579    
580                            return true;
581                    }
582                    catch (PathNotFoundException pnfe) {
583                            return false;
584                    }
585                    catch (RepositoryException re) {
586                            throw new SystemException(re);
587                    }
588                    finally {
589                            JCRFactoryUtil.closeSession(session);
590                    }
591            }
592    
593            @Override
594            public boolean hasFile(
595                    long companyId, long repositoryId, String fileName,
596                    String versionLabel) {
597    
598                    try {
599                            getFileContentNode(companyId, repositoryId, fileName, versionLabel);
600                    }
601                    catch (NoSuchFileException nsfe) {
602                            return false;
603                    }
604    
605                    return true;
606            }
607    
608            @Override
609            public void move(String srcDir, String destDir) {
610                    Session session = null;
611    
612                    try {
613                            session = JCRFactoryUtil.createSession();
614    
615                            session.move(srcDir, destDir);
616    
617                            session.save();
618                    }
619                    catch (RepositoryException re) {
620                            throw new SystemException(re);
621                    }
622                    finally {
623                            JCRFactoryUtil.closeSession(session);
624                    }
625            }
626    
627            @Override
628            public void updateFile(
629                            long companyId, long repositoryId, long newRepositoryId,
630                            String fileName)
631                    throws DuplicateFileException, NoSuchFileException {
632    
633                    Session session = null;
634    
635                    try {
636                            session = JCRFactoryUtil.createSession();
637    
638                            Node rootNode = getRootNode(session, companyId);
639    
640                            Node repositoryNode = getFolderNode(rootNode, repositoryId);
641    
642                            if (fileName.contains(StringPool.SLASH)) {
643                                    String path = fileName.substring(
644                                            0, fileName.lastIndexOf(StringPool.SLASH));
645    
646                                    fileName = fileName.substring(path.length() + 1);
647    
648                                    repositoryNode = getFolderNode(repositoryNode, path);
649                            }
650    
651                            Node newRepositoryNode = getFolderNode(rootNode, newRepositoryId);
652    
653                            if (newRepositoryNode.hasNode(fileName)) {
654                                    throw new DuplicateFileException(
655                                            companyId, newRepositoryId, fileName);
656                            }
657    
658                            Node fileNode = repositoryNode.getNode(fileName);
659    
660                            Node contentNode = fileNode.getNode(JCRConstants.JCR_CONTENT);
661    
662                            String contentNodePath = contentNode.getPath();
663    
664                            Node newFileNode = newRepositoryNode.addNode(
665                                    fileName, JCRConstants.NT_FILE);
666    
667                            String newContentNodePath = newFileNode.getPath().concat(
668                                    StringPool.SLASH).concat(JCRConstants.JCR_CONTENT);
669    
670                            session.move(contentNodePath, newContentNodePath);
671    
672                            fileNode.remove();
673    
674                            session.save();
675                    }
676                    catch (PathNotFoundException pnfe) {
677                            throw new NoSuchFileException(
678                                    companyId, repositoryId, fileName, pnfe);
679                    }
680                    catch (RepositoryException re) {
681                            throw new SystemException(re);
682                    }
683                    finally {
684                            JCRFactoryUtil.closeSession(session);
685                    }
686            }
687    
688            @Override
689            public void updateFile(
690                            long companyId, long repositoryId, String fileName,
691                            String newFileName)
692                    throws DuplicateFileException, NoSuchFileException {
693    
694                    Session session = null;
695    
696                    try {
697                            session = JCRFactoryUtil.createSession();
698    
699                            Node rootNode = getRootNode(session, companyId);
700    
701                            Node repositoryNode = getFolderNode(rootNode, repositoryId);
702    
703                            if (fileName.contains(StringPool.SLASH)) {
704                                    String path = fileName.substring(
705                                            0, fileName.lastIndexOf(StringPool.SLASH));
706    
707                                    fileName = fileName.substring(path.length() + 1);
708    
709                                    repositoryNode = getFolderNode(repositoryNode, path);
710                            }
711    
712                            if (repositoryNode.hasNode(newFileName)) {
713                                    throw new DuplicateFileException(
714                                            companyId, repositoryId, newFileName);
715                            }
716    
717                            Node fileNode = repositoryNode.getNode(fileName);
718    
719                            Node contentNode = fileNode.getNode(JCRConstants.JCR_CONTENT);
720    
721                            String contentNodePath = contentNode.getPath();
722    
723                            Node newFileNode = repositoryNode.addNode(
724                                    newFileName, JCRConstants.NT_FILE);
725    
726                            String newContentNodePath = newFileNode.getPath().concat(
727                                    StringPool.SLASH).concat(JCRConstants.JCR_CONTENT);
728    
729                            session.move(contentNodePath, newContentNodePath);
730    
731                            fileNode.remove();
732    
733                            session.save();
734                    }
735                    catch (PathNotFoundException pnfe) {
736                            throw new NoSuchFileException(
737                                    companyId, repositoryId, fileName, pnfe);
738                    }
739                    catch (RepositoryException re) {
740                            throw new SystemException(re);
741                    }
742                    finally {
743                            JCRFactoryUtil.closeSession(session);
744                    }
745            }
746    
747            @Override
748            public void updateFile(
749                            long companyId, long repositoryId, String fileName,
750                            String versionLabel, InputStream is)
751                    throws DuplicateFileException, NoSuchFileException {
752    
753                    Session session = null;
754    
755                    try {
756                            session = JCRFactoryUtil.createSession();
757    
758                            Workspace workspace = session.getWorkspace();
759    
760                            VersionManager versionManager = workspace.getVersionManager();
761    
762                            Node rootNode = getRootNode(session, companyId);
763    
764                            Node repositoryNode = getFolderNode(rootNode, repositoryId);
765    
766                            if (fileName.contains(StringPool.SLASH)) {
767                                    String path = fileName.substring(
768                                            0, fileName.lastIndexOf(StringPool.SLASH));
769    
770                                    fileName = fileName.substring(path.length() + 1);
771    
772                                    repositoryNode = getFolderNode(repositoryNode, path);
773                            }
774    
775                            Node fileNode = repositoryNode.getNode(fileName);
776    
777                            Node contentNode = fileNode.getNode(JCRConstants.JCR_CONTENT);
778    
779                            versionManager.checkout(contentNode.getPath());
780    
781                            contentNode.setProperty(
782                                    JCRConstants.JCR_MIME_TYPE, ContentTypes.TEXT_PLAIN);
783    
784                            ValueFactory valueFactory = session.getValueFactory();
785    
786                            Binary binary = valueFactory.createBinary(is);
787    
788                            contentNode.setProperty(JCRConstants.JCR_DATA, binary);
789    
790                            contentNode.setProperty(
791                                    JCRConstants.JCR_LAST_MODIFIED, Calendar.getInstance());
792    
793                            session.save();
794    
795                            Version version = versionManager.checkin(contentNode.getPath());
796    
797                            VersionHistory versionHistory = versionManager.getVersionHistory(
798                                    contentNode.getPath());
799    
800                            if (versionHistory.hasVersionLabel(versionLabel)) {
801                                    throw new DuplicateFileException(
802                                            companyId, repositoryId, fileName, versionLabel);
803                            }
804    
805                            versionHistory.addVersionLabel(
806                                    version.getName(), versionLabel,
807                                    PropsValues.DL_STORE_JCR_MOVE_VERSION_LABELS);
808                    }
809                    catch (PathNotFoundException pnfe) {
810                            throw new NoSuchFileException(
811                                    companyId, repositoryId, fileName, versionLabel, pnfe);
812                    }
813                    catch (RepositoryException re) {
814                            throw new SystemException(re);
815                    }
816                    finally {
817                            JCRFactoryUtil.closeSession(session);
818                    }
819            }
820    
821            protected void doGetFileNames(
822                            List<String> fileNames, String dirName, Node node)
823                    throws RepositoryException {
824    
825                    NodeType primaryNodeType = node.getPrimaryNodeType();
826    
827                    String primaryNodeTypeName = primaryNodeType.getName();
828    
829                    if (primaryNodeTypeName.equals(JCRConstants.NT_FOLDER)) {
830                            NodeIterator itr = node.getNodes();
831    
832                            while (itr.hasNext()) {
833                                    Node curNode = itr.nextNode();
834    
835                                    String subDirName = null;
836    
837                                    if (Validator.isBlank(dirName)) {
838                                            subDirName = curNode.getName();
839                                    }
840                                    else {
841                                            subDirName = dirName + StringPool.SLASH + curNode.getName();
842                                    }
843    
844                                    doGetFileNames(fileNames, subDirName, curNode);
845                            }
846                    }
847                    else if (primaryNodeTypeName.equals(JCRConstants.NT_FILE)) {
848                            fileNames.add(dirName);
849                    }
850            }
851    
852            protected Node getFileContentNode(
853                            long companyId, long repositoryId, String fileName,
854                            String versionLabel)
855                    throws NoSuchFileException {
856    
857                    Node contentNode = null;
858    
859                    Session session = null;
860    
861                    try {
862                            session = JCRFactoryUtil.createSession();
863    
864                            contentNode = getFileContentNode(
865                                    session, companyId, repositoryId, fileName, versionLabel);
866                    }
867                    catch (RepositoryException re) {
868                            throw new SystemException(re);
869                    }
870                    finally {
871                            JCRFactoryUtil.closeSession(session);
872                    }
873    
874                    return contentNode;
875            }
876    
877            protected Node getFileContentNode(
878                            Session session, long companyId, long repositoryId, String fileName,
879                            String versionLabel)
880                    throws NoSuchFileException {
881    
882                    Node contentNode = null;
883    
884                    try {
885                            Workspace workspace = session.getWorkspace();
886    
887                            VersionManager versionManager = workspace.getVersionManager();
888    
889                            Node rootNode = getRootNode(session, companyId);
890    
891                            Node repositoryNode = getFolderNode(rootNode, repositoryId);
892    
893                            Node fileNode = repositoryNode.getNode(fileName);
894    
895                            contentNode = fileNode.getNode(JCRConstants.JCR_CONTENT);
896    
897                            if (Validator.isNotNull(versionLabel)) {
898                                    VersionHistory versionHistory =
899                                            versionManager.getVersionHistory(contentNode.getPath());
900    
901                                    if (!versionHistory.hasVersionLabel(versionLabel)) {
902                                            throw new NoSuchFileException(
903                                                    companyId, repositoryId, fileName, versionLabel);
904                                    }
905    
906                                    Version version = versionHistory.getVersionByLabel(
907                                            versionLabel);
908    
909                                    contentNode = version.getNode(JCRConstants.JCR_FROZEN_NODE);
910                            }
911                    }
912                    catch (PathNotFoundException pnfe) {
913                            throw new NoSuchFileException(
914                                    companyId, repositoryId, fileName, versionLabel);
915                    }
916                    catch (RepositoryException re) {
917                            throw new SystemException(re);
918                    }
919    
920                    return contentNode;
921            }
922    
923            protected Node getFolderNode(Node node, long name)
924                    throws RepositoryException {
925    
926                    return getFolderNode(node, String.valueOf(name));
927            }
928    
929            protected Node getFolderNode(Node node, String name)
930                    throws RepositoryException {
931    
932                    if (name.contains(StringPool.SLASH)) {
933                            String[] nameParts = name.split(StringPool.SLASH, 2);
934    
935                            node = getFolderNode(node, nameParts[0]);
936    
937                            return getFolderNode(node, nameParts[1]);
938                    }
939    
940                    Node folderNode = null;
941    
942                    if (node.hasNode(name)) {
943                            folderNode = node.getNode(name);
944                    }
945                    else {
946                            folderNode = node.addNode(name, JCRConstants.NT_FOLDER);
947                    }
948    
949                    return folderNode;
950            }
951    
952            protected Node getRootNode(Session session, long companyId)
953                    throws RepositoryException {
954    
955                    Node companyNode = getFolderNode(session.getRootNode(), companyId);
956    
957                    return getFolderNode(companyNode, JCRFactory.NODE_DOCUMENTLIBRARY);
958            }
959    
960    }