KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > enterprise > admin > util > XMLAlterUtil


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23
24 /*
25  * Copyright 2004-2005 Sun Microsystems, Inc. All rights reserved.
26  * Use is subject to license terms.
27  */

28 package com.sun.enterprise.admin.util;
29
30 import org.w3c.dom.*;
31 import javax.xml.parsers.*;
32 import java.lang.reflect.*;
33 import java.io.*;
34 import javax.xml.transform.stream.*;
35 import javax.xml.transform.*;
36 import javax.xml.transform.dom.*;
37
38
39 import org.xml.sax.helpers.DefaultHandler JavaDoc;
40 import org.xml.sax.InputSource JavaDoc;
41 import org.xml.sax.SAXException JavaDoc;
42
43 /**
44 * This program is a utility to alter XML documents that need to be changed when
45 * implementing the S1AS SE/EE version on the PE base. XSLT was deemed to be verbose
46 * error prone and did not have the required funtionality when working at the attribute
47 * level. The XML document that governs the changes made to the base XML document is
48 * constrained by an XML Shema which is called change.xsd
49 * <br>
50 * This program is meant to be modified to address and needs that are encounted in altering
51 * all the base XML documents.
52 * <br>
53 * A sample XML change document could look like this
54 *
55 * <?xml version="1.0"?>
56 * <alterations xmlns="http://java.sun.com/j2ee/s1as8se/node_agent"
57 * xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="change.xsd">
58 *
59 * <alteration type="FIRST_OCCURRENCE" elementName="mbean" dnType="attribute" dnName="name" dnValue="node-controllers">
60 * <addAttribute name="classname" value="com.sun.enterprise.ee.nodeagent.mbeans.NodeAgentConfigMBean"/>
61 * <addAttribute name="value" value="someValue"/>
62 * <changeAttribute name="group" value="configxxxx"/>
63 * </alteration>
64 * <alteration type="ALL" elementName="mbean">
65 * <addAttribute name="target" value="TESTTEST"/>
66 * </alteration>
67 * <alteration type="ALL" elementName="mbean" dnType="attribute" dnName="name" dnValue="applications">
68 * <removeElement/>
69 * </alteration>
70 * </alterations>
71 *
72 * @author
73 */

74
75 class NOOPHandler extends DefaultHandler JavaDoc {
76    
77     static String JavaDoc _dtdFileName;
78     
79     NOOPHandler(String JavaDoc dtdFileName) {
80         super();
81         _dtdFileName = dtdFileName;
82     }
83
84     public InputSource JavaDoc resolveEntity(String JavaDoc publicId,
85          String JavaDoc systemId) throws SAXException JavaDoc
86     {
87         InputSource JavaDoc is = null;
88         try {
89             is = new InputSource JavaDoc(new FileInputStream(_dtdFileName));
90         } catch(Exception JavaDoc e) {
91             throw new SAXException JavaDoc("cannot resolve dtd", e);
92         }
93         return is;
94     }
95
96 }
97
98 public class XMLAlterUtil {
99     
100     /**
101     * main - Static invocation method, could also be used programatically.
102     * Proper Usage: java XMLAlterUtil BASE_DOCUMENT_TO_CHANGE CHANGES_DOCUMENT OUTPUT_DOCUMENT
103     *
104     * @param args - command line arguments
105     */

106     public static void main(String JavaDoc[] args) {
107         try {
108             // minimal check for proper usage
109
if (args.length != 4) {
110                 System.out.println("Proper Usage: java XMLAlterUtil BASE_DOCUMENT_TO_CHANGE BASE_DOCUMENT_DTD CHANGES_DOCUMENT OUTPUT_DOCUMENT");
111                 System.exit(1);
112             }
113                     
114             String JavaDoc baseXML=args[0];
115             String JavaDoc baseDTD=args[1];
116             String JavaDoc changeXML=args[2];
117             String JavaDoc outXML=args[3];
118             
119             if (System.getProperty("Debug") != null) {
120                 bDebug=true;
121             }
122             
123             XMLAlterUtil xau=new XMLAlterUtil();
124             
125             // read in documents
126
if (bDebug) System.out.println("parsing - " + baseXML);
127             Document baseDoc=null;
128             if(baseDTD.equals("null")) {
129                 baseDoc=xau.readDOM(baseXML);
130             } else {
131                 baseDoc=xau.readDOM(baseXML, baseDTD);
132             }
133             
134             if (bDebug) System.out.println("parsing - " + changeXML);
135             Document changeDoc=xau.readDOM(changeXML);
136             
137             // execute alterations on base document
138
xau.alterDOM(baseDoc, changeDoc);
139             
140             // baseDoc should be altered
141
DocumentType baseDocType=baseDoc.getDoctype();
142             
143             String JavaDoc doctype_system=null, doctype_public=null;
144             if (baseDocType != null) {
145                 doctype_system=baseDocType.getSystemId();
146                 doctype_public=baseDocType.getPublicId();
147             }
148             
149             xau.writeDOM(baseDoc, outXML, doctype_system, doctype_public);
150             
151         } catch (Exception JavaDoc e) {
152             e.printStackTrace();
153         }
154     }
155
156
157
158     /**
159     * alterDOM - method that executes the required changes to the base document
160     *
161     * @param baseDoc - A DOM of the base document that is going to be altered by reference
162     * @param changeDoc - A DOM of the changes that are constrained by the change.xsd schema
163     */

164     public void alterDOM(Document baseDoc, Document changeDoc) throws Exception JavaDoc {
165
166         // get root elements for both documents
167
Element baseRoot=baseDoc.getDocumentElement();
168         Element changeRoot=changeDoc.getDocumentElement();
169         
170         NodeList nlx, bnl, bnlx;
171         Node bNode, bNodex;
172         Element cElement, bElement, bElementx;
173         String JavaDoc elementName, type, dnType, dnName, dnValue, dnModifier, bAttrValue;
174
175         //
176
// get list of alterations that have to be made
177
NodeList nl=changeRoot.getElementsByTagName("alteration");
178         boolean matched=false;
179     
180         if (bDebug) System.out.println("\n** Base Root Node Name is '" + baseRoot.getNodeName() + "' **");
181         
182         for(int ii=0; ii < nl.getLength(); ii++) {
183             
184             // get alteration specifics to change
185
cElement=(Element)nl.item(ii);
186
187             // get the method for identifying the element to change
188
matched=false;
189             elementName=cElement.getAttribute("elementName");
190             type=cElement.getAttribute("type");
191             dnType=cElement.getAttribute("dnType");
192             dnName=cElement.getAttribute("dnName");
193             dnValue=cElement.getAttribute("dnValue");
194             dnModifier=cElement.getAttribute("dnModifier");
195                           
196             if (bDebug) System.out.println("\n** Trying to match an element '" + elementName + "' with dnType='"
197                 + dnType + "', dnName='" + dnName + "' and dnValue='" + dnValue + "'");
198             
199             //
200
// search through base document to see if a match can be found
201
if (elementName.equals(baseRoot.getNodeName())) {
202                 // match is to root node so get proper node list
203
bnl=baseDoc.getElementsByTagName(elementName);
204             } else {
205                 bnl=baseRoot.getElementsByTagName(elementName);
206             }
207             
208             if (bDebug) System.out.println("\n\tFound " + bnl.getLength() + " elements to match to.");
209             for (int jj=0; jj < bnl.getLength(); jj++) {
210             
211                 // make sure it is an element
212
if (bnl.item(jj) instanceof Element) {
213                     
214                     // caste into element to use attribute functionality
215
bElement=(Element)bnl.item(jj);
216                     
217                     // match the element with critera
218
if (dnType.equals("attribute")) {
219                         // match on attrbute get name
220

221                         // get value for attribute, if it doesn't exist
222
// it will return an empty String
223
bAttrValue=bElement.getAttribute(dnName);
224                         
225                         if ( matchValue(bAttrValue, dnValue, dnModifier) ) {
226                             // match found, execute change
227
if (bDebug) System.out.println("\n\tFound match on Attibute! Executing alteration...");
228                             matched=true;
229                             executeAlteration(bElement, cElement);
230                         }
231                     
232                     } else if(dnType.equals("text")) {
233                         // text match, retrieve text from element
234
bnlx=bElement.getChildNodes();
235                         for (int mm=0; mm < bnlx.getLength(); mm++) {
236                             if (bnlx.item(mm) instanceof Text) {
237                                 if (bDebug) System.out.println("Text - '" + bnlx.item(mm).getNodeValue() + "'");
238
239                                 if ( matchValue(bnlx.item(mm).getNodeValue(), dnValue, dnModifier) ) {
240                                     // match found, execute change
241
if (bDebug) System.out.println("\n\tFound match on Text! Executing alteration...");
242                                     matched=true;
243                                     executeAlteration(bElement, cElement);
244                                 }
245                             }
246                         }
247                         
248                     } else if(dnType.equals("")) {
249                         // no match type, so must be for all
250
if (bDebug) System.out.println("\n\tMatch on All! Executing alteration...");
251                         matched=true;
252                         executeAlteration(bElement, cElement);
253                     }
254                 }
255                 
256                 // check to see how many time a change should be performes
257
if (type.equals("FIRST_OCCURRENCE") && matched) {
258                     // since match found and type is set to FIRST_OCCURRENCE, break out of loop
259
break;
260                 }
261             }
262         }
263     }
264     
265
266     /**
267     * matchValue - Method that executes the matching strategies that are identified by the dnModifier.
268     * The default modifier is "equals"
269     * @param targetString - Target string to be matched.
270     * @param dnValue - Value used in match
271     * @param dnModifier - Modifier used in match could be startsWith, endsWith, contains or equals.
272     * equals is the default modifier.
273     *
274     * @return boolean - Returns true if there is a match, or false if not
275     */

276     public boolean matchValue(String JavaDoc targetString, String JavaDoc dnValue, String JavaDoc dnModifier) {
277         boolean bRet=false;
278         if (dnModifier.equals("startsWith")) {
279             // startWith
280
bRet=targetString.startsWith(dnValue);
281         } else if (dnModifier.equals("endsWith")) {
282             // endsWith
283
bRet=targetString.endsWith(dnValue);
284         
285         } else if (dnModifier.equals("contains")) {
286             // contains
287
bRet=targetString.indexOf(dnValue) >= 0 ? true : false;
288         
289         } else {
290             // direct match
291
bRet=targetString.equals(dnValue);
292         }
293         return bRet;
294     }
295     
296
297     /**
298     * executeAlteration - This method makes the alterations that are passed as an argument to
299     * the base element that is also passed in
300     *
301     * @param bElement - Base element that matches the change criteria. The changes are returned by reference
302     * @param cElement - Changes that are required to be performed
303     */

304     public void executeAlteration(Element bElement, Element cElement) throws Exception JavaDoc {
305
306         // get alterations that need to be done to the item identified from
307
// the above information
308
NodeList nlx=cElement.getChildNodes();
309         NodeList nlChild;
310         Element cElementx;
311
312         // loop so multiple changes can be performed on the same element
313
for(int kk=0; kk < nlx.getLength(); kk++) {
314             // compile alteration that is required to be done
315
if (nlx.item(kk) instanceof Element) {
316                 cElementx=(Element)nlx.item(kk);
317                 if (bDebug) System.out.println("\n\t* Performing Action - " + cElementx.getTagName());
318
319                 // now see what action needs to be taken on the identified element
320
if (cElementx.getTagName().equals("addAttribute") ||
321                     cElementx.getTagName().equals("changeAttribute") ) {
322                         
323                     // add or change attribute to the element
324
bElement.setAttribute(cElementx.getAttribute("name"),cElementx.getAttribute("value"));
325
326                 } else if (cElementx.getTagName().equals("prefixAttribute") ||
327                     cElementx.getTagName().equals("suffixAttribute")) {
328                         String JavaDoc attName=cElementx.getAttribute("name");
329                         
330                         // set newValue so it will be added if it doesn't already exist
331
String JavaDoc newValue=cElementx.getAttribute("value");
332                         
333                         // see if the attibute exists
334
if(bElement.hasAttribute(attName)) {
335                             // attribute exists add value in proper place
336
if(cElementx.getTagName().equals("prefixAttrbute")) {
337                                 // prefix new value on to attribute
338
newValue=newValue + bElement.getAttribute(attName) ;
339                             } else {
340                                 // append new value on to attribute attribute
341
newValue=bElement.getAttribute(attName) + newValue;
342                             }
343                         }
344                         if (bDebug) System.out.println("\n\t" + cElementx.getTagName() + " attribute:" + attName
345                             + " final value is " + newValue);
346                         // set attribute with value
347
bElement.setAttribute(attName, newValue);
348
349                 } else if (cElementx.getTagName().equals("deleteAttrbute")) {
350                     // delete attribute
351
bElement.removeAttribute(cElementx.getAttribute("name"));
352
353                 } else if (cElementx.getTagName().equals("removeElement")) {
354                     // remove element from parents perspective
355
bElement.getParentNode().removeChild(bElement);
356                     // don't continue with changes if there are more,
357
// element is gone
358
break;
359                 } else if (cElementx.getTagName().equals("addElement")) {
360                     // add element(s) as children to the parent that are hardcoded under
361
// the addElement or that are stored in a file
362
Node importedNode=null;
363
364                     String JavaDoc docFragFile=cElementx.getAttribute("file");
365                     if (!docFragFile.equals("")) {
366                         // get elements for input from file
367
try {
368                             Document docFrag=readDOM(docFragFile);
369                             importedNode=bElement.getOwnerDocument().importNode(docFrag.getDocumentElement(),true);
370                             //bElement.appendChild(bElement.getOwnerDocument().importNode(docFrag.getDocumentElement(),true));
371
} catch (Exception JavaDoc ee) {
372                             if (bDebug) System.out.println("Exception encounted when reading/inserting fragment '" + docFragFile + "'***");
373                             throw ee;
374                         }
375
376                     } else {
377                         // get elements to append from addElement children
378
NodeList nlxx=cElementx.getChildNodes();
379
380                         // loop so can add multiple elements that may be the children of addElement
381
for(int ll=0; ll < nlxx.getLength(); ll++) {
382                             // compile alteration that is required to be done
383
if (nlxx.item(ll) instanceof Element) {
384                                 importedNode=bElement.getOwnerDocument().importNode(nlxx.item(ll),true);
385                                 //bElement.appendChild(bElement.getOwnerDocument().importNode(nlxx.item(ll),true));
386
}
387                         }
388                     }
389
390                     //
391
// find where to insert the imported node
392
String JavaDoc location=cElementx.getAttribute("location");
393                     String JavaDoc dnType=cElementx.getAttribute("dnType");
394                     String JavaDoc dnName=cElementx.getAttribute("dnName");
395                     String JavaDoc eName="null";
396                     Node lNode=null;
397                     Element lElement=null, nElement=null;
398
399                     if (bDebug) System.out.println("\n\t\tAddElement Match with location='" + location + "' with dnType='" + dnType + "' and dnName='" + dnName + "'");
400
401                     if (location.equals("first")) {
402                         // add the element to the beginning of the parent element
403
bElement.insertBefore(importedNode,bElement.getFirstChild());
404
405                     } else if (location.equals("before")) {
406                         // insert before the dnType element specified in dnName
407
if (dnType.equals("element")) {
408                             lNode=bElement.getFirstChild();
409                             while (lNode != null) {
410                                 if (lNode instanceof Element) {
411                                     lElement=(Element)lNode;
412                                     if (lElement.getNodeName().equals(dnName)) {
413                                         // if match is found, break and insert
414
break;
415                                     }
416                                 }
417
418                                 // go to next sibling in order
419
lNode=lNode.getNextSibling();
420                                }
421
422                            // if match is not found, node will be place at the end
423
bElement.insertBefore(importedNode,lNode);
424
425                         } else {
426                             throw new UnsupportedOperationException JavaDoc("Only addElement that has a location set to 'before' only supports a dnType of 'element'");
427                         }
428
429                     } else if (location.equals("after")) {
430                         // insert after the dnType element specified in dnName
431
if (dnType.equals("element")) {
432                             lNode=bElement.getFirstChild();
433                             boolean loop=true;
434
435                             // look for element that matches dnName
436
while (lNode != null) {
437                                 //if (bDebug) System.out.println("\n\t\tAddElement After - looking for match in node - " + lNode.getNodeName());
438
if (lNode instanceof Element) {
439                                     lElement=(Element)lNode;
440                                     if (lElement.getNodeName().equals(dnName)) {
441                                         if (bDebug) System.out.println("\n\t\t\tMatch found on element for dnName='" + dnName + "', look for next element that is different");
442
443                                         // match is found, since it is "after" loop until you get an "Element" that is
444
// different than the matching dnName (or null) and break
445
lNode=lNode.getNextSibling();
446                                         while(lNode != null) {
447                                             if (lNode instanceof Element && !((Element)lNode).getNodeName().equals(dnName)) {
448                                                 break; // break of inner while loop
449
}
450                                             lNode=lNode.getNextSibling();
451                                         }
452
453                                         // used only for debugging, get name of node
454
if (lNode != null && lNode instanceof Element) eName=lNode.getNodeName();
455                                         if (bDebug) System.out.println("\n\t\t\tFound last item of type '" + lElement.getNodeName()
456                                             + "' with nextSibling being '" + eName + "'");
457
458                                         break; // break out of main while loop
459
}
460                                 }
461
462                                // go to next sibling in order
463
lNode=lNode.getNextSibling();
464                            }
465
466                            // if match is not found, node will be place at the end if lNode is null
467
bElement.insertBefore(importedNode,lNode);
468
469                         } else {
470                             throw new UnsupportedOperationException JavaDoc("Only addElement that has a location set to 'after' only supports a dnType of 'element'");
471                         }
472
473                     } else {
474                         // Default, add the element to the end of the parent element
475
bElement.appendChild(importedNode);
476                     }
477                 } else if (cElementx.getTagName().equals("addTextToElement")) {
478                     // this is a very simple alter text element routine to facilitate change to the jvm-options
479
// elements in domain.xml
480

481                     System.out.println("******** in addTextTOElement **********");
482                     
483                     // find how to add text and wait element use
484
String JavaDoc location=cElementx.getAttribute("location");
485                     String JavaDoc dataValue=cElementx.getAttribute("value");
486                     
487
488                     nlChild=bElement.getChildNodes();
489                     for (int mm=0; mm < nlChild.getLength(); mm++) {
490                         if (nlChild.item(mm) instanceof Text) {
491                             // have text node
492
if (bDebug) System.out.println("addTextToElement - Text - " + dataValue + " - " + location + " - " + nlChild.item(mm).getNodeValue() + "'");
493                                 // check to see how to add text before or after
494
if(location.equals("before")) {
495                                 nlChild.item(mm).setNodeValue(dataValue + nlChild.item(mm).getNodeValue());
496                             } else {
497                                 nlChild.item(mm).setNodeValue(nlChild.item(mm).getNodeValue() + dataValue);
498                             }
499                             // only apply to first text node
500
break;
501                         }
502                     }
503                 }
504             }
505         }
506     }
507
508
509     /**
510     * writeDOM - This method writes out the resulting DOM to a file
511     *
512     * @param doc - DOM to be written out
513     * @param file - The qualified file of where to write the DOM
514     */

515     public void writeDOM(Document doc, String JavaDoc file, String JavaDoc doctype_system, String JavaDoc doctype_public) throws Exception JavaDoc {
516         DOMSource domSource=new DOMSource(doc);
517         StreamResult sr=new StreamResult(new File(file));
518         TransformerFactory tf=TransformerFactory.newInstance();
519         Transformer t=tf.newTransformer();
520         t.setOutputProperty(OutputKeys.METHOD,"xml");
521         t.setOutputProperty(OutputKeys.INDENT,"no");
522         
523         if (doctype_public !=null) t.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC, doctype_public);
524         if (doctype_system !=null) t.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, doctype_system);
525         t.transform(domSource, sr);
526     }
527
528
529     /**
530     * readDOM - This method reads in XML into a DOM
531     *
532     * @param file - A qualified file where to read the XML
533     * @return Document - The read in DOM
534     * @exception - Any thrown exception that may occur during the read process
535     */

536     public Document readDOM(String JavaDoc file) throws Exception JavaDoc {
537         DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance();
538         DocumentBuilder db=dbf.newDocumentBuilder();
539         return db.parse(file);
540     }
541     
542     public Document readDOM(String JavaDoc file, String JavaDoc dtd) throws Exception JavaDoc {
543         DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance();
544         DocumentBuilder db=dbf.newDocumentBuilder();
545         db.setEntityResolver(new NOOPHandler(dtd));
546         return db.parse(file);
547     }
548     
549
550     // debug variable that will enable the printing of debug information
551
private static boolean bDebug=false;
552     
553 }
554
Popular Tags