View Javadoc

1   /**
2    * .
3    */
4   package org.sirius.client.win32.classes;
5   
6   import java.lang.annotation.Annotation;
7   import java.lang.reflect.Constructor;
8   import java.lang.reflect.Field;
9   import java.lang.reflect.InvocationTargetException;
10  import java.lang.reflect.Method;
11  import java.rmi.RemoteException;
12  import java.util.Date;
13  
14  import org.apache.axis.types.UnsignedShort;
15  import org.apache.log4j.ConsoleAppender;
16  import org.apache.log4j.Logger;
17  import org.apache.log4j.SimpleLayout;
18  import org.sirius.client.win32.Win32Client;
19  import org.sirius.client.win32.annotations.Locator;
20  import org.sirius.client.win32.core.types.Rect;
21  import org.sirius.client.win32.types.Win32Locator;
22  
23  import com.sun.jna.platform.win32.WinUser;
24  
25  /**
26   * @author Myk Kolisnyk .
27   */
28  public class Window implements WinUser {
29  
30      /**
31       * .
32       */
33      private Win32Client  client;
34      /**
35       * .
36       */
37      private Win32Locator locator;
38      /**
39       * .
40       */
41      private Window       parent;
42  
43      /**
44       * .
45       */
46      private Logger       logger;
47  
48      /**
49       * @return the client
50       */
51      public final Win32Client getClient() {
52          return client;
53      }
54  
55      /**
56       * @param clientValue
57       *            the client to set
58       */
59      public final void setClient(final Win32Client clientValue) {
60          this.client = clientValue;
61      }
62  
63      /**
64       * @return the logger
65       */
66      public final Logger getLogger() {
67          return logger;
68      }
69  
70      /**
71       * @param locatorValue
72       *            the locator to set
73       */
74      public final void setLocator(final Win32Locator locatorValue) {
75          this.locator = locatorValue;
76      }
77  
78      /**
79       * @param parentValue
80       *            the parent to set
81       */
82      public final void setParent(final Window parentValue) {
83          this.parent = parentValue;
84      }
85  
86      /**
87       * .
88       * 
89       * @param clientValue
90       *            .
91       * @param locatorValue
92       *            .
93       * @throws Exception
94       */
95      public Window(final Win32Client clientValue, final Win32Locator locatorValue) {
96          this(clientValue, null, locatorValue);
97      }
98  
99      /**
100      * .
101      * 
102      * @param clientValue
103      *            .
104      * @param parentValue
105      *            .
106      * @param locatorValue
107      *            .
108      * @throws Exception
109      */
110     public Window(final Win32Client clientValue, final Window parentValue,
111             final Win32Locator locatorValue) {
112         this.client = clientValue;
113         this.locator = locatorValue;
114         this.parent = parentValue;
115         logger = Logger.getLogger(this.getClass());
116         logger.addAppender(new ConsoleAppender(new SimpleLayout()));
117 
118         logger.debug("Initializing instance");
119         this.initializeElements(this);
120     }
121 
122     /**
123      * .
124      * 
125      * @param parentValue
126      *            .
127      * @param locatorValue
128      *            .
129      * @throws Exception
130      */
131     public Window(final Window parentValue, final Win32Locator locatorValue) {
132         client = null;
133         this.locator = locatorValue;
134         this.parent = parentValue;
135         logger = Logger.getLogger(this.getClass());
136         logger.addAppender(new ConsoleAppender(new SimpleLayout()));
137 
138         logger.debug("Initializing instance");
139         if (parent != null) {
140             client = parent.client;
141         }
142         this.initializeElements(this);
143     }
144 
145     /**
146      * .
147      * 
148      * @throws Exception .
149      */
150     public final void click() throws Exception {
151         if (!exists()) {
152             return;
153         }
154         client.core().window()
155                 .click(locator.getHwnd(), 0, 0, 0, false, false, false);
156     }
157 
158     /**
159      * .
160      * 
161      * @return .
162      * @throws Exception .
163      */
164     public final boolean disappears() throws Exception {
165         return !exists();
166     }
167 
168     /**
169      * .
170      * 
171      * @param timeout
172      *            .
173      * @return .
174      * @throws Exception .
175      */
176     public final boolean disappears(final long timeout) throws Exception {
177         return waitFor(timeout, "disappears", true);
178     }
179 
180     /**
181      * .
182      * 
183      * @return .
184      * @throws RemoteException .
185      */
186     public boolean exists() throws RemoteException {
187         logger.debug(String.format("Searching for window: %s", locator));
188 
189         if (parent != null) {
190             logger.debug(String.format("Searching for parent window: %s",
191                     parent.getLocator()));
192 
193             if (!parent.exists()) {
194                 logger.debug(String
195                         .format("Parent window doesn't exist. Returning false"));
196                 return false;
197             } else {
198                 logger.debug(String.format("The parent window was found: %s. "
199                         + "Looking for current window: %s",
200                         parent.getLocator(), this.getLocator()));
201                 locator.setParent(parent.getHwnd());
202             }
203         }
204 
205         locator.setHwnd(0);
206         if (parent != null) {
207             client = parent.client;
208         }
209 
210         long hwnd = 0;
211         logger.debug(String.format("Searching for window: %s", locator));
212         try {
213             hwnd = client.utils().searchWindow(locator);
214         } catch (Throwable e) {
215             logger.debug(
216                     String.format("Error while searching for window", locator),
217                     e);
218         }
219         logger.debug(String.format("HWND returned: %d", hwnd));
220         if (hwnd != 0) {
221             locator.setHwnd(hwnd);
222 
223             logger.debug(String.format("Window found: %s", locator));
224 
225             return true;
226         } else {
227             locator.setHwnd(0);
228         }
229 
230         logger.debug(String.format("Window wasn't found"));
231 
232         return false;
233     }
234 
235     /**
236      * .
237      * 
238      * @param timeout
239      *            .
240      * @return .
241      * @throws Exception .
242      */
243     public boolean exists(final long timeout) throws Exception {
244         return waitFor(timeout, "exists", true);
245     }
246 
247     /**
248      * .
249      * 
250      * @param params
251      *            .
252      * @return .
253      */
254     private Class<?>[] getArrayTypes(final Object... params) {
255         Class<?>[] types = new Class[params.length];
256         for (int i = 0; i < params.length; i++) {
257             types[i] = params[i].getClass();
258         }
259         return types;
260     }
261 
262     /**
263      * .
264      * 
265      * @return .
266      * @throws Exception .
267      */
268     public final Rect getClientRect() throws Exception {
269         Rect rc = client.core().window().getClientRect(locator.getHwnd());
270         return rc;
271     }
272 
273     /**
274      * .
275      * 
276      * @return .
277      */
278     public final long getHwnd() {
279         return locator.getHwnd();
280     }
281 
282     /**
283      * .
284      * 
285      * @return .
286      */
287     public final Win32Locator getLocator() {
288         return locator;
289     }
290 
291     /**
292      * .
293      * 
294      * @param text
295      *            .
296      * @return .
297      */
298     protected final String getNativeText(final UnsignedShort[] text) {
299         char[] convertedText = new char[text.length];
300         for (int i = 0; i < text.length; i++) {
301             convertedText[i] = (char) text[i].intValue();
302         }
303         return null;
304     }
305 
306     /**
307      * .
308      * 
309      * @return .
310      */
311     public final Window getParent() {
312         return parent;
313     }
314 
315     /**
316      * .
317      * 
318      * @return .
319      * @throws Exception .
320      */
321     public final Rect getRect() throws Exception {
322         Rect rc = client.core().window().getRect(locator.getHwnd());
323         return rc;
324     }
325 
326     public final void initializeElements(Window win) {
327         Class<? extends Window> clazz = win.getClass();
328         Field[] fields = clazz.getFields();
329         try {
330             for (Field field : fields) {
331                 getLogger().debug(String.format("Field %s", field.getName()));
332                 Locator tag = field.getAnnotation(Locator.class);
333                 if(tag == null){
334                     getLogger().debug("No annotations found");
335                     continue;
336                 }
337                 getLogger().debug(String.format("Locator found: (%s,%s,%d)", tag.winClass(),tag.caption(),tag.index()));
338                 
339                 Win32Locator locator = new Win32Locator(tag.winClass(),
340                         tag.caption(), tag.index());
341                 getLogger().debug("Creating object");
342                 //Window object = new Window(win.getClient(), win, locator);
343                 
344                 for(Constructor<?> construct:field.getType().getConstructors()){
345                     getLogger().debug("Constructor: " + construct.getName());
346                     for(Class<?> type:construct.getParameterTypes()){
347                         getLogger().debug("- arg: " + type.getName());
348                     }
349                 }
350                 Constructor<?> construct = null;
351                 Class<?> declaringClass = field.getType().getDeclaringClass();
352                 if( declaringClass != null ){
353                     construct = field.getType().getConstructor(declaringClass,Window.class,Win32Locator.class);
354                     getLogger().debug("Constructor created");
355                     field.set(win, construct.newInstance(win,win, locator)); 
356                 }
357                 else {
358                     construct = field.getType().getConstructor(Window.class,Win32Locator.class);
359                     getLogger().debug("Constructor created");
360                     field.set(win, construct.newInstance(win, locator));                    
361                 }
362                 getLogger().debug("Field is set");
363             }
364         } catch (Exception e) {
365             e.printStackTrace();
366         }
367         Aliases.set(win);
368     }
369 
370     /**
371      * .
372      * 
373      * @return .
374      */
375     public final boolean isActive() {
376         return false;
377     }
378 
379     /**
380      * .
381      * 
382      * @return .
383      * @throws Exception .
384      */
385     public final boolean isEnabled() throws Exception {
386         return client.core().window().isEnabled(locator.getHwnd());
387     }
388 
389     /**
390      * .
391      * 
392      * @param timeout
393      *            .
394      * @return .
395      * @throws Exception .
396      */
397     public final boolean isEnabled(final long timeout) throws Exception {
398         return waitFor(timeout, "isEnabled", true);
399     }
400 
401     /**
402      * .
403      * 
404      * @return .
405      * @throws Exception .
406      */
407     public final boolean isVisible() throws Exception {
408         return client.core().window().isVisible(locator.getHwnd());
409     }
410 
411     /**
412      * .
413      * 
414      * @param timeout
415      *            .
416      * @return .
417      * @throws Exception .
418      */
419     public final boolean isVisible(final long timeout) throws Exception {
420         return waitFor(timeout, "isVisible", true);
421     }
422 
423     /**
424      * .
425      */
426     public final void sendKeys() {
427     }
428 
429     /**
430      * .
431      * 
432      * @param text
433      *            .
434      * @throws Exception .
435      */
436     public final void typeKeys(final String text) throws Exception {
437         if (!exists()) {
438             return;
439         }
440         for (char key : text.toCharArray()) {
441             int code = key;
442             // TODO Add specific keys handling
443             client.core().window().keyPress(locator.getHwnd(), code);
444         }
445     }
446 
447     /**
448      * .
449      * 
450      * @param timeout
451      *            .
452      * @param methodName
453      *            .
454      * @param expectedValue
455      *            .
456      * @param params
457      *            .
458      * @return .
459      * @throws Exception .
460      */
461     public final boolean waitFor(final long timeout, final String methodName,
462             final Object expectedValue, final Object... params)
463             throws Exception {
464         long end = new Date().getTime() + timeout;
465         Class<?>[] parameterTypes = getArrayTypes(params);
466         while (new Date().getTime() < end) {
467             Method waitMethod = this.getClass().getMethod(methodName,
468                     parameterTypes);
469             Object result = waitMethod.invoke(this, params);
470             if (result.equals(expectedValue)) {
471                 return true;
472             }
473         }
474         return false;
475     }
476 }