Checking in first implementations of Database and File objects.
This commit is contained in:
parent
67f38dceb8
commit
0c2ac1d781
2 changed files with 1121 additions and 0 deletions
613
src/helma/scripting/rhino/DatabaseObject.java
Normal file
613
src/helma/scripting/rhino/DatabaseObject.java
Normal file
|
@ -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; i<numcols; i++) {
|
||||
String colName = resultSetMetaData.getColumnLabel(i+1);
|
||||
//IServer.getLogger().log("$$COL : " + colName);
|
||||
colNames.addElement(colName);
|
||||
}
|
||||
} catch(SQLException e) {
|
||||
colNames = new Vector(); // An empty one
|
||||
throw new SQLException("Could not get column names: "+e);
|
||||
|
||||
// System.err.println("##Cannot get column names: " + e);
|
||||
// e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public String getClassName() {
|
||||
return "RowSet";
|
||||
}
|
||||
|
||||
public String toDetailString() {
|
||||
return "ES:[Object: builtin " + this.getClass().getName() + ":" +
|
||||
this.toString() + "]";
|
||||
}
|
||||
|
||||
public int getColumnCount() {
|
||||
return colNames.size();
|
||||
}
|
||||
|
||||
public Object getMetaData()
|
||||
{
|
||||
return resultSetMetaData;
|
||||
}
|
||||
|
||||
public Object getLastError() {
|
||||
if (lastError == null) {
|
||||
return null;
|
||||
} else {
|
||||
return lastError;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void release() {
|
||||
try {
|
||||
if (statement!= null) statement.close();
|
||||
if (resultSet != null) resultSet.close();
|
||||
} catch (SQLException e) {
|
||||
// ignored
|
||||
}
|
||||
statement = null;
|
||||
resultSet = null;
|
||||
resultSetMetaData = null;
|
||||
}
|
||||
|
||||
public boolean hasMoreRows() {
|
||||
return !lastRowSeen; // Simplistic implementation
|
||||
}
|
||||
|
||||
public String getColumnName(int idx) throws SQLException {
|
||||
if (resultSet == null) {
|
||||
throw new SQLException("Attempt to access a released result set");
|
||||
}
|
||||
if (idx>0 && 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]")));
|
||||
}
|
||||
|
||||
}
|
508
src/helma/scripting/rhino/FileObject.java
Normal file
508
src/helma/scripting/rhino/FileObject.java
Normal file
|
@ -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<methods.length; i++) {
|
||||
if ("fileObjCtor".equals(methods[i].getName())) {
|
||||
ctorMember = methods[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
FunctionObject ctor = new FunctionObject("File", ctorMember, scope);
|
||||
ctor.addAsConstructor(scope, proto);
|
||||
String[] fileFuncs = {
|
||||
"getParent",
|
||||
"isAbsolute",
|
||||
"write",
|
||||
"remove",
|
||||
"list",
|
||||
"flush",
|
||||
"writeln",
|
||||
"close",
|
||||
"getPath",
|
||||
"open",
|
||||
"error",
|
||||
"canRead",
|
||||
"canWrite",
|
||||
"exists",
|
||||
"getAbsolutePath",
|
||||
"getLength",
|
||||
"isDirectory",
|
||||
"isFile",
|
||||
"lastModified",
|
||||
"mkdir",
|
||||
"renameTo",
|
||||
"eof",
|
||||
"isOpened",
|
||||
"readln",
|
||||
"clearError",
|
||||
"readAll"
|
||||
};
|
||||
try {
|
||||
proto.defineFunctionProperties(fileFuncs, FileObject.class, 0);
|
||||
} catch (Exception ignore) {
|
||||
System.err.println ("Error defining function properties: "+ignore);
|
||||
}
|
||||
}
|
||||
|
||||
static private Method lookupMethod(Method[] methods, String name) {
|
||||
for (int i=0; i<methods.length; i++) {
|
||||
if (name.equals(methods[i].getName())) {
|
||||
return methods[i];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getClassName() {
|
||||
return "File";
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
if (file==null) return "<null>";
|
||||
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
|
||||
|
Loading…
Add table
Reference in a new issue