blob: 89d69eb84cc42b6a623e341eace13f5343254ce4 [file] [log] [blame]
package org.apache.maven.doxia.xsd;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.net.JarURLConnection;
import java.net.URL;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import org.apache.maven.doxia.parser.AbstractXmlParser;
import org.codehaus.plexus.util.FileUtils;
import org.codehaus.plexus.util.IOUtil;
import org.codehaus.plexus.util.ReaderFactory;
import org.codehaus.plexus.util.SelectorUtils;
import org.codehaus.plexus.util.xml.XmlUtil;
import org.xml.sax.EntityResolver;
/**
* Abstract class to validate XML files with DTD or XSD mainly for Doxia namespaces.
*
* @author <a href="mailto:vincent.siveton@gmail.com">Vincent Siveton</a>
* @version $Id$
* @since 1.0
*/
public abstract class AbstractXmlValidatorTest
extends AbstractXmlValidator
{
/** Simple cache mechanism to load test documents. */
private static final Map<String,String> CACHE_DOXIA_TEST_DOCUMENTS = new Hashtable<String,String>();
/** Maven resource in the doxia-test-docs-XXX.jar */
private static final String MAVEN_RESOURCE_PATH = "META-INF/maven/org.apache.maven.doxia/doxia-test-docs/";
// ----------------------------------------------------------------------
// Protected methods
// ----------------------------------------------------------------------
/**
* @return a non null patterns to includes specific test files.
* @see AbstractXmlValidatorTest#getTestDocuments()
*/
protected abstract String[] getIncludes();
/**
* @return a map of test resources filtered by patterns from {@link #getIncludes()}.
* @throws IOException if any
* @see #getIncludes()
* @see #getAllTestDocuments()
*/
protected Map<String, String> getTestDocuments()
throws IOException
{
if ( getIncludes() == null )
{
return Collections.emptyMap();
}
Map<String,String> testDocs = getAllTestDocuments();
Map<String,String> ret = new Hashtable<String,String>();
ret.putAll( testDocs );
for ( Iterator<String> it = testDocs.keySet().iterator(); it.hasNext(); )
{
String key = it.next();
for ( int i = 0; i < getIncludes().length; i++ )
{
if ( !SelectorUtils.matchPath( getIncludes()[i], key.toLowerCase( Locale.ENGLISH ) ) )
{
ret.remove( key );
}
}
}
return ret;
}
/**
* Returns the EntityResolver that is used by the XMLReader for validation.
* By default a {@link AbstractXmlParser.CachedFileEntityResolver} is used,
* but implementations should override this for performance reasons.
*
* @return an EntityResolver. Not null.
*
* @since 1.2
*/
protected EntityResolver getEntityResolver()
{
return new AbstractXmlParser.CachedFileEntityResolver();
}
/**
* Find test resources in the <code>doxia-test-docs-XXX.jar</code> or in an IDE project.
*
* @return a map of test resources defined as follow:
* <ul>
* <li>key, the full url of test documents,
* i.e. <code>jar:file:/.../doxia-test-docs-XXX.jar!/path/to/resource</code></li>
* <li>value, the content for the resource defined by the key</li>
* </ul>
* @throws IOException if any
*/
protected static Map<String,String> getAllTestDocuments()
throws IOException
{
if ( CACHE_DOXIA_TEST_DOCUMENTS != null && !CACHE_DOXIA_TEST_DOCUMENTS.isEmpty() )
{
return Collections.unmodifiableMap( CACHE_DOXIA_TEST_DOCUMENTS );
}
URL testJar = AbstractXmlValidatorTest.class.getClassLoader().getResource( MAVEN_RESOURCE_PATH );
if ( testJar == null )
{
// maybe in an IDE project
testJar = AbstractXmlValidatorTest.class.getClassLoader().getResource( "doxia-site" );
if ( testJar == null )
{
throw new RuntimeException(
"Could not find the Doxia test documents artefact i.e. doxia-test-docs-XXX.jar" );
}
}
if ( testJar.toString().startsWith( "jar" ))
{
JarURLConnection conn = (JarURLConnection) testJar.openConnection();
JarFile jarFile = conn.getJarFile();
for ( Enumeration<JarEntry> e = jarFile.entries(); e.hasMoreElements(); )
{
JarEntry entry = e.nextElement();
if ( entry.getName().startsWith( "META-INF" ) )
{
continue;
}
if ( entry.isDirectory() )
{
continue;
}
InputStream in = null;
try
{
in = AbstractXmlValidatorTest.class.getClassLoader().getResource( entry.getName() ).openStream();
String content = IOUtil.toString( in, "UTF-8" );
CACHE_DOXIA_TEST_DOCUMENTS.put( "jar:" + conn.getJarFileURL() + "!/" + entry.getName(), content );
}
finally
{
IOUtil.close( in );
}
}
}
else
{
// IDE projects
File testDocsDir = FileUtils.toFile( testJar ).getParentFile();
List<File> files = FileUtils.getFiles( testDocsDir, "**/*.*", FileUtils.getDefaultExcludesAsString(), true );
for ( Iterator<File> it = files.iterator(); it.hasNext();)
{
File file = new File( it.next().toString() );
if ( file.getAbsolutePath().contains( "META-INF" ) )
{
continue;
}
Reader reader = null;
if ( XmlUtil.isXml( file ))
{
reader = ReaderFactory.newXmlReader( file );
}
else
{
reader = ReaderFactory.newReader( file, "UTF-8" );
}
String content = IOUtil.toString( reader );
CACHE_DOXIA_TEST_DOCUMENTS.put( file.toURI().toString(), content );
}
}
return Collections.unmodifiableMap( CACHE_DOXIA_TEST_DOCUMENTS );
}
}