package org.wikiwizard.jspwiki.plugin; import java.util.ArrayList; import java.util.Map; import java.util.Stack; import javax.servlet.http.Cookie; import org.apache.ecs.xhtml.col; import com.ecyrd.jspwiki.WikiContext; import com.ecyrd.jspwiki.WikiEngine; import com.ecyrd.jspwiki.plugin.PluginException; import com.ecyrd.jspwiki.plugin.PluginManager; import com.ecyrd.jspwiki.plugin.WikiPlugin; /** * @author Tim Wieschadlo * @date 23.04.2006 */ public class TreeView implements WikiPlugin { /* * JSPWiki */ WikiContext context; WikiEngine engine; String pageName; /* * important Fields */ boolean expanded = false; boolean useCookies = true; boolean usePageName = false; boolean states[]; byte depth[]; String lines[]; String leafImg = "leaf.gif"; String expandImg = "minus.gif"; String collapseImg = "plus.gif"; String treeName = "treeview"; String templateDir = "default"; /* * TreeStructture */ TreeNode rootNode = new TreeNode("root", true); /* * Constants */ private static final String TREE_EXPANDED = "expanded"; private static final String TREE_USE_COOKIES = "cookies"; private static final String TREE_LEAF_IMG = "leaf"; private static final String TREE_EXPANDED_IMG = "expand"; private static final String TREE_COLLAPSED_IMG = "collapse"; private static final String TREE_NAME = "name"; private static final String TREE_USE_PAGENAME = "pagename"; public String execute(WikiContext context, Map params) throws PluginException { this.context = context; this.engine = context.getEngine(); this.pageName = context.getPage().getName(); StringBuffer res = new StringBuffer(); templateDir = engine.getTemplateDir(); processParams(params); if (usePageName) treeName = treeName + pageName; depth = getDepth(); processCookies(res); buildTree(res); appendWriteCookieJS(res); appendJS(engine, res); buildHTML(res); return res.toString(); } private void appendWriteCookieJS(StringBuffer res) { res .append("\n"); } private void appendJS(WikiEngine engine, StringBuffer res) { res .append("\n\n\n"); } private void buildHTML(StringBuffer res) { if (rootNode.hasChilds()) { for (int i = 0; i < rootNode.childs.size(); i++) res.append(rootNode.childs.get(i).toString()); } } private void buildTree(StringBuffer res) { Stack stack = new Stack(); rootNode = new TreeNode("rootNode", true); TreeNode current = rootNode; stack.push(rootNode); TreeNode next = new TreeNode(lines[0], states[0]); rootNode.addChild(next); current = next; // for (int i = 0; i < states.length; i++) // res.append("
States Data "+i+": " + ((states[i]) ? '1' : '0')); for (int i = 1; i < depth.length; i++) { // res.append(((states[i]) ? '1' : '0')); if (depth[i - 1] < depth[i]) { stack.push(current); next = new TreeNode(lines[i], states[i]); current.addChild(next); current = next; } else if (depth[i - 1] == depth[i]) { next = new TreeNode(lines[i], states[i]); ((TreeNode) stack.peek()).addChild(next); current = next; } else { for (int j = 0; j < depth[i - 1] - depth[i]; j++) { stack.pop(); } current = (TreeNode) stack.peek(); next = new TreeNode(lines[i], states[i]); current.addChild(next); current = next; } } } private byte[] getDepth() { /* alle relevanten lines abarbeiten und zugehörige Tiefe speichern */ byte depth[] = new byte[lines.length]; for (int i = 0; i < lines.length; i++) { byte asterikscount = 0; char lineChars[] = lines[i].toCharArray(); while (lineChars[asterikscount] == '*') asterikscount++; depth[i] = asterikscount; lines[i] = lines[i].substring(depth[i]).trim(); } return depth; } private void processParams(Map params) { if (params.get(TREE_NAME) != null) treeName = (String) params.get(TREE_NAME); if (params.get(TREE_COLLAPSED_IMG) != null) collapseImg = (String) params.get(TREE_COLLAPSED_IMG); if (params.get(TREE_EXPANDED_IMG) != null) expandImg = (String) params.get(TREE_EXPANDED_IMG); if (params.get(TREE_LEAF_IMG) != null) leafImg = (String) params.get(TREE_LEAF_IMG); if (params.get(TREE_USE_COOKIES) != null) useCookies = (((String) params.get(TREE_USE_COOKIES)) .equalsIgnoreCase("yes")) ? true : false; if (params.get(TREE_EXPANDED) != null) expanded = (((String) params.get(TREE_EXPANDED)) .equalsIgnoreCase("yes")) ? true : false; if (params.get(TREE_USE_PAGENAME) != null) usePageName = (((String) params.get(TREE_USE_PAGENAME)) .equalsIgnoreCase("yes")) ? true : false; parseLines(((String) params.get(PluginManager.PARAM_BODY))); } private void parseLines(String s) { lines = s.split("\n"); /* filter out the empty lines */ ArrayList temp = new ArrayList(); for (int i = 0; i < lines.length; i++) { lines[i] = lines[i].trim(); if ((lines[i] != null) && !(lines[i].equals("")) && !(lines[i].equals("'"))) { temp.add(lines[i]); } } lines = new String[temp.size()]; temp.toArray(lines); } private void processCookies(StringBuffer res) { if (this.useCookies) { Cookie cookies[] = context.getHttpRequest().getCookies(); String value = null; if (cookies != null) { for (int i = 0; i < cookies.length; i++) { if (cookies[i].getName().equals(treeName)) { value = cookies[i].getValue(); } } } // is TreeView altered is Size or no cookie ? if (value == null || value.length() != lines.length) { this.useCookies = false; processCookies(res); } else { states = new boolean[value.length()]; char[] ex = value.toCharArray(); // res.append("
Cookie Data: "); for (int i = 0; i < ex.length; i++) { if (ex[i] == '0') states[i] = false; else states[i] = true; // res.append(ex[i]); } } } else { states = new boolean[lines.length]; states[0] = true; for (int i = 1; i < lines.length; i++) { if (expanded) { states[i] = true; continue; } // per depth nodes herausfinden und je nach expanded status // setzen if (depth[i] == 1) states[i] = true; else states[i] = false; } } } private class TreeNode { private String nodeName; private boolean isVisible; private ArrayList childs = null; private HTMLFactory html = new HTMLFactory(); public TreeNode(String nodeName, boolean isVisible) { this.nodeName = nodeName; this.isVisible = isVisible; } public void addChild(TreeNode child) { if (childs == null) { childs = new ArrayList(); } childs.add(child); } public boolean hasChilds() { return (childs != null); } public boolean isLeaf() { return (childs == null); } public boolean isVisible() { return isVisible; } public String toString() { StringBuffer res = new StringBuffer(); if (childs != null) { res.append(html.openNode(nodeName, ((TreeNode) childs.get(0)) .isVisible(), isVisible)); for (int i = 0; i < childs.size(); i++) { res.append(((TreeNode) childs.get(i)).toString()); } res.append(html.closeNode()); } else res.append(html.appendLeaf(nodeName, isVisible)); return res.toString(); } } private class HTMLFactory { public String appendLeaf(String value, boolean selfVisible) { StringBuffer res = new StringBuffer(); res.append(openTable(selfVisible)); res.append(openTR()); res.append(openTD()); res.append(insertLeafImg()); res.append(closeTD()); res.append(openTD()); res.append(parse(value) + "\n"); // res.append(value+"\n"); res.append(closeTD()); res.append(closeTR()); res.append(closeTable()); return res.toString(); } public String openNode(String value, boolean childsVisible, boolean selfVisible) { StringBuffer res = new StringBuffer(); res.append(openTable(selfVisible)); res.append(openTR()); res.append(openTD()); if (childsVisible) res.append(insertExpandImg()); else res.append(insertCollapseImg()); res.append(closeTD()); res.append(openTD()); res.append(parse(value) + "\n"); // res.append(value+"\n"); return res.toString(); } public String closeNode() { StringBuffer res = new StringBuffer(); res.append(closeTD()); res.append(closeTR()); res.append(closeTable()); return res.toString(); } public String openTR() { return "\n"; } public String closeTR() { return "\n"; } public String openTD() { return "\n"; } public String closeTD() { return "\n"; } public String insertLeafImg() { return "\n"; } public String insertCollapseImg() { return "\n"; } public String insertExpandImg() { return "\n"; } public String openTable(boolean isVisible) { String visible = (isVisible) ? "block" : "none"; return "\n\n"; } public String closeTable() { return "\n
\n"; } private String parse(String s) { return context.getEngine().textToHTML(context, s); } } }