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

org.apache.oodt.commons.util.EnterpriseEntityResolver Maven / Gradle / Ivy

There is a newer version: 1.9.1
Show newest version
// Licensed to the Apache Software Foundation (ASF) under one or more contributor
// license agreements.  See the NOTICE.txt 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.

package org.apache.oodt.commons.util;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.DefaultHandler;
import java.io.InputStreamReader;

/** XML entity resolver for enterprise applications.
 *
 * This resolver attempts to retrieves entities from local sources before deferring to the
 * default parser's entity resolver.
 *
 * @author Kelly
 */
public class EnterpriseEntityResolver implements EntityResolver {
	/** Mapping of public identifiers to known file names. */
	static Map entities;

	/** Initialize the class by reading the entites.xml file. */
	static {
		entities = new HashMap();
		try {
			SAXParserFactory factory = SAXParserFactory.newInstance();
			factory.setNamespaceAware(false);
			factory.setValidating(true);
			javax.xml.parsers.SAXParser p = factory.newSAXParser();
			p.parse(new InputSource(EnterpriseEntityResolver.class.getResourceAsStream("entities.xml")),
				new DefaultHandler() {
					private StringBuffer token = new StringBuffer();
					private String pi;
					public void characters(char[] ch, int start, int length) {
						token.append(ch, start, length);
					}
					public void endElement(String ns, String name, String qual) {
						if ("pi".equals(qual))
							pi = token.toString().trim();
						else if ("filename".equals(qual)) {
							entities.put(pi, token.toString().trim());
						}
						token.delete(0, token.length());
					}
				});
		} catch (ParserConfigurationException ex) {
			throw new IllegalStateException("Unexpected ParserConfigurationException: " + ex.getMessage());
		} catch (SAXParseException ex) {
			System.err.println("Error parsing entities.xml at line " + ex.getLineNumber() + ", column "
				+ ex.getColumnNumber() + "; ignoring entity lookup");
		} catch (SAXException ex) {
			System.err.println("Exception parsing entities.xml: " + ex.getMessage() + "; ignoring entity lookup");
		} catch (IOException ex) {
			System.err.println("I/O error reading entities.xml: " + ex.getMessage() + "; ignoring entity lookup");
		}
	}

	public InputSource resolveEntity(String publicID, String systemID) throws SAXException, IOException {
		String filename = computeFilename(publicID, systemID);
		if (filename == null) return null;

		// Resolve it using class loader first.  Any DTD in the toplevel directory
		// of any jar present to the application is a potential source.
		InputStream in = getClass().getResourceAsStream("/" + filename);
		if (in != null)
			return new InputSource(new BufferedReader(new InputStreamReader(in)));

		// OK, try the filesystem next.  You can control what directories get
		// searched by setting the entity.dirs property.
		File file = findFile(getEntityRefDirs(System.getProperty("entity.dirs", "")), filename);
		if (file != null) try {
			return new InputSource(new BufferedReader(new FileReader(file)));
		} catch (IOException ignore) {}

		// No luck either way.
		return null;
	}

	/** Compute the possible filename from public and system identifiers.
	 *
	 * This attempts to map the public ID to a known file based on a table (see
	 * entity.xml).  If that doesn't work, then it will use the
	 * file part of the system ID.  If there's no file part, it returns null.
	 *
	 * @param publicID The public identifier.
	 * @param systemID The system identifier.
	 * @return A file computed from publicID and systemID.
	 */
	static String computeFilename(String publicID, String systemID) {
		String name = (String) entities.get(publicID);
		if (name == null) try {
			URL url = new URL(systemID);
			File file = new File(url.getFile());
			name = file.getName();
		} catch (MalformedURLException ignore) {}
		return name;
	}

	/**
	 * Get a list of entity directories from the given string specification.
	 *
	 * @param spec Directory names separated by commas.
	 * @return a {@link List} of those directory names.
	 */
	static List getEntityRefDirs(String spec) {
		List dirs = new ArrayList();
		for (StringTokenizer t = new StringTokenizer(spec, ",;|"); t.hasMoreTokens();)
			dirs.add(t.nextToken());
		return dirs;
	}

	/** Find a file under a list of directories.
	 * 
	 * @param dirs List of {@link java.lang.String} directory names.
	 * @param filename Name of the file to find under one of the directories named in dirs.
	 * @return The first path to the file named by filename under a directory in dirs,
	 * or null if no directory in dirs contains a file named filename.
	 */
	static File findFile(List dirs, String filename) {
		for (Iterator i = dirs.iterator(); i.hasNext();) {
			File potentialFile = new File((String) i.next(), filename);
			if (potentialFile.isFile()) return potentialFile;
		}
		return null;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy