001: /*
002: * JOnAS: Java(TM) Open Application Server
003: * Copyright (C) 1999 Bull S.A.
004: * Contact: jonas-team@objectweb.org
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation; either
009: * version 2.1 of the License, or any later version.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: *
016: * You should have received a copy of the GNU Lesser General Public
017: * License along with this library; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
019: * USA
020: *
021: * Initial developer(s): Michel-Ange ANTON
022: * --------------------------------------------------------------------------
023: * $Id: TreeControlRenderTag.java 3686 2003-11-12 17:19:38Z antonma $
024: * --------------------------------------------------------------------------
025: */
026:
027: package org.objectweb.jonas.webapp.taglib;
028:
029: import java.io.IOException;
030: import java.net.URLEncoder;
031:
032: import javax.servlet.http.HttpServletResponse;
033: import javax.servlet.jsp.JspException;
034: import javax.servlet.jsp.JspWriter;
035:
036: public class TreeControlRenderTag extends TreeControlTag {
037: /**
038: * The names of tree state images that we need.
039: */
040: static final String IMAGE_NODE_OPEN = "node_open.gif";
041: static final String IMAGE_NODE_OPEN_FIRST = "node_open_first.gif";
042: static final String IMAGE_NODE_OPEN_MIDDLE = "node_open_middle.gif";
043: static final String IMAGE_NODE_OPEN_LAST = "node_open_last.gif";
044: static final String IMAGE_NODE_CLOSE = "node_close.gif";
045: static final String IMAGE_NODE_CLOSE_FIRST = "node_close_first.gif";
046: static final String IMAGE_NODE_CLOSE_MIDDLE = "node_close_middle.gif";
047: static final String IMAGE_NODE_CLOSE_LAST = "node_close_last.gif";
048: static final String IMAGE_BLANK = "noline.gif";
049: static final String IMAGE_LINE_FIRST = "line_first.gif";
050: static final String IMAGE_LINE_LAST = "line_last.gif";
051: static final String IMAGE_LINE_MIDDLE = "line_middle.gif";
052: static final String IMAGE_LINE_VERTICAL = "line.gif";
053:
054: // --------------------------------------------------------- Instance Variables
055:
056: /**
057: * Flag who indicate when the first node is rendered.
058: */
059: private boolean mb_FirstNodeRendered;
060: private int mi_MaxChar;
061:
062: // --------------------------------------------------------- Public Methods
063:
064: /**
065: * Render this tree control.
066: *
067: * @exception JspException if a processing error occurs
068: */
069: public int doEndTag() throws JspException {
070: /*
071: mb_FirstNodeRendered = false;
072: return super.doEndTag();
073: */
074:
075: TreeControl treeControl = getTreeControl();
076: JspWriter out = pageContext.getOut();
077: try {
078: out
079: .print("<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\"");
080: if (style != null) {
081: out.print(" class=\"");
082: out.print(style);
083: out.print("\"");
084: }
085: out.println(">");
086: int level = 0;
087: mb_FirstNodeRendered = false;
088: mi_MaxChar = 0;
089: TreeControlNode node = treeControl.getRoot();
090: render(out, node, level, treeControl.getWidth(), true);
091:
092: // Avoid bug Netscape 4
093: out.print("<tr>");
094: for (int i = 0; i < treeControl.getWidth() + 2; i++) {
095: out.print("<td></td>");
096: }
097: StringBuffer sb = new StringBuffer("<td nowrap>");
098: for (int i = 0; i < (mi_MaxChar + 1); i++) {
099: sb.append(" ");
100: }
101: sb.append("</td>");
102: out.print(sb.toString());
103: out.println("</tr>");
104:
105: out.println("</table>");
106: } catch (IOException e) {
107: throw new JspException(e);
108: }
109: return (EVAL_PAGE);
110:
111: }
112:
113: // ------------------------------------------------------ Protected Methods
114:
115: /**
116: * Render the specified node, as controlled by the specified parameters.
117: *
118: * @param out The <code>JspWriter</code> to which we are writing
119: * @param node The <code>TreeControlNode</code> we are currently
120: * rendering
121: * @param level The indentation level of this node in the tree
122: * @param width Total displayable width of the tree
123: * @param last Is this the last node in a list?
124: *
125: * @exception IOException if an input/output error occurs
126: */
127: protected void render(JspWriter out, TreeControlNode node,
128: int level, int width, boolean last) throws IOException {
129: HttpServletResponse response = (HttpServletResponse) pageContext
130: .getResponse();
131:
132: // if the node is root node and the label value is
133: // null, then do not render root node in the tree.
134:
135: if ("ROOT-NODE".equalsIgnoreCase(node.getName())
136: && (node.getLabel() == null)) {
137: // Render the children of this node
138: TreeControlNode children[] = node.findChildren();
139: int firstIndex = children.length - 1;
140: int lastIndex = children.length - 1;
141: int newLevel = level + 1;
142: for (int i = 0; i < children.length; i++) {
143: render(out, children[i], newLevel, width,
144: i == lastIndex);
145: }
146: return;
147: }
148:
149: // Render the beginning of this node
150: out.println(" <tr valign=\"middle\">");
151:
152: // Create the appropriate number of indents
153: for (int i = 0; i < level; i++) {
154: int levels = level - i;
155: TreeControlNode parent = node;
156: for (int j = 1; j <= levels; j++) {
157: parent = parent.getParent();
158: }
159: if (parent.isLast()) {
160: out.print(" <td></td>");
161: } else {
162: out.print(" <td><img src=\"");
163: out.print(images);
164: out.print("/");
165: out.print("tree/");
166: out.print(IMAGE_LINE_VERTICAL);
167: out.print("\" border=\"0\"></td>");
168: }
169: out.println();
170: }
171:
172: // Render the tree state image for this node
173:
174: // HACK to take into account special characters like = and &
175: // in the node name, could remove this code if encode URL
176: // and later request.getParameter() could deal with = and &
177: // character in parameter values.
178: String encodedNodeName = URLEncoder.encode(node.getName(),
179: "UTF-8");
180:
181: String action = replace(getAction(), "${name}", encodedNodeName);
182:
183: String updateTreeAction = replace(getAction(), "tree=${name}",
184: "select=" + encodedNodeName);
185: updateTreeAction = ((HttpServletResponse) pageContext
186: .getResponse()).encodeURL(updateTreeAction);
187:
188: out.print(" <td>");
189: if ((action != null) && !node.isLeaf()) {
190: out.print("<a href=\"");
191: out.print(response.encodeURL(action));
192: out.print("\">");
193: }
194: out.print("<img src=\"");
195: out.print(images);
196: out.print("/");
197: out.print("tree/");
198: if (node.isLeaf()) {
199: if (mb_FirstNodeRendered == false) {
200: if (node.isLast()) {
201: out.print(IMAGE_BLANK);
202: } else {
203: out.print(IMAGE_LINE_FIRST);
204: }
205: } else if (node.isLast()) {
206: out.print(IMAGE_LINE_LAST);
207: } else {
208: out.print(IMAGE_LINE_MIDDLE);
209: }
210: } else if (node.isExpanded()) {
211: if (mb_FirstNodeRendered == false) {
212: if (node.isLast()) {
213: out.print(IMAGE_NODE_OPEN);
214: } else {
215: out.print(IMAGE_NODE_OPEN_FIRST);
216: }
217: } else if (node.isLast()) {
218: out.print(IMAGE_NODE_OPEN_LAST);
219: } else {
220: out.print(IMAGE_NODE_OPEN_MIDDLE);
221: }
222: } else {
223: if (mb_FirstNodeRendered == false) {
224: if (node.isLast()) {
225: out.print(IMAGE_NODE_CLOSE);
226: } else {
227: out.print(IMAGE_NODE_CLOSE_FIRST);
228: }
229: } else if (node.isLast()) {
230: out.print(IMAGE_NODE_CLOSE_LAST);
231: } else {
232: out.print(IMAGE_NODE_CLOSE_MIDDLE);
233: }
234: }
235: out.print("\" border=\"0\" align=\"absmiddle\">");
236: if ((action != null) && !node.isLeaf()) {
237: out.print("</a>");
238: }
239: out.println("</td>");
240:
241: // Calculate the hyperlink for this node (if any)
242: String hyperlink = null;
243: if (node.getAction() != null) {
244: hyperlink = ((HttpServletResponse) pageContext
245: .getResponse()).encodeURL(node.getAction());
246: }
247:
248: // Render the icon for this node (if any)
249: out.print(" <td>");
250:
251: // Anchor name
252: out.print("<a name=\"");
253: out.print(encodedNodeName);
254: out.print("\"></a>");
255:
256: if (node.getIcon() != null) {
257: if (hyperlink != null) {
258: out.print("<a href=\"");
259: out.print(hyperlink);
260: out.print("\"");
261: String target = node.getTarget();
262: if (target != null) {
263: out.print(" target=\"");
264: out.print(target);
265: out.print("\"");
266: }
267: // to refresh the tree in the same 'self' frame
268: out.print(" onclick=\"");
269: out.print("self.location.href='" + updateTreeAction
270: + "'");
271: out.print("\"");
272: out.print(">");
273: }
274: out.print("<img src=\"");
275: out.print(images);
276: out.print("/");
277: out.print(node.getIcon());
278: out.print("\" border=\"0\" align=\"absmiddle\">");
279: if (hyperlink != null) {
280: out.print("</a>");
281: }
282: }
283: out.println("</td>");
284:
285: // Render the label for this node (if any)
286: int iColspan = width - level + 1;
287: if (iColspan > 1) {
288: out.print(" <td width=\"100%\" colspan=\"");
289: out.print(iColspan);
290: out.print("\" nowrap>");
291: } else {
292: out.print(" <td width=\"100%\" nowrap>");
293: }
294: if (node.getLabel() != null) {
295: if (node.getLabel().length() > mi_MaxChar) {
296: mi_MaxChar = node.getLabel().length();
297: }
298: // Note the leading space so that the text has some space
299: // between it and any preceding images
300: out.print(" ");
301: String labelStyle = null;
302: if (node.isSelected() && (styleSelected != null)) {
303: labelStyle = styleSelected;
304: } else if (!node.isSelected() && (styleUnselected != null)) {
305: labelStyle = styleUnselected;
306: }
307: if (hyperlink != null) {
308: out.print("<a href=\"");
309: out.print(hyperlink);
310: out.print("\"");
311: String target = node.getTarget();
312: if (target != null) {
313: out.print(" target=\"");
314: out.print(target);
315: out.print("\"");
316: }
317: if (labelStyle != null) {
318: out.print(" class=\"");
319: out.print(labelStyle);
320: out.print("\"");
321: }
322: // to refresh the tree in the same 'self' frame
323: out.print(" onclick=\"");
324: out.print("self.location.href='" + updateTreeAction
325: + "'");
326: out.print("\"");
327: out.print(">");
328: } else if (labelStyle != null) {
329: out.print("<span class=\"");
330: out.print(labelStyle);
331: out.print("\">");
332: }
333: out.print(node.getLabel());
334: if (hyperlink != null) {
335: out.print("</a>");
336: } else if (labelStyle != null) {
337: out.print("</span>");
338: }
339: }
340: out.println("</td>");
341:
342: // Render the end of this node
343: out.println(" </tr>");
344: // Remember the first node is rendered
345: mb_FirstNodeRendered = true;
346:
347: // Render the children of this node
348: if (node.isExpanded()) {
349: TreeControlNode children[] = node.findChildren();
350: int lastIndex = children.length - 1;
351: int newLevel = level + 1;
352: for (int i = 0; i < children.length; i++) {
353: render(out, children[i], newLevel, width,
354: i == lastIndex);
355: }
356: }
357:
358: }
359: }
|