View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    * 
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   * 
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.jetspeed.page.document.psml;
18  
19  import java.util.Collection;
20  import java.util.List;
21  import java.util.Locale;
22  
23  import org.apache.jetspeed.JetspeedActions;
24  import org.apache.jetspeed.om.common.GenericMetadata;
25  import org.apache.jetspeed.om.common.SecurityConstraints;
26  import org.apache.jetspeed.om.page.PageMetadataImpl;
27  import org.apache.jetspeed.om.page.PageSecurity;
28  import org.apache.jetspeed.om.page.psml.AbstractBaseElement;
29  import org.apache.jetspeed.om.page.psml.SecurityConstraintsImpl;
30  import org.apache.jetspeed.page.document.Node;
31  
32  
33  /***
34   * <p>
35   * AbstractNode
36   * </p>
37   * <p>
38   * 
39   * </p>
40   * 
41   * @author <a href="mailto:weaver@apache.org">Scott T. Weaver </a>
42   * @version $Id: AbstractNode.java 551606 2007-06-28 16:07:53Z taylor $
43   *  
44   */
45  public abstract class AbstractNode extends AbstractBaseElement implements Node
46  {
47      private PageMetadataImpl metadata;
48      private Node parent;
49      private String path;
50      private String url;
51      private boolean hidden=false;
52      private String profiledPath;
53      private boolean dirty=false;
54      
55      public AbstractNode()
56      {
57      }
58  
59      /***
60       * getMetadata - get/construct metadata
61       *
62       * @return metadata
63       */
64      public GenericMetadata getMetadata()
65      {
66          return getPageMetadata();
67      }
68  
69      /***
70       * setMetadata - set metadata fields
71       *
72       * @param metadata metadata
73       */
74      public void setMetadata(GenericMetadata metadata)
75      {
76          getPageMetadata().setFields(metadata.getFields());
77      }
78  
79      /***
80       * getMetadataFields - get metadata fields collection for
81       *                     marshalling/unmarshalling
82       *
83       * @return metadata fields collection
84       */
85      public Collection getMetadataFields()
86      {
87          // return metadata fields collection that
88          // may in fact be side effected on unmarshall
89          return getPageMetadata().getFields();
90      }
91  
92      /***
93       * setMetadataFields - set metadata fields collection
94       *
95       * @param metadataFields metadata fields collection
96       */
97      public void setMetadataFields(Collection metadataFields)
98      {
99          // set metadata fields collection that
100         // may in fact be side effected after
101         // invocation on unmarshall
102         getPageMetadata().setFields(metadataFields);
103     }
104 
105     /***
106      * getPageMetadata - get/construct page metadata instance
107      *
108      * @return metadata instance
109      */
110     private PageMetadataImpl getPageMetadata()
111     {
112         if (metadata == null)
113         {
114             metadata = new PageMetadataImpl();
115         }
116         return metadata;
117     }
118 
119     /***
120      * <p>
121      * getTitle
122      * </p>
123      * 
124      * @see org.apache.jetspeed.page.document.Node#getTitle(java.util.Locale)
125      * @param locale
126      * @return title in specified locale
127      */
128     public String getTitle(Locale locale)
129     {
130         // get title from metadata or use default title
131         String title = getPageMetadata().getText("title", locale);
132         if (title == null)
133         {
134             title = getTitle();
135         }
136         return title;
137     }
138 
139     /***
140      * <p>
141      * getShortTitle
142      * </p>
143      * 
144      * @see org.apache.jetspeed.page.document.Node#getShortTitle(java.util.Locale)
145      * @param locale
146      * @return short title in specified locale
147      */
148     public String getShortTitle( Locale locale )
149     {
150         // get short title from metadata or use title from metadata,
151         // default short title, or default title
152         String shortTitle = getPageMetadata().getText("short-title", locale);
153         if (shortTitle == null)
154         {
155             shortTitle = getPageMetadata().getText("title", locale);
156             if (shortTitle == null)
157             {
158                 shortTitle = getShortTitle();
159                 if (shortTitle == null)
160                 {
161                     shortTitle = getTitle();
162                 }
163             }
164         }
165         return shortTitle;
166     }
167 
168     /***
169      * <p>
170      * getParent
171      * </p>
172      * 
173      * @param checkAccess flag
174      * @return parent node
175      */
176     public Node getParent(boolean checkAccess)
177     {
178         AbstractNode parent = (AbstractNode) this.parent;
179 
180         // check access
181         if ((parent != null) && checkAccess)
182         {
183             parent.checkAccess(JetspeedActions.VIEW);
184         }
185         return parent;
186     }
187 
188     /***
189      * <p>
190      * getParent
191      * </p>
192      * 
193      * @see org.apache.jetspeed.page.document.Node#getParent()
194      * @return parent node
195      */
196     public Node getParent()
197     {
198         // by default disable access checks since it is assumed
199         // that by accessing this node, access to parent must
200         // also be granted
201         return getParent(false);
202     }
203 
204     /***
205      * <p>
206      * setParent
207      * </p>
208      * 
209      * @see org.apache.jetspeed.page.document.Node#setParent(Node)
210      * @param parent
211      */
212     public void setParent( Node parent )
213     {
214         this.parent = parent;
215     }
216 
217     /***
218      * <p>
219      * getName
220      * </p>
221      *
222      * @see org.apache.jetspeed.page.document.Node#getName()
223      * @return Name
224      */
225     public String getName()
226     {
227         // simply strip path to determine name
228         String name = getPath();
229         if ((name != null) && !name.equals(PATH_SEPARATOR))
230         {
231             if (name.endsWith(PATH_SEPARATOR))
232             {
233                 name = name.substring(0, name.length()-1);
234             }
235             name = name.substring(name.lastIndexOf(PATH_SEPARATOR)+1);
236         }
237         return name;
238     }
239 
240     /***
241      * getTitleName - get name for use as default titles
242      *
243      * @return title name
244      */
245     public String getTitleName()
246     {
247         String titleName = getName();
248         if (titleName != null)
249         {
250             // transform file system name to title
251             if (titleName.endsWith(getType()))
252             {
253                 titleName = titleName.substring(0, titleName.length()-getType().length());
254             }
255             else if (titleName.equals(PATH_SEPARATOR))
256             {
257                 titleName = "top";
258             }
259             titleName = titleName.replace('_', ' ');
260             titleName = titleName.replace('-', ' ');
261             int wordIndex = -1;
262             do
263             {
264                 if (!Character.isTitleCase(titleName.charAt(wordIndex+1)))
265                 {
266                     StringBuffer makeTitle = new StringBuffer();
267                     makeTitle.append(titleName.substring(0, wordIndex+1));
268                     makeTitle.append(Character.toTitleCase(titleName.charAt(wordIndex+1)));
269                     makeTitle.append(titleName.substring(wordIndex+2));
270                     titleName = makeTitle.toString();
271                 }
272                 wordIndex = titleName.indexOf(' ', wordIndex+1);
273             }
274             while (wordIndex != -1);
275         }
276         return titleName;
277     }
278 
279     /***
280      * @return Returns the path.
281      */
282     public String getPath()
283     {
284         return path;
285     }
286     
287     /***
288      * <p>
289      * setPath
290      * </p>
291      *
292      * @param path The path to set.
293      */
294     public void setPath( String path )
295     {
296         // PSML id is always kept in sync with path, despite how the
297         // id may be loaded from the persistent store
298         this.path = path;
299         setId(path);
300     }
301 
302     /***
303      * <p>
304      * getUrl
305      * </p>
306      * Same as invoking <code>Node.getPath()</code> unless url explicitly set.
307      *
308      * @see org.apache.jetspeed.page.document.Node#getUrl()
309      * @return url as string
310      */
311     public String getUrl()
312     {
313         if (url != null)
314         {
315             return url;
316         }
317         return getPath();
318     }
319 
320     /***
321      * <p>
322      * setUrl
323      * </p>
324      *
325      * @param url The url to set.
326      */
327     public void setUrl( String url )
328     {
329         this.url = url;
330     }
331 
332     /***
333      * <p>
334      * isHidden
335      * </p>
336      *
337      * @see org.apache.jetspeed.page.document.Node#isHidden()
338      * @return hidden
339      */
340     public boolean isHidden()
341     {
342         return hidden;
343     }
344     /***
345      * @param hidden The hidden to set.
346      */
347     public void setHidden( boolean hidden )
348     {
349         this.hidden = hidden;
350     }
351 
352     /***
353      * @return Returns the profiled path.
354      */
355     public String getProfiledPath()
356     {
357         return profiledPath;
358     }
359     /***
360      * @param profiledPath The profiled path to set.
361      */
362     public void setProfiledPath( String profiledPath )
363     {
364         this.profiledPath = profiledPath;
365     }
366 
367     /***
368      * getEffectivePageSecurity
369      *
370      * @see org.apache.jetspeed.om.page.psml.AbstractBaseElement#getEffectivePageSecurity()
371      */
372     public PageSecurity getEffectivePageSecurity()
373     {
374         // by default, delegate to parent node implementation
375         if (parent != null)
376         {
377             return ((AbstractNode)parent).getEffectivePageSecurity();
378         }
379         return null;
380     }
381 
382     /***
383      * <p>
384      * checkConstraints
385      * </p>
386      *
387      * @param actions
388      * @param userPrincipals
389      * @param rolePrincipals
390      * @param groupPrincipals
391      * @param checkNodeOnly
392      * @param checkParentsOnly
393      * @throws SecurityException
394      */
395     public void checkConstraints(List actions, List userPrincipals, List rolePrincipals, List groupPrincipals, boolean checkNodeOnly, boolean checkParentsOnly) throws SecurityException
396     {
397         // check constraints in node hierarchy
398         if (checkNodeOnly)
399         {
400             // check node constraints if available; otherwise,
401             // recursively check parent constraints until
402             // default constraints for node are checked
403             SecurityConstraints constraints = getSecurityConstraints();
404             if ((constraints != null) && !constraints.isEmpty())
405             {
406                 ((SecurityConstraintsImpl)constraints).checkConstraints(actions, userPrincipals, rolePrincipals, groupPrincipals, getEffectivePageSecurity());
407             }
408             else if (parent != null)
409             {
410                 ((AbstractNode)parent).checkConstraints(actions, userPrincipals, rolePrincipals, groupPrincipals, checkNodeOnly, false);
411             }
412         }
413         else
414         {
415             // check node constraints if available and not
416             // to be skipped due to explicity granted access
417             if (!checkParentsOnly)
418             {
419                 SecurityConstraints constraints = getSecurityConstraints();
420                 if ((constraints != null) && !constraints.isEmpty())
421                 {
422                     ((SecurityConstraintsImpl)constraints).checkConstraints(actions, userPrincipals, rolePrincipals, groupPrincipals, getEffectivePageSecurity());
423                 }
424             }
425 
426             // recursively check all parent constraints in hierarchy
427             if (parent != null)
428             {
429                 ((AbstractNode)parent).checkConstraints(actions, userPrincipals, rolePrincipals, groupPrincipals, false, false);
430             }
431         }
432     }
433 
434     /***
435      * <p>
436      * checkPermissions
437      * </p>
438      *
439      * @param path
440      * @param mask Mask of actions requested
441      * @param checkNodeOnly
442      * @param checkParentsOnly
443      * @throws SecurityException
444      */
445     public void checkPermissions(String path, int mask, boolean checkNodeOnly, boolean checkParentsOnly) throws SecurityException
446     {
447         // check granted node permissions unless the check is
448         // to be skipped due to explicity granted access
449         if (!checkParentsOnly)
450         {
451             super.checkPermissions(path, mask, true, false);
452         }
453         
454         // if not checking node only, recursively check
455         // all parent permissions in hierarchy
456         if (!checkNodeOnly && (parent != null))
457         {
458             ((AbstractNode)parent).checkPermissions(mask, false, false);
459         }
460     }
461 
462     /***
463      * <p>
464      * getLogicalPermissionPath
465      * </p>
466      *
467      * @return path used for permissions checks
468      */
469     public String getLogicalPermissionPath()
470     {
471         return profiledPath;
472     }
473 
474     /***
475      * <p>
476      * getPhysicalPermissionPath
477      * </p>
478      *
479      * @return path used for permissions checks
480      */
481     public String getPhysicalPermissionPath()
482     {
483         return path;
484     }
485 
486     /***
487      * unmarshalled - notification that this instance has been
488      *                loaded from the persistent store
489      */
490     public void unmarshalled()
491     {
492         // notify super class implementation
493         super.unmarshalled();
494 
495         // force metadata update after unmarshalled since
496         // metadata collection can be side effected by
497         // unmarshalling colection accessors
498         Collection metadataFields = getMetadataFields();
499         if (metadataFields != null)
500         {
501             setMetadataFields(metadataFields);
502         }
503     }
504 
505 	public boolean isDirty() {
506 		return dirty;
507 	}
508 
509 	public void setDirty(boolean dirty) {
510 		this.dirty=dirty;
511 	}
512     
513     
514 }