1   package com.atlassian.performance;
2   
3   import com.google.inject.AbstractModule;
4   import com.google.inject.Provider;
5   import java.lang.reflect.Constructor;
6   import org.apache.commons.lang.ClassUtils;
7   
8   import static java.util.Arrays.asList;
9   import static com.google.inject.matcher.Matchers.*;
10  
11  public class PageInstantiatorModule extends AbstractModule
12  {
13      private PageObjectProvider pop;
14      
15      public PageInstantiatorModule(Class clazz, Object[] args)
16      {
17  	pop = new PageObjectProvider(clazz, args);
18      }
19      
20      @Override
21      protected void configure()
22      {
23  	bind(pop.clazz).toProvider(pop);
24      }
25  
26      class PageObjectProvider<P> implements Provider<P>
27      {
28  	Class<P> clazz;
29  	Object[] args;
30  	
31  	public PageObjectProvider(Class<P>  clazz, Object[] args) {
32  	    this.clazz = clazz;
33  	    this.args = args;
34  	}
35  
36  	public P get() 
37  	{
38  	    try{
39  		if (args != null && args.length > 0)
40  		{
41  		    for (Constructor c : clazz.getConstructors())
42  		    {
43  			Class[] paramTypes = c.getParameterTypes();
44  			if (args.length == paramTypes.length)
45  			{
46  			    boolean match = true;
47  			    for (int x = 0; x < args.length; x++)
48  			    {
49  				if (args[x] != null && !ClassUtils.isAssignable(args[x].getClass(), paramTypes[x], true /*autoboxing*/))
50  				{
51  				    match = false;
52  				    break;
53  				}
54                          }
55                          if (match)
56                          {
57                              return (P) c.newInstance(args);
58                          }
59                      }
60                  }
61              }
62              else
63              {
64                  try
65                  {
66                      return clazz.newInstance();
67                  }
68                  catch (InstantiationException ex)
69                  {
70                      throw new IllegalArgumentException("Error invoking default constructor", ex);
71                  }
72              }
73              throw new IllegalArgumentException("Cannot find constructor on " + clazz + " to match args: " + asList(args));
74  	    } catch (Exception e) {
75  		throw new RuntimeException(e);
76  	    }
77          }	
78      }
79  
80  }