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