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 }