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 }