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: * Free SoftwareFoundation, Inc.
023: * 59 Temple Place, Suite 330
024: * Boston, MA 02111-1307 USA
025: *
026: * @author Scott Ferguson
027: */
028:
029: package com.caucho.jsp.java;
030:
031: import com.caucho.jsp.JspParseException;
032: import com.caucho.util.L10N;
033: import com.caucho.vfs.WriteStream;
034: import com.caucho.xml.QName;
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 JspRoot extends JspContainerNode {
045: static final L10N L = new L10N(JspRoot.class);
046:
047: static final private QName VERSION = new QName("version");
048:
049: private String _version;
050:
051: private HashMap<String, String> _namespaceMap = new HashMap<String, String>();
052:
053: private HashMap<String, String> _revNamespaceMap = new HashMap<String, String>();
054:
055: /**
056: * Sets the versino.
057: */
058: public void setVersion(String version) {
059: _version = version;
060: }
061:
062: /**
063: * Adds an attribute.
064: *
065: * @param name the attribute name
066: * @param value the attribute value
067: */
068: public void addAttribute(QName name, String value)
069: throws JspParseException {
070: if (VERSION.equals(name)) {
071: if (!value.equals("2.1") && !value.equals("2.0")
072: && !value.equals("1.2"))
073: throw error(L.l(
074: "'{0}' is an unsupported jsp:root version.",
075: value));
076:
077: _version = value;
078: } else {
079: throw error(L
080: .l(
081: "'{0}' is an unknown jsp:root attribute. 'version' is the only allowed JSP root value.",
082: name.getName()));
083: }
084: }
085:
086: /**
087: * Adds a text node.
088: */
089: public JspNode addText(String text) throws JspParseException {
090: for (int i = 0; i < text.length(); i++) {
091: if (!XmlChar.isWhitespace(text.charAt(i))) {
092: JspNode node = new StaticText(_gen, text, this );
093:
094: addChild(node);
095:
096: return node;
097: }
098: }
099:
100: return null;
101: }
102:
103: /**
104: * Called after all the attributes from the tag.
105: */
106: public void endAttributes() throws JspParseException {
107: _gen.setOmitXmlDeclaration(true);
108:
109: if (getParent() != null && !(getParent() instanceof JspTop))
110: throw error(L.l("jsp:root must be the root JSP element."));
111:
112: if (_version == null)
113: throw error(L
114: .l("'version' is a required attribute of jsp:root"));
115: }
116:
117: /**
118: * Adds a child node.
119: */
120: public void addChild(JspNode node) throws JspParseException {
121: super .addChild(node);
122: }
123:
124: /**
125: * Adds a namespace, e.g. from a prefix declaration.
126: */
127: @Override
128: public void addNamespaceRec(String prefix, String value) {
129: _namespaceMap.put(prefix, value);
130: _revNamespaceMap.put(value, prefix);
131: }
132:
133: /**
134: * Adds a namespace, e.g. from a prefix declaration.
135: */
136: @Override
137: public String getNamespacePrefix(String uri) {
138: return _revNamespaceMap.get(uri);
139: }
140:
141: /**
142: * Set true if the node only has static text.
143: */
144: public boolean isStatic() {
145: for (int i = 0; i < _children.size(); i++) {
146: JspNode node = _children.get(i);
147:
148: if (!node.isStatic())
149: return false;
150: }
151:
152: return true;
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: os
162: .print("<jsp:root xmlns:jsp=\"http://java.sun.com/JSP/Page\"");
163:
164: for (Map.Entry entry : _namespaceMap.entrySet()) {
165: os.print(" xmlns:" + entry.getKey() + "=\""
166: + entry.getValue() + "\"");
167: }
168:
169: printJspId(os);
170: os.print(" version=\"2.0\"");
171:
172: os.print(">");
173: printXmlChildren(os);
174: os.print("</jsp:root>");
175: }
176:
177: /**
178: * Generates the code for the tag
179: *
180: * @param out the output writer for the generated java.
181: */
182: public void generate(JspJavaWriter out) throws Exception {
183: if (!_gen.isOmitXmlDeclaration()) {
184: String encoding = _gen.getCharacterEncoding();
185:
186: if (encoding == null)
187: encoding = "UTF-8";
188:
189: out.addText("<?xml version=\"1.0\" encoding=\"" + encoding
190: + "\"?>\n");
191: }
192:
193: if (_gen.getDoctypeSystem() != null) {
194: out.addText("<!DOCTYPE ");
195: out.addText(_gen.getDoctypeRootElement());
196:
197: if (_gen.getDoctypePublic() != null) {
198: out.addText(" PUBLIC \"");
199: out.addText(_gen.getDoctypePublic());
200: out.addText("\" \"");
201: out.addText(_gen.getDoctypeSystem());
202: out.addText("\"");
203: } else {
204: out.addText(" SYSTEM \"");
205: out.addText(_gen.getDoctypeSystem());
206: out.addText("\"");
207: }
208:
209: out.addText(">\n");
210: }
211:
212: generateChildren(out);
213: }
214: }
|