When you validate a XML file, and this has a XSD URL for some namespace, and this XSD URL redirects to another URL, then the default EntityResolver2 takes that as a failure.
Jess noticed (and fixed) this when debugging WINDUP-997.
So for instance, this XML was not valid, because some of the URLs (perhaps in the linked XSD's) is behind a redirect:
<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<mvc:resources mapping="/resources/**" location="/" />
So here's a fixed implementation. It follows only a single redirect, but change the if to a for and it will follow more (don't forget to prevent infinite loop).
package org.jboss.windup.rules.apps.xml.xml;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.ext.EntityResolver2;
/**
* This is an {@link EntityResolver2} that has been enhanced to support URL redirection.
*
* @author <a href="mailto:jesse.sightler@gmail.com">Jesse Sightler</a>
*/
public class EnhancedEntityResolver2 implements EntityResolver2
{
@Override
public InputSource getExternalSubset(String name, String baseURI) throws SAXException, IOException
{
return null;
}
@Override
public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException
{
return resolveEntity(null, publicId, null, systemId);
}
@Override
public InputSource resolveEntity(String name, String publicId, String baseURI, String systemId) throws SAXException, IOException
{
URL url = baseURI != null ? new URL(new URL(baseURI), systemId) : new URL(systemId);
URLConnection connection = url.openConnection();
// Not a HTTP connection... skip redirection logic
if (!(connection instanceof HttpURLConnection))
return new InputSource(connection.getInputStream());
HttpURLConnection httpConnection = (HttpURLConnection)connection;
int status = httpConnection.getResponseCode();
if ((status != HttpURLConnection.HTTP_OK) &&
(status == HttpURLConnection.HTTP_MOVED_TEMP
|| status == HttpURLConnection.HTTP_MOVED_PERM
|| status == HttpURLConnection.HTTP_SEE_OTHER))
{
String newUrl = httpConnection.getHeaderField("Location");
httpConnection = (HttpURLConnection) new URL(newUrl).openConnection();
}
InputSource inputSource = new InputSource(httpConnection.getInputStream());
inputSource.setSystemId(url.toString());
inputSource.setPublicId(publicId);
return inputSource;
}
}