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  
18  package org.apache.jetspeed.om.page.psml;
19  
20  import java.security.AccessController;
21  import java.util.ArrayList;
22  import java.util.HashMap;
23  import java.util.Iterator;
24  import java.util.List;
25  import java.util.Map;
26  
27  import org.apache.jetspeed.JetspeedActions;
28  import org.apache.jetspeed.om.folder.Folder;
29  import org.apache.jetspeed.om.page.Fragment;
30  import org.apache.jetspeed.om.page.PageSecurity;
31  import org.apache.jetspeed.security.FragmentPermission;
32  
33  /***
34   * @version $Id: FragmentImpl.java 551606 2007-06-28 16:07:53Z taylor $
35   */
36  public class FragmentImpl extends AbstractBaseElement implements Fragment, java.io.Serializable
37  {
38  
39  	private static int fragment_id_counter = 0;
40  	
41      private String type = null;
42  
43      private String state = null;
44  
45      private String mode = null;
46  
47      private String decorator = null;
48  
49      private String skin = null;
50  
51      private List fragments = new ArrayList();
52  
53      private List propertiesList = new ArrayList();
54      
55      private List preferences = new ArrayList();
56      
57      private Map propertiesMap = new HashMap();
58  
59      private String name;
60  
61      private FragmentList fragmentsList;
62  
63      private PageImpl page;
64  
65      private boolean dirty = false;
66      /***
67       * <p>
68       * Default Constructor.
69       * </p>
70       */
71      public FragmentImpl()
72      {
73      }
74  
75      public FragmentImpl(String id)
76      {
77      	if (id == null || id.length() == 0){
78      		setId(generateId());
79      		dirty=true;
80      	} else {
81      		setId(id);
82      	}    	
83      }
84  
85      public String getType()
86      {
87          return this.type;
88      }
89  
90      public void setType( String type )
91      {
92          this.type = type;
93      }
94  
95      public String getState()
96      {
97          return this.state;
98      }
99  
100     public void setState( String state )
101     {
102         this.state = state;
103     }
104 
105     public String getMode()
106     {
107         return this.mode;
108     }
109 
110     public void setMode( String mode )
111     {
112         this.mode = mode;
113     }
114 
115     public String getDecorator()
116     {
117         return this.decorator;
118     }
119 
120     public void setDecorator( String decoratorName )
121     {
122         this.decorator = decoratorName;
123     }
124 
125     public String getSkin()
126     {
127         return this.skin;
128     }
129 
130     public void setSkin( String skin )
131     {
132         this.skin = skin;
133     }
134 
135     public boolean isReference()
136     {
137         return false;
138     }
139 
140     List accessFragments()
141     {
142         return fragments;
143     }
144 
145     public List getFragments()
146     {
147         // create and return mutable fragments collection
148         // filtered by view access
149         if (fragmentsList == null)
150         {
151             fragmentsList = new FragmentList(this);
152         }
153         return filterFragmentsByAccess(fragmentsList);
154     }
155 
156     public List getPropertiesList()
157     {
158         return (List) this.propertiesList;
159     }
160     
161     /***
162      * @see org.apache.jetspeed.om.page.Fragment#getProperty(java.lang.String)
163      */
164     public String getProperty(String propName)
165     {
166         return (String)propertiesMap.get(propName);
167     }
168     
169     /***
170      * @see org.apache.jetspeed.om.page.Fragment#getIntProperty(java.lang.String)
171      */
172     public int getIntProperty(String propName)
173     {
174         String prop = (String)propertiesMap.get(propName);
175         if (prop != null)
176         {
177             return Integer.parseInt(prop);
178         }
179         return -1;
180     }
181     
182     /***
183      * @see org.apache.jetspeed.om.page.Fragment#getFloatProperty(java.lang.String)
184      */
185     public float getFloatProperty(String propName)
186     {
187         String prop = (String)propertiesMap.get(propName);
188         if (prop != null)
189         {
190             return Float.parseFloat(prop);
191         }
192         return -1.0F;
193     }
194     
195     /***
196      * @see org.apache.jetspeed.om.page.Fragment#getProperties()
197      */
198     public Map getProperties()
199     {
200         return propertiesMap;
201     }
202 
203     /***
204      * @see org.apache.jetspeed.om.page.Fragment#getLayoutRow()
205      */
206     public int getLayoutRow()
207     {
208         return getIntProperty(ROW_PROPERTY_NAME);
209     }
210 
211     /***
212      * @see org.apache.jetspeed.om.page.Fragment#setLayoutRow(int)
213      */
214     public void setLayoutRow(int row)
215     {
216         if (row >= 0)
217         {
218             propertiesMap.put(ROW_PROPERTY_NAME, String.valueOf(row));
219         }
220         else
221         {
222             propertiesMap.remove(ROW_PROPERTY_NAME);
223         }
224     }
225     
226     /***
227      * @see org.apache.jetspeed.om.page.Fragment#getLayoutColumn()
228      */
229     public int getLayoutColumn()
230     {
231         return getIntProperty(COLUMN_PROPERTY_NAME);
232     }
233 
234     /***
235      * @see org.apache.jetspeed.om.page.Fragment#setLayoutColumn(int)
236      */
237     public void setLayoutColumn(int column)
238     {
239         if (column >= 0)
240         {
241             propertiesMap.put(COLUMN_PROPERTY_NAME, String.valueOf(column));
242         }
243         else
244         {
245             propertiesMap.remove(COLUMN_PROPERTY_NAME);
246         }
247     }
248     
249     /***
250      * @see org.apache.jetspeed.om.page.Fragment#getLayoutSizes()
251      */
252     public String getLayoutSizes()
253     {
254         return (String)propertiesMap.get(SIZES_PROPERTY_NAME);
255     }
256     
257     /***
258      * @see org.apache.jetspeed.om.page.Fragment#setLayoutSizes(java.lang.String)
259      */
260     public void setLayoutSizes(String sizes)
261     {
262         if (sizes != null)
263         {
264             propertiesMap.put(SIZES_PROPERTY_NAME, sizes);
265         }
266         else
267         {
268             propertiesMap.remove(SIZES_PROPERTY_NAME);
269         }
270     }
271 
272     /***
273      * @see org.apache.jetspeed.om.page.Fragment#getLayoutX()
274      */
275     public float getLayoutX()
276     {
277         return getFloatProperty(X_PROPERTY_NAME);
278     }
279 
280     /***
281      * @see org.apache.jetspeed.om.page.Fragment#setLayoutX(float)
282      */
283     public void setLayoutX(float x)
284     {
285         if (x >= 0.0F)
286         {
287             propertiesMap.put(X_PROPERTY_NAME, String.valueOf(x));
288         }
289         else
290         {
291             propertiesMap.remove(X_PROPERTY_NAME);
292         }
293     }
294     
295     /***
296      * @see org.apache.jetspeed.om.page.Fragment#getLayoutY()
297      */
298     public float getLayoutY()
299     {
300         return getFloatProperty(Y_PROPERTY_NAME);
301     }
302 
303     /***
304      * @see org.apache.jetspeed.om.page.Fragment#setLayoutY(float)
305      */
306     public void setLayoutY(float y)
307     {
308         if (y >= 0.0F)
309         {
310             propertiesMap.put(Y_PROPERTY_NAME, String.valueOf(y));
311         }
312         else
313         {
314             propertiesMap.remove(Y_PROPERTY_NAME);
315         }
316     }
317 
318     /***
319      * @see org.apache.jetspeed.om.page.Fragment#getLayoutZ()
320      */
321     public float getLayoutZ()
322     {
323         return getFloatProperty(Z_PROPERTY_NAME);
324     }
325 
326     /***
327      * @see org.apache.jetspeed.om.page.Fragment#setLayoutZ(float)
328      */
329     public void setLayoutZ(float z)
330     {
331         if (z >= 0.0F)
332         {
333             propertiesMap.put(Z_PROPERTY_NAME, String.valueOf(z));
334         }
335         else
336         {
337             propertiesMap.remove(Z_PROPERTY_NAME);
338         }
339     }
340 
341     /***
342      * @see org.apache.jetspeed.om.page.Fragment#getLayoutWidth()
343      */
344     public float getLayoutWidth()
345     {
346         return getFloatProperty(WIDTH_PROPERTY_NAME);
347     }
348 
349     /***
350      * @see org.apache.jetspeed.om.page.Fragment#setLayoutWidth(float)
351      */
352     public void setLayoutWidth(float width)
353     {
354         if (width >= 0.0F)
355         {
356             propertiesMap.put(WIDTH_PROPERTY_NAME, String.valueOf(width));
357         }
358         else
359         {
360             propertiesMap.remove(WIDTH_PROPERTY_NAME);
361         }
362     }
363 
364     /***
365      * @see org.apache.jetspeed.om.page.Fragment#getLayoutHeight()
366      */
367     public float getLayoutHeight()
368     {
369         return getFloatProperty(HEIGHT_PROPERTY_NAME);
370     }
371 
372     /***
373      * @see org.apache.jetspeed.om.page.Fragment#setLayoutHeight(float)
374      */
375     public void setLayoutHeight(float height)
376     {
377         if (height >= 0.0F)
378         {
379             propertiesMap.put(HEIGHT_PROPERTY_NAME, String.valueOf(height));
380         }
381         else
382         {
383             propertiesMap.remove(HEIGHT_PROPERTY_NAME);
384         }
385     }
386 
387     /***
388      * <p>
389      * equals
390      * </p>
391      * 
392      * @see java.lang.Object#equals(java.lang.Object)
393      * @param obj
394      * @return
395      */
396     public boolean equals( Object obj )
397     {
398         boolean isEqual = false;
399         if (obj != null && obj instanceof Fragment)
400         {
401             Fragment aFragment = (Fragment) obj;
402             if ((null != aFragment.getId()) && (null != getId()) && (getId().equals(aFragment.getId())))
403             {
404                 isEqual = true;
405             }
406         }
407         return isEqual;
408     }
409 
410     /***
411      * <p>
412      * hashCode
413      * </p>
414      * 
415      * @see java.lang.Object#hashCode()
416      * @return
417      */
418     public int hashCode()
419     {
420         if (getId() != null)
421         {
422             return (Fragment.class.getName() + ":" + getId()).hashCode();
423         }
424         else
425         {
426             return super.hashCode();
427         }
428     }
429 
430     /***
431      * <p>
432      * getName
433      * </p>
434      * 
435      * @see org.apache.jetspeed.om.page.Fragment#getName()
436      * @return
437      */
438     public String getName()
439     {
440         return name;
441     }
442 
443     /***
444      * <p>
445      * setName
446      * </p>
447      * 
448      * @see org.apache.jetspeed.om.page.Fragment#setName(java.lang.String)
449      * @param name
450      */
451     public void setName( String name )
452     {
453         this.name = name;
454 
455     }
456 
457     /***
458      * <p>
459      * getPreferences
460      * </p>
461      * 
462      * @see org.apache.jetspeed.om.page.Fragment#getPreferences()
463      * @param name
464      */
465     public List getPreferences()
466     {
467         return preferences;
468     }
469 
470     public void setPreferences(List preferences)
471     {
472         this.preferences = preferences;  
473     } 
474     
475     PageImpl getPage()
476     {
477         return page;
478     }
479 
480     void setPage(PageImpl page)
481     {
482         // set page implementation
483         this.page = page;
484         if (dirty){
485         	page.setDirty(dirty);	
486         }        
487         // propagate to children
488         if (fragments != null)
489         {
490             Iterator fragmentsIter = fragments.iterator();
491             while (fragmentsIter.hasNext())
492             {
493                 ((FragmentImpl)fragmentsIter.next()).setPage(page);
494             }
495         }
496     }
497 
498     /* (non-Javadoc)
499      * @see org.apache.jetspeed.om.page.psml.AbstractElementImpl#getEffectivePageSecurity()
500      */
501     public PageSecurity getEffectivePageSecurity()
502     {
503         // delegate to page implementation
504         if (page != null)
505         {
506             return page.getEffectivePageSecurity();
507         }
508         return null;
509     }
510 
511     /* (non-Javadoc)
512      * @see org.apache.jetspeed.om.page.psml.AbstractElementImpl#getLogicalPermissionPath()
513      */
514     public String getLogicalPermissionPath()
515     {
516         // use page implementation path as base and append name
517         if ((page != null) && (getName() != null))
518         {
519             return page.getLogicalPermissionPath() + Folder.PATH_SEPARATOR + getName();
520         }
521         return null;
522     }
523 
524     /* (non-Javadoc)
525      * @see org.apache.jetspeed.om.page.psml.AbstractBaseElementImpl#getPhysicalPermissionPath()
526      */
527     public String getPhysicalPermissionPath()
528     {
529         // use page implementation path as base and append name
530         if ((page != null) && (getName() != null))
531         {
532             return page.getPhysicalPermissionPath() + Folder.PATH_SEPARATOR + getName();
533         }
534         return null;
535     }
536 
537     /* (non-Javadoc)
538      * @see org.apache.jetspeed.om.page.psml.AbstractElementImpl#checkPermissions(java.lang.String, int, boolean, boolean)
539      */
540     public void checkPermissions(String path, int mask, boolean checkNodeOnly, boolean checkParentsOnly) throws SecurityException
541     {
542         // always check for granted fragment permissions
543         FragmentPermission permission = new FragmentPermission(path, mask);
544         AccessController.checkPermission(permission);
545     }
546 
547     /* (non-Javadoc)
548      * @see org.apache.jetspeed.om.common.SecuredResource#getConstraintsEnabled()
549      */
550     public boolean getConstraintsEnabled()
551     {
552         if (page != null)
553         {
554             return page.getConstraintsEnabled();
555         }
556         return false;
557     }
558     
559     /* (non-Javadoc)
560      * @see org.apache.jetspeed.om.common.SecuredResource#getPermissionsEnabled()
561      */
562     public boolean getPermissionsEnabled()
563     {
564         if (page != null)
565         {
566             return page.getPermissionsEnabled();
567         }
568         return false;
569     }
570 
571     /***
572      * unmarshalled - notification that this instance has been
573      *                loaded from the persistent store
574      */
575     public void unmarshalled()
576     {
577         // notify super class implementation
578         super.unmarshalled();
579 
580         // propagate unmarshalled notification
581         // to all fragments
582         Iterator fragmentIter = fragments.iterator();
583         while (fragmentIter.hasNext())
584         {
585             ((FragmentImpl)fragmentIter.next()).unmarshalled();
586         }
587 
588         // load the properties map from list
589         propertiesMap.clear();
590         Iterator propsIter = propertiesList.iterator();
591         while (propsIter.hasNext())
592         {
593             PropertyImpl prop = (PropertyImpl) propsIter.next();
594             propertiesMap.put(prop.getName(), prop.getValue());
595         }
596     }
597 
598     /***
599      * marshalling - notification that this instance is to
600      *               be saved to the persistent store
601      */
602     public void marshalling()
603     {
604         // update the properties list from the map
605         // if change/edit detected
606         boolean changed = (propertiesMap.size() != propertiesList.size());
607         if (!changed)
608         {
609             Iterator propsIter = propertiesList.iterator();
610             while (!changed && propsIter.hasNext())
611             {
612                 PropertyImpl prop = (PropertyImpl) propsIter.next();
613                 changed = (prop.getValue() != propertiesMap.get(prop.getName()));
614             }
615         }
616         if (changed)
617         {
618             propertiesList.clear();
619             Iterator propsIter = propertiesMap.entrySet().iterator();
620             while (propsIter.hasNext())
621             {
622                 Map.Entry prop = (Map.Entry) propsIter.next();
623                 PropertyImpl listProp = new PropertyImpl();
624                 listProp.setName((String)prop.getKey());
625                 listProp.setValue((String)prop.getValue());
626                 propertiesList.add(listProp);
627             }
628         }
629 
630         // propagate marshalling notification
631         // to all fragments
632         Iterator fragmentIter = fragments.iterator();
633         while (fragmentIter.hasNext())
634         {
635             ((FragmentImpl)fragmentIter.next()).marshalling();
636         }
637 
638         // notify super class implementation
639         super.marshalling();
640     }
641 
642     /***
643      * filterFragmentsByAccess
644      *
645      * Filter fragments list for view access.
646      *
647      * @param nodes list containing fragments to check
648      * @return original list if all elements viewable, a filtered
649      *         partial list, or null if all filtered for view access
650      */
651     List filterFragmentsByAccess(List fragments)
652     {
653         if ((fragments != null) && !fragments.isEmpty())
654         {
655             // check permissions and constraints, filter fragments as required
656             List filteredFragments = null;
657             Iterator checkAccessIter = fragments.iterator();
658             while (checkAccessIter.hasNext())
659             {
660                 Fragment fragment = (Fragment) checkAccessIter.next();
661                 try
662                 {
663                     // check access
664                     fragment.checkAccess(JetspeedActions.VIEW);
665 
666                     // add to filteredFragments fragments if copying
667                     if (filteredFragments != null)
668                     {
669                         // permitted, add to filteredFragments fragments
670                         filteredFragments.add(fragment);
671                     }
672                 }
673                 catch (SecurityException se)
674                 {
675                     // create filteredFragments fragments if not already copying
676                     if (filteredFragments == null)
677                     {
678                         // not permitted, copy previously permitted fragments
679                         // to new filteredFragments node set with same comparator
680                         filteredFragments = new ArrayList(fragments.size());
681                         Iterator copyIter = fragments.iterator();
682                         while (copyIter.hasNext())
683                         {
684                             Fragment copyFragment = (Fragment)copyIter.next();
685                             if (copyFragment != fragment)
686                             {
687                                 filteredFragments.add(copyFragment);
688                             }
689                             else
690                             {
691                                 break;
692                             }
693                         }
694                     }
695                 }
696             }
697 
698             // return filteredFragments fragments if generated
699             if (filteredFragments != null)
700             {
701                 // patch for JS2-633, security filtered (permission) lists
702                 // were returning null, we need an empty fragment list 
703                 return new FilteredFragmentList(this, filteredFragments);
704             }
705         }
706         return fragments;
707     }
708     
709     private synchronized static String generateId(){
710     	return new StringBuffer("F.").append(Long.toHexString(System.currentTimeMillis())).append(".").append(fragment_id_counter++).toString();
711     }
712 }