Package net.percederberg.mibble

Source Code of net.percederberg.mibble.MibLoader

/*
* MibLoader.java
*
* This work is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation; either version 2 of the License,
* or (at your option) any later version.
*
* This work 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, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*
* Copyright (c) 2004-2009 Per Cederberg. All rights reserved.
*/

package net.percederberg.mibble;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URL;
import java.util.ArrayList;

import net.percederberg.grammatica.parser.ParserCreationException;
import net.percederberg.grammatica.parser.ParserLogException;

import net.percederberg.mibble.asn1.Asn1Parser;
import net.percederberg.mibble.value.ObjectIdentifierValue;

/**
* A MIB loader. This class contains a search path for locating MIB
* files, and also holds a refererence to previously loaded MIB files
* to avoid loading the same file multiple times. The MIB search path
* consists of directories with MIB files that can be imported into
* other MIBs. The search path directories can either be normal file
* system directories or resource directories. By default the search
* path contains resource directories containing standard IANA and
* IETF MIB files (packaged in the Mibble JAR file).<p>
*
* The MIB loader searches for MIB files in a specific order. First,
* the file system directories in the search path are scanned for
* files with the same name as the MIB module being imported. This
* search ignores any file name extensions and compares the base file
* name in case-insensitive mode. If this search fails, the resource
* directories are searched for a file having the exact name of the
* MIB module being imported (case sensitive). The last step, if both
* the previous ones have failed, is to open the files in the search
* path one by one to check the MIB module names specified inside.
* Note that this may be slow for large directories with many files,
* and it is therefore recommended to always name the MIB files
* according to their module name.<p>
*
* The MIB loader is not thread-safe, i.e. it cannot be used
* concurrently in multiple threads.
*
* @author   Per Cederberg, <per at percederberg dot net>
* @version  2.9
* @since    2.0
*/
public class MibLoader {

    /**
     * The MIB file directory caches. This is also a list of the MIB
     * file search path, as each directory on the path has its own
     * cache. If a MIB isn't found among these directories, the
     * resource directories will be attempted.
     */
    private ArrayList dirCaches = new ArrayList();

    /**
     * The MIB file resource directories. This is a list of Java class
     * loader resource directories to search for MIB files. These
     * directories can be used to store MIB files as resources inside
     * a JAR file.
     */
    private ArrayList resources = new ArrayList();

    /**
     * The MIB files loaded. This list contains all MIB file loaded
     * with this loader, in order to avoid loading some MIB files
     * multiple times (and thus duplicating import symbols).
     */
    private ArrayList mibs = new ArrayList();

    /**
     * The queue of MIB files to load. This queue contains either
     * MIB module names or MibSource objects.
     */
    private ArrayList queue = new ArrayList();

    /**
     * The default MIB context.
     */
    private DefaultContext context = new DefaultContext();

    /**
     * Creates a new MIB loader.
     */
    public MibLoader() {
        addResourceDir("mibs/iana");
        addResourceDir("mibs/ietf");
    }

    /**
     * Checks if a directory is in the MIB search path. If a file is
     * specified instead of a directory, this method checks if the
     * parent directory is in the MIB search path.
     *
     * @param dir            the directory or file to check
     *
     * @return true if the directory is in the MIB search path, or
     *         false otherwise
     *
     * @since 2.9
     */
    public boolean hasDir(File dir) {
        MibDirectoryCache  cache;

        if (dir == null) {
            dir = new File(".");
        } else if (!dir.isDirectory()) {
            dir = dir.getParentFile();
        }
        for (int i = 0; i < dirCaches.size(); i++) {
            cache = (MibDirectoryCache) dirCaches.get(i);
            if (cache.getDir().equals(dir)) {
                return true;
            }
        }
        return false;
    }

    /**
     * Returns all the directories in the MIB search path. If a tree
     * of directories has been added, all the individual directories
     * will be returned by this method.
     *
     * @return the directories in the MIB search path
     *
     * @since 2.9
     */
    public File[] getDirs() {
        File[]             res = new File[dirCaches.size()];
        MibDirectoryCache  cache;

        for (int i = 0; i < dirCaches.size(); i++) {
            cache = (MibDirectoryCache) dirCaches.get(i);
            res[i] = cache.getDir();
        }
        return res;
    }

    /**
     * Adds a directory to the MIB search path. If the directory
     * specified is null, the current working directory will be added.
     *
     * @param dir            the directory to add
     */
    public void addDir(File dir) {
        if (dir == null) {
            dir = new File(".");
        }
        if (!hasDir(dir)) {
            dirCaches.add(new MibDirectoryCache(dir));
        }
    }

    /**
     * Adds directories to the MIB search path.
     *
     * @param dirs           the directories to add
     */
    public void addDirs(File[] dirs) {
        for (int i = 0; i < dirs.length; i++) {
            addDir(dirs[i]);
        }
    }

    /**
     * Adds a directory and all subdirectories to the MIB search path.
     * If the directory specified is null, the current working
     * directory (and subdirectories) will be added.
     *
     * @param dir            the directory to add
     */
    public void addAllDirs(File dir) {
        File[]  files;

        if (dir == null) {
            dir = new File(".");
        }
        addDir(dir);
        files = dir.listFiles();
        for (int i = 0; i < files.length; i++) {
            if (files[i].isDirectory()) {
                addAllDirs(files[i]);
            }
        }
    }

    /**
     * Removes a directory from the MIB search path.
     *
     * @param dir            the directory to remove
     */
    public void removeDir(File dir) {
        MibDirectoryCache  cache;

        for (int i = 0; i < dirCaches.size(); i++) {
            cache = (MibDirectoryCache) dirCaches.get(i);
            if (cache.getDir().equals(dir)) {
                dirCaches.remove(i--);
            }
        }
    }

    /**
     * Removes all directories from the MIB search path.
     */
    public void removeAllDirs() {
        dirCaches.clear();
    }

    /**
     * Checks if a directory is in the MIB resource path. The
     * resource search path is used for searching for MIB files with
     * the ClassLoader (i.e. MIB files on the Java classpath) and is
     * a secondary alternative to the directory search path. Note
     * that the MIB files stored as resources must have the EXACT MIB
     * name, i.e. no file extensions can be used and name casing is
     * important.
     *
     * @param dir            the directory to check
     *
     * @return true if the directory is in the MIB resource path, or
     *         false otherwise
     *
     * @since 2.9
     */
    public boolean hasResourceDir(String dir) {
        return resources.contains(dir);
    }

    /**
     * Returns all the directories in the MIB resource path. The
     * resource search path is used for searching for MIB files with
     * the ClassLoader (i.e. MIB files on the Java classpath) and is
     * a secondary alternative to the directory search path. Note
     * that the MIB files stored as resources must have the EXACT MIB
     * name, i.e. no file extensions can be used and name casing is
     * important.
     *
     * @return the directories in the MIB resource path
     *
     * @since 2.9
     */
    public String[] getResourceDirs() {
        return (String[]) resources.toArray(new String[resources.size()]);
    }

    /**
     * Adds a directory to the MIB resource search path. The resource
     * search path is used for searching for MIB files with the
     * ClassLoader (i.e. MIB files on the Java classpath) and is a
     * secondary alternative to the directory search path. Note that
     * the MIB files stored as resources must have the EXACT MIB
     * name, i.e. no file extensions can be used and name casing is
     * important.
     *
     * @param dir            the resource directory to add
     *
     * @since 2.3
     */
    public void addResourceDir(String dir) {
        if (!hasResourceDir(dir)) {
            resources.add(dir);
        }
    }

    /**
     * Removes a directory from the MIB resource search path. The
     * resource search path can be used to load MIB files as resources
     * via the ClassLoader.
     *
     * @param dir            the resource directory to remove
     *
     * @since 2.3
     */
    public void removeResourceDir(String dir) {
        resources.remove(dir);
    }

    /**
     * Removes all directories from the MIB resource search path. This
     * will also remove the default directories where the IANA and
     * IETF MIB are present, and may thus make this MIB loader mostly
     * unusable. Use this method with caution.
     *
     * @since 2.3
     */
    public void removeAllResourceDirs() {
        resources.clear();
    }

    /**
     * Resets this loader. This means that all references to previuos
     * MIB files will be removed, forcing a reload of any imported
     * MIB.<p>
     *
     * Note that this is not the same operation as unloadAll, since
     * the MIB files previously loaded will be unaffected by this
     * this method (i.e. they remain possible to use). If the purpose
     * is to free all memory used by the loaded MIB files, use the
     * unloadAll() method instead.
     *
     * @see #unloadAll()
     */
    public void reset() {
        mibs.clear();
        queue.clear();
        context = new DefaultContext();
    }

    /**
     * Returns the default MIB context. This context contains the
     * symbols that are predefined for all MIB:s (such as 'iso').
     *
     * @return the default MIB context
     */
    public MibContext getDefaultContext() {
        return context;
    }

    /**
     * Returns the root object identifier value (OID). This OID is
     * the "iso" symbol.
     *
     * @return the root object identifier value
     *
     * @since 2.7
     */
    public ObjectIdentifierValue getRootOid() {
        MibSymbol symbol;
        MibValue  value;

        symbol = context.findSymbol(DefaultContext.ISO, false);
        value = ((MibValueSymbol) symbol).getValue();
        return (ObjectIdentifierValue) value;
    }

    /**
     * Returns a previously loaded MIB file. If the MIB file hasn't
     * been loaded, null will be returned. The MIB is identified by
     * it's MIB name (i.e. the module name).
     *
     * @param name           the MIB (module) name
     *
     * @return the MIB module if found, or
     *         null otherwise
     */
    public Mib getMib(String name) {
        Mib  mib;

        for (int i = 0; i < mibs.size(); i++) {
            mib = (Mib) mibs.get(i);
            if (mib.equals(name)) {
                return mib;
            }
        }
        return null;
    }

    /**
     * Returns a previously loaded MIB file. If the MIB file hasn't
     * been loaded, null will be returned. The MIB is identified by
     * it's file name. Note that if the file contained several MIB
     * modules, this method will only return the first one.
     *
     * @param file           the MIB file
     *
     * @return the first MIB module if found, or
     *         null otherwise
     *
     * @since 2.3
     */
    public Mib getMib(File file) {
        Mib  mib;

        for (int i = 0; i < mibs.size(); i++) {
            mib = (Mib) mibs.get(i);
            if (mib.equals(file)) {
                return mib;
            }
        }
        return null;
    }

    /**
     * Returns all previously loaded MIB files. If no MIB files have
     * been loaded an empty array will be returned.
     *
     * @return an array with all loaded MIB files
     *
     * @since 2.2
     */
    public Mib[] getAllMibs() {
        Mib[]  res;

        res = new Mib[mibs.size()];
        mibs.toArray(res);
        return res;
    }

    /**
     * Loads a MIB file with the specified base name. The file is
     * searched for in the MIB search path. The MIB is identified by
     * it's MIB name (i.e. the module name). This method will also
     * load all imported MIB:s if not previously loaded by this
     * loader. If a MIB with the same name has already been loaded, it
     * will be returned directly instead of reloading it.
     *
     * @param name           the MIB name (filename without extension)
     *
     * @return the MIB module loaded
     *
     * @throws IOException if the MIB file couldn't be found in the
     *             MIB search path
     * @throws MibLoaderException if the MIB file couldn't be loaded
     *             correctly
     */
    public Mib load(String name) throws IOException, MibLoaderException {
        MibSource  src;
        Mib        mib;

        mib = getMib(name);
        if (mib == null) {
            src = locate(name);
            if (src == null) {
                throw new FileNotFoundException("couldn't locate MIB: '" +
                                                name + "'");
            }
            mib = load(src);
        } else {
            mib.setLoaded(true);
        }
        return mib;
    }

    /**
     * Loads a MIB file. This method will also load all imported MIB:s
     * if not previously loaded by this loader. If a MIB with the same
     * file name has already been loaded, it will be returned directly
     * instead of reloading it. Note that if a file contains several
     * MIB modules, this method will only return the first one
     * (although all are loaded).
     *
     * @param file           the MIB file
     *
     * @return the first MIB module loaded
     *
     * @throws IOException if the MIB file couldn't be read
     * @throws MibLoaderException if the MIB file couldn't be loaded
     *             correctly
     */
    public Mib load(File file) throws IOException, MibLoaderException {
        Mib  mib;

        mib = getMib(file);
        if (mib == null) {
            mib = load(new MibSource(file));
        } else {
            mib.setLoaded(true);
        }
        return mib;
    }

    /**
     * Loads a MIB file from the specified URL. This method will also
     * load all imported MIB:s if not previously loaded by this
     * loader. Note that if the URL data contains several MIB modules,
     * this method will only return the first one (although all are
     * loaded).
     *
     * @param url            the URL containing the MIB
     *
     * @return the first MIB module loaded
     *
     * @throws IOException if the MIB URL couldn't be read
     * @throws MibLoaderException if the MIB file couldn't be loaded
     *             correctly
     *
     * @since 2.3
     */
    public Mib load(URL url) throws IOException, MibLoaderException {
        return load(new MibSource(url));
    }

    /**
     * Loads a MIB file from the specified input reader. This method
     * will also load all imported MIB:s if not previously loaded by
     * this loader. Note that if the input data contains several MIB
     * modules, this method will only return the first one (although
     * all are loaded).
     *
     * @param input          the input stream containing the MIB
     *
     * @return the first MIB module loaded
     *
     * @throws IOException if the input stream couldn't be read
     * @throws MibLoaderException if the MIB file couldn't be loaded
     *             correctly
     *
     * @since 2.3
     */
    public Mib load(Reader input) throws IOException, MibLoaderException {
        return load(new MibSource(input));
    }

    /**
     * Loads a MIB. This method will also load all imported MIB:s if
     * not previously loaded by this loader. Note that if the source
     * contains several MIB modules, this method will only return the
     * first one (although all are loaded).
     *
     * @param src            the MIB source
     *
     * @return the first MIB module loaded
     *
     * @throws IOException if the MIB couldn't be found
     * @throws MibLoaderException if the MIB couldn't be loaded
     *             correctly
     */
    private Mib load(MibSource src) throws IOException, MibLoaderException {

        int           position;
        MibLoaderLog  log;

        position = mibs.size();
        queue.clear();
        queue.add(src);
        log = loadQueue();
        if (log.errorCount() > 0) {
            throw new MibLoaderException(log);
        }
        return (Mib) mibs.get(position);
    }

    /**
     * Unloads a MIB. This method will remove the loader reference to
     * a previously loaded MIB if no other MIBs are depending on it.
     * This method attempts to free the memory used by the MIB, as it
     * clears both the loader and internal MIB references to the data
     * structures (thereby allowing the garbage collector to recover
     * the memory used if no other references exist). Other MIB:s
     * should be unaffected by this operation.
     *
     * @param name           the MIB name
     *
     * @throws MibLoaderException if the MIB couldn't be unloaded
     *             due to dependencies from other loaded MIBs
     *
     * @see #reset
     *
     * @since 2.3
     */
    public void unload(String name) throws MibLoaderException {
        Mib  mib;

        for (int i = 0; i < mibs.size(); i++) {
            mib = (Mib) mibs.get(i);
            if (mib.equals(name)) {
                unload(mib);
                return;
            }
        }
    }

    /**
     * Unloads a MIB. This method will remove the loader reference to
     * a previously loaded MIB if no other MIBs are depending on it.
     * This method attempts to free the memory used by the MIB, as it
     * clears both the loader and internal MIB references to the data
     * structures (thereby allowing the garbage collector to recover
     * the memory used if no other references exist). Other MIB:s
     * should be unaffected by this operation.
     *
     * @param file           the MIB file
     *
     * @throws MibLoaderException if the MIB couldn't be unloaded
     *             due to dependencies from other loaded MIBs
     *
     * @see #reset
     *
     * @since 2.3
     */
    public void unload(File file) throws MibLoaderException {
        Mib  mib;

        for (int i = 0; i < mibs.size(); i++) {
            mib = (Mib) mibs.get(i);
            if (mib.equals(file)) {
                unload(mib);
                return;
            }
        }
    }

    /**
     * Unloads a MIB. This method will remove the loader reference to
     * a previously loaded MIB if no other MIBs are depending on it.
     * This method attempts to free the memory used by the MIB, as it
     * clears both the loader and internal MIB references to the data
     * structures (thereby allowing the garbage collector to recover
     * the memory used if no other references exist). Other MIB:s
     * should be unaffected by this operation.
     *
     * @param mib            the MIB
     *
     * @throws MibLoaderException if the MIB couldn't be unloaded
     *             due to dependencies from other loaded MIBs
     *
     * @see #reset
     *
     * @since 2.3
     */
    public void unload(Mib mib) throws MibLoaderException {
        Mib[]   referers;
        String  message;
        int     pos;

        pos = mibs.indexOf(mib);
        if (pos >= 0) {
            referers = mib.getImportingMibs();
            if (referers.length > 0) {
                message = "cannot be unloaded due to reference in " +
                          referers[0];
                throw new MibLoaderException(mib.getFile(), message);
            }
            mib = (Mib) mibs.remove(pos);
            mib.clear();
        }
    }

    /**
     * Unloads all MIBs loaded by this loaded (since the last reset).
     * This method attempts to free all the memory used by the MIBs,
     * as it clears both the loader and internal MIB references to
     * the data structures (thereby allowing the garbage collector to
     * recover the memory used if no other references exist). Note
     * that no previous MIBs returned by this loader should be
     * accessed after this method has been called.<p>
     *
     * In order to just reset the MIB loader to force re-loading of
     * MIB files, use the reset() method instead which will leave the
     * MIBs unaffected.
     *
     * @see #reset()
     * @since 2.9
     */
    public void unloadAll() {
        for (int i = 0; i < mibs.size(); i++) {
            ((Mib) mibs.get(i)).clear();
        }
        reset();
    }

    /**
     * Schedules the loading of a MIB file. The file is added to the
     * queue of MIB files to be loaded, unless it is already loaded
     * or in the queue. The MIB file search is postponed until the
     * MIB is to be loaded, avoiding loading if the MIB name was
     * defined in another MIB file in the queue.
     *
     * @param name           the MIB name (filename without extension)
     */
    void scheduleLoad(String name) {
        if (getMib(name) == null && !queue.contains(name)) {
            queue.add(name);
        }
    }

    /**
     * Loads all MIB files in the loader queue. New entries may be
     * added to the queue while loading a MIB, as a result of
     * importing other MIB files. This method will either load all
     * MIB files in the queue or none (if errors were encountered).
     *
     * @return the loader log for the whole queue
     *
     * @throws IOException if the MIB file in the queue couldn't be
     *             found
     */
    private MibLoaderLog loadQueue() throws IOException {
        MibLoaderLog  log = new MibLoaderLog();
        ArrayList     processed = new ArrayList();
        boolean       loaded;
        MibSource     src;
        ArrayList     list;
        Object        obj;

        // Parse MIB files in queue
        while (queue.size() > 0) {
            try {
                loaded = false;
                obj = queue.get(0);
                if (obj instanceof MibSource) {
                    loaded = true;
                    src = (MibSource) obj;
                } else if (getMib((String) obj) == null) {
                    src = locate((String) obj);
                } else {
                    src = null;
                }
                if (src != null && getMib(src.getFile()) == null) {
                    list = src.parseMib(this, log);
                    for (int i = 0; i < list.size(); i++) {
                        ((Mib) list.get(i)).setLoaded(loaded);
                    }
                    mibs.addAll(list);
                    processed.addAll(list);
                }
            } catch (MibLoaderException e) {
                // Do nothing, errors are already in the log
            }
            queue.remove(0);
        }

        // Initialize all parsed MIB files in reverse order
        for (int i = processed.size() - 1; i >= 0; i--) {
            try {
                ((Mib) processed.get(i)).initialize();
            } catch (MibLoaderException e) {
                // Do nothing, errors are already in the log
            }
        }

        // Validate all parsed MIB files in reverse order
        for (int i = processed.size() - 1; i >= 0; i--) {
            try {
                ((Mib) processed.get(i)).validate();
            } catch (MibLoaderException e) {
                // Do nothing, errors are already in the log
            }
        }

        // Handle errors
        if (log.errorCount() > 0) {
            mibs.removeAll(processed);
        }

        return log;
    }

    /**
     * Searches for a MIB in the search path. The name specified
     * should be the MIB name. If a matching file name isn't found in
     * the directory search path, the contents in the base resource
     * path are also tested. Finally, if no MIB file has been found,
     * the files in the search path will be opened regardless of file
     * name to perform a small heuristic test for the MIB in question.
     *
     * @param name           the MIB name
     *
     * @return the MIB found, or
     *         null if no MIB was found
     */
    private MibSource locate(String name) {
        ClassLoader        loader = getClass().getClassLoader();
        MibDirectoryCache  cache;
        File               file;
        URL                url;
        int                i;

        for (i = 0; i < dirCaches.size(); i++) {
            cache = (MibDirectoryCache) dirCaches.get(i);
            file = cache.findByName(name);
            if (file != null) {
                return new MibSource(file);
            }
        }
        for (i = 0; i < resources.size(); i++) {
            url = loader.getResource(resources.get(i) + "/" + name);
            if (url != null) {
                return new MibSource(name, url);
            }
        }
        for (i = 0; i < dirCaches.size(); i++) {
            cache = (MibDirectoryCache) dirCaches.get(i);
            file = cache.findByContent(name);
            if (file != null) {
                return new MibSource(file);
            }
        }
        return null;
    }

    /**
     * A MIB input source. This class encapsulates the two different
     * ways of loacating a MIB file, either through a file or a URL.
     */
    private static class MibSource {

        /**
         * The singleton ASN.1 parser used by all MIB sources.
         */
        private static Asn1Parser parser = null;

        /**
         * The MIB file. This variable is only set if the MIB is read
         * from file, or if the MIB name is known.
         */
        private File file = null;

        /**
         * The MIB URL location. This variable is only set if the MIB
         * is read from a URL.
         */
        private URL url = null;

        /**
         * The MIB reader. This variable is only set if the MIB
         * is read from an input stream.
         */
        private Reader input = null;

        /**
         * Creates a new MIB input source. The MIB will be read from
         * the specified file.
         *
         * @param file           the file to read from
         */
        public MibSource(File file) {
            this.file = file;
        }

        /**
         * Creates a new MIB input source. The MIB will be read from
         * the specified URL.
         *
         * @param url            the URL to read from
         */
        public MibSource(URL url) {
            this.url = url;
        }

        /**
         * Creates a new MIB input source. The MIB will be read from
         * the specified URL. This method also create a default file
         * from the specified MIB name in order to improve possible
         * error messages.
         *
         * @param name           the MIB name
         * @param url            the URL to read from
         */
        public MibSource(String name, URL url) {
            this(url);
            this.file = new File(name);
        }

        /**
         * Creates a new MIB input source. The MIB will be read from
         * the specified input reader. The input reader will be closed
         * after reading the MIB.
         *
         * @param input          the input stream to read from
         */
        public MibSource(Reader input) {
            this.input = input;
        }

        /**
         * Checks if this object is equal to another. This method
         * will only return true for another mib source object with
         * the same input source.
         *
         * @param obj            the object to compare with
         *
         * @return true if the object is equal to this, or
         *         false otherwise
         */
        public boolean equals(Object obj) {
            MibSource  src;

            if (obj instanceof MibSource) {
                src = (MibSource) obj;
                if (url != null) {
                    return url.equals(src.url);
                } else if (file != null) {
                    return file.equals(src.file);
                }
            }
            return false;
        }

        /**
         * Returns the hash code value for the object. This method is
         * reimplemented to fulfil the contract of returning the same
         * hash code for objects that are considered equal.
         *
         * @return the hash code value for the object
         *
         * @since 2.6
         */
        public int hashCode() {
            if (url != null) {
                return url.hashCode();
            } else if (file != null) {
                return file.hashCode();
            } else {
                return super.hashCode();
            }
        }

        /**
         * Returns the MIB file. If the MIB is loaded from URL this
         * file does not actually exist, but is used for providing a
         * unique reference to the MIB.
         *
         * @return the MIB file
         */
        public File getFile() {
            return file;
        }

        /**
         * Parses the MIB input source and returns the MIB modules
         * found. This method will read the MIB either from file, URL
         * or input stream.
         *
         * @param loader         the MIB loader to use for imports
         * @param log            the MIB log to use for errors
         *
         * @return the list of MIB modules created
         *
         * @throws IOException if the MIB couldn't be found
         * @throws MibLoaderException if the MIB couldn't be parsed
         *             or analyzed correctly
         */
        public ArrayList parseMib(MibLoader loader, MibLoaderLog log)
            throws IOException, MibLoaderException {

            MibAnalyzer  analyzer;
            String       msg;

            // Open input stream
            if (input != null) {
                // Do nothing as input stream already setup
            } else if (url != null) {
                input = new InputStreamReader(url.openStream());
            } else {
                input = new FileReader(file);
            }

            // Parse input stream
            analyzer = new MibAnalyzer(file, loader, log);
            try {
                if (parser == null) {
                    parser = new Asn1Parser(input, analyzer);
                    parser.getTokenizer().setUseTokenList(true);
                } else {
                    parser.reset(input, analyzer);
                }
                parser.parse();
                return analyzer.getMibs();
            } catch (ParserCreationException e) {
                msg = "parser creation error in ASN.1 parser: " +
                      e.getMessage();
                log.addInternalError(file, msg);
                throw new MibLoaderException(log);
            } catch (ParserLogException e) {
                log.addAll(file, e);
                throw new MibLoaderException(log);
            } finally {
                try {
                    input.close();
                } catch (Throwable ignore) {
                    // Errors on close are ignored
                }
                analyzer.reset();
            }
        }
    }
}
TOP

Related Classes of net.percederberg.mibble.MibLoader

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.