/*
* Copyright (C) 2008 Laurent Caillette
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.novelang.novella;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.io.SAXReader;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.novelang.configuration.ConfigurationTools;
import org.novelang.logger.Logger;
import org.novelang.logger.LoggerFactory;
import org.novelang.outfit.loader.ClasspathResourceLoader;
import org.novelang.outfit.loader.ResourceLoader;
import org.novelang.outfit.loader.ResourceName;
/**
* @author Laurent Caillette
*/
public class VectorImageTools {
private VectorImageTools() { }
/**
* Loads a SVG document, using all official entities.
*/
public static org.dom4j.Document loadSvgAsDom4jDocument( final InputSource inputSource )
throws DocumentException
{
final SAXReader reader = new SAXReader() ;
reader.setEntityResolver( ENTITY_RESOLVER ) ;
final Document document = reader.read( inputSource ) ;
return document ;
}
/**
* This global variable is dirty.
* TODO propagate the {@code ResourceLoader} up to here.
*/
private static final ResourceLoader ENTITY_RESOURCE_LOADER =
new ClasspathResourceLoader( ConfigurationTools.BUNDLED_STYLE_DIR ) ;
private static final String SVG11_PUBLICID_PREFIX_0 = "-//W3C//DTD SVG 1.0//EN" ;
private static final String SVG11_PUBLICID_PREFIX_1 = "-//W3C//ENTITIES SVG 1.1" ;
private static final String SVG11_PUBLICID_PREFIX_2 = "-//W3C//DTD SVG 1.1" ;
private static final String SVG11_PUBLICID_PREFIX_3 = "-//W3C//ELEMENTS SVG 1.1" ;
/**
* This is the path under default {@value ConfigurationTools#BUNDLED_STYLE_DIR}.
*/
private static final String SVG_1_0_DTD_RESOURCE_PREFIX = "svg10-dtd";
/**
* This is the path under default {@value ConfigurationTools#BUNDLED_STYLE_DIR}.
*/
private static final String SVG_1_1_DTD_RESOURCE_PREFIX = "svg11-dtd";
private static final Logger LOGGER = LoggerFactory.getLogger( VectorImageTools.class );
/**
* Dirty implementation only supporting DTD for SVG 1.1 in bundled style directory.
*/
private static final EntityResolver ENTITY_RESOLVER = new EntityResolver() {
@Override
public InputSource resolveEntity( final String publicId, final String systemId ) {
if( publicId.startsWith( SVG11_PUBLICID_PREFIX_1 )
|| publicId.startsWith( SVG11_PUBLICID_PREFIX_2 )
|| publicId.startsWith( SVG11_PUBLICID_PREFIX_3 )
) {
return createInputSourceForBundledDtd( publicId, systemId, SVG_1_1_DTD_RESOURCE_PREFIX ) ;
} else if( publicId.startsWith( SVG11_PUBLICID_PREFIX_0 ) ) {
return createInputSourceForBundledDtd( publicId, systemId, SVG_1_0_DTD_RESOURCE_PREFIX ) ;
} else {
throw new IllegalArgumentException(
"Unsupported yet: public identifier='" + publicId + "', systemId='" + systemId + "'" ) ;
}
}
} ;
private static InputSource createInputSourceForBundledDtd(
final String publicId,
final String systemId,
final String dtdResourcePrefix
) {
final String dtdResourceName = systemId.substring( systemId.lastIndexOf( "/" ) + 1 ) ;
LOGGER.debug(
"Attempting to load definition for publicIdentifier='",
publicId,
"', systemIdentifier='",
systemId,
"', resourceName='",
dtdResourceName,
"'"
) ;
return new InputSource(
ENTITY_RESOURCE_LOADER.getInputStream(
new ResourceName( dtdResourcePrefix + "/" + dtdResourceName ) ) ) ;
}
}