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.util.HashMap;
021: import java.util.Iterator;
022: import java.util.List;
023: import java.util.Map;
024: import java.util.Stack;
025:
026: import org.apache.jetspeed.om.folder.Folder;
027: import org.apache.jetspeed.om.folder.MenuDefinition;
028: import org.apache.jetspeed.om.folder.MenuExcludeDefinition;
029: import org.apache.jetspeed.om.folder.MenuIncludeDefinition;
030: import org.apache.jetspeed.om.folder.MenuOptionsDefinition;
031: import org.apache.jetspeed.om.folder.MenuSeparatorDefinition;
032: import org.apache.jetspeed.om.folder.psml.MenuDefinitionImpl;
033: import org.apache.jetspeed.om.folder.psml.MenuExcludeDefinitionImpl;
034: import org.apache.jetspeed.om.folder.psml.MenuIncludeDefinitionImpl;
035: import org.apache.jetspeed.om.folder.psml.MenuOptionsDefinitionImpl;
036: import org.apache.jetspeed.om.folder.psml.MenuSeparatorDefinitionImpl;
037: import org.apache.jetspeed.om.page.Fragment;
038: import org.apache.jetspeed.om.page.Page;
039: import org.apache.jetspeed.page.impl.DatabasePageManagerUtils;
040:
041: /**
042: * @version $Id: PageImpl.java 550655 2007-06-26 01:41:35Z taylor $
043: */
044: public class PageImpl extends DocumentImpl implements Page {
045: private DefaultsImpl defaults = new DefaultsImpl();
046:
047: private Fragment root = null;
048:
049: private int hashCode;
050:
051: /**
052: * menuDefinitions - menu definitions for page
053: */
054: private List menuDefinitions;
055:
056: public PageImpl() {
057: // empty constructor
058: super ();
059: }
060:
061: /**
062: * <p>
063: * setId
064: * </p>
065: *
066: * @see org.apache.jetspeed.om.page.psml.AbstractBaseElement#setId(java.lang.String)
067: * @param id
068: */
069: public void setId(String id) {
070: // Cheaper to generate the hash code now then every call to hashCode()
071: hashCode = (Page.class.getName() + ":" + id).hashCode();
072: super .setId(id);
073: }
074:
075: /**
076: * <p>
077: * equals
078: * </p>
079: *
080: * @see java.lang.Object#equals(java.lang.Object)
081: * @param obj
082: * @return
083: */
084: public boolean equals(Object obj) {
085: if (obj instanceof Page) {
086: Page page = (Page) obj;
087: return page != null && page.getId() != null
088: && this .getId() != null
089: && this .getId().equals(page.getId());
090: } else {
091: return false;
092: }
093:
094: }
095:
096: /**
097: * <p>
098: * hashCode
099: * </p>
100: *
101: * @see java.lang.Object#hashCode()
102: * @return
103: */
104: public int hashCode() {
105: return hashCode;
106: }
107:
108: public String getSkin() {
109: return defaults.getSkin();
110: }
111:
112: public void setSkin(String skinName) {
113: defaults.setSkin(skinName);
114: }
115:
116: /* (non-Javadoc)
117: * @see org.apache.jetspeed.om.page.Page#getEffectiveDefaultDecorator(java.lang.String)
118: */
119: public String getEffectiveDefaultDecorator(String fragmentType) {
120: // get locally defined decorator
121: String decorator = getDefaultDecorator(fragmentType);
122: if (decorator == null) {
123: // delegate to parent folder
124: Folder parentFolder = (Folder) getParent();
125: if (parentFolder != null) {
126: return parentFolder
127: .getEffectiveDefaultDecorator(fragmentType);
128: }
129: }
130: return decorator;
131: }
132:
133: public String getDefaultDecorator(String fragmentType) {
134: return defaults.getDecorator(fragmentType);
135: }
136:
137: public void setDefaultDecorator(String decoratorName,
138: String fragmentType) {
139: defaults.setDecorator(fragmentType, decoratorName);
140: }
141:
142: public Fragment getRootFragment() {
143: return this .root;
144: }
145:
146: public void setRootFragment(Fragment root) {
147: this .root = root;
148: if (root instanceof FragmentImpl) {
149: ((FragmentImpl) root).setPage(this );
150: }
151: }
152:
153: public Fragment getFragmentById(String id) {
154: Stack stack = new Stack();
155: if (getRootFragment() != null) {
156: stack.push(getRootFragment());
157: }
158:
159: Fragment f = (Fragment) stack.pop();
160:
161: while ((f != null) && (!(f.getId().equals(id)))) {
162: Iterator i = f.getFragments().iterator();
163:
164: while (i.hasNext()) {
165: stack.push(i.next());
166: }
167:
168: if (stack.size() > 0) {
169: f = (Fragment) stack.pop();
170: } else {
171: f = null;
172: }
173: }
174:
175: return f;
176: }
177:
178: public Fragment removeFragmentById(String id) {
179: // find fragment by id, tracking fragment parent
180: Map parents = new HashMap();
181: Stack stack = new Stack();
182: if (getRootFragment() != null) {
183: stack.push(getRootFragment());
184: }
185: Fragment f = (Fragment) stack.pop();
186: while ((f != null) && (!(f.getId().equals(id)))) {
187: Iterator i = f.getFragments().iterator();
188:
189: while (i.hasNext()) {
190: Fragment child = (Fragment) i.next();
191: stack.push(child);
192: parents.put(child, f);
193: }
194:
195: if (stack.size() > 0) {
196: f = (Fragment) stack.pop();
197: } else {
198: f = null;
199: }
200: }
201:
202: // remove fragment from parent/page root
203: if (f != null) {
204: Fragment parent = (Fragment) parents.get(f);
205: if (parent != null) {
206: if (parent.getFragments().remove(f)) {
207: return f;
208: }
209: } else {
210: if (f == root) {
211: root = null;
212: return f;
213: }
214: }
215: }
216:
217: // not found or removed
218: return null;
219: }
220:
221: public List getFragmentsByName(String name) {
222: List fragments = DatabasePageManagerUtils.createList();
223:
224: Stack stack = new Stack();
225: if (getRootFragment() != null) {
226: stack.push(getRootFragment());
227: }
228:
229: Fragment f = (Fragment) stack.pop();
230:
231: while (f != null) {
232: if ((f.getName() != null) && f.getName().equals(name)) {
233: fragments.add(f);
234: }
235:
236: Iterator i = f.getFragments().iterator();
237:
238: while (i.hasNext()) {
239: stack.push(i.next());
240: }
241:
242: if (stack.size() > 0) {
243: f = (Fragment) stack.pop();
244: } else {
245: f = null;
246: }
247: }
248:
249: return fragments;
250: }
251:
252: public DefaultsImpl getDefaults() {
253: return this .defaults;
254: }
255:
256: public void setDefaults(DefaultsImpl defaults) {
257: this .defaults = defaults;
258: }
259:
260: /**
261: * <p>
262: * getType
263: * </p>
264: *
265: * @see org.apache.jetspeed.om.page.Document#getType()
266: * @return
267: */
268: public String getType() {
269: return DOCUMENT_TYPE;
270: }
271:
272: /**
273: * getMenuDefinitions - get list of menu definitions
274: *
275: * @return definition list
276: */
277: public List getMenuDefinitions() {
278: return menuDefinitions;
279: }
280:
281: /**
282: * newMenuDefinition - creates a new empty menu definition
283: *
284: * @return a newly created MenuDefinition object for use in Page
285: */
286: public MenuDefinition newMenuDefinition() {
287: return new MenuDefinitionImpl();
288: }
289:
290: /**
291: * newMenuExcludeDefinition - creates a new empty menu exclude definition
292: *
293: * @return a newly created MenuExcludeDefinition object for use in Page
294: */
295: public MenuExcludeDefinition newMenuExcludeDefinition() {
296: return new MenuExcludeDefinitionImpl();
297: }
298:
299: /**
300: * newMenuIncludeDefinition - creates a new empty menu include definition
301: *
302: * @return a newly created MenuIncludeDefinition object for use in Page
303: */
304: public MenuIncludeDefinition newMenuIncludeDefinition() {
305: return new MenuIncludeDefinitionImpl();
306: }
307:
308: /**
309: * newMenuOptionsDefinition - creates a new empty menu options definition
310: *
311: * @return a newly created MenuOptionsDefinition object for use in Page
312: */
313: public MenuOptionsDefinition newMenuOptionsDefinition() {
314: return new MenuOptionsDefinitionImpl();
315: }
316:
317: /**
318: * newMenuSeparatorDefinition - creates a new empty menu separator definition
319: *
320: * @return a newly created MenuSeparatorDefinition object for use in Page
321: */
322: public MenuSeparatorDefinition newMenuSeparatorDefinition() {
323: return new MenuSeparatorDefinitionImpl();
324: }
325:
326: /**
327: * setMenuDefinitions - set list of menu definitions
328: *
329: * @param definitions definition list
330: */
331: public void setMenuDefinitions(List definitions) {
332: menuDefinitions = definitions;
333: }
334:
335: /**
336: * unmarshalled - notification that this instance has been
337: * loaded from the persistent store
338: */
339: public void unmarshalled() {
340: // notify super class implementation
341: super .unmarshalled();
342:
343: // propagate unmarshalled notification
344: // to all menu definitions
345: if (menuDefinitions != null) {
346: Iterator menuIter = menuDefinitions.iterator();
347: while (menuIter.hasNext()) {
348: ((MenuDefinitionImpl) menuIter.next()).unmarshalled();
349: }
350: }
351:
352: // propagate unmarshalled notification
353: // to root fragment
354: if (root != null) {
355: ((FragmentImpl) root).unmarshalled();
356: }
357:
358: // default title of pages to name
359: if (getTitle() == null) {
360: setTitle(getTitleName());
361: }
362: }
363:
364: /**
365: * marshalling - notification that this instance is to
366: * be saved to the persistent store
367: */
368: public void marshalling() {
369: // propagate marshalling notification
370: // to root fragment
371: if (root != null) {
372: ((FragmentImpl) root).marshalling();
373: }
374:
375: // propagate marshalling notification
376: // to all menu definitions
377: if (menuDefinitions != null) {
378: Iterator menuIter = menuDefinitions.iterator();
379: while (menuIter.hasNext()) {
380: ((MenuDefinitionImpl) menuIter.next()).marshalling();
381: }
382: }
383:
384: // notify super class implementation
385: super.marshalling();
386: }
387: }
|