KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sf > jguard > ext > authorization > manager > XmlAuthorizationManager


1 /*
2 jGuard is a security framework based on top of jaas (java authentication and authorization security).
3 it is written for web applications, to resolve simply, access control problems.
4 version $Name$
5 http://sourceforge.net/projects/jguard/
6
7 Copyright (C) 2004 Charles GAY
8
9 This library is free software; you can redistribute it and/or
10 modify it under the terms of the GNU Lesser General Public
11 License as published by the Free Software Foundation; either
12 version 2.1 of the License, or (at your option) any later version.
13
14 This library is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Lesser General Public License for more details.
18
19 You should have received a copy of the GNU Lesser General Public
20 License along with this library; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22
23
24 jGuard project home page:
25 http://sourceforge.net/projects/jguard/
26
27 */

28 package net.sf.jguard.ext.authorization.manager;
29
30 import java.io.FileWriter JavaDoc;
31 import java.io.IOException JavaDoc;
32 import java.io.OutputStream JavaDoc;
33 import java.security.Permission JavaDoc;
34 import java.security.Principal JavaDoc;
35 import java.util.ArrayList JavaDoc;
36 import java.util.Arrays JavaDoc;
37 import java.util.Collection JavaDoc;
38 import java.util.HashSet JavaDoc;
39 import java.util.Iterator JavaDoc;
40 import java.util.List JavaDoc;
41 import java.util.Map JavaDoc;
42 import java.util.Set JavaDoc;
43 import java.util.logging.Level JavaDoc;
44 import java.util.logging.Logger JavaDoc;
45
46 import net.sf.jguard.core.CoreConstants;
47 import net.sf.jguard.core.authorization.permissions.Domain;
48 import net.sf.jguard.core.authorization.permissions.JGPermissionCollection;
49 import net.sf.jguard.core.authorization.permissions.PermissionUtils;
50 import net.sf.jguard.core.principals.RolePrincipal;
51 import net.sf.jguard.ext.SecurityConstants;
52 import net.sf.jguard.ext.authorization.AuthorizationException;
53 import net.sf.jguard.ext.principals.PrincipalUtils;
54 import net.sf.jguard.ext.util.XMLUtils;
55
56 import org.dom4j.Attribute;
57 import org.dom4j.Document;
58 import org.dom4j.Element;
59 import org.dom4j.QName;
60 import org.dom4j.io.HTMLWriter;
61 import org.dom4j.io.OutputFormat;
62 import org.dom4j.io.XMLWriter;
63 import org.dom4j.util.UserDataAttribute;
64
65
66 /**
67  * AuthorizationManager implementation which enable Permission Management with an XML backend.
68  * @author <a HREF="mailto:diabolo512@users.sourceforge.net">Charles Gay</a>
69  * @author <a HREF="mailto:vinipitta@users.sourceforge.net">Vinicius Pitta Lima de Araujo</a>
70  */

71 public class XmlAuthorizationManager extends AbstractAuthorizationManager implements AuthorizationManager{
72     /** Logger for this class */
73     private static final Logger JavaDoc logger = Logger.getLogger(XmlAuthorizationManager.class.getName());
74
75     private Element root;
76     private Document document = null;
77     private String JavaDoc fileLocation;
78
79
80
81     /**
82      * constructor.
83      */

84     public XmlAuthorizationManager(){
85        super();
86     }
87
88     /**
89      * initialize this XML AuthorizationManager.
90      * @param options
91      * @see net.sf.jguard.ext.authorization.manager.AuthorizationManager#init(java.util.Properties)
92      */

93     public void init(Map JavaDoc options) {
94         super.init(options);
95         String JavaDoc applicationName= (String JavaDoc)options.get(CoreConstants.APPLICATION_NAME);
96         this.setApplicationName(applicationName);
97         super.options = options;
98         fileLocation = (String JavaDoc)options.get(SecurityConstants.AUTHORIZATION_XML_FILE_LOCATION);
99         if(fileLocation ==null ||"".equals(fileLocation)){
100             throw new IllegalArgumentException JavaDoc(SecurityConstants.AUTHORIZATION_XML_FILE_LOCATION+" argument for XMLAuthorizationManager is null or empty "+fileLocation);
101         }
102         init();
103
104     }
105
106
107     /**
108      * initialize permissions and Principals.
109      */

110     private void init() {
111         //remove white spaces on both ends
112
fileLocation = fileLocation.trim();
113         //replace the white space remaining in the internal string structure
114
// by the '%20' pattern
115
fileLocation = fileLocation.replaceAll(" ","%20");
116
117         if(logger.isLoggable(Level.FINEST)){
118             logger.finest("fileLocation="+fileLocation);
119         }
120         document = XMLUtils.read(fileLocation);
121         root = document.getRootElement();
122
123         initPermissions();
124         initPrincipals();
125     }
126
127
128     /**
129      * build Principals and associate to them their permissions.
130      */

131     private void initPrincipals() {
132
133          Element principalsElement = root.element("principals");
134             //convert a List into a Set because it is a functional requirement
135
//=> you can't have two same principals
136
List JavaDoc principalsElementList = principalsElement.elements("principal");
137             Iterator JavaDoc itPrincipals = principalsElementList.iterator();
138
139             while(itPrincipals.hasNext()){
140                 Element principalElement = (Element)itPrincipals.next();
141                 String JavaDoc className = principalElement.element("class").getStringValue();
142                 String JavaDoc name = null;
143                 
144                 if(className.equals(RolePrincipal.class.getName())){
145                     name = RolePrincipal.getName(principalElement.element("name").getStringValue(), applicationName);
146                  
147                 }else{
148                     name = principalElement.element("name").getStringValue();
149                 }
150                 Principal JavaDoc ppal = PrincipalUtils.getPrincipal(className,name);
151                 if(className.equals(RolePrincipal.class.getName())){
152                     buildJGuardPrincipal(principalElement, ppal);
153                 }
154                 //add principal created to the Principals Set
155
principalsSet.add(ppal);
156                 //add principal created to the principals map
157
principals.put(getLocalName(ppal),ppal);
158             }
159
160             assemblyHierarchy();
161     }
162
163
164     /**
165      * build permissions and domain maps.
166      */

167     private void initPermissions() {
168
169          Element domainsElement = root.element("permissions");
170          List JavaDoc domainsElementList = domainsElement.elements("domain");
171         Iterator JavaDoc itDomains = domainsElementList.iterator();
172
173         while(itDomains.hasNext()){
174             Element domainElement = (Element)itDomains.next();
175             String JavaDoc id = domainElement.element("name").getStringValue();
176             JGPermissionCollection domain = new Domain(id);
177             //add the new domain to the set
178
domainsSet.add(domain);
179             // add the new domain to the map
180
domains.put(id,domain);
181             //permissions domain's Set
182
Set JavaDoc permissionsDomain = new HashSet JavaDoc();
183             //dom4j elements list
184
List JavaDoc permissionsElementList = domainElement.elements("permission");
185             Iterator JavaDoc itPermissions = permissionsElementList.iterator();
186
187             //iterate over domain's permissions
188
while(itPermissions.hasNext()){
189                 Element permissionElement = (Element)itPermissions.next();
190                 Element actionsElement = permissionElement.element("actions");
191                 List JavaDoc actionsList = actionsElement.elements();
192                 Iterator JavaDoc itActions = actionsList.iterator();
193                 StringBuffer JavaDoc sbActions = new StringBuffer JavaDoc();
194                 int i = 0;
195                 while(itActions.hasNext()){
196                     String JavaDoc actionTemp = ((Element)itActions.next()).getText();
197                     if(i!=0){
198                       sbActions.append(',');
199                     }
200                     sbActions.append(actionTemp);
201                     i++;
202                 }
203                 String JavaDoc actions = sbActions.toString();
204                 String JavaDoc permissionName= permissionElement.element("name").getTextTrim();
205
206                 String JavaDoc className = ((Element)permissionElement.element("class")).getTextTrim();
207                 Permission JavaDoc perm = null;
208                 try {
209                     perm = PermissionUtils.getPermission(className,permissionName,actions);
210                 } catch (ClassNotFoundException JavaDoc e) {
211                     logger.warning(e.getMessage());
212                     continue;
213                 }
214                 //add the permission to her domain
215
domain.add(perm);
216
217                 //add the permission to the global map
218
permissions.put(perm.getName(),perm);
219                 permissionsSet.add(perm);
220                 //add the permission to the domain' permissions list
221
permissionsDomain.add(perm);
222
223             }
224             //add to the map the domain's id and his permissions
225
domainsPermissions.put(id,permissionsDomain);
226         }
227         super.urlp.addAll(permissionsSet);
228     }
229
230     /**
231      * return needed initialization parameters.
232      * @see net.sf.jguard.ext.authorization.manager.AuthorizationManager#getInitParameters()
233      */

234     public List JavaDoc getInitParameters() {
235         String JavaDoc[] authorizationParams = {"fileLocation"};
236        return Arrays.asList(authorizationParams);
237     }
238
239     /**
240      * create an URLPermission int the corresponding backend.
241      * @param permission Permission
242      * @throws AuthorizationException
243      * @see net.sf.jguard.ext.authorization.manager.AuthorizationManager#createPermission(java.security.Permission, java.lang.String)
244      */

245      public void createPermission(Permission JavaDoc permission,String JavaDoc domainName) throws AuthorizationException {
246          String JavaDoc[] actions = permission.getActions().split(",");
247
248          Element domainElement = (Element)root.selectSingleNode("//domain[name='"+domainName+"']");
249          //add the permissionElement reference to the domainElement
250
Element permissionElement = domainElement.addElement("permission");
251          Element nameElement = permissionElement.addElement("name");
252          nameElement.setText(permission.getName());
253          Element classElement = permissionElement.addElement("class");
254          classElement.setText(permission.getClass().getName());
255          Element actionsElement = permissionElement.addElement("actions");
256          for(int i= 0;i<actions.length;i++){
257              Element actionElement = actionsElement.addElement("action");
258              actionElement.setText(actions[i]);
259          }
260
261          //we retrieve the domain corresponding to the domainName
262
//and linking together the URLPermission newly created
263
//and it
264
permissions.put(permission.getName(),permission);
265          permissionsSet.add(permission);
266          urlp.add(permission);
267          //add the permission to the Domain
268
((JGPermissionCollection)domains.get(domainName)).add(permission);
269
270          try {
271             XMLUtils.write(fileLocation,document);
272         } catch (IOException JavaDoc e) {
273             logger.log(Level.SEVERE, "error when create permission "+permission,e);
274         }
275
276     }
277
278      /**
279       * create a new domain.
280       * @param domainName
281       * @see net.sf.jguard.ext.authorization.manager.AuthorizationManager#createDomain(java.lang.String)
282       */

283      public void createDomain(String JavaDoc domainName) throws AuthorizationException {
284
285          Element domainsElement = (Element)root.selectSingleNode("//permissions");
286           //add the permissionElement reference to the domainElement
287
Element domainElement = domainsElement.addElement("domain");
288           Element nameElement = domainElement.addElement("name");
289           nameElement.setText(domainName);
290           JGPermissionCollection domain = new Domain(domainName);
291           domains.put(domainName,domain);
292           domainsSet.add(domain);
293          try {
294              XMLUtils.write(fileLocation,document);
295         } catch (IOException JavaDoc e) {
296             logger.log(Level.SEVERE, "createDomain(String)", e);
297         }
298
299      }
300     /**
301      * replace the inital permission with the new one.
302      * @param oldPermissionName old permission name
303      * @param permission URLPermission updated
304      * @param newDomainName
305      * @see net.sf.jguard.ext.authorization.manager.AuthorizationManager#updatePermission(java.lang.String, java.security.Permission, java.lang.String)
306      */

307     public void updatePermission(String JavaDoc oldPermissionName, Permission JavaDoc permission,String JavaDoc newDomainName) throws AuthorizationException {
308         //we set the real domain to the updated permission and not a dummy one
309
deletePermission(oldPermissionName);
310         createPermission(permission,newDomainName);
311     }
312
313
314     /**
315      * remove the permission.
316      * @param permissionName
317      * @see net.sf.jguard.ext.authorization.manager.AuthorizationManager#deletePermission(java.lang.String)
318      */

319     public void deletePermission(String JavaDoc permissionName) throws AuthorizationException {
320         Element permissionElement = (Element)root.selectSingleNode("//permission[name='"+permissionName+"']");
321         Element domainElement = (Element)root.selectSingleNode("//permission[name='"+permissionName+"']/..");
322         domainElement.remove(permissionElement);
323         Permission JavaDoc oldPermission = (Permission JavaDoc)permissions.remove(permissionName);
324         Domain domain = getDomain(oldPermission);
325         domain.removePermission(oldPermission);
326         permissions.remove(oldPermission.getName());
327         permissionsSet.remove(oldPermission);
328         urlp.removePermission(oldPermission);
329         removePermissionFromPrincipals(permissionName);
330         updatePrincipals(domain);
331
332         try {
333             XMLUtils.write(fileLocation,document);
334         } catch (IOException JavaDoc e) {
335             logger.log(Level.SEVERE, "deletePermission(String)", e);
336         }
337     }
338
339
340     /**
341      * delete domain
342      * @param domainName name to delete
343      * @see net.sf.jguard.ext.authorization.manager.AuthorizationManager#deleteDomain(java.lang.String)
344      */

345     public void deleteDomain(String JavaDoc domainName) throws AuthorizationException {
346         domains.remove(domainName);
347         domainsSet.remove(new Domain(domainName));
348         Element domainsElement = (Element)root.selectSingleNode("//permissions");
349         Element domainElement = (Element)domainsElement.selectSingleNode("//domain[name='"+domainName+"']");
350         domainsElement.remove(domainElement);
351         super.removeDomainFromPrincipals(domainName);
352         try {
353             XMLUtils.write(fileLocation,document);
354         } catch (IOException JavaDoc e) {
355             logger.log(Level.SEVERE, "deleteDomain(String)", e);
356         }
357
358     }
359
360
361     /**
362      * create a new Role/principal
363      * @param principal principal/role to create
364      * @see net.sf.jguard.ext.authorization.manager.AuthorizationManager#createPrincipal(net.sf.jguard.core.principals.RolePrincipal)
365      */

366     public void createPrincipal(Principal JavaDoc principal) throws AuthorizationException {
367         Element principalsElement = root.element("principals");
368         //add the permissionElement reference to the domainElement
369
Element principalElement = principalsElement.addElement("principal");
370         Element nameElement = principalElement.addElement("name");
371         //add 'class' Element
372
Element classElement = principalElement.addElement("class");
373         classElement.setText(principal.getClass().getName());
374
375         nameElement.setText(getLocalName(principal));
376         principals.put(getLocalName(principal),principal);
377         principalsSet.add(principal);
378         if (principal.getClass().equals(RolePrincipal.class)){
379           RolePrincipal ppal = (RolePrincipal)principal;
380           insertPermissionsAndInheritance(principalElement, ppal);
381         }
382
383        try {
384            XMLUtils.write(fileLocation,document);
385       } catch (IOException JavaDoc e) {
386             logger.log(Level.SEVERE, "createRole(RolePrincipal)", e);
387       }
388
389     }
390
391     private void insertPermissionsAndInheritance(Element principalElement, RolePrincipal ppal) {
392         //add the orphaned permissions to the XML file
393
Element permsRefElement = principalElement.addElement("permissionsRef");
394         Set JavaDoc orphanedPerms = ppal.getOrphanedPermissions();
395         Iterator JavaDoc orphanedPermsIterator = orphanedPerms.iterator();
396         while(orphanedPermsIterator.hasNext()){
397             Permission JavaDoc perm = (Permission JavaDoc)orphanedPermsIterator.next();
398             Element permRef = permsRefElement.addElement("permissionRef");
399             //add the name attribute
400
Attribute nameAttribute = new UserDataAttribute(new QName("name"));
401             nameAttribute.setValue(perm.getName());
402             permRef.add(nameAttribute);
403         }
404
405         //add the permissions from domains to the XML file
406
Set JavaDoc doms = ppal.getDomains();
407         Iterator JavaDoc PermsFromDomainsIterator = doms.iterator();
408         while(PermsFromDomainsIterator.hasNext()){
409             Domain dom = (Domain)PermsFromDomainsIterator.next();
410             Element permRef = permsRefElement.addElement("domainRef");
411             //add the name attribute
412
Attribute nameAttribute = new UserDataAttribute(new QName("name"));
413             nameAttribute.setValue(dom.getName());
414             permRef.add(nameAttribute);
415         }
416
417         //role inheritance is only supported by RolePrincipal
418
if(ppal.getDescendants().size() > 0) {
419                 Element descendants = principalElement.addElement("descendants");
420
421                 //add the descendants of this role
422
for (Iterator JavaDoc descendantsIterator = ppal.getDescendants().iterator();
423                     descendantsIterator.hasNext(); ) {
424                     Element principalRef = descendants.addElement("principalRef");
425
426                     Attribute nameAttribute = new UserDataAttribute(new QName("name"));
427                     nameAttribute.setValue(((RolePrincipal) descendantsIterator.next()).getLocalName());
428                     principalRef.add(nameAttribute);
429                 }
430         }
431     }
432
433     /**
434      * remove the corrspoding principal/role
435      * @param principal name
436      * @see net.sf.jguard.ext.authorization.manager.AuthorizationManager#deletePrincipal(java.security.Principal)
437      */

438     public void deletePrincipal(Principal JavaDoc principal) throws AuthorizationException {
439         Principal JavaDoc ppalReference = (Principal JavaDoc)principals.remove(getLocalName(principal));
440         principalsSet.remove(ppalReference);
441         Element principalsElement = root.element("principals");
442         Element principalElement = (Element)principalsElement.selectSingleNode("//principal[name='"+getLocalName(principal)+"']");
443         principalsElement.remove(principalElement);
444         if(ppalReference.getClass().equals(RolePrincipal.class)){
445           deleteReferenceInHierarchy((RolePrincipal)ppalReference);
446           //delete all the references of this principal
447
XMLUtils.deletePrincipalRefs(root,(RolePrincipal)ppalReference);
448         }
449         try {
450             XMLUtils.write(fileLocation,document);
451         } catch (IOException JavaDoc e) {
452             logger.log(Level.SEVERE, "deleteRole(String)", e);
453         }
454     }
455
456
457
458     /**
459      * update the specified Domain.
460      * @param newName new name for the corresponding Domain
461      * @param oldName old name for the corresponding Domain
462      * @see net.sf.jguard.ext.authorization.manager.AuthorizationManager#updateDomain(java.lang.String, java.lang.String)
463      */

464     public void updateDomain(String JavaDoc newName, String JavaDoc oldName) throws AuthorizationException {
465
466         Domain domain = (Domain)domains.get(oldName);
467         domains.remove(oldName);
468         domainsSet.remove(domain);
469         domain.setName(newName);
470         domains.put(domain.getName(),domain);
471         domainsSet.add(domain);
472         this.updatePrincipals(domain, oldName);
473         Element domainsElement = (Element)root.selectSingleNode("//permissions");
474         Element domainElement = (Element)domainsElement.selectSingleNode("//domain[name='"+oldName+"']");
475         Element name =domainElement.element("name");
476         name.setText(newName);
477         try {
478             XMLUtils.write(fileLocation,document);
479         } catch (IOException JavaDoc e) {
480             logger.log(Level.SEVERE, "updateDomain(String, String)", e);
481         }
482     }
483
484     /**
485      * update a principal
486      * @param oldPrincipalName name of the principal to be replaced
487      * @param principal new principal
488      * @see net.sf.jguard.ext.authorization.manager.AuthorizationManager#updatePrincipal(java.lang.String, net.sf.jguard.core.principals.RolePrincipal)
489      */

490     public void updatePrincipal(String JavaDoc oldPrincipalName, Principal JavaDoc principal) throws AuthorizationException {
491         Principal JavaDoc oldPal = (Principal JavaDoc)principals.remove(oldPrincipalName);
492         principalsSet.remove(oldPal);
493         principals.put(getLocalName(principal),principal);
494         principalsSet.add(principal);
495
496         try {
497             XMLUtils.write(fileLocation,document);
498         } catch (IOException JavaDoc e) {
499             logger.log(Level.SEVERE, "updateRole(String, RolePrincipal)", e);
500         }
501     }
502
503
504
505
506
507     /**
508      * add specific object to RolePrincipal (permissions and domains references).
509      * @param principalElement
510      * @param ppal
511      */

512     private void buildJGuardPrincipal(Element principalElement, Principal JavaDoc ppal) {
513         RolePrincipal jp = (RolePrincipal)ppal;
514         Element pel = principalElement.element("permissionsRef");
515         Collection JavaDoc domainsPrincipal = pel.elements("domainRef");
516         Iterator JavaDoc itDomainsPrincipal = domainsPrincipal.iterator();
517         //domains names owned by this principal
518
Set JavaDoc domainNames = new HashSet JavaDoc();
519
520         //iterate over principal's domains
521
while(itDomainsPrincipal.hasNext()){
522             Element domainElement = (Element)itDomainsPrincipal.next();
523             String JavaDoc domainName = domainElement.attributeValue("name");
524             JGPermissionCollection domain = (JGPermissionCollection)domains.get(domainName);
525
526             if(domain==null){
527                 if (logger.isLoggable(Level.WARNING)) {
528                     logger.warning("initPrincipals() - principal "
529                         + jp.getLocalName()
530                         + " refers to a unknown domain name :"
531                         + domainName);
532                 }
533             }
534             if(!domainNames.contains(domainName)){
535                 domainNames.add(domainName);
536                 permissionsSet.addAll(domain.getPermissions());
537                 urlp.addAll(domain.getPermissions());
538                 jp.addDomain(domain);
539             }
540         }
541
542
543         Collection JavaDoc permissionsPrincipal = pel.elements("permissionRef");
544         Iterator JavaDoc itPermissionsPrincipal = permissionsPrincipal.iterator();
545
546         //iterate over permissions defined and add them to the principal permissions Set
547
while(itPermissionsPrincipal.hasNext()){
548             Element perm = (Element)itPermissionsPrincipal.next();
549             String JavaDoc permissionName=perm.attributeValue("name");
550             permissionsSet.add(permissions.get(permissionName));
551             Permission JavaDoc permission = (Permission JavaDoc)permissions.get(permissionName);
552             urlp.add(permission);
553             jp.addPermission(permission);
554             if(null == permission){
555                 if (logger.isLoggable(Level.WARNING)) {
556                     logger.warning("initPrincipals() - principal "
557                             + jp.getName()
558                             + " refers to a unknown permission name :"
559                             + permissionName);
560                 }
561             }
562         }
563         //store the links between ascendants
564
Element descendants = principalElement.element("descendants");
565         if (descendants != null) {
566               List JavaDoc descendantsElements = descendants.elements("principalRef");
567               Iterator JavaDoc itDescendantsElements = descendantsElements.iterator();
568               Collection JavaDoc descendantsNames = new ArrayList JavaDoc();
569               while(itDescendantsElements.hasNext()){
570                     Element descentantItem = (Element)itDescendantsElements.next();
571                     descendantsNames.add(principals.get(descentantItem.attributeValue("name")));
572               }
573
574               hierarchyMap.put(getLocalName(jp),descendantsNames);
575         }
576     }
577
578     /**
579      * @return <i>true</i> if there is no principals and no permissions.
580      * <i>false</i> otherwise.
581      */

582     public boolean isEmpty() {
583         List JavaDoc principalsList = root.selectNodes("//principal");
584         List JavaDoc permissions = root.selectNodes("//permissions");
585         if(!principalsList.isEmpty()&&!permissions.isEmpty()){
586             return false;
587         }
588         return true;
589     }
590     
591     public String JavaDoc exportAsXMLString(){
592         return this.document.asXML();
593     }
594
595     public void writeAsHTML(OutputStream JavaDoc outputStream) throws IOException JavaDoc {
596          HTMLWriter writer = new HTMLWriter(outputStream,OutputFormat.createPrettyPrint());
597          writer.write(this.document);
598          writer.flush();
599         
600     }
601     
602     public void writeAsXML(OutputStream JavaDoc outputStream, String JavaDoc encodingScheme) throws IOException JavaDoc {
603            OutputFormat outformat = OutputFormat.createPrettyPrint();
604            outformat.setEncoding(encodingScheme);
605            XMLWriter writer = new XMLWriter(outputStream, outformat);
606            writer.write(this.document);
607            writer.flush();
608     }
609     public void exportAsXMLFile(String JavaDoc fileName) throws IOException JavaDoc {
610         XMLWriter xmlWriter = new XMLWriter(new FileWriter JavaDoc(fileName), OutputFormat.createPrettyPrint());
611         xmlWriter.write(document);
612         xmlWriter.close();
613     }
614
615 }
616
Popular Tags