0001: /*
0002: * $Id: Context.java,v 1.102 2002/09/16 08:05:03 jkl Exp $
0003: *
0004: * Copyright (c) 2002 Njet Communications Ltd. All Rights Reserved.
0005: *
0006: * Use is subject to license terms, as defined in
0007: * Anvil Sofware License, Version 1.1. See LICENSE
0008: * file, or http://njet.org/license-1.1.txt
0009: */
0010: package anvil.script;
0011:
0012: import anvil.Log;
0013: import anvil.ErrorListener;
0014: import anvil.core.Any;
0015: import anvil.core.Any.Op;
0016: import anvil.core.AnyList;
0017: import anvil.core.AnyString;
0018: import anvil.core.AnyClass;
0019: import anvil.core.Array;
0020: import anvil.core.ObjectPool;
0021: import anvil.core.AnyThrowable;
0022: import anvil.core.Modules;
0023: import anvil.core.runtime.AnyFunction;
0024: import anvil.core.runtime.AnyNamespace;
0025: import anvil.core.runtime.AnyScope;
0026: import anvil.core.runtime.AnyStackTraceElement;
0027: import anvil.core.reflect.Reflection;
0028: import anvil.core.Register;
0029: import anvil.ErrorEvent;
0030: import anvil.ErrorListener;
0031: import anvil.ErrorListenerImpl;
0032: import anvil.ForgingException;
0033: import anvil.Location;
0034: import anvil.server.Citizen;
0035: import anvil.server.Zone;
0036: import anvil.server.Address;
0037: import anvil.server.Server;
0038: import anvil.server.LocalizationPreferences;
0039: import anvil.java.util.BindingEnumeration;
0040: import java.io.IOException;
0041: import java.io.OutputStream;
0042: import java.io.PrintStream;
0043: import java.net.URL;
0044: import java.util.Enumeration;
0045: import java.util.Locale;
0046: import java.util.Stack;
0047: import java.util.TimeZone;
0048: import java.util.Map;
0049: import java.util.WeakHashMap;
0050: import java.util.HashSet;
0051: import java.util.Iterator;
0052: import java.security.Permission;
0053: import java.security.PermissionCollection;
0054: import org.apache.oro.text.regex.MalformedPatternException;
0055: import org.apache.oro.text.regex.Perl5Matcher;
0056: import org.apache.oro.text.regex.Pattern;
0057: import anvil.core.Throwables;
0058:
0059: public final class Context extends StackFrameStack implements Namespace {
0060:
0061: public static final byte[] NEWLINE = new byte[] { (byte) '\n' };
0062:
0063: public static final String GLOBAL = "global";
0064: public static final String MODULE = "module";
0065:
0066: public static final NamespaceType TYPE = new NamespaceType() {
0067:
0068: public String getName() {
0069: return GLOBAL;
0070: }
0071:
0072: public String getQualifiedName() {
0073: return GLOBAL;
0074: }
0075:
0076: public int getType() {
0077: return Type.GLOBAL_NAMESPACE;
0078: }
0079:
0080: public Scope getParent() {
0081: return null;
0082: }
0083:
0084: public anvil.doc.Doc getDocument() {
0085: return null;
0086: }
0087:
0088: public int getTypeRef(anvil.codec.ConstantPool pool) {
0089: return 0;
0090: }
0091:
0092: public Namespace getNamespace() {
0093: return null;
0094: }
0095:
0096: };
0097:
0098: private Zone _zone;
0099: private boolean _hasPolicy = false;
0100: private Citizen _citizen;
0101: private Thread _thread;
0102: private Modules _modules;
0103: private Namespace _globals;
0104: private OutputStream _output = null;
0105: private Stack _outputStack = new Stack();
0106: private Locale _locale;
0107: private String _language;
0108: private TimeZone _timezone;
0109: private AnyNamespace _global;
0110:
0111: private static WeakHashMap _context = new WeakHashMap();
0112:
0113: public static final Context getInstance() {
0114: synchronized (_context) {
0115: Stack stack = (Stack) _context.get(Thread.currentThread());
0116: if (stack == null || stack.isEmpty()) {
0117: throw new RuntimeException(
0118: "Context is missing for thread: "
0119: + Thread.currentThread());
0120: }
0121: return (Context) stack.peek();
0122: }
0123: }
0124:
0125: public static final void dumpStacks(PrintStream out) {
0126: synchronized (_context) {
0127: Iterator iter = _context.entrySet().iterator();
0128: while (iter.hasNext()) {
0129: Map.Entry entry = (Map.Entry) iter.next();
0130: Thread thread = (Thread) entry.getKey();
0131: Stack stack = (Stack) entry.getValue();
0132: out.println("----------- " + thread + " ---------");
0133: if (stack != null) {
0134: int i = stack.size() - 1;
0135: while (i >= 0) {
0136: Context ctx = (Context) stack.get(i);
0137: if (ctx != null) {
0138: int j = ctx.size() - 1;
0139: while (j >= 0) {
0140: StackFrame frame = ctx.peek(j--);
0141: if (frame != null) {
0142: Function function = frame
0143: .getFunction();
0144: String path = frame.getPathinfo();
0145: if (function != null
0146: && path != null) {
0147: out.print(function);
0148: out.print(" [");
0149: out.print(path);
0150: int line = frame.getLine();
0151: if (line > 0) {
0152: out.print(": ");
0153: out.print(line);
0154: }
0155: out.println("]");
0156: }
0157: }
0158: }
0159: out.println();
0160: }
0161: i--;
0162: }
0163: out.println();
0164: }
0165: }
0166: }
0167: }
0168:
0169: public static final Context getExistingInstance() {
0170: synchronized (_context) {
0171: Stack stack = (Stack) _context.get(Thread.currentThread());
0172: if (stack == null || stack.isEmpty()) {
0173: return null;
0174: } else {
0175: return (Context) stack.peek();
0176: }
0177: }
0178: }
0179:
0180: public static final Context getInstance(Zone zone) {
0181: synchronized (_context) {
0182: Thread thread = Thread.currentThread();
0183: Stack stack = (Stack) _context.get(thread);
0184: if (stack == null || stack.isEmpty()) {
0185: Context context = new Context(zone);
0186: putInstance(thread, context);
0187: return context;
0188: }
0189: return (Context) stack.peek();
0190: }
0191: }
0192:
0193: public static final Context getInstance(Thread thread) {
0194: synchronized (_context) {
0195: Stack stack = (Stack) _context.get(thread);
0196: if (stack == null || stack.isEmpty()) {
0197: throw new RuntimeException(
0198: "Context is missing for thread: " + thread);
0199: }
0200: return (Context) stack.peek();
0201: }
0202: }
0203:
0204: public static final void putInstance(Thread thread, Context context) {
0205: synchronized (_context) {
0206: Stack stack = (Stack) _context.get(thread);
0207: if (stack == null) {
0208: _context.put(thread, stack = new Stack());
0209: }
0210: stack.push(context);
0211: }
0212: }
0213:
0214: public static final void destroyInstance(Thread thread) {
0215: synchronized (_context) {
0216: Stack stack = (Stack) _context.get(thread);
0217: if (stack != null && !stack.isEmpty()) {
0218: Context ctx = (Context) stack.pop();
0219: }
0220: }
0221: }
0222:
0223: public Context(Zone zone) {
0224: this (Thread.currentThread(), zone, null, new NamespaceImpl());
0225: }
0226:
0227: public Context(Thread thread, Zone zone, Citizen citizen,
0228: Namespace globals) {
0229: _thread = thread;
0230: _zone = zone;
0231: _hasPolicy = zone.getDomain().hasPolicy();
0232: if (citizen != null) {
0233: if (citizen.getCombinedPermissions() != null) {
0234: _hasPolicy = true;
0235: }
0236: }
0237: _citizen = citizen;
0238: _modules = zone.getModules();
0239: _globals = globals;
0240: _global = new AnyNamespace(this );
0241: LocalizationPreferences prefs = zone
0242: .getLocalizationPreferences();
0243: _language = prefs.getLanguage();
0244: _locale = prefs.getLocaleInstance();
0245: _timezone = prefs.getTimezoneInstance();
0246: if (thread != null) {
0247: putInstance(thread, this );
0248: }
0249: }
0250:
0251: public final void join(Thread thread) {
0252: putInstance(thread, this );
0253: }
0254:
0255: public final Context copy(Thread thread) {
0256: Context ctx = new Context(thread, _zone, _citizen,
0257: new NamespaceImpl());
0258: ctx._locale = _locale;
0259: ctx._language = _language;
0260: ctx._timezone = _timezone;
0261: return ctx;
0262: }
0263:
0264: public void destroy() {
0265: destroyInstance(_thread);
0266: _zone = null;
0267: _thread = null;
0268: _modules = null;
0269: _globals = null;
0270: _output = null;
0271: _outputStack.clear();
0272: _outputStack = null;
0273: _locale = null;
0274: _language = null;
0275: _timezone = null;
0276: _global = null;
0277: }
0278:
0279: public final Modules getModules() {
0280: return _modules;
0281: }
0282:
0283: /* exceptions */
0284:
0285: public final Location getCurrentLocation() {
0286: return new Location(address().getURL(), _frame.getLine(), 0);
0287: }
0288:
0289: public final AnyList getStackTrace() {
0290: int n = size();
0291: Any[] trace = new Any[n];
0292: int c = 0;
0293: for (int i = n - 1; i >= 0; i--) {
0294: trace[c++] = new AnyStackTraceElement(peek(i));
0295: }
0296: return new AnyList(trace);
0297: }
0298:
0299: public final ScriptException exception(Any data) {
0300: return new ScriptException(data);
0301: }
0302:
0303: /* stack frame */
0304:
0305: public final StackFrame frame() {
0306: return _frame;
0307: }
0308:
0309: public final Function function() {
0310: return _frame.getFunction();
0311: }
0312:
0313: public final Module script() {
0314: return _frame.getModule();
0315: }
0316:
0317: public final Address address() {
0318: if (_frame == null) {
0319: return _zone.getAddress();
0320: }
0321: return _frame.getModule().getAddress();
0322: }
0323:
0324: public final Zone zone() {
0325: if (_frame == null) {
0326: return _zone;
0327: }
0328: return _frame.getZone();
0329: }
0330:
0331: public final Log log() {
0332: if (_frame == null) {
0333: return _zone.log();
0334: }
0335: return _frame.getZone().log();
0336: }
0337:
0338: /* security */
0339:
0340: public boolean checkPermission(Permission perm) {
0341: Log log = log();
0342: if (log.getSeverity() >= Log.DEBUG) {
0343: log.debug(perm.toString());
0344: }
0345:
0346: Citizen citizen = _citizen;
0347: if (citizen != null) {
0348: PermissionCollection pc = citizen.getCombinedPermissions();
0349: if (pc != null) {
0350: if (pc.implies(perm)) {
0351: return true;
0352: }
0353: }
0354: }
0355:
0356: int n = size();
0357: Zone[] zones = new Zone[n];
0358: int c = 0;
0359:
0360: alreadyChecked: for (int i = n - 1; i >= 0; i--) {
0361: Zone zone = peek(i).getZone();
0362: for (int j = 0; j < c; j++) {
0363: if (zones[j] == zone) {
0364: continue alreadyChecked;
0365: }
0366: }
0367: if (zone.checkPermission(perm)) {
0368: return true;
0369: }
0370: zones[c++] = zone;
0371: }
0372:
0373: return false;
0374: }
0375:
0376: public void checkAcquire(String poolname)
0377: throws anvil.database.CannotReturnPooledConnectionException {
0378: if (_hasPolicy) {
0379: if (!checkPermission(new anvil.database.ConnectionPoolPermission(
0380: poolname))) {
0381: throw new anvil.database.CannotReturnPooledConnectionException(
0382: "Access denied: " + poolname);
0383: }
0384: }
0385: }
0386:
0387: public void checkRealm(String name) {
0388: if (_hasPolicy) {
0389: if (!checkPermission(new anvil.server.RealmPermission(name))) {
0390: throw AccessDenied("Cannot access realm: " + name);
0391: }
0392: }
0393: }
0394:
0395: public void checkNamespace(String namespace, boolean writable) {
0396: if (_hasPolicy) {
0397: if (!checkPermission(new anvil.server.NamespacePermission(
0398: namespace, writable))) {
0399: if (writable) {
0400: throw AccessDenied("Cannot modify namespace: "
0401: + namespace);
0402: } else {
0403: throw AccessDenied("Cannot access namespace: "
0404: + namespace);
0405: }
0406: }
0407: }
0408: }
0409:
0410: public void checkAccess(String resource) {
0411: if (_hasPolicy) {
0412: if (!checkPermission(new anvil.core.RuntimePermission(
0413: resource))) {
0414: throw AccessDenied("Cannot access: " + resource);
0415: }
0416: }
0417: }
0418:
0419: public void checkAccess(String resource, boolean writable) {
0420: if (_hasPolicy) {
0421: if (!checkPermission(new anvil.core.RuntimePermission(
0422: resource, writable))) {
0423: if (writable) {
0424: throw AccessDenied("Cannot modify: " + resource);
0425: } else {
0426: throw AccessDenied("Cannot access: " + resource);
0427: }
0428: }
0429: }
0430: }
0431:
0432: public void checkAccess(anvil.core.RuntimePermission perm) {
0433: if (_hasPolicy) {
0434: if (!checkPermission(perm)) {
0435: if (perm.isWritable()) {
0436: throw AccessDenied("Cannot modify: "
0437: + perm.getName());
0438: } else {
0439: throw AccessDenied("Cannot access: "
0440: + perm.getName());
0441: }
0442: }
0443: }
0444: }
0445:
0446: public void checkReflection(String classname) {
0447: if (_hasPolicy) {
0448: if (!checkPermission(new anvil.java.security.JavaPermission(
0449: classname))) {
0450: throw AccessDenied("Cannot access java: " + classname);
0451: }
0452: }
0453: }
0454:
0455: public void checkImport(String target) {
0456: checkImport(frame().getPathinfo(), target);
0457: }
0458:
0459: public void checkImport(String source, String target) {
0460: if (_hasPolicy) {
0461: if (ImportPermission.onSameDir(source, target)) {
0462: return;
0463: }
0464: if (!checkPermission(new ImportPermission(target))) {
0465: throw AccessDenied("Cannot import: " + target);
0466: }
0467: }
0468: }
0469:
0470: private static java.net.SocketPermission _localListenPermission = null;
0471:
0472: public void checkListen(int port) {
0473: if (_hasPolicy) {
0474: if (port == 0) {
0475: if (_localListenPermission == null) {
0476: _localListenPermission = new java.net.SocketPermission(
0477: "localhost:1024-", "listen");
0478: }
0479: if (!checkPermission(_localListenPermission)) {
0480: throw AccessDenied("Cannot listen: localhost:1024-");
0481: }
0482: } else {
0483: if (!checkPermission(new java.net.SocketPermission(
0484: "localhost:" + port, "listen"))) {
0485: throw AccessDenied("Cannot listen: localhost:"
0486: + port);
0487: }
0488: }
0489: }
0490: }
0491:
0492: public void checkAccept(String host, int port) {
0493: if (_hasPolicy) {
0494: if (!checkPermission(new java.net.SocketPermission(host
0495: + ':' + port, "accept"))) {
0496: throw AccessDenied("Cannot accept: " + host + ':'
0497: + port);
0498: }
0499: }
0500: }
0501:
0502: public void checkConnect(String host, int port) {
0503: if (_hasPolicy) {
0504: if (port == -1) {
0505: if (!checkPermission(new java.net.SocketPermission(
0506: host, "resolve"))) {
0507: throw AccessDenied("Cannot resolve: " + host);
0508: }
0509: } else {
0510: if (!checkPermission(new java.net.SocketPermission(host
0511: + ':' + port, "connect"))) {
0512: throw AccessDenied("Cannot connect: " + host + ':'
0513: + port);
0514: }
0515: }
0516: }
0517: }
0518:
0519: public void checkRead(String path) {
0520: if (_hasPolicy) {
0521: if (!checkPermission(new java.io.FilePermission(path,
0522: "read"))) {
0523: throw AccessDenied("Cannot read: " + path);
0524: }
0525: }
0526: }
0527:
0528: public void checkWrite(String path) {
0529: if (_hasPolicy) {
0530: if (!checkPermission(new java.io.FilePermission(path,
0531: "write"))) {
0532: throw AccessDenied("Cannot write: " + path);
0533: }
0534: }
0535: }
0536:
0537: public void checkDelete(String path) {
0538: if (_hasPolicy) {
0539: if (!checkPermission(new java.io.FilePermission(path,
0540: "delete"))) {
0541: throw AccessDenied("Cannot delete: " + path);
0542: }
0543: }
0544: }
0545:
0546: public void checkExec(String path) {
0547: if (_hasPolicy) {
0548: if (!checkPermission(new java.io.FilePermission(path,
0549: "exec"))) {
0550: throw AccessDenied("Cannot execute: " + path);
0551: }
0552: }
0553: }
0554:
0555: /* namespaces */
0556:
0557: public Any global() {
0558: return _global;
0559: }
0560:
0561: public String getName() {
0562: return "global";
0563: }
0564:
0565: public Any getNS(String name) {
0566: if (name == GLOBAL || name.equals(GLOBAL)) {
0567: return new AnyNamespace(this );
0568: }
0569: checkNamespace(name, false);
0570: Namespace ns = zone().getNamespace(name);
0571: return (ns != null) ? new AnyNamespace(ns) : Any.UNDEFINED;
0572: }
0573:
0574: public final BindingEnumeration getVariables() {
0575: return _globals.getVariables();
0576: }
0577:
0578: public final Any getVariable(String name) {
0579: return _globals.getVariable(name);
0580: }
0581:
0582: public final Any setVariable(String name, Any value) {
0583: return _globals.setVariable(name, value);
0584: }
0585:
0586: public final Any checkVariable(String name) {
0587: return _globals.checkVariable(name);
0588: }
0589:
0590: public final boolean deleteVariable(String name) {
0591: return _globals.deleteVariable(name);
0592: }
0593:
0594: public final Any exec(Function function, StackFrame escape,
0595: Any[] parameters) {
0596: _escape = escape;
0597: return function.execute(this , null, parameters);
0598: }
0599:
0600: public final Any exec(Function function, StackFrame escape) {
0601: _escape = escape;
0602: return function.execute(this , (Any) null);
0603: }
0604:
0605: public final Any exec(Function function, StackFrame escape,
0606: Any param1) {
0607: _escape = escape;
0608: return function.execute(this , null, param1);
0609: }
0610:
0611: public final Any exec(Function function, StackFrame escape,
0612: Any param1, Any param2) {
0613: _escape = escape;
0614: return function.execute(this , null, param1, param2);
0615: }
0616:
0617: public final Any exec(Function function, StackFrame escape,
0618: Any param1, Any param2, Any param3) {
0619: _escape = escape;
0620: return function.execute(this , null, param1, param2, param3);
0621: }
0622:
0623: public final Any exec(Function function, StackFrame escape,
0624: Any param1, Any param2, Any param3, Any param4) {
0625: _escape = escape;
0626: return function.execute(this , null, param1, param2, param3,
0627: param4);
0628: }
0629:
0630: public final Any exec(Any self, Function function,
0631: StackFrame escape, Any[] parameters) {
0632: _escape = escape;
0633: return function.execute(this , self, parameters);
0634: }
0635:
0636: public final Any exec(Any self, Function function, StackFrame escape) {
0637: _escape = escape;
0638: return function.execute(this , self);
0639: }
0640:
0641: public final Any exec(Any self, Function function,
0642: StackFrame escape, Any param1) {
0643: _escape = escape;
0644: return function.execute(this , self, param1);
0645: }
0646:
0647: public final Any exec(Any self, Function function,
0648: StackFrame escape, Any param1, Any param2) {
0649: _escape = escape;
0650: return function.execute(this , self, param1, param2);
0651: }
0652:
0653: public final Any exec(Any self, Function function,
0654: StackFrame escape, Any param1, Any param2, Any param3) {
0655: _escape = escape;
0656: return function.execute(this , self, param1, param2, param3);
0657: }
0658:
0659: public final Any exec(Any self, Function function,
0660: StackFrame escape, Any param1, Any param2, Any param3,
0661: Any param4) {
0662: _escape = escape;
0663: return function.execute(this , self, param1, param2, param3,
0664: param4);
0665: }
0666:
0667: /* external entry point to context */
0668:
0669: public final Any execute(Module script, String name,
0670: Any[] parameters) throws ScriptException {
0671: Type type = script.lookupDeclaration(name);
0672: if (!(type instanceof Function)) {
0673: throw NoSuchFunction(name);
0674: }
0675: Function function = (Function) type;
0676: try {
0677: return function.execute(this , parameters);
0678:
0679: } catch (ExitException exitex) {
0680: return exitex.getExitValue();
0681:
0682: } catch (ScriptException scriptex) {
0683: scriptex.fillInStackTrace();
0684: throw scriptex;
0685:
0686: } catch (Throwable thrown) {
0687: if (size() > 1) {
0688: StackFrame frame = peek();
0689: log().error(
0690: "Abnormal script termination at '"
0691: + frame.getPathinfo() + "' line "
0692: + frame.getLine() + " in function '"
0693: + frame.getFunction().getName() + "'",
0694: thrown);
0695: } else {
0696: log().error("Abnormal script termination", thrown);
0697: }
0698: }
0699: return Any.UNDEFINED;
0700: }
0701:
0702: /* localization */
0703:
0704: public final String getLanguage() {
0705: return _language;
0706: }
0707:
0708: public final void setLanguage(String language) {
0709: _language = language;
0710: _locale = new Locale(language, _locale.getCountry());
0711: }
0712:
0713: public final Locale getLocale() {
0714: return _locale;
0715: }
0716:
0717: public final void setLocale(Locale locale) {
0718: _locale = locale;
0719: }
0720:
0721: public final TimeZone getTimeZone() {
0722: return _timezone;
0723: }
0724:
0725: public final void setTimeZone(TimeZone timezone) {
0726: _timezone = timezone;
0727: }
0728:
0729: /* output */
0730:
0731: public final void setOutputStream(OutputStream output) {
0732: pushOutputStream(output);
0733: }
0734:
0735: public final OutputStream getOutputStream() {
0736: return _output;
0737: }
0738:
0739: public final void pushOutputStream(OutputStream output) {
0740: _output = output;
0741: _outputStack.push(output);
0742: }
0743:
0744: public final OutputStream popOutputStream() {
0745: if (!_outputStack.isEmpty()) {
0746: OutputStream popped = (OutputStream) _outputStack.pop();
0747: if (!_outputStack.isEmpty()) {
0748: _output = (OutputStream) _outputStack.peek();
0749: } else {
0750: _output = null;
0751: }
0752: return popped;
0753: } else {
0754: return null;
0755: }
0756: }
0757:
0758: public final OutputStream peekOutputStream() {
0759: int n = _outputStack.size();
0760: if (_outputStack.size() > 1) {
0761: return (OutputStream) _outputStack.elementAt(n - 2);
0762: } else {
0763: return null;
0764: }
0765: }
0766:
0767: public final void println() {
0768: if (_output != null) {
0769: try {
0770: _output.write(NEWLINE, 0, 1);
0771: } catch (IOException exception) {
0772: _output = null;
0773: throw exception(exception);
0774: }
0775: } else {
0776: }
0777: }
0778:
0779: public final void println(String cdata) {
0780: print(cdata);
0781: println();
0782: }
0783:
0784: public final void print(String cdata) {
0785: if ((cdata != null) && (cdata.length() > 0)) {
0786: if (_output != null) {
0787: try {
0788: byte[] array = anvil.util.Conversions
0789: .getBytes(cdata);
0790: _output.write(array, 0, array.length);
0791: } catch (IOException exception) {
0792: _output = null;
0793: throw exception(exception);
0794: }
0795: } else {
0796: log().debug(cdata);
0797: }
0798: }
0799: }
0800:
0801: public final void println(byte[] array) {
0802: if (array == null) {
0803: return;
0804: }
0805: print(array);
0806: println();
0807: }
0808:
0809: public final void print(byte[] array) {
0810: if (array == null) {
0811: return;
0812: }
0813: int n = array.length;
0814: if (n > 0) {
0815: if (_output != null) {
0816: try {
0817: _output.write(array, 0, n);
0818: } catch (IOException exception) {
0819: _output = null;
0820: throw exception(exception);
0821: }
0822: } else {
0823: log().debug(new String(array));
0824: }
0825: }
0826: }
0827:
0828: public final void println(byte[] array, int offset, int length) {
0829: if (array == null) {
0830: return;
0831: }
0832: print(array, offset, length);
0833: println();
0834: }
0835:
0836: public final void print(byte[] array, int offset, int length) {
0837: if (array == null) {
0838: return;
0839: }
0840: if (length > 0) {
0841: if (_output != null) {
0842: try {
0843: _output.write(array, offset, length);
0844: } catch (IOException exception) {
0845: _output = null;
0846: throw exception(exception);
0847: }
0848: } else {
0849: log().debug(new String(array, offset, length));
0850: }
0851: }
0852: }
0853:
0854: public final void println(Any value) {
0855: print(value.toBinary());
0856: println();
0857: }
0858:
0859: public final void print(Any value) {
0860: print(value.toBinary());
0861: }
0862:
0863: /** new shortcuts */
0864:
0865: public static final Any predec(Any target, String field,
0866: Context context) {
0867: return target.setAttribute(context, field, target.getAttribute(
0868: context, field).decrease());
0869: }
0870:
0871: public static final Any preinc(Any target, String field,
0872: Context context) {
0873: return target.setAttribute(context, field, target.getAttribute(
0874: context, field).increase());
0875: }
0876:
0877: public static final Any postdec(Any target, String field,
0878: Context context) {
0879: Any value = target.getAttribute(context, field);
0880: target.setAttribute(context, field, value.decrease());
0881: return value;
0882: }
0883:
0884: public static final Any postinc(Any target, String field,
0885: Context context) {
0886: Any value = target.getAttribute(context, field);
0887: target.setAttribute(context, field, value.increase());
0888: return value;
0889: }
0890:
0891: public static final Any assign(Any value, Any target, String field,
0892: Context context) {
0893: return target.setAttribute(context, field, value);
0894: }
0895:
0896: public static final Any add(Any value, Any target, String field,
0897: Context context) {
0898: return target.setAttribute(context, field, Op.add(target
0899: .getAttribute(context, field), value));
0900: }
0901:
0902: public static final Any sub(Any value, Any target, String field,
0903: Context context) {
0904: return target.setAttribute(context, field, Op.sub(target
0905: .getAttribute(context, field), value));
0906: }
0907:
0908: public static final Any mul(Any value, Any target, String field,
0909: Context context) {
0910: return target.setAttribute(context, field, Op.mul(target
0911: .getAttribute(context, field), value));
0912: }
0913:
0914: public static final Any div(Any value, Any target, String field,
0915: Context context) {
0916: return target.setAttribute(context, field, Op.div(target
0917: .getAttribute(context, field), value));
0918: }
0919:
0920: public static final Any mod(Any value, Any target, String field,
0921: Context context) {
0922: return target.setAttribute(context, field, Op.mod(target
0923: .getAttribute(context, field), value));
0924: }
0925:
0926: public static final Any concat(Any value, Any target, String field,
0927: Context context) {
0928: return target.setAttribute(context, field, target.getAttribute(
0929: context, field).concat(value));
0930: }
0931:
0932: public static final Any init(Any value, Any target, String field,
0933: Context context) {
0934: Any old = target.getAttribute(context, field);
0935: if (old.isUndefined()) {
0936: return target.setAttribute(context, field, value);
0937: } else {
0938: return old;
0939: }
0940: }
0941:
0942: /* reference shortcuts */
0943:
0944: public static final Any predec(Any target, Any index,
0945: Context context) {
0946: return target.setReference(context, index, target.getReference(
0947: context, index).decrease());
0948: }
0949:
0950: public static final Any preinc(Any target, Any index,
0951: Context context) {
0952: return target.setReference(context, index, target.getReference(
0953: context, index).increase());
0954: }
0955:
0956: public static final Any postdec(Any target, Any index,
0957: Context context) {
0958: Any value = target.getReference(context, index);
0959: target.setReference(context, index, value.decrease());
0960: return value;
0961: }
0962:
0963: public static final Any postinc(Any target, Any index,
0964: Context context) {
0965: Any value = target.getReference(context, index);
0966: target.setReference(context, index, value.increase());
0967: return value;
0968: }
0969:
0970: public static final Any assign(Any value, Any target, Any index,
0971: Context context) {
0972: return target.setReference(context, index, value);
0973: }
0974:
0975: public static final Any add(Any value, Any target, Any index,
0976: Context context) {
0977: return target.setReference(context, index, Op.add(target
0978: .getReference(context, index), value));
0979: }
0980:
0981: public static final Any sub(Any value, Any target, Any index,
0982: Context context) {
0983: return target.setReference(context, index, Op.sub(target
0984: .getReference(context, index), value));
0985: }
0986:
0987: public static final Any mul(Any value, Any target, Any index,
0988: Context context) {
0989: return target.setReference(context, index, Op.mul(target
0990: .getReference(context, index), value));
0991: }
0992:
0993: public static final Any div(Any value, Any target, Any index,
0994: Context context) {
0995: return target.setReference(context, index, Op.div(target
0996: .getReference(context, index), value));
0997: }
0998:
0999: public static final Any mod(Any value, Any target, Any index,
1000: Context context) {
1001: return target.setReference(context, index, Op.mod(target
1002: .getReference(context, index), value));
1003: }
1004:
1005: public static final Any concat(Any value, Any target, Any index,
1006: Context context) {
1007: return target.setReference(context, index, target.getReference(
1008: context, index).concat(value));
1009: }
1010:
1011: public static final Any init(Any value, Any target, Any index,
1012: Context context) {
1013: Any old = target.getReference(context, index);
1014: if (old.isUndefined()) {
1015: return target.setReference(context, index, value);
1016: } else {
1017: return old;
1018: }
1019: }
1020:
1021: /* regular expressions */
1022:
1023: public static final boolean match(Context context, Any image,
1024: Any pattern) {
1025: Pattern p;
1026: if (pattern.isPattern()) {
1027: p = pattern.toPattern();
1028: } else {
1029: try {
1030: p = ObjectPool.createPattern(pattern.toString(), null);
1031: } catch (MalformedPatternException e) {
1032: if (context == null) {
1033: context = Context.getInstance();
1034: }
1035: throw context.exception(e);
1036: }
1037: }
1038: Perl5Matcher matcher = new Perl5Matcher();
1039: return matcher.contains(image.toString(), p);
1040: }
1041:
1042: public static final boolean nomatch(Context context, Any image,
1043: Any pattern) {
1044: return !match(context, image, pattern);
1045: }
1046:
1047: /* importing */
1048:
1049: public final Any dynamicImport(String source) {
1050: return new anvil.core.runtime.AnyScope(import_(source));
1051: }
1052:
1053: public final Scope import_(String source) {
1054: Zone zone = zone();
1055:
1056: if (source.equals(Modules.NAME)) {
1057: return zone.getModules();
1058: }
1059:
1060: Address importing = null;
1061:
1062: try {
1063: importing = address().resolve(source);
1064: } catch (anvil.server.ZoneInactiveException e) {
1065: throw ImportError(e.getMessage(), null);
1066: }
1067:
1068: checkImport(frame().getPathinfo(), importing.getPathinfo());
1069:
1070: try {
1071: return zone.getServer().getCache().load(importing)
1072: .getModule();
1073:
1074: } catch (ForgingException e) {
1075: throw ImportError(source, e.getErrorListener());
1076:
1077: } catch (IOException e) {
1078: throw exception(e);
1079:
1080: } catch (Throwable t) {
1081: log().error("Import failed", t);
1082: throw exception(t);
1083: }
1084: }
1085:
1086: /*reflection*/
1087:
1088: public Reflection reflect(String classname) {
1089: checkReflection(classname);
1090: Reflection reflection = ObjectPool.getReflection(classname);
1091: if (reflection == null) {
1092: reflection = zone().findJava(classname);
1093: }
1094: if (reflection == null) {
1095: throw ClassNotFound(classname);
1096: }
1097: return reflection;
1098: }
1099:
1100: private Reflection reflect0(String classname) {
1101: Reflection reflection = ObjectPool.getReflection(classname);
1102: if (reflection == null) {
1103: reflection = zone().findJava(classname);
1104: }
1105: if (reflection == null) {
1106: throw ClassNotFound(classname);
1107: }
1108: return reflection;
1109: }
1110:
1111: /* piping */
1112:
1113: public final Any pipe(Any list, Any pipe) {
1114: return new anvil.core.AnyBindingEnumeration(
1115: new anvil.core.AnyUtils.PipeEnumeration(this , pipe,
1116: list.enumeration(), Any.UNDEFINED));
1117: }
1118:
1119: /* foreach */
1120:
1121: public final Any foreach(Any list, Any block) {
1122: Any rv = Any.UNDEFINED;
1123: BindingEnumeration e = list.enumeration();
1124: Any[] args = new Any[2];
1125: while (e.hasMoreElements()) {
1126: args[1] = Any.create(e.nextKey());
1127: args[0] = Any.create(e.nextElement());
1128: rv = block.execute(this , args);
1129: }
1130: return rv;
1131: }
1132:
1133: /* multiassign */
1134:
1135: public final Any nth(Any value, int index) {
1136: if (value.isEnumeration()) {
1137: Enumeration e = value.enumeration();
1138: if (e.hasMoreElements()) {
1139: return Any.create(e.nextElement());
1140: }
1141: } else if (value.isArray()) {
1142: value = value.toArray().elementAt(index);
1143: if (value != null) {
1144: return value;
1145: }
1146: } else {
1147: return value.checkReference(this , Any.create(index));
1148: }
1149: return Any.UNDEFINED;
1150: }
1151:
1152: /* exceptions */
1153:
1154: public ScriptException TypeError(String message) {
1155: return new ScriptException(new Throwables.TypeError(this ,
1156: message));
1157: }
1158:
1159: public ScriptException BadParameter(String message) {
1160: return new ScriptException(
1161: new Throwables.TypeError.BadParameter(this , message));
1162: }
1163:
1164: public ScriptException NotEnoughParameters() {
1165: return new ScriptException(
1166: new Throwables.TypeError.NotEnoughParameters(this , null));
1167: }
1168:
1169: public ScriptException NotEnoughParameters(String message) {
1170: return new ScriptException(
1171: new Throwables.TypeError.NotEnoughParameters(this ,
1172: message));
1173: }
1174:
1175: public ScriptException NotEnoughParameters(int index) {
1176: return new ScriptException(
1177: new Throwables.TypeError.NotEnoughParameters(this ,
1178: Register.getNameOf(index)));
1179: }
1180:
1181: public ScriptException NoSuchMethod(String message) {
1182: return new ScriptException(
1183: new Throwables.TypeError.NoSuchMethod(this , message));
1184: }
1185:
1186: public ScriptException NoSuchMethod(int index) {
1187: return new ScriptException(
1188: new Throwables.TypeError.NoSuchMethod(this , Register
1189: .getNameOf(index)));
1190: }
1191:
1192: public ScriptException NoSuchMethod(String classname, int index) {
1193: return new ScriptException(
1194: new Throwables.TypeError.NoSuchMethod(this , classname
1195: + '.' + Register.getNameOf(index)));
1196: }
1197:
1198: public ScriptException NoSuchMember(String message) {
1199: return new ScriptException(
1200: new Throwables.TypeError.NoSuchMember(this , message));
1201: }
1202:
1203: public ScriptException NoSuchFunction(String message) {
1204: return new ScriptException(
1205: new Throwables.TypeError.NoSuchFunction(this , message));
1206: }
1207:
1208: public ScriptException NoSuchClass(String message) {
1209: return new ScriptException(
1210: new Throwables.TypeError.NoSuchClass(this , message));
1211: }
1212:
1213: public ScriptException NoSuchEntity(String message) {
1214: return new ScriptException(
1215: new Throwables.TypeError.NoSuchEntity(this , message));
1216: }
1217:
1218: public ScriptException NoInstance(String message) {
1219: return new ScriptException(new Throwables.TypeError.NoInstance(
1220: this , message));
1221: }
1222:
1223: public ScriptException InstantiationError(String message) {
1224: return new ScriptException(
1225: new Throwables.TypeError.InstantiationError(this ,
1226: message));
1227: }
1228:
1229: public ScriptException AttributeError(String message) {
1230: return new ScriptException(
1231: new Throwables.TypeError.AttributeError(this , message));
1232: }
1233:
1234: public ScriptException ReferenceError(String message) {
1235: return new ScriptException(
1236: new Throwables.TypeError.ReferenceError(this , message));
1237: }
1238:
1239: public ScriptException CallError(String message) {
1240: return new ScriptException(new Throwables.TypeError.CallError(
1241: this , message));
1242: }
1243:
1244: public ScriptException BadState(String message) {
1245: return new ScriptException(new Throwables.BadState(this ,
1246: message));
1247: }
1248:
1249: public ScriptException AssertFailed(String message) {
1250: return new ScriptException(new Throwables.AssertFailed(this ,
1251: message));
1252: }
1253:
1254: public ScriptException CorruptedSerialization() {
1255: return new ScriptException(
1256: new Throwables.CorruptedSerialization(this , null));
1257: }
1258:
1259: public ScriptException CorruptedSerialization(String message) {
1260: return new ScriptException(
1261: new Throwables.CorruptedSerialization(this , message));
1262: }
1263:
1264: public ScriptException MalformedPattern(String message) {
1265: return new ScriptException(new Throwables.MalformedPattern(
1266: this , message));
1267: }
1268:
1269: public ScriptException AcquireError(String message) {
1270: return new ScriptException(new Throwables.AcquireError(this ,
1271: message));
1272: }
1273:
1274: public ScriptException AccessDenied(String message) {
1275: return new ScriptException(new Throwables.AccessDenied(this ,
1276: message));
1277: }
1278:
1279: public ScriptException ClassNotFound(String message) {
1280: return new ScriptException(new Throwables.ClassNotFound(this ,
1281: message));
1282: }
1283:
1284: public ScriptException XMLError(String message,
1285: ErrorListener listener) {
1286: return new ScriptException(new Throwables.XMLError(this ,
1287: message, listener));
1288: }
1289:
1290: public ScriptException InternalError(String message) {
1291: return new ScriptException(new Throwables.InternalError(this ,
1292: message));
1293: }
1294:
1295: public ScriptException ImportError(String message,
1296: ErrorListener listener) {
1297: return new ScriptException(new Throwables.ImportError(this ,
1298: message, listener));
1299: }
1300:
1301: public ScriptException Interrupted(String message) {
1302: return new ScriptException(new Throwables.Interrupted(this ,
1303: message));
1304: }
1305:
1306: public ScriptException SQLError(java.sql.SQLException exception) {
1307: return new ScriptException(new Throwables.SQLError(this ,
1308: exception));
1309: }
1310:
1311: public ScriptException OperationFailed(String message) {
1312: return new ScriptException(new Throwables.OperationFailed(this ,
1313: message));
1314: }
1315:
1316: public final ScriptException exception(Throwable throwable) {
1317: if (throwable instanceof java.io.IOException) {
1318: return exception((java.io.IOException) throwable);
1319: }
1320: if (throwable instanceof java.sql.SQLException) {
1321: return exception((java.sql.SQLException) throwable);
1322: }
1323: if (throwable instanceof javax.naming.NamingException) {
1324: return exception((javax.naming.NamingException) throwable);
1325: }
1326: if (throwable instanceof anvil.server.OperationFailedException) {
1327: return exception((anvil.server.OperationFailedException) throwable);
1328: }
1329: return new ScriptException(new Throwables.JavaError(this ,
1330: throwable));
1331: }
1332:
1333: public final ScriptException exception(java.io.IOException e) {
1334: Any t;
1335: if (e instanceof java.io.FileNotFoundException) {
1336: t = new anvil.core.Throwables.IOError.FileNotFound(this , e
1337: .getMessage());
1338: } else if (e instanceof java.io.EOFException) {
1339: t = new anvil.core.Throwables.IOError.EndOfFile(this , e
1340: .getMessage());
1341: } else if (e instanceof java.io.InterruptedIOException) {
1342: t = new anvil.core.Throwables.IOError.InterruptedIO(this , e
1343: .getMessage());
1344: } else if (e instanceof java.io.SyncFailedException) {
1345: t = new anvil.core.Throwables.IOError.SyncFailed(this , e
1346: .getMessage());
1347: } else if (e instanceof java.net.SocketException) {
1348: return exception((java.net.SocketException) e);
1349: } else if (e instanceof java.net.MalformedURLException) {
1350: t = new anvil.core.Throwables.IOError.MalformedURL(this , e
1351: .getMessage());
1352: } else if (e instanceof java.net.UnknownHostException) {
1353: t = new anvil.core.Throwables.IOError.UnknownHost(this , e
1354: .getMessage());
1355: } else if (e instanceof java.net.ProtocolException) {
1356: t = new anvil.core.Throwables.IOError.ProtocolError(this , e
1357: .getMessage());
1358: } else if (e instanceof java.net.UnknownServiceException) {
1359: t = new anvil.core.Throwables.IOError.UnknownService(this ,
1360: e.getMessage());
1361: } else {
1362: t = new anvil.core.Throwables.IOError(this , e.getMessage());
1363: }
1364: return new ScriptException(t);
1365: }
1366:
1367: public final ScriptException exception(java.net.SocketException e) {
1368: Any t;
1369: if (e instanceof java.net.BindException) {
1370: t = new anvil.core.Throwables.IOError.SocketError.BindError(
1371: this , e.getMessage());
1372: } else if (e instanceof java.net.ConnectException) {
1373: t = new anvil.core.Throwables.IOError.SocketError.ConnectError(
1374: this , e.getMessage());
1375: } else if (e instanceof java.net.NoRouteToHostException) {
1376: t = new anvil.core.Throwables.IOError.SocketError.NoRouteToHost(
1377: this , e.getMessage());
1378: } else {
1379: t = new anvil.core.Throwables.IOError.SocketError(this , e
1380: .getMessage());
1381: }
1382: return new ScriptException(t);
1383: }
1384:
1385: public final ScriptException exception(java.sql.SQLException e) {
1386: return new ScriptException(new anvil.core.Throwables.SQLError(
1387: this , e));
1388: }
1389:
1390: public final ScriptException exception(
1391: javax.naming.NamingException e) {
1392: return new ScriptException(Any.create(e));
1393: }
1394:
1395: public final ScriptException exception(
1396: anvil.server.OperationFailedException e) {
1397: return new ScriptException(
1398: new anvil.core.Throwables.OperationFailed(this, e
1399: .getMessage()));
1400: }
1401: }
|