001: /*
002: * Copyright (C) 2006 Methodhead Software LLC. All rights reserved.
003: *
004: * This file is part of TransferCM.
005: *
006: * TransferCM is free software; you can redistribute it and/or modify it under the
007: * terms of the GNU General Public License as published by the Free Software
008: * Foundation; either version 2 of the License, or (at your option) any later
009: * version.
010: *
011: * TransferCM is distributed in the hope that it will be useful, but WITHOUT ANY
012: * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
013: * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
014: * details.
015: *
016: * You should have received a copy of the GNU General Public License along with
017: * TransferCM; if not, write to the Free Software Foundation, Inc., 51 Franklin St,
018: * Fifth Floor, Boston, MA 02110-1301 USA
019: */
020:
021: package com.methodhead.shim;
022:
023: import org.apache.commons.lang.StringUtils;
024:
025: /**
026: * Renders a folding navigation.
027: */
028: public class FoldingNavRenderer {
029:
030: // constructors /////////////////////////////////////////////////////////////
031:
032: // constants ////////////////////////////////////////////////////////////////
033:
034: public static final String URL_KEY = "{url}";
035: public static final String TITLE_KEY = "{title}";
036: public static final String LEVEL_KEY = "{level}";
037:
038: // classes //////////////////////////////////////////////////////////////////
039:
040: // methods //////////////////////////////////////////////////////////////////
041:
042: /**
043: * Appends this nav's header to <tt>buf</tt>.
044: */
045: protected void renderHeader(StringBuffer buf) {
046:
047: buf.append(getHeader());
048: }
049:
050: /**
051: * Appends a link to <tt>buf</tt>, using the template set by {@link #setLink
052: * setLink()} and replacing placeholders ({@link #URL_KEY URL_KEY}, {@link
053: * #TITLE_KEY TITLE_KEY}, {@link #LEVEL_KEY LEVEL_KEY}) with their
054: * appropriate values.
055: */
056: protected void renderLink(StringBuffer buf, Link link, int level) {
057:
058: String s = null;
059:
060: if (link == cur_)
061: s = getCurLink();
062: else
063: s = getLink();
064:
065: //
066: // don't try to remove site context from path in edit mode
067: //
068: s = StringUtils.replace(s, URL_KEY, ShimUtils.getLinkUrl(link));
069:
070: s = StringUtils.replace(s, TITLE_KEY, link.getTitle());
071: s = StringUtils.replace(s, LEVEL_KEY, "" + level);
072:
073: buf.append(s);
074: }
075:
076: /**
077: * Appends this nav's footer to <tt>buf</tt>.
078: */
079: protected void renderFooter(StringBuffer buf) {
080:
081: buf.append(getFooter());
082: }
083:
084: protected void traverse(StringBuffer buf, Link link, int level) {
085:
086: if (link.getHidden())
087: return;
088:
089: if (link == cur_) {
090: if (link.getLevel() >= (start_ - 1))
091: renderLink(buf, link, level);
092:
093: for (int i = 0; i < link.getChildCount(); i++)
094: traverse(buf, (Link) link.getChildAt(i), level + 1);
095: }
096:
097: else if (link.isNodeDescendant(cur_)) {
098: if (link.getLevel() >= (start_ - 1)) {
099: renderLink(buf, link, level);
100: level++;
101: }
102:
103: for (int i = 0; i < link.getChildCount(); i++)
104: traverse(buf, (Link) link.getChildAt(i), level);
105: }
106:
107: else if (((link.getLevel() - cur_.getLevel()) < context_)
108: && ((link.getLevel() - cur_.getLevel()) >= 0)) {
109: if (link.getLevel() >= (start_ - 1))
110: renderLink(buf, link, level);
111:
112: for (int i = 0; i < link.getChildCount(); i++)
113: traverse(buf, (Link) link.getChildAt(i), level + 1);
114: }
115:
116: else if (link.isNodeAncestor(cur_)
117: && ((link.getLevel() - cur_.getLevel()) <= depth_)) {
118:
119: if (link.getLevel() >= (start_ - 1))
120: renderLink(buf, link, level);
121:
122: for (int i = 0; i < link.getChildCount(); i++)
123: traverse(buf, (Link) link.getChildAt(i), level + 1);
124: }
125:
126: else if (level <= top_) {
127: if (link.getLevel() >= (start_ - 1)) {
128: renderLink(buf, link, level);
129: level++;
130: }
131:
132: if (level <= top_)
133: for (int i = 0; i < link.getChildCount(); i++)
134: traverse(buf, (Link) link.getChildAt(i), level);
135: }
136: }
137:
138: /**
139: * Appends this nav's footer to <tt>buf</tt>.
140: */
141: protected void renderNav(StringBuffer buf) {
142:
143: renderHeader(buf);
144:
145: traverse(buf, root_, 1);
146:
147: renderFooter(buf);
148: }
149:
150: /**
151: * Returns the HTML for the nav.
152: */
153: public String getNavHtml() {
154: StringBuffer buf = new StringBuffer();
155: renderNav(buf);
156: return buf.toString();
157: }
158:
159: // properties ///////////////////////////////////////////////////////////////
160:
161: public Link getRoot() {
162: return root_;
163: }
164:
165: public void setRoot(Link root) {
166: root_ = root;
167: }
168:
169: public Link getCur() {
170: return cur_;
171: }
172:
173: public void setCur(Link cur) {
174: cur_ = cur;
175: }
176:
177: public int getStart() {
178: return start_;
179: }
180:
181: public void setStart(int start) {
182: start_ = start;
183: }
184:
185: public int getContext() {
186: return context_;
187: }
188:
189: public void setContext(int context) {
190: context_ = context;
191: }
192:
193: public int getDepth() {
194: return depth_;
195: }
196:
197: public void setDepth(int depth) {
198: depth_ = depth;
199: }
200:
201: public int getTop() {
202: return top_;
203: }
204:
205: public void setTop(int top) {
206: top_ = top;
207: }
208:
209: public String getHeader() {
210: return header_;
211: }
212:
213: public void setHeader(String header) {
214: header_ = header;
215: }
216:
217: public String getLink() {
218: return link_;
219: }
220:
221: public void setLink(String link) {
222: link_ = link;
223: }
224:
225: public String getCurLink() {
226: return curLink_;
227: }
228:
229: public void setCurLink(String curLink) {
230: curLink_ = curLink;
231: }
232:
233: public String getFooter() {
234: return footer_;
235: }
236:
237: public void setFooter(String footer) {
238: footer_ = footer;
239: }
240:
241: public boolean getIsEditMode() {
242: return isEditMode_;
243: }
244:
245: public void setIsEditMode(boolean isEditMode) {
246: isEditMode_ = isEditMode;
247: }
248:
249: // attributes ///////////////////////////////////////////////////////////////
250:
251: private Link root_ = null;
252: private Link cur_ = null;
253: private int start_ = 1;
254: private int context_ = 1;
255: private int depth_ = 1;
256: private int top_ = 1;
257: private String header_ = "";
258: private String link_ = "";
259: private String curLink_ = "";
260: private String footer_ = "";
261: private boolean isEditMode_ = false;
262: }
|