1336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beustpackage org.testng.internal;
2336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust
321c6d08b4857e3c9d3d2d21934f35cf787e013a5Dariusz Lukszaimport static org.testng.internal.Utils.isStringNotEmpty;
421c6d08b4857e3c9d3d2d21934f35cf787e013a5Dariusz Luksza
5b3a4d753d567c7c8f6c78a7f0a9fb6641b96788cCédric Beustimport com.google.inject.Injector;
6d001f3960f66312b94dcb7bae88c92158eb38a75Cédric Beustimport com.google.inject.Module;
787485d3848462cf1ac8f07c429f1e2237ff70425cguillaumeimport com.google.inject.Stage;
8d001f3960f66312b94dcb7bae88c92158eb38a75Cédric Beust
9336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beustimport org.testng.IClass;
10a9bd8f0998a6fde123d996edf87a0e74917e747dCédric Beustimport org.testng.IModuleFactory;
1121c6d08b4857e3c9d3d2d21934f35cf787e013a5Dariusz Lukszaimport org.testng.ISuite;
129f2367a1c4b17a5b38fb6fa209b717fb42d4faccCédric Beustimport org.testng.ITest;
13b44cd9ee2acc5dcd25d3aca8bc33cbb2e564b339Cédric Beustimport org.testng.ITestContext;
14ed65240afc7792175d9fe09bb9bb553360798ae8Cédric Beustimport org.testng.ITestObjectFactory;
15d001f3960f66312b94dcb7bae88c92158eb38a75Cédric Beustimport org.testng.TestNGException;
1676fe48e370b5cc15fe477615aa885bb8a2d25799Cédric Beustimport org.testng.annotations.Guice;
1706ee812f9dbb2e780083c3909e1618e49431209eJulien Herrimport org.testng.annotations.ITestAnnotation;
18ed0917f31f0b66158bc786cd018fd95175f76f29Cédric Beustimport org.testng.collections.Lists;
1954a1dff85605912356caf3c3bcc4f73e80fd1311Cédric Beustimport org.testng.collections.Objects;
20d001f3960f66312b94dcb7bae88c92158eb38a75Cédric Beustimport org.testng.internal.annotations.AnnotationHelper;
21336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beustimport org.testng.internal.annotations.IAnnotationFinder;
22682629c7059fca8adc2cc2eacdb2d372d7a28c3dCédric Beustimport org.testng.xml.XmlClass;
23336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beustimport org.testng.xml.XmlTest;
24336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust
25d001f3960f66312b94dcb7bae88c92158eb38a75Cédric Beustimport java.lang.annotation.Annotation;
264ed682a9019c3063c60dea4ff9cba5fcf6482f08Julien Herrimport java.lang.reflect.Constructor;
279337911f6e208401d05bd915540af04439fa8bf2Cédric Beustimport java.util.List;
289337911f6e208401d05bd915540af04439fa8bf2Cédric Beustimport java.util.Map;
299337911f6e208401d05bd915540af04439fa8bf2Cédric Beust
30336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust/**
31336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust * Implementation of an IClass.
320f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin *
33336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust * @author <a href="mailto:cedric@beust.com">Cedric Beust</a>
34336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust */
35336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beustpublic class ClassImpl implements IClass {
361963187da6a45f898e62e4e922faac6b9382b4e4nullin  private static final long serialVersionUID = 1118178273317520344L;
37336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  transient private Class m_class = null;
38336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  transient private Object m_defaultInstance = null;
39336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  private XmlTest m_xmlTest = null;
40336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  transient private IAnnotationFinder m_annotationFinder = null;
41ed0917f31f0b66158bc786cd018fd95175f76f29Cédric Beust  transient private List<Object> m_instances = Lists.newArrayList();
42336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  transient private Map<Class, IClass> m_classes = null;
43336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  private int m_instanceCount;
44336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  private long[] m_instanceHashCodes;
459337911f6e208401d05bd915540af04439fa8bf2Cédric Beust  private transient Object m_instance;
46ed65240afc7792175d9fe09bb9bb553360798ae8Cédric Beust  private ITestObjectFactory m_objectFactory;
479f2367a1c4b17a5b38fb6fa209b717fb42d4faccCédric Beust  private String m_testName = null;
48682629c7059fca8adc2cc2eacdb2d372d7a28c3dCédric Beust  private XmlClass m_xmlClass;
49b44cd9ee2acc5dcd25d3aca8bc33cbb2e564b339Cédric Beust  private ITestContext m_testContext;
5021c6d08b4857e3c9d3d2d21934f35cf787e013a5Dariusz Luksza  private final boolean m_hasParentModule;
51df7f78b6a19dcc515afbb928a22e0de6295eefadbileblog
52b44cd9ee2acc5dcd25d3aca8bc33cbb2e564b339Cédric Beust  public ClassImpl(ITestContext context, Class cls, XmlClass xmlClass, Object instance,
53b44cd9ee2acc5dcd25d3aca8bc33cbb2e564b339Cédric Beust      Map<Class, IClass> classes, XmlTest xmlTest, IAnnotationFinder annotationFinder,
54b44cd9ee2acc5dcd25d3aca8bc33cbb2e564b339Cédric Beust      ITestObjectFactory objectFactory) {
55b44cd9ee2acc5dcd25d3aca8bc33cbb2e564b339Cédric Beust    m_testContext = context;
56336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    m_class = cls;
57336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    m_classes = classes;
58682629c7059fca8adc2cc2eacdb2d372d7a28c3dCédric Beust    m_xmlClass = xmlClass;
59336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    m_xmlTest = xmlTest;
60336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    m_annotationFinder = annotationFinder;
61336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    m_instance = instance;
62df7f78b6a19dcc515afbb928a22e0de6295eefadbileblog    m_objectFactory = objectFactory;
639f2367a1c4b17a5b38fb6fa209b717fb42d4faccCédric Beust    if (instance instanceof ITest) {
649f2367a1c4b17a5b38fb6fa209b717fb42d4faccCédric Beust      m_testName = ((ITest) instance).getTestName();
659f2367a1c4b17a5b38fb6fa209b717fb42d4faccCédric Beust    }
6606ee812f9dbb2e780083c3909e1618e49431209eJulien Herr    if (m_testName == null) {
6706ee812f9dbb2e780083c3909e1618e49431209eJulien Herr      ITestAnnotation annotation = m_annotationFinder.findAnnotation(cls, ITestAnnotation.class);
6806ee812f9dbb2e780083c3909e1618e49431209eJulien Herr      if (annotation != null) {
6906ee812f9dbb2e780083c3909e1618e49431209eJulien Herr        m_testName = annotation.getTestName();
7006ee812f9dbb2e780083c3909e1618e49431209eJulien Herr      }
7106ee812f9dbb2e780083c3909e1618e49431209eJulien Herr    }
7221c6d08b4857e3c9d3d2d21934f35cf787e013a5Dariusz Luksza    m_hasParentModule = isStringNotEmpty(m_testContext.getSuite().getParentModule());
73336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  }
74682629c7059fca8adc2cc2eacdb2d372d7a28c3dCédric Beust
75336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  private static void ppp(String s) {
76336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    System.out.println("[ClassImpl] " + s);
77336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  }
789f2367a1c4b17a5b38fb6fa209b717fb42d4faccCédric Beust
799337911f6e208401d05bd915540af04439fa8bf2Cédric Beust  @Override
809f2367a1c4b17a5b38fb6fa209b717fb42d4faccCédric Beust  public String getTestName() {
819f2367a1c4b17a5b38fb6fa209b717fb42d4faccCédric Beust    return m_testName;
829f2367a1c4b17a5b38fb6fa209b717fb42d4faccCédric Beust  }
839f2367a1c4b17a5b38fb6fa209b717fb42d4faccCédric Beust
849337911f6e208401d05bd915540af04439fa8bf2Cédric Beust  @Override
85336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  public String getName() {
86336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    return m_class.getName();
87336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  }
88336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust
899337911f6e208401d05bd915540af04439fa8bf2Cédric Beust  @Override
90336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  public Class getRealClass() {
91336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    return m_class;
92336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  }
93336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust
949337911f6e208401d05bd915540af04439fa8bf2Cédric Beust  @Override
95336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  public int getInstanceCount() {
96336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    return m_instanceCount;
97336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  }
98682629c7059fca8adc2cc2eacdb2d372d7a28c3dCédric Beust
999337911f6e208401d05bd915540af04439fa8bf2Cédric Beust  @Override
100336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  public long[] getInstanceHashCodes() {
101336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    return m_instanceHashCodes;
102336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  }
103682629c7059fca8adc2cc2eacdb2d372d7a28c3dCédric Beust
1049337911f6e208401d05bd915540af04439fa8bf2Cédric Beust  @Override
105682629c7059fca8adc2cc2eacdb2d372d7a28c3dCédric Beust  public XmlTest getXmlTest() {
106682629c7059fca8adc2cc2eacdb2d372d7a28c3dCédric Beust    return m_xmlTest;
107682629c7059fca8adc2cc2eacdb2d372d7a28c3dCédric Beust  }
108682629c7059fca8adc2cc2eacdb2d372d7a28c3dCédric Beust
1099337911f6e208401d05bd915540af04439fa8bf2Cédric Beust  @Override
110682629c7059fca8adc2cc2eacdb2d372d7a28c3dCédric Beust  public XmlClass getXmlClass() {
111682629c7059fca8adc2cc2eacdb2d372d7a28c3dCédric Beust    return m_xmlClass;
112682629c7059fca8adc2cc2eacdb2d372d7a28c3dCédric Beust  }
113682629c7059fca8adc2cc2eacdb2d372d7a28c3dCédric Beust
114336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  private Object getDefaultInstance() {
115336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    if (m_defaultInstance == null) {
116d001f3960f66312b94dcb7bae88c92158eb38a75Cédric Beust      if (m_instance != null) {
117d001f3960f66312b94dcb7bae88c92158eb38a75Cédric Beust        m_defaultInstance = m_instance;
118d001f3960f66312b94dcb7bae88c92158eb38a75Cédric Beust      } else {
119d001f3960f66312b94dcb7bae88c92158eb38a75Cédric Beust        Object instance = getInstanceFromGuice();
120d001f3960f66312b94dcb7bae88c92158eb38a75Cédric Beust
121d001f3960f66312b94dcb7bae88c92158eb38a75Cédric Beust        if (instance != null) {
122d001f3960f66312b94dcb7bae88c92158eb38a75Cédric Beust          m_defaultInstance = instance;
123d001f3960f66312b94dcb7bae88c92158eb38a75Cédric Beust        } else {
1244438e4fa82ea3d7d8623d11156657d119cddaa14Cédric Beust          m_defaultInstance =
1254438e4fa82ea3d7d8623d11156657d119cddaa14Cédric Beust              ClassHelper.createInstance(m_class, m_classes, m_xmlTest,
1264438e4fa82ea3d7d8623d11156657d119cddaa14Cédric Beust                  m_annotationFinder, m_objectFactory);
127d001f3960f66312b94dcb7bae88c92158eb38a75Cédric Beust        }
128d001f3960f66312b94dcb7bae88c92158eb38a75Cédric Beust      }
129336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    }
130682629c7059fca8adc2cc2eacdb2d372d7a28c3dCédric Beust
131336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    return m_defaultInstance;
132336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  }
133682629c7059fca8adc2cc2eacdb2d372d7a28c3dCédric Beust
134d001f3960f66312b94dcb7bae88c92158eb38a75Cédric Beust  /**
135d001f3960f66312b94dcb7bae88c92158eb38a75Cédric Beust   * @return an instance from Guice if @Test(guiceModule) attribute was found, null otherwise
136d001f3960f66312b94dcb7bae88c92158eb38a75Cédric Beust   */
137ad7277dd257bb43edb833bc2f526269df155a846Cédric Beust  @SuppressWarnings("unchecked")
138d001f3960f66312b94dcb7bae88c92158eb38a75Cédric Beust  private Object getInstanceFromGuice() {
1399270c7a2b3898b4cb6048a69fc958530ab2fd825Julien Herr    Injector injector = m_testContext.getInjector(this);
1405816aa6e67aa9ae07024c7cbf99f6ea845e59990Julien Herr    if (injector == null) return null;
141b3a4d753d567c7c8f6c78a7f0a9fb6641b96788cCédric Beust    return injector.getInstance(m_class);
142d001f3960f66312b94dcb7bae88c92158eb38a75Cédric Beust  }
143d001f3960f66312b94dcb7bae88c92158eb38a75Cédric Beust
14421c6d08b4857e3c9d3d2d21934f35cf787e013a5Dariusz Luksza  public Injector getParentInjector() {
14521c6d08b4857e3c9d3d2d21934f35cf787e013a5Dariusz Luksza    ISuite suite = m_testContext.getSuite();
14621c6d08b4857e3c9d3d2d21934f35cf787e013a5Dariusz Luksza    // Reuse the previous parent injector, if any
14721c6d08b4857e3c9d3d2d21934f35cf787e013a5Dariusz Luksza    Injector injector = suite.getParentInjector();
14821c6d08b4857e3c9d3d2d21934f35cf787e013a5Dariusz Luksza    if (injector == null) {
1491f23509ed2d8806b5bb8c85497fe7027eeee7745cguillaume      String stageString = suite.getGuiceStage();
1501f23509ed2d8806b5bb8c85497fe7027eeee7745cguillaume      Stage stage;
1511f23509ed2d8806b5bb8c85497fe7027eeee7745cguillaume      if (isStringNotEmpty(stageString)) {
1521f23509ed2d8806b5bb8c85497fe7027eeee7745cguillaume        stage = Stage.valueOf(stageString);
1531f23509ed2d8806b5bb8c85497fe7027eeee7745cguillaume      } else {
1541f23509ed2d8806b5bb8c85497fe7027eeee7745cguillaume        stage = Stage.DEVELOPMENT;
1551f23509ed2d8806b5bb8c85497fe7027eeee7745cguillaume      }
15621c6d08b4857e3c9d3d2d21934f35cf787e013a5Dariusz Luksza      if (m_hasParentModule) {
1574ed682a9019c3063c60dea4ff9cba5fcf6482f08Julien Herr        Class<Module> parentModule = (Class<Module>) ClassHelper.forName(suite.getParentModule());
15821c6d08b4857e3c9d3d2d21934f35cf787e013a5Dariusz Luksza        if (parentModule == null) {
15921c6d08b4857e3c9d3d2d21934f35cf787e013a5Dariusz Luksza          throw new TestNGException("Cannot load parent Guice module class: " + parentModule);
16021c6d08b4857e3c9d3d2d21934f35cf787e013a5Dariusz Luksza        }
161d19ca1bedce11f7ef9dec023f1f393f2981f4622Julien Herr        Module module = newModule(parentModule);
1621f23509ed2d8806b5bb8c85497fe7027eeee7745cguillaume        injector = com.google.inject.Guice.createInjector(stage, module);
16321c6d08b4857e3c9d3d2d21934f35cf787e013a5Dariusz Luksza      } else {
1641f23509ed2d8806b5bb8c85497fe7027eeee7745cguillaume        injector = com.google.inject.Guice.createInjector(stage);
16521c6d08b4857e3c9d3d2d21934f35cf787e013a5Dariusz Luksza      }
16621c6d08b4857e3c9d3d2d21934f35cf787e013a5Dariusz Luksza      suite.setParentInjector(injector);
16721c6d08b4857e3c9d3d2d21934f35cf787e013a5Dariusz Luksza    }
16821c6d08b4857e3c9d3d2d21934f35cf787e013a5Dariusz Luksza    return injector;
16921c6d08b4857e3c9d3d2d21934f35cf787e013a5Dariusz Luksza  }
17021c6d08b4857e3c9d3d2d21934f35cf787e013a5Dariusz Luksza
171d19ca1bedce11f7ef9dec023f1f393f2981f4622Julien Herr  private Module newModule(Class<Module> module) {
1724ed682a9019c3063c60dea4ff9cba5fcf6482f08Julien Herr    try {
1734ed682a9019c3063c60dea4ff9cba5fcf6482f08Julien Herr      Constructor<Module> moduleConstructor = module.getDeclaredConstructor(ITestContext.class);
1744ed682a9019c3063c60dea4ff9cba5fcf6482f08Julien Herr      return ClassHelper.newInstance(moduleConstructor, m_testContext);
1754ed682a9019c3063c60dea4ff9cba5fcf6482f08Julien Herr    } catch (NoSuchMethodException e) {
1764ed682a9019c3063c60dea4ff9cba5fcf6482f08Julien Herr      return ClassHelper.newInstance(module);
1774ed682a9019c3063c60dea4ff9cba5fcf6482f08Julien Herr    }
1784ed682a9019c3063c60dea4ff9cba5fcf6482f08Julien Herr  }
1794ed682a9019c3063c60dea4ff9cba5fcf6482f08Julien Herr
1809337911f6e208401d05bd915540af04439fa8bf2Cédric Beust  @Override
181336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  public Object[] getInstances(boolean create) {
182336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    Object[] result = {};
183682629c7059fca8adc2cc2eacdb2d372d7a28c3dCédric Beust
184336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    if (m_xmlTest.isJUnit()) {
185336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      if (create) {
186682629c7059fca8adc2cc2eacdb2d372d7a28c3dCédric Beust        result = new Object[] { ClassHelper.createInstance(m_class, m_classes,
187682629c7059fca8adc2cc2eacdb2d372d7a28c3dCédric Beust            m_xmlTest, m_annotationFinder, m_objectFactory) };
188336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      }
189682629c7059fca8adc2cc2eacdb2d372d7a28c3dCédric Beust    } else {
190336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      result = new Object[] { getDefaultInstance() };
191336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    }
192336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    if (m_instances.size() > 0) {
193336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      result = m_instances.toArray(new Object[m_instances.size()]);
194336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    }
195336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust
196336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    m_instanceCount = m_instances.size();
197336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    m_instanceHashCodes = new long[m_instanceCount];
198336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    for (int i = 0; i < m_instanceCount; i++) {
199336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      m_instanceHashCodes[i] = m_instances.get(i).hashCode();
200336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    }
201336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    return result;
202336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  }
203682629c7059fca8adc2cc2eacdb2d372d7a28c3dCédric Beust
204336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  @Override
205336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  public String toString() {
20654a1dff85605912356caf3c3bcc4f73e80fd1311Cédric Beust    return Objects.toStringHelper(getClass())
20754a1dff85605912356caf3c3bcc4f73e80fd1311Cédric Beust        .add("class", m_class.getName())
20854a1dff85605912356caf3c3bcc4f73e80fd1311Cédric Beust        .toString();
209336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  }
210336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust
2119337911f6e208401d05bd915540af04439fa8bf2Cédric Beust  @Override
212336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  public void addInstance(Object instance) {
213336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    m_instances.add(instance);
214336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  }
215336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust
216336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust}
217