001 /** 002 * 003 * Copyright 2004 Protique Ltd 004 * 005 * Licensed under the Apache License, Version 2.0 (the "License"); 006 * you may not use this file except in compliance with the License. 007 * You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 * 017 **/ 018 package org.activemq.spring; 019 020 import org.activemq.ActiveMQConnectionMetaData; 021 import org.apache.commons.logging.Log; 022 import org.apache.commons.logging.LogFactory; 023 import org.springframework.core.io.ClassPathResource; 024 import org.springframework.core.io.Resource; 025 import org.xml.sax.EntityResolver; 026 import org.xml.sax.InputSource; 027 028 import java.io.IOException; 029 import java.io.InputStream; 030 import java.net.URL; 031 032 /** 033 * EntityResolver implementation for the ActiveMQ DTD, 034 * to load the DTD from the ActiveMQ classpath JAR file. 035 * <p/> 036 * <p>Fetches "activemq.dtd" from the classpath resource 037 * "/org/activemq/activemq.dtd", 038 * no matter if specified as some local URL or as 039 * "http://activemq.org/dtd/activemq.dtd". 040 * 041 * @version $Revision$ 042 */ 043 public class ActiveMQDtdResolver implements EntityResolver { 044 045 private static final String DTD_NAME = "activemq.dtd"; 046 047 private static final String SEARCH_PACKAGE = "/org/activemq/"; 048 049 protected final Log logger = LogFactory.getLog(getClass()); 050 051 public InputSource resolveEntity(String publicId, String systemId) throws IOException { 052 logger.debug("Trying to resolve XML entity with public ID [" + publicId + 053 "] and system ID [" + systemId + "]"); 054 055 InputSource source = null; 056 if (systemId != null && systemId.indexOf(DTD_NAME) > systemId.lastIndexOf("/")) { 057 source = resolveRemotely(publicId, systemId); 058 if( source == null ) { 059 source = resolveLocally(publicId, systemId); 060 } 061 } 062 return source; 063 } 064 065 /** 066 * Try to resolve against the latest DTD for this version of activemq. 067 * 068 * @param publicId 069 * @param systemId 070 * @return 071 */ 072 InputSource resolveRemotely(String publicId, String systemId) { 073 InputSource source=null; 074 if( systemId.endsWith(DTD_NAME) ) { 075 String dtdFile = "http://activemq.org/dtd/"+ActiveMQConnectionMetaData.PROVIDER_VERSION+"/"+DTD_NAME; 076 logger.debug("Trying to locate [" + dtdFile + "]"); 077 try { 078 URL url = new URL(dtdFile); 079 InputStream stream = url.openStream(); 080 if( stream!=null ) { 081 source = new InputSource(stream); 082 source.setPublicId(publicId); 083 source.setSystemId(systemId); 084 logger.debug("Found beans DTD [" + systemId + "] at: "+dtdFile); 085 } 086 } 087 catch (IOException ex) { 088 logger.debug("Could not resolve beans DTD [" + systemId + "]: not found in classpath", ex); 089 } 090 } 091 return null; 092 } 093 094 /** 095 * Use the DTD that this version of ActiveMQ shipped with. 096 * 097 * @param publicId 098 * @param systemId 099 * @return 100 */ 101 InputSource resolveLocally(String publicId, String systemId) { 102 String dtdFile = systemId.substring(systemId.indexOf(DTD_NAME)); 103 logger.debug("Trying to locate [" + dtdFile + "] under [" + SEARCH_PACKAGE + "]"); 104 try { 105 String name = SEARCH_PACKAGE + dtdFile; 106 Resource resource = new ClassPathResource(name, getClass()); 107 InputSource source = new InputSource(resource.getInputStream()); 108 source.setPublicId(publicId); 109 source.setSystemId(systemId); 110 logger.debug("Found beans DTD [" + systemId + "] in classpath"); 111 return source; 112 } 113 catch (IOException ex) { 114 logger.debug("Could not resolve beans DTD [" + systemId + "]: not found in classpath", ex); 115 // use the default behaviour -> download from website or wherever 116 return null; 117 } 118 } 119 120 }