/*
 * Copyright 2002-2006 the original author or authors.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.beans.factory.xml;

import java.io.IOException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;

import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;

/**
 * EntityResolver implementation for the Spring beans DTD,
 * to load the DTD from the Spring class path (or JAR file).
 *
 * <p>Fetches "spring-beans_2_0.dtd" from the class path resource
 * "/org/springframework/beans/factory/xml/spring-beans_2_0.dtd",
 * no matter whether specified as some local URL that includes "spring-beans"
 * in the DTD name or as "http://www.springframework.org/dtd/spring-beans_2_0.dtd".
 *
 * @author Juergen Hoeller
 * @author Colin Sampaleanu
 * @since 04.06.2003
 * @see ResourceEntityResolver
 */
public class BeansDtdResolver implements EntityResolver {
	
	private static String[] DTD_NAMES = {"spring-beans_2_0", "spring-beans"}; 

	/** Logger available to subclasses */
	protected final Log logger = LogFactory.getLog(getClass());


	public InputSource resolveEntity(String publicId, String systemId) throws IOException {
		if (logger.isDebugEnabled()) {
			logger.debug("Trying to resolve XML entity with public ID [" + publicId +
					"] and system ID [" + systemId + "]");
		}
		if (systemId != null) {
			for (int i = 0; i < DTD_NAMES.length; ++i) {

				if (systemId.indexOf(DTD_NAMES[i]) > systemId.lastIndexOf("/")) {
					String dtdFile = systemId.substring(systemId.indexOf(DTD_NAMES[i]));
					if (logger.isDebugEnabled()) {
						logger.debug("Trying to locate [" + dtdFile + "] in Spring jar");
					}
					try {
						Resource resource = new ClassPathResource(dtdFile, getClass());
						InputSource source = new InputSource(resource.getInputStream());
						source.setPublicId(publicId);
						source.setSystemId(systemId);
						if (logger.isDebugEnabled()) {
							logger.debug("Found beans DTD [" + systemId + "] in classpath");
						}
						return source;
					}
					catch (IOException ex) {
						if (logger.isDebugEnabled()) {
							logger.debug("Could not resolve beans DTD [" + systemId + "]: not found in class path", ex);
						}
					}
				
				}
			}
		}

		// Use the default behavior -> download from website or wherever.
		return null;
	}
}

@@ -1559,16 +1559,76 @@
  static 
+final String DTD_EXTENSION = %22.dtd%22;%0A%0A%09private static final 
 String%5B%5D
@@ -1685,56 +1685,22 @@
  %0A%0A%09
-/** Logger available to subclasses */%0A%09protected
+private static
  fin
@@ -1733,26 +1733,38 @@
 .getLog(
-getC
+BeansDtdResolver.c
 lass
-()
 );%0A%0A%0A%09pu
@@ -2029,19 +2029,109 @@
  != null
-) %7B
+ && systemId.endsWith(DTD_EXTENSION)) %7B%0A%09%09%09int lastPathSeparator = systemId.lastIndexOf(%22/%22);
 %0A%09%09%09for 
@@ -2175,17 +2175,31 @@
 ) %7B%0A
-%0A
 %09%09%09%09i
-f (
+nt dtdNameStart = 
 syst
@@ -2228,36 +2228,50 @@
 %5Bi%5D)
- %3E systemId.lastIndexOf(%22/%22)
+;%0A%09%09%09%09if (dtdNameStart %3E lastPathSeparator
 ) %7B%0A
@@ -2315,38 +2315,20 @@
 ing(
-systemId.indexOf(DTD_NAMES%5Bi%5D)
+dtdNameStart
 );%0A%09
@@ -3099,10 +3099,11 @@
 ull;%0A%09%7D%0A
+%0A
 %7D%0A

check for ".dtd" extension