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.Alert;
25  import org.millscript.millscript.alert.Alerts;
26  import org.millscript.millscript.vm.Machine;
27  
28  import java.lang.reflect.Constructor;
29  import java.lang.reflect.InvocationTargetException;
30  
31  /**
32   * This class implements a function which invokes a Java constructor to create
33   * a new instance of a Java class.
34   */
35  public final class JConstructor extends Function {
36  
37      /**
38       * The Java constructor to invoke.
39       */
40      private final Constructor con;
41  
42      /**
43       * The type of the parameters this constructor requires.
44       */
45      private final Class[] ptypes;
46  
47      /**
48       * The number of arguments this function requires.
49       */
50      private final int numArgs;
51  
52      /**
53       * A buffer to use for storing the arguments prior to invoking the
54       * underlying contsructor.
55       */
56      private final Object[] buffer;
57  
58      /**
59       * Constructs a new <code>JConstructor</code> function to invoke the
60       * specified Java constructor.
61       *
62       * @param c the Java constructor to invoke
63       */
64      public JConstructor( final Constructor c ) {
65          this.con = c;
66          ptypes = con.getParameterTypes();
67          numArgs = ptypes.length;
68          buffer = new Object[ numArgs ];
69      }
70  
71      /**
72       * @see org.millscript.millscript.functions.Function#apply(org.millscript.millscript.vm.Machine, int)
73       */
74      @Override
75      public void apply( final Machine mc, final int nargs ) {
76          checkNargs( mc, numArgs, nargs );
77          mc.popArgsIntoArray( buffer );
78          try {
79              mc.pushObject( con.newInstance( buffer ) );
80          } catch ( InvocationTargetException ex ) {
81              final Throwable cause = ex.getCause();
82              if ( cause instanceof NoClassDefFoundError ) {
83                  throw(
84                      Alerts.eval(
85                          "Cannot construct instance",
86                          "A required class could not be found"
87                      ).
88                      culprit( "Missing class", cause.getMessage() ).
89                      mishap()
90                  );
91              } else if ( cause instanceof Alert ) {
92                  throw (Alert) cause;
93              } else {
94                  throw(
95                      Alerts.eval(
96                          "Cannot construct instance",
97                          "An invocation target exception was thrown"
98                      ).culprit( "reason", ex.getMessage() ).
99                      culprit( "exception", cause ).
100                     mishap()
101                 );
102             }
103         } catch ( InstantiationException ex ) {
104             throw(
105                 Alerts.eval(
106                     "Cannot construct instance",
107                     "An instantiation exception was thrown"
108                 ).culprit( "reason", ex.getMessage() ).mishap()
109             );
110         } catch ( IllegalAccessException ex ) {
111             throw(
112                 Alerts.eval(
113                     "Cannot construct instance",
114                     "An illegal access exception was thrown"
115                 ).culprit( "reason", ex.getMessage() ).mishap()
116             );
117         } catch ( IllegalArgumentException ex ) {
118             throw(
119                 Alerts.eval(
120                     "Cannot construct instance",
121                     "An illegal argument exception was thrown"
122                 ).culprit( "reason", ex.getMessage() ).mishap()
123             );
124         }
125     }
126 
127 }