1 package com.atlassian.pageobjects;
2
3 import com.google.common.base.Supplier;
4
5 import java.lang.reflect.Constructor;
6 import java.lang.reflect.InvocationTargetException;
7 import java.net.InetAddress;
8 import java.net.UnknownHostException;
9
10
11
12
13
14
15
16
17 public class TestedProductFactory
18 {
19
20
21
22
23 public static interface TesterFactory<T>
24 {
25
26
27
28 T create();
29 }
30
31
32
33
34
35 public static class SingletonTesterFactory<T extends Tester> implements TesterFactory<T>
36 {
37 private final T tester;
38
39 public SingletonTesterFactory(T tester)
40 {
41 this.tester = tester;
42 }
43
44 public T create()
45 {
46 return tester;
47 }
48 }
49
50 public static <T extends TestedProduct<?>> Supplier<T> fromFactory(final Class<T> productClass)
51 {
52 return new Supplier<T>()
53 {
54 @Override
55 public T get()
56 {
57 return create(productClass);
58 }
59 };
60 }
61
62
63
64
65
66
67 @SuppressWarnings("unchecked")
68 public static TestedProduct<?> create(String testedProductClass)
69 {
70 Class<TestedProduct<?>> clazz;
71 try
72 {
73 clazz = (Class<TestedProduct<?>>) TestedProductFactory.class.getClassLoader().loadClass(testedProductClass);
74 }
75 catch (ClassNotFoundException e)
76 {
77 throw new IllegalArgumentException("Cannot find tested product class: " + testedProductClass);
78 }
79 return create(clazz);
80 }
81
82
83
84
85
86
87
88 public static <P extends TestedProduct<?>> P create(Class<P> testedProductClass)
89 {
90 return create(testedProductClass, getDefaultInstanceId(testedProductClass), null);
91 }
92
93
94
95
96
97
98
99
100
101 public static <P extends TestedProduct<?>> P create(Class<P> testedProductClass, String instanceId, TesterFactory<?> testerFactory)
102 {
103 final String contextPath, baseUrl;
104 final int httpPort;
105
106 final String ampsBaseUrl = System.getProperty("baseurl." + instanceId);
107 final ProductInstance instance;
108 if (ampsBaseUrl != null)
109 {
110 httpPort = Integer.getInteger("http." + instanceId + ".port");
111 contextPath = System.getProperty("context." + instanceId + ".path");
112 baseUrl = ampsBaseUrl;
113 }
114 else
115 {
116 Defaults defaults = getDefaultsAnnotation(testedProductClass);
117 httpPort = defaults.httpPort();
118 contextPath = defaults.contextPath();
119 baseUrl = "http://" + getLocalHostName() + ":" + httpPort + contextPath;
120 }
121 instance = new DefaultProductInstance(baseUrl, instanceId, httpPort, contextPath);
122 return create(testedProductClass, instance, testerFactory);
123 }
124
125 private static String getDefaultInstanceId(Class<?> testedProductClass)
126 {
127 Defaults annotation = getDefaultsAnnotation(testedProductClass);
128 return annotation.instanceId();
129 }
130
131 private static Defaults getDefaultsAnnotation(Class<?> testedProductClass)
132 {
133 Defaults annotation = testedProductClass.getAnnotation(Defaults.class);
134 if (annotation == null)
135 {
136 throw new IllegalArgumentException("The tested product class '" + testedProductClass.getName() + "' is missing the @Defaults annotation");
137 }
138 return annotation;
139 }
140
141
142
143
144
145
146
147
148
149 public static <P extends TestedProduct<?>> P create(Class<P> testedProductClass, ProductInstance productInstance, TesterFactory<?> testerFactory) {
150 try
151 {
152 Constructor<P> c = testedProductClass.getConstructor(TesterFactory.class, ProductInstance.class);
153 return c.newInstance(testerFactory, productInstance);
154 }
155 catch (NoSuchMethodException e)
156 {
157 throw new RuntimeException(e);
158 }
159 catch (InvocationTargetException e)
160 {
161 throw new RuntimeException(e);
162 }
163 catch (InstantiationException e)
164 {
165 throw new RuntimeException(e);
166 }
167 catch (IllegalAccessException e)
168 {
169 throw new RuntimeException(e);
170 }
171 }
172
173 private static String getLocalHostName()
174 {
175 try
176 {
177 return InetAddress.getLocalHost().getHostName();
178 }
179 catch (UnknownHostException e)
180 {
181 throw new RuntimeException(e);
182 }
183 }
184
185 }