001: /**
002: * JOnAS: Java(TM) Open Application Server
003: * Copyright (C) 1999-2005 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: * --------------------------------------------------------------------------
022: * $Id: XmlFileTag.java 6472 2005-03-24 13:35:10Z benoitf $
023: * --------------------------------------------------------------------------
024: */package org.objectweb.jonas.webapp.taglib;
025:
026: import java.io.IOException;
027: import java.util.StringTokenizer;
028:
029: import javax.servlet.jsp.JspException;
030: import javax.servlet.jsp.JspWriter;
031: import javax.servlet.jsp.tagext.BodyTagSupport;
032:
033: /**
034: * @author Michel-Ange ANTON
035: */
036: public class XmlFileTag extends BodyTagSupport {
037:
038: // ----------------------------------------------------- Constants
039: private static final int NONE = 0;
040: private static final int HEADER = 1;
041: private static final int ELEMENT = 2;
042: private static final int ELEMENT_AUTO_CLOSE = 3;
043: private static final int ELEMENT_CLOSE = 4;
044: private static final int COMMENT = 5;
045: private static final int TEXT = 6;
046: // ----------------------------------------------------- Instance Variables
047:
048: protected String m_Body = null;
049: protected int m_LastPrint = NONE;
050: protected int m_Indent = 0;
051:
052: //are we printing XML comment content
053: protected boolean comment = false;
054:
055: // ------------------------------------------------------------- Properties
056:
057: // --------------------------------------------------------- Public Methods
058:
059: /**
060: * Render this instant actions control.
061: *
062: * @exception JspException if a processing error occurs
063: */
064: public int doEndTag() throws JspException {
065: JspWriter out = pageContext.getOut();
066: try {
067: String sXml = null;
068: // Get body
069: if (m_Body != null) {
070: sXml = m_Body;
071: m_Body = null;
072: }
073: // Display
074: if (sXml != null) {
075: m_LastPrint = NONE;
076: m_Indent = 0;
077: render(out, sXml, 0, sXml.length());
078: }
079: } catch (IOException e) {
080: throw new JspException(e);
081: }
082: return (EVAL_PAGE);
083: }
084:
085: public int doAfterBody() throws JspException {
086: String sBody = bodyContent.getString();
087: if (sBody != null) {
088: sBody = sBody.trim();
089: if (sBody.length() > 0) {
090: this .m_Body = sBody;
091: }
092: }
093: return (SKIP_BODY);
094: }
095:
096: /**
097: * Release all state information set by this tag.
098: */
099: public void release() {
100: m_Body = null;
101: }
102:
103: // -------------------------------------------------------- Protected Methods
104:
105: protected void render(JspWriter p_Out, String p_Xml, int p_Begin,
106: int p_End) throws IOException, JspException {
107:
108: int iCurrent = p_Begin;
109: int iBegin;
110: int iEnd;
111: String sElement;
112: String sElementWithAttr;
113: String sName;
114: char cType;
115:
116: for (;;) {
117: // Find begin element
118: iBegin = p_Xml.indexOf("<", iCurrent);
119: if ((iBegin == -1) || (iBegin >= p_End)) {
120: break;
121: }
122: // Find end element
123: iEnd = p_Xml.indexOf(">", iBegin);
124: if (iEnd == -1) {
125: break;
126: }
127: // render normal text
128: if (iBegin > iCurrent) {
129: String sText = p_Xml.substring(iCurrent, iBegin);
130: sText = sText.trim();
131: if (sText.length() > 0) {
132: printText(p_Out, sText);
133: }
134: }
135:
136: // Get complete element
137: sElement = p_Xml.substring(iBegin, iEnd + 4);
138: // Detect special element (doctype, header, comment)
139: cType = sElement.charAt(4);
140: if ((cType == '!') || (cType == '?')) {
141: // Special element (doctype, header, comment)
142: if (cType == '!') {
143: // Detect comment
144: cType = sElement.charAt(5);
145: if (cType == '-') {
146: // Find actual end element - if we are dealing with comment
147: iEnd = p_Xml.indexOf("-->", iBegin);
148: if (iEnd == -1) {
149: break;
150: }
151: // set counter on proper value
152: iEnd = iEnd + 2;
153:
154: // Get complete element
155: sElement = p_Xml.substring(iBegin, iEnd + 4);
156:
157: printComment(p_Out, sElement);
158: } else {
159: printHeader(p_Out, sElement);
160: }
161: } else {
162: printHeader(p_Out, sElement);
163: }
164: // Next
165: iCurrent = iEnd + 4;
166: } else {
167: // get name of element
168: sElementWithAttr = sElement.substring(4, sElement
169: .length() - 4);
170: sName = getNameElement(sElementWithAttr);
171: // Detect end element
172: if (sElementWithAttr.charAt(0) == '/') {
173: // Next
174: iCurrent = iEnd + 4;
175: break;
176: }
177: // Detect auto-end element
178: else if (sElementWithAttr.charAt(sElementWithAttr
179: .length() - 1) == '/') {
180: printElementAutoClose(p_Out, sElement);
181: // Next
182: iCurrent = iEnd + 4;
183: } else {
184: // Render element
185: printElement(p_Out, sElement);
186: // Search close element
187: String sCloseElement = "</" + sName + ">";
188: int iPosCloseElement = p_Xml.indexOf(sCloseElement,
189: iEnd);
190: if (iPosCloseElement == -1) {
191: // Error
192: break;
193: }
194: // render children element (or text)
195: render(p_Out, p_Xml, iEnd + 4, iPosCloseElement
196: + sCloseElement.length());
197: // render end element
198: printElementClose(p_Out, sCloseElement);
199: // Next
200: iCurrent = iPosCloseElement
201: + sCloseElement.length();
202: }
203: }
204: }
205: }
206:
207: protected void printElement(JspWriter p_Out, String p_Print)
208: throws IOException, JspException {
209: switch (m_LastPrint) {
210: case NONE:
211: case TEXT:
212: break;
213: case HEADER:
214: case ELEMENT:
215: case ELEMENT_AUTO_CLOSE:
216: case ELEMENT_CLOSE:
217: case COMMENT:
218: p_Out.print("<br>");
219: break;
220: }
221:
222: printIndent(p_Out, m_Indent);
223:
224: // are we printing comment
225: if (!comment)
226: p_Out.print("<span class=\"xmlElement\">");
227:
228: p_Out.print(p_Print);
229:
230: // are we printing comment
231: if (!comment)
232: p_Out.print("</span>");
233:
234: m_LastPrint = ELEMENT;
235: m_Indent++;
236: }
237:
238: protected void printElementAutoClose(JspWriter p_Out, String p_Print)
239: throws IOException, JspException {
240:
241: switch (m_LastPrint) {
242: case NONE:
243: case TEXT:
244: break;
245: case HEADER:
246: case ELEMENT:
247: case ELEMENT_AUTO_CLOSE:
248: case ELEMENT_CLOSE:
249: case COMMENT:
250: p_Out.print("<br>");
251: break;
252: }
253: printIndent(p_Out, m_Indent);
254: //are we printing comment
255: if (!comment)
256: p_Out.print("<span class=\"xmlElement\">");
257:
258: p_Out.print(p_Print);
259:
260: // are we printing comment
261: if (!comment)
262: p_Out.print("</span>");
263:
264: m_LastPrint = ELEMENT_AUTO_CLOSE;
265: }
266:
267: protected void printElementClose(JspWriter p_Out, String p_Print)
268: throws IOException, JspException {
269:
270: m_Indent--;
271:
272: switch (m_LastPrint) {
273: case NONE:
274: case ELEMENT:
275: case TEXT:
276: break;
277: case HEADER:
278: case ELEMENT_AUTO_CLOSE:
279: case ELEMENT_CLOSE:
280: case COMMENT:
281: p_Out.print("<br>");
282: printIndent(p_Out, m_Indent);
283: break;
284: }
285: // are we printing comment
286: if (!comment)
287: p_Out.print("<span class=\"xmlElement\">");
288:
289: p_Out.print(p_Print);
290:
291: // are we printing comment
292: if (!comment)
293: p_Out.print("</span>");
294:
295: m_LastPrint = ELEMENT_CLOSE;
296: }
297:
298: protected void printComment(JspWriter p_Out, String p_Print)
299: throws IOException, JspException {
300: switch (m_LastPrint) {
301: case NONE:
302: break;
303: case HEADER:
304: case ELEMENT:
305: case ELEMENT_AUTO_CLOSE:
306: case ELEMENT_CLOSE:
307: case COMMENT:
308: case TEXT:
309: p_Out.print("<br>");
310: break;
311: }
312: printIndent(p_Out, m_Indent);
313: p_Out.print("<span class=\"xmlComment\">");
314:
315: // take only comment content
316: p_Print = p_Print.substring(7, p_Print.length() - 6).trim();
317: // start printing commented element
318: p_Out.print("<!--");
319:
320: // are we dealing with commented element
321: if (p_Print.indexOf("/>") == -1) {
322: // print simple comment text
323: p_Out.print(p_Print);
324: } else {
325: // set comment property value - disables <span/> elements
326: setComment(true);
327: // print commented element
328: render(p_Out, p_Print, 0, p_Print.length() - 1);
329: p_Out.print("<br>");
330: // turn back comment property value - enable <span/> elements again
331: setComment(false);
332: }
333:
334: // print comment ending
335: printIndent(p_Out, m_Indent);
336: p_Out.print("-->");
337:
338: p_Out.print("</span>");
339:
340: m_LastPrint = COMMENT;
341: }
342:
343: protected void printHeader(JspWriter p_Out, String p_Print)
344: throws IOException, JspException {
345: switch (m_LastPrint) {
346: case NONE:
347: break;
348: case HEADER:
349: case ELEMENT:
350: case ELEMENT_AUTO_CLOSE:
351: case ELEMENT_CLOSE:
352: case COMMENT:
353: case TEXT:
354: p_Out.print("<br>");
355: break;
356: }
357: // are we printing comment
358: if (!comment)
359: p_Out.print("<span class=\"xmlHeader\">");
360:
361: p_Out.print(p_Print);
362:
363: // are we printing comment
364: if (!comment)
365: p_Out.print("</span>");
366:
367: m_LastPrint = HEADER;
368: }
369:
370: protected void printText(JspWriter p_Out, String p_Print)
371: throws IOException, JspException {
372:
373: // are we printing comment
374: if (!comment)
375: p_Out.print("<span class=\"xmlText\">");
376:
377: p_Out.print(p_Print);
378:
379: // are we printing comment
380: if (!comment)
381: p_Out.print("</span>");
382:
383: m_LastPrint = TEXT;
384: }
385:
386: protected void printIndent(JspWriter p_Out, int p_Indent)
387: throws IOException, JspException {
388: for (int i = 0; i < p_Indent; i++) {
389: p_Out.print(" ");
390: }
391: }
392:
393: protected String getNameElement(String p_ElementWithAttr) {
394: StringTokenizer st = new StringTokenizer(p_ElementWithAttr, " ");
395: return st.nextToken();
396: }
397:
398: protected void setComment(boolean value) {
399: // are we printing comment (enable/disable <span/> elements)
400: comment = value;
401: }
402:
403: }
|