You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

XMLHandlerRegistry.java 6.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. /*
  2. * Licensed to the Apache Software Foundation (ASF) under one or more
  3. * contributor license agreements. See the NOTICE file distributed with
  4. * this work for additional information regarding copyright ownership.
  5. * The ASF licenses this file to You under the Apache License, Version 2.0
  6. * (the "License"); you may not use this file except in compliance with
  7. * the License. You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. /* $Id$ */
  18. package org.apache.fop.render;
  19. import java.lang.reflect.InvocationTargetException;
  20. import java.util.Iterator;
  21. import java.util.List;
  22. import java.util.Map;
  23. import org.apache.commons.logging.Log;
  24. import org.apache.commons.logging.LogFactory;
  25. import org.apache.xmlgraphics.util.Service;
  26. /**
  27. * This class holds references to various XML handlers used by FOP. It also
  28. * supports automatic discovery of additional XML handlers available through
  29. * the class path.
  30. */
  31. public class XMLHandlerRegistry {
  32. /** the logger */
  33. private static Log log = LogFactory.getLog(XMLHandlerRegistry.class);
  34. /** Map containing XML handlers for various document types */
  35. private Map<String, List<XMLHandler>> handlers
  36. = new java.util.HashMap<String, List<XMLHandler>>();
  37. /**
  38. * Default constructor.
  39. */
  40. public XMLHandlerRegistry() {
  41. discoverXMLHandlers();
  42. }
  43. /**
  44. * Add a default XML handler which is able to handle any namespace.
  45. * @param handler XMLHandler to use
  46. */
  47. private void setDefaultXMLHandler(XMLHandler handler) {
  48. addXMLHandler(XMLHandler.HANDLE_ALL, handler);
  49. }
  50. /**
  51. * Add an XML handler. The handler itself is inspected to find out what it supports.
  52. * @param classname the fully qualified class name
  53. */
  54. public void addXMLHandler(String classname) {
  55. try {
  56. XMLHandler handlerInstance = (XMLHandler)Class.forName(classname).getDeclaredConstructor().newInstance();
  57. addXMLHandler(handlerInstance);
  58. } catch (ClassNotFoundException e) {
  59. throw new IllegalArgumentException("Could not find "
  60. + classname);
  61. } catch (InstantiationException e) {
  62. throw new IllegalArgumentException("Could not instantiate "
  63. + classname);
  64. } catch (IllegalAccessException e) {
  65. throw new IllegalArgumentException("Could not access "
  66. + classname);
  67. } catch (ClassCastException e) {
  68. throw new IllegalArgumentException(classname
  69. + " is not an "
  70. + XMLHandler.class.getName());
  71. } catch (NoSuchMethodException e) {
  72. throw new IllegalArgumentException(e);
  73. } catch (InvocationTargetException e) {
  74. throw new IllegalArgumentException(e);
  75. }
  76. }
  77. /**
  78. * Add an XML handler. The handler itself is inspected to find out what it supports.
  79. * @param handler the XMLHandler instance
  80. */
  81. public void addXMLHandler(XMLHandler handler) {
  82. String ns = handler.getNamespace();
  83. if (ns == null) {
  84. setDefaultXMLHandler(handler);
  85. } else {
  86. addXMLHandler(ns, handler);
  87. }
  88. }
  89. /**
  90. * Add an XML handler for the given MIME type and XML namespace.
  91. * @param ns Namespace URI
  92. * @param handler XMLHandler to use
  93. */
  94. private void addXMLHandler(String ns, XMLHandler handler) {
  95. List<XMLHandler> lst = handlers.get(ns);
  96. if (lst == null) {
  97. lst = new java.util.ArrayList<XMLHandler>();
  98. handlers.put(ns, lst);
  99. }
  100. lst.add(handler);
  101. }
  102. /**
  103. * Returns an XMLHandler which handles an XML dialect of the given namespace and for
  104. * a specified output format defined by its MIME type.
  105. * @param renderer the Renderer for which to retrieve a Renderer
  106. * @param ns the XML namespace associated with the XML to be rendered
  107. * @return the XMLHandler responsible for handling the XML or null if none is available
  108. */
  109. public XMLHandler getXMLHandler(Renderer renderer, String ns) {
  110. XMLHandler handler;
  111. List<XMLHandler> lst = handlers.get(ns);
  112. handler = getXMLHandler(renderer, lst);
  113. if (handler == null) {
  114. lst = handlers.get(XMLHandler.HANDLE_ALL);
  115. handler = getXMLHandler(renderer, lst);
  116. }
  117. return handler;
  118. }
  119. private XMLHandler getXMLHandler(Renderer renderer, List<XMLHandler> lst) {
  120. XMLHandler handler;
  121. if (lst != null) {
  122. for (XMLHandler aLst : lst) {
  123. //TODO Maybe add priorities later
  124. handler = aLst;
  125. if (handler.supportsRenderer(renderer)) {
  126. return handler;
  127. }
  128. }
  129. }
  130. return null; //No handler found
  131. }
  132. /**
  133. * Discovers XMLHandler implementations through the classpath and dynamically
  134. * registers them.
  135. */
  136. private void discoverXMLHandlers() {
  137. // add mappings from available services
  138. Iterator<Object> providers = Service.providers(XMLHandler.class);
  139. if (providers != null) {
  140. while (providers.hasNext()) {
  141. XMLHandler handler = (XMLHandler)providers.next();
  142. try {
  143. if (log.isDebugEnabled()) {
  144. log.debug("Dynamically adding XMLHandler: " + handler.getClass().getName());
  145. }
  146. addXMLHandler(handler);
  147. } catch (IllegalArgumentException e) {
  148. log.error("Error while adding XMLHandler", e);
  149. }
  150. }
  151. }
  152. }
  153. }