1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 package org.openoffice.xmerge.util.registry; 25 26 import java.io.*; 27 import java.util.*; 28 import java.util.jar.*; 29 import org.xml.sax.*; 30 import org.w3c.dom.*; 31 import javax.xml.parsers.*; 32 import java.net.URL; 33 import java.net.JarURLConnection; 34 35 /** 36 * The <code>ConverterInfoReader</code> pulls a META-INF/converter.xml 37 * file out of a jar file and parses it, providing access to this 38 * information in a <code>Vector</code> of <code>ConverterInfo</code> 39 * objects. 40 * 41 * @author Brian Cameron 42 */ 43 public class ConverterInfoReader { 44 45 private final static String TAG_CONVERTER = "converter"; 46 private final static String ATTRIB_OFFICE_TYPE = "type"; 47 private final static String ATTRIB_VERSION = "version"; 48 private final static String TAG_NAME = "converter-display-name"; 49 private final static String TAG_DESC = "converter-description"; 50 private final static String TAG_VENDOR = "converter-vendor"; 51 private final static String TAG_CLASS_IMPL = "converter-class-impl"; 52 private final static String TAG_TARGET = "converter-target"; 53 private final static String ATTRIB_DEVICE_TYPE = "type"; 54 private final static String TAG_XSLT_DESERIAL = "converter-xslt-deserialize"; 55 private final static String TAG_XSLT_SERIAL = "converter-xslt-serialize"; 56 private String jarfilename; 57 private Document document; 58 private Vector converterInfoList; 59 60 61 /** 62 * Constructor. A jar file is passed in. The jar file is 63 * parsed and the <code>Vector</code> of <code>ConverterInfo</code> 64 * objects is built. 65 * 66 * @param jar The URL of the jar file to process. 67 * @param shouldvalidate Boolean to enable or disable xml validation. 68 * 69 * @throws IOException If the jar file cannot 70 * be read or if the 71 * META-INF/converter.xml 72 * can not be read in the 73 * jar file. 74 * @throws ParserConfigurationException If the DocumentBuilder 75 * can not be built. 76 * @throws org.xml.sax.SAXException If the converter.xml 77 * file can not be parsed. 78 * @throws RegistryException If the ConverterFactory 79 * implementation of a 80 * plug-in cannot be loaded. 81 */ ConverterInfoReader(String jar,boolean shouldvalidate)82 public ConverterInfoReader(String jar,boolean shouldvalidate) throws IOException, 83 ParserConfigurationException, org.xml.sax.SAXException, 84 RegistryException { 85 86 InputStream istream; 87 InputSource isource; 88 DocumentBuilderFactory builderFactory; 89 DocumentBuilder builder; 90 JarURLConnection jarConnection; 91 JarEntry jarentry; 92 JarFile jarfile; 93 URL url; 94 95 converterInfoList = new Vector(); 96 jarfilename = jar; 97 98 // Get Jar via URL 99 // 100 url = new URL("jar:" + jar + "!/META-INF/converter.xml"); 101 jarConnection = (JarURLConnection)url.openConnection(); 102 jarentry = jarConnection.getJarEntry(); 103 jarfile = jarConnection.getJarFile(); 104 105 // Build the InputSource 106 // 107 istream = jarfile.getInputStream(jarentry); 108 isource = new InputSource(istream); 109 110 // Get the DOM builder and build the document. 111 // 112 builderFactory = DocumentBuilderFactory.newInstance(); 113 114 //DTD validation 115 if (shouldvalidate){ 116 System.out.println("Validating xml..."); 117 builderFactory.setValidating(true); 118 } 119 // 120 builder = builderFactory.newDocumentBuilder(); 121 document = builder.parse(isource); 122 123 // Parse the document. 124 // 125 parseDocument(); 126 } 127 128 129 /** 130 * Loops over the <i>converter</i> <code>Node</code> in the converter.xml 131 * file and processes them. 132 * 133 * @throws RegistryException If the plug-in associated with a 134 * specific <i>converter</i> <code>Node</code> 135 * cannot be loaded. 136 */ parseDocument()137 private void parseDocument() throws RegistryException { 138 139 Node converterNode; 140 NodeList converterNodes = document.getElementsByTagName(TAG_CONVERTER); 141 142 for (int i=0; i < converterNodes.getLength(); i++) { 143 converterNode = converterNodes.item(i); 144 if (converterNode.getNodeType() == Node.ELEMENT_NODE) { 145 parseConverterNode((Element)converterNode); 146 } 147 } 148 } 149 150 151 /** 152 * Parses a <i>converter</i> node, pulling the information out of 153 * the <code>Node</code> and placing it in a <code>ConverterInfo</code> 154 * object, and adds that object to a <code>Vector</code> of 155 * <code>ConverterInfo</code> objects. 156 * 157 * @param e The <code>Element</code> corresponding to the 158 * <i>converter</i> XML tag. 159 * 160 * 161 * @throws RegistryException If the plug-in cannot be loaded. 162 */ parseConverterNode(Element e)163 private void parseConverterNode(Element e) throws RegistryException { 164 165 Element detailElement; 166 Node detailNode; 167 String elementTagName; 168 String officeMime = null; 169 Vector deviceMime = new Vector(); 170 String name = null; 171 String desc = null; 172 String version = null; 173 String vendor = null; 174 String classImpl = null; 175 String xsltSerial = null; 176 String xsltDeserial= null; 177 String temp; 178 179 temp = e.getAttribute(ATTRIB_OFFICE_TYPE); 180 if (temp.length() != 0) { 181 officeMime = temp; 182 } 183 184 temp = e.getAttribute(ATTRIB_VERSION); 185 if (temp.length() != 0) { 186 version = temp; 187 } 188 189 NodeList detailNodes = e.getChildNodes(); 190 for (int i=0; i < detailNodes.getLength(); i++) { 191 192 detailNode = detailNodes.item(i); 193 if (detailNode.getNodeType() == Node.ELEMENT_NODE) { 194 195 detailElement = (Element)detailNode; 196 elementTagName = detailElement.getTagName(); 197 198 if (TAG_NAME.equalsIgnoreCase(elementTagName)) { 199 name = getTextValue(detailElement); 200 } else if (TAG_DESC.equalsIgnoreCase(elementTagName)) { 201 desc = getTextValue(detailElement); 202 } else if (TAG_VENDOR.equalsIgnoreCase(elementTagName)) { 203 vendor = getTextValue(detailElement); 204 } else if (TAG_XSLT_SERIAL.equalsIgnoreCase(elementTagName)) { 205 xsltSerial = getTextValue(detailElement); 206 } else if (TAG_XSLT_DESERIAL.equalsIgnoreCase(elementTagName)) { 207 xsltDeserial = getTextValue(detailElement); 208 } else if (TAG_CLASS_IMPL.equalsIgnoreCase(elementTagName)) { 209 classImpl = getTextValue(detailElement); 210 } else if (TAG_TARGET.equalsIgnoreCase(elementTagName)) { 211 212 temp = detailElement.getAttribute(ATTRIB_DEVICE_TYPE); 213 if (temp.length() != 0) { 214 deviceMime.add(temp); 215 } 216 } 217 } 218 } 219 ConverterInfo converterInfo; 220 if ((xsltSerial==null) || (xsltDeserial==null)){ 221 converterInfo = new ConverterInfo(jarfilename, 222 officeMime, deviceMime, name, 223 desc, version, vendor,classImpl); 224 } 225 else{ 226 converterInfo = new ConverterInfo(jarfilename, 227 officeMime, deviceMime, name, 228 desc, version, vendor,classImpl, 229 xsltSerial,xsltDeserial); 230 } 231 /*ConverterInfo converterInfo = new ConverterInfo(jarfilename, 232 officeMime, deviceMime, name, desc, version, vendor, 233 classImpl);*/ 234 converterInfoList.add(converterInfo); 235 } 236 237 238 /** 239 * Helper function to get the text value of an 240 * <code>Element</code>. 241 * 242 * @param e The <code>Element</code> to process. 243 * 244 * @return The text value of the <code>Element</code>. 245 */ getTextValue(Element e)246 private String getTextValue(Element e) { 247 248 NodeList tempNodes = e.getChildNodes(); 249 String text = null; 250 Node tempNode; 251 252 for (int j=0; j < tempNodes.getLength(); j++) { 253 tempNode = tempNodes.item(j); 254 if (tempNode.getNodeType() == Node.TEXT_NODE) { 255 text = tempNode.getNodeValue().trim(); 256 break; 257 } 258 } 259 260 return text; 261 } 262 263 264 /** 265 * Returns an <code>Enumeration</code> of <code>ConverterInfo</code> 266 * objects. 267 * 268 * @return An <code>Enumeration</code> of <code>ConverterInfo</code> 269 * objects. 270 */ getConverterInfoEnumeration()271 public Enumeration getConverterInfoEnumeration() { 272 return (converterInfoList.elements()); 273 } 274 } 275 276