From 0c2ac1d781d87a492c84d49d0c54abc40826560d Mon Sep 17 00:00:00 2001 From: hns Date: Thu, 12 Jun 2003 16:08:01 +0000 Subject: [PATCH] Checking in first implementations of Database and File objects. --- src/helma/scripting/rhino/DatabaseObject.java | 613 ++++++++++++++++++ src/helma/scripting/rhino/FileObject.java | 508 +++++++++++++++ 2 files changed, 1121 insertions(+) create mode 100644 src/helma/scripting/rhino/DatabaseObject.java create mode 100644 src/helma/scripting/rhino/FileObject.java diff --git a/src/helma/scripting/rhino/DatabaseObject.java b/src/helma/scripting/rhino/DatabaseObject.java new file mode 100644 index 00000000..15810088 --- /dev/null +++ b/src/helma/scripting/rhino/DatabaseObject.java @@ -0,0 +1,613 @@ +// Database.java +// FESI Copyright (c) Jean-Marc Lugrin, 1999 +// +// 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 2 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 +// Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +// Modified to use Helma database connections, Hannes Wallnöfer 2000-2003 + +package helma.scripting.rhino; + +import helma.framework.core.Application; +import helma.objectmodel.db.DbSource; +import java.util.Date; +import java.util.Enumeration; +import java.util.Vector; +import java.sql.*; + + +/** + * A Database object, representing a connection to a JDBC Driver + */ +public class DatabaseObject { + + private transient Connection connection = null; // Null if not connected + private transient DatabaseMetaData databaseMetaData = null; + private transient String driverName = null; + private transient ClassLoader driverLoader = null; + private transient Exception lastError = null; + private transient boolean driverOK = false; + + /** + * Create a new database object based on a hop data source. + * + * @param dbsource The name of the DB source + */ + + DatabaseObject(DbSource dbsource, int flag) { + try { + connection = dbsource.getConnection (); + driverName = dbsource.getDriverName (); + } catch (Exception e) { + // System.err.println("##Cannot find driver class: " + e); + // e.printStackTrace(); + lastError = e; + } + driverOK = true; + } + + /** + * Create a new database object based on a driver name, with driver on the classpath + * + * @param driverName The class name of the JDBC driver + */ + + DatabaseObject(String driverName) { + this.driverName = driverName; + try { + Class driverClass = Class.forName(driverName); + if (!Driver.class.isAssignableFrom(driverClass)) { + + // System.err.println("##Bad class " + driverClass); + lastError = new RuntimeException("Class " + driverClass + " is not a JDBC driver"); + } + driverClass.newInstance(); // may be needed by some drivers, harmless for others + } catch (ClassNotFoundException e) { + // System.err.println("##Cannot find driver class: " + e); + // e.printStackTrace(); + lastError = e; + } catch (InstantiationException e) { + + // System.err.println("##Cannot instantiate driver class: " + e); + // e.printStackTrace(); + lastError = e; + } catch (IllegalAccessException e) { + // ignore as this may happen depending on driver, it may not be severe + // for example because the instance was created at class initialization time + } + driverOK = true; + } + + + /** + * Create the database prototype object which cannot be connected + * + */ + + DatabaseObject() { + this.driverName = null; + driverOK = false; // Avoid usage of this object + } + + public String getClassName() { + return "DatabaseObject"; + } + + public String toString() { + if (driverName==null) return "[database protoype]"; + return "[Database: '" + driverName + + (driverOK ? + (connection==null ? "' - disconnected] " : " - connected]") + : " - in error]"); + } + + public String toDetailString() { + return "ES:[Object: builtin " + this.getClass().getName() + ":" + + this.toString() + "]"; + } + + public Object getLastError() { + if (lastError == null) { + return null; + } else { + return lastError; + } + } + + + /** + * Connect to the database, using the specific url, optional user name and password + * + * @param arguments The argument list + * @return true if successful, false otherwise + */ + public boolean connect(String url, String userName, String password) throws SQLException { + if (!driverOK) { + throw new SQLException("Driver not initialized properly - cannot connect"); + } + lastError = null; + try { + if (userName == null) { + connection = DriverManager.getConnection(url); + } else { + connection = DriverManager.getConnection(url,userName,password); + } + } catch(Exception e) { + // System.err.println("##Cannot connect: " + e); + // e.printStackTrace(); + lastError = e; + return false; + } + return true; + } + + + /** + * Disconnect from the database, nop if not conected + * + * @return true if successful, false if error during idsconnect + */ + public boolean disconnect() throws SQLException { + if (!driverOK) { + throw new SQLException("Driver not initialized properly - cannot disconnect"); + } + lastError = null; + if (connection != null) { + try { + connection.close(); + connection = null; + lastError = null; + } catch (SQLException e) { + // System.err.println("##Cannot disonnect: " + e); + // e.printStackTrace(); + lastError = e; + return false; + } + } + return true; + } + + public void release() { + if (driverOK) { + try { + disconnect(); + } catch (SQLException e) { + // ignored + } + } + } + + public RowSet executeRetrieval(String sql) throws SQLException { + if (connection==null) { + throw new SQLException("JDBC driver not connected"); + } + Statement statement = null; + ResultSet resultSet = null; + + try { + statement = connection.createStatement(); + resultSet = statement.executeQuery(sql); // will return true if first result is a result set + } catch(SQLException e) { + // System.err.println("##Cannot retrieve: " + e); + // e.printStackTrace(); + lastError = e; + try { + if (statement!=null) statement.close(); + } catch (Exception ignored) { + } + statement = null; + return null; + } + RowSet rowSet = new RowSet(sql, this, statement, resultSet); + return rowSet; + } + + public int executeCommand(String sql) throws SQLException { + int count = 0; + + if (connection==null) { + throw new SQLException("JDBC driver not connected"); + } + + Statement statement = null; + try { + + statement = connection.createStatement(); + count = statement.executeUpdate(sql); // will return true if first result is a result set + } catch(SQLException e) { + // System.err.println("##Cannot retrieve: " + e); + // e.printStackTrace(); + lastError = e; + try { + if (statement != null) statement.close(); + } catch (Exception ignored) { + } + statement = null; + return -1; + } + if (statement!=null) try { + statement.close(); + } catch (SQLException e) { + // ignored + } + return count; + } + + public Object getMetaData() + { + if (databaseMetaData == null) + try { + databaseMetaData = connection.getMetaData(); + } catch (SQLException e) { + // ignored + } + return databaseMetaData; + } +} + + +/** + * A RowSet object + */ +class RowSet { + + private transient DatabaseObject database = null; + private transient String sql = null; + private transient Statement statement = null; + private transient ResultSet resultSet = null; + private transient ResultSetMetaData resultSetMetaData = null; + private transient Vector colNames = null; + private transient boolean lastRowSeen = false; + private transient boolean firstRowSeen = false; + private transient Exception lastError = null; + + RowSet(String sql, + DatabaseObject database, + Statement statement, + ResultSet resultSet) throws SQLException { + this.sql = sql; + this.database = database; + this.statement = statement; + this.resultSet = resultSet; + + if (sql==null) throw new NullPointerException(); + if (resultSet==null) throw new NullPointerException(); + if (statement==null) throw new NullPointerException(); + if (database==null) throw new NullPointerException(); + + try { + + this.resultSetMetaData = resultSet.getMetaData(); + int numcols = resultSetMetaData.getColumnCount(); + //IServer.getLogger().log("$$NEXT : " + numcols); + colNames = new Vector(numcols); + for (int i=0; i0 && idx <=colNames.size()) { + return (String) colNames.elementAt(idx-1); // to base 0 + } else { + throw new SQLException("Column index (base 1) " + idx + + " out of range, max: " +colNames.size()); + } + } + + + public int getColumnDatatypeNumber(int idx) throws SQLException { + if (resultSet == null) { + throw new SQLException("Attempt to access a released result set"); + } + if (idx>0 && idx <=colNames.size()) { + try { + return resultSetMetaData.getColumnType(idx); + } catch (SQLException e) { + lastError = e; + return -1; + } + } else { + throw new SQLException("Column index (base 1) " + idx + + " out of range, max: " +colNames.size()); + } + } + + + public String getColumnDatatypeName(int idx) throws SQLException { + if (resultSet == null) { + throw new SQLException("Attempt to access a released result set"); + } + if (idx>0 && idx <=colNames.size()) { + try { + return resultSetMetaData.getColumnTypeName(idx); + } catch (SQLException e) { + lastError = e; + return null; + } + } else { + throw new SQLException("Column index (base 1) " + idx + + " out of range, max: " +colNames.size()); + } + } + + + public Object getColumnItem(String propertyName) throws SQLException { + if (resultSet == null) { + throw new SQLException("Attempt to access a released result set"); + } + if (!firstRowSeen) { + throw new SQLException("Attempt to access data before the first row is read"); + } + int hash = propertyName.hashCode(); + try { + int index = -1; // indicates not a valid index value + try { + char c = propertyName.charAt(0); + if ('0' <= c && c <= '9') { + index = Integer.parseInt(propertyName); + } + } catch (NumberFormatException e) { + } catch (StringIndexOutOfBoundsException e) { // for charAt + } + if (index>=0) { + return getProperty(index); + } + Object value = resultSet.getObject(propertyName); + // IServer.getLogger().log("&& @VALUE : " + value); + lastError = null; + return value; + } catch (SQLException e) { + //System.err.println("##Cannot get property '" + propertyName + "' " + e); + //e.printStackTrace(); + lastError = e; + } + return null; + } + + public Object getProperty(String propertyName, int hash) + throws SQLException { + //System.err.println(" &&& Getting property '" + propertyName + "'"); + + // Length property is firsy checked + + // First return system or or prototype properties + if (propertyName.equals("length")) { + return new Integer(colNames.size()); + } else { + if (resultSet == null) { + throw new SQLException("Attempt to access a released result set"); + } + if (!firstRowSeen) { + throw new SQLException("Attempt to access data before the first row is read"); + } + try { + int index = -1; // indicates not a valid index value + try { + char c = propertyName.charAt(0); + if ('0' <= c && c <= '9') { + index = Integer.parseInt(propertyName); + } + } catch (NumberFormatException e) { + } catch (StringIndexOutOfBoundsException e) { // for charAt + } + if (index>=0) { + return getProperty(index); + } + Object value = resultSet.getObject(propertyName); + // IServer.getLogger().log("&& @VALUE : " + value); + lastError = null; + return value; + } catch (SQLException e) { + // System.err.println("##Cannot get property '" + propertyName + "' " + e); + // e.printStackTrace(); + lastError = e; + } + } + return null; + } + + public Object getProperty(int index) + throws SQLException { + if (!firstRowSeen) { + throw new SQLException("Attempt to access data before the first row is read"); + } + if (resultSet == null) { + throw new SQLException("Attempt to access a released result set"); + } + + try { + Object value = resultSet.getObject(index); + lastError = null; + return value; + } catch (SQLException e) { + // System.err.println("##Cannot get property: " + e); + // e.printStackTrace(); + lastError = e; + } + return null; + } + + /* + * Returns an enumerator for the key elements of this object. + * + * @return the enumerator - may have 0 length of coulmn names where not found + */ + public Enumeration getProperties() { + if (resultSet == null) { + return (new Vector()).elements(); + } + return colNames.elements(); + } + + /** + * Get all properties (including hidden ones), for the command + * @listall of the interpreter. Include the visible properties of the + * prototype (that is the one added by the user) but not the + * hidden ones of the prototype (otherwise this would list + * all functions for any object). + * + * @return An enumeration of all properties (visible and hidden). + */ + /* public Enumeration getAllProperties() { + return new Enumeration() { + String [] specialProperties = getSpecialPropertyNames(); + int specialEnumerator = 0; + Enumeration props = getProperties(); // all of object properties + String currentKey = null; + int currentHash = 0; + boolean inside = false; // true when examing prototypes properties + public boolean hasMoreElements() { + // OK if we already checked for a property and one exists + if (currentKey != null) return true; + // Loop on special properties first + if (specialEnumerator < specialProperties.length) { + currentKey = specialProperties[specialEnumerator]; + currentHash = currentKey.hashCode(); + specialEnumerator++; + return true; + } + // loop on standard or prototype properties + while (props.hasMoreElements()) { + currentKey = (String) props.nextElement(); + currentHash = currentKey.hashCode(); + if (inside) { + try { + if (hasProperty(currentKey, currentHash)) continue; + } catch (EcmaScriptException ignore) { + } + // SHOULD CHECK IF NOT IN SPECIAL + } + return true; + } + // If prototype properties have not yet been examined, look for them + if (!inside && getPrototype() != null) { + inside = true; + props = getPrototype().getProperties(); + while (props.hasMoreElements()) { + currentKey = (String) props.nextElement(); + currentHash = currentKey.hashCode(); + try { + if (hasProperty(currentKey, currentHash)) continue; + } catch (EcmaScriptException ignore) { + } + return true; + } + } + return false; + } + public Object nextElement() { + if (hasMoreElements()) { + String key = currentKey; + currentKey = null; + return key; + } else { + throw new java.util.NoSuchElementException(); + } + } + }; + } */ + + public String[] getSpecialPropertyNames() { + String [] ns = {"length"}; + return ns; + } + + + public boolean next() throws SQLException { + boolean status = false; + if (lastRowSeen) { + throw new SQLException("Attempt to access a next row after last row has been returned"); + } + if (resultSet == null) { + throw new SQLException("Attempt to access a released result set"); + } + try { + status = resultSet.next(); + lastError = null; + } catch (SQLException e) { + // System.err.println("##Cannot do next:" + e); + // e.printStackTrace(); + lastError = e; + } + if (status) firstRowSeen = true; + else lastRowSeen = true; + return status; + } + + public String toString() { + return "[RowSet: '"+sql+"'" + + (resultSet==null ? " - released]" : + (lastRowSeen ? " - at end]" : + (firstRowSeen ? "]" : " - at start]"))); + } + +} diff --git a/src/helma/scripting/rhino/FileObject.java b/src/helma/scripting/rhino/FileObject.java new file mode 100644 index 00000000..ae40190d --- /dev/null +++ b/src/helma/scripting/rhino/FileObject.java @@ -0,0 +1,508 @@ +// FileIO.java +// FESI Copyright (c) Jean-Marc Lugrin, 1999 +// +// 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 2 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 +// Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package helma.scripting.rhino; + + +import java.io.BufferedReader; +import java.io.File; +import java.io.Reader; +import java.io.Writer; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.PrintWriter; +import java.io.EOFException; +import java.io.IOException; +import java.util.Date; +import org.mozilla.javascript.Context; +import org.mozilla.javascript.Function; +import org.mozilla.javascript.FunctionObject; +import org.mozilla.javascript.Scriptable; +import org.mozilla.javascript.ScriptableObject; +import org.mozilla.javascript.PropertyException; +import org.mozilla.javascript.Undefined; +import java.lang.reflect.Member; +import java.lang.reflect.Method; + +/** + * An EcmaScript FileIO 'File' object + */ +public class FileObject extends ScriptableObject { + File file = null; + Object readerWriter = null; + boolean atEOF = false; + String lastLine = null; + Throwable lastError = null; + + protected FileObject() { + } + + protected FileObject(String fileName) { + file = new File(fileName); + } + + protected FileObject(String pathName, String fileName) { + file = new File(pathName, fileName); + } + + public static FileObject fileObjCtor(Context cx, Object[] args, + Function ctorObj, boolean inNewExpr) { + if (args.length == 0 || args[0] == Undefined.instance) { + throw new IllegalArgumentException("File constructor called without argument"); + } + if (args.length < 2 || args[1] == Undefined.instance) { + return new FileObject(args[0].toString()); + } + return new FileObject(args[0].toString(), args[1].toString()); + } + + public static void init(Scriptable scope) { + Method[] methods = FileObject.class.getDeclaredMethods(); + ScriptableObject proto = new FileObject(); + proto.setPrototype(getObjectPrototype(scope)); + Member ctorMember = null; + for (int i=0; i"; + return file.toString(); + } + + public String toDetailString() { + return "ES:[Object: builtin " + this.getClass().getName() + ":" + + ((file == null) ? "null" : file.toString()) + "]"; + } + + protected void setError(Throwable e) { + lastError = e; + } + + public boolean exists() { + if (file == null) return false; + return file.exists(); + } + + public boolean open() { + if (readerWriter != null) { + setError(new IllegalStateException("File already open")); + return false; + } + if (file == null) { + setError(new IllegalArgumentException("Uninitialized File object")); + return false; + } + + // We assume that the BufferedReader and PrintWriter creation + // cannot fail except if the FileReader/FileWriter fails. + // Otherwise we have an open file until the reader/writer + // get garbage collected. + try{ + if (file.exists()) { + readerWriter = new BufferedReader(new FileReader(file)); + } else { + readerWriter = new PrintWriter(new FileWriter(file)); + } + return true; + } catch (IOException e) { + setError(e); + return false; + } + } + + public boolean isOpened() { + return (readerWriter != null); + } + + public boolean close() { + if (readerWriter == null) + return false; + try { + if (readerWriter instanceof Reader) { + ((Reader) readerWriter).close(); + } else { + ((Writer) readerWriter).close(); + } + readerWriter = null; + return true; + } catch (IOException e) { + setError(e); + readerWriter = null; + return false; + } + } + + public boolean write(Object what) { + if (readerWriter == null) { + setError(new IllegalStateException("File not opened")); + return false; + } + if (! (readerWriter instanceof PrintWriter)) { + setError(new IllegalStateException("File not opened for writing")); + return false; + } + PrintWriter writer = (PrintWriter) readerWriter; + if (what != null) { + writer.print(what.toString()); + } + // writer.println(); + return true; + } + + public boolean writeln(Object what) { + if (readerWriter == null) { + setError(new IllegalStateException("File not opened")); + return false; + } + if (! (readerWriter instanceof PrintWriter)) { + setError(new IllegalStateException("File not opened for writing")); + return false; + } + PrintWriter writer = (PrintWriter) readerWriter; + if (what != null) { + writer.print(what.toString()); + } + writer.println(); + return true; + } + + public String readln() { + if (readerWriter == null) { + setError(new IllegalStateException("File not opened")); + return null; + } + if (! (readerWriter instanceof BufferedReader)) { + setError(new IllegalStateException("File not opened for reading")); + return null; + } + if (atEOF) { + setError(new EOFException()); + return null; + } + if (lastLine!=null) { + String line = lastLine; + lastLine = null; + return line; + } + BufferedReader reader = (BufferedReader) readerWriter; + // Here lastLine is null, return a new line + try { + String line = reader.readLine(); + if (line == null) { + atEOF = true; + setError(new EOFException()); + } + return line; + } catch (IOException e) { + setError(e); + return null; + } + } + + public boolean eof() { + if (readerWriter == null) { + setError(new IllegalStateException("File not opened")); + return true; + } + if (! (readerWriter instanceof BufferedReader)) { + setError(new IllegalStateException("File not opened for read")); + return true; + } + if (atEOF) return true; + if (lastLine!=null) return false; + BufferedReader reader = (BufferedReader) readerWriter; + try { + lastLine = reader.readLine(); + if (lastLine == null) atEOF = true; + return atEOF; + } catch (IOException e) { + setError(e); + return true; + } + } + + public boolean isFile() { + if (file == null) { + setError(new IllegalArgumentException("Uninitialized File object")); + return false; + } + return file.isFile(); + } + + public boolean isDirectory() { + if (file == null) { + setError(new IllegalArgumentException("Uninitialized File object")); + return false; + } + return file.isDirectory(); + } + + public boolean flush() { + if (readerWriter == null) { + setError(new IllegalStateException("File not opened")); + return false; + } + if (readerWriter instanceof Writer) { + try { + ((Writer) readerWriter).flush(); + } catch (IOException e) { + setError(e); + return false; + } + } else { + setError(new IllegalStateException("File not opened for write")); + return false; // not supported by reader + } + return true; + } + + + public long getLength() { + if (file == null) { + setError(new IllegalArgumentException("Uninitialized File object")); + return -1; + } + return file.length(); + } + + public long lastModified() { + if (file == null) { + setError(new IllegalArgumentException("Uninitialized File object")); + return 0L; + } + return file.lastModified(); + } + + public String error() { + if (lastError == null) { + return ""; + } else { + String exceptionName = lastError.getClass().getName(); + int l = exceptionName.lastIndexOf("."); + if (l>0) exceptionName = exceptionName.substring(l+1); + return exceptionName +": " + lastError.getMessage(); + } + } + + public void clearError() { + lastError = null; + } + + public boolean remove() { + if (file == null) { + setError(new IllegalArgumentException("Uninitialized File object")); + return false; + } + if (readerWriter != null) { + setError(new IllegalStateException("An openened file cannot be removed")); + return false; + } + return file.delete(); + } + + public boolean renameTo(FileObject toFile) { + if (file == null) { + setError(new IllegalArgumentException("Uninitialized source File object")); + return false; + } + if (toFile.file == null) { + setError(new IllegalArgumentException("Uninitialized target File object")); + return false; + } + if (readerWriter != null) { + setError(new IllegalStateException("An openened file cannot be renamed")); + return false; + } + if (toFile.readerWriter!=null) { + setError(new IllegalStateException("You cannot rename to an openened file")); + return false; + } + return file.renameTo(toFile.file); + } + + public boolean canRead() { + if (file == null) { + setError(new IllegalArgumentException("Uninitialized File object")); + return false; + } + return file.canRead(); + } + + public boolean canWrite() { + if (file == null) { + setError(new IllegalArgumentException("Uninitialized File object")); + return false; + } + return file.canWrite(); + } + + public String getParent() { + if (file == null) { + setError(new IllegalArgumentException("Uninitialized File object")); + return ""; + } + String parent = file.getParent(); + return (parent==null ? "" : parent); + } + + public String getName() { + if (file == null) { + setError(new IllegalArgumentException("Uninitialized File object")); + return ""; + } + String name = file.getName(); + return (name==null ? "" : name); + } + + public String getPath() { + if (file == null) { + setError(new IllegalArgumentException("Uninitialized File object")); + return ""; + } + String path = file.getPath(); + return (path==null ? "" : path); + } + + public String getAbsolutePath() { + if (file == null) { + setError(new IllegalArgumentException("Uninitialized File object")); + return ""; + } + String absolutPath = file.getAbsolutePath(); + return (absolutPath==null ? "" : absolutPath); + } + + public boolean isAbsolute() { + if (file == null) return false; + return file.isAbsolute(); + } + + public boolean mkdir() { + if (file == null) return false; + if(readerWriter != null) return false; + return file.mkdirs(); // Using multi directory version + } + + public String [] list() { + if (file == null) return null; + if(readerWriter != null) return null; + if (!file.isDirectory()) return null; + return file.list(); + } + + + public String readAll() { + // Open the file for readAll + if (readerWriter != null) { + setError(new IllegalStateException("File already open")); + return null; + } + if (file == null) { + setError(new IllegalArgumentException("Uninitialized File object")); + return null; + } + try{ + if (file.exists()) { + readerWriter = new BufferedReader(new FileReader(file)); + } else { + setError(new IllegalStateException("File does not exist")); + return null; + } + if(!file.isFile()) { + setError(new IllegalStateException("File is not a regular file")); + return null; + } + + // read content line by line to setup properl eol + StringBuffer buffer = new StringBuffer((int) (file.length()*1.10)); + BufferedReader reader = (BufferedReader) readerWriter; + while (true) { + String line = reader.readLine(); + if (line == null) { + break; + } + buffer.append(line); + buffer.append("\n"); // EcmaScript EOL + } + + + // Close the file + ((Reader) readerWriter).close(); + readerWriter = null; + return buffer.toString(); + } catch (IOException e) { + readerWriter = null; + setError(e); + return null; + } + } + +} //class FileObject +