PolicyXMLNode | Line # 53 | 56 | 16 | 82.8% |
0.82828283
|
No Tests | |||
1 | /* | |
2 | * Copyright (c) 2000-2005, University of Salford | |
3 | * All rights reserved. | |
4 | * | |
5 | * Redistribution and use in source and binary forms, with or without | |
6 | * modification, are permitted provided that the following conditions are met: | |
7 | * | |
8 | * Redistributions of source code must retain the above copyright notice, this | |
9 | * list of conditions and the following disclaimer. | |
10 | * | |
11 | * Redistributions in binary form must reproduce the above copyright notice, | |
12 | * this list of conditions and the following disclaimer in the documentation | |
13 | * and/or other materials provided with the distribution. | |
14 | * | |
15 | * Neither the name of the University of Salford nor the names of its | |
16 | * contributors may be used to endorse or promote products derived from this | |
17 | * software without specific prior written permission. | |
18 | * | |
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |
20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | |
23 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
29 | * POSSIBILITY OF SUCH DAMAGE. | |
30 | */ | |
31 | ||
32 | package issrg.pba.rbac.xmlpolicy; | |
33 | ||
34 | import java.util.Iterator; | |
35 | import java.util.Map; | |
36 | ||
37 | /** | |
38 | * This is the class that represents the node of the XML Policy. Its subclasses | |
39 | * are used when parsing the Policy. | |
40 | * <p> | |
41 | * As the XMLPolicyParser has been written in 2000, the DOM3 classes were not | |
42 | * readily available with Java, so we went for a lightweight parser, SAX parser. | |
43 | * XMLPolicyParser is an extension of SAXParser, which builds a tree of | |
44 | * PolicyXMLNodes, similar to the trees of Nodes, built by modern DOM3 parsers. | |
45 | * XMLPolicyParser keeps a register of classes corresponding to each XML tag, | |
46 | * so when such tag is encountered in XML, a respective class is instantiated. | |
47 | * It is assumed that each class extends PolicyXMLNode. | |
48 | * | |
49 | * @author A Otenko | |
50 | * @version 1.0 | |
51 | */ | |
52 | ||
53 | public class PolicyXMLNode { | |
54 | /** | |
55 | * The name of the node. It can differ from what is actually stated in the | |
56 | * XML, | |
57 | * if the implementation desires. | |
58 | */ | |
59 | protected String name = ""; | |
60 | ||
61 | /** | |
62 | * This is the Map of element attributes by their names; each element is a | |
63 | * String. | |
64 | */ | |
65 | protected java.util.Map attributes = new java.util.Hashtable(); | |
66 | ||
67 | /** | |
68 | * This is a collection of the element children nodes; each element is of | |
69 | * the | |
70 | * PolicyXMLNode class. | |
71 | */ | |
72 | protected java.util.Vector children = new java.util.Vector(); | |
73 | ||
74 | /** | |
75 | * This is the string associated with the node. it is normally the string | |
76 | * that appears beteeen the opening | |
77 | * tag and the closing tag. For example, if | |
78 | * <Obligation> | |
79 | * This is the obligation node. | |
80 | * </Obligation> | |
81 | * string will be holding the String "This is the obligation node." | |
82 | */ | |
83 | protected String nodeStr=null; | |
84 | ||
85 | /** | |
86 | * This method adds more text that is read in blocks by the XML Parser. | |
87 | * This text is the text that appears between the opening and closing tags | |
88 | * of a XML element. | |
89 | * | |
90 | * @param str is the string associated with the node | |
91 | */ | |
92 | 7094 | public void addString(String str){ |
93 | 7094 | if (nodeStr==null) nodeStr=str; |
94 | 5793 | else nodeStr+=str; |
95 | } | |
96 | ||
97 | /** | |
98 | * This method returns the text contained between the opening and closing | |
99 | * tags of the element. | |
100 | * | |
101 | * <Obligation> | |
102 | * This is the text returned by this method | |
103 | * </Obligation> | |
104 | * | |
105 | * @return the String associated with the node | |
106 | */ | |
107 | 0 | public String getString(){ |
108 | 0 | return nodeStr; |
109 | } | |
110 | ||
111 | /** | |
112 | * This constructor builds a PolicyXMLNode with no name and no attributes. | |
113 | * This is equivalent to using PolicyXMLNode("", null) constructor. | |
114 | */ | |
115 | 0 | protected PolicyXMLNode(){ |
116 | 0 | _init_("", null); |
117 | } | |
118 | ||
119 | /** | |
120 | * This constructor builds a node with a given name, but no attributes. | |
121 | * | |
122 | * @param nodeName - the name of the XML element | |
123 | */ | |
124 | 0 | protected PolicyXMLNode(String nodeName){ |
125 | 0 | _init_(nodeName, null); |
126 | } | |
127 | ||
128 | /** | |
129 | * This method does the actual initialisation of the object and is invoked | |
130 | * by all the constructors. | |
131 | * | |
132 | * @param nodeName - the name of the XML element this object represents | |
133 | * @param attr - the collection of attributes of this XML element | |
134 | */ | |
135 | 2668 | private void _init_(String nodeName, org.xml.sax.Attributes attr){ |
136 | 2668 | name = nodeName; |
137 | ||
138 | //System.out.println("XML Node : "+ nodeName); | |
139 | ||
140 | 5229 | for (int i=0; i<attr.getLength(); i++){ |
141 | // System.out.println(":"+ attr.getQName(i) + "="+attr.getValue(i)); | |
142 | 2561 | attributes.put(attr.getQName(i), attr.getValue(i)); |
143 | } | |
144 | } | |
145 | ||
146 | /** | |
147 | * This constructor builds a node with the given name and a set of | |
148 | * attributes. | |
149 | * | |
150 | * @param nodeName - the name of the XML element | |
151 | * @param attr - the attributes of the XML element represented by this | |
152 | * object | |
153 | */ | |
154 | 2668 | public PolicyXMLNode(String nodeName, org.xml.sax.Attributes attr){ |
155 | 2668 | _init_(nodeName, attr); |
156 | } | |
157 | ||
158 | /** | |
159 | * This constructor builds a node with the given name and a set of | |
160 | * attributes, | |
161 | * though, the attributes are in a different form. | |
162 | * | |
163 | * @param nodeName - the name of the XML element | |
164 | * @param attrs - the Map of attributes of the XML element represented by | |
165 | * this object | |
166 | */ | |
167 | 0 | public PolicyXMLNode(String nodeName, java.util.Map attrs){ |
168 | 0 | name = nodeName; |
169 | 0 | attributes = attrs; |
170 | } | |
171 | ||
172 | /** | |
173 | * This method adds another child to the collection of children. It should | |
174 | * be | |
175 | * called before the call to the <code>construct</code> method to have any | |
176 | * effect. | |
177 | * | |
178 | * @see #construct() | |
179 | * | |
180 | * @param child is the node to append as a child node at the end of the list | |
181 | * of children | |
182 | */ | |
183 | 2643 | public void addChild(PolicyXMLNode child){ |
184 | 2643 | children.add(child); |
185 | } | |
186 | ||
187 | /** | |
188 | * This method returns the name of the node, so you could walk down the | |
189 | * tree, | |
190 | * if you wanted. | |
191 | * | |
192 | * @return String name of the XML element represented by this object | |
193 | */ | |
194 | 2243 | public String getName(){ |
195 | 2243 | return name; |
196 | } | |
197 | ||
198 | /** | |
199 | * This method returns the collection of attributes for this node; for | |
200 | * walking the tree. | |
201 | * | |
202 | * @return Map of the attributes of this XML element | |
203 | */ | |
204 | 2921 | public java.util.Map getAttributes(){ |
205 | 2921 | return attributes; |
206 | } | |
207 | ||
208 | /** | |
209 | * This method returns the collection of children. Each of the objects of | |
210 | * the | |
211 | * Vector is of type PolicyXMLNode. | |
212 | * | |
213 | * @return Vector of children of this XML element; never null, but may be | |
214 | * empty, if there are no children of this element | |
215 | */ | |
216 | 1134 | public java.util.Vector getChildren(){ |
217 | 1134 | return children; |
218 | } | |
219 | ||
220 | /** | |
221 | * This method is called when the node is closed. It performs the actual | |
222 | * semantic loading of the node. Without it, the implementations may assume | |
223 | * they are not ready to be used. | |
224 | * <p> | |
225 | * This method does nothing by default, and should be overridden. | |
226 | * | |
227 | * @throws PolicyParsingException if any syntax or semantics error occurred | |
228 | */ | |
229 | 1868 | public void construct() throws issrg.pba.rbac.PolicyParsingException { |
230 | } | |
231 | ||
232 | /** | |
233 | * @return a string representation of this XML element; by default returns | |
234 | * the XML representation of it | |
235 | */ | |
236 | 2947 | public String toString(){ |
237 | 2947 | return toXML(); |
238 | } | |
239 | ||
240 | ||
241 | /** | |
242 | * This function returnes the XML representation of the XML element. It | |
243 | * outputs the internal structure to | |
244 | * XML text. The text is not a complete XML file as it does not include | |
245 | * the XML headers, etc. It only generates | |
246 | * the text as a component of an XML file, thus it's the text of the | |
247 | * subtree begining with the current node. | |
248 | * | |
249 | * Example Output: | |
250 | * | |
251 | * <pre><Obligations> | |
252 | * <Obligation ObligationID="111" Chronicle="BeforeEnforcement"/> | |
253 | * <Obligation ObligationID="123" Chronicle="BeforeEnforcement"> | |
254 | * Any Text here representing the chilldren of the obligation 123. | |
255 | * </Obligation> | |
256 | * </Obligations></pre> | |
257 | */ | |
258 | 2947 | public String toXML() { |
259 | 2947 | StringBuffer xmlStr=new StringBuffer(); |
260 | 2947 | toXML(xmlStr, "", null); |
261 | 2947 | return xmlStr.toString(); |
262 | } | |
263 | ||
264 | /** | |
265 | * This method converts the node to XML text with the specified indent | |
266 | * for the current node and the indent increment for children nodes. | |
267 | * | |
268 | * @param xmlStr - the StringBuffer to output the XML text to | |
269 | * @param currentIndent - the indent for the current node; if null, no | |
270 | * indentation is performed for this node, or any children, and the | |
271 | * whole piece of XML will be output as a single line | |
272 | * @param indentIncrement - the increment of indentation between the current | |
273 | * node and its childrent; has no effect, if the currentIndent is null; | |
274 | * if this value is null, two white spaces are used as the indentation | |
275 | * | |
276 | * @return the XML text of the node with all of its children | |
277 | */ | |
278 | 24786 | public void toXML(StringBuffer xmlStr, String currentIndent, String indentIncrement){ |
279 | 24786 | if (indentIncrement==null) indentIncrement=" "; |
280 | ||
281 | 24786 | if (currentIndent!=null) xmlStr.append(currentIndent); |
282 | 24786 | xmlStr.append("<"); |
283 | 24786 | xmlStr.append(this.name); |
284 | // now: | |
285 | // ...(indent)...<TAG | |
286 | ||
287 | //begin to add attributes. | |
288 | 24786 | Iterator entryIter=this.attributes.entrySet().iterator(); |
289 | 24786 | Map.Entry entry=null; |
290 | ||
291 | //generate all the text for all attributes | |
292 | 24786 | if(entryIter!=null){ |
293 | 52394 | while(entryIter.hasNext()){ |
294 | 27608 | entry=(Map.Entry) entryIter.next(); |
295 | 27608 | xmlStr.append(" "); |
296 | 27608 | xmlStr.append((String)entry.getKey()); |
297 | 27608 | xmlStr.append("=\""); |
298 | 27608 | xmlStr.append((String)entry.getValue()); // assume the values do not require escaping! |
299 | 27608 | xmlStr.append("\""); |
300 | } | |
301 | } | |
302 | // now: | |
303 | // ...(indent)...<TAG ATTRIBUTE="VALUE" ATTRIBUTE="VALUE" ... | |
304 | ||
305 | 24786 | if(children.size()<1 && (this.nodeStr==null || this.nodeStr.length()==0)){ |
306 | // no children, no text - just close the tag | |
307 | 13804 | xmlStr.append("/"); |
308 | // now: | |
309 | // ...(indent)...<TAG ATTRIBUTE="VALUE" .../ | |
310 | }else{ | |
311 | 10982 | xmlStr.append(">"); |
312 | 10982 | if (currentIndent!=null){ |
313 | 10982 | xmlStr.append("\n"); |
314 | } | |
315 | // now: | |
316 | // ...(indent)...<TAG ATTRIBUTE="VALUE" ...> | |
317 | ||
318 | 10982 | if (this.nodeStr!=null){ // append text, if it exists |
319 | 10982 | xmlStr.append(this.nodeStr); |
320 | 10982 | if (currentIndent!=null){ |
321 | 10982 | xmlStr.append("\n"); |
322 | } | |
323 | } | |
324 | // now: | |
325 | // ...(indent)...<TAG ATTRIBUTE="VALUE" ...> | |
326 | // TEXT (if any) | |
327 | ||
328 | 10982 | String newIndent=currentIndent==null?null:(currentIndent+indentIncrement); |
329 | ||
330 | 32821 | for(int i=0;i <this.children.size();i++){ |
331 | 21839 | PolicyXMLNode node=(PolicyXMLNode)children.get(i); |
332 | 21839 | node.toXML(xmlStr, newIndent, indentIncrement); //recursively genereated child XML text |
333 | 21839 | if (currentIndent!=null){ |
334 | 21839 | xmlStr.append("\n"); |
335 | } | |
336 | } | |
337 | // now: | |
338 | // ...(indent)...<TAG ATTRIBUTE="VALUE" ...> | |
339 | // TEXT (if any) | |
340 | // ......(new indent)...<CHILDTAG ........./>(if any) | |
341 | // ......(new indent)...<CHILDTAG ........./> | |
342 | // ... | |
343 | 10982 | if (currentIndent!=null) xmlStr.append(currentIndent); |
344 | ||
345 | 10982 | xmlStr.append("</"); |
346 | 10982 | xmlStr.append(name); |
347 | // now: | |
348 | // ...(indent)...<TAG ATTRIBUTE="VALUE" ...> | |
349 | // TEXT (if any) | |
350 | // ......(new indent)...<CHILDTAG ........./>(if any) | |
351 | // ... | |
352 | // ...(indent)...</TAG | |
353 | } | |
354 | ||
355 | 24786 | xmlStr.append(">"); |
356 | // now: | |
357 | // ...(indent)...<TAG ATTRIBUTE="VALUE" ...> | |
358 | // TEXT (if any) | |
359 | // ......(new indent)...<CHILDTAG ........./>(if any) | |
360 | // ... | |
361 | // ...(indent)...</TAG> | |
362 | // | |
363 | // or, if no text and no children | |
364 | // | |
365 | // ...(indent)...<TAG ATTRIBUTE="VALUE" .../> | |
366 | } | |
367 | } |
|