/* Author: Jeff Dalton * Updated: Sat Jul 14 01:41:41 2001 by Jeff Dalton * Copyright: (c) 2000, AIAI, University of Edinburgh */ package ix.iface.domain; import java.io.FileNotFoundException; import java.io.File; import java.awt.Component; import javax.swing.*; import ix.icore.domain.Domain; import ix.util.*; /** * An object that parses a domain description to populate a Domain. */ public abstract class DomainParser { public abstract Domain readDomain(); public abstract Domain readDomain(Domain dom); /** * Returns an abstract pathname (File) that refers to the default * library of domain descriptions. This default can be set by * the "domain-library" command-line argument ot by calling the * Parameters.setParameter method. * * @see ix.util.Parameters */ public static File getLibraryDirectory() { return new File(Parameters.getParameter("domain-library", "domain-library")); } /** * Factory method that returns an appropriate parser for the * indicated file. It converts the filename to an abstract * pathname (File) and calls the makeParser(File) * method. */ public static DomainParser makeParser(String filename) throws FileNotFoundException { return makeParser(new File(filename)); } /** * Factory method that returns an appropriate parser for the * indicated file, based on the file's type or extension. * If the file does not specify a parent directory, the result * of calling getLibraryDirectory() is used.

* * Here's how it might be used: *

     *   File domainName = ...;
     *   Domain domain = ...;
     *   ...
     *   try {
     *       DomainParser.makeParser(domainName).readDomain(domain);
     *   }
     *   catch (FileNotFoundException e) { ... }
     * 
*/ public static DomainParser makeParser(File file) throws FileNotFoundException { // Factory method. // Based on file type. if (file.getParentFile() == null) { File libDir = getLibraryDirectory(); Debug.noteln("Resolving " + file + " against " + libDir); file = new File(libDir, file.getPath()); } String name = file.getName(); if (name.endsWith(".lsp")) return new LTF_Parser(file); else if (name.endsWith(".xml")) return new XMLTF_Parser(file); else throw new Error("Cannot create parser for " + file); } /** * Reads a description of a domain from a file selected by the user, * conducting all necessary dialogs along the way. It repeatedly * asks the user to select a file until either the domain description * has been successfully read or the user decices to cancel the * operation. The user is informed of any exceptions thrown while * attempting to read, and "success" means that no exceptions were * thrown. If the description has been read from a file, a * corresponding File (abstract pathname) is returned; otherwise, * the result is null.

* * The input syntax is a function of the file's type as * understood by makeParser(File).

* * Note that this method modifies an existing Domain object * rather than creating a new one. However, no modifications * occur until after the file has been completely processed * without an exception being thrown. * * @see #makeParser(File) * * @param parentComponent determines the Frame in which dialogs * are displayed. * @param domain the Domain object to modify * @return a File if the domain description has been read successfully, * otherwise null */ public static File loadDomain(Component parentComponent, Domain domain) { File libDir = DomainParser.getLibraryDirectory(); while (true) { File domainFile = chooseDomain(parentComponent, libDir); if (domainFile == null) return null; // user cancels File result = loadDomain(parentComponent, domain, domainFile); if (result != null) return result; // success! } } private static File loadDomain(Component frame, Domain domain, File domainName) { try { Domain tempDomain = new Domain(); DomainParser.makeParser(domainName).readDomain(tempDomain); domain.takeFrom(tempDomain); return domainName; } catch (FileNotFoundException e) { JOptionPane.showMessageDialog(frame, "Can't find file " + Util.quote(domainName.getPath()), "File not found", JOptionPane.ERROR_MESSAGE); return null; } } private static File chooseDomain(Component frame, File directory) { JFileChooser chooser = new JFileChooser(directory); chooser.setFileFilter(new DomainFileFilter()); int option = chooser.showOpenDialog(frame); if (option == JFileChooser.APPROVE_OPTION) return chooser.getSelectedFile(); else return null; } } // Issues: // * Should the makeParser method expect a String or a File?