All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.xwiki.xml.internal.LocalEntityResolver Maven / Gradle / Ivy

/*
 * See the NOTICE file distributed with this work for additional
 * information regarding copyright ownership.
 *
 * This 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 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
package org.xwiki.xml.internal;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;

import javax.inject.Inject;
import javax.inject.Singleton;

import org.slf4j.Logger;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xwiki.component.annotation.Component;
import org.xwiki.xml.EntityResolver;

/**
 * Entity resolver that resolves entities using entity files (like xhtml-symbol.ent, xhtml-special.ent, xhtml-lat1.ent)
 * located on the file system (in the classpath). This allows an XML parser that uses this entity resolver to work even
 * when there's no internet connection. It also speeds up the entity resolution.
 *
 * @version $Id: 2c91f8dbdef9aac67ff9cec8f1319da6a62fb829 $
 */
@Component
@Singleton
public class LocalEntityResolver implements EntityResolver
{
    /**
     * The logger to use for logging.
     */
    @Inject
    private Logger logger;

    /**
     * Allow the application to resolve external entities.
     * 

*

The Parser will call this method before opening any external entity except the top-level document entity * including the external DTD subset, external entities referenced within the DTD, and external entities referenced * within the document element): the application may request that the parser resolve the entity itself, that it use * an alternative URI, or that it use an entirely different input source.

*

*

Application writers can use this method to redirect external system identifiers to secure and/or local URIs, * to look up public identifiers in a catalogue, or to read an entity from a database or other input source * (including, for example, a dialog box).

*

*

If the system identifier is a URL, the SAX parser must resolve it fully before reporting it to the * application.

* * @param publicId The public identifier of the external entity being referenced, or null if none was supplied. * @param systemId The system identifier of the external entity being referenced. * @return An InputSource object describing the new input source, or null to request that the parser open a regular * URI connection to the system identifier. * @throws org.xml.sax.SAXException Any SAX exception, possibly wrapping another exception. * @throws java.io.IOException A Java-specific IO exception, possibly the result of creating a new InputStream or * Reader for the InputSource. * @see org.xml.sax.InputSource */ @Override public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException { InputSource source = null; try { URI uri = new URI(systemId); if ("http".equals(uri.getScheme()) || "file".equals(uri.getScheme())) { String filename = new File(uri.getPath()).getName(); InputStream istream = getClass().getClassLoader().getResourceAsStream(filename); if (istream != null) { source = new InputSource(istream); } else { this.logger.warn("Failed to load resource [{}] locally. " + "Will try to get it online at [{}]", filename, systemId); } } else { // As there's no scheme we'll assume that it's an already resolved systemId that is // passed. This happens when a DTD file uses a relative systemId for dependent // entity files. For example the default xhtml1-strict.dtd and // xhtml1-transitional.dtd files reference xhtml-lat1.ent, xhtml-special.ent and // xhtml1-symbol.ent relatively. Normally these relative declarations generate a // URL with a "file" scheme but apparently there are some cases when the raw // entity file names is passed to this resolveEntity method... this.logger.debug("Unknown URI scheme [{}] for entity [{}]. " + "Assuming the entity is already resolved and looking for it in the file system.", uri.getScheme(), systemId); InputStream istream = getClass().getClassLoader().getResourceAsStream(systemId); if (istream != null) { source = new InputSource(istream); } else { this.logger.warn("Failed to load resource [{}]", systemId); } } } catch (URISyntaxException e) { this.logger.warn("Invalid URI [{}]. Reason [{}]", systemId, e.getMessage()); } // Returning null causes the caller to try accessing the entity online return source; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy