001 /* 002 * @(#)$Id: AbstractMarshallerImpl.java,v 1.21 2003/02/13 23:41:06 kk122374 Exp $ 003 * 004 * Copyright 2001 Sun Microsystems, Inc. All Rights Reserved. 005 * 006 * This software is the proprietary information of Sun Microsystems, Inc. 007 * Use is subject to license terms. 008 * 009 */ 010 package javax.xml.bind.helpers; 011 012 import javax.xml.bind.Marshaller; 013 import javax.xml.bind.JAXBException; 014 import javax.xml.bind.PropertyException; 015 import javax.xml.bind.ValidationEventHandler; 016 import javax.xml.transform.stream.StreamResult; 017 import javax.xml.transform.sax.SAXResult; 018 import javax.xml.transform.dom.DOMResult; 019 020 import java.io.UnsupportedEncodingException; 021 // J2SE1.4 feature 022 // import java.nio.charset.Charset; 023 // import java.nio.charset.UnsupportedCharsetException; 024 025 /** 026 * Partial default <tt>Marshaller</tt> implementation. 027 * 028 * <p> 029 * This class provides a partial default implementation for the 030 * {@link javax.xml.bind.Marshaller} interface. 031 * 032 * <p> 033 * The only method that a JAXB Provider has to implement is 034 * {@link Marshaller#marshal(Object, Result) marshal(Object, javax.xml.transform.Result)}. 035 * 036 * @author <ul><li>Kohsuke Kawaguchi, Sun Microsystems, Inc.</li></ul> 037 * @version $Revision: 1.21 $ $Date: 2003/02/13 23:41:06 $ 038 * @see javax.xml.bind.Marshaller 039 * @since JAXB1.0 040 */ 041 public abstract class AbstractMarshallerImpl implements Marshaller 042 { 043 /** handler that will be used to process errors and warnings during marshal */ 044 private ValidationEventHandler eventHandler = 045 new DefaultValidationEventHandler(); 046 047 //J2SE1.4 feature 048 //private Charset encoding = null; 049 050 /** store the value of the encoding property. */ 051 private String encoding = "UTF-8"; 052 053 /** store the value of the schemaLocation property. */ 054 private String schemaLocation = null; 055 056 /** store the value of the noNamespaceSchemaLocation property. */ 057 private String noNSSchemaLocation = null; 058 059 /** store the value of the formattedOutput property. */ 060 private boolean formattedOutput = false; 061 062 public final void marshal( Object obj, java.io.OutputStream os ) 063 throws JAXBException { 064 065 checkNotNull( obj, "obj", os, "os" ); 066 marshal( obj, new StreamResult(os) ); 067 } 068 069 public final void marshal( Object obj, java.io.Writer w ) 070 throws JAXBException { 071 072 checkNotNull( obj, "obj", w, "writer" ); 073 marshal( obj, new StreamResult(w) ); 074 } 075 076 public final void marshal( Object obj, org.xml.sax.ContentHandler handler ) 077 throws JAXBException { 078 079 checkNotNull( obj, "obj", handler, "handler" ); 080 marshal( obj, new SAXResult(handler) ); 081 } 082 083 public final void marshal( Object obj, org.w3c.dom.Node node ) 084 throws JAXBException { 085 086 checkNotNull( obj, "obj", node, "node" ); 087 marshal( obj, new DOMResult(node) ); 088 } 089 090 /** 091 * By default, the getNode method is unsupported and throw 092 * an {@link java.lang.UnsupportedOperationException}. 093 * 094 * Implementations that choose to support this method must 095 * override this method. 096 */ 097 public org.w3c.dom.Node getNode( Object obj ) throws JAXBException { 098 099 checkNotNull( obj, "obj", Boolean.TRUE, "foo" ); 100 101 throw new UnsupportedOperationException(); 102 } 103 104 /** 105 * Convenience method for getting the current output encoding. 106 * 107 * @return the current encoding or "UTF-8" if it hasn't been set. 108 */ 109 protected String getEncoding() { 110 return encoding; 111 } 112 113 /** 114 * Convenience method for setting the output encoding. 115 * 116 * @param encoding a valid encoding as specified in the Marshaller class 117 * documentation 118 */ 119 protected void setEncoding( String encoding ) { 120 this.encoding = encoding; 121 } 122 123 /** 124 * Convenience method for getting the current schemaLocation. 125 * 126 * @return the current schemaLocation or null if it hasn't been set 127 */ 128 protected String getSchemaLocation() { 129 return schemaLocation; 130 } 131 132 /** 133 * Convenience method for setting the schemaLocation. 134 * 135 * @param location the schemaLocation value 136 */ 137 protected void setSchemaLocation( String location ) { 138 schemaLocation = location; 139 } 140 141 /** 142 * Convenience method for getting the current noNamespaceSchemaLocation. 143 * 144 * @return the current noNamespaceSchemaLocation or null if it hasn't 145 * been set 146 */ 147 protected String getNoNSSchemaLocation() { 148 return noNSSchemaLocation; 149 } 150 151 /** 152 * Convenience method for setting the noNamespaceSchemaLocation. 153 * 154 * @param location the noNamespaceSchemaLocation value 155 */ 156 protected void setNoNSSchemaLocation( String location ) { 157 noNSSchemaLocation = location; 158 } 159 160 /** 161 * Convenience method for getting the formatted output flag. 162 * 163 * @return the current value of the formatted output flag or false if 164 * it hasn't been set. 165 */ 166 protected boolean isFormattedOutput() { 167 return formattedOutput; 168 } 169 170 /** 171 * Convenience method for setting the formatted output flag. 172 * 173 * @param v value of the formatted output flag. 174 */ 175 protected void setFormattedOutput( boolean v ) { 176 formattedOutput = v; 177 } 178 179 180 static String[] aliases = { 181 "UTF-8", "UTF8", 182 "UTF-16", "Unicode", 183 "UTF-16BE", "UnicodeBigUnmarked", 184 "UTF-16LE", "UnicodeLittleUnmarked", 185 "US-ASCII", "ASCII", 186 "TIS-620", "TIS620", 187 188 // taken from the project-X parser 189 "ISO-10646-UCS-2", "Unicode", 190 191 "EBCDIC-CP-US", "cp037", 192 "EBCDIC-CP-CA", "cp037", 193 "EBCDIC-CP-NL", "cp037", 194 "EBCDIC-CP-WT", "cp037", 195 196 "EBCDIC-CP-DK", "cp277", 197 "EBCDIC-CP-NO", "cp277", 198 "EBCDIC-CP-FI", "cp278", 199 "EBCDIC-CP-SE", "cp278", 200 201 "EBCDIC-CP-IT", "cp280", 202 "EBCDIC-CP-ES", "cp284", 203 "EBCDIC-CP-GB", "cp285", 204 "EBCDIC-CP-FR", "cp297", 205 206 "EBCDIC-CP-AR1", "cp420", 207 "EBCDIC-CP-HE", "cp424", 208 "EBCDIC-CP-BE", "cp500", 209 "EBCDIC-CP-CH", "cp500", 210 211 "EBCDIC-CP-ROECE", "cp870", 212 "EBCDIC-CP-YU", "cp870", 213 "EBCDIC-CP-IS", "cp871", 214 "EBCDIC-CP-AR2", "cp918", 215 216 // IANA also defines two that JDK 1.2 doesn't handle: 217 // EBCDIC-CP-GR --> CP423 218 // EBCDIC-CP-TR --> CP905 219 }; 220 221 /** 222 * Gets the corresponding Java encoding name from an IANA name. 223 * 224 * This method is a helper method for the derived class to convert 225 * encoding names. 226 * 227 * @exception UnsupportedEncodingException 228 * If this implementation couldn't find the Java encoding name. 229 */ 230 protected String getJavaEncoding( String encoding ) throws UnsupportedEncodingException { 231 try { 232 "1".getBytes(encoding); 233 return encoding; 234 } catch( UnsupportedEncodingException e ) { 235 // try known alias 236 for( int i=0; i<aliases.length; i+=2 ) { 237 if(encoding.equals(aliases[i])) { 238 "1".getBytes(aliases[i+1]); 239 return aliases[i+1]; 240 } 241 } 242 243 throw new UnsupportedEncodingException(encoding); 244 } 245 /* J2SE1.4 feature 246 try { 247 this.encoding = Charset.forName( _encoding ); 248 } catch( UnsupportedCharsetException uce ) { 249 throw new JAXBException( uce ); 250 } 251 */ 252 } 253 254 /** 255 * Default implementation of the setProperty method handles 256 * the four defined properties in Marshaller. If a provider 257 * needs to handle additional properties, it should override 258 * this method in a derived class. 259 */ 260 public void setProperty( String name, Object value ) 261 throws PropertyException { 262 263 if( name == null ) { 264 throw new IllegalArgumentException( 265 Messages.format( Messages.MUST_NOT_BE_NULL, "name" ) ); 266 } 267 268 // recognize and handle four pre-defined properties. 269 if( JAXB_ENCODING.equals(name) ) { 270 checkString( name, value ); 271 setEncoding( (String)value ); 272 return; 273 } 274 if( JAXB_FORMATTED_OUTPUT.equals(name) ) { 275 checkBoolean( name, value ); 276 setFormattedOutput( ((Boolean)value).booleanValue() ); 277 return; 278 } 279 if( JAXB_NO_NAMESPACE_SCHEMA_LOCATION.equals(name) ) { 280 checkString( name, value ); 281 setNoNSSchemaLocation( (String)value ); 282 return; 283 } 284 if( JAXB_SCHEMA_LOCATION.equals(name) ) { 285 checkString( name, value ); 286 setSchemaLocation( (String)value ); 287 return; 288 } 289 290 throw new PropertyException(name, value); 291 } 292 293 /** 294 * Default implementation of the getProperty method handles 295 * the four defined properties in Marshaller. If a provider 296 * needs to support additional provider specific properties, 297 * it should override this method in a derived class. 298 */ 299 public Object getProperty( String name ) 300 throws PropertyException { 301 302 if( name == null ) { 303 throw new IllegalArgumentException( 304 Messages.format( Messages.MUST_NOT_BE_NULL, "name" ) ); 305 } 306 307 // recognize and handle four pre-defined properties. 308 if( JAXB_ENCODING.equals(name) ) 309 return getEncoding(); 310 if( JAXB_FORMATTED_OUTPUT.equals(name) ) 311 return isFormattedOutput()?Boolean.TRUE:Boolean.FALSE; 312 if( JAXB_NO_NAMESPACE_SCHEMA_LOCATION.equals(name) ) 313 return getNoNSSchemaLocation(); 314 if( JAXB_SCHEMA_LOCATION.equals(name) ) 315 return getSchemaLocation(); 316 317 throw new PropertyException(name); 318 } 319 /** 320 * @see javax.xml.bind.Marshaller#getEventHandler() 321 */ 322 public ValidationEventHandler getEventHandler() throws JAXBException { 323 return eventHandler; 324 } 325 326 /** 327 * @see javax.xml.bind.Marshaller#setEventHandler(ValidationEventHandler) 328 */ 329 public void setEventHandler(ValidationEventHandler handler) 330 throws JAXBException { 331 332 if( handler == null ) { 333 eventHandler = new DefaultValidationEventHandler(); 334 } else { 335 eventHandler = handler; 336 } 337 } 338 339 340 341 342 /* 343 * assert that the given object is a Boolean 344 */ 345 private void checkBoolean( String name, Object value ) throws PropertyException { 346 if(!(value instanceof Boolean)) 347 throw new PropertyException( 348 Messages.format( Messages.MUST_BE_BOOLEAN, name ) ); 349 } 350 351 /* 352 * assert that the given object is a String 353 */ 354 private void checkString( String name, Object value ) throws PropertyException { 355 if(!(value instanceof String)) 356 throw new PropertyException( 357 Messages.format( Messages.MUST_BE_STRING, name ) ); 358 } 359 360 /* 361 * assert that the parameters are not null 362 */ 363 private void checkNotNull( Object o1, String o1Name, 364 Object o2, String o2Name ) { 365 366 if( o1 == null ) { 367 throw new IllegalArgumentException( 368 Messages.format( Messages.MUST_NOT_BE_NULL, o1Name ) ); 369 } 370 if( o2 == null ) { 371 throw new IllegalArgumentException( 372 Messages.format( Messages.MUST_NOT_BE_NULL, o2Name ) ); 373 } 374 } 375 }