blob: 9238e3a14efb03ca9dc53ac3875a5ac4290158cc [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
package org.openoffice.setup.SetupData;
import org.openoffice.setup.InstallData;
import org.openoffice.setup.Util.FileExtensionFilter;
import java.io.File;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Stack;
import java.util.Vector;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.DefaultHandler;
public class XMLPackageDescription {
/**
* fill the package description tree by handling the SAXParser events
*/
private class PackageDescriptionHandler extends DefaultHandler {
private XMLPackageDescription root;
private Stack stack;
public PackageDescriptionHandler(XMLPackageDescription base) {
root = base;
stack = new Stack();
}
private PackageDescriptionHandler() {
/* forbidden */
}
public XMLPackageDescription getDescription() {
return root;
}
/* implement the DefaultHandler interface */
public void characters(char[] ch, int start, int length) {
XMLPackageDescription entity = (XMLPackageDescription) stack.peek();
entity.value = entity.value == null ? new String(ch, start, length)
: entity.value + new String(ch, start, length);
}
public void startDocument() {
stack.push(root);
}
public void endDocument() {
stack.pop();
}
public void startElement(String uri, String localName, String qName, Attributes attributes) {
XMLPackageDescription parent = (XMLPackageDescription) stack.peek();
XMLPackageDescription entity = new XMLPackageDescription();
entity.key = qName;
for (int i = 0; i < attributes.getLength(); i++) {
entity.attributes.put(attributes.getQName(i), attributes.getValue(i));
}
parent.add(entity);
stack.push(entity);
}
public void endElement(String uri, String localName, String qName) {
stack.pop();
}
public void error(SAXParseException e) {
System.err.println("Parse Error:" + e);
}
public void processingInstruction(String target, String data) {
/* ignore */
}
public void skippedEntity(String name) {
/* ignore */
}
public void warning(SAXParseException e) {
System.err.println("Warning:" + e);
}
}
/**
* general storage for XML elements
*/
private String key; /* XML element name */
private String value; /* XML element characters */
private Hashtable attributes; /* XML element attributes */
private Vector children; /* children are of type XMLPackageDescription */
protected XMLPackageDescription() {
key = "";
value = null;
attributes = new Hashtable();
children = new Vector();
}
private void add(XMLPackageDescription p) {
children.add(p);
}
/**
* helper routines to find content information
*/
protected String getKey() {
return key;
}
protected String getAttribute(String key) {
return (String) attributes.get(key);
}
protected String getValue() {
return value;
}
protected XMLPackageDescription getElement(String key) {
return getElement(key, null, null);
}
protected XMLPackageDescription getElement(String key, String attrKey, String attrValue) {
for (Enumeration e = children.elements(); e.hasMoreElements();) {
XMLPackageDescription child = (XMLPackageDescription) e.nextElement();
if (child.key.equals(key)) {
if (attrKey == null) {
return child;
} else if (attrValue.equals(child.getAttribute(attrKey))) {
return child;
}
}
}
return null;
}
/**
* find a PackageDescription of type package that has the given name,
* recurses into the children
*/
private XMLPackageDescription findPackage(String name) {
String self = (String) attributes.get("name");
if ((self != null) && self.equals(name))
return this;
XMLPackageDescription found = null;
for (Enumeration e = children.elements(); e.hasMoreElements();) {
XMLPackageDescription child = (XMLPackageDescription) e.nextElement();
if (child.getAttribute("parent") != null) {
found = child.findPackage(name);
if (found != null) {
break;
}
}
}
return found;
}
/**
* adjust the tree so that all children have a matching parent and not just
* the ones they got by reading files in random order
*/
private void adjust(XMLPackageDescription root) {
String self = (String) attributes.get("name");
for (int i = children.size() - 1; i >= 0; --i) {
XMLPackageDescription child = (XMLPackageDescription) children.elementAt(i);
String childParentName = child.getAttribute("parent");
if (childParentName != null) {
child.adjust(root);
if ((childParentName != null) && (childParentName.length() > 0) && (! childParentName.equals(self))) {
XMLPackageDescription newParent = root.findPackage(childParentName);
if (newParent != null) {
newParent.add(child);
children.remove(i);
}
}
}
}
}
protected void read() {
PackageDescriptionHandler handler = new PackageDescriptionHandler(this);
try {
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser parser = factory.newSAXParser();
InstallData data = InstallData.getInstance();
File xpdRoot = data.getInfoRoot("xpd");
if ( xpdRoot != null ) {
File[] file = xpdRoot.listFiles(new FileExtensionFilter("xpd"));
if (file != null) {
for (int i = 0; i < file.length; i++) {
parser.parse(file[i], handler);
}
} else {
key = "";
value = "no package file found";
}
}
else {
System.err.println("Did not find xpd directory");
}
} catch (ParserConfigurationException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
} catch (SAXException ex) {
ex.printStackTrace();
}
adjust(this);
}
/* provide an iterator through the children */
protected class Elements implements Enumeration {
Enumeration e;
protected Elements() {
e = children.elements();
}
public boolean hasMoreElements() {
return e.hasMoreElements();
}
public Object nextElement() {
return e.nextElement();
}
}
protected Enumeration elements() {
return new Elements();
}
// FIXME: remove it, dump() is for testing only
public void dump() {
dump("");
}
// FIXME: remove it, dump(String) is for testing only
public void dump(String indent) {
final String space = " ";
if (key != null) {
System.out.print(indent + "<" + key);
}
for (Enumeration e = attributes.keys() ; e.hasMoreElements() ;) {
String key = (String) e.nextElement();
String value = (String) attributes.get(key);
System.out.print(" " + key + "=\"" + value + "\"");
}
if (key != null) {
System.out.print(">");
}
if ((value != null) && (value.length() > 0)) {
String trimmedValue = value.trim();
if (trimmedValue.length() > 60) {
trimmedValue = trimmedValue.substring(0, 57) + "...";
}
if (trimmedValue.length() > 0) {
System.out.print(trimmedValue);
}
}
for (Enumeration e = children.elements() ; e.hasMoreElements() ;) {
XMLPackageDescription current = (XMLPackageDescription) e.nextElement();
System.out.println();
current.dump(indent + space);
}
if (children.size() > 0) {
System.out.println();
System.out.print(indent);
}
if (key != null) {
System.out.print("</" + key + ">");
}
}
}