001: /*
002: * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved
003: *
004: * This file is part of Resin(R) Open Source
005: *
006: * Each copy or derived work must preserve the copyright notice and this
007: * notice unmodified.
008: *
009: * Resin Open Source is free software; you can redistribute it and/or modify
010: * it under the terms of the GNU General Public License as published by
011: * the Free Software Foundation; either version 2 of the License, or
012: * (at your option) any later version.
013: *
014: * Resin Open Source is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
017: * of NON-INFRINGEMENT. See the GNU General Public License for more
018: * details.
019: *
020: * You should have received a copy of the GNU General Public License
021: * along with Resin Open Source; if not, write to the
022: *
023: * Free Software Foundation, Inc.
024: * 59 Temple Place, Suite 330
025: * Boston, MA 02111-1307 USA
026: *
027: * @author Scott Ferguson
028: */
029:
030: package com.caucho.jsp.java;
031:
032: import com.caucho.jsp.JspParseException;
033: import com.caucho.util.L10N;
034: import com.caucho.vfs.WriteStream;
035: import com.caucho.xml.XmlChar;
036:
037: import java.io.IOException;
038: import java.util.HashMap;
039: import java.util.Map;
040:
041: /**
042: * Represents the root node.
043: */
044: public class JspTop extends JspContainerNode implements JspSegmentNode {
045: private static final L10N L = new L10N(JspTop.class);
046:
047: private boolean _hasRoot;
048: private int _maxFragmentIndex = -1;
049: private int _maxStaticFragmentIndex = -1;
050:
051: private HashMap<String, String> _namespaceMap = new HashMap<String, String>();
052: private HashMap<String, String> _revNamespaceMap = new HashMap<String, String>();
053:
054: /**
055: * Adds a text node.
056: */
057: public JspNode addText(String text) throws JspParseException {
058: // jsp/0705
059: if (true || !_hasRoot) {
060: JspNode node = new StaticText(_gen, text, this );
061:
062: addChild(node);
063:
064: return node;
065: } else {
066: for (int i = 0; i < text.length(); i++)
067: if (!XmlChar.isWhitespace(text.charAt(i)))
068: throw error(L
069: .l("JSP pages with <jsp:root> must not have text outside the <jsp:root>."));
070:
071: return null;
072: }
073: }
074:
075: /**
076: * Adds a child node.
077: */
078: public void addChild(JspNode child) throws JspParseException {
079: if (child instanceof JspRoot) {
080: _hasRoot = true;
081: _gen.setOmitXmlDeclaration(true);
082: }
083:
084: super .addChild(child);
085: }
086:
087: /**
088: * Set true if the node only has static text.
089: */
090: public boolean isStatic() {
091: for (int i = 0; i < _children.size(); i++) {
092: JspNode node = _children.get(i);
093:
094: if (!node.isStatic())
095: return false;
096: }
097:
098: return true;
099: }
100:
101: /**
102: * Returns the containing segment.
103: */
104: public JspSegmentNode getSegment() {
105: return this ;
106: }
107:
108: /**
109: * Returns the largest fragment index.
110: */
111: public int getMaxFragmentIndex() {
112: return _maxFragmentIndex;
113: }
114:
115: /**
116: * Sets the largest fragment index.
117: */
118: public void setMaxFragmentIndex(int index) {
119: if (_maxFragmentIndex < index)
120: _maxFragmentIndex = index;
121: }
122:
123: /**
124: * Returns the largest static fragment index.
125: */
126: public int getMaxStaticFragmentIndex() {
127: return _maxStaticFragmentIndex;
128: }
129:
130: /**
131: * Sets the largest static fragment index.
132: */
133: public void setMaxStaticFragmentIndex(int index) {
134: if (_maxStaticFragmentIndex < index)
135: _maxStaticFragmentIndex = index;
136: }
137:
138: /**
139: * Adds a namespace, e.g. from a prefix declaration.
140: */
141: @Override
142: public void addNamespaceRec(String prefix, String value) {
143: _namespaceMap.put(prefix, value);
144: _revNamespaceMap.put(value, prefix);
145: }
146:
147: /**
148: * Adds a namespace, e.g. from a prefix declaration.
149: */
150: @Override
151: public String getNamespacePrefix(String uri) {
152: return _revNamespaceMap.get(uri);
153: }
154:
155: /**
156: * Generates the XML text representation for the tag validation.
157: *
158: * @param os write stream to the generated XML.
159: */
160: public void printXml(WriteStream os) throws IOException {
161: if (_hasRoot) {
162: printXmlChildren(os);
163: return;
164: }
165:
166: /*
167: os.print("<jsp:root xmlns:jsp=\"http://java.sun.com/JSP/Page\">");
168: printXmlChildren(os);
169: os.print("</jsp:root>");
170: */
171: os.print("<jsp:root");
172: printJspId(os);
173: os.print(" version=\"2.0\"");
174: os.print(" xmlns:jsp=\"http://java.sun.com/JSP/Page\"");
175:
176: for (Map.Entry entry : _namespaceMap.entrySet()) {
177: os.print(" xmlns:" + entry.getKey() + "=\""
178: + entry.getValue() + "\"");
179: }
180: os.print(">");
181: printXmlChildren(os);
182: os.print("</jsp:root>");
183: }
184:
185: /**
186: * Returns true if the namespace decl has been printed.
187: */
188: public boolean hasNamespace(String prefix, String uri) {
189: if ("".equals(uri) && ("".equals(prefix) || prefix == null))
190: return true;
191: else
192: return false;
193: }
194:
195: /**
196: * Generates the code for the tag
197: *
198: * @param out the output writer for the generated java.
199: */
200: public void generate(JspJavaWriter out) throws Exception {
201: if (!_hasRoot) {
202: if (!_gen.isOmitXmlDeclaration()) {
203: String encoding = _gen.getCharacterEncoding();
204:
205: if (encoding == null)
206: encoding = "UTF-8";
207:
208: out.addText("<?xml version=\"1.0\" encoding=\""
209: + encoding + "\"?>\n");
210: }
211:
212: if (_gen.getDoctypeSystem() != null) {
213: out.addText("<!DOCTYPE ");
214: out.addText(_gen.getDoctypeRootElement());
215:
216: if (_gen.getDoctypePublic() != null) {
217: out.addText(" PUBLIC \"");
218: out.addText(_gen.getDoctypePublic());
219: out.addText("\" \"");
220: out.addText(_gen.getDoctypeSystem());
221: out.addText("\"");
222: } else {
223: out.addText(" SYSTEM \"");
224: out.addText(_gen.getDoctypeSystem());
225: out.addText("\"");
226: }
227:
228: out.addText(">\n");
229: }
230: }
231:
232: generateChildren(out);
233: }
234: }
|