Subj : Re: Rhino question: multiple constructors in scriptable objects To : mesuti@aciworldwide.com From : Igor Bukanov Date : Mon Mar 01 2004 05:21 pm mesuti@aciworldwide.com wrote: > > > > Hi, > > Is it possible to define a subclass of ScriptableObject that contains > multiple constructors (jsConstructor() methods). > > I want to define a class called "ByteBuffer" extending the Scriptable > Object and instantiate it in JavaScript using different constructors. > > > Example Class: > > public class ByteBuffer extends ScriptableObject { > > public ByteBuffer() { > } > > public void jsConstructor() { > } > > public void jsConstructor(String value, int encoding) { > } > > public void jsConstructor(ByteString source) { > } > > public String getClassName() { > return "ByteBuffer"; > } > > } > > The 'ByteString' object (see example above) is also a subclass of > ScriptableObject. > > > I know that it's not allowed to define multiple methods called > 'jsConstructor'. My question is how can I define a Host-Object which I can > instantiate it in JavaScript with different constructor signatures? > > i.e. > > var obj1 = new ByteBuffer(); > var obj2 = new ByteBuffer("a string", 2); > var obj3 = new ByteBuffer(new ByteString("another string", 2)); > As with jsFunction_, Rhino does not support overloading with jsConstructor directly. To achieve the desired effect you have to declare jsConstructor as a generic JS constructor and do argument selection yourself: public static jsConstructor( Context cx, Object[] args, Function functionObject, boolean isNew) { if (args.length == 0) { return new ByteBuffer(); } else if (args.length == 1) { Object arg = args[0]; // If ByteString is an instance of Scripatble, // you do not need the following 3 lines if (arg instanceof org.mozilla.javascript.Wrapper) { arg = ((org.mozilla.javascript.Wrapper)arg).unwrap(); } if (!(arg instanceof ByteString)) { Context.reportRuntimeError("Bad argument: "+arg); } ByteString bs = (ByteString)arg; return construct_ByteBuffer_using_bs(bs); } else if (args.length == 2) { String value = Context.toString(args[0]); double encoding = Context.toNumber(args[1]); int iencoding = (int)encoding; if (encoding != iencoding) { Context.reportRuntimeError("Bad encoding argument: "+args[1]); } return construct_ByetBuffer_using_value_encoding(value, encoding); } } In the above code functionObject gives you the function object that wraps jsConstructor method in JS which you can use, for example, to get scope through functionObject.getParentScope() that is required for various Rhino APIs. The last isNew argument allows to distinguish between js calls like: var obj1 = new ByteBuffer(); // isNew == true and var obj1 = ByteBuffer(); // isNew == false Regards, Igor .