1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.jetspeed.portalsite.view;
18
19 import java.util.ArrayList;
20 import java.util.HashSet;
21 import java.util.Iterator;
22 import java.util.List;
23 import java.util.Map;
24 import java.util.Set;
25
26 import org.apache.jetspeed.om.folder.Folder;
27 import org.apache.jetspeed.om.folder.FolderNotFoundException;
28 import org.apache.jetspeed.om.folder.proxy.FolderProxy;
29 import org.apache.jetspeed.om.page.Page;
30 import org.apache.jetspeed.om.page.proxy.PageProxy;
31 import org.apache.jetspeed.page.PageManager;
32 import org.apache.jetspeed.page.document.Node;
33 import org.apache.jetspeed.page.document.NodeException;
34 import org.apache.jetspeed.page.document.NodeNotFoundException;
35 import org.apache.jetspeed.page.document.NodeSet;
36 import org.apache.jetspeed.page.document.proxy.NodeProxy;
37 import org.apache.jetspeed.portalsite.menu.StandardBackMenuDefinition;
38 import org.apache.jetspeed.portalsite.menu.StandardBreadcrumbsMenuDefinition;
39 import org.apache.jetspeed.portalsite.menu.StandardNavigationsMenuDefinition;
40 import org.apache.jetspeed.portalsite.menu.StandardPagesMenuDefinition;
41 import org.apache.jetspeed.profiler.ProfileLocator;
42 import org.apache.jetspeed.profiler.ProfileLocatorProperty;
43
44 /***
45 * This class defines the logical view of site content.
46 *
47 * @author <a href="mailto:rwatler@apache.org">Randy Watler</a>
48 * @version $Id: SiteView.java 534967 2007-05-03 19:23:06Z taylor $
49 */
50 public class SiteView
51 {
52 /***
53 * CURRENT_PAGE_PATH - expression used to match the current page
54 */
55 public final static String CURRENT_PAGE_PATH = "~";
56
57 /***
58 * ALT_CURRENT_PAGE_PATH - alternate expression used to match the current page
59 */
60 public final static String ALT_CURRENT_PAGE_PATH = "@";
61
62 /***
63 * STANDARD_*_MENU_NAME - standard menu names
64 */
65 public final static String STANDARD_BACK_MENU_NAME = "back";
66 public final static String STANDARD_BREADCRUMBS_MENU_NAME = "breadcrumbs";
67 public final static String STANDARD_PAGES_MENU_NAME = "pages";
68 public final static String STANDARD_NAVIGATIONS_MENU_NAME = "navigations";
69
70 /***
71 * CUSTOM_*_MENU_NAME - custom menu names
72 */
73 public final static String CUSTOM_PAGE_NAVIGATIONS_MENU_NAME = "page-navigations";
74
75 /***
76 * STANDARD_MENU_NAMES - set of supported standard menu names
77 */
78 private final static Set STANDARD_MENU_NAMES = new HashSet(3);
79 static
80 {
81 STANDARD_MENU_NAMES.add(STANDARD_BACK_MENU_NAME);
82 STANDARD_MENU_NAMES.add(STANDARD_BREADCRUMBS_MENU_NAME);
83 STANDARD_MENU_NAMES.add(STANDARD_PAGES_MENU_NAME);
84 STANDARD_MENU_NAMES.add(STANDARD_NAVIGATIONS_MENU_NAME);
85 }
86
87 /***
88 * STANDARD_MENU_DEFINITION_LOCATORS - list of standard menu definition locators
89 */
90 private final static List STANDARD_MENU_DEFINITION_LOCATORS = new ArrayList(4);
91 static
92 {
93 STANDARD_MENU_DEFINITION_LOCATORS.add(new SiteViewMenuDefinitionLocator(new StandardBackMenuDefinition()));
94 STANDARD_MENU_DEFINITION_LOCATORS.add(new SiteViewMenuDefinitionLocator(new StandardBreadcrumbsMenuDefinition()));
95 STANDARD_MENU_DEFINITION_LOCATORS.add(new SiteViewMenuDefinitionLocator(new StandardPagesMenuDefinition()));
96 STANDARD_MENU_DEFINITION_LOCATORS.add(new SiteViewMenuDefinitionLocator(new StandardNavigationsMenuDefinition()));
97 }
98
99 /***
100 * pageManager - PageManager component
101 */
102 private PageManager pageManager;
103
104 /***
105 * searchPaths - validated list of ordered search path objects
106 * where paths have no trailing folder separator
107 */
108 private List searchPaths;
109
110 /***
111 * searchPathsString - search paths as string
112 */
113 private String searchPathsString;
114
115 /***
116 * rootFolderProxy - root folder proxy instance
117 */
118 private Folder rootFolderProxy;
119
120 /***
121 * SiteView - validating constructor
122 *
123 * @param pageManager PageManager component instance
124 * @param searchPaths list of search paths in string or search path
125 * object form
126 */
127 public SiteView(PageManager pageManager, List searchPaths)
128 {
129 this.pageManager = pageManager;
130 if ((searchPaths != null) && !searchPaths.isEmpty())
131 {
132
133 this.searchPaths = new ArrayList(searchPaths.size());
134 StringBuffer searchPathsStringBuffer = new StringBuffer();
135 Iterator pathsIter = searchPaths.iterator();
136 while (pathsIter.hasNext())
137 {
138 Object pathObject = pathsIter.next();
139 if (!(pathObject instanceof SiteViewSearchPath))
140 {
141 String path = pathObject.toString().trim();
142 if (path.length() > 0)
143 {
144 pathObject = new SiteViewSearchPath(ProfileLocator.PAGE_LOCATOR, path);
145 }
146 }
147 SiteViewSearchPath searchPath = (SiteViewSearchPath)pathObject;
148 if (this.searchPaths.indexOf(searchPath) == -1)
149 {
150 try
151 {
152 if (this.pageManager.getFolder(searchPath.toString()) != null)
153 {
154 this.searchPaths.add(searchPath);
155
156
157 if (searchPathsStringBuffer.length() == 0)
158 {
159 searchPathsStringBuffer.append(searchPath);
160 }
161 else
162 {
163 searchPathsStringBuffer.append(',');
164 searchPathsStringBuffer.append(searchPath);
165 }
166 }
167 }
168 catch (NodeException ne)
169 {
170 }
171 catch (NodeNotFoundException nnfe)
172 {
173 }
174 catch (SecurityException se)
175 {
176 }
177 }
178 }
179
180
181
182
183 if (this.searchPaths.isEmpty())
184 {
185 this.searchPaths.add(new SiteViewSearchPath(ProfileLocator.PAGE_LOCATOR, Folder.PATH_SEPARATOR));
186 this.searchPathsString = Folder.PATH_SEPARATOR;
187 }
188 else
189 {
190 this.searchPathsString = searchPathsStringBuffer.toString();
191 }
192 }
193 else
194 {
195
196 this.searchPaths = new ArrayList(1);
197 this.searchPaths.add(new SiteViewSearchPath(ProfileLocator.PAGE_LOCATOR, Folder.PATH_SEPARATOR));
198 this.searchPathsString = Folder.PATH_SEPARATOR;
199 }
200 }
201
202 /***
203 * SiteView - validating constructor
204 *
205 * @param pageManager PageManager component instance
206 * @param searchPaths array of search paths
207 */
208 public SiteView(PageManager pageManager, String [] searchPaths)
209 {
210 this(pageManager, makeSearchPathList(searchPaths));
211 }
212
213 /***
214 * makeSearchPathList - construct from array
215 *
216 * @param searchPaths array of search paths
217 * @return search path list
218 */
219 private static List makeSearchPathList(String [] searchPaths)
220 {
221 if ((searchPaths != null) && (searchPaths.length > 0))
222 {
223 List searchPathsList = new ArrayList(searchPaths.length);
224 for (int i = 0; (i < searchPaths.length); i++)
225 {
226 searchPathsList.add(searchPaths[i]);
227 }
228 return searchPathsList;
229 }
230 return null;
231 }
232
233 /***
234 * SiteView - validating constructor
235 *
236 * @param pageManager PageManager component instance
237 * @param searchPaths string of comma separated search paths
238 */
239 public SiteView(PageManager pageManager, String searchPaths)
240 {
241 this(pageManager, makeSearchPathList(searchPaths));
242 }
243
244 /***
245 * makeSearchPathList - construct from string
246 *
247 * @param searchPaths string of comma separated search paths
248 * @return search path list
249 */
250 private static List makeSearchPathList(String searchPaths)
251 {
252 return ((searchPaths != null) ? makeSearchPathList(searchPaths.split(",")) : null);
253 }
254
255 /***
256 * SiteView - validating constructor
257 *
258 * @param pageManager PageManager component instance
259 * @param locator profile locator search specification
260 */
261 public SiteView(PageManager pageManager, ProfileLocator locator)
262 {
263 this(pageManager, makeSearchPathList(locator));
264 }
265
266 /***
267 * makeSearchPathList - construct from profile locator
268 *
269 * @param locator profile locator search specification
270 * @return search path list
271 */
272 private static List makeSearchPathList(ProfileLocator locator)
273 {
274 if (locator != null)
275 {
276
277 return mergeSearchPathList(ProfileLocator.PAGE_LOCATOR, locator, new ArrayList(8));
278 }
279 return null;
280 }
281
282 /***
283 * SiteView - validating constructor
284 *
285 * @param pageManager PageManager component instance
286 * @param locators map of named profile locator search specifications
287 */
288 public SiteView(PageManager pageManager, Map locators)
289 {
290 this(pageManager, makeSearchPathList(locators));
291 }
292
293 /***
294 * makeSearchPathList - construct from profile locators
295 *
296 * @param locators map of named profile locator search specifications
297 * @return search path list
298 */
299 private static List makeSearchPathList(Map locators)
300 {
301 if ((locators != null) && !locators.isEmpty())
302 {
303
304
305
306
307 List searchPaths = new ArrayList(8 * locators.size());
308 ProfileLocator pageLocator = (ProfileLocator)locators.get(ProfileLocator.PAGE_LOCATOR);
309 if (pageLocator != null)
310 {
311
312 mergeSearchPathList(ProfileLocator.PAGE_LOCATOR, pageLocator, searchPaths);
313 }
314 if ((pageLocator == null) || (locators.size() > 1))
315 {
316 Iterator locatorNameIter = locators.keySet().iterator();
317 while (locatorNameIter.hasNext())
318 {
319 String locatorName = (String)locatorNameIter.next();
320 if (!locatorName.equals(ProfileLocator.PAGE_LOCATOR))
321 {
322
323 mergeSearchPathList(locatorName, (ProfileLocator)locators.get(locatorName), searchPaths);
324 }
325 }
326 }
327 return searchPaths;
328 }
329 return null;
330 }
331
332 /***
333 * mergeSearchPathList - append search paths from profile locator
334 *
335 * @param locatorName name of profile locator
336 * @param locator profile locator search specification
337 * @param searchPaths list of search paths to merge into
338 * @return search path list
339 */
340 private static List mergeSearchPathList(String locatorName, ProfileLocator locator, List searchPaths)
341 {
342
343
344
345
346
347
348
349
350
351
352 List locatorSearchPaths = new ArrayList(8);
353 int addLocatorSearchPathsAt = 0;
354 Iterator locatorIter = locator.iterator();
355 while (locatorIter.hasNext())
356 {
357
358 String pathRoot = Folder.PATH_SEPARATOR;
359 List paths = new ArrayList(8);
360 paths.add(new StringBuffer(pathRoot));
361 int pathDepth = 0;
362 int lastPathsCount = 0;
363 String lastPropertyName = null;
364 int lastPropertyValueLength = 0;
365 boolean navigatedPathRoot = false;
366
367
368
369 int skipProfileLocatorIterations = -1;
370
371
372 ProfileLocatorProperty [] properties = (ProfileLocatorProperty []) locatorIter.next();
373 for (int i = 0; (i < properties.length); i++)
374 {
375 if (properties[i].isNavigation())
376 {
377
378
379 if (properties[i].getValue() != null)
380 {
381
382
383
384
385
386 pathRoot = properties[i].getValue();
387 if (!pathRoot.startsWith(Folder.PATH_SEPARATOR))
388 {
389 pathRoot = Folder.PATH_SEPARATOR + pathRoot;
390 }
391 if (!pathRoot.endsWith(Folder.PATH_SEPARATOR))
392 {
393 pathRoot += Folder.PATH_SEPARATOR;
394 }
395 if (!pathRoot.equals(Folder.PATH_SEPARATOR))
396 {
397 int folderIndex = 1;
398 do
399 {
400 if (!pathRoot.regionMatches(folderIndex, Folder.RESERVED_SUBSITE_FOLDER_PREFIX, 0, Folder.RESERVED_SUBSITE_FOLDER_PREFIX.length()))
401 {
402 pathRoot = pathRoot.substring(0, folderIndex) + Folder.RESERVED_SUBSITE_FOLDER_PREFIX + pathRoot.substring(folderIndex);
403 }
404 folderIndex = pathRoot.indexOf(Folder.PATH_SEPARATOR, folderIndex) + 1;
405 }
406 while ((folderIndex != -1) && (folderIndex != pathRoot.length()));
407 }
408
409
410 pathDepth = 0;
411 paths.clear();
412 paths.add(new StringBuffer(pathRoot));
413 lastPathsCount = 0;
414 lastPropertyName = null;
415 lastPropertyValueLength = 0;
416 navigatedPathRoot = true;
417
418
419 skipProfileLocatorIterations = 0;
420 }
421 else
422 {
423
424
425
426 skipProfileLocatorIterations++;
427 }
428 }
429 else if (properties[i].isControl())
430 {
431
432 if (properties[i].getValue() != null)
433 {
434
435
436 String propertyName = properties[i].getName().toLowerCase();
437 String propertyValue = properties[i].getValue();
438
439
440
441 if (propertyName.equals(lastPropertyName))
442 {
443
444
445
446 ArrayList multipleValuePaths = new ArrayList(lastPathsCount);
447 Iterator pathsIter = paths.iterator();
448 for (int count = 0; (pathsIter.hasNext() && (count < lastPathsCount)); count++)
449 {
450 StringBuffer path = (StringBuffer) pathsIter.next();
451 StringBuffer multipleValuePath = new StringBuffer(path.toString());
452 multipleValuePath.setLength(multipleValuePath.length() - lastPropertyValueLength - 1);
453 multipleValuePath.append(propertyValue);
454 multipleValuePath.append(Folder.PATH_SEPARATOR_CHAR);
455 multipleValuePaths.add(multipleValuePath);
456 }
457 paths.addAll(multipleValuePaths);
458
459
460
461
462 skipProfileLocatorIterations++;
463 }
464 else
465 {
466
467 Iterator pathsIter = paths.iterator();
468 while (pathsIter.hasNext())
469 {
470 StringBuffer path = (StringBuffer) pathsIter.next();
471 path.append(Folder.RESERVED_FOLDER_PREFIX);
472 path.append(propertyName);
473 path.append(Folder.PATH_SEPARATOR_CHAR);
474 path.append(propertyValue);
475 path.append(Folder.PATH_SEPARATOR_CHAR);
476 }
477
478
479 pathDepth++;
480 lastPathsCount = paths.size();
481 lastPropertyValueLength = propertyValue.length();
482 lastPropertyName = propertyName;
483
484
485 skipProfileLocatorIterations = 0;
486 }
487 }
488 else
489 {
490
491
492
493
494 skipProfileLocatorIterations++;
495 }
496 }
497 else
498 {
499
500
501
502 skipProfileLocatorIterations++;
503 }
504 }
505
506
507 for (int skip = skipProfileLocatorIterations; ((skip > 0) && (locatorIter.hasNext())); skip--)
508 {
509 locatorIter.next();
510 }
511
512
513
514
515
516 if ((pathDepth > 0) || navigatedPathRoot)
517 {
518 locatorSearchPaths.addAll(addLocatorSearchPathsAt, paths);
519 addLocatorSearchPathsAt += paths.size();
520 }
521 if ((pathDepth == 1) && !navigatedPathRoot)
522 {
523 locatorSearchPaths.add(addLocatorSearchPathsAt++, new StringBuffer(pathRoot));
524 }
525
526
527
528
529 if ((pathDepth == 0) && navigatedPathRoot)
530 {
531 addLocatorSearchPathsAt = 0;
532 }
533
534
535
536
537 if (((pathDepth <= 1) && !navigatedPathRoot) || !locatorIter.hasNext())
538 {
539
540
541
542
543 Iterator locatorSearchPathsIter = locatorSearchPaths.iterator();
544 while (locatorSearchPathsIter.hasNext())
545 {
546 SiteViewSearchPath searchPath = new SiteViewSearchPath(locatorName, locatorSearchPathsIter.next().toString());
547
548 int existsAt = searchPaths.indexOf(searchPath);
549 if (existsAt != -1)
550 {
551 if (existsAt < (searchPaths.size()-1))
552 {
553
554 searchPaths.add(searchPaths.remove(existsAt));
555 }
556 }
557 else
558 {
559
560 searchPaths.add(searchPath);
561 }
562 }
563
564
565 locatorSearchPaths.clear();
566 addLocatorSearchPathsAt = 0;
567 }
568 }
569 return searchPaths;
570 }
571
572 /***
573 * SiteView - basic constructor
574 *
575 * @param pageManager PageManager component instance
576 */
577 public SiteView(PageManager pageManager)
578 {
579 this(pageManager, (List)null);
580 }
581
582 /***
583 * getPageManager - return PageManager component instance
584 *
585 * @return PageManager instance
586 */
587 public PageManager getPageManager()
588 {
589 return pageManager;
590 }
591
592 /***
593 * getSearchPaths - return ordered search paths list that
594 * defines this view
595 *
596 * @return search paths list
597 */
598 public List getSearchPaths()
599 {
600 return searchPaths;
601 }
602
603 /***
604 * getSearchPathsString - return search paths as string
605 *
606 * @return search paths list as comma separated string
607 */
608 public String getSearchPathsString()
609 {
610 return searchPathsString;
611 }
612
613 /***
614 * getRootFolderProxy - create and return root folder proxy instance
615 *
616 * @return root folder proxy
617 * @throws FolderNotFoundException if not found
618 * @throws SecurityException if view access not granted
619 */
620 public Folder getRootFolderProxy() throws FolderNotFoundException
621 {
622
623 if (rootFolderProxy == null)
624 {
625 try
626 {
627
628
629
630 SiteViewSearchPath searchPath = (SiteViewSearchPath)searchPaths.get(0);
631 String path = searchPath.toString();
632 String locatorName = searchPath.getLocatorName();
633
634
635
636 Folder rootFolder = pageManager.getFolder(path);
637 rootFolderProxy = FolderProxy.newInstance(this, locatorName, null, rootFolder);
638 }
639 catch (NodeException ne)
640 {
641 FolderNotFoundException fnfe = new FolderNotFoundException("Root folder not found");
642 fnfe.initCause(ne);
643 throw fnfe;
644 }
645 catch (NodeNotFoundException nnfe)
646 {
647 FolderNotFoundException fnfe = new FolderNotFoundException("Root folder not found");
648 fnfe.initCause(nnfe);
649 throw fnfe;
650 }
651 }
652 return rootFolderProxy;
653 }
654
655 /***
656 * getNodeProxy - get single folder, page, or link proxy
657 * at relative or absolute path
658 *
659 * @param path single node path
660 * @param currentNode current folder or page for relative paths or null
661 * @param onlyViewable node required to be viewable
662 * @param onlyVisible node required to be visible, (or current)
663 * @return folder, page, or link node proxy
664 * @throws NodeNotFoundException if not found
665 * @throws SecurityException if view access not granted
666 */
667 public Node getNodeProxy(String path, Node currentNode, boolean onlyViewable, boolean onlyVisible) throws NodeNotFoundException
668 {
669
670 String currentPath = path;
671 Folder currentFolder = null;
672 Page currentPage = null;
673 if (currentNode instanceof Page)
674 {
675 currentPage = (Page)currentNode;
676 currentFolder = (Folder)currentPage.getParent();
677 }
678 else if (currentNode instanceof Folder)
679 {
680 currentFolder = (Folder)currentNode;
681 }
682
683
684 if (currentPath.equals(CURRENT_PAGE_PATH) || currentPath.equals(ALT_CURRENT_PAGE_PATH))
685 {
686
687 return currentPage;
688 }
689
690
691
692 if (currentPath.startsWith(Folder.PATH_SEPARATOR))
693 {
694 currentPath = currentPath.substring(1);
695 currentFolder = null;
696 }
697 if (currentFolder == null)
698 {
699 currentFolder = getRootFolderProxy();
700 }
701
702
703 while ((currentPath.length() > 0) && !currentPath.equals(Folder.PATH_SEPARATOR))
704 {
705
706 int separatorIndex = currentPath.indexOf(Folder.PATH_SEPARATOR);
707 if (separatorIndex != -1)
708 {
709
710
711 String subfolder = currentPath.substring(0, separatorIndex);
712 currentPath = currentPath.substring(separatorIndex+1);
713 if (subfolder.equals(".."))
714 {
715
716 if (currentFolder.getParent() != null)
717 {
718 currentFolder = (Folder)currentFolder.getParent();
719 }
720 else
721 {
722 throw new NodeNotFoundException("Specified path " + path + " not found.");
723 }
724 }
725 else if (!subfolder.equals("."))
726 {
727
728
729 try
730 {
731 currentFolder = currentFolder.getFolder(subfolder);
732 }
733 catch (NodeException ne)
734 {
735 NodeNotFoundException nnfe = new NodeNotFoundException("Specified path " + path + " not found.");
736 nnfe.initCause(ne);
737 throw nnfe;
738 }
739 catch (NodeNotFoundException nnfe)
740 {
741 NodeNotFoundException nnfeWrapper = new NodeNotFoundException("Specified path " + path + " not found.");
742 nnfeWrapper.initCause(nnfe);
743 throw nnfeWrapper;
744 }
745 }
746 }
747 else
748 {
749
750
751
752 try
753 {
754 NodeSet children = currentFolder.getAll();
755 if (children != null)
756 {
757 Node node = children.get(currentPath);
758 if ((node != null) && (!onlyVisible || !node.isHidden() || (node == currentPage)) &&
759 (!onlyViewable || isProxyViewable(node, onlyVisible)))
760 {
761 return node;
762 }
763 }
764 }
765 catch (NodeException ne)
766 {
767 NodeNotFoundException nnfe = new NodeNotFoundException("Specified path " + path + " not found.");
768 nnfe.initCause(ne);
769 throw nnfe;
770 }
771 throw new NodeNotFoundException("Specified path " + path + " not found or viewable/visible.");
772 }
773 }
774
775
776
777 if ((!onlyVisible || !currentFolder.isHidden()) &&
778 (!onlyViewable || isProxyViewable(currentFolder, onlyVisible)))
779 {
780 return currentFolder;
781 }
782 throw new NodeNotFoundException("Specified path " + path + " not found or viewable/visible.");
783 }
784
785 /***
786 * getNodeProxies - get folder, page, or link proxies at
787 * relative or absolute path using simple path
788 * wildcards and character classes
789 *
790 * @param regexpPath regular expression node path
791 * @param currentNode current folder or page for relative paths or null
792 * @param onlyViewable nodes required to be viewable flag
793 * @param onlyVisible node required to be visible, (or current)
794 * @return list of folder, page, or link node proxies
795 */
796 public List getNodeProxies(String regexpPath, Node currentNode, boolean onlyViewable, boolean onlyVisible)
797 {
798
799 String currentRegexpPath = regexpPath;
800 Folder currentFolder = null;
801 Page currentPage = null;
802 if (currentNode instanceof Page)
803 {
804 currentPage = (Page)currentNode;
805 currentFolder = (Folder)currentPage.getParent();
806 }
807 else if (currentNode instanceof Folder)
808 {
809 currentFolder = (Folder)currentNode;
810 }
811
812
813 if (currentRegexpPath.equals(CURRENT_PAGE_PATH) || currentRegexpPath.equals(ALT_CURRENT_PAGE_PATH))
814 {
815 if (currentPage != null)
816 {
817
818 List proxies = new ArrayList(1);
819 proxies.add(currentPage);
820 return proxies;
821 }
822 else
823 {
824
825 return null;
826 }
827 }
828
829
830
831 if (currentRegexpPath.startsWith(Folder.PATH_SEPARATOR))
832 {
833 currentRegexpPath = currentRegexpPath.substring(1);
834 currentFolder = null;
835 }
836 if (currentFolder == null)
837 {
838 try
839 {
840 currentFolder = getRootFolderProxy();
841 }
842 catch (FolderNotFoundException fnfe)
843 {
844 return null;
845 }
846 catch (SecurityException se)
847 {
848 return null;
849 }
850 }
851
852
853 while ((currentRegexpPath.length() > 0) && !currentRegexpPath.equals(Folder.PATH_SEPARATOR))
854 {
855
856 int separatorIndex = currentRegexpPath.indexOf(Folder.PATH_SEPARATOR);
857 if (separatorIndex != -1)
858 {
859
860
861 String subfolder = currentRegexpPath.substring(0, separatorIndex);
862 currentRegexpPath = currentRegexpPath.substring(separatorIndex+1);
863 if (subfolder.equals(".."))
864 {
865
866 if (currentFolder.getParent() != null)
867 {
868 currentFolder = (Folder)currentFolder.getParent();
869 }
870 else
871 {
872 return null;
873 }
874 }
875 else if (!subfolder.equals("."))
876 {
877 try
878 {
879
880 String subfolderPattern = pathRegexpPattern(subfolder);
881 if (subfolderPattern != null)
882 {
883
884 NodeSet subfolders = currentFolder.getFolders();
885 if (subfolders != null)
886 {
887 subfolders = subfolders.inclusiveSubset(subfolderPattern);
888 if (subfolders != null)
889 {
890
891
892
893 if (subfolders.size() > 1)
894 {
895
896 List proxies = null;
897 Iterator subfoldersIter = subfolders.iterator();
898 while (subfoldersIter.hasNext())
899 {
900 currentFolder = (Folder)subfoldersIter.next();
901 List subfolderProxies = getNodeProxies(currentRegexpPath, currentFolder, onlyViewable, onlyVisible);
902 if ((subfolderProxies != null) && !subfolderProxies.isEmpty())
903 {
904 if (proxies == null)
905 {
906 proxies = new ArrayList();
907 }
908 proxies.addAll(subfolderProxies);
909 }
910 }
911 return proxies;
912 }
913 else if (subfolders.size() == 1)
914 {
915
916 currentFolder = (Folder)subfolders.iterator().next();
917 }
918 else
919 {
920
921 return null;
922 }
923 }
924 else
925 {
926
927 return null;
928 }
929 }
930 else
931 {
932
933 return null;
934 }
935 }
936 else
937 {
938
939
940 currentFolder = currentFolder.getFolder(subfolder);
941 }
942 }
943 catch (NodeException ne)
944 {
945
946 return null;
947 }
948 catch (NodeNotFoundException nnfe)
949 {
950
951 return null;
952 }
953 catch (SecurityException se)
954 {
955
956 return null;
957 }
958 }
959 }
960 else
961 {
962 try
963 {
964
965 NodeSet children = currentFolder.getAll();
966 if (children != null)
967 {
968
969 String pathPattern = pathRegexpPattern(currentRegexpPath);
970 if (pathPattern != null)
971 {
972
973
974
975 children = children.inclusiveSubset(pathPattern);
976 if ((children != null) && !children.isEmpty())
977 {
978 List proxies = null;
979 Iterator childrenIter = children.iterator();
980 while (childrenIter.hasNext())
981 {
982 Node child = (Node)childrenIter.next();
983 if ((!onlyVisible || !child.isHidden() || (child == currentPage)) &&
984 (!onlyViewable || isProxyViewable(child, onlyVisible)))
985 {
986 if (proxies == null)
987 {
988 proxies = new ArrayList(children.size());
989 }
990 proxies.add(child);
991 }
992 }
993 return proxies;
994 }
995 }
996 else
997 {
998
999
1000
1001 Node child = children.get(currentRegexpPath);
1002 if ((child != null) && (!onlyVisible || !child.isHidden() || (child == currentPage)) &&
1003 (!onlyViewable || isProxyViewable(child, onlyVisible)))
1004 {
1005 List proxies = new ArrayList(1);
1006 proxies.add(currentFolder);
1007 return proxies;
1008 }
1009 }
1010 }
1011
1012 }
1013 catch (NodeException ne)
1014 {
1015 }
1016 catch (SecurityException se)
1017 {
1018 }
1019
1020
1021 return null;
1022 }
1023 }
1024
1025
1026
1027 if ((!onlyVisible || !currentFolder.isHidden()) &&
1028 (!onlyViewable || isProxyViewable(currentFolder, onlyVisible)))
1029 {
1030 List proxies = new ArrayList(1);
1031 proxies.add(currentFolder);
1032 return proxies;
1033 }
1034 return null;
1035 }
1036
1037 /***
1038 * pathRegexpPattern - tests for and converts simple path wildcard
1039 * and character class regular exressions to
1040 * perl5/standard java pattern syntax
1041 *
1042 * @param regexp - candidate path regular expression
1043 * @return - converted pattern or null if no regular expression
1044 */
1045 private static String pathRegexpPattern(String regexp)
1046 {
1047
1048 StringBuffer pattern = null;
1049 for (int i = 0, limit = regexp.length(); (i < limit); i++)
1050 {
1051 char regexpChar = regexp.charAt(i);
1052 switch (regexpChar)
1053 {
1054 case '*':
1055 case '.':
1056 case '?':
1057 case '[':
1058 if (pattern == null)
1059 {
1060 pattern = new StringBuffer(regexp.length()*2);
1061 pattern.append(regexp.substring(0, i));
1062 }
1063 switch (regexpChar)
1064 {
1065 case '*':
1066 pattern.append(".*");
1067 break;
1068 case '.':
1069 pattern.append("//.");
1070 break;
1071 case '?':
1072 pattern.append('.');
1073 break;
1074 case '[':
1075 pattern.append('[');
1076 break;
1077 }
1078 break;
1079 default:
1080 if (pattern != null)
1081 {
1082 pattern.append(regexpChar);
1083 }
1084 break;
1085 }
1086 }
1087
1088
1089 if (pattern != null)
1090 return pattern.toString();
1091 return null;
1092 }
1093
1094 /***
1095 * isProxyViewable - tests for node proxy visibility in view
1096 *
1097 * @param nodeProxy test node proxy
1098 * @param onlyVisible nodes required to be visible
1099 * @return - viewable flag
1100 */
1101 private static boolean isProxyViewable(Node nodeProxy, boolean onlyVisible)
1102 {
1103
1104
1105
1106 if (nodeProxy instanceof Folder)
1107 {
1108 try
1109 {
1110 NodeSet children = ((Folder) nodeProxy).getAll();
1111 if (children != null)
1112 {
1113 Iterator childrenIter = children.iterator();
1114 while (childrenIter.hasNext())
1115 {
1116 Node child = (Node)childrenIter.next();
1117 if ((!onlyVisible || !child.isHidden()) && isProxyViewable(child, onlyVisible))
1118 {
1119 return true;
1120 }
1121 }
1122 }
1123 }
1124 catch (NodeException ne)
1125 {
1126 }
1127 catch (SecurityException se)
1128 {
1129 }
1130 return false;
1131 }
1132 return true;
1133 }
1134
1135 /***
1136 * getStandardMenuNames - get set of available standard menu names
1137 *
1138 * @return menu names set
1139 */
1140 public Set getStandardMenuNames()
1141 {
1142
1143 return STANDARD_MENU_NAMES;
1144 }
1145
1146 /***
1147 * getStandardMenuDefinitionLocators - get list of available standard
1148 * menu definition locators
1149 *
1150 * @return menu definition locators list
1151 */
1152 public List getStandardMenuDefinitionLocators()
1153 {
1154
1155 return STANDARD_MENU_DEFINITION_LOCATORS;
1156 }
1157
1158 /***
1159 * getMenuDefinitionLocators - get list of view node proxy menu
1160 * definition locators; implemented here
1161 * to hide view proxy manipulation from
1162 * more general portal site implementation
1163 *
1164 * @param node node proxy
1165 * @return definition locator list
1166 */
1167 public List getMenuDefinitionLocators(Node node)
1168 {
1169
1170
1171 NodeProxy nodeProxy = NodeProxy.getNodeProxy(node);
1172 if (nodeProxy != null)
1173 {
1174 return nodeProxy.getMenuDefinitionLocators();
1175 }
1176 return null;
1177 }
1178
1179 /***
1180 * getMenuDefinitionLocator - get named view node proxy menu
1181 * definition locator; implemented here
1182 * to hide view proxy manipulation from
1183 * more general portal site implementation
1184 *
1185 * @param node node proxy
1186 * @param name menu definition name
1187 * @return menu definition locator
1188 */
1189 public SiteViewMenuDefinitionLocator getMenuDefinitionLocator(Node node, String name)
1190 {
1191
1192
1193 NodeProxy nodeProxy = NodeProxy.getNodeProxy(node);
1194 if (nodeProxy != null)
1195 {
1196 return nodeProxy.getMenuDefinitionLocator(name);
1197 }
1198 return null;
1199 }
1200
1201 /***
1202 * getProfileLocatorName - get view node proxy profile locator name;
1203 * implemented here to hide view proxy manipulation
1204 * from more general portal site implementation
1205 *
1206 * @param node node proxy
1207 * @return profile locator name
1208 */
1209 public String getProfileLocatorName(Node node)
1210 {
1211 SiteViewProxy siteViewProxy = SiteViewProxy.getSiteViewProxy(node);
1212 if (siteViewProxy != null)
1213 {
1214 return siteViewProxy.getLocatorName();
1215 }
1216 return null;
1217 }
1218
1219 /***
1220 * getManagedPage - get concrete page instance from page proxy;
1221 * implemented here to hide view proxy manipulation
1222 * from more general portal site implementation
1223 *
1224 * @param page page proxy
1225 * @return managed page
1226 */
1227 public Page getManagedPage(Page page)
1228 {
1229
1230
1231 PageProxy pageProxy = (PageProxy)NodeProxy.getNodeProxy(page);
1232 if (pageProxy != null)
1233 {
1234 return pageProxy.getPage();
1235 }
1236 return null;
1237 }
1238 }