1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.apache.commons.jelly.tags.xml;
17
18 import org.apache.commons.jelly.JellyTagException;
19 import org.apache.commons.jelly.TagSupport;
20 import org.apache.commons.jelly.XMLOutput;
21 import org.xml.sax.Attributes;
22 import org.xml.sax.SAXException;
23 import org.xml.sax.helpers.AttributesImpl;
24
25 /*** A tag to produce an XML element which can contain other attributes
26 * or elements like the <code><xsl:element></code> tag.
27 *
28 * @author James Strachan
29 * @version $Revision: 1.5 $
30 */
31 public class ElementTag extends TagSupport {
32
33 /*** The namespace URI */
34 private String namespace;
35
36 /*** The qualified name */
37 private String name;
38
39 /*** The XML Attributes */
40 private AttributesImpl attributes = new AttributesImpl();
41
42 /*** flag set if attributes are output */
43 private boolean outputAttributes;
44
45 public ElementTag() {
46 }
47
48 /***
49 * Sets the attribute of the given name to the specified value.
50 *
51 * @param name of the attribute
52 * @param value of the attribute
53 * @throws JellyException if the start element has already been output.
54 * Attributes must be set on the outer element before any content
55 * (child elements or text) is output
56 */
57 public void setAttributeValue( String name, String value ) throws JellyTagException {
58 if (outputAttributes) {
59 throw new JellyTagException(
60 "Cannot set the value of attribute: "
61 + name + " as we have already output the startElement() SAX event"
62 );
63 }
64
65
66
67
68 int index = attributes.getIndex("", name);
69 if (index >= 0) {
70 attributes.removeAttribute(index);
71 }
72
73 if (value != null) {
74 attributes.addAttribute("", name, name, "CDATA", value);
75 }
76 }
77
78
79
80 public void doTag(XMLOutput output) throws JellyTagException {
81 int idx = name.indexOf(':');
82 final String localName = (idx >= 0)
83 ? name.substring(idx + 1)
84 : name;
85
86 outputAttributes = false;
87
88 XMLOutput newOutput = new XMLOutput(output) {
89
90
91
92 public void startElement(
93 String uri,
94 String localName,
95 String qName,
96 Attributes atts)
97 throws SAXException {
98 initialize();
99 super.startElement(uri, localName, qName, atts);
100 }
101
102 public void endElement(String uri, String localName, String qName)
103 throws SAXException {
104 initialize();
105 super.endElement(uri, localName, qName);
106 }
107
108 public void characters(char ch[], int start, int length) throws SAXException {
109 initialize();
110 super.characters(ch, start, length);
111 }
112
113 public void ignorableWhitespace(char ch[], int start, int length)
114 throws SAXException {
115 initialize();
116 super.ignorableWhitespace(ch, start, length);
117 }
118 public void processingInstruction(String target, String data)
119 throws SAXException {
120 initialize();
121 super.processingInstruction(target, data);
122 }
123
124 /***
125 * Ensure that the outer start element is generated
126 * before any content is output
127 */
128 protected void initialize() throws SAXException {
129 if (!outputAttributes) {
130 super.startElement(namespace, localName, name, attributes);
131 outputAttributes = true;
132 }
133 }
134 };
135
136 invokeBody(newOutput);
137
138 try {
139 if (!outputAttributes) {
140 output.startElement(namespace, localName, name, attributes);
141 outputAttributes = true;
142 }
143
144 output.endElement(namespace, localName, name);
145 attributes.clear();
146 } catch (SAXException e) {
147 throw new JellyTagException(e);
148 }
149 }
150
151
152
153
154 /***
155 * @return the qualified name of the element
156 */
157 public String getName() {
158 return name;
159 }
160
161 /***
162 * Sets the qualified name of the element
163 */
164 public void setName(String name) {
165 this.name = name;
166 }
167
168 /***
169 * @return the namespace URI of the element
170 */
171 public String getURI() {
172 return namespace;
173 }
174
175 /***
176 * Sets the namespace URI of the element
177 */
178 public void setURI(String namespace) {
179 this.namespace = namespace;
180 }
181 }