View Javadoc

1   ////////////////////////////////////////////////////////////////////////////////
2   // MillScript: an Open Spice interpreter and batch website creation tool
3   // Copyright (C) 2001-2004 Open World Ltd
4   // Copyright (C) 2005 Kevin Rogers
5   //
6   // This file is part of MillScript.
7   //
8   // MillScript is free software; you can redistribute it and/or modify it under
9   // the terms of the GNU General Public License as published by the Free
10  // Software Foundation; either version 2 of the License, or (at your option)
11  // any later version.
12  //
13  // MillScript is distributed in the hope that it will be useful, but WITHOUT
14  // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15  // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
16  // more details.
17  //
18  // You should have received a copy of the GNU General Public License along with
19  // MillScript; if not, write to the Free Software Foundation, Inc., 59 Temple
20  // Place, Suite 330, Boston, MA  02111-1307  USA
21  ////////////////////////////////////////////////////////////////////////////////
22  package org.millscript.millscript.functions;
23  
24  import org.millscript.commons.alert.alerts.ClassNotFoundAlert;
25  import org.millscript.millscript.alert.Alerts;
26  import org.millscript.millscript.alert.Phases;
27  import org.millscript.millscript.vm.Machine;
28  
29  import java.lang.reflect.Constructor;
30  import java.util.Arrays;
31  
32  /**
33   * This class implements the MillScript <code>javaConstructor</code> function.
34   */
35  public class JavaConstructorFunction extends Function {
36  
37      /**
38       * @see org.millscript.millscript.functions.Function#apply(org.millscript.millscript.vm.Machine, int)
39       */
40      @Override
41      public void apply( final Machine mc, final int nargs ) {
42          if ( nargs <= 0 ) {
43              throw(
44                  Alerts.eval(
45                      "Calling javaConstructorFunction with no arguments",
46                      "javaConstructorFunction requires at least the class name"
47                  ).mishap()
48              );
49          }
50  
51          int numArgs = nargs - 1;
52  
53          try {
54  
55              Class[] types = new Class[ numArgs ];
56              for ( int i = numArgs - 1; i >= 0; i-- ) {
57                  types[ i ] = ParameterType.findClass( mc.popString() );
58              }
59              String className = mc.popString();
60              Class clss = Class.forName( className );
61  
62              Constructor[] cons = clss.getConstructors();
63              for ( int k = 0; k < cons.length; k++ ) {
64                  Constructor c = cons[ k ];
65                  if ( Arrays.equals( c.getParameterTypes(), types ) ) {
66                      mc.pushObject( new JConstructor( c ) );
67                      return;
68                  }
69              }
70  
71              throw(
72                  Alerts.eval(
73                      "Cannot find matching constructor",
74                      "There was no constructor with a matching type signature"
75                  ).culprit( "class name", className ).mishap()
76              );
77  
78          } catch ( ClassNotFoundException ex ) {
79              throw(
80                  new ClassNotFoundAlert(
81                      "The class name could not be resolved ($CLASSPATH problem?)"
82                  ).culprit( "reason", ex.getMessage() ).setPhase( Phases.EVAL ).mishap()
83              );
84          }
85  
86      }
87  
88  }