001 /* 002 // $Id: //open/util/resgen/src/org/eigenbase/xom/XOMUtil.java#5 $ 003 // Package org.eigenbase.xom is an XML Object Mapper. 004 // Copyright (C) 2005-2005 The Eigenbase Project 005 // Copyright (C) 2005-2005 Disruptive Tech 006 // Copyright (C) 2005-2005 LucidEra, Inc. 007 // Portions Copyright (C) 2001-2005 Kana Software, Inc. and others. 008 // 009 // This library is free software; you can redistribute it and/or modify it 010 // under the terms of the GNU Lesser General Public License as published by the 011 // Free Software Foundation; either version 2 of the License, or (at your 012 // option) any later version approved by The Eigenbase Project. 013 // 014 // This library is distributed in the hope that it will be useful, 015 // but WITHOUT ANY WARRANTY; without even the implied warranty of 016 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 017 // GNU Lesser General Public License for more details. 018 // 019 // You should have received a copy of the GNU Lesser General Public License 020 // along with this library; if not, write to the Free Software 021 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 022 // 023 // jhyde, 3 October, 2001 024 */ 025 026 package org.eigenbase.xom; 027 import java.io.File; 028 import java.io.StringWriter; 029 import java.lang.reflect.Array; 030 import java.lang.reflect.Field; 031 import java.lang.reflect.InvocationTargetException; 032 import java.lang.reflect.Method; 033 034 /** 035 * Utility functions for the <code>org.eigenbase.xom</code> and 036 * <code>org.eigenbase.xom.wrappers</code> packages. 037 * 038 * @author jhyde 039 * @since 3 October, 2001 040 * @version $Id: //open/util/resgen/src/org/eigenbase/xom/XOMUtil.java#5 $ 041 **/ 042 public abstract class XOMUtil extends XMLUtil { 043 044 static final NodeDef[] emptyNodeArray = new NodeDef[0]; 045 046 /** 047 * When the compiler is complaining that you are not using a variable, just 048 * call one of these routines with it. 049 **/ 050 public static void discard(boolean b) { 051 } 052 053 public static void discard(byte b) { 054 } 055 056 public static void discard(char c) { 057 } 058 059 public static void discard(double d) { 060 } 061 062 public static void discard(float d) { 063 } 064 065 public static void discard(int i) { 066 } 067 068 public static void discard(long l) { 069 } 070 071 public static void discard(Object o) { 072 } 073 074 public static void discard(short s) { 075 } 076 077 /** 078 * Converts the first letter of <code>name</code> to upper-case. 079 */ 080 static String capitalize(String name) { 081 if (name == null || name.length() < 1) { 082 return name; 083 } 084 return name.substring(0,1).toUpperCase() + name.substring(1); 085 } 086 087 /** 088 * Adds an object to the end of an array. The resulting array is of the 089 * same type (e.g. <code>String[]</code>) as the input array. 090 **/ 091 public static Object[] addElement(Object[] a, Object o) 092 { 093 Class clazz = a.getClass().getComponentType(); 094 Object[] a2 = (Object[]) Array.newInstance(clazz, a.length + 1); 095 System.arraycopy(a, 0, a2, 0, a.length); 096 a2[a.length] = o; 097 return a2; 098 } 099 100 /** 101 * Concatenates two arrays. The resulting array is of the 102 * same type (e.g. <code>String[]</code>) as the first array. 103 **/ 104 public static Object[] concatenate(Object[] a0, Object[] a1) 105 { 106 Class clazz = a0.getClass().getComponentType(); 107 Object[] a2 = (Object[]) Array.newInstance( 108 clazz, a0.length + a1.length); 109 System.arraycopy(a0, 0, a2, 0, a0.length); 110 System.arraycopy(a1, 0, a2, a0.length, a1.length); 111 return a2; 112 } 113 114 /** 115 * Adds a set of children to an object, using its best guess as to where to 116 * put them. 117 **/ 118 public static void addChildren(ElementDef parent, NodeDef[] children) 119 throws XOMException 120 { 121 if (parent instanceof GenericDef) { 122 GenericDef xmlGeneric = (GenericDef) parent; 123 for (int i = 0; i < children.length; i++) { 124 xmlGeneric.addChild(children[i]); 125 } 126 } else if (parent instanceof Any) { 127 Any any = (Any) parent; 128 NodeDef[] currentChildren = any.getChildren(); 129 if (currentChildren == null) { 130 if (children instanceof ElementDef[]) { 131 currentChildren = new ElementDef[0]; 132 } else { 133 currentChildren = new NodeDef[0]; 134 } 135 } 136 NodeDef[] newChildren = (NodeDef[]) concatenate( 137 currentChildren, children); 138 any.setChildren(newChildren); 139 } else { 140 // Use reflection. We presume that the children are stored in the 141 // first array field. 142 Field field = null; 143 Field[] fields = parent.getClass().getFields(); 144 for (int i = 0; i < fields.length; i++) { 145 if (fields[i].getType().isArray()) { 146 field = fields[i]; 147 break; 148 } 149 } 150 if (field == null) { 151 throw new XOMException( 152 "cannot add field to " + parent.getClass() + 153 ": it has no array field"); 154 } 155 try { 156 Object[] a = (Object[]) field.get(parent); 157 Object[] b = concatenate(a, children); 158 field.set(parent, b); 159 } catch (IllegalAccessException e) { 160 throw new XOMException(e, "in XOMUtil.getChildren"); 161 } 162 } 163 } 164 165 public static void addChild(ElementDef parent, ElementDef child) 166 throws XOMException 167 { 168 addChildren(parent, new ElementDef[] {child}); 169 } 170 171 public static void addChild(ElementDef parent, NodeDef child) 172 throws XOMException 173 { 174 addChildren(parent, new NodeDef[] {child}); 175 } 176 177 /** 178 * Creates a {@link Parser} of the default parser type. 179 **/ 180 public static Parser createDefaultParser() throws XOMException 181 { 182 String className = "org.eigenbase.xom.wrappers.JaxpDOMParser"; 183 try { 184 Class clazz = Class.forName(className); 185 return (Parser) clazz.newInstance(); 186 } catch (ClassNotFoundException e) { 187 throw new XOMException(e, "Error while creating xml parser '" + className + "'"); 188 } catch (IllegalAccessException e) { 189 throw new XOMException(e, "Error while creating xml parser '" + className + "'"); 190 } catch (InstantiationException e) { 191 throw new XOMException(e, "Error while creating xml parser '" + className + "'"); 192 } catch (VerifyError e) { 193 throw new XOMException( 194 e, "Error while creating xml parser '" + className + "' " + 195 "(If you are running Weblogic 6.1, try putting " + 196 "xml-apis.jar and xercesImpl.jar BEFORE weblogic.jar " + 197 "on CLASSPATH)"); 198 } 199 } 200 201 /** * @see #makeParser **/ 202 static final int MSXML = 1; 203 /** * @see #makeParser **/ 204 static final int XERCES = 2; 205 206 /** 207 * Creates a parser of given type. 208 * 209 * @param parserType valid values are {@link #MSXML} and {@link #XERCES}. 210 **/ 211 static Parser makeParser( 212 int parserType, boolean usesPlugins, String fileDirectory, 213 String dtdName, String docType) throws XOMException 214 { 215 try { 216 switch (parserType) { 217 case MSXML: 218 if (usesPlugins) { 219 // Use reflection to call 220 // MSXMLWrapper.createParser(); 221 Class clazz = Class.forName( 222 "org.eigenbase.xom.wrappers.MSXMLWrapper"); 223 Method method = clazz.getDeclaredMethod( 224 "createParser", new Class[] {}); 225 return (Parser) method.invoke(null, new Object[] {}); 226 } else { 227 // Use reflection to call 228 // MSXMLWrapper.createParser(docType, dtdPath); 229 File dtdPath = new File(fileDirectory, dtdName); 230 Class clazz = Class.forName( 231 "org.eigenbase.xom.wrappers.MSXMLWrapper"); 232 Method method = clazz.getDeclaredMethod( 233 "createParser", new Class[] { 234 String.class, String.class}); 235 return (Parser) method.invoke(null, new Object[] { 236 docType, dtdPath}); 237 } 238 case XERCES: 239 return new org.eigenbase.xom.wrappers.XercesDOMParser( 240 !usesPlugins); 241 default: 242 throw new XOMException("Unknown parser type: " + parserType); 243 } 244 } catch (ClassNotFoundException e) { 245 throw new XOMException(e, "while creating xml parser"); 246 } catch (IllegalAccessException e) { 247 throw new XOMException(e, "while creating xml parser"); 248 } catch (NoSuchMethodException e) { 249 throw new XOMException(e, "while creating xml parser"); 250 } catch (InvocationTargetException e) { 251 throw new XOMException(e, "while creating xml parser"); 252 } 253 } 254 255 /** 256 * Returns the first member of an array of objects which is an instance of 257 * a given class, or null if there is no such. 258 **/ 259 public static Object getFirstInstance(Object[] a, Class clazz) 260 { 261 for (int i = 0; i < a.length; i++) { 262 if (clazz.isInstance(a[i])) { 263 return a[i]; 264 } 265 } 266 return null; 267 } 268 269 public static String wrapperToXml(DOMWrapper wrapper, boolean ignorePcdata) 270 { 271 try { 272 NodeDef node; 273 switch (wrapper.getType()) { 274 case DOMWrapper.ELEMENT: 275 node = new WrapperElementDef(wrapper,null,null); 276 break; 277 case DOMWrapper.CDATA: 278 node = new CdataDef(wrapper); 279 break; 280 case DOMWrapper.FREETEXT: 281 node = new TextDef(wrapper); 282 break; 283 case DOMWrapper.COMMENT: 284 node = new CommentDef(wrapper); 285 break; 286 default: 287 throw new Error( 288 "unknown node type " + wrapper.getType() + 289 " while converting node to xml"); 290 } 291 StringWriter sw = new StringWriter(); 292 XMLOutput out = new XMLOutput(sw); 293 out.setIgnorePcdata(ignorePcdata); 294 out.setGlob(true); 295 node.displayXML(out, 0); 296 return sw.toString(); 297 } catch (XOMException e) { 298 throw new Error( 299 "[" + e.toString() + "] while converting node to xml"); 300 } 301 } 302 } 303 304 305 // End XOMUtil.java