1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.jetspeed.om.folder.psml;
18
19 import java.security.AccessController;
20 import java.util.Iterator;
21 import java.util.List;
22 import java.util.Locale;
23
24 import org.apache.commons.logging.Log;
25 import org.apache.commons.logging.LogFactory;
26 import org.apache.jetspeed.JetspeedActions;
27 import org.apache.jetspeed.om.common.GenericMetadata;
28 import org.apache.jetspeed.om.common.SecurityConstraints;
29 import org.apache.jetspeed.om.folder.Folder;
30 import org.apache.jetspeed.om.folder.FolderNotFoundException;
31 import org.apache.jetspeed.om.folder.MenuDefinition;
32 import org.apache.jetspeed.om.folder.MenuExcludeDefinition;
33 import org.apache.jetspeed.om.folder.MenuIncludeDefinition;
34 import org.apache.jetspeed.om.folder.MenuOptionsDefinition;
35 import org.apache.jetspeed.om.folder.MenuSeparatorDefinition;
36 import org.apache.jetspeed.om.folder.Reset;
37 import org.apache.jetspeed.om.page.Link;
38 import org.apache.jetspeed.om.page.Page;
39 import org.apache.jetspeed.om.page.PageSecurity;
40 import org.apache.jetspeed.page.PageManagerUtils;
41 import org.apache.jetspeed.page.PageNotFoundException;
42 import org.apache.jetspeed.page.document.DocumentException;
43 import org.apache.jetspeed.page.document.DocumentHandlerFactory;
44 import org.apache.jetspeed.page.document.DocumentNotFoundException;
45 import org.apache.jetspeed.page.document.FolderHandler;
46 import org.apache.jetspeed.page.document.Node;
47 import org.apache.jetspeed.page.document.NodeException;
48 import org.apache.jetspeed.page.document.NodeNotFoundException;
49 import org.apache.jetspeed.page.document.NodeSet;
50 import org.apache.jetspeed.page.document.UnsupportedDocumentTypeException;
51 import org.apache.jetspeed.page.document.psml.AbstractNode;
52 import org.apache.jetspeed.page.document.psml.NodeOrderCompartaor;
53 import org.apache.jetspeed.page.document.psml.NodeSetImpl;
54 import org.apache.jetspeed.security.FolderPermission;
55
56 /***
57 * FolderImpl
58 *
59 * @author <a href="mailto:taylor@apache.org">David Sean Taylor </a>
60 * @author <a href="mailto:jford@apache.org">Jeremy Ford </a>
61 * @author <a href="mailto:weaver@apache.org">Scott T. Weaver</a>
62 * @version $Id: FolderImpl.java 595429 2007-11-15 20:20:41Z smilek $
63 */
64 public class FolderImpl extends AbstractNode implements Folder, Reset
65 {
66
67 private NodeSet allNodes;
68 private FolderMetaDataImpl metadata;
69 private FolderHandler folderHandler;
70 private int reservedType = RESERVED_FOLDER_NONE;
71
72 private static final Log log = LogFactory.getLog(FolderImpl.class);
73
74 public FolderImpl( String path, FolderMetaDataImpl metadata, DocumentHandlerFactory handlerFactory,
75 FolderHandler folderHandler )
76 {
77 this.metadata = metadata;
78 this.metadata.setParent(this);
79 this.folderHandler = folderHandler;
80 setPath(path);
81 setReservedType();
82 setHandlerFactory(handlerFactory);
83 setPermissionsEnabled(handlerFactory.getPermissionsEnabled());
84 setConstraintsEnabled(handlerFactory.getConstraintsEnabled());
85 }
86
87 public FolderImpl( String path, DocumentHandlerFactory handlerFactory, FolderHandler folderHandler )
88 {
89 this.metadata = new FolderMetaDataImpl();
90 this.metadata.setParent(this);
91 this.folderHandler = folderHandler;
92 setPath(path);
93 setReservedType();
94 setHandlerFactory(handlerFactory);
95 setPermissionsEnabled(handlerFactory.getPermissionsEnabled());
96 setConstraintsEnabled(handlerFactory.getConstraintsEnabled());
97 }
98
99 public FolderImpl()
100 {
101 this.metadata = new FolderMetaDataImpl();
102 this.metadata.setParent(this);
103 setReservedType();
104 }
105
106
107
108
109 public String getSkin()
110 {
111 return metadata.getSkin();
112 }
113
114
115
116
117 public void setSkin( String skinName )
118 {
119 metadata.setSkin(skinName);
120 }
121
122
123
124
125 public String getEffectiveDefaultDecorator(String fragmentType)
126 {
127
128 String decorator = getDefaultDecorator(fragmentType);
129 if (decorator == null)
130 {
131
132 Folder parentFolder = (Folder)getParent();
133 if (parentFolder != null)
134 {
135 return parentFolder.getEffectiveDefaultDecorator(fragmentType);
136 }
137 }
138 return decorator;
139 }
140
141
142
143
144 public String getDefaultDecorator( String fragmentType )
145 {
146 return metadata.getDefaultDecorator(fragmentType);
147 }
148
149
150
151
152 public void setDefaultDecorator( String decoratorName, String fragmentType )
153 {
154 metadata.setDefaultDecorator(decoratorName, fragmentType);
155 }
156
157
158
159
160 public List getDocumentOrder()
161 {
162 return metadata.getDocumentOrder();
163 }
164
165
166
167
168 public void setDocumentOrder(List docIndexes)
169 {
170 metadata.setDocumentOrder(docIndexes);
171 }
172
173
174
175
176 public String getDefaultPage()
177 {
178 return metadata.getDefaultPage();
179 }
180
181
182
183
184
185
186 public void setDefaultPage( String defaultPage )
187 {
188 metadata.setDefaultPage(defaultPage);
189 }
190
191 /***
192 * <p>
193 * getFolders
194 * </p>
195 *
196 * @param checkAccess flag
197 * @return folders node set
198 * @throws DocumentException
199 */
200 public NodeSet getFolders(boolean checkAccess) throws DocumentException
201 {
202
203 NodeSet folders = getAllNodes().subset(FOLDER_TYPE);
204
205
206 if (checkAccess)
207 {
208 folders = checkAccess(folders, JetspeedActions.VIEW);
209 }
210 return folders;
211 }
212
213
214
215
216
217
218 public NodeSet getFolders() throws DocumentException
219 {
220
221 return getFolders(true);
222 }
223
224 /***
225 * <p>
226 * getFolder
227 * </p>
228 *
229 * @param name
230 * @param checkAccess flag
231 * @return folder
232 * @throws FolderNotFoundException
233 * @throws DocumentException
234 */
235 public Folder getFolder(String name, boolean checkAccess) throws FolderNotFoundException, DocumentException
236 {
237
238 Folder folder = (Folder) getAllNodes().subset(FOLDER_TYPE).get(name);
239 if (folder == null)
240 {
241 throw new FolderNotFoundException("Jetspeed PSML folder not found: " + name);
242 }
243
244
245 if (checkAccess)
246 {
247 folder.checkAccess(JetspeedActions.VIEW);
248 }
249 return folder;
250 }
251
252
253
254
255
256
257 public Folder getFolder(String name) throws FolderNotFoundException, DocumentException
258 {
259
260 return getFolder(name, true);
261 }
262
263 /***
264 * <p>
265 * getPages
266 * </p>
267 *
268 * @param checkAccess flag
269 * @return pages node set
270 * @throws NodeException
271 */
272 public NodeSet getPages(boolean checkAccess) throws NodeException
273 {
274
275 NodeSet pages = getAllNodes().subset(Page.DOCUMENT_TYPE);
276
277
278 if (checkAccess)
279 {
280 pages = checkAccess(pages, JetspeedActions.VIEW);
281 }
282 return pages;
283 }
284
285
286
287
288
289
290 public NodeSet getPages() throws NodeException
291 {
292
293 return getPages(true);
294 }
295
296 /***
297 * <p>
298 * getPage
299 * </p>
300 *
301 * @param name
302 * @param checkAccess flag
303 * @return page
304 * @throws PageNotFoundException
305 * @throws NodeException
306 */
307 public Page getPage(String name, boolean checkAccess) throws PageNotFoundException, NodeException
308 {
309
310 Page page = (Page) getAllNodes().subset(Page.DOCUMENT_TYPE).get(name);
311 if (page == null)
312 {
313 throw new PageNotFoundException("Jetspeed PSML page not found: " + name);
314 }
315
316
317 if (checkAccess)
318 {
319 page.checkAccess(JetspeedActions.VIEW);
320 }
321 return page;
322 }
323
324
325
326
327
328
329 public Page getPage(String name) throws PageNotFoundException, NodeException
330 {
331
332 return getPage(name, true);
333 }
334
335 /***
336 * <p>
337 * getLinks
338 * </p>
339 *
340 * @param checkAccess flag
341 * @return links node set
342 * @throws NodeException
343 */
344 public NodeSet getLinks(boolean checkAccess) throws NodeException
345 {
346
347 NodeSet links = getAllNodes().subset(Link.DOCUMENT_TYPE);
348
349
350 if (checkAccess)
351 {
352 links = checkAccess(links, JetspeedActions.VIEW);
353 }
354 return links;
355 }
356
357
358
359
360
361
362 public NodeSet getLinks() throws NodeException
363 {
364
365 return getLinks(true);
366 }
367
368 /***
369 * <p>
370 * getLink
371 * </p>
372 *
373 * @param name
374 * @param checkAccess flag
375 * @return link
376 * @throws DocumentNotFoundException
377 * @throws NodeException
378 */
379 public Link getLink(String name, boolean checkAccess) throws DocumentNotFoundException, NodeException
380 {
381
382 Link link = (Link) getAllNodes().subset(Link.DOCUMENT_TYPE).get(name);
383 if (link == null)
384 {
385 throw new DocumentNotFoundException("Jetspeed PSML link not found: " + name);
386 }
387
388
389 if (checkAccess)
390 {
391 link.checkAccess(JetspeedActions.VIEW);
392 }
393 return link;
394 }
395
396
397
398
399
400
401 public Link getLink(String name) throws DocumentNotFoundException, NodeException
402 {
403
404 return getLink(name, true);
405 }
406
407 /***
408 * <p>
409 * getPageSecurity
410 * </p>
411 *
412 * @param checkAccess flag
413 * @return page security
414 * @throws DocumentNotFoundException
415 * @throws NodeException
416 */
417 public PageSecurity getPageSecurity(boolean checkAccess) throws DocumentNotFoundException, NodeException
418 {
419
420
421 if (checkAccess)
422 {
423 checkAccess(JetspeedActions.VIEW);
424 }
425
426
427 PageSecurity pageSecurity = (PageSecurity) getAllNodes( false ).subset(PageSecurity.DOCUMENT_TYPE).get(PageSecurity.DOCUMENT_TYPE);
428 if (pageSecurity == null)
429 {
430 throw new DocumentNotFoundException("Jetspeed PSML page security not found: " + PageSecurity.DOCUMENT_TYPE);
431 }
432 return pageSecurity;
433 }
434
435
436
437
438
439
440 public PageSecurity getPageSecurity() throws DocumentNotFoundException, NodeException
441 {
442
443 return getPageSecurity(false);
444 }
445
446
447
448
449
450
451 public NodeSet getAll() throws DocumentException
452 {
453
454
455 NodeSet nodes = getAllNodes();
456 NodeSet filteredNodes = null;
457 Iterator checkAccessIter = nodes.iterator();
458 while (checkAccessIter.hasNext())
459 {
460 Node node = (Node)checkAccessIter.next();
461 try
462 {
463 ((AbstractNode) node).checkAccess(JetspeedActions.VIEW);
464 if (filteredNodes != null)
465 {
466 filteredNodes.add(node);
467 }
468 }
469 catch (SecurityException se)
470 {
471 if (filteredNodes == null)
472 {
473 filteredNodes = new NodeSetImpl(getPath(), ((NodeSetImpl) nodes).getComparator());
474 Iterator copyIter = nodes.iterator();
475 while (copyIter.hasNext())
476 {
477 Node copyNode = (Node)copyIter.next();
478 if (copyNode != node)
479 {
480 filteredNodes.add(copyNode);
481 }
482 else
483 {
484 break;
485 }
486 }
487 }
488 }
489 }
490 if (filteredNodes != null)
491 {
492 return filteredNodes;
493 }
494 return nodes;
495 }
496
497 /***
498 * <p>
499 * getAllNodes
500 * </p>
501 *
502 * @return all nodes immediatley under this
503 * @throws DocumentException
504 */
505 public NodeSet getAllNodes() throws DocumentException
506 {
507 return getAllNodes( true );
508 }
509
510 protected synchronized NodeSet getAllNodes( boolean folderExistenceRequired ) throws DocumentException
511 {
512 if((allNodes == null) && (folderHandler != null))
513 {
514 if(metadata.getDocumentOrder() != null)
515 {
516 if (getPath().endsWith(PATH_SEPARATOR))
517 {
518 allNodes = new NodeSetImpl(getPath(), new NodeOrderCompartaor(metadata.getDocumentOrder(), getPath()));
519 }
520 else
521 {
522 allNodes = new NodeSetImpl(getPath(), new NodeOrderCompartaor(metadata.getDocumentOrder(), getPath() + PATH_SEPARATOR));
523 }
524 }
525 else
526 {
527 allNodes = new NodeSetImpl(getPath());
528 }
529
530 try
531 {
532 String[] nodeNames = folderHandler.listAll(getPath());
533 for (int i = 0; i < nodeNames.length; i++)
534 {
535 if (!nodeNames[i].equals(FolderMetaDataImpl.DOCUMENT_TYPE))
536 {
537 Node node = null;
538 try
539 {
540 if (getPath().endsWith(PATH_SEPARATOR))
541 {
542 String full = PageManagerUtils.concatenatePaths(getPath(), nodeNames[i]);
543 if (!folderHandler.isFolder(full))
544 {
545 node = getHandlerFactory().getDocumentHandlerForPath(nodeNames[i]).getDocument(getPath() + nodeNames[i]);
546 }
547 else
548 {
549 node = folderHandler.getFolder(getPath() + nodeNames[i]);
550 }
551 }
552 else
553 {
554 String full = PageManagerUtils.concatenatePaths(getPath(), nodeNames[i]);
555 if (!folderHandler.isFolder(full))
556
557 {
558 node = getHandlerFactory().getDocumentHandlerForPath(nodeNames[i]).getDocument(getPath() + PATH_SEPARATOR + nodeNames[i]);
559 }
560 else
561 {
562 node = folderHandler.getFolder(getPath() + PATH_SEPARATOR + nodeNames[i]);
563 }
564 }
565 node.setParent(this);
566 allNodes.add(node);
567 }
568 catch (UnsupportedDocumentTypeException e)
569 {
570
571 log.info("getAllNodes() Skipping unsupported document: "+nodeNames[i]);
572 }
573 catch (Exception e)
574 {
575 log.warn("getAllNodes() failed to create Node: "+nodeNames[i]+":"+e.toString(), e);
576 }
577 }
578 }
579 }
580 catch (FolderNotFoundException fnfe)
581 {
582 if ( folderExistenceRequired )
583 {
584 log.error( "getAllNodes() unexpected missing folder: " + getPath(), fnfe );
585 }
586 }
587 }
588
589 return allNodes;
590 }
591
592 /***
593 * <p>
594 * getFolderMetaData
595 * </p>
596 *
597 * @return implementation specific folder metadata
598 */
599 public FolderMetaDataImpl getFolderMetaData()
600 {
601 return metadata;
602 }
603
604 /***
605 * <p>
606 * setFolderHandler
607 * </p>
608 *
609 * @param handler folder handler
610 */
611 public void setFolderHandler(FolderHandler handler)
612 {
613 this.folderHandler = handler;
614 }
615
616 /***
617 * <p>
618 * getMetadata
619 * </p>
620 *
621 * @see org.apache.jetspeed.page.document.AbstractNode#getMetadata()
622 * @return metadata
623 */
624 public GenericMetadata getMetadata()
625 {
626 return metadata.getMetadata();
627 }
628
629 /***
630 * <p>
631 * getSecurityConstraints
632 * </p>
633 *
634 * @see org.apache.jetspeed.om.common.SecureResource#getSecurityConstraints()
635 * @return
636 */
637 public SecurityConstraints getSecurityConstraints()
638 {
639 return metadata.getSecurityConstraints();
640 }
641 /***
642 * <p>
643 * setSecurityConstraints
644 * </p>
645 *
646 * @see org.apache.jetspeed.om.common.SecureResource#setSecurityConstraints(org.apache.jetspeed.om.common.SecurityConstraints)
647 * @param constraints
648 */
649 public void setSecurityConstraints(SecurityConstraints constraints)
650 {
651 metadata.setSecurityConstraints(constraints);
652 }
653
654 /***
655 * getEffectivePageSecurity
656 *
657 * @see org.apache.jetspeed.om.page.psml.AbstractElementImpl#getEffectivePageSecurity()
658 */
659 public PageSecurity getEffectivePageSecurity()
660 {
661
662 PageSecurity pageSecurity = null;
663 try
664 {
665 pageSecurity = getPageSecurity(false);
666 if (pageSecurity != null)
667 {
668 return pageSecurity;
669 }
670 }
671 catch (NodeException ne)
672 {
673 }
674 catch (NodeNotFoundException nnfe)
675 {
676 }
677
678
679 FolderImpl parentFolderImpl = (FolderImpl)getParent();
680 if (parentFolderImpl != null)
681 {
682 return parentFolderImpl.getEffectivePageSecurity();
683 }
684 return null;
685 }
686
687 /***
688 * <p>
689 * checkPermissions
690 * </p>
691 *
692 * @param path
693 * @param mask
694 * @param checkNodeOnly
695 * @param checkParentsOnly
696 * @throws SecurityException
697 */
698 public void checkPermissions(String path, int mask, boolean checkNodeOnly, boolean checkParentsOnly) throws SecurityException
699 {
700
701
702 if (!checkParentsOnly)
703 {
704 FolderPermission permission = new FolderPermission(path, mask);
705 AccessController.checkPermission(permission);
706 }
707
708
709
710 if (!checkNodeOnly && (getParent() != null))
711 {
712 ((AbstractNode)getParent()).checkPermissions(mask, false, false);
713 }
714 }
715
716 /***
717 * <p>
718 * getTitle
719 * </p>
720 *
721 * @see org.apache.jetspeed.page.document.Node#getTitle(java.util.Locale)
722 * @param locale
723 * @return title in specified locale
724 */
725 public String getTitle( Locale locale )
726 {
727 return metadata.getTitle(locale);
728 }
729 /***
730 * <p>
731 * getTitle
732 * </p>
733 *
734 * @see org.apache.jetspeed.om.page.BaseElement#getTitle()
735 * @return title
736 */
737 public String getTitle()
738 {
739 return metadata.getTitle();
740 }
741 /***
742 * <p>
743 * setTitle
744 * </p>
745 *
746 * @see org.apache.jetspeed.om.page.BaseElement#setTitle(java.lang.String)
747 * @param title
748 */
749 public void setTitle( String title )
750 {
751 metadata.setTitle(title);
752 }
753 /***
754 * <p>
755 * getShortTitle
756 * </p>
757 *
758 * @see org.apache.jetspeed.page.document.Node#getShortTitle(java.util.Locale)
759 * @param locale
760 * @return short title in supplied locate
761 */
762 public String getShortTitle( Locale locale )
763 {
764 return metadata.getShortTitle(locale);
765 }
766 /***
767 * <p>
768 * getShortTitle
769 * </p>
770 *
771 * @see org.apache.jetspeed.om.page.BaseElement#getShortTitle()
772 * @return short title
773 */
774 public String getShortTitle()
775 {
776 return metadata.getShortTitle();
777 }
778 /***
779 * <p>
780 * setShortTitle
781 * </p>
782 *
783 * @see org.apache.jetspeed.om.page.BaseElement#setShortTitle(java.lang.String)
784 * @param title
785 */
786 public void setShortTitle( String title )
787 {
788 metadata.setShortTitle(title);
789 }
790 /***
791 * <p>
792 * getType
793 * </p>
794 *
795 * @see org.apache.jetspeed.page.document.Node#getType()
796 * @return type string
797 */
798 public String getType()
799 {
800 return FOLDER_TYPE;
801 }
802 /***
803 * <p>
804 * isHidden
805 * </p>
806 *
807 * @see org.apache.jetspeed.page.document.Node#isHidden()
808 * @return whether folder is hidden
809 */
810 public boolean isHidden()
811 {
812 return metadata.isHidden();
813 }
814 /***
815 * <p>
816 * setHidden
817 * </p>
818 *
819 * @see org.apache.jetspeed.page.document.AbstractNode#setHidden(boolean)
820 * @param hidden
821 */
822 public void setHidden( boolean hidden )
823 {
824 ((AbstractNode)metadata).setHidden(hidden);
825 }
826
827
828
829
830 public void reset()
831 {
832 allNodes = null;
833
834 }
835
836 /***
837 * getMenuDefinitions - get list of menu definitions
838 *
839 * @return definition list
840 */
841 public List getMenuDefinitions()
842 {
843 return metadata.getMenuDefinitions();
844 }
845
846 /***
847 * newMenuDefinition - creates a new empty menu definition
848 *
849 * @return a newly created MenuDefinition object for use in Folder
850 */
851 public MenuDefinition newMenuDefinition()
852 {
853 return new MenuDefinitionImpl();
854 }
855
856 /***
857 * newMenuExcludeDefinition - creates a new empty menu exclude definition
858 *
859 * @return a newly created MenuExcludeDefinition object for use in Folder
860 */
861 public MenuExcludeDefinition newMenuExcludeDefinition()
862 {
863 return new MenuExcludeDefinitionImpl();
864 }
865
866 /***
867 * newMenuIncludeDefinition - creates a new empty menu include definition
868 *
869 * @return a newly created MenuIncludeDefinition object for use in Folder
870 */
871 public MenuIncludeDefinition newMenuIncludeDefinition()
872 {
873 return new MenuIncludeDefinitionImpl();
874 }
875
876 /***
877 * newMenuOptionsDefinition - creates a new empty menu options definition
878 *
879 * @return a newly created MenuOptionsDefinition object for use in Folder
880 */
881 public MenuOptionsDefinition newMenuOptionsDefinition()
882 {
883 return new MenuOptionsDefinitionImpl();
884 }
885
886 /***
887 * newMenuSeparatorDefinition - creates a new empty menu separator definition
888 *
889 * @return a newly created MenuSeparatorDefinition object for use in Folder
890 */
891 public MenuSeparatorDefinition newMenuSeparatorDefinition()
892 {
893 return new MenuSeparatorDefinitionImpl();
894 }
895
896 /***
897 * setMenuDefinitions - set list of menu definitions
898 *
899 * @param definitions definition list
900 */
901 public void setMenuDefinitions(List definitions)
902 {
903 metadata.setMenuDefinitions(definitions);
904 }
905
906 /***
907 * unmarshalled - notification that this instance has been
908 * loaded from the persistent store
909 */
910 public void unmarshalled()
911 {
912
913 super.unmarshalled();
914
915
916 if (getTitle() == null)
917 {
918 setTitle(getTitleName());
919 }
920 }
921
922 public boolean isReserved()
923 {
924 return (reservedType > RESERVED_FOLDER_NONE);
925 }
926
927 public int getReservedType()
928 {
929 return reservedType;
930 }
931
932 private void setReservedType()
933 {
934 String name = getName();
935 if (name != null)
936 {
937 if (name.startsWith(RESERVED_SUBSITE_FOLDER_PREFIX))
938 {
939 reservedType = RESERVED_FOLDER_SUBSITES;
940 }
941 else if (name.startsWith(RESERVED_FOLDER_PREFIX))
942 {
943 if (name.equals(RESERVED_USER_FOLDER_NAME))
944 reservedType = RESERVED_FOLDER_USERS;
945 else if (name.equals(RESERVED_ROLE_FOLDER_NAME))
946 reservedType = RESERVED_FOLDER_ROLES;
947 else if (name.equals(RESERVED_GROUP_FOLDER_NAME))
948 reservedType = RESERVED_FOLDER_GROUPS;
949 else if (name.equals(RESERVED_MEDIATYPE_FOLDER_NAME))
950 reservedType = RESERVED_FOLDER_MEDIATYPE;
951 else if (name.equals(RESERVED_LANGUAGE_FOLDER_NAME))
952 reservedType = RESERVED_FOLDER_LANGUAGE;
953 else if (name.equals(RESERVED_COUNTRY_FOLDER_NAME))
954 reservedType = RESERVED_FOLDER_COUNTRY;
955 else
956 reservedType = RESERVED_FOLDER_OTHER;
957 }
958 }
959 }
960
961 }