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 CHECK_FOR_DTD_UPDATE = "activemq.check_for_dtd_update"; 046 private static final String DTD_NAME = "activemq.dtd"; 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 058 if( "true".equals(System.getProperty(CHECK_FOR_DTD_UPDATE, "true")) ) { 059 source = resolveRemotely(publicId, systemId); 060 } 061 if( source == null ) { 062 source = resolveLocally(publicId, systemId); 063 } 064 } 065 return source; 066 } 067 068 /** 069 * Try to resolve against the latest DTD for this version of activemq. 070 * 071 * @param publicId 072 * @param systemId 073 * @return 074 */ 075 InputSource resolveRemotely(String publicId, String systemId) { 076 InputSource source=null; 077 if( systemId.endsWith(DTD_NAME) ) { 078 String dtdFile = "http://activemq.org/dtd/"+ActiveMQConnectionMetaData.PROVIDER_VERSION+"/"+DTD_NAME; 079 logger.debug("Trying to locate [" + dtdFile + "]"); 080 try { 081 URL url = new URL(dtdFile); 082 InputStream stream = url.openStream(); 083 if( stream!=null ) { 084 source = new InputSource(stream); 085 source.setPublicId(publicId); 086 source.setSystemId(systemId); 087 logger.debug("Found beans DTD [" + systemId + "] at: "+dtdFile); 088 } 089 } 090 catch (IOException ex) { 091 logger.debug("Could not resolve beans DTD [" + systemId + "]: not found in classpath", ex); 092 } 093 } 094 return null; 095 } 096 097 /** 098 * Use the DTD that this version of ActiveMQ shipped with. 099 * 100 * @param publicId 101 * @param systemId 102 * @return 103 */ 104 InputSource resolveLocally(String publicId, String systemId) { 105 String dtdFile = systemId.substring(systemId.indexOf(DTD_NAME)); 106 logger.debug("Trying to locate [" + dtdFile + "] under [" + SEARCH_PACKAGE + "]"); 107 try { 108 String name = SEARCH_PACKAGE + dtdFile; 109 Resource resource = new ClassPathResource(name, getClass()); 110 InputSource source = new InputSource(resource.getInputStream()); 111 source.setPublicId(publicId); 112 source.setSystemId(systemId); 113 logger.debug("Found beans DTD [" + systemId + "] in classpath"); 114 return source; 115 } 116 catch (IOException ex) { 117 logger.debug("Could not resolve beans DTD [" + systemId + "]: not found in classpath", ex); 118 // use the default behaviour -> download from website or wherever 119 return null; 120 } 121 } 122 123 }