/******************************************************************************* * Copyright (c) 2001, 2009 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation * David Carver - STAR - [205989] - [validation] validate XML after XInclude resolution * * * The class is partially copied from WTP because of its poor visibility * org.eclipse.wst.xml.core.internal.validation.XMLValidator.MyEntityResolver * *******************************************************************************/ package org.jboss.tools.jsf.web.validation; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.net.URL; import org.apache.xerces.xni.XMLResourceIdentifier; import org.apache.xerces.xni.XNIException; import org.apache.xerces.xni.parser.XMLEntityResolver; import org.apache.xerces.xni.parser.XMLInputSource; import org.eclipse.wst.common.uriresolver.internal.provisional.URIResolver; import org.eclipse.wst.xml.core.internal.validation.XMLNestedValidatorContext; import org.eclipse.wst.xml.core.internal.validation.core.LazyURLInputStream; import org.eclipse.wst.xml.core.internal.validation.core.NestedValidatorContext; /** * A custom entity resolver that uses the URI resolver specified to resolve * entities. */ public class XHTMLEntityResolver implements XMLEntityResolver { private URIResolver uriResolver; private String resolvedDTDLocation; private NestedValidatorContext context; /** * Constructor. * * @param uriResolver * The URI resolver to use with this entity resolver. * @param context * The XML validator context. */ public XHTMLEntityResolver(URIResolver uriResolver, NestedValidatorContext context) { this.uriResolver = uriResolver; this.context = context; } /* * (non-Javadoc) * * @see * org.apache.xerces.xni.parser.XMLEntityResolver#resolveEntity(org.apache * .xerces.xni.XMLResourceIdentifier) */ public XMLInputSource resolveEntity(XMLResourceIdentifier rid) throws XNIException, IOException { XMLInputSource inputSource = _internalResolveEntity(uriResolver, rid, context); if (inputSource != null) { resolvedDTDLocation = inputSource.getSystemId(); } return inputSource; } public String getLocation() { return resolvedDTDLocation; } // cs : I've refactored the common SAX based resolution code into this // method for use by other validators // (i.e. XML Schema, WSDL etc). The other approach is maintain a copy for // each validator that has // identical code. In any case we should strive to ensure that the // validators perform resolution consistently. public static XMLInputSource _internalResolveEntity( URIResolver uriResolver, XMLResourceIdentifier rid) throws IOException { return _internalResolveEntity(uriResolver, rid, null); } public static XMLInputSource _internalResolveEntity( URIResolver uriResolver, XMLResourceIdentifier rid, NestedValidatorContext context) throws IOException { XMLInputSource is = null; if (uriResolver != null) { String id = rid.getPublicId(); if (id == null) { id = rid.getNamespace(); } String location = null; if (id != null || rid.getLiteralSystemId() != null) { location = uriResolver.resolve(rid.getBaseSystemId(), id, rid .getLiteralSystemId()); } if (location != null) { String physical = uriResolver.resolvePhysicalLocation(rid .getBaseSystemId(), id, location); // if physical is already a known bad uri, just go ahead and // throw an exception if (context instanceof XMLNestedValidatorContext) { XMLNestedValidatorContext xmlContext = ((XMLNestedValidatorContext) context); if (xmlContext.isURIMarkedInaccessible(physical)) { throw new FileNotFoundException(physical); } } // // This block checks that the file exists. If it doesn't we need // // to throw // // an exception so Xerces will report an error. note: This may // // not be // // necessary with all versions of Xerces but has specifically // // been // // experienced with the version included in IBM's 1.4.2 JDK. // InputStream isTemp = null; // try { // isTemp = new URL(physical).openStream(); // } catch (IOException e) { // // physical was a bad url, so cache it so we know next time // if (context instanceof XMLNestedValidatorContext) { // XMLNestedValidatorContext xmlContext = ((XMLNestedValidatorContext) context); // xmlContext.markURIInaccessible(physical); // } // throw e; // } finally { // if (isTemp != null) { // isTemp.close(); // } // } if(physical.startsWith("file:")||physical.startsWith("jar:")) { is = new XMLInputSource(rid.getPublicId(), location, location); is.setByteStream(new LazyURLInputStream(physical)); } } } return is; } }