/jEdit/branches/4.4.x-merge-request-for-r19201/org/gjt/sp/util/XMLUtilities.java

# · Java · 202 lines · 112 code · 12 blank · 78 comment · 19 complexity · d539832e0f9f256d4db30dda40437f7f MD5 · raw file

  1. /*
  2. * StandardUtilities.java - Miscelaneous XML utility functions.
  3. * :tabSize=8:indentSize=8:noTabs=false:
  4. * :folding=explicit:collapseFolds=1:
  5. *
  6. * Copyright (C) 1999, 2006 Marcelo Vanzin, Slava Pestov
  7. * Portions copyright (C) 2000 Richard S. Hall
  8. * Portions copyright (C) 2001 Dirk Moebius
  9. *
  10. * This program is free software; you can redistribute it and/or
  11. * modify it under the terms of the GNU General Public License
  12. * as published by the Free Software Foundation; either version 2
  13. * of the License, or any later version.
  14. *
  15. * This program is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. * GNU General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU General Public License
  21. * along with this program; if not, write to the Free Software
  22. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  23. */
  24. package org.gjt.sp.util;
  25. //{{{ Imports
  26. import java.io.InputStream;
  27. import java.io.BufferedInputStream;
  28. import java.io.IOException;
  29. import org.xml.sax.InputSource;
  30. import org.xml.sax.SAXException;
  31. import org.xml.sax.SAXParseException;
  32. import org.xml.sax.XMLReader;
  33. import org.xml.sax.helpers.DefaultHandler;
  34. import org.xml.sax.helpers.XMLReaderFactory;
  35. //}}}
  36. /**
  37. * XML utility methods that only depend on the JDK.
  38. *
  39. * @author Marcelo Vanzin
  40. * @version $Id: XMLUtilities.java 13929 2008-10-25 14:23:41Z k_satoda $
  41. * @since 4.3pre6
  42. */
  43. public class XMLUtilities
  44. {
  45. //{{{ charsToEntities() method
  46. /**
  47. * Converts <, >, & in the string to their HTML entity
  48. * equivalents.
  49. *
  50. * <p>If <code>xml11</code> is true, then character entities
  51. * are used to convert illegal XML characters (mainly ASCII
  52. * control characters).</p>
  53. *
  54. * @param str The string
  55. * @param xml11 Whether to allow XML 1.1 constructs.
  56. */
  57. public static String charsToEntities(String str, boolean xml11)
  58. {
  59. StringBuilder buf = new StringBuilder(str.length());
  60. for(int i = 0; i < str.length(); i++)
  61. {
  62. char ch = str.charAt(i);
  63. // control characters, excluding \t, \r and \n
  64. // See: http://www.w3.org/International/questions/qa-controls
  65. if (((0x00 <= ch && ch <= 0x1F) || (0x7F <= ch && ch <= 0x9F))
  66. && ch != '\r' && ch != '\n' && ch != '\t')
  67. {
  68. if (xml11 && ch != 0x00)
  69. {
  70. buf.append("&#").append((int)ch).append(';');
  71. }
  72. else
  73. {
  74. // The character is illegal.
  75. // But put a PI instead, to make it
  76. // recoverable in certain apps.
  77. buf.append("<?illegal-xml-character ")
  78. .append((int)ch)
  79. .append("?>");
  80. }
  81. continue;
  82. }
  83. switch(ch)
  84. {
  85. case '<':
  86. buf.append("&lt;");
  87. break;
  88. case '>':
  89. buf.append("&gt;");
  90. break;
  91. case '&':
  92. buf.append("&amp;");
  93. break;
  94. default:
  95. buf.append(ch);
  96. break;
  97. }
  98. }
  99. return buf.toString();
  100. } //}}}
  101. //{{{ parseXML() method
  102. /**
  103. * Convenience method for parsing an XML file. This method will
  104. * wrap the resource in an InputSource and set the source's
  105. * systemId to "jedit.jar" (so the source should be able to
  106. * handle any external entities by itself).
  107. *
  108. * <p>SAX Errors are caught and are not propagated to the caller;
  109. * instead, an error message is printed to jEdit's activity
  110. * log. So, if you need custom error handling, <b>do not use
  111. * this method</b>.
  112. *
  113. * <p>The given stream is closed before the method returns,
  114. * regardless whether there were errors or not.</p>
  115. *
  116. * @return true if any error occured during parsing, false if success.
  117. */
  118. public static boolean parseXML(InputStream in, DefaultHandler handler)
  119. throws IOException
  120. {
  121. try
  122. {
  123. XMLReader parser = XMLReaderFactory.createXMLReader();
  124. InputSource isrc = new InputSource(
  125. new BufferedInputStream(in));
  126. isrc.setSystemId("jedit.jar");
  127. parser.setContentHandler(handler);
  128. parser.setDTDHandler(handler);
  129. parser.setEntityResolver(handler);
  130. parser.setErrorHandler(handler);
  131. parser.parse(isrc);
  132. }
  133. catch(SAXParseException se)
  134. {
  135. int line = se.getLineNumber();
  136. Log.log(Log.ERROR,XMLUtilities.class,
  137. "while parsing from " + in + ": SAXParseException: line " + line + ": " , se);
  138. return true;
  139. }
  140. catch(SAXException e)
  141. {
  142. Log.log(Log.ERROR,XMLUtilities.class,e);
  143. return true;
  144. }
  145. finally
  146. {
  147. try
  148. {
  149. if(in != null)
  150. in.close();
  151. }
  152. catch(IOException io)
  153. {
  154. Log.log(Log.ERROR,XMLUtilities.class,io);
  155. }
  156. }
  157. return false;
  158. } //}}}
  159. //{{{ resolveEntity() method
  160. /**
  161. * Tries to find the given systemId in the context of the given
  162. * class. If the given systemId ends with the given test string,
  163. * then try to load a resource using the Class's
  164. * <code>getResourceAsStream()</code> method using the test string
  165. * as the resource.
  166. *
  167. * <p>This is used a lot internally while parsing XML files used
  168. * by jEdit, but anyone is free to use the method if it sounds
  169. * usable.</p>
  170. */
  171. public static InputSource findEntity(String systemId, String test, Class where)
  172. {
  173. if (systemId != null && systemId.endsWith(test))
  174. {
  175. try
  176. {
  177. return new InputSource(new BufferedInputStream(
  178. where.getResourceAsStream(test)));
  179. }
  180. catch (Exception e)
  181. {
  182. Log.log(Log.ERROR,XMLUtilities.class,
  183. "Error while opening " + test + ':');
  184. Log.log(Log.ERROR,XMLUtilities.class,e);
  185. }
  186. }
  187. return null;
  188. } //}}}
  189. private XMLUtilities() { }
  190. }