Wed, 27 Apr 2016 15:32:20 -0700
Added tag jdk8u102-b05 for changeset 1f512419ae33
ohair@286 | 1 | /* |
mkos@494 | 2 | * Copyright (c) 1997, 2013, 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(); |
mkos@494 | 371 | |
mkos@494 | 372 | if (transferFlavors == emptyFlavors) |
mkos@494 | 373 | return transferFlavors; |
mkos@494 | 374 | else |
mkos@494 | 375 | return transferFlavors.clone(); |
mkos@494 | 376 | |
ohair@286 | 377 | } |
ohair@286 | 378 | |
ohair@286 | 379 | /** |
ohair@286 | 380 | * Returns whether the specified data flavor is supported |
ohair@286 | 381 | * for this object.<p> |
ohair@286 | 382 | * |
ohair@286 | 383 | * This method iterates through the DataFlavors returned from |
ohair@286 | 384 | * <code>getTransferDataFlavors</code>, comparing each with |
ohair@286 | 385 | * the specified flavor. |
ohair@286 | 386 | * |
ohair@286 | 387 | * @param flavor the requested flavor for the data |
ohair@286 | 388 | * @return true if the data flavor is supported |
ohair@286 | 389 | * @see javax.activation.DataHandler#getTransferDataFlavors |
ohair@286 | 390 | */ |
ohair@286 | 391 | public boolean isDataFlavorSupported(DataFlavor flavor) { |
ohair@286 | 392 | DataFlavor[] lFlavors = getTransferDataFlavors(); |
ohair@286 | 393 | |
ohair@286 | 394 | for (int i = 0; i < lFlavors.length; i++) { |
ohair@286 | 395 | if (lFlavors[i].equals(flavor)) |
ohair@286 | 396 | return true; |
ohair@286 | 397 | } |
ohair@286 | 398 | return false; |
ohair@286 | 399 | } |
ohair@286 | 400 | |
ohair@286 | 401 | /** |
ohair@286 | 402 | * Returns an object that represents the data to be |
ohair@286 | 403 | * transferred. The class of the object returned is defined by the |
ohair@286 | 404 | * representation class of the data flavor.<p> |
ohair@286 | 405 | * |
ohair@286 | 406 | * <b>For DataHandler's created with DataSources or URLs:</b><p> |
ohair@286 | 407 | * |
ohair@286 | 408 | * The DataHandler attempts to locate a DataContentHandler |
ohair@286 | 409 | * for this MIME type. If one is found, the passed in DataFlavor |
ohair@286 | 410 | * and the type of the data are passed to its <code>getTransferData</code> |
ohair@286 | 411 | * method. If the DataHandler fails to locate a DataContentHandler |
ohair@286 | 412 | * and the flavor specifies this object's MIME type and the |
ohair@286 | 413 | * <code>java.io.InputStream</code> class, this object's InputStream |
ohair@286 | 414 | * is returned. |
ohair@286 | 415 | * Otherwise it throws an UnsupportedFlavorException. <p> |
ohair@286 | 416 | * |
ohair@286 | 417 | * <b>For DataHandler's created with Objects:</b><p> |
ohair@286 | 418 | * |
ohair@286 | 419 | * The DataHandler attempts to locate a DataContentHandler |
ohair@286 | 420 | * for this MIME type. If one is found, the passed in DataFlavor |
ohair@286 | 421 | * and the type of the data are passed to its getTransferData |
ohair@286 | 422 | * method. If the DataHandler fails to locate a DataContentHandler |
ohair@286 | 423 | * and the flavor specifies this object's MIME type and its class, |
ohair@286 | 424 | * this DataHandler's referenced object is returned. |
ohair@286 | 425 | * Otherwise it throws an UnsupportedFlavorException. |
ohair@286 | 426 | * |
ohair@286 | 427 | * @param flavor the requested flavor for the data |
ohair@286 | 428 | * @return the object |
ohair@286 | 429 | * @exception UnsupportedFlavorException if the data could not be |
ohair@286 | 430 | * converted to the requested flavor |
ohair@286 | 431 | * @exception IOException if an I/O error occurs |
ohair@286 | 432 | * @see javax.activation.ActivationDataFlavor |
ohair@286 | 433 | */ |
ohair@286 | 434 | public Object getTransferData(DataFlavor flavor) |
ohair@286 | 435 | throws UnsupportedFlavorException, IOException { |
ohair@286 | 436 | return getDataContentHandler().getTransferData(flavor, dataSource); |
ohair@286 | 437 | } |
ohair@286 | 438 | |
ohair@286 | 439 | /** |
ohair@286 | 440 | * Set the CommandMap for use by this DataHandler. |
ohair@286 | 441 | * Setting it to <code>null</code> causes the CommandMap to revert |
ohair@286 | 442 | * to the CommandMap returned by the |
ohair@286 | 443 | * <code>CommandMap.getDefaultCommandMap</code> method. |
ohair@286 | 444 | * Changing the CommandMap, or setting it to <code>null</code>, |
ohair@286 | 445 | * clears out any data cached from the previous CommandMap. |
ohair@286 | 446 | * |
ohair@286 | 447 | * @param commandMap the CommandMap to use in this DataHandler |
ohair@286 | 448 | * |
ohair@286 | 449 | * @see javax.activation.CommandMap#setDefaultCommandMap |
ohair@286 | 450 | */ |
ohair@286 | 451 | public synchronized void setCommandMap(CommandMap commandMap) { |
ohair@286 | 452 | if (commandMap != currentCommandMap || commandMap == null) { |
ohair@286 | 453 | // clear cached values... |
ohair@286 | 454 | transferFlavors = emptyFlavors; |
ohair@286 | 455 | dataContentHandler = null; |
ohair@286 | 456 | |
ohair@286 | 457 | currentCommandMap = commandMap; |
ohair@286 | 458 | } |
ohair@286 | 459 | } |
ohair@286 | 460 | |
ohair@286 | 461 | /** |
ohair@286 | 462 | * Return the <i>preferred</i> commands for this type of data. |
ohair@286 | 463 | * This method calls the <code>getPreferredCommands</code> method |
ohair@286 | 464 | * in the CommandMap associated with this instance of DataHandler. |
ohair@286 | 465 | * This method returns an array that represents a subset of |
ohair@286 | 466 | * available commands. In cases where multiple commands for the |
ohair@286 | 467 | * MIME type represented by this DataHandler are present, the |
ohair@286 | 468 | * installed CommandMap chooses the appropriate commands. |
ohair@286 | 469 | * |
ohair@286 | 470 | * @return the CommandInfo objects representing the preferred commands |
ohair@286 | 471 | * |
ohair@286 | 472 | * @see javax.activation.CommandMap#getPreferredCommands |
ohair@286 | 473 | */ |
ohair@286 | 474 | public CommandInfo[] getPreferredCommands() { |
ohair@286 | 475 | if (dataSource != null) |
ohair@286 | 476 | return getCommandMap().getPreferredCommands(getBaseType(), |
ohair@286 | 477 | dataSource); |
ohair@286 | 478 | else |
ohair@286 | 479 | return getCommandMap().getPreferredCommands(getBaseType()); |
ohair@286 | 480 | } |
ohair@286 | 481 | |
ohair@286 | 482 | /** |
ohair@286 | 483 | * Return all the commands for this type of data. |
ohair@286 | 484 | * This method returns an array containing all commands |
ohair@286 | 485 | * for the type of data represented by this DataHandler. The |
ohair@286 | 486 | * MIME type for the underlying data represented by this DataHandler |
ohair@286 | 487 | * is used to call through to the <code>getAllCommands</code> method |
ohair@286 | 488 | * of the CommandMap associated with this DataHandler. |
ohair@286 | 489 | * |
ohair@286 | 490 | * @return the CommandInfo objects representing all the commands |
ohair@286 | 491 | * |
ohair@286 | 492 | * @see javax.activation.CommandMap#getAllCommands |
ohair@286 | 493 | */ |
ohair@286 | 494 | public CommandInfo[] getAllCommands() { |
ohair@286 | 495 | if (dataSource != null) |
ohair@286 | 496 | return getCommandMap().getAllCommands(getBaseType(), dataSource); |
ohair@286 | 497 | else |
ohair@286 | 498 | return getCommandMap().getAllCommands(getBaseType()); |
ohair@286 | 499 | } |
ohair@286 | 500 | |
ohair@286 | 501 | /** |
ohair@286 | 502 | * Get the command <i>cmdName</i>. Use the search semantics as |
ohair@286 | 503 | * defined by the CommandMap installed in this DataHandler. The |
ohair@286 | 504 | * MIME type for the underlying data represented by this DataHandler |
ohair@286 | 505 | * is used to call through to the <code>getCommand</code> method |
ohair@286 | 506 | * of the CommandMap associated with this DataHandler. |
ohair@286 | 507 | * |
ohair@286 | 508 | * @param cmdName the command name |
ohair@286 | 509 | * @return the CommandInfo corresponding to the command |
ohair@286 | 510 | * |
ohair@286 | 511 | * @see javax.activation.CommandMap#getCommand |
ohair@286 | 512 | */ |
ohair@286 | 513 | public CommandInfo getCommand(String cmdName) { |
ohair@286 | 514 | if (dataSource != null) |
ohair@286 | 515 | return getCommandMap().getCommand(getBaseType(), cmdName, |
ohair@286 | 516 | dataSource); |
ohair@286 | 517 | else |
ohair@286 | 518 | return getCommandMap().getCommand(getBaseType(), cmdName); |
ohair@286 | 519 | } |
ohair@286 | 520 | |
ohair@286 | 521 | /** |
ohair@286 | 522 | * Return the data in its preferred Object form. <p> |
ohair@286 | 523 | * |
ohair@286 | 524 | * If the DataHandler was instantiated with an object, return |
ohair@286 | 525 | * the object. <p> |
ohair@286 | 526 | * |
ohair@286 | 527 | * If the DataHandler was instantiated with a DataSource, |
ohair@286 | 528 | * this method uses a DataContentHandler to return the content |
ohair@286 | 529 | * object for the data represented by this DataHandler. If no |
ohair@286 | 530 | * <code>DataContentHandler</code> can be found for the |
ohair@286 | 531 | * the type of this data, the DataHandler returns an |
ohair@286 | 532 | * InputStream for the data. |
ohair@286 | 533 | * |
ohair@286 | 534 | * @return the content. |
ohair@286 | 535 | * @exception IOException if an IOException occurs during |
ohair@286 | 536 | * this operation. |
ohair@286 | 537 | */ |
ohair@286 | 538 | public Object getContent() throws IOException { |
ohair@286 | 539 | if (object != null) |
ohair@286 | 540 | return object; |
ohair@286 | 541 | else |
ohair@286 | 542 | return getDataContentHandler().getContent(getDataSource()); |
ohair@286 | 543 | } |
ohair@286 | 544 | |
ohair@286 | 545 | /** |
ohair@286 | 546 | * A convenience method that takes a CommandInfo object |
ohair@286 | 547 | * and instantiates the corresponding command, usually |
ohair@286 | 548 | * a JavaBean component. |
ohair@286 | 549 | * <p> |
ohair@286 | 550 | * This method calls the CommandInfo's <code>getCommandObject</code> |
ohair@286 | 551 | * method with the <code>ClassLoader</code> used to load |
ohair@286 | 552 | * the <code>javax.activation.DataHandler</code> class itself. |
ohair@286 | 553 | * |
ohair@286 | 554 | * @param cmdinfo the CommandInfo corresponding to a command |
ohair@286 | 555 | * @return the instantiated command object |
ohair@286 | 556 | */ |
ohair@286 | 557 | public Object getBean(CommandInfo cmdinfo) { |
ohair@286 | 558 | Object bean = null; |
ohair@286 | 559 | |
ohair@286 | 560 | try { |
ohair@286 | 561 | // make the bean |
ohair@286 | 562 | ClassLoader cld = null; |
ohair@286 | 563 | // First try the "application's" class loader. |
ohair@286 | 564 | cld = SecuritySupport.getContextClassLoader(); |
ohair@286 | 565 | if (cld == null) |
ohair@286 | 566 | cld = this.getClass().getClassLoader(); |
ohair@286 | 567 | bean = cmdinfo.getCommandObject(this, cld); |
ohair@286 | 568 | } catch (IOException e) { |
ohair@286 | 569 | } catch (ClassNotFoundException e) { } |
ohair@286 | 570 | |
ohair@286 | 571 | return bean; |
ohair@286 | 572 | } |
ohair@286 | 573 | |
ohair@286 | 574 | /** |
ohair@286 | 575 | * Get the DataContentHandler for this DataHandler: <p> |
ohair@286 | 576 | * |
ohair@286 | 577 | * If a DataContentHandlerFactory is set, use it. |
ohair@286 | 578 | * Otherwise look for an object to serve DCH in the |
ohair@286 | 579 | * following order: <p> |
ohair@286 | 580 | * |
ohair@286 | 581 | * 1) if a factory is set, use it <p> |
ohair@286 | 582 | * 2) if a CommandMap is set, use it <p> |
ohair@286 | 583 | * 3) use the default CommandMap <p> |
ohair@286 | 584 | * |
ohair@286 | 585 | * In any case, wrap the real DataContentHandler with one of our own |
ohair@286 | 586 | * to handle any missing cases, fill in defaults, and to ensure that |
ohair@286 | 587 | * we always have a non-null DataContentHandler. |
ohair@286 | 588 | * |
ohair@286 | 589 | * @return the requested DataContentHandler |
ohair@286 | 590 | */ |
ohair@286 | 591 | private synchronized DataContentHandler getDataContentHandler() { |
ohair@286 | 592 | |
ohair@286 | 593 | // make sure the factory didn't change |
ohair@286 | 594 | if (factory != oldFactory) { |
ohair@286 | 595 | oldFactory = factory; |
ohair@286 | 596 | factoryDCH = null; |
ohair@286 | 597 | dataContentHandler = null; |
ohair@286 | 598 | transferFlavors = emptyFlavors; |
ohair@286 | 599 | } |
ohair@286 | 600 | |
ohair@286 | 601 | if (dataContentHandler != null) |
ohair@286 | 602 | return dataContentHandler; |
ohair@286 | 603 | |
ohair@286 | 604 | String simpleMT = getBaseType(); |
ohair@286 | 605 | |
ohair@286 | 606 | if (factoryDCH == null && factory != null) |
ohair@286 | 607 | factoryDCH = factory.createDataContentHandler(simpleMT); |
ohair@286 | 608 | |
ohair@286 | 609 | if (factoryDCH != null) |
ohair@286 | 610 | dataContentHandler = factoryDCH; |
ohair@286 | 611 | |
ohair@286 | 612 | if (dataContentHandler == null) { |
ohair@286 | 613 | if (dataSource != null) |
ohair@286 | 614 | dataContentHandler = getCommandMap(). |
ohair@286 | 615 | createDataContentHandler(simpleMT, dataSource); |
ohair@286 | 616 | else |
ohair@286 | 617 | dataContentHandler = getCommandMap(). |
ohair@286 | 618 | createDataContentHandler(simpleMT); |
ohair@286 | 619 | } |
ohair@286 | 620 | |
ohair@286 | 621 | // getDataContentHandler always uses these 'wrapper' handlers |
ohair@286 | 622 | // to make sure it returns SOMETHING meaningful... |
ohair@286 | 623 | if (dataSource != null) |
ohair@286 | 624 | dataContentHandler = new DataSourceDataContentHandler( |
ohair@286 | 625 | dataContentHandler, |
ohair@286 | 626 | dataSource); |
ohair@286 | 627 | else |
ohair@286 | 628 | dataContentHandler = new ObjectDataContentHandler( |
ohair@286 | 629 | dataContentHandler, |
ohair@286 | 630 | object, |
ohair@286 | 631 | objectMimeType); |
ohair@286 | 632 | return dataContentHandler; |
ohair@286 | 633 | } |
ohair@286 | 634 | |
ohair@286 | 635 | /** |
ohair@286 | 636 | * Use the MimeType class to extract the MIME type/subtype, |
ohair@286 | 637 | * ignoring the parameters. The type is cached. |
ohair@286 | 638 | */ |
ohair@286 | 639 | private synchronized String getBaseType() { |
ohair@286 | 640 | if (shortType == null) { |
ohair@286 | 641 | String ct = getContentType(); |
ohair@286 | 642 | try { |
ohair@286 | 643 | MimeType mt = new MimeType(ct); |
ohair@286 | 644 | shortType = mt.getBaseType(); |
ohair@286 | 645 | } catch (MimeTypeParseException e) { |
ohair@286 | 646 | shortType = ct; |
ohair@286 | 647 | } |
ohair@286 | 648 | } |
ohair@286 | 649 | return shortType; |
ohair@286 | 650 | } |
ohair@286 | 651 | |
ohair@286 | 652 | /** |
ohair@286 | 653 | * Sets the DataContentHandlerFactory. The DataContentHandlerFactory |
ohair@286 | 654 | * is called first to find DataContentHandlers. |
ohair@286 | 655 | * The DataContentHandlerFactory can only be set once. |
ohair@286 | 656 | * <p> |
ohair@286 | 657 | * If the DataContentHandlerFactory has already been set, |
ohair@286 | 658 | * this method throws an Error. |
ohair@286 | 659 | * |
ohair@286 | 660 | * @param newFactory the DataContentHandlerFactory |
ohair@286 | 661 | * @exception Error if the factory has already been defined. |
ohair@286 | 662 | * |
ohair@286 | 663 | * @see javax.activation.DataContentHandlerFactory |
ohair@286 | 664 | */ |
ohair@286 | 665 | public static synchronized void setDataContentHandlerFactory( |
ohair@286 | 666 | DataContentHandlerFactory newFactory) { |
ohair@286 | 667 | if (factory != null) |
ohair@286 | 668 | throw new Error("DataContentHandlerFactory already defined"); |
ohair@286 | 669 | |
ohair@286 | 670 | SecurityManager security = System.getSecurityManager(); |
ohair@286 | 671 | if (security != null) { |
ohair@286 | 672 | try { |
ohair@286 | 673 | // if it's ok with the SecurityManager, it's ok with me... |
ohair@286 | 674 | security.checkSetFactory(); |
ohair@286 | 675 | } catch (SecurityException ex) { |
ohair@286 | 676 | // otherwise, we also allow it if this code and the |
ohair@286 | 677 | // factory come from the same class loader (e.g., |
ohair@286 | 678 | // the JAF classes were loaded with the applet classes). |
ohair@286 | 679 | if (DataHandler.class.getClassLoader() != |
ohair@286 | 680 | newFactory.getClass().getClassLoader()) |
ohair@286 | 681 | throw ex; |
ohair@286 | 682 | } |
ohair@286 | 683 | } |
ohair@286 | 684 | factory = newFactory; |
ohair@286 | 685 | } |
ohair@286 | 686 | } |
ohair@286 | 687 | |
ohair@286 | 688 | /** |
ohair@286 | 689 | * The DataHanderDataSource class implements the |
ohair@286 | 690 | * DataSource interface when the DataHandler is constructed |
ohair@286 | 691 | * with an Object and a mimeType string. |
ohair@286 | 692 | */ |
ohair@286 | 693 | class DataHandlerDataSource implements DataSource { |
ohair@286 | 694 | DataHandler dataHandler = null; |
ohair@286 | 695 | |
ohair@286 | 696 | /** |
ohair@286 | 697 | * The constructor. |
ohair@286 | 698 | */ |
ohair@286 | 699 | public DataHandlerDataSource(DataHandler dh) { |
ohair@286 | 700 | this.dataHandler = dh; |
ohair@286 | 701 | } |
ohair@286 | 702 | |
ohair@286 | 703 | /** |
ohair@286 | 704 | * Returns an <code>InputStream</code> representing this object. |
ohair@286 | 705 | * @return the <code>InputStream</code> |
ohair@286 | 706 | */ |
ohair@286 | 707 | public InputStream getInputStream() throws IOException { |
ohair@286 | 708 | return dataHandler.getInputStream(); |
ohair@286 | 709 | } |
ohair@286 | 710 | |
ohair@286 | 711 | /** |
ohair@286 | 712 | * Returns the <code>OutputStream</code> for this object. |
ohair@286 | 713 | * @return the <code>OutputStream</code> |
ohair@286 | 714 | */ |
ohair@286 | 715 | public OutputStream getOutputStream() throws IOException { |
ohair@286 | 716 | return dataHandler.getOutputStream(); |
ohair@286 | 717 | } |
ohair@286 | 718 | |
ohair@286 | 719 | /** |
ohair@286 | 720 | * Returns the MIME type of the data represented by this object. |
ohair@286 | 721 | * @return the MIME type |
ohair@286 | 722 | */ |
ohair@286 | 723 | public String getContentType() { |
ohair@286 | 724 | return dataHandler.getContentType(); |
ohair@286 | 725 | } |
ohair@286 | 726 | |
ohair@286 | 727 | /** |
ohair@286 | 728 | * Returns the name of this object. |
ohair@286 | 729 | * @return the name of this object |
ohair@286 | 730 | */ |
ohair@286 | 731 | public String getName() { |
ohair@286 | 732 | return dataHandler.getName(); // what else would it be? |
ohair@286 | 733 | } |
ohair@286 | 734 | } |
ohair@286 | 735 | |
ohair@286 | 736 | /* |
ohair@286 | 737 | * DataSourceDataContentHandler |
ohair@286 | 738 | * |
ohair@286 | 739 | * This is a <i>private</i> DataContentHandler that wraps the real |
ohair@286 | 740 | * DataContentHandler in the case where the DataHandler was instantiated |
ohair@286 | 741 | * with a DataSource. |
ohair@286 | 742 | */ |
ohair@286 | 743 | class DataSourceDataContentHandler implements DataContentHandler { |
ohair@286 | 744 | private DataSource ds = null; |
ohair@286 | 745 | private DataFlavor transferFlavors[] = null; |
ohair@286 | 746 | private DataContentHandler dch = null; |
ohair@286 | 747 | |
ohair@286 | 748 | /** |
ohair@286 | 749 | * The constructor. |
ohair@286 | 750 | */ |
ohair@286 | 751 | public DataSourceDataContentHandler(DataContentHandler dch, DataSource ds) { |
ohair@286 | 752 | this.ds = ds; |
ohair@286 | 753 | this.dch = dch; |
ohair@286 | 754 | } |
ohair@286 | 755 | |
ohair@286 | 756 | /** |
ohair@286 | 757 | * Return the DataFlavors for this <code>DataContentHandler</code>. |
ohair@286 | 758 | * @return the DataFlavors |
ohair@286 | 759 | */ |
ohair@286 | 760 | public DataFlavor[] getTransferDataFlavors() { |
ohair@286 | 761 | |
ohair@286 | 762 | if (transferFlavors == null) { |
ohair@286 | 763 | if (dch != null) { // is there a dch? |
ohair@286 | 764 | transferFlavors = dch.getTransferDataFlavors(); |
ohair@286 | 765 | } else { |
ohair@286 | 766 | transferFlavors = new DataFlavor[1]; |
ohair@286 | 767 | transferFlavors[0] = |
ohair@286 | 768 | new ActivationDataFlavor(ds.getContentType(), |
ohair@286 | 769 | ds.getContentType()); |
ohair@286 | 770 | } |
ohair@286 | 771 | } |
ohair@286 | 772 | return transferFlavors; |
ohair@286 | 773 | } |
ohair@286 | 774 | |
ohair@286 | 775 | /** |
ohair@286 | 776 | * Return the Transfer Data of type DataFlavor from InputStream. |
ohair@286 | 777 | * @param df the DataFlavor |
ohair@286 | 778 | * @param ds the DataSource |
ohair@286 | 779 | * @return the constructed Object |
ohair@286 | 780 | */ |
ohair@286 | 781 | public Object getTransferData(DataFlavor df, DataSource ds) throws |
ohair@286 | 782 | UnsupportedFlavorException, IOException { |
ohair@286 | 783 | |
ohair@286 | 784 | if (dch != null) |
ohair@286 | 785 | return dch.getTransferData(df, ds); |
ohair@286 | 786 | else if (df.equals(getTransferDataFlavors()[0])) // only have one now |
ohair@286 | 787 | return ds.getInputStream(); |
ohair@286 | 788 | else |
ohair@286 | 789 | throw new UnsupportedFlavorException(df); |
ohair@286 | 790 | } |
ohair@286 | 791 | |
ohair@286 | 792 | public Object getContent(DataSource ds) throws IOException { |
ohair@286 | 793 | |
ohair@286 | 794 | if (dch != null) |
ohair@286 | 795 | return dch.getContent(ds); |
ohair@286 | 796 | else |
ohair@286 | 797 | return ds.getInputStream(); |
ohair@286 | 798 | } |
ohair@286 | 799 | |
ohair@286 | 800 | /** |
ohair@286 | 801 | * Write the object to the output stream. |
ohair@286 | 802 | */ |
ohair@286 | 803 | public void writeTo(Object obj, String mimeType, OutputStream os) |
ohair@286 | 804 | throws IOException { |
ohair@286 | 805 | if (dch != null) |
ohair@286 | 806 | dch.writeTo(obj, mimeType, os); |
ohair@286 | 807 | else |
ohair@286 | 808 | throw new UnsupportedDataTypeException( |
ohair@286 | 809 | "no DCH for content type " + ds.getContentType()); |
ohair@286 | 810 | } |
ohair@286 | 811 | } |
ohair@286 | 812 | |
ohair@286 | 813 | /* |
ohair@286 | 814 | * ObjectDataContentHandler |
ohair@286 | 815 | * |
ohair@286 | 816 | * This is a <i>private</i> DataContentHandler that wraps the real |
ohair@286 | 817 | * DataContentHandler in the case where the DataHandler was instantiated |
ohair@286 | 818 | * with an object. |
ohair@286 | 819 | */ |
ohair@286 | 820 | class ObjectDataContentHandler implements DataContentHandler { |
ohair@286 | 821 | private DataFlavor transferFlavors[] = null; |
ohair@286 | 822 | private Object obj; |
ohair@286 | 823 | private String mimeType; |
ohair@286 | 824 | private DataContentHandler dch = null; |
ohair@286 | 825 | |
ohair@286 | 826 | /** |
ohair@286 | 827 | * The constructor. |
ohair@286 | 828 | */ |
ohair@286 | 829 | public ObjectDataContentHandler(DataContentHandler dch, |
ohair@286 | 830 | Object obj, String mimeType) { |
ohair@286 | 831 | this.obj = obj; |
ohair@286 | 832 | this.mimeType = mimeType; |
ohair@286 | 833 | this.dch = dch; |
ohair@286 | 834 | } |
ohair@286 | 835 | |
ohair@286 | 836 | /** |
ohair@286 | 837 | * Return the DataContentHandler for this object. |
ohair@286 | 838 | * Used only by the DataHandler class. |
ohair@286 | 839 | */ |
ohair@286 | 840 | public DataContentHandler getDCH() { |
ohair@286 | 841 | return dch; |
ohair@286 | 842 | } |
ohair@286 | 843 | |
ohair@286 | 844 | /** |
ohair@286 | 845 | * Return the DataFlavors for this <code>DataContentHandler</code>. |
ohair@286 | 846 | * @return the DataFlavors |
ohair@286 | 847 | */ |
ohair@286 | 848 | public synchronized DataFlavor[] getTransferDataFlavors() { |
ohair@286 | 849 | if (transferFlavors == null) { |
ohair@286 | 850 | if (dch != null) { |
ohair@286 | 851 | transferFlavors = dch.getTransferDataFlavors(); |
ohair@286 | 852 | } else { |
ohair@286 | 853 | transferFlavors = new DataFlavor[1]; |
ohair@286 | 854 | transferFlavors[0] = new ActivationDataFlavor(obj.getClass(), |
ohair@286 | 855 | mimeType, mimeType); |
ohair@286 | 856 | } |
ohair@286 | 857 | } |
ohair@286 | 858 | return transferFlavors; |
ohair@286 | 859 | } |
ohair@286 | 860 | |
ohair@286 | 861 | /** |
ohair@286 | 862 | * Return the Transfer Data of type DataFlavor from InputStream. |
ohair@286 | 863 | * @param df the DataFlavor |
ohair@286 | 864 | * @param ds the DataSource |
ohair@286 | 865 | * @return the constructed Object |
ohair@286 | 866 | */ |
ohair@286 | 867 | public Object getTransferData(DataFlavor df, DataSource ds) |
ohair@286 | 868 | throws UnsupportedFlavorException, IOException { |
ohair@286 | 869 | |
ohair@286 | 870 | if (dch != null) |
ohair@286 | 871 | return dch.getTransferData(df, ds); |
ohair@286 | 872 | else if (df.equals(getTransferDataFlavors()[0])) // only have one now |
ohair@286 | 873 | return obj; |
ohair@286 | 874 | else |
ohair@286 | 875 | throw new UnsupportedFlavorException(df); |
ohair@286 | 876 | |
ohair@286 | 877 | } |
ohair@286 | 878 | |
ohair@286 | 879 | public Object getContent(DataSource ds) { |
ohair@286 | 880 | return obj; |
ohair@286 | 881 | } |
ohair@286 | 882 | |
ohair@286 | 883 | /** |
ohair@286 | 884 | * Write the object to the output stream. |
ohair@286 | 885 | */ |
ohair@286 | 886 | public void writeTo(Object obj, String mimeType, OutputStream os) |
ohair@286 | 887 | throws IOException { |
ohair@286 | 888 | if (dch != null) |
ohair@286 | 889 | dch.writeTo(obj, mimeType, os); |
ohair@286 | 890 | else if (obj instanceof byte[]) |
ohair@286 | 891 | os.write((byte[])obj); |
ohair@286 | 892 | else if (obj instanceof String) { |
ohair@286 | 893 | OutputStreamWriter osw = new OutputStreamWriter(os); |
ohair@286 | 894 | osw.write((String)obj); |
ohair@286 | 895 | osw.flush(); |
ohair@286 | 896 | } else throw new UnsupportedDataTypeException( |
ohair@286 | 897 | "no object DCH for MIME type " + this.mimeType); |
ohair@286 | 898 | } |
ohair@286 | 899 | } |