Tue, 06 Mar 2012 16:09:35 -0800
7150322: Stop using drop source bundles in jaxws
Reviewed-by: darcy, ohrstrom
ohair@286 | 1 | /* |
ohair@286 | 2 | * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved. |
ohair@286 | 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
ohair@286 | 4 | * |
ohair@286 | 5 | * This code is free software; you can redistribute it and/or modify it |
ohair@286 | 6 | * under the terms of the GNU General Public License version 2 only, as |
ohair@286 | 7 | * published by the Free Software Foundation. Oracle designates this |
ohair@286 | 8 | * particular file as subject to the "Classpath" exception as provided |
ohair@286 | 9 | * by Oracle in the LICENSE file that accompanied this code. |
ohair@286 | 10 | * |
ohair@286 | 11 | * This code is distributed in the hope that it will be useful, but WITHOUT |
ohair@286 | 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
ohair@286 | 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
ohair@286 | 14 | * version 2 for more details (a copy is included in the LICENSE file that |
ohair@286 | 15 | * accompanied this code). |
ohair@286 | 16 | * |
ohair@286 | 17 | * You should have received a copy of the GNU General Public License version |
ohair@286 | 18 | * 2 along with this work; if not, write to the Free Software Foundation, |
ohair@286 | 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
ohair@286 | 20 | * |
ohair@286 | 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
ohair@286 | 22 | * or visit www.oracle.com if you need additional information or have any |
ohair@286 | 23 | * questions. |
ohair@286 | 24 | */ |
ohair@286 | 25 | |
ohair@286 | 26 | package javax.activation; |
ohair@286 | 27 | |
ohair@286 | 28 | import java.io.InputStream; |
ohair@286 | 29 | import java.io.IOException; |
ohair@286 | 30 | import java.io.OutputStream; |
ohair@286 | 31 | import java.io.PipedInputStream; |
ohair@286 | 32 | import java.io.PipedOutputStream; |
ohair@286 | 33 | import java.io.OutputStreamWriter; |
ohair@286 | 34 | import java.net.URL; |
ohair@286 | 35 | import java.awt.datatransfer.Transferable; |
ohair@286 | 36 | import java.awt.datatransfer.DataFlavor; |
ohair@286 | 37 | import java.awt.datatransfer.UnsupportedFlavorException; |
ohair@286 | 38 | |
ohair@286 | 39 | /** |
ohair@286 | 40 | * The DataHandler class provides a consistent interface to data |
ohair@286 | 41 | * available in many different sources and formats. |
ohair@286 | 42 | * It manages simple stream to string conversions and related operations |
ohair@286 | 43 | * using DataContentHandlers. |
ohair@286 | 44 | * It provides access to commands that can operate on the data. |
ohair@286 | 45 | * The commands are found using a CommandMap. <p> |
ohair@286 | 46 | * |
ohair@286 | 47 | * <b>DataHandler and the Transferable Interface</b><p> |
ohair@286 | 48 | * DataHandler implements the Transferable interface so that data can |
ohair@286 | 49 | * be used in AWT data transfer operations, such as cut and paste and |
ohair@286 | 50 | * drag and drop. The implementation of the Transferable interface |
ohair@286 | 51 | * relies on the availability of an installed DataContentHandler |
ohair@286 | 52 | * object corresponding to the MIME type of the data represented in |
ohair@286 | 53 | * the specific instance of the DataHandler.<p> |
ohair@286 | 54 | * |
ohair@286 | 55 | * <b>DataHandler and CommandMaps</b><p> |
ohair@286 | 56 | * The DataHandler keeps track of the current CommandMap that it uses to |
ohair@286 | 57 | * service requests for commands (<code>getCommand</code>, |
ohair@286 | 58 | * <code>getAllCommands</code>, <code>getPreferredCommands</code>). |
ohair@286 | 59 | * Each instance of a DataHandler may have a CommandMap associated with |
ohair@286 | 60 | * it using the <code>setCommandMap</code> method. If a CommandMap was |
ohair@286 | 61 | * not set, DataHandler calls the <code>getDefaultCommandMap</code> |
ohair@286 | 62 | * method in CommandMap and uses the value it returns. See |
ohair@286 | 63 | * <i>CommandMap</i> for more information. <p> |
ohair@286 | 64 | * |
ohair@286 | 65 | * <b>DataHandler and URLs</b><p> |
ohair@286 | 66 | * The current DataHandler implementation creates a private |
ohair@286 | 67 | * instance of URLDataSource when it is constructed with a URL. |
ohair@286 | 68 | * |
ohair@286 | 69 | * @see javax.activation.CommandMap |
ohair@286 | 70 | * @see javax.activation.DataContentHandler |
ohair@286 | 71 | * @see javax.activation.DataSource |
ohair@286 | 72 | * @see javax.activation.URLDataSource |
ohair@286 | 73 | * |
ohair@286 | 74 | * @since 1.6 |
ohair@286 | 75 | */ |
ohair@286 | 76 | |
ohair@286 | 77 | public class DataHandler implements Transferable { |
ohair@286 | 78 | |
ohair@286 | 79 | // Use the datasource to indicate whether we were started via the |
ohair@286 | 80 | // DataSource constructor or the object constructor. |
ohair@286 | 81 | private DataSource dataSource = null; |
ohair@286 | 82 | private DataSource objDataSource = null; |
ohair@286 | 83 | |
ohair@286 | 84 | // The Object and mimetype from the constructor (if passed in). |
ohair@286 | 85 | // object remains null if it was instantiated with a |
ohair@286 | 86 | // DataSource. |
ohair@286 | 87 | private Object object = null; |
ohair@286 | 88 | private String objectMimeType = null; |
ohair@286 | 89 | |
ohair@286 | 90 | // Keep track of the CommandMap |
ohair@286 | 91 | private CommandMap currentCommandMap = null; |
ohair@286 | 92 | |
ohair@286 | 93 | // our transfer flavors |
ohair@286 | 94 | private static final DataFlavor emptyFlavors[] = new DataFlavor[0]; |
ohair@286 | 95 | private DataFlavor transferFlavors[] = emptyFlavors; |
ohair@286 | 96 | |
ohair@286 | 97 | // our DataContentHandler |
ohair@286 | 98 | private DataContentHandler dataContentHandler = null; |
ohair@286 | 99 | private DataContentHandler factoryDCH = null; |
ohair@286 | 100 | |
ohair@286 | 101 | // our DataContentHandlerFactory |
ohair@286 | 102 | private static DataContentHandlerFactory factory = null; |
ohair@286 | 103 | private DataContentHandlerFactory oldFactory = null; |
ohair@286 | 104 | // the short representation of the ContentType (sans params) |
ohair@286 | 105 | private String shortType = null; |
ohair@286 | 106 | |
ohair@286 | 107 | /** |
ohair@286 | 108 | * Create a <code>DataHandler</code> instance referencing the |
ohair@286 | 109 | * specified DataSource. The data exists in a byte stream form. |
ohair@286 | 110 | * The DataSource will provide an InputStream to access the data. |
ohair@286 | 111 | * |
ohair@286 | 112 | * @param ds the DataSource |
ohair@286 | 113 | */ |
ohair@286 | 114 | public DataHandler(DataSource ds) { |
ohair@286 | 115 | // save a reference to the incoming DS |
ohair@286 | 116 | dataSource = ds; |
ohair@286 | 117 | oldFactory = factory; // keep track of the factory |
ohair@286 | 118 | } |
ohair@286 | 119 | |
ohair@286 | 120 | /** |
ohair@286 | 121 | * Create a <code>DataHandler</code> instance representing an object |
ohair@286 | 122 | * of this MIME type. This constructor is |
ohair@286 | 123 | * used when the application already has an in-memory representation |
ohair@286 | 124 | * of the data in the form of a Java Object. |
ohair@286 | 125 | * |
ohair@286 | 126 | * @param obj the Java Object |
ohair@286 | 127 | * @param mimeType the MIME type of the object |
ohair@286 | 128 | */ |
ohair@286 | 129 | public DataHandler(Object obj, String mimeType) { |
ohair@286 | 130 | object = obj; |
ohair@286 | 131 | objectMimeType = mimeType; |
ohair@286 | 132 | oldFactory = factory; // keep track of the factory |
ohair@286 | 133 | } |
ohair@286 | 134 | |
ohair@286 | 135 | /** |
ohair@286 | 136 | * Create a <code>DataHandler</code> instance referencing a URL. |
ohair@286 | 137 | * The DataHandler internally creates a <code>URLDataSource</code> |
ohair@286 | 138 | * instance to represent the URL. |
ohair@286 | 139 | * |
ohair@286 | 140 | * @param url a URL object |
ohair@286 | 141 | */ |
ohair@286 | 142 | public DataHandler(URL url) { |
ohair@286 | 143 | dataSource = new URLDataSource(url); |
ohair@286 | 144 | oldFactory = factory; // keep track of the factory |
ohair@286 | 145 | } |
ohair@286 | 146 | |
ohair@286 | 147 | /** |
ohair@286 | 148 | * Return the CommandMap for this instance of DataHandler. |
ohair@286 | 149 | */ |
ohair@286 | 150 | private synchronized CommandMap getCommandMap() { |
ohair@286 | 151 | if (currentCommandMap != null) |
ohair@286 | 152 | return currentCommandMap; |
ohair@286 | 153 | else |
ohair@286 | 154 | return CommandMap.getDefaultCommandMap(); |
ohair@286 | 155 | } |
ohair@286 | 156 | |
ohair@286 | 157 | /** |
ohair@286 | 158 | * Return the DataSource associated with this instance |
ohair@286 | 159 | * of DataHandler. |
ohair@286 | 160 | * <p> |
ohair@286 | 161 | * For DataHandlers that have been instantiated with a DataSource, |
ohair@286 | 162 | * this method returns the DataSource that was used to create the |
ohair@286 | 163 | * DataHandler object. In other cases the DataHandler |
ohair@286 | 164 | * constructs a DataSource from the data used to construct |
ohair@286 | 165 | * the DataHandler. DataSources created for DataHandlers <b>not</b> |
ohair@286 | 166 | * instantiated with a DataSource are cached for performance |
ohair@286 | 167 | * reasons. |
ohair@286 | 168 | * |
ohair@286 | 169 | * @return a valid DataSource object for this DataHandler |
ohair@286 | 170 | */ |
ohair@286 | 171 | public DataSource getDataSource() { |
ohair@286 | 172 | if (dataSource == null) { |
ohair@286 | 173 | // create one on the fly |
ohair@286 | 174 | if (objDataSource == null) |
ohair@286 | 175 | objDataSource = new DataHandlerDataSource(this); |
ohair@286 | 176 | return objDataSource; |
ohair@286 | 177 | } |
ohair@286 | 178 | return dataSource; |
ohair@286 | 179 | } |
ohair@286 | 180 | |
ohair@286 | 181 | /** |
ohair@286 | 182 | * Return the name of the data object. If this DataHandler |
ohair@286 | 183 | * was created with a DataSource, this method calls through |
ohair@286 | 184 | * to the <code>DataSource.getName</code> method, otherwise it |
ohair@286 | 185 | * returns <i>null</i>. |
ohair@286 | 186 | * |
ohair@286 | 187 | * @return the name of the object |
ohair@286 | 188 | */ |
ohair@286 | 189 | public String getName() { |
ohair@286 | 190 | if (dataSource != null) |
ohair@286 | 191 | return dataSource.getName(); |
ohair@286 | 192 | else |
ohair@286 | 193 | return null; |
ohair@286 | 194 | } |
ohair@286 | 195 | |
ohair@286 | 196 | /** |
ohair@286 | 197 | * Return the MIME type of this object as retrieved from |
ohair@286 | 198 | * the source object. Note that this is the <i>full</i> |
ohair@286 | 199 | * type with parameters. |
ohair@286 | 200 | * |
ohair@286 | 201 | * @return the MIME type |
ohair@286 | 202 | */ |
ohair@286 | 203 | public String getContentType() { |
ohair@286 | 204 | if (dataSource != null) // data source case |
ohair@286 | 205 | return dataSource.getContentType(); |
ohair@286 | 206 | else |
ohair@286 | 207 | return objectMimeType; // obj/type case |
ohair@286 | 208 | } |
ohair@286 | 209 | |
ohair@286 | 210 | /** |
ohair@286 | 211 | * Get the InputStream for this object. <p> |
ohair@286 | 212 | * |
ohair@286 | 213 | * For DataHandlers instantiated with a DataSource, the DataHandler |
ohair@286 | 214 | * calls the <code>DataSource.getInputStream</code> method and |
ohair@286 | 215 | * returns the result to the caller. |
ohair@286 | 216 | * <p> |
ohair@286 | 217 | * For DataHandlers instantiated with an Object, the DataHandler |
ohair@286 | 218 | * first attempts to find a DataContentHandler for the Object. If |
ohair@286 | 219 | * the DataHandler can not find a DataContentHandler for this MIME |
ohair@286 | 220 | * type, it throws an UnsupportedDataTypeException. If it is |
ohair@286 | 221 | * successful, it creates a pipe and a thread. The thread uses the |
ohair@286 | 222 | * DataContentHandler's <code>writeTo</code> method to write the |
ohair@286 | 223 | * stream data into one end of the pipe. The other end of the pipe |
ohair@286 | 224 | * is returned to the caller. Because a thread is created to copy |
ohair@286 | 225 | * the data, IOExceptions that may occur during the copy can not be |
ohair@286 | 226 | * propagated back to the caller. The result is an empty stream.<p> |
ohair@286 | 227 | * |
ohair@286 | 228 | * @return the InputStream representing this data |
ohair@286 | 229 | * @exception IOException if an I/O error occurs |
ohair@286 | 230 | * |
ohair@286 | 231 | * @see javax.activation.DataContentHandler#writeTo |
ohair@286 | 232 | * @see javax.activation.UnsupportedDataTypeException |
ohair@286 | 233 | */ |
ohair@286 | 234 | public InputStream getInputStream() throws IOException { |
ohair@286 | 235 | InputStream ins = null; |
ohair@286 | 236 | |
ohair@286 | 237 | if (dataSource != null) { |
ohair@286 | 238 | ins = dataSource.getInputStream(); |
ohair@286 | 239 | } else { |
ohair@286 | 240 | DataContentHandler dch = getDataContentHandler(); |
ohair@286 | 241 | // we won't even try if we can't get a dch |
ohair@286 | 242 | if (dch == null) |
ohair@286 | 243 | throw new UnsupportedDataTypeException( |
ohair@286 | 244 | "no DCH for MIME type " + getBaseType()); |
ohair@286 | 245 | |
ohair@286 | 246 | if (dch instanceof ObjectDataContentHandler) { |
ohair@286 | 247 | if (((ObjectDataContentHandler)dch).getDCH() == null) |
ohair@286 | 248 | throw new UnsupportedDataTypeException( |
ohair@286 | 249 | "no object DCH for MIME type " + getBaseType()); |
ohair@286 | 250 | } |
ohair@286 | 251 | // there is none but the default^^^^^^^^^^^^^^^^ |
ohair@286 | 252 | final DataContentHandler fdch = dch; |
ohair@286 | 253 | |
ohair@286 | 254 | // from bill s. |
ohair@286 | 255 | // ce n'est pas une pipe! |
ohair@286 | 256 | // |
ohair@286 | 257 | // NOTE: This block of code needs to throw exceptions, but |
ohair@286 | 258 | // can't because it is in another thread!!! ARG! |
ohair@286 | 259 | // |
ohair@286 | 260 | final PipedOutputStream pos = new PipedOutputStream(); |
ohair@286 | 261 | PipedInputStream pin = new PipedInputStream(pos); |
ohair@286 | 262 | new Thread( |
ohair@286 | 263 | new Runnable() { |
ohair@286 | 264 | public void run() { |
ohair@286 | 265 | try { |
ohair@286 | 266 | fdch.writeTo(object, objectMimeType, pos); |
ohair@286 | 267 | } catch (IOException e) { |
ohair@286 | 268 | |
ohair@286 | 269 | } finally { |
ohair@286 | 270 | try { |
ohair@286 | 271 | pos.close(); |
ohair@286 | 272 | } catch (IOException ie) { } |
ohair@286 | 273 | } |
ohair@286 | 274 | } |
ohair@286 | 275 | }, |
ohair@286 | 276 | "DataHandler.getInputStream").start(); |
ohair@286 | 277 | ins = pin; |
ohair@286 | 278 | } |
ohair@286 | 279 | |
ohair@286 | 280 | return ins; |
ohair@286 | 281 | } |
ohair@286 | 282 | |
ohair@286 | 283 | /** |
ohair@286 | 284 | * Write the data to an <code>OutputStream</code>.<p> |
ohair@286 | 285 | * |
ohair@286 | 286 | * If the DataHandler was created with a DataSource, writeTo |
ohair@286 | 287 | * retrieves the InputStream and copies the bytes from the |
ohair@286 | 288 | * InputStream to the OutputStream passed in. |
ohair@286 | 289 | * <p> |
ohair@286 | 290 | * If the DataHandler was created with an object, writeTo |
ohair@286 | 291 | * retrieves the DataContentHandler for the object's type. |
ohair@286 | 292 | * If the DataContentHandler was found, it calls the |
ohair@286 | 293 | * <code>writeTo</code> method on the <code>DataContentHandler</code>. |
ohair@286 | 294 | * |
ohair@286 | 295 | * @param os the OutputStream to write to |
ohair@286 | 296 | * @exception IOException if an I/O error occurs |
ohair@286 | 297 | */ |
ohair@286 | 298 | public void writeTo(OutputStream os) throws IOException { |
ohair@286 | 299 | // for the DataSource case |
ohair@286 | 300 | if (dataSource != null) { |
ohair@286 | 301 | InputStream is = null; |
ohair@286 | 302 | byte data[] = new byte[8*1024]; |
ohair@286 | 303 | int bytes_read; |
ohair@286 | 304 | |
ohair@286 | 305 | is = dataSource.getInputStream(); |
ohair@286 | 306 | |
ohair@286 | 307 | try { |
ohair@286 | 308 | while ((bytes_read = is.read(data)) > 0) { |
ohair@286 | 309 | os.write(data, 0, bytes_read); |
ohair@286 | 310 | } |
ohair@286 | 311 | } finally { |
ohair@286 | 312 | is.close(); |
ohair@286 | 313 | is = null; |
ohair@286 | 314 | } |
ohair@286 | 315 | } else { // for the Object case |
ohair@286 | 316 | DataContentHandler dch = getDataContentHandler(); |
ohair@286 | 317 | dch.writeTo(object, objectMimeType, os); |
ohair@286 | 318 | } |
ohair@286 | 319 | } |
ohair@286 | 320 | |
ohair@286 | 321 | /** |
ohair@286 | 322 | * Get an OutputStream for this DataHandler to allow overwriting |
ohair@286 | 323 | * the underlying data. |
ohair@286 | 324 | * If the DataHandler was created with a DataSource, the |
ohair@286 | 325 | * DataSource's <code>getOutputStream</code> method is called. |
ohair@286 | 326 | * Otherwise, <code>null</code> is returned. |
ohair@286 | 327 | * |
ohair@286 | 328 | * @return the OutputStream |
ohair@286 | 329 | * |
ohair@286 | 330 | * @see javax.activation.DataSource#getOutputStream |
ohair@286 | 331 | * @see javax.activation.URLDataSource |
ohair@286 | 332 | */ |
ohair@286 | 333 | public OutputStream getOutputStream() throws IOException { |
ohair@286 | 334 | if (dataSource != null) |
ohair@286 | 335 | return dataSource.getOutputStream(); |
ohair@286 | 336 | else |
ohair@286 | 337 | return null; |
ohair@286 | 338 | } |
ohair@286 | 339 | |
ohair@286 | 340 | /** |
ohair@286 | 341 | * Return the DataFlavors in which this data is available. <p> |
ohair@286 | 342 | * |
ohair@286 | 343 | * Returns an array of DataFlavor objects indicating the flavors |
ohair@286 | 344 | * the data can be provided in. The array is usually ordered |
ohair@286 | 345 | * according to preference for providing the data, from most |
ohair@286 | 346 | * richly descriptive to least richly descriptive.<p> |
ohair@286 | 347 | * |
ohair@286 | 348 | * The DataHandler attempts to find a DataContentHandler that |
ohair@286 | 349 | * corresponds to the MIME type of the data. If one is located, |
ohair@286 | 350 | * the DataHandler calls the DataContentHandler's |
ohair@286 | 351 | * <code>getTransferDataFlavors</code> method. <p> |
ohair@286 | 352 | * |
ohair@286 | 353 | * If a DataContentHandler can <i>not</i> be located, and if the |
ohair@286 | 354 | * DataHandler was created with a DataSource (or URL), one |
ohair@286 | 355 | * DataFlavor is returned that represents this object's MIME type |
ohair@286 | 356 | * and the <code>java.io.InputStream</code> class. If the |
ohair@286 | 357 | * DataHandler was created with an object and a MIME type, |
ohair@286 | 358 | * getTransferDataFlavors returns one DataFlavor that represents |
ohair@286 | 359 | * this object's MIME type and the object's class. |
ohair@286 | 360 | * |
ohair@286 | 361 | * @return an array of data flavors in which this data can be transferred |
ohair@286 | 362 | * @see javax.activation.DataContentHandler#getTransferDataFlavors |
ohair@286 | 363 | */ |
ohair@286 | 364 | public synchronized DataFlavor[] getTransferDataFlavors() { |
ohair@286 | 365 | if (factory != oldFactory) // if the factory has changed, clear cache |
ohair@286 | 366 | transferFlavors = emptyFlavors; |
ohair@286 | 367 | |
ohair@286 | 368 | // if it's not set, set it... |
ohair@286 | 369 | if (transferFlavors == emptyFlavors) |
ohair@286 | 370 | transferFlavors = getDataContentHandler().getTransferDataFlavors(); |
ohair@286 | 371 | return transferFlavors; |
ohair@286 | 372 | } |
ohair@286 | 373 | |
ohair@286 | 374 | /** |
ohair@286 | 375 | * Returns whether the specified data flavor is supported |
ohair@286 | 376 | * for this object.<p> |
ohair@286 | 377 | * |
ohair@286 | 378 | * This method iterates through the DataFlavors returned from |
ohair@286 | 379 | * <code>getTransferDataFlavors</code>, comparing each with |
ohair@286 | 380 | * the specified flavor. |
ohair@286 | 381 | * |
ohair@286 | 382 | * @param flavor the requested flavor for the data |
ohair@286 | 383 | * @return true if the data flavor is supported |
ohair@286 | 384 | * @see javax.activation.DataHandler#getTransferDataFlavors |
ohair@286 | 385 | */ |
ohair@286 | 386 | public boolean isDataFlavorSupported(DataFlavor flavor) { |
ohair@286 | 387 | DataFlavor[] lFlavors = getTransferDataFlavors(); |
ohair@286 | 388 | |
ohair@286 | 389 | for (int i = 0; i < lFlavors.length; i++) { |
ohair@286 | 390 | if (lFlavors[i].equals(flavor)) |
ohair@286 | 391 | return true; |
ohair@286 | 392 | } |
ohair@286 | 393 | return false; |
ohair@286 | 394 | } |
ohair@286 | 395 | |
ohair@286 | 396 | /** |
ohair@286 | 397 | * Returns an object that represents the data to be |
ohair@286 | 398 | * transferred. The class of the object returned is defined by the |
ohair@286 | 399 | * representation class of the data flavor.<p> |
ohair@286 | 400 | * |
ohair@286 | 401 | * <b>For DataHandler's created with DataSources or URLs:</b><p> |
ohair@286 | 402 | * |
ohair@286 | 403 | * The DataHandler attempts to locate a DataContentHandler |
ohair@286 | 404 | * for this MIME type. If one is found, the passed in DataFlavor |
ohair@286 | 405 | * and the type of the data are passed to its <code>getTransferData</code> |
ohair@286 | 406 | * method. If the DataHandler fails to locate a DataContentHandler |
ohair@286 | 407 | * and the flavor specifies this object's MIME type and the |
ohair@286 | 408 | * <code>java.io.InputStream</code> class, this object's InputStream |
ohair@286 | 409 | * is returned. |
ohair@286 | 410 | * Otherwise it throws an UnsupportedFlavorException. <p> |
ohair@286 | 411 | * |
ohair@286 | 412 | * <b>For DataHandler's created with Objects:</b><p> |
ohair@286 | 413 | * |
ohair@286 | 414 | * The DataHandler attempts to locate a DataContentHandler |
ohair@286 | 415 | * for this MIME type. If one is found, the passed in DataFlavor |
ohair@286 | 416 | * and the type of the data are passed to its getTransferData |
ohair@286 | 417 | * method. If the DataHandler fails to locate a DataContentHandler |
ohair@286 | 418 | * and the flavor specifies this object's MIME type and its class, |
ohair@286 | 419 | * this DataHandler's referenced object is returned. |
ohair@286 | 420 | * Otherwise it throws an UnsupportedFlavorException. |
ohair@286 | 421 | * |
ohair@286 | 422 | * @param flavor the requested flavor for the data |
ohair@286 | 423 | * @return the object |
ohair@286 | 424 | * @exception UnsupportedFlavorException if the data could not be |
ohair@286 | 425 | * converted to the requested flavor |
ohair@286 | 426 | * @exception IOException if an I/O error occurs |
ohair@286 | 427 | * @see javax.activation.ActivationDataFlavor |
ohair@286 | 428 | */ |
ohair@286 | 429 | public Object getTransferData(DataFlavor flavor) |
ohair@286 | 430 | throws UnsupportedFlavorException, IOException { |
ohair@286 | 431 | return getDataContentHandler().getTransferData(flavor, dataSource); |
ohair@286 | 432 | } |
ohair@286 | 433 | |
ohair@286 | 434 | /** |
ohair@286 | 435 | * Set the CommandMap for use by this DataHandler. |
ohair@286 | 436 | * Setting it to <code>null</code> causes the CommandMap to revert |
ohair@286 | 437 | * to the CommandMap returned by the |
ohair@286 | 438 | * <code>CommandMap.getDefaultCommandMap</code> method. |
ohair@286 | 439 | * Changing the CommandMap, or setting it to <code>null</code>, |
ohair@286 | 440 | * clears out any data cached from the previous CommandMap. |
ohair@286 | 441 | * |
ohair@286 | 442 | * @param commandMap the CommandMap to use in this DataHandler |
ohair@286 | 443 | * |
ohair@286 | 444 | * @see javax.activation.CommandMap#setDefaultCommandMap |
ohair@286 | 445 | */ |
ohair@286 | 446 | public synchronized void setCommandMap(CommandMap commandMap) { |
ohair@286 | 447 | if (commandMap != currentCommandMap || commandMap == null) { |
ohair@286 | 448 | // clear cached values... |
ohair@286 | 449 | transferFlavors = emptyFlavors; |
ohair@286 | 450 | dataContentHandler = null; |
ohair@286 | 451 | |
ohair@286 | 452 | currentCommandMap = commandMap; |
ohair@286 | 453 | } |
ohair@286 | 454 | } |
ohair@286 | 455 | |
ohair@286 | 456 | /** |
ohair@286 | 457 | * Return the <i>preferred</i> commands for this type of data. |
ohair@286 | 458 | * This method calls the <code>getPreferredCommands</code> method |
ohair@286 | 459 | * in the CommandMap associated with this instance of DataHandler. |
ohair@286 | 460 | * This method returns an array that represents a subset of |
ohair@286 | 461 | * available commands. In cases where multiple commands for the |
ohair@286 | 462 | * MIME type represented by this DataHandler are present, the |
ohair@286 | 463 | * installed CommandMap chooses the appropriate commands. |
ohair@286 | 464 | * |
ohair@286 | 465 | * @return the CommandInfo objects representing the preferred commands |
ohair@286 | 466 | * |
ohair@286 | 467 | * @see javax.activation.CommandMap#getPreferredCommands |
ohair@286 | 468 | */ |
ohair@286 | 469 | public CommandInfo[] getPreferredCommands() { |
ohair@286 | 470 | if (dataSource != null) |
ohair@286 | 471 | return getCommandMap().getPreferredCommands(getBaseType(), |
ohair@286 | 472 | dataSource); |
ohair@286 | 473 | else |
ohair@286 | 474 | return getCommandMap().getPreferredCommands(getBaseType()); |
ohair@286 | 475 | } |
ohair@286 | 476 | |
ohair@286 | 477 | /** |
ohair@286 | 478 | * Return all the commands for this type of data. |
ohair@286 | 479 | * This method returns an array containing all commands |
ohair@286 | 480 | * for the type of data represented by this DataHandler. The |
ohair@286 | 481 | * MIME type for the underlying data represented by this DataHandler |
ohair@286 | 482 | * is used to call through to the <code>getAllCommands</code> method |
ohair@286 | 483 | * of the CommandMap associated with this DataHandler. |
ohair@286 | 484 | * |
ohair@286 | 485 | * @return the CommandInfo objects representing all the commands |
ohair@286 | 486 | * |
ohair@286 | 487 | * @see javax.activation.CommandMap#getAllCommands |
ohair@286 | 488 | */ |
ohair@286 | 489 | public CommandInfo[] getAllCommands() { |
ohair@286 | 490 | if (dataSource != null) |
ohair@286 | 491 | return getCommandMap().getAllCommands(getBaseType(), dataSource); |
ohair@286 | 492 | else |
ohair@286 | 493 | return getCommandMap().getAllCommands(getBaseType()); |
ohair@286 | 494 | } |
ohair@286 | 495 | |
ohair@286 | 496 | /** |
ohair@286 | 497 | * Get the command <i>cmdName</i>. Use the search semantics as |
ohair@286 | 498 | * defined by the CommandMap installed in this DataHandler. The |
ohair@286 | 499 | * MIME type for the underlying data represented by this DataHandler |
ohair@286 | 500 | * is used to call through to the <code>getCommand</code> method |
ohair@286 | 501 | * of the CommandMap associated with this DataHandler. |
ohair@286 | 502 | * |
ohair@286 | 503 | * @param cmdName the command name |
ohair@286 | 504 | * @return the CommandInfo corresponding to the command |
ohair@286 | 505 | * |
ohair@286 | 506 | * @see javax.activation.CommandMap#getCommand |
ohair@286 | 507 | */ |
ohair@286 | 508 | public CommandInfo getCommand(String cmdName) { |
ohair@286 | 509 | if (dataSource != null) |
ohair@286 | 510 | return getCommandMap().getCommand(getBaseType(), cmdName, |
ohair@286 | 511 | dataSource); |
ohair@286 | 512 | else |
ohair@286 | 513 | return getCommandMap().getCommand(getBaseType(), cmdName); |
ohair@286 | 514 | } |
ohair@286 | 515 | |
ohair@286 | 516 | /** |
ohair@286 | 517 | * Return the data in its preferred Object form. <p> |
ohair@286 | 518 | * |
ohair@286 | 519 | * If the DataHandler was instantiated with an object, return |
ohair@286 | 520 | * the object. <p> |
ohair@286 | 521 | * |
ohair@286 | 522 | * If the DataHandler was instantiated with a DataSource, |
ohair@286 | 523 | * this method uses a DataContentHandler to return the content |
ohair@286 | 524 | * object for the data represented by this DataHandler. If no |
ohair@286 | 525 | * <code>DataContentHandler</code> can be found for the |
ohair@286 | 526 | * the type of this data, the DataHandler returns an |
ohair@286 | 527 | * InputStream for the data. |
ohair@286 | 528 | * |
ohair@286 | 529 | * @return the content. |
ohair@286 | 530 | * @exception IOException if an IOException occurs during |
ohair@286 | 531 | * this operation. |
ohair@286 | 532 | */ |
ohair@286 | 533 | public Object getContent() throws IOException { |
ohair@286 | 534 | if (object != null) |
ohair@286 | 535 | return object; |
ohair@286 | 536 | else |
ohair@286 | 537 | return getDataContentHandler().getContent(getDataSource()); |
ohair@286 | 538 | } |
ohair@286 | 539 | |
ohair@286 | 540 | /** |
ohair@286 | 541 | * A convenience method that takes a CommandInfo object |
ohair@286 | 542 | * and instantiates the corresponding command, usually |
ohair@286 | 543 | * a JavaBean component. |
ohair@286 | 544 | * <p> |
ohair@286 | 545 | * This method calls the CommandInfo's <code>getCommandObject</code> |
ohair@286 | 546 | * method with the <code>ClassLoader</code> used to load |
ohair@286 | 547 | * the <code>javax.activation.DataHandler</code> class itself. |
ohair@286 | 548 | * |
ohair@286 | 549 | * @param cmdinfo the CommandInfo corresponding to a command |
ohair@286 | 550 | * @return the instantiated command object |
ohair@286 | 551 | */ |
ohair@286 | 552 | public Object getBean(CommandInfo cmdinfo) { |
ohair@286 | 553 | Object bean = null; |
ohair@286 | 554 | |
ohair@286 | 555 | try { |
ohair@286 | 556 | // make the bean |
ohair@286 | 557 | ClassLoader cld = null; |
ohair@286 | 558 | // First try the "application's" class loader. |
ohair@286 | 559 | cld = SecuritySupport.getContextClassLoader(); |
ohair@286 | 560 | if (cld == null) |
ohair@286 | 561 | cld = this.getClass().getClassLoader(); |
ohair@286 | 562 | bean = cmdinfo.getCommandObject(this, cld); |
ohair@286 | 563 | } catch (IOException e) { |
ohair@286 | 564 | } catch (ClassNotFoundException e) { } |
ohair@286 | 565 | |
ohair@286 | 566 | return bean; |
ohair@286 | 567 | } |
ohair@286 | 568 | |
ohair@286 | 569 | /** |
ohair@286 | 570 | * Get the DataContentHandler for this DataHandler: <p> |
ohair@286 | 571 | * |
ohair@286 | 572 | * If a DataContentHandlerFactory is set, use it. |
ohair@286 | 573 | * Otherwise look for an object to serve DCH in the |
ohair@286 | 574 | * following order: <p> |
ohair@286 | 575 | * |
ohair@286 | 576 | * 1) if a factory is set, use it <p> |
ohair@286 | 577 | * 2) if a CommandMap is set, use it <p> |
ohair@286 | 578 | * 3) use the default CommandMap <p> |
ohair@286 | 579 | * |
ohair@286 | 580 | * In any case, wrap the real DataContentHandler with one of our own |
ohair@286 | 581 | * to handle any missing cases, fill in defaults, and to ensure that |
ohair@286 | 582 | * we always have a non-null DataContentHandler. |
ohair@286 | 583 | * |
ohair@286 | 584 | * @return the requested DataContentHandler |
ohair@286 | 585 | */ |
ohair@286 | 586 | private synchronized DataContentHandler getDataContentHandler() { |
ohair@286 | 587 | |
ohair@286 | 588 | // make sure the factory didn't change |
ohair@286 | 589 | if (factory != oldFactory) { |
ohair@286 | 590 | oldFactory = factory; |
ohair@286 | 591 | factoryDCH = null; |
ohair@286 | 592 | dataContentHandler = null; |
ohair@286 | 593 | transferFlavors = emptyFlavors; |
ohair@286 | 594 | } |
ohair@286 | 595 | |
ohair@286 | 596 | if (dataContentHandler != null) |
ohair@286 | 597 | return dataContentHandler; |
ohair@286 | 598 | |
ohair@286 | 599 | String simpleMT = getBaseType(); |
ohair@286 | 600 | |
ohair@286 | 601 | if (factoryDCH == null && factory != null) |
ohair@286 | 602 | factoryDCH = factory.createDataContentHandler(simpleMT); |
ohair@286 | 603 | |
ohair@286 | 604 | if (factoryDCH != null) |
ohair@286 | 605 | dataContentHandler = factoryDCH; |
ohair@286 | 606 | |
ohair@286 | 607 | if (dataContentHandler == null) { |
ohair@286 | 608 | if (dataSource != null) |
ohair@286 | 609 | dataContentHandler = getCommandMap(). |
ohair@286 | 610 | createDataContentHandler(simpleMT, dataSource); |
ohair@286 | 611 | else |
ohair@286 | 612 | dataContentHandler = getCommandMap(). |
ohair@286 | 613 | createDataContentHandler(simpleMT); |
ohair@286 | 614 | } |
ohair@286 | 615 | |
ohair@286 | 616 | // getDataContentHandler always uses these 'wrapper' handlers |
ohair@286 | 617 | // to make sure it returns SOMETHING meaningful... |
ohair@286 | 618 | if (dataSource != null) |
ohair@286 | 619 | dataContentHandler = new DataSourceDataContentHandler( |
ohair@286 | 620 | dataContentHandler, |
ohair@286 | 621 | dataSource); |
ohair@286 | 622 | else |
ohair@286 | 623 | dataContentHandler = new ObjectDataContentHandler( |
ohair@286 | 624 | dataContentHandler, |
ohair@286 | 625 | object, |
ohair@286 | 626 | objectMimeType); |
ohair@286 | 627 | return dataContentHandler; |
ohair@286 | 628 | } |
ohair@286 | 629 | |
ohair@286 | 630 | /** |
ohair@286 | 631 | * Use the MimeType class to extract the MIME type/subtype, |
ohair@286 | 632 | * ignoring the parameters. The type is cached. |
ohair@286 | 633 | */ |
ohair@286 | 634 | private synchronized String getBaseType() { |
ohair@286 | 635 | if (shortType == null) { |
ohair@286 | 636 | String ct = getContentType(); |
ohair@286 | 637 | try { |
ohair@286 | 638 | MimeType mt = new MimeType(ct); |
ohair@286 | 639 | shortType = mt.getBaseType(); |
ohair@286 | 640 | } catch (MimeTypeParseException e) { |
ohair@286 | 641 | shortType = ct; |
ohair@286 | 642 | } |
ohair@286 | 643 | } |
ohair@286 | 644 | return shortType; |
ohair@286 | 645 | } |
ohair@286 | 646 | |
ohair@286 | 647 | /** |
ohair@286 | 648 | * Sets the DataContentHandlerFactory. The DataContentHandlerFactory |
ohair@286 | 649 | * is called first to find DataContentHandlers. |
ohair@286 | 650 | * The DataContentHandlerFactory can only be set once. |
ohair@286 | 651 | * <p> |
ohair@286 | 652 | * If the DataContentHandlerFactory has already been set, |
ohair@286 | 653 | * this method throws an Error. |
ohair@286 | 654 | * |
ohair@286 | 655 | * @param newFactory the DataContentHandlerFactory |
ohair@286 | 656 | * @exception Error if the factory has already been defined. |
ohair@286 | 657 | * |
ohair@286 | 658 | * @see javax.activation.DataContentHandlerFactory |
ohair@286 | 659 | */ |
ohair@286 | 660 | public static synchronized void setDataContentHandlerFactory( |
ohair@286 | 661 | DataContentHandlerFactory newFactory) { |
ohair@286 | 662 | if (factory != null) |
ohair@286 | 663 | throw new Error("DataContentHandlerFactory already defined"); |
ohair@286 | 664 | |
ohair@286 | 665 | SecurityManager security = System.getSecurityManager(); |
ohair@286 | 666 | if (security != null) { |
ohair@286 | 667 | try { |
ohair@286 | 668 | // if it's ok with the SecurityManager, it's ok with me... |
ohair@286 | 669 | security.checkSetFactory(); |
ohair@286 | 670 | } catch (SecurityException ex) { |
ohair@286 | 671 | // otherwise, we also allow it if this code and the |
ohair@286 | 672 | // factory come from the same class loader (e.g., |
ohair@286 | 673 | // the JAF classes were loaded with the applet classes). |
ohair@286 | 674 | if (DataHandler.class.getClassLoader() != |
ohair@286 | 675 | newFactory.getClass().getClassLoader()) |
ohair@286 | 676 | throw ex; |
ohair@286 | 677 | } |
ohair@286 | 678 | } |
ohair@286 | 679 | factory = newFactory; |
ohair@286 | 680 | } |
ohair@286 | 681 | } |
ohair@286 | 682 | |
ohair@286 | 683 | /** |
ohair@286 | 684 | * The DataHanderDataSource class implements the |
ohair@286 | 685 | * DataSource interface when the DataHandler is constructed |
ohair@286 | 686 | * with an Object and a mimeType string. |
ohair@286 | 687 | */ |
ohair@286 | 688 | class DataHandlerDataSource implements DataSource { |
ohair@286 | 689 | DataHandler dataHandler = null; |
ohair@286 | 690 | |
ohair@286 | 691 | /** |
ohair@286 | 692 | * The constructor. |
ohair@286 | 693 | */ |
ohair@286 | 694 | public DataHandlerDataSource(DataHandler dh) { |
ohair@286 | 695 | this.dataHandler = dh; |
ohair@286 | 696 | } |
ohair@286 | 697 | |
ohair@286 | 698 | /** |
ohair@286 | 699 | * Returns an <code>InputStream</code> representing this object. |
ohair@286 | 700 | * @return the <code>InputStream</code> |
ohair@286 | 701 | */ |
ohair@286 | 702 | public InputStream getInputStream() throws IOException { |
ohair@286 | 703 | return dataHandler.getInputStream(); |
ohair@286 | 704 | } |
ohair@286 | 705 | |
ohair@286 | 706 | /** |
ohair@286 | 707 | * Returns the <code>OutputStream</code> for this object. |
ohair@286 | 708 | * @return the <code>OutputStream</code> |
ohair@286 | 709 | */ |
ohair@286 | 710 | public OutputStream getOutputStream() throws IOException { |
ohair@286 | 711 | return dataHandler.getOutputStream(); |
ohair@286 | 712 | } |
ohair@286 | 713 | |
ohair@286 | 714 | /** |
ohair@286 | 715 | * Returns the MIME type of the data represented by this object. |
ohair@286 | 716 | * @return the MIME type |
ohair@286 | 717 | */ |
ohair@286 | 718 | public String getContentType() { |
ohair@286 | 719 | return dataHandler.getContentType(); |
ohair@286 | 720 | } |
ohair@286 | 721 | |
ohair@286 | 722 | /** |
ohair@286 | 723 | * Returns the name of this object. |
ohair@286 | 724 | * @return the name of this object |
ohair@286 | 725 | */ |
ohair@286 | 726 | public String getName() { |
ohair@286 | 727 | return dataHandler.getName(); // what else would it be? |
ohair@286 | 728 | } |
ohair@286 | 729 | } |
ohair@286 | 730 | |
ohair@286 | 731 | /* |
ohair@286 | 732 | * DataSourceDataContentHandler |
ohair@286 | 733 | * |
ohair@286 | 734 | * This is a <i>private</i> DataContentHandler that wraps the real |
ohair@286 | 735 | * DataContentHandler in the case where the DataHandler was instantiated |
ohair@286 | 736 | * with a DataSource. |
ohair@286 | 737 | */ |
ohair@286 | 738 | class DataSourceDataContentHandler implements DataContentHandler { |
ohair@286 | 739 | private DataSource ds = null; |
ohair@286 | 740 | private DataFlavor transferFlavors[] = null; |
ohair@286 | 741 | private DataContentHandler dch = null; |
ohair@286 | 742 | |
ohair@286 | 743 | /** |
ohair@286 | 744 | * The constructor. |
ohair@286 | 745 | */ |
ohair@286 | 746 | public DataSourceDataContentHandler(DataContentHandler dch, DataSource ds) { |
ohair@286 | 747 | this.ds = ds; |
ohair@286 | 748 | this.dch = dch; |
ohair@286 | 749 | } |
ohair@286 | 750 | |
ohair@286 | 751 | /** |
ohair@286 | 752 | * Return the DataFlavors for this <code>DataContentHandler</code>. |
ohair@286 | 753 | * @return the DataFlavors |
ohair@286 | 754 | */ |
ohair@286 | 755 | public DataFlavor[] getTransferDataFlavors() { |
ohair@286 | 756 | |
ohair@286 | 757 | if (transferFlavors == null) { |
ohair@286 | 758 | if (dch != null) { // is there a dch? |
ohair@286 | 759 | transferFlavors = dch.getTransferDataFlavors(); |
ohair@286 | 760 | } else { |
ohair@286 | 761 | transferFlavors = new DataFlavor[1]; |
ohair@286 | 762 | transferFlavors[0] = |
ohair@286 | 763 | new ActivationDataFlavor(ds.getContentType(), |
ohair@286 | 764 | ds.getContentType()); |
ohair@286 | 765 | } |
ohair@286 | 766 | } |
ohair@286 | 767 | return transferFlavors; |
ohair@286 | 768 | } |
ohair@286 | 769 | |
ohair@286 | 770 | /** |
ohair@286 | 771 | * Return the Transfer Data of type DataFlavor from InputStream. |
ohair@286 | 772 | * @param df the DataFlavor |
ohair@286 | 773 | * @param ds the DataSource |
ohair@286 | 774 | * @return the constructed Object |
ohair@286 | 775 | */ |
ohair@286 | 776 | public Object getTransferData(DataFlavor df, DataSource ds) throws |
ohair@286 | 777 | UnsupportedFlavorException, IOException { |
ohair@286 | 778 | |
ohair@286 | 779 | if (dch != null) |
ohair@286 | 780 | return dch.getTransferData(df, ds); |
ohair@286 | 781 | else if (df.equals(getTransferDataFlavors()[0])) // only have one now |
ohair@286 | 782 | return ds.getInputStream(); |
ohair@286 | 783 | else |
ohair@286 | 784 | throw new UnsupportedFlavorException(df); |
ohair@286 | 785 | } |
ohair@286 | 786 | |
ohair@286 | 787 | public Object getContent(DataSource ds) throws IOException { |
ohair@286 | 788 | |
ohair@286 | 789 | if (dch != null) |
ohair@286 | 790 | return dch.getContent(ds); |
ohair@286 | 791 | else |
ohair@286 | 792 | return ds.getInputStream(); |
ohair@286 | 793 | } |
ohair@286 | 794 | |
ohair@286 | 795 | /** |
ohair@286 | 796 | * Write the object to the output stream. |
ohair@286 | 797 | */ |
ohair@286 | 798 | public void writeTo(Object obj, String mimeType, OutputStream os) |
ohair@286 | 799 | throws IOException { |
ohair@286 | 800 | if (dch != null) |
ohair@286 | 801 | dch.writeTo(obj, mimeType, os); |
ohair@286 | 802 | else |
ohair@286 | 803 | throw new UnsupportedDataTypeException( |
ohair@286 | 804 | "no DCH for content type " + ds.getContentType()); |
ohair@286 | 805 | } |
ohair@286 | 806 | } |
ohair@286 | 807 | |
ohair@286 | 808 | /* |
ohair@286 | 809 | * ObjectDataContentHandler |
ohair@286 | 810 | * |
ohair@286 | 811 | * This is a <i>private</i> DataContentHandler that wraps the real |
ohair@286 | 812 | * DataContentHandler in the case where the DataHandler was instantiated |
ohair@286 | 813 | * with an object. |
ohair@286 | 814 | */ |
ohair@286 | 815 | class ObjectDataContentHandler implements DataContentHandler { |
ohair@286 | 816 | private DataFlavor transferFlavors[] = null; |
ohair@286 | 817 | private Object obj; |
ohair@286 | 818 | private String mimeType; |
ohair@286 | 819 | private DataContentHandler dch = null; |
ohair@286 | 820 | |
ohair@286 | 821 | /** |
ohair@286 | 822 | * The constructor. |
ohair@286 | 823 | */ |
ohair@286 | 824 | public ObjectDataContentHandler(DataContentHandler dch, |
ohair@286 | 825 | Object obj, String mimeType) { |
ohair@286 | 826 | this.obj = obj; |
ohair@286 | 827 | this.mimeType = mimeType; |
ohair@286 | 828 | this.dch = dch; |
ohair@286 | 829 | } |
ohair@286 | 830 | |
ohair@286 | 831 | /** |
ohair@286 | 832 | * Return the DataContentHandler for this object. |
ohair@286 | 833 | * Used only by the DataHandler class. |
ohair@286 | 834 | */ |
ohair@286 | 835 | public DataContentHandler getDCH() { |
ohair@286 | 836 | return dch; |
ohair@286 | 837 | } |
ohair@286 | 838 | |
ohair@286 | 839 | /** |
ohair@286 | 840 | * Return the DataFlavors for this <code>DataContentHandler</code>. |
ohair@286 | 841 | * @return the DataFlavors |
ohair@286 | 842 | */ |
ohair@286 | 843 | public synchronized DataFlavor[] getTransferDataFlavors() { |
ohair@286 | 844 | if (transferFlavors == null) { |
ohair@286 | 845 | if (dch != null) { |
ohair@286 | 846 | transferFlavors = dch.getTransferDataFlavors(); |
ohair@286 | 847 | } else { |
ohair@286 | 848 | transferFlavors = new DataFlavor[1]; |
ohair@286 | 849 | transferFlavors[0] = new ActivationDataFlavor(obj.getClass(), |
ohair@286 | 850 | mimeType, mimeType); |
ohair@286 | 851 | } |
ohair@286 | 852 | } |
ohair@286 | 853 | return transferFlavors; |
ohair@286 | 854 | } |
ohair@286 | 855 | |
ohair@286 | 856 | /** |
ohair@286 | 857 | * Return the Transfer Data of type DataFlavor from InputStream. |
ohair@286 | 858 | * @param df the DataFlavor |
ohair@286 | 859 | * @param ds the DataSource |
ohair@286 | 860 | * @return the constructed Object |
ohair@286 | 861 | */ |
ohair@286 | 862 | public Object getTransferData(DataFlavor df, DataSource ds) |
ohair@286 | 863 | throws UnsupportedFlavorException, IOException { |
ohair@286 | 864 | |
ohair@286 | 865 | if (dch != null) |
ohair@286 | 866 | return dch.getTransferData(df, ds); |
ohair@286 | 867 | else if (df.equals(getTransferDataFlavors()[0])) // only have one now |
ohair@286 | 868 | return obj; |
ohair@286 | 869 | else |
ohair@286 | 870 | throw new UnsupportedFlavorException(df); |
ohair@286 | 871 | |
ohair@286 | 872 | } |
ohair@286 | 873 | |
ohair@286 | 874 | public Object getContent(DataSource ds) { |
ohair@286 | 875 | return obj; |
ohair@286 | 876 | } |
ohair@286 | 877 | |
ohair@286 | 878 | /** |
ohair@286 | 879 | * Write the object to the output stream. |
ohair@286 | 880 | */ |
ohair@286 | 881 | public void writeTo(Object obj, String mimeType, OutputStream os) |
ohair@286 | 882 | throws IOException { |
ohair@286 | 883 | if (dch != null) |
ohair@286 | 884 | dch.writeTo(obj, mimeType, os); |
ohair@286 | 885 | else if (obj instanceof byte[]) |
ohair@286 | 886 | os.write((byte[])obj); |
ohair@286 | 887 | else if (obj instanceof String) { |
ohair@286 | 888 | OutputStreamWriter osw = new OutputStreamWriter(os); |
ohair@286 | 889 | osw.write((String)obj); |
ohair@286 | 890 | osw.flush(); |
ohair@286 | 891 | } else throw new UnsupportedDataTypeException( |
ohair@286 | 892 | "no object DCH for MIME type " + this.mimeType); |
ohair@286 | 893 | } |
ohair@286 | 894 | } |