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.cfg.TldAttribute;
034: import com.caucho.jsp.cfg.TldVariable;
035: import com.caucho.util.L10N;
036: import com.caucho.vfs.WriteStream;
037: import com.caucho.xml.QName;
038:
039: import java.io.IOException;
040: import java.util.ArrayList;
041:
042: public class JspDirectiveVariable extends JspNode {
043: private static final QName NAME_GIVEN = new QName("name-given");
044: private static final QName NAME_FROM_ATTRIBUTE = new QName(
045: "name-from-attribute");
046: private static final QName ALIAS = new QName("alias");
047: private static final QName VARIABLE_CLASS = new QName(
048: "variable-class");
049: private static final QName DECLARE = new QName("declare");
050: private static final QName SCOPE = new QName("scope");
051: private static final QName DESCRIPTION = new QName("description");
052:
053: static final L10N L = new L10N(JspDirectiveVariable.class);
054:
055: private String _nameGiven;
056: private String _nameFromAttribute;
057: private String _alias;
058: private String _variableClass;
059: private boolean _isDeclare = true;
060: private String _scope;
061: private String _description;
062:
063: /**
064: * Adds an attribute.
065: *
066: * @param name the attribute name
067: * @param value the attribute value
068: */
069: public void addAttribute(QName name, String value)
070: throws JspParseException {
071: if (!_gen.getParseState().isTag())
072: throw error(L
073: .l(
074: "'{0}' is only allowed in .tag files. Attribute directives are not allowed in normal JSP files.",
075: getTagName()));
076:
077: JavaTagGenerator gen = (JavaTagGenerator) _gen;
078: if (NAME_GIVEN.equals(name)) {
079: if (gen.findVariable(value) != null) {
080: throw error(L
081: .l(
082: "@variable name-given '{0}' is already used by another variable.",
083: value));
084: } else if (gen.findAttribute(value) != null) {
085: throw error(L
086: .l(
087: "@variable name-given '{0}' is already used by an attribute.",
088: value));
089: } else if (value.equals(gen.getDynamicAttributes())) {
090: throw error(L
091: .l(
092: "@variable name-given '{0}' cannot be the same as the tag's dynamic-attributes.",
093: value));
094: }
095:
096: _nameGiven = value;
097: } else if (NAME_FROM_ATTRIBUTE.equals(name)) {
098: if (gen.findVariable(value) != null) {
099: throw error(L
100: .l(
101: "@variable name-from-attribute '{0}' is already used by another variable.",
102: value));
103: }
104: /*
105: else if (gen.findAttribute(value) != null) {
106: throw error(L.l("@variable name-from-attribute '{0}' is already used by an attribute.",
107: value));
108: }
109: */
110:
111: _nameFromAttribute = value;
112: } else if (ALIAS.equals(name))
113: _alias = value;
114: else if (VARIABLE_CLASS.equals(name))
115: _variableClass = value;
116: else if (DECLARE.equals(name))
117: _isDeclare = attributeToBoolean(name.getName(), value);
118: else if (SCOPE.equals(name)) {
119: if (!"NESTED".equals(value) && !"AT_BEGIN".equals(value)
120: && !"AT_END".equals(value))
121: throw error(L
122: .l(
123: "'{0}' is an illegal scope value. NESTED, AT_BEGIN, and AT_END are the only accepted values.",
124: value));
125:
126: _scope = value;
127: } else if (DESCRIPTION.equals(name))
128: _description = value;
129: else {
130: throw error(L
131: .l(
132: "'{0}' is an unknown JSP variable directive attributes. Valid attributes are: alias, declare, description, name-from-attribute, name-given, scope, variable-class.",
133: name.getName()));
134: }
135: }
136:
137: /**
138: * When the element complets.
139: */
140: public void endElement() throws JspParseException {
141: if (!_gen.getParseState().isTag())
142: throw error(L
143: .l(
144: "'{0}' is only allowed in .tag files. Variable directives are not allowed in normal JSP files.",
145: getTagName()));
146:
147: if (_nameGiven == null && _nameFromAttribute == null)
148: throw error(L
149: .l(
150: "<{0}> needs a 'name-given' or 'name-from-attribute' attribute.",
151: getTagName()));
152:
153: if (_nameFromAttribute != null && _alias == null)
154: throw error(L
155: .l(
156: "<{0}> needs an 'alias' attribute. name-from-attribute requires an alias attribute.",
157: getTagName()));
158: if (_alias != null && _nameFromAttribute == null)
159: throw error(L
160: .l(
161: "<{0}> needs an 'name-from-attribute' attribute. alias requires a name-from-attribute attribute.",
162: getTagName()));
163:
164: JavaTagGenerator tagGen = (JavaTagGenerator) _gen;
165:
166: TldVariable var = new TldVariable();
167: var.setNameGiven(_nameGiven);
168: var.setNameFromAttribute(_nameFromAttribute);
169: var.setAlias(_alias);
170:
171: String name = _nameGiven;
172: if (name == null)
173: name = _nameFromAttribute;
174:
175: if (_variableClass != null)
176: var.setVariableClass(_variableClass);
177:
178: var.setDeclare(_isDeclare);
179: if (_scope != null)
180: var.setScope(_scope);
181:
182: tagGen.addVariable(var);
183: }
184:
185: /**
186: * Return true if the node only has static text.
187: */
188: public boolean isStatic() {
189: return true;
190: }
191:
192: /**
193: * Generates the XML text representation for the tag validation.
194: *
195: * @param os write stream to the generated XML.
196: */
197: public void printXml(WriteStream os) throws IOException {
198: os.print("<jsp:directive.variable");
199: os.print(" jsp:id=\"" + _gen.generateJspId() + "\"");
200:
201: if (_nameGiven != null)
202: os.print(" name-given=\"" + _nameGiven + "\"");
203:
204: if (_nameFromAttribute != null)
205: os.print(" name-from-attribute=\"" + _nameFromAttribute
206: + "\"");
207:
208: if (_variableClass != null)
209: os.print(" variable-class=\"" + _variableClass + "\"");
210:
211: os.print("/>");
212: }
213:
214: /**
215: * Generates the code for the tag
216: *
217: * @param out the output writer for the generated java.
218: */
219: public void generatePrologue(JspJavaWriter out) throws Exception {
220: JavaTagGenerator gen = (JavaTagGenerator) _gen;
221:
222: if (_nameFromAttribute == null)
223: return;
224:
225: ArrayList<TldAttribute> attributes = gen.getAttributes();
226: for (int i = 0; i < attributes.size(); i++) {
227: TldAttribute attr = attributes.get(i);
228:
229: if (!attr.getName().equals(_nameFromAttribute))
230: continue;
231:
232: if (!String.class.equals(attr.getType()))
233: throw error(L
234: .l(
235: "name-from-attribute variable '{0}' needs a matching String attribute, not '{1}' . name-from-attribute requires a matching String attribute.",
236: _nameFromAttribute, attr.getType()
237: .getName()));
238:
239: return;
240: }
241:
242: throw error(L
243: .l(
244: "name-from-attribute variable '{0}' needs a matching String attribute.",
245: _nameFromAttribute));
246: }
247:
248: /**
249: * Generates the code for the tag
250: *
251: * @param out the output writer for the generated java.
252: */
253: public void generate(JspJavaWriter out) throws Exception {
254: }
255: }
|