001: /*
002: * $Id: IOModule.java,v 1.25 2002/09/16 08:05:02 jkl Exp $
003: *
004: * Copyright (c) 2002 Njet Communications Ltd. All Rights Reserved.
005: *
006: * Use is subject to license terms, as defined in
007: * Anvil Sofware License, Version 1.1. See LICENSE
008: * file, or http://njet.org/license-1.1.txt
009: */
010: package anvil.core.io;
011:
012: import anvil.core.Any;
013: import anvil.core.AnyString;
014: import anvil.core.AnyUtils;
015: import anvil.core.Array;
016: import anvil.core.AnyList;
017: import anvil.core.Serialization;
018: import anvil.core.UnserializationException;
019: import anvil.script.Context;
020: import anvil.java.util.BindingEnumeration;
021: import java.io.BufferedReader;
022: import java.io.File;
023: import java.io.FileInputStream;
024: import java.io.FileOutputStream;
025: import java.io.FileReader;
026: import java.io.InputStream;
027: import java.io.IOException;
028:
029: /// @module anvil.io
030: /// Provides for system input and output through data streams,
031: /// serialization and the file system.
032: ///
033: public class IOModule {
034:
035: /// @const separator
036: /// The system-dependent path-separator character.
037: public static final Any separator = new AnyString(File.separator);
038:
039: /// @const pathSeparator
040: /// The system-dependent default name-separator character.
041: public static final Any pathSeparator = new AnyString(
042: File.pathSeparator);
043:
044: /// @function load
045: /// Loads serialized data from file.
046: /// @synopsis object load(File file)
047: /// @synopsis object load(string file)
048: /// @param file File to load from
049: /// @throws CorruptedSerialization If serialized data is corrupted.
050: /// @throws IOError If an I/O error occurs
051: public static final Object[] p_load = { null, "file" };
052:
053: public static final Any load(Context context, Any file) {
054: try {
055: File source = toFile(file);
056: context.checkRead(source.getPath());
057: FileInputStream in = new FileInputStream(source);
058: Any struct = Serialization.unserialize(context, in);
059: in.close();
060: return struct;
061: } catch (UnserializationException e) {
062: throw context.CorruptedSerialization();
063: } catch (IOException e) {
064: throw context.exception(e);
065: }
066: }
067:
068: /// @function save
069: /// Serializes data to file.
070: /// @synopsis boolean save(File file, object data)
071: /// @synopsis boolean save(string file, object data)
072: /// @param file Filename to save to
073: /// @param data Data to serialize
074: /// @throws IOError If an I/O error occurs
075: public static final Object[] p_save = { null, "file", "struct" };
076:
077: public static final Any save(Context context, Any file, Any struct) {
078: try {
079: File source = toFile(file);
080: context.checkWrite(source.getPath());
081: FileOutputStream out = new FileOutputStream(source);
082: Serialization.serialize(context, struct, out);
083: out.close();
084: return Any.TRUE;
085: } catch (IOException e) {
086: throw context.exception(e);
087: }
088: }
089:
090: private static String[] toStringArray(Array list) {
091: int n = list.size();
092: String[] array = new String[n];
093: int i = 0;
094: BindingEnumeration e = list.keysAndElements();
095: while (e.hasMoreElements()) {
096: array[i++] = e.nextKey().toString() + "="
097: + e.nextElement().toString();
098: }
099: return array;
100: }
101:
102: static final String toPathname(Any f) {
103: if (f == null) {
104: return null;
105: }
106: if (f instanceof AnyFile) {
107: return ((File) f.toObject()).getAbsolutePath();
108: } else {
109: return f.toString();
110: }
111: }
112:
113: private static final File toFile(Any f) {
114: if (f == null) {
115: return null;
116: }
117: if (f instanceof AnyFile) {
118: return (File) f.toObject();
119: } else {
120: return new File(f.toString());
121: }
122: }
123:
124: /// @function listRoots
125: /// Lists all the file system roots of the system.
126: /// @synopsis list listRoots()
127: /// @return List of Files
128: public static final Any listRoots() {
129: File[] list = File.listRoots();
130: if (list == null) {
131: return Any.NULL;
132: }
133: int n = list.length;
134: Any[] files = new Any[n];
135: for (int i = 0; i < n; i++) {
136: files[i] = Any.create(list[i]);
137: }
138: return new AnyList(files);
139: }
140:
141: /// @function createTempFile
142: /// Creates temporary file with given 'prefix' and 'suffix' to optional
143: /// 'path'. If path is omitted system's default temporary directory is used.
144: /// @synopsis File createTempFile(string prefix, string suffix)
145: /// @synopsis File createTempFile(string prefix, string suffix, File path)
146: /// @synopsis File createTempFile(string prefix, string suffix, string path)
147: /// @param prefix Prefix of created file
148: /// @param suffix Suffix of create file
149: /// @param path Path into which the file is created
150: /// @return Temporary file
151: /// @throws IOError If an I/O error occurs
152: public static final Object[] p_createTempFile = { "prefix",
153: "suffix", "*path", null };
154:
155: public static final Any createTempFile(Context context,
156: String prefix, String suffix, Any path) {
157: File file = null;
158: if (path != null) {
159: if (path instanceof AnyFile) {
160: file = (File) path.toObject();
161: } else {
162: file = new File(path.toString());
163: }
164: context.checkWrite(file.getPath());
165: }
166: try {
167: if (file != null) {
168: return new AnyFile(File.createTempFile(prefix, suffix,
169: file));
170: } else {
171: return new AnyFile(File.createTempFile(prefix, suffix));
172: }
173: } catch (IOException e) {
174: throw context.exception(e);
175: }
176: }
177:
178: /// @function readText
179: /// Reads the contents of a file into a text string.
180: /// @synopsis string readText(File file)
181: /// @synopsis string readText(string file)
182: /// @param file File to read
183: /// @throws IOError If an I/O error occurs
184: public static final Object[] p_readText = { "file" };
185:
186: public static final Any readText(Context context, Any file) {
187: try {
188: File source = toFile(file);
189: context.checkRead(source.getPath());
190: BufferedReader reader = new BufferedReader(new FileReader(
191: source));
192: StringBuffer buf = new StringBuffer();
193: String line;
194: while (true) {
195: line = reader.readLine();
196: if (line == null) {
197: break;
198: }
199: buf.append(line);
200: buf.append('\n');
201: }
202: reader.close();
203: return Any.create(buf.toString());
204: } catch (IOException e) {
205: throw context.exception(e);
206: }
207:
208: }
209:
210: private static final int RETURN_PROCESS = 0;
211: private static final int PASSTHRU_AND_RETURN_EXIT_VALUE = 1;
212:
213: private static final Any doExec(Context context, Any cmd, Any env,
214: int action) {
215: String[] cmdarray;
216: String[] envarray = null;
217:
218: cmdarray = AnyUtils.toStringArray(cmd);
219: if (cmdarray.length > 0) {
220: context.checkExec(cmdarray[0]);
221: }
222:
223: if (env != null) {
224: if (env.isArray()) {
225: envarray = toStringArray(env.toArray());
226: } else {
227: envarray = AnyUtils.toStringArray(env);
228: }
229: }
230:
231: try {
232: Process process = Runtime.getRuntime().exec(cmdarray,
233: envarray);
234:
235: switch (action) {
236: case RETURN_PROCESS:
237: return new AnyProcess(process);
238:
239: /*case WAIT_AND_RETURN_EXIT_VALUE:
240: for(;;) {
241: try {
242: process.waitFor();
243: break;
244: } catch (InterruptedException e) {
245: }
246: }
247: return Any.create(process.exitValue());*/
248:
249: case PASSTHRU_AND_RETURN_EXIT_VALUE:
250: byte[] buffer = new byte[512];
251: InputStream input = process.getInputStream();
252: for (;;) {
253: int read = input.read(buffer, 0, 512);
254: if (read == -1) {
255: break;
256: }
257: if (read > 0) {
258: context.print(buffer, 0, read);
259: }
260: }
261: for (;;) {
262: try {
263: process.waitFor();
264: break;
265: } catch (InterruptedException e) {
266: }
267: }
268: return Any.create(process.exitValue());
269:
270: default:
271: return Any.NULL;
272: }
273:
274: } catch (IOException e) {
275: throw context.exception(e);
276: }
277: }
278:
279: /// @function exec
280: /// Executes given command and return process datatype.
281: /// @synopsis Process exec(sequence arguments)
282: /// @synopsis Process exec(sequence arguments, array environment)
283: /// @param arguments Sequence of arguments
284: /// @param environment Process environment
285: /// @return a process datatype
286: public static final Object[] p_exec = { null, "command",
287: "*environment", null };
288:
289: public static final Any exec(Context context, Any cmd, Any env) {
290: return doExec(context, cmd, env, RETURN_PROCESS);
291: }
292:
293: /// @function passthru
294: /// Executes given command and prints its output.
295: /// @synopsis int passthru(sequence arguments)
296: /// @synopsis int passthru(sequence arguments, array environment)
297: /// @param arguments Sequence of arguments
298: /// @param environment Process environment
299: /// @return the exit value returned by the command
300: public static final Object[] p_passthru = { null, "command",
301: "*environment", null };
302:
303: public static final Any passthru(Context context, Any cmd, Any env) {
304: return doExec(context, cmd, env, PASSTHRU_AND_RETURN_EXIT_VALUE);
305: }
306:
307: public static final anvil.script.compiler.NativeNamespace __module__ = new anvil.script.compiler.NativeNamespace(
308: "io", IOModule.class,
309: new Class[] { AnyFile.class, AnyInputStream.class,
310: AnyOutputStream.class, AnyProcess.class,
311: AnyFile.class,
312: anvil.core.Throwables.IOError.EndOfFile.class,
313: anvil.core.Throwables.IOError.FileNotFound.class,
314: anvil.core.Throwables.IOError.InterruptedIO.class,
315: anvil.core.Throwables.IOError.SyncFailed.class,
316: anvil.core.Throwables.IOError.class, },
317: //DOC{{
318: ""
319: + " @module anvil.io\n"
320: + " Provides for system input and output through data streams, \n"
321: + " serialization and the file system. \n"
322: + "\n"
323: + " @const separator\n"
324: + " The system-dependent path-separator character.\n"
325: + " @const pathSeparator\n"
326: + " The system-dependent default name-separator character.\n"
327: + " @function load\n"
328: + " Loads serialized data from file.\n"
329: + " @synopsis object load(File file)\n"
330: + " @synopsis object load(string file)\n"
331: + " @param file File to load from\n"
332: + " @throws CorruptedSerialization If serialized data is corrupted.\n"
333: + " @throws IOError If an I/O error occurs\n"
334: + " @function save\n"
335: + " Serializes data to file.\n"
336: + " @synopsis boolean save(File file, object data)\n"
337: + " @synopsis boolean save(string file, object data)\n"
338: + " @param file Filename to save to\n"
339: + " @param data Data to serialize\n"
340: + " @throws IOError If an I/O error occurs\n"
341: + " @function listRoots\n"
342: + " Lists all the file system roots of the system.\n"
343: + " @synopsis list listRoots()\n"
344: + " @return List of Files\n"
345: + " @function createTempFile \n"
346: + " Creates temporary file with given 'prefix' and 'suffix' to optional\n"
347: + " 'path'. If path is omitted system's default temporary directory is used.\n"
348: + " @synopsis File createTempFile(string prefix, string suffix)\n"
349: + " @synopsis File createTempFile(string prefix, string suffix, File path)\n"
350: + " @synopsis File createTempFile(string prefix, string suffix, string path)\n"
351: + " @param prefix Prefix of created file\n"
352: + " @param suffix Suffix of create file\n"
353: + " @param path Path into which the file is created\n"
354: + " @return Temporary file\n"
355: + " @throws IOError If an I/O error occurs\n"
356: + " @function readText\n"
357: + " Reads the contents of a file into a text string.\n"
358: + " @synopsis string readText(File file)\n"
359: + " @synopsis string readText(string file)\n"
360: + " @param file File to read\n"
361: + " @throws IOError If an I/O error occurs\n"
362: + " @function exec\n"
363: + " Executes given command and return process datatype.\n"
364: + " @synopsis Process exec(sequence arguments)\n"
365: + " @synopsis Process exec(sequence arguments, array environment)\n"
366: + " @param arguments Sequence of arguments\n"
367: + " @param environment Process environment \n"
368: + " @return a process datatype\n"
369: + " @function passthru\n"
370: + " Executes given command and prints its output. \n"
371: + " @synopsis int passthru(sequence arguments)\n"
372: + " @synopsis int passthru(sequence arguments, array environment)\n"
373: + " @param arguments Sequence of arguments\n"
374: + " @param environment Process environment \n"
375: + " @return the exit value returned by the command\n"
376: //}}DOC
377: );
378:
379: }
|