001: /*
002: Copyright (c) 2003 eInnovation Inc. All rights reserved
003:
004: This library is free software; you can redistribute it and/or modify it under the terms
005: of the GNU Lesser General Public License as published by the Free Software Foundation;
006: either version 2.1 of the License, or (at your option) any later version.
007:
008: This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
009: without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
010: See the GNU Lesser General Public License for more details.
011: */
012:
013: /*
014: * Created on May 29, 2003
015: */
016: package com.openedit.webui.tree;
017:
018: import java.util.HashSet;
019: import java.util.Set;
020:
021: import com.openedit.util.PathUtilities;
022:
023: /**
024: * This is the base implemation of a JavaScript renderer for output to the web.
025: *
026: * @author Matt Avery
027: */
028: public abstract class BaseTreeRenderer implements TreeRenderer {
029: protected WebTree fieldWebTree;
030: protected String fieldHome;
031:
032: protected String fieldImageDir = "/openedit/images/tree";
033: protected Set fieldExpandedNodes;
034: protected Object fieldSelectedNode;
035:
036: protected String fieldUrlPrefix = "";
037: protected String fieldUrlPostfix = "";
038: protected boolean fieldFoldersLinked;
039:
040: public BaseTreeRenderer(WebTree inWebTree) {
041: fieldWebTree = inWebTree;
042: }
043:
044: public BaseTreeRenderer() {
045:
046: }
047:
048: public String getHome() {
049: if (fieldHome == null) {
050: fieldHome = "";
051: }
052: return fieldHome;
053: }
054:
055: public void setHome(String inHome) {
056: fieldHome = inHome;
057: }
058:
059: public String getExpandNodeCommand() {
060: return "WebTree.expandTreeNode";
061: }
062:
063: public String getImageDir() {
064: return fieldImageDir;
065: }
066:
067: public void setImageDir(String inImageDir) {
068: fieldImageDir = inImageDir;
069: }
070:
071: public void setWebTree(WebTree tree) {
072: fieldWebTree = tree;
073: }
074:
075: public WebTree getWebTree() {
076: return fieldWebTree;
077: }
078:
079: protected Set getExpandedNodes() {
080: if (fieldExpandedNodes == null) {
081: fieldExpandedNodes = new HashSet();
082: }
083:
084: return fieldExpandedNodes;
085: }
086:
087: public void expandNode(Object inNode) {
088: String path = toUrl(inNode);
089: if (!getExpandedNodes().contains(path)) {
090: getExpandedNodes().add(path);
091: //get all the parents somehow
092: Object parent = getWebTree().getModel().getParent(inNode);
093: if (parent != null) {
094: expandNode(parent);
095: }
096: }
097: }
098:
099: /* (non-javadoc)
100: * @see com.openedit.webui.tree.TreeRenderer#collapseNode(java.lang.Object)
101: */
102: public void collapseNode(Object inNode) {
103: String path = toUrl(inNode);
104:
105: getExpandedNodes().remove(path);
106: }
107:
108: public boolean hasBeenExpanded(Object inNode) {
109: String path = toUrl(inNode);
110:
111: return getExpandedNodes().contains(path);
112: }
113:
114: protected String quotes(String inString) {
115: inString = inString.replace("\"", "\\\"");
116: return "\"" + inString + "\"";
117: }
118:
119: public String renderAsString() {
120: StringBuffer js = new StringBuffer("var tree = new Tree( \n");
121:
122: // Ensure the root node is always expanded.
123: expandNode(getWebTree().getModel().getRoot());
124:
125: js.append(renderNewFolder(getWebTree().getModel().getRoot()));
126: js.append(", ");
127: js.append(quotes(getWebTree().getId()));
128: js.append(", \"");
129: js.append(getHome());
130: js.append(getImageDir() + "/\" );\n");
131: if (getUrlPrefix() != null) {
132: js.append("tree.setViewerUrl( '" + getHome()
133: + getUrlPrefix() + "' );\n");
134: }
135: if (getUrlPostfix() != null) {
136: js.append("tree.setViewerUrlEnding( '" + getUrlPostfix()
137: + "' );\n");
138: }
139: js.append("tree.showFolderData= " + isFoldersLinked() + ";\n");
140: if (getSelectedNode() != null) {
141: js.append("tree.setSelectedNodeById(");
142: js.append(quotes(getWebTree().getModel().getId(
143: getSelectedNode())));
144: js.append(");\n");
145: }
146: return js.toString();
147: }
148:
149: public String renderAsString(String inNodeId) {
150: return null;
151: }
152:
153: public void setSelectedNodeByUrl(String inPath) {
154: if (inPath == null) {
155: return;
156: }
157:
158: Object node = null;
159:
160: String root = toUrl(getWebTree().getModel().getRoot());
161: if (PathUtilities.match(root, inPath)) {
162: node = getWebTree().getModel().getRoot();
163: } else {
164: node = findNodeByUrl(getWebTree().getModel().getRoot(),
165: inPath);
166: }
167: setSelectedNode(node);
168: if (node != null) {
169: //expand the parent
170: node = getWebTree().getModel().getParent(node);
171: if (node != null) {
172: expandNode(node);
173: }
174: }
175: }
176:
177: public Object findNodeByUrl(Object inRoot, String inUrl) {
178: int count = getWebTree().getModel().getChildCount(inRoot);
179: for (int i = 0; i < count; i++) {
180: Object child = getWebTree().getModel().getChild(inRoot, i);
181:
182: String test = toUrl(child);
183: if (PathUtilities.match(test, inUrl)) {
184: return child;
185: }
186:
187: //this test must be a directory
188: if (!inUrl.startsWith(test)) {
189: continue;
190: }
191: child = findNodeByUrl(child, inUrl);
192: if (child != null) {
193: return child;
194: }
195: }
196: return null;
197: }
198:
199: public void setSelectedNodeById(String inId) {
200: if (inId == null) {
201: return;
202: }
203: Object node = getWebTree().getModel().getChildById(inId);
204: setSelectedNode(node);
205: if (node != null) {
206: //expand the parent
207: node = getWebTree().getModel().getParent(node);
208: if (node != null) {
209: expandNode(node);
210: }
211: }
212:
213: }
214:
215: protected String renderNewFolder(Object inNode) {
216: StringBuffer js = new StringBuffer("new Node( "
217: + quotes(toName(inNode)) + ", " + quotes(toUrl(inNode))
218: + ", ");
219:
220: js.append(quotes(getWebTree().getModel().getId(inNode)));
221:
222: if (getWebTree().getModel().isLeaf(inNode)) {
223: js.append(",null");
224: } else {
225: js.append(renderChildren(inNode));
226: }
227:
228: js.append("," + getWebTree().getModel().isLeaf(inNode));
229:
230: String iconsset = customIconSet(inNode);
231: if (iconsset != null) {
232: js.append(',');
233: js.append("\"" + iconsset + "\")");
234: } else {
235: js.append(")");
236: }
237:
238: return js.toString();
239: }
240:
241: /**
242: * Allows a certain node to have a custom icon set. Icon sets can be defined in the tree.js
243: * @param inNode
244: * @return
245: */
246: protected String customIconSet(Object inNode) {
247: return null;
248: }
249:
250: protected String renderChildren(Object inNode) {
251: // Use null for our folder icon, and the JavaScript tree will substitute either folder.gif or
252: // folderopen.gif, depending on whether the node is open or closed.
253: StringBuffer js = new StringBuffer();
254:
255: if (hasBeenExpanded(inNode)) {
256: // String collapseUrl = quotes("?" + "WebTreeName=" + getWebTree().getName() + "&oe-action=" +
257: // getCollapseNodeCommand() + "&nodeID=" + getWebTree().getModel().getId(inNode));
258: // js.append(collapseUrl +", new Array(\n");
259:
260: js.append(", new Array(\n");
261:
262: int c = getWebTree().getModel().getChildCount(inNode);
263: for (int i = 0; i < c; i++) {
264: if (i > 0) {
265: js.append(",\n");
266: }
267: Object childNode = getWebTree().getModel().getChild(
268: inNode, i);
269: js.append(renderNewFolder(childNode));
270: }
271:
272: js.append(" ) ");
273: } else {
274: // String expandUrl = quotes("?" + "WebTreeName=" + getWebTree().getName() + "&oe-action=" +
275: // getExpandNodeCommand() + "&nodeID=" + getWebTree().getModel().getId(inNode));
276:
277: // Might need to make this configurable later on.
278: // Different controllers may want to use different commands here.
279: js.append(",null ");
280:
281: // js.append(
282: // quotes("?" + "WebTreeName=" + getWebTree().getName() + "&oe-action=" +
283: // getExpandNodeCommand() + "&nodeID=" + getWebTree().getModel().getId(inNode)) + ", null, ");
284:
285: }
286:
287: return js.toString();
288: }
289:
290: /**
291: * The name is used on the tree display
292: * @param inNode
293: * @return
294: */
295: public abstract String toName(Object inNode);
296:
297: /**
298: * The url will be triggered when a node is clicked
299: * @param inNode
300: * @return
301: */
302: public abstract String toUrl(Object inNode);
303:
304: public String getCollapseNodeCommand() {
305: return "WebTree.collapseTreeNode";
306: }
307:
308: public String getUrlPrefix() {
309: return fieldUrlPrefix;
310: }
311:
312: public void setUrlPrefix(String inUrlPrefix) {
313: fieldUrlPrefix = inUrlPrefix;
314: }
315:
316: public boolean isFoldersLinked() {
317: return fieldFoldersLinked;
318: }
319:
320: public void setFoldersLinked(boolean inFoldersLinked) {
321: fieldFoldersLinked = inFoldersLinked;
322: }
323:
324: public Object getSelectedNode() {
325: return fieldSelectedNode;
326: }
327:
328: public String getSelectedId() {
329: Object selected = getSelectedNode();
330: if (selected == null) {
331: return null;
332: }
333: return getWebTree().getModel().getId(selected);
334: }
335:
336: public void setSelectedNode(Object inSelectedNode) {
337: fieldSelectedNode = inSelectedNode;
338: }
339:
340: public String getUrlPostfix() {
341: return fieldUrlPostfix;
342: }
343:
344: public void setUrlPostfix(String inUrlPostfix) {
345: fieldUrlPostfix = inUrlPostfix;
346: }
347: }
|