DataFlavor.java 28 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007
  1. /* DataFlavor.java -- A type of data to transfer via the clipboard.
  2. Copyright (C) 1999, 2001 Free Software Foundation, Inc.
  3. This file is part of GNU Classpath.
  4. GNU Classpath is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2, or (at your option)
  7. any later version.
  8. GNU Classpath is distributed in the hope that it will be useful, but
  9. WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with GNU Classpath; see the file COPYING. If not, write to the
  14. Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  15. 02111-1307 USA.
  16. Linking this library statically or dynamically with other modules is
  17. making a combined work based on this library. Thus, the terms and
  18. conditions of the GNU General Public License cover the whole
  19. combination.
  20. As a special exception, the copyright holders of this library give you
  21. permission to link this library with independent modules to produce an
  22. executable, regardless of the license terms of these independent
  23. modules, and to copy and distribute the resulting executable under
  24. terms of your choice, provided that you also meet, for each linked
  25. independent module, the terms and conditions of the license of that
  26. module. An independent module is a module which is not derived from
  27. or based on this library. If you modify this library, you may extend
  28. this exception to your version of the library, but you are not
  29. obligated to do so. If you do not wish to do so, delete this
  30. exception statement from your version. */
  31. package java.awt.datatransfer;
  32. import java.io.ByteArrayInputStream;
  33. import java.io.InputStream;
  34. import java.io.InputStreamReader;
  35. import java.io.IOException;
  36. import java.io.ObjectOutput;
  37. import java.io.ObjectInput;
  38. import java.io.Reader;
  39. import java.io.StringReader;
  40. import java.io.UnsupportedEncodingException;
  41. /**
  42. * This class represents a particular data format used for transferring
  43. * data via the clipboard.
  44. *
  45. * @author Aaron M. Renn (arenn@urbanophile.com)
  46. */
  47. public class DataFlavor implements java.io.Externalizable, Cloneable
  48. {
  49. static final long serialVersionUID = 8367026044764648243L;
  50. // FIXME: Serialization: Need to write methods for.
  51. /*
  52. * Static Variables
  53. */
  54. /**
  55. * This is the data flavor used for tranferring plain text. The MIME
  56. * type is "text/plain; charset=unicode". The representation class
  57. * is <code>java.io.InputStream</code>.
  58. *
  59. * @deprecated The charset unicode is platform specific and InputStream
  60. * deals with bytes not chars. Use <code>getRederForText()</code>.
  61. */
  62. public static final DataFlavor plainTextFlavor;
  63. /**
  64. * This is the data flavor used for transferring Java strings. The
  65. * MIME type is "application/x-java-serialized-object" and the
  66. * representation class is <code>java.lang.String</code>.
  67. */
  68. public static final DataFlavor stringFlavor;
  69. /**
  70. * This is a data flavor used for transferring lists of files. The
  71. * representation type is a <code>java.util.List</code>, with each element of
  72. * the list being a <code>java.io.File</code>.
  73. */
  74. public static final DataFlavor javaFileListFlavor;
  75. public static final DataFlavor imageFlavor;
  76. /**
  77. * This is the MIME type used for transferring a serialized object.
  78. * The representation class is the type of object be deserialized.
  79. */
  80. public static final String javaSerializedObjectMimeType =
  81. "application/x-java-serialized-object";
  82. /**
  83. * This is the MIME type used to transfer a Java object reference within
  84. * the same JVM. The representation class is the class of the object
  85. * being transferred.
  86. */
  87. public static final String javaJVMLocalObjectMimeType =
  88. "application/x-java-jvm-local-object";
  89. /**
  90. * This is the MIME type used to transfer a link to a remote object.
  91. * The representation class is the type of object being linked to.
  92. */
  93. public static final String javaRemoteObjectMimeType =
  94. "application/x-java-remote-object";
  95. static
  96. {
  97. plainTextFlavor
  98. = new DataFlavor(java.io.InputStream.class,
  99. "text/plain; charset=unicode",
  100. "plain unicode text");
  101. stringFlavor
  102. = new DataFlavor(java.lang.String.class,
  103. "Java Unicode String");
  104. javaFileListFlavor
  105. = new DataFlavor(java.util.List.class,
  106. "Java File List");
  107. // javaFileListFlavor.mimeType = "application/x-java-file-list";
  108. imageFlavor
  109. = new DataFlavor(java.awt.Image.class,
  110. "Java Image");
  111. }
  112. /*************************************************************************/
  113. /*
  114. * Instance Variables
  115. */
  116. // The MIME type for this flavor
  117. private final String mimeType;
  118. // The representation class for this flavor
  119. private final Class representationClass;
  120. // The human readable name of this flavor
  121. private String humanPresentableName;
  122. /*************************************************************************/
  123. /*
  124. * Static Methods
  125. */
  126. /**
  127. * This method attempts to load the named class. The following class
  128. * loaders are searched in order: the bootstrap class loader, the
  129. * system class loader, the context class loader (if it exists), and
  130. * the specified fallback class loader.
  131. *
  132. * @param className The name of the class to load.
  133. * @param classLoader The class loader to use if all others fail, which
  134. * may be <code>null</code>.
  135. *
  136. * @exception ClassNotFoundException If the class cannot be loaded.
  137. */
  138. protected static final Class
  139. tryToLoadClass(String className, ClassLoader classLoader)
  140. throws ClassNotFoundException
  141. {
  142. try
  143. {
  144. return(Class.forName(className));
  145. }
  146. catch(Exception e) { ; }
  147. // Commented out for Java 1.1
  148. /*
  149. try
  150. {
  151. return(className.getClass().getClassLoader().findClass(className));
  152. }
  153. catch(Exception e) { ; }
  154. try
  155. {
  156. return(ClassLoader.getSystemClassLoader().findClass(className));
  157. }
  158. catch(Exception e) { ; }
  159. */
  160. // FIXME: What is the context class loader?
  161. /*
  162. try
  163. {
  164. }
  165. catch(Exception e) { ; }
  166. */
  167. if (classLoader != null)
  168. return(classLoader.loadClass(className));
  169. else
  170. throw new ClassNotFoundException(className);
  171. }
  172. /*************************************************************************/
  173. /*
  174. * Constructors
  175. */
  176. /**
  177. * Empty public constructor needed for externalization.
  178. * Should not be used for normal instantiation.
  179. */
  180. public
  181. DataFlavor()
  182. {
  183. mimeType = null;
  184. representationClass = null;
  185. humanPresentableName = null;
  186. }
  187. /*************************************************************************/
  188. /**
  189. * Private constructor.
  190. */
  191. private
  192. DataFlavor(Class representationClass,
  193. String mimeType,
  194. String humanPresentableName)
  195. {
  196. this.representationClass = representationClass;
  197. this.mimeType = mimeType;
  198. if (humanPresentableName != null)
  199. this.humanPresentableName = humanPresentableName;
  200. else
  201. this.humanPresentableName = mimeType;
  202. }
  203. /*************************************************************************/
  204. /**
  205. * Initializes a new instance of <code>DataFlavor</code>. The class
  206. * and human readable name are specified, the MIME type will be
  207. * "application/x-java-serialized-object". If the human readable name
  208. * is not specified (<code>null</code>) then the human readable name
  209. * will be the same as the MIME type.
  210. *
  211. * @param representationClass The representation class for this object.
  212. * @param humanPresentableName The display name of the object.
  213. */
  214. public
  215. DataFlavor(Class representationClass, String humanPresentableName)
  216. {
  217. this(representationClass,
  218. "application/x-java-serialized-object"
  219. + "; class="
  220. + representationClass.getName(),
  221. humanPresentableName);
  222. }
  223. /*************************************************************************/
  224. /**
  225. * Initializes a new instance of <code>DataFlavor</code> with the
  226. * specified MIME type and description. If the MIME type has a
  227. * "class=<rep class>" parameter then the representation class will
  228. * be the class name specified. Otherwise the class defaults to
  229. * <code>java.io.InputStream</code>. If the human readable name
  230. * is not specified (<code>null</code>) then the human readable name
  231. * will be the same as the MIME type.
  232. *
  233. * @param mimeType The MIME type for this flavor.
  234. * @param humanPresentableName The display name of this flavor.
  235. * @param classLoader The class loader for finding classes if the default
  236. * class loaders do not work.
  237. *
  238. * @exception IllegalArgumentException If the representation class
  239. * specified cannot be loaded.
  240. * @exception ClassNotFoundException If the class is not loaded.
  241. */
  242. public
  243. DataFlavor(String mimeType, String humanPresentableName,
  244. ClassLoader classLoader) throws ClassNotFoundException
  245. {
  246. this(getRepresentationClassFromMime(mimeType, classLoader),
  247. mimeType, humanPresentableName);
  248. }
  249. private static Class
  250. getRepresentationClassFromMime(String mimeString, ClassLoader classLoader)
  251. {
  252. String classname = getParameter("class", mimeString);
  253. if (classname != null)
  254. {
  255. try
  256. {
  257. return tryToLoadClass(classname, classLoader);
  258. }
  259. catch(Exception e)
  260. {
  261. throw new IllegalArgumentException("classname: " + e.getMessage());
  262. }
  263. }
  264. else
  265. {
  266. return java.io.InputStream.class;
  267. }
  268. }
  269. /*************************************************************************/
  270. /**
  271. * Initializes a new instance of <code>DataFlavor</code> with the
  272. * specified MIME type and description. If the MIME type has a
  273. * "class=<rep class>" parameter then the representation class will
  274. * be the class name specified. Otherwise the class defaults to
  275. * <code>java.io.InputStream</code>. If the human readable name
  276. * is not specified (<code>null</code>) then the human readable name
  277. * will be the same as the MIME type. This is the same as calling
  278. * <code>new DataFlavor(mimeType, humanPresentableName, null)</code>.
  279. *
  280. * @param mimeType The MIME type for this flavor.
  281. * @param humanPresentableName The display name of this flavor.
  282. * @param classLoader The class loader for finding classes.
  283. *
  284. * @exception IllegalArgumentException If the representation class
  285. * specified cannot be loaded.
  286. */
  287. public
  288. DataFlavor(String mimeType, String humanPresentableName)
  289. throws ClassNotFoundException
  290. {
  291. this(mimeType, humanPresentableName, null);
  292. }
  293. /*************************************************************************/
  294. /**
  295. * Initializes a new instance of <code>DataFlavor</code> with the specified
  296. * MIME type. This type can have a "class=" parameter to specify the
  297. * representation class, and then the class must exist or an exception will
  298. * be thrown. If there is no "class=" parameter then the representation class
  299. * will be <code>java.io.InputStream</code>. This is the same as calling
  300. * <code>new DataFlavor(mimeType, null)</code>.
  301. *
  302. * @param mimeType The MIME type for this flavor.
  303. *
  304. * @exception IllegalArgumentException If a class is not specified in
  305. * the MIME type.
  306. * @exception ClassNotFoundException If the class cannot be loaded.
  307. */
  308. public
  309. DataFlavor(String mimeType) throws ClassNotFoundException
  310. {
  311. this(mimeType, null);
  312. }
  313. /*************************************************************************/
  314. /**
  315. * Returns the MIME type of this flavor.
  316. *
  317. * @return The MIME type for this flavor.
  318. */
  319. public String
  320. getMimeType()
  321. {
  322. return(mimeType);
  323. }
  324. /*************************************************************************/
  325. /**
  326. * Returns the representation class for this flavor.
  327. *
  328. * @return The representation class for this flavor.
  329. */
  330. public Class
  331. getRepresentationClass()
  332. {
  333. return(representationClass);
  334. }
  335. /*************************************************************************/
  336. /**
  337. * Returns the human presentable name for this flavor.
  338. *
  339. * @return The human presentable name for this flavor.
  340. */
  341. public String
  342. getHumanPresentableName()
  343. {
  344. return(humanPresentableName);
  345. }
  346. /*************************************************************************/
  347. /**
  348. * Returns the primary MIME type for this flavor.
  349. *
  350. * @return The primary MIME type for this flavor.
  351. */
  352. public String
  353. getPrimaryType()
  354. {
  355. int idx = mimeType.indexOf("/");
  356. if (idx == -1)
  357. return(mimeType);
  358. return(mimeType.substring(0, idx));
  359. }
  360. /*************************************************************************/
  361. /**
  362. * Returns the MIME subtype for this flavor.
  363. *
  364. * @return The MIME subtype for this flavor.
  365. */
  366. public String
  367. getSubType()
  368. {
  369. int idx = mimeType.indexOf("/");
  370. if (idx == -1)
  371. return("");
  372. String subtype = mimeType.substring(idx + 1);
  373. idx = subtype.indexOf(" ");
  374. if (idx == -1)
  375. return(subtype);
  376. else
  377. return(subtype.substring(0, idx));
  378. }
  379. /*************************************************************************/
  380. /**
  381. * Returns the value of the named MIME type parameter, or <code>null</code>
  382. * if the parameter does not exist. Given the parameter name and the mime
  383. * string.
  384. *
  385. * @param paramName The name of the parameter.
  386. * @param mimeString The mime string from where the name should be found.
  387. *
  388. * @return The value of the parameter or null.
  389. */
  390. private static String
  391. getParameter(String paramName, String mimeString)
  392. {
  393. int idx = mimeString.indexOf(paramName + "=");
  394. if (idx == -1)
  395. return(null);
  396. String value = mimeString.substring(idx + paramName.length() + 2);
  397. idx = value.indexOf(" ");
  398. if (idx == -1)
  399. return(value);
  400. else
  401. return(value.substring(0, idx));
  402. }
  403. /*************************************************************************/
  404. /**
  405. * Returns the value of the named MIME type parameter, or <code>null</code>
  406. * if the parameter does not exist.
  407. *
  408. * @param paramName The name of the paramter.
  409. *
  410. * @return The value of the parameter.
  411. */
  412. public String
  413. getParameter(String paramName)
  414. {
  415. return getParameter(paramName, mimeType);
  416. }
  417. /*************************************************************************/
  418. /**
  419. * Sets the human presentable name to the specified value.
  420. *
  421. * @param humanPresentableName The new display name.
  422. */
  423. public void
  424. setHumanPresentableName(String humanPresentableName)
  425. {
  426. this.humanPresentableName = humanPresentableName;
  427. }
  428. /*************************************************************************/
  429. /**
  430. * Tests the MIME type of this object for equality against the specified
  431. * MIME type.
  432. *
  433. * @param mimeType The MIME type to test against.
  434. *
  435. * @return <code>true</code> if the MIME type is equal to this object's
  436. * MIME type, <code>false</code> otherwise.
  437. *
  438. * @exception NullPointerException If mimeType is null.
  439. */
  440. public final boolean
  441. isMimeTypeEqual(String mimeType)
  442. {
  443. // FIXME: Need to handle default attributes and parameters
  444. return(this.mimeType.equals(mimeType));
  445. }
  446. /*************************************************************************/
  447. /**
  448. * Tests the MIME type of this object for equality against the specified
  449. * data flavor's MIME type
  450. *
  451. * @param flavor The flavor to test against.
  452. *
  453. * @return <code>true</code> if the flavor's MIME type is equal to this
  454. * object's MIME type, <code>false</code> otherwise.
  455. */
  456. public boolean
  457. isMimeTypeEqual(DataFlavor flavor)
  458. {
  459. return(isMimeTypeEqual(flavor.getMimeType()));
  460. }
  461. /*************************************************************************/
  462. /**
  463. * Tests whether or not this flavor represents a serialized object.
  464. *
  465. * @return <code>true</code> if this flavor represents a serialized
  466. * object, <code>false</code> otherwise.
  467. */
  468. public boolean
  469. isMimeTypeSerializedObject()
  470. {
  471. return(mimeType.startsWith(javaSerializedObjectMimeType));
  472. }
  473. /*************************************************************************/
  474. /**
  475. * Tests whether or not this flavor has a representation class of
  476. * <code>java.io.InputStream</code>.
  477. *
  478. * @param <code>true</code> if the representation class of this flavor
  479. * is <code>java.io.InputStream</code>, <code>false</code> otherwise.
  480. */
  481. public boolean
  482. isRepresentationClassInputStream()
  483. {
  484. return(representationClass.getName().equals("java.io.InputStream"));
  485. }
  486. /*************************************************************************/
  487. /**
  488. * Tests whether the representation class for this flavor is
  489. * serializable.
  490. *
  491. * @param <code>true</code> if the representation class is serializable,
  492. * <code>false</code> otherwise.
  493. */
  494. public boolean
  495. isRepresentationClassSerializable()
  496. {
  497. Class[] interfaces = representationClass.getInterfaces();
  498. int i = 0;
  499. while (i < interfaces.length)
  500. {
  501. if (interfaces[i].getName().equals("java.io.Serializable"))
  502. return(true);
  503. ++i;
  504. }
  505. return(false);
  506. }
  507. /*************************************************************************/
  508. /**
  509. * Tests whether the representation class for his flavor is remote.
  510. *
  511. * @return <code>true</code> if the representation class is remote,
  512. * <code>false</code> otherwise.
  513. */
  514. public boolean
  515. isRepresentationClassRemote()
  516. {
  517. // FIXME: Implement
  518. throw new RuntimeException("Not implemented");
  519. }
  520. /*************************************************************************/
  521. /**
  522. * Tests whether or not this flavor represents a serialized object.
  523. *
  524. * @return <code>true</code> if this flavor represents a serialized
  525. * object, <code>false</code> otherwise.
  526. */
  527. public boolean
  528. isFlavorSerializedObjectType()
  529. {
  530. // FIXME: What is the diff between this and isMimeTypeSerializedObject?
  531. return(mimeType.startsWith(javaSerializedObjectMimeType));
  532. }
  533. /*************************************************************************/
  534. /**
  535. * Tests whether or not this flavor represents a remote object.
  536. *
  537. * @return <code>true</code> if this flavor represents a remote object,
  538. * <code>false</code> otherwise.
  539. */
  540. public boolean
  541. isFlavorRemoteObjectType()
  542. {
  543. return(mimeType.startsWith(javaRemoteObjectMimeType));
  544. }
  545. /*************************************************************************/
  546. /**
  547. * Tests whether or not this flavor represents a list of files.
  548. *
  549. * @return <code>true</code> if this flavor represents a list of files,
  550. * <code>false</code> otherwise.
  551. */
  552. public boolean
  553. isFlavorJavaFileListType()
  554. {
  555. if (this.mimeType.equals(javaFileListFlavor.mimeType) &&
  556. this.representationClass.equals(javaFileListFlavor.representationClass))
  557. return(true);
  558. return(false);
  559. }
  560. /*************************************************************************/
  561. /**
  562. * Returns a copy of this object.
  563. *
  564. * @return A copy of this object.
  565. *
  566. * @exception CloneNotSupportedException If the object's class does not support
  567. * the Cloneable interface. Subclasses that override the clone method can also
  568. * throw this exception to indicate that an instance cannot be cloned.
  569. */
  570. public Object
  571. clone()
  572. {
  573. try
  574. {
  575. return(super.clone());
  576. }
  577. catch(Exception e)
  578. {
  579. return(null);
  580. }
  581. }
  582. /*************************************************************************/
  583. /**
  584. * This method test the specified <code>DataFlavor</code> for equality
  585. * against this object. This will be true if the MIME type and
  586. * representation type are the equal.
  587. *
  588. * @param flavor The <code>DataFlavor</code> to test against.
  589. *
  590. * @return <code>true</code> if the flavor is equal to this object,
  591. * <code>false</code> otherwise.
  592. */
  593. public boolean
  594. equals(DataFlavor flavor)
  595. {
  596. if (flavor == null)
  597. return(false);
  598. if (!this.mimeType.toLowerCase().equals(flavor.mimeType.toLowerCase()))
  599. return(false);
  600. if (!this.representationClass.equals(flavor.representationClass))
  601. return(false);
  602. return(true);
  603. }
  604. /*************************************************************************/
  605. /**
  606. * This method test the specified <code>Object</code> for equality
  607. * against this object. This will be true if the following conditions
  608. * are met:
  609. * <p>
  610. * <ul>
  611. * <li>The object is not <code>null</code>.
  612. * <li>The object is an instance of <code>DataFlavor</code>.
  613. * <li>The object's MIME type and representation class are equal to
  614. * this object's.
  615. * </ul>
  616. *
  617. * @param obj The <code>Object</code> to test against.
  618. *
  619. * @return <code>true</code> if the flavor is equal to this object,
  620. * <code>false</code> otherwise.
  621. */
  622. public boolean
  623. equals(Object obj)
  624. {
  625. if (obj == null)
  626. return(false);
  627. if (!(obj instanceof DataFlavor))
  628. return(false);
  629. return(equals((DataFlavor)obj));
  630. }
  631. /*************************************************************************/
  632. /**
  633. * Tests whether or not the specified string is equal to the MIME type
  634. * of this object.
  635. *
  636. * @param str The string to test against.
  637. *
  638. * @return <code>true</code> if the string is equal to this object's MIME
  639. * type, <code>false</code> otherwise.
  640. *
  641. * @deprecated Not compatible with <code>hashCode()</code>.
  642. * Use <code>isMimeTypeEqual()</code>
  643. */
  644. public boolean
  645. equals(String str)
  646. {
  647. return(isMimeTypeEqual(str));
  648. }
  649. /*************************************************************************/
  650. /**
  651. * Returns the hash code for this data flavor.
  652. * The hash code is based on the (lower case) mime type and the
  653. * representation class.
  654. */
  655. public int
  656. hashCode()
  657. {
  658. return(mimeType.toLowerCase().hashCode()^representationClass.hashCode());
  659. }
  660. /*************************************************************************/
  661. /**
  662. * Returns <code>true</code> when the given <code>DataFlavor</code>
  663. * matches this one.
  664. */
  665. public boolean
  666. match(DataFlavor dataFlavor)
  667. {
  668. // XXX - How is this different from equals?
  669. return(equals(dataFlavor));
  670. }
  671. /*************************************************************************/
  672. /**
  673. * This method exists for backward compatibility. It simply returns
  674. * the same name/value pair passed in.
  675. *
  676. * @param name The parameter name.
  677. * @param value The parameter value.
  678. *
  679. * @return The name/value pair.
  680. *
  681. * @deprecated
  682. */
  683. protected String
  684. normalizeMimeTypeParameter(String name, String value)
  685. {
  686. return(name + "=" + value);
  687. }
  688. /*************************************************************************/
  689. /**
  690. * This method exists for backward compatibility. It simply returns
  691. * the MIME type string unchanged.
  692. *
  693. * @param type The MIME type.
  694. *
  695. * @return The MIME type.
  696. *
  697. * @deprecated
  698. */
  699. protected String
  700. normalizeMimeType(String type)
  701. {
  702. return(type);
  703. }
  704. /*************************************************************************/
  705. /**
  706. * Serialize this class.
  707. *
  708. * @param stream The <code>ObjectOutput</code> stream to serialize to.
  709. *
  710. * @exception IOException If an error occurs.
  711. */
  712. public void
  713. writeExternal(ObjectOutput stream) throws IOException
  714. {
  715. // FIXME: Implement me
  716. }
  717. /*************************************************************************/
  718. /**
  719. * De-serialize this class.
  720. *
  721. * @param stream The <code>ObjectInput</code> stream to deserialize from.
  722. *
  723. * @exception IOException If an error ocurs.
  724. * @exception ClassNotFoundException If the class for an object being restored
  725. * cannot be found.
  726. */
  727. public void
  728. readExternal(ObjectInput stream) throws IOException, ClassNotFoundException
  729. {
  730. // FIXME: Implement me
  731. }
  732. /*************************************************************************/
  733. /**
  734. * Returns a string representation of this DataFlavor. Including the
  735. * representation class name, MIME type and human presentable name.
  736. */
  737. public String
  738. toString()
  739. {
  740. return("DataFlavor[representationClass="
  741. + representationClass.getName()
  742. + ",mimeType="
  743. + mimeType
  744. + "humanPresentableName="
  745. + humanPresentableName);
  746. }
  747. /*************************************************************************/
  748. /**
  749. * XXX - Currently returns <code>plainTextFlavor</code>.
  750. */
  751. public static final DataFlavor
  752. getTextPlainUnicodeFlavor()
  753. {
  754. return(plainTextFlavor);
  755. }
  756. /*************************************************************************/
  757. /**
  758. * XXX - Currently returns <code>java.io.InputStream</code>.
  759. *
  760. * @since 1.3
  761. */
  762. public final Class
  763. getDefaultRepresentationClass()
  764. {
  765. return(java.io.InputStream.class);
  766. }
  767. /*************************************************************************/
  768. /**
  769. * XXX - Currently returns <code>java.io.InputStream</code>.
  770. */
  771. public final String
  772. getDefaultRepresentationClassAsString()
  773. {
  774. return(getDefaultRepresentationClass().getName());
  775. }
  776. /*************************************************************************/
  777. /**
  778. * Selects the best supported text flavor on this implementation.
  779. * Returns <code>null</code> when none of the given flavors is liked.
  780. *
  781. * The <code>DataFlavor</code> returned the first data flavor in the
  782. * array that has either a representation class which is (a subclass of)
  783. * <code>Reader</code> or <code>String</code>, or has a representation
  784. * class which is (a subclass of) <code>InputStream</code> and has a
  785. * primary MIME type of "text" and has an supported encoding.
  786. */
  787. public static final DataFlavor
  788. selectBestTextFlavor(DataFlavor[] availableFlavors)
  789. {
  790. for(int i=0; i<availableFlavors.length; i++)
  791. {
  792. DataFlavor df = availableFlavors[i];
  793. Class c = df.representationClass;
  794. // A Reader or String is good.
  795. if ((Reader.class.isAssignableFrom(c))
  796. || (String.class.isAssignableFrom(c)))
  797. {
  798. return df;
  799. }
  800. // A InputStream is good if the mime primary type is "text"
  801. if ((InputStream.class.isAssignableFrom(c))
  802. && ("text".equals(df.getPrimaryType())))
  803. {
  804. String encoding = availableFlavors[i].getParameter("charset");
  805. if (encoding == null)
  806. encoding = "us-ascii";
  807. Reader r = null;
  808. try
  809. {
  810. // Try to construct a dummy reader with the found encoding
  811. r = new InputStreamReader
  812. (new ByteArrayInputStream(new byte[0]), encoding);
  813. }
  814. catch(UnsupportedEncodingException uee) { /* ignore */ }
  815. if (r != null)
  816. return df;
  817. }
  818. }
  819. // Nothing found
  820. return(null);
  821. }
  822. /*************************************************************************/
  823. /**
  824. * Creates a <code>Reader</code> for a given <code>Transferable</code>.
  825. *
  826. * If the representation class is a (subclass of) <code>Reader</code>
  827. * then an instance of the representation class is returned. If the
  828. * representatation class is a <code>String</code> then a
  829. * <code>StringReader</code> is returned. And if the representation class
  830. * is a (subclass of) <code>InputStream</code> and the primary MIME type
  831. * is "text" then a <code>InputStreamReader</code> for the correct charset
  832. * encoding is returned.
  833. *
  834. * @param transferable The <code>Transferable</code> for which a text
  835. * <code>Reader</code> is requested.
  836. *
  837. * @exception IllegalArgumentException If the representation class is not one
  838. * of the seven listed above or the Transferable has null data.
  839. * @exception NullPointerException If the Transferable is null.
  840. * @exception UnsupportedFlavorException when the transferable doesn't
  841. * support this <code>DataFlavor</code>. Or if the representable class
  842. * isn't a (subclass of) <code>Reader</code>, <code>String</code>,
  843. * <code>InputStream</code> and/or the primary MIME type isn't "text".
  844. * @exception IOException when any IOException occurs.
  845. * @exception UnsupportedEncodingException if the "charset" isn't supported
  846. * on this platform.
  847. */
  848. public Reader
  849. getReaderForText(Transferable transferable) throws UnsupportedFlavorException,
  850. IOException,
  851. UnsupportedEncodingException
  852. {
  853. if (!transferable.isDataFlavorSupported(this))
  854. throw new UnsupportedFlavorException(this);
  855. if (Reader.class.isAssignableFrom(representationClass))
  856. return((Reader)transferable.getTransferData(this));
  857. if (String.class.isAssignableFrom(representationClass))
  858. return(new StringReader((String)transferable.getTransferData(this)));
  859. if (InputStream.class.isAssignableFrom(representationClass)
  860. && "text".equals(getPrimaryType()))
  861. {
  862. InputStream in = (InputStream)transferable.getTransferData(this);
  863. String encoding = getParameter("charset");
  864. if (encoding == null)
  865. encoding = "us-ascii";
  866. return(new InputStreamReader(in, encoding));
  867. }
  868. throw new UnsupportedFlavorException(this);
  869. }
  870. } // class DataFlavor