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.jsp.TagInstance;
034: import com.caucho.vfs.WriteStream;
035: import com.caucho.xml.QName;
036: import com.caucho.xml.XmlChar;
037:
038: import java.io.IOException;
039:
040: /**
041: * Represents a jsp:attribute node
042: */
043: public class JspAttribute extends JspFragmentNode {
044: private static final QName NAME = new QName("name");
045: private static final QName TRIM = new QName("trim");
046:
047: private QName _name;
048: private boolean _trim = true;
049: private TagInstance _tag;
050:
051: private boolean _oldScriptingInvalid;
052:
053: public JspAttribute() {
054: }
055:
056: /**
057: * Returns the attribute name.
058: */
059: public QName getName() {
060: return _name;
061: }
062:
063: /**
064: * Returns true if trimming is enabled.
065: */
066: public boolean isTrim() {
067: return _trim;
068: }
069:
070: /**
071: * Adds an attribute.
072: */
073: public void addAttribute(QName name, String value)
074: throws JspParseException {
075: if (NAME.equals(name))
076: _name = _gen.getParseState().getQName(value);
077: else if (TRIM.equals(name))
078: _trim = value.equals("true");
079: else
080: throw error(L.l(
081: "`{0}' is an unknown attribute for jsp:attribute.",
082: name));
083: }
084:
085: /**
086: * Called when the attributes end.
087: */
088: public void endAttributes() throws JspParseException {
089: _oldScriptingInvalid = _parseState.isScriptingInvalid();
090: // jsp/18di
091: // _parseState.setScriptingInvalid(true);
092:
093: super .endAttributes();
094: }
095:
096: /**
097: * Adds a text node.
098: */
099: public JspNode addText(String text) throws JspParseException {
100: JspNode node = new StaticText(_gen, text, this );
101:
102: addChild(node);
103:
104: return node;
105: }
106:
107: /**
108: * Adds an attribute.
109: */
110: public void endElement() throws JspParseException {
111: _parseState.setScriptingInvalid(_oldScriptingInvalid);
112:
113: if (_name == null)
114: throw error(L.l("jsp:attribute needs a `name' attribute."));
115:
116: if (_trim) {
117: prefix_loop: while (_children.size() > 0) {
118: JspNode node = (JspNode) _children.get(0);
119:
120: if (!(node instanceof StaticText))
121: break;
122:
123: StaticText textNode = (StaticText) node;
124:
125: String text = textNode.getText();
126:
127: for (int i = 0; i < text.length(); i++) {
128: if (!XmlChar.isWhitespace(text.charAt(i))) {
129: textNode.setText(text.substring(i));
130: break prefix_loop;
131: }
132: }
133:
134: _children.remove(0);
135: }
136:
137: suffix_loop: while (_children.size() > 0) {
138: JspNode node = _children.get(_children.size() - 1);
139:
140: if (!(node instanceof StaticText))
141: break;
142:
143: StaticText textNode = (StaticText) node;
144:
145: String text = textNode.getText();
146:
147: for (int i = text.length() - 1; i >= 0; i--) {
148: if (!XmlChar.isWhitespace(text.charAt(i))) {
149: textNode.setText(text.substring(0, i + 1));
150: break suffix_loop;
151: }
152: }
153:
154: _children.remove(_children.size() - 1);
155: }
156: }
157: }
158:
159: /**
160: * Returns the root tag instance of the root.
161: */
162: public TagInstance getTag() {
163: if (_tag == null)
164: _tag = new TagInstance(_gen.getTagManager());
165:
166: return _tag;
167: }
168:
169: /**
170: * Returns true if the children are static.
171: */
172: public boolean isStatic() {
173: return isChildrenStatic();
174: }
175:
176: /**
177: * Generates the XML text representation for the tag validation.
178: *
179: * @param os write stream to the generated XML.
180: */
181: public void printXml(WriteStream os) throws IOException {
182: os.print("<jsp:attribute name=\"" + _name + "\">");
183: printXmlChildren(os);
184: os.print("</jsp:attribute>");
185: }
186:
187: /**
188: * Generates the prologue.
189: */
190: public void generatePrologue(JspJavaWriter out) throws Exception {
191: JspNode parent = getParent();
192:
193: if (!isJspFragment()) {
194: generatePrologueChildren(out);
195: return;
196: }
197:
198: TagInstance parentTag = getParent().getTag();
199:
200: if (parentTag == null || parentTag.getId() == null) {
201: } else if (parentTag.isSimpleTag())
202: getTag().setId(TagInstance.FRAGMENT_WITH_SIMPLE_PARENT);
203: else
204: getTag().setId(TagInstance.FRAGMENT_WITH_TAG_PARENT);
205:
206: super .generatePrologue(out);
207: }
208:
209: /**
210: * Generates the fragment as a value.
211: */
212: String generateValue(Class type) throws Exception {
213: if (isStatic()) {
214: String text = getStaticText();
215:
216: if (_trim)
217: text = text.trim();
218:
219: return stringToValue(type,
220: '"' + escapeJavaString(text) + '"');
221: } else {
222: return stringToValue(type, generateValue());
223: }
224: }
225:
226: /**
227: * Generates the code for a fragment.
228: */
229: protected String generateValue() throws Exception {
230: if (!isStatic())
231: return super .generateValue();
232: else if (_trim)
233: return '"' + escapeJavaString(getStaticText().trim()) + '"';
234: else
235: return '"' + escapeJavaString(getStaticText()) + '"';
236: }
237: }
|