001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: package org.apache.jetspeed.om.page.psml;
019:
020: import java.security.AccessController;
021: import java.util.ArrayList;
022: import java.util.HashMap;
023: import java.util.Iterator;
024: import java.util.List;
025: import java.util.Map;
026:
027: import org.apache.jetspeed.JetspeedActions;
028: import org.apache.jetspeed.om.folder.Folder;
029: import org.apache.jetspeed.om.page.Fragment;
030: import org.apache.jetspeed.om.page.PageSecurity;
031: import org.apache.jetspeed.security.FragmentPermission;
032:
033: /**
034: * @version $Id: FragmentImpl.java 551606 2007-06-28 16:07:53Z taylor $
035: */
036: public class FragmentImpl extends AbstractBaseElement implements
037: Fragment, java.io.Serializable {
038:
039: private static int fragment_id_counter = 0;
040:
041: private String type = null;
042:
043: private String state = null;
044:
045: private String mode = null;
046:
047: private String decorator = null;
048:
049: private String skin = null;
050:
051: private List fragments = new ArrayList();
052:
053: private List propertiesList = new ArrayList();
054:
055: private List preferences = new ArrayList();
056:
057: private Map propertiesMap = new HashMap();
058:
059: private String name;
060:
061: private FragmentList fragmentsList;
062:
063: private PageImpl page;
064:
065: private boolean dirty = false;
066:
067: /**
068: * <p>
069: * Default Constructor.
070: * </p>
071: */
072: public FragmentImpl() {
073: }
074:
075: public FragmentImpl(String id) {
076: if (id == null || id.length() == 0) {
077: setId(generateId());
078: dirty = true;
079: } else {
080: setId(id);
081: }
082: }
083:
084: public String getType() {
085: return this .type;
086: }
087:
088: public void setType(String type) {
089: this .type = type;
090: }
091:
092: public String getState() {
093: return this .state;
094: }
095:
096: public void setState(String state) {
097: this .state = state;
098: }
099:
100: public String getMode() {
101: return this .mode;
102: }
103:
104: public void setMode(String mode) {
105: this .mode = mode;
106: }
107:
108: public String getDecorator() {
109: return this .decorator;
110: }
111:
112: public void setDecorator(String decoratorName) {
113: this .decorator = decoratorName;
114: }
115:
116: public String getSkin() {
117: return this .skin;
118: }
119:
120: public void setSkin(String skin) {
121: this .skin = skin;
122: }
123:
124: public boolean isReference() {
125: return false;
126: }
127:
128: List accessFragments() {
129: return fragments;
130: }
131:
132: public List getFragments() {
133: // create and return mutable fragments collection
134: // filtered by view access
135: if (fragmentsList == null) {
136: fragmentsList = new FragmentList(this );
137: }
138: return filterFragmentsByAccess(fragmentsList);
139: }
140:
141: public List getPropertiesList() {
142: return (List) this .propertiesList;
143: }
144:
145: /**
146: * @see org.apache.jetspeed.om.page.Fragment#getProperty(java.lang.String)
147: */
148: public String getProperty(String propName) {
149: return (String) propertiesMap.get(propName);
150: }
151:
152: /**
153: * @see org.apache.jetspeed.om.page.Fragment#getIntProperty(java.lang.String)
154: */
155: public int getIntProperty(String propName) {
156: String prop = (String) propertiesMap.get(propName);
157: if (prop != null) {
158: return Integer.parseInt(prop);
159: }
160: return -1;
161: }
162:
163: /**
164: * @see org.apache.jetspeed.om.page.Fragment#getFloatProperty(java.lang.String)
165: */
166: public float getFloatProperty(String propName) {
167: String prop = (String) propertiesMap.get(propName);
168: if (prop != null) {
169: return Float.parseFloat(prop);
170: }
171: return -1.0F;
172: }
173:
174: /**
175: * @see org.apache.jetspeed.om.page.Fragment#getProperties()
176: */
177: public Map getProperties() {
178: return propertiesMap;
179: }
180:
181: /**
182: * @see org.apache.jetspeed.om.page.Fragment#getLayoutRow()
183: */
184: public int getLayoutRow() {
185: return getIntProperty(ROW_PROPERTY_NAME);
186: }
187:
188: /**
189: * @see org.apache.jetspeed.om.page.Fragment#setLayoutRow(int)
190: */
191: public void setLayoutRow(int row) {
192: if (row >= 0) {
193: propertiesMap.put(ROW_PROPERTY_NAME, String.valueOf(row));
194: } else {
195: propertiesMap.remove(ROW_PROPERTY_NAME);
196: }
197: }
198:
199: /**
200: * @see org.apache.jetspeed.om.page.Fragment#getLayoutColumn()
201: */
202: public int getLayoutColumn() {
203: return getIntProperty(COLUMN_PROPERTY_NAME);
204: }
205:
206: /**
207: * @see org.apache.jetspeed.om.page.Fragment#setLayoutColumn(int)
208: */
209: public void setLayoutColumn(int column) {
210: if (column >= 0) {
211: propertiesMap.put(COLUMN_PROPERTY_NAME, String
212: .valueOf(column));
213: } else {
214: propertiesMap.remove(COLUMN_PROPERTY_NAME);
215: }
216: }
217:
218: /**
219: * @see org.apache.jetspeed.om.page.Fragment#getLayoutSizes()
220: */
221: public String getLayoutSizes() {
222: return (String) propertiesMap.get(SIZES_PROPERTY_NAME);
223: }
224:
225: /**
226: * @see org.apache.jetspeed.om.page.Fragment#setLayoutSizes(java.lang.String)
227: */
228: public void setLayoutSizes(String sizes) {
229: if (sizes != null) {
230: propertiesMap.put(SIZES_PROPERTY_NAME, sizes);
231: } else {
232: propertiesMap.remove(SIZES_PROPERTY_NAME);
233: }
234: }
235:
236: /**
237: * @see org.apache.jetspeed.om.page.Fragment#getLayoutX()
238: */
239: public float getLayoutX() {
240: return getFloatProperty(X_PROPERTY_NAME);
241: }
242:
243: /**
244: * @see org.apache.jetspeed.om.page.Fragment#setLayoutX(float)
245: */
246: public void setLayoutX(float x) {
247: if (x >= 0.0F) {
248: propertiesMap.put(X_PROPERTY_NAME, String.valueOf(x));
249: } else {
250: propertiesMap.remove(X_PROPERTY_NAME);
251: }
252: }
253:
254: /**
255: * @see org.apache.jetspeed.om.page.Fragment#getLayoutY()
256: */
257: public float getLayoutY() {
258: return getFloatProperty(Y_PROPERTY_NAME);
259: }
260:
261: /**
262: * @see org.apache.jetspeed.om.page.Fragment#setLayoutY(float)
263: */
264: public void setLayoutY(float y) {
265: if (y >= 0.0F) {
266: propertiesMap.put(Y_PROPERTY_NAME, String.valueOf(y));
267: } else {
268: propertiesMap.remove(Y_PROPERTY_NAME);
269: }
270: }
271:
272: /**
273: * @see org.apache.jetspeed.om.page.Fragment#getLayoutZ()
274: */
275: public float getLayoutZ() {
276: return getFloatProperty(Z_PROPERTY_NAME);
277: }
278:
279: /**
280: * @see org.apache.jetspeed.om.page.Fragment#setLayoutZ(float)
281: */
282: public void setLayoutZ(float z) {
283: if (z >= 0.0F) {
284: propertiesMap.put(Z_PROPERTY_NAME, String.valueOf(z));
285: } else {
286: propertiesMap.remove(Z_PROPERTY_NAME);
287: }
288: }
289:
290: /**
291: * @see org.apache.jetspeed.om.page.Fragment#getLayoutWidth()
292: */
293: public float getLayoutWidth() {
294: return getFloatProperty(WIDTH_PROPERTY_NAME);
295: }
296:
297: /**
298: * @see org.apache.jetspeed.om.page.Fragment#setLayoutWidth(float)
299: */
300: public void setLayoutWidth(float width) {
301: if (width >= 0.0F) {
302: propertiesMap.put(WIDTH_PROPERTY_NAME, String
303: .valueOf(width));
304: } else {
305: propertiesMap.remove(WIDTH_PROPERTY_NAME);
306: }
307: }
308:
309: /**
310: * @see org.apache.jetspeed.om.page.Fragment#getLayoutHeight()
311: */
312: public float getLayoutHeight() {
313: return getFloatProperty(HEIGHT_PROPERTY_NAME);
314: }
315:
316: /**
317: * @see org.apache.jetspeed.om.page.Fragment#setLayoutHeight(float)
318: */
319: public void setLayoutHeight(float height) {
320: if (height >= 0.0F) {
321: propertiesMap.put(HEIGHT_PROPERTY_NAME, String
322: .valueOf(height));
323: } else {
324: propertiesMap.remove(HEIGHT_PROPERTY_NAME);
325: }
326: }
327:
328: /**
329: * <p>
330: * equals
331: * </p>
332: *
333: * @see java.lang.Object#equals(java.lang.Object)
334: * @param obj
335: * @return
336: */
337: public boolean equals(Object obj) {
338: boolean isEqual = false;
339: if (obj != null && obj instanceof Fragment) {
340: Fragment aFragment = (Fragment) obj;
341: if ((null != aFragment.getId()) && (null != getId())
342: && (getId().equals(aFragment.getId()))) {
343: isEqual = true;
344: }
345: }
346: return isEqual;
347: }
348:
349: /**
350: * <p>
351: * hashCode
352: * </p>
353: *
354: * @see java.lang.Object#hashCode()
355: * @return
356: */
357: public int hashCode() {
358: if (getId() != null) {
359: return (Fragment.class.getName() + ":" + getId())
360: .hashCode();
361: } else {
362: return super .hashCode();
363: }
364: }
365:
366: /**
367: * <p>
368: * getName
369: * </p>
370: *
371: * @see org.apache.jetspeed.om.page.Fragment#getName()
372: * @return
373: */
374: public String getName() {
375: return name;
376: }
377:
378: /**
379: * <p>
380: * setName
381: * </p>
382: *
383: * @see org.apache.jetspeed.om.page.Fragment#setName(java.lang.String)
384: * @param name
385: */
386: public void setName(String name) {
387: this .name = name;
388:
389: }
390:
391: /**
392: * <p>
393: * getPreferences
394: * </p>
395: *
396: * @see org.apache.jetspeed.om.page.Fragment#getPreferences()
397: * @param name
398: */
399: public List getPreferences() {
400: return preferences;
401: }
402:
403: public void setPreferences(List preferences) {
404: this .preferences = preferences;
405: }
406:
407: PageImpl getPage() {
408: return page;
409: }
410:
411: void setPage(PageImpl page) {
412: // set page implementation
413: this .page = page;
414: if (dirty) {
415: page.setDirty(dirty);
416: }
417: // propagate to children
418: if (fragments != null) {
419: Iterator fragmentsIter = fragments.iterator();
420: while (fragmentsIter.hasNext()) {
421: ((FragmentImpl) fragmentsIter.next()).setPage(page);
422: }
423: }
424: }
425:
426: /* (non-Javadoc)
427: * @see org.apache.jetspeed.om.page.psml.AbstractElementImpl#getEffectivePageSecurity()
428: */
429: public PageSecurity getEffectivePageSecurity() {
430: // delegate to page implementation
431: if (page != null) {
432: return page.getEffectivePageSecurity();
433: }
434: return null;
435: }
436:
437: /* (non-Javadoc)
438: * @see org.apache.jetspeed.om.page.psml.AbstractElementImpl#getLogicalPermissionPath()
439: */
440: public String getLogicalPermissionPath() {
441: // use page implementation path as base and append name
442: if ((page != null) && (getName() != null)) {
443: return page.getLogicalPermissionPath()
444: + Folder.PATH_SEPARATOR + getName();
445: }
446: return null;
447: }
448:
449: /* (non-Javadoc)
450: * @see org.apache.jetspeed.om.page.psml.AbstractBaseElementImpl#getPhysicalPermissionPath()
451: */
452: public String getPhysicalPermissionPath() {
453: // use page implementation path as base and append name
454: if ((page != null) && (getName() != null)) {
455: return page.getPhysicalPermissionPath()
456: + Folder.PATH_SEPARATOR + getName();
457: }
458: return null;
459: }
460:
461: /* (non-Javadoc)
462: * @see org.apache.jetspeed.om.page.psml.AbstractElementImpl#checkPermissions(java.lang.String, int, boolean, boolean)
463: */
464: public void checkPermissions(String path, int mask,
465: boolean checkNodeOnly, boolean checkParentsOnly)
466: throws SecurityException {
467: // always check for granted fragment permissions
468: FragmentPermission permission = new FragmentPermission(path,
469: mask);
470: AccessController.checkPermission(permission);
471: }
472:
473: /* (non-Javadoc)
474: * @see org.apache.jetspeed.om.common.SecuredResource#getConstraintsEnabled()
475: */
476: public boolean getConstraintsEnabled() {
477: if (page != null) {
478: return page.getConstraintsEnabled();
479: }
480: return false;
481: }
482:
483: /* (non-Javadoc)
484: * @see org.apache.jetspeed.om.common.SecuredResource#getPermissionsEnabled()
485: */
486: public boolean getPermissionsEnabled() {
487: if (page != null) {
488: return page.getPermissionsEnabled();
489: }
490: return false;
491: }
492:
493: /**
494: * unmarshalled - notification that this instance has been
495: * loaded from the persistent store
496: */
497: public void unmarshalled() {
498: // notify super class implementation
499: super .unmarshalled();
500:
501: // propagate unmarshalled notification
502: // to all fragments
503: Iterator fragmentIter = fragments.iterator();
504: while (fragmentIter.hasNext()) {
505: ((FragmentImpl) fragmentIter.next()).unmarshalled();
506: }
507:
508: // load the properties map from list
509: propertiesMap.clear();
510: Iterator propsIter = propertiesList.iterator();
511: while (propsIter.hasNext()) {
512: PropertyImpl prop = (PropertyImpl) propsIter.next();
513: propertiesMap.put(prop.getName(), prop.getValue());
514: }
515: }
516:
517: /**
518: * marshalling - notification that this instance is to
519: * be saved to the persistent store
520: */
521: public void marshalling() {
522: // update the properties list from the map
523: // if change/edit detected
524: boolean changed = (propertiesMap.size() != propertiesList
525: .size());
526: if (!changed) {
527: Iterator propsIter = propertiesList.iterator();
528: while (!changed && propsIter.hasNext()) {
529: PropertyImpl prop = (PropertyImpl) propsIter.next();
530: changed = (prop.getValue() != propertiesMap.get(prop
531: .getName()));
532: }
533: }
534: if (changed) {
535: propertiesList.clear();
536: Iterator propsIter = propertiesMap.entrySet().iterator();
537: while (propsIter.hasNext()) {
538: Map.Entry prop = (Map.Entry) propsIter.next();
539: PropertyImpl listProp = new PropertyImpl();
540: listProp.setName((String) prop.getKey());
541: listProp.setValue((String) prop.getValue());
542: propertiesList.add(listProp);
543: }
544: }
545:
546: // propagate marshalling notification
547: // to all fragments
548: Iterator fragmentIter = fragments.iterator();
549: while (fragmentIter.hasNext()) {
550: ((FragmentImpl) fragmentIter.next()).marshalling();
551: }
552:
553: // notify super class implementation
554: super .marshalling();
555: }
556:
557: /**
558: * filterFragmentsByAccess
559: *
560: * Filter fragments list for view access.
561: *
562: * @param nodes list containing fragments to check
563: * @return original list if all elements viewable, a filtered
564: * partial list, or null if all filtered for view access
565: */
566: List filterFragmentsByAccess(List fragments) {
567: if ((fragments != null) && !fragments.isEmpty()) {
568: // check permissions and constraints, filter fragments as required
569: List filteredFragments = null;
570: Iterator checkAccessIter = fragments.iterator();
571: while (checkAccessIter.hasNext()) {
572: Fragment fragment = (Fragment) checkAccessIter.next();
573: try {
574: // check access
575: fragment.checkAccess(JetspeedActions.VIEW);
576:
577: // add to filteredFragments fragments if copying
578: if (filteredFragments != null) {
579: // permitted, add to filteredFragments fragments
580: filteredFragments.add(fragment);
581: }
582: } catch (SecurityException se) {
583: // create filteredFragments fragments if not already copying
584: if (filteredFragments == null) {
585: // not permitted, copy previously permitted fragments
586: // to new filteredFragments node set with same comparator
587: filteredFragments = new ArrayList(fragments
588: .size());
589: Iterator copyIter = fragments.iterator();
590: while (copyIter.hasNext()) {
591: Fragment copyFragment = (Fragment) copyIter
592: .next();
593: if (copyFragment != fragment) {
594: filteredFragments.add(copyFragment);
595: } else {
596: break;
597: }
598: }
599: }
600: }
601: }
602:
603: // return filteredFragments fragments if generated
604: if (filteredFragments != null) {
605: // patch for JS2-633, security filtered (permission) lists
606: // were returning null, we need an empty fragment list
607: return new FilteredFragmentList(this , filteredFragments);
608: }
609: }
610: return fragments;
611: }
612:
613: private synchronized static String generateId() {
614: return new StringBuffer("F.").append(
615: Long.toHexString(System.currentTimeMillis())).append(
616: ".").append(fragment_id_counter++).toString();
617: }
618: }
|