xref: /AOO41X/main/javainstaller2/src/JavaSetup/org/openoffice/setup/SetupData/XMLPackageDescription.java (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 package org.openoffice.setup.SetupData;
29 
30 import org.openoffice.setup.InstallData;
31 import org.openoffice.setup.Util.FileExtensionFilter;
32 import java.io.File;
33 import java.io.IOException;
34 import java.util.Enumeration;
35 import java.util.Hashtable;
36 import java.util.Stack;
37 import java.util.Vector;
38 import javax.xml.parsers.ParserConfigurationException;
39 import javax.xml.parsers.SAXParser;
40 import javax.xml.parsers.SAXParserFactory;
41 import org.xml.sax.Attributes;
42 import org.xml.sax.SAXException;
43 import org.xml.sax.SAXParseException;
44 import org.xml.sax.helpers.DefaultHandler;
45 public class XMLPackageDescription {
46 
47     /**
48      * fill the package description tree by handling the SAXParser events
49      */
50     private class PackageDescriptionHandler extends DefaultHandler {
51 
52         private XMLPackageDescription root;
53         private Stack stack;
54 
55         public PackageDescriptionHandler(XMLPackageDescription base) {
56             root  = base;
57             stack = new Stack();
58         }
59 
60         private PackageDescriptionHandler() {
61             /* forbidden */
62         }
63 
64         public XMLPackageDescription getDescription() {
65             return root;
66         }
67 
68         /* implement the DefaultHandler interface */
69 
70         public void characters(char[] ch, int start, int length) {
71             XMLPackageDescription entity = (XMLPackageDescription) stack.peek();
72             entity.value = entity.value == null ? new String(ch, start, length)
73                                                 : entity.value + new String(ch, start, length);
74         }
75         public void startDocument() {
76             stack.push(root);
77         }
78         public void endDocument() {
79             stack.pop();
80         }
81         public void startElement(String uri, String localName, String qName, Attributes attributes) {
82             XMLPackageDescription parent = (XMLPackageDescription) stack.peek();
83             XMLPackageDescription entity = new XMLPackageDescription();
84 
85             entity.key = qName;
86             for (int i = 0; i < attributes.getLength(); i++) {
87                 entity.attributes.put(attributes.getQName(i), attributes.getValue(i));
88             }
89 
90             parent.add(entity);
91             stack.push(entity);
92         }
93         public void endElement(String uri, String localName, String qName) {
94             stack.pop();
95         }
96         public void error(SAXParseException e) {
97             System.err.println("Parse Error:" + e);
98         }
99         public void processingInstruction(String target, String data) {
100             /* ignore */
101         }
102         public void skippedEntity(String name) {
103             /* ignore */
104         }
105         public void warning(SAXParseException e) {
106             System.err.println("Warning:" + e);
107         }
108     }
109 
110     /**
111      * general storage for XML elements
112      */
113 
114     private String key;             /* XML element name       */
115     private String value;           /* XML element characters */
116     private Hashtable attributes;   /* XML element attributes */
117     private Vector children;        /* children are of type XMLPackageDescription */
118 
119     protected XMLPackageDescription() {
120         key        = "";
121         value      = null;
122         attributes = new Hashtable();
123         children   = new Vector();
124     }
125 
126     private void add(XMLPackageDescription p) {
127         children.add(p);
128     }
129 
130     /**
131      * helper routines to find content information
132      */
133     protected String getKey() {
134         return key;
135     }
136     protected String getAttribute(String key) {
137         return (String) attributes.get(key);
138     }
139     protected String getValue() {
140         return value;
141     }
142     protected XMLPackageDescription getElement(String key) {
143         return getElement(key, null, null);
144     }
145     protected XMLPackageDescription getElement(String key, String attrKey, String attrValue) {
146         for (Enumeration e = children.elements(); e.hasMoreElements();) {
147             XMLPackageDescription child = (XMLPackageDescription) e.nextElement();
148             if (child.key.equals(key)) {
149                 if (attrKey == null) {
150                     return child;
151                 } else if (attrValue.equals(child.getAttribute(attrKey))) {
152                     return child;
153                 }
154             }
155         }
156         return null;
157     }
158 
159     /**
160      * find a PackageDescription of type package that has the given name,
161      * recurses into the children
162      */
163     private XMLPackageDescription findPackage(String name) {
164         String self = (String) attributes.get("name");
165 
166         if ((self != null) && self.equals(name))
167             return this;
168 
169         XMLPackageDescription found = null;
170         for (Enumeration e = children.elements(); e.hasMoreElements();) {
171             XMLPackageDescription child = (XMLPackageDescription) e.nextElement();
172             if (child.getAttribute("parent") != null) {
173                 found = child.findPackage(name);
174                 if (found != null) {
175                     break;
176                 }
177             }
178         }
179         return found;
180     }
181 
182     /**
183      * adjust the tree so that all children have a matching parent and not just
184      * the ones they got by reading files in random order
185      */
186     private void adjust(XMLPackageDescription root) {
187         String self = (String) attributes.get("name");
188 
189         for (int i = children.size() - 1; i >= 0; --i) {
190             XMLPackageDescription child = (XMLPackageDescription) children.elementAt(i);
191             String childParentName = child.getAttribute("parent");
192             if (childParentName != null) {
193 
194                 child.adjust(root);
195 
196                 if ((childParentName != null) && (childParentName.length() > 0) && (! childParentName.equals(self))) {
197                     XMLPackageDescription newParent = root.findPackage(childParentName);
198                     if (newParent != null) {
199                         newParent.add(child);
200                         children.remove(i);
201                     }
202                 }
203             }
204         }
205     }
206 
207     protected void read() {
208         PackageDescriptionHandler handler = new PackageDescriptionHandler(this);
209 
210         try {
211             SAXParserFactory factory = SAXParserFactory.newInstance();
212             SAXParser parser = factory.newSAXParser();
213 
214             InstallData data = InstallData.getInstance();
215             File xpdRoot = data.getInfoRoot("xpd");
216 
217             if ( xpdRoot != null ) {
218                 File[] file = xpdRoot.listFiles(new FileExtensionFilter("xpd"));
219 
220                 if (file != null) {
221                     for (int i = 0; i < file.length; i++) {
222                         parser.parse(file[i], handler);
223                     }
224                 } else {
225                     key   = "";
226                     value = "no package file found";
227                 }
228             }
229             else {
230                 System.err.println("Did not find xpd directory");
231             }
232         } catch (ParserConfigurationException ex) {
233             ex.printStackTrace();
234         } catch (IOException ex) {
235             ex.printStackTrace();
236         } catch (SAXException ex) {
237             ex.printStackTrace();
238         }
239 
240         adjust(this);
241     }
242 
243     /* provide an iterator through the children */
244     protected class Elements implements Enumeration {
245 
246         Enumeration e;
247 
248         protected Elements() {
249             e = children.elements();
250         }
251         public boolean hasMoreElements() {
252             return e.hasMoreElements();
253         }
254         public Object nextElement() {
255             return e.nextElement();
256         }
257     }
258 
259     protected Enumeration elements() {
260         return new Elements();
261     }
262 
263 
264     // FIXME: remove it, dump() is for testing only
265     public void dump() {
266         dump("");
267     }
268 
269     // FIXME: remove it, dump(String) is for testing only
270     public void dump(String indent) {
271         final String space = "    ";
272         if (key != null) {
273             System.out.print(indent + "<" + key);
274         }
275         for (Enumeration e = attributes.keys() ; e.hasMoreElements() ;) {
276             String key   = (String) e.nextElement();
277             String value = (String) attributes.get(key);
278             System.out.print(" " + key + "=\"" + value + "\"");
279         }
280         if (key != null) {
281             System.out.print(">");
282         }
283 
284         if ((value != null) && (value.length() > 0)) {
285             String trimmedValue = value.trim();
286             if (trimmedValue.length() > 60) {
287                 trimmedValue = trimmedValue.substring(0, 57) + "...";
288             }
289             if (trimmedValue.length() > 0) {
290                 System.out.print(trimmedValue);
291             }
292         }
293 
294         for (Enumeration e = children.elements() ; e.hasMoreElements() ;) {
295             XMLPackageDescription current = (XMLPackageDescription) e.nextElement();
296             System.out.println();
297             current.dump(indent + space);
298         }
299         if (children.size() > 0) {
300             System.out.println();
301             System.out.print(indent);
302         }
303         if (key != null) {
304            System.out.print("</" + key + ">");
305         }
306     }
307 }
308