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