Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

MessageListXmlReader.java 8.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. /* *******************************************************************
  2. * Copyright (c) 2003 Contributors.
  3. * All rights reserved.
  4. * This program and the accompanying materials are made available
  5. * under the terms of the Common Public License v1.0
  6. * which accompanies this distribution and is available at
  7. * http://www.eclipse.org/legal/cpl-v10.html
  8. *
  9. * Contributors:
  10. * Wes Isberg initial implementation
  11. * ******************************************************************/
  12. package org.aspectj.testing.xml;
  13. import java.io.File;
  14. import java.io.FileInputStream;
  15. import java.io.FileOutputStream;
  16. import java.io.IOException;
  17. import java.io.PrintWriter;
  18. import java.util.ArrayList;
  19. import java.util.List;
  20. import org.apache.commons.digester.Digester;
  21. import org.aspectj.bridge.AbortException;
  22. import org.aspectj.bridge.IMessage;
  23. import org.aspectj.bridge.ISourceLocation;
  24. import org.aspectj.bridge.MessageUtil;
  25. import org.aspectj.util.LangUtil;
  26. import org.xml.sax.SAXException;
  27. /**
  28. * Read a list of messages in xml form.
  29. * Input files should comply with DOCTYPE
  30. */
  31. public class MessageListXmlReader {
  32. private static final String INLINE_DOCTYPE;
  33. static {
  34. final String EOL = LangUtil.EOL;
  35. final StringBuffer r = new StringBuffer();
  36. r.append("<!DOCTYPE ");
  37. r.append(MessageList.XMLNAME);
  38. r.append(" [");
  39. r.append(EOL + " <!ELEMENT " + MessageList.XMLNAME
  40. + " (" + SoftMessage.XMLNAME + "+) >");
  41. String name = SoftMessage.XMLNAME;
  42. r.append(EOL + " <!ELEMENT " + name + " (" + SoftSourceLocation.XMLNAME + ")*>");
  43. r.append(EOL + " <!ATTLIST " + name + " kind CDATA #REQUIRED >");
  44. r.append(EOL + " <!ATTLIST " + name + " message CDATA #IMPLIED >");
  45. name = SoftSourceLocation.XMLNAME;
  46. r.append(EOL + " <!ELEMENT " + name + " (#PCDATA) >");
  47. r.append(EOL + " <!ATTLIST " + name + " line CDATA #REQUIRED >");
  48. r.append(EOL + " <!ATTLIST " + name + " endLine CDATA #IMPLIED >");
  49. r.append(EOL + " <!ATTLIST " + name + " column CDATA #IMPLIED >");
  50. r.append(EOL + " <!ATTLIST " + name + " sourceFile CDATA #IMPLIED >");
  51. r.append(EOL + "] >");
  52. INLINE_DOCTYPE = r.toString();
  53. }
  54. private static final String[] LOG = new String[] {"info", "debug", "trace" };
  55. private int logLevel;
  56. /**
  57. * Print IMessage[] to the output file as XML.
  58. * @param output the File to write to - overwritten
  59. * @param messages the IMessage[] to write
  60. * @return null if no warnings detected, warnings otherwise
  61. */
  62. public String writeMessages(File output, IMessage[] messages) throws IOException {
  63. LangUtil.throwIaxIfNull(output, "output");
  64. LangUtil.throwIaxIfFalse(!LangUtil.isEmpty(messages), "no messages");
  65. PrintWriter writer = new PrintWriter(new FileOutputStream(output));
  66. XMLWriter printSink = new XMLWriter(writer);
  67. writer.println("");
  68. writer.println(INLINE_DOCTYPE);
  69. writer.println("");
  70. writer.println("<" + MessageList.XMLNAME + ">");
  71. SoftMessage.writeXml(printSink, messages);
  72. writer.println("</" + MessageList.XMLNAME + ">");
  73. writer.close();
  74. return null;
  75. }
  76. /** @param level 0..2, info..trace */
  77. public void setLogLevel(int level) {
  78. if (level < 0) {
  79. level = 0;
  80. }
  81. if (level > 2) {
  82. level = 2;
  83. }
  84. logLevel = level;
  85. }
  86. /**
  87. * Read the specifications for a list of IMessage from an XML file.
  88. * @param file the File must be readable, comply with DOCTYPE.
  89. * @return IMessage[] read from file
  90. * @see setLogLevel(int)
  91. */
  92. public IMessage[] readMessages(File file) throws IOException, AbortException {
  93. // setup loggers for digester and beanutils...
  94. System.setProperty("org.apache.commons.logging.Log", "org.apache.commons.logging.impl.SimpleLog"); // XXX
  95. System.setProperty("org.apache.commons.logging.simplelog.defaultlog", LOG[logLevel]); // trace debug XXX
  96. final Digester digester = new Digester();
  97. setupDigester(digester);
  98. MessageListHolder holder = new MessageListHolder();
  99. digester.push(holder);
  100. FileInputStream input = new FileInputStream(file);
  101. try {
  102. digester.parse(input);
  103. } catch (SAXException e) {
  104. MessageUtil.fail("parsing " + file, e);
  105. } finally {
  106. if (null != input) {
  107. input.close();
  108. input = null;
  109. }
  110. }
  111. return (null == holder.list
  112. ? new IMessage[0]
  113. : holder.list.getMessages());
  114. }
  115. /** set up the mapping between the xml and Java. */
  116. private void setupDigester(Digester digester) {
  117. // XXX supply sax parser to ignore white space?
  118. digester.setValidating(true);
  119. // element names come from the element components
  120. final String messageListX = MessageList.XMLNAME;
  121. final String messageX = messageListX + "/" + SoftMessage.XMLNAME;
  122. final String messageSrcLocX = messageX + "/" + SoftSourceLocation.XMLNAME;
  123. // ---- each sub-element needs to be created
  124. // handle messages the same at any level
  125. digester.addObjectCreate(messageListX, MessageList.class.getName());
  126. digester.addObjectCreate(messageX, SoftMessage.class.getName());
  127. digester.addObjectCreate(messageSrcLocX, SoftSourceLocation.class.getName());
  128. // ---- set bean properties for sub-elements created automatically
  129. // -- some remapped - warnings
  130. // - if property exists, map will not be used
  131. digester.addSetProperties(messageListX);
  132. digester.addSetProperties(messageX);
  133. digester.addSetProperties(messageSrcLocX);
  134. digester.addSetProperties(messageX, "kind", "kindAsString");
  135. digester.addSetProperties(messageX, "line", "lineAsString");
  136. // ---- when subelements are created, add to parent
  137. digester.addSetNext(messageListX, "addMessage", IMessage.class.getName());
  138. digester.addSetNext(messageX, "setSourceLocation", ISourceLocation.class.getName());
  139. // can set parent, but prefer to have "knows-about" flow down only...
  140. }
  141. // ------------------------------------------------------------ testing code
  142. /**
  143. * This is only to do compile-time checking for the APIs impliedly
  144. * used in setupDigester(..).
  145. * The property setter checks are redundant with tests based on
  146. * expectedProperties().
  147. */
  148. // private static void setupDigesterCompileTimeCheck() {
  149. // if (true) { throw new Error("never invoked"); }
  150. //
  151. // MessageListHolder holder = new MessageListHolder();
  152. // MessageList ml = new MessageList();
  153. // SoftMessage m = new SoftMessage();
  154. // SoftSourceLocation sl = new SoftSourceLocation();
  155. //
  156. // holder.setMessageList(ml);
  157. // ml.addMessage((IMessage) null);
  158. // m.setSourceLocation(sl);
  159. // m.setText((String) null);
  160. // m.setKindAsString((String) null);
  161. //
  162. // sl.setFile((String) null);
  163. // sl.setLine((String) null);
  164. // sl.setColumn((String) null);
  165. // sl.setEndLine((String) null);
  166. //
  167. // // add attribute setters to validate?
  168. // }
  169. // inner classes, to make public for bean utilities
  170. /** a list of messages */
  171. public static class MessageList {
  172. public static final String XMLNAME = "message-list";
  173. private List messages = new ArrayList();
  174. public void addMessage(IMessage message) {
  175. messages.add(message);
  176. }
  177. IMessage[] getMessages() {
  178. return (IMessage[]) messages.toArray(new IMessage[0]);
  179. }
  180. }
  181. /** push on digester stack to hold message list */
  182. public static class MessageListHolder {
  183. public MessageList list;
  184. public void setMessageList(MessageList list) {
  185. this.list = list;
  186. }
  187. }
  188. }