View Javadoc

1   package com.atlassian.pageobjects.internal.elements.search;
2   
3   import com.atlassian.pageobjects.PageBinder;
4   import com.atlassian.pageobjects.PageObjects;
5   import com.atlassian.pageobjects.elements.query.Conditions;
6   import com.atlassian.pageobjects.elements.query.Queries;
7   import com.atlassian.pageobjects.elements.query.TimedCondition;
8   import com.atlassian.pageobjects.elements.query.TimedQuery;
9   import com.atlassian.pageobjects.elements.search.AnyQuery;
10  import com.atlassian.pageobjects.elements.search.SearchQuery;
11  import com.atlassian.pageobjects.elements.timeout.Timeouts;
12  import com.google.common.base.Function;
13  import com.google.common.base.Predicate;
14  import com.google.common.base.Supplier;
15  import com.google.common.collect.FluentIterable;
16  import com.google.common.collect.Iterables;
17  
18  import javax.annotation.Nonnull;
19  import javax.annotation.Nullable;
20  import javax.inject.Inject;
21  
22  import static com.google.common.base.Preconditions.checkNotNull;
23  import static com.google.common.collect.Iterables.getFirst;
24  
25  public abstract class AbstractSearchQuery<E, Q extends SearchQuery<E, Q>> implements SearchQuery<E, Q>
26  {
27      @Inject
28      protected Timeouts timeouts;
29  
30      @Inject
31      protected PageBinder pageBinder;
32  
33      protected final Supplier<Iterable<E>> querySupplier;
34  
35      protected AbstractSearchQuery(@Nonnull Supplier<Iterable<E>> querySupplier)
36      {
37          this.querySupplier = checkNotNull(querySupplier, "querySupplier");
38      }
39  
40      @Nonnull
41      @Override
42      public final Q filter(@Nonnull final Predicate<? super E> predicate)
43      {
44          return newInstance(new Supplier<Iterable<E>>()
45          {
46              @Override
47              public Iterable<E> get()
48              {
49                  return Iterables.filter(querySupplier.get(), predicate);
50              }
51          });
52      }
53  
54      @Nonnull
55      @Override
56      public final <F> AnyQuery<F> map(@Nonnull final Function<? super E, F> mapper)
57      {
58          return newAnyQueryInstance(mapSupplier(mapper));
59      }
60  
61      @Nonnull
62      @Override
63      public final <F> AnyQuery<F> flatMap(@Nonnull final Function<? super E, Iterable<F>> mapper)
64      {
65          return newAnyQueryInstance(flatMapSupplier(mapper));
66      }
67  
68      @Nonnull
69      @Override
70      public final <F> AnyQuery<F> bindTo(@Nonnull Class<F> pageObjectClass, @Nonnull Object... extraArgs)
71      {
72          return map(PageObjects.bindTo(pageBinder, pageObjectClass, extraArgs));
73      }
74  
75      @Override
76      public final Iterable<E> get()
77      {
78          return getResultNow();
79      }
80  
81      @Nullable
82      @Override
83      public final E first()
84      {
85          return getFirst(getResultNow(), null);
86      }
87  
88      @Nonnull
89      @Override
90      public final Iterable<E> now()
91      {
92          return getResultNow();
93      }
94  
95      @Nonnull
96      @Override
97      public final TimedCondition hasResult()
98      {
99          return Conditions.forSupplier(timeouts, new Supplier<Boolean>()
100         {
101             @Override
102             public Boolean get()
103             {
104                 return hasResultNow();
105             }
106         });
107     }
108 
109     @Nonnull
110     @Override
111     public final TimedQuery<Iterable<E>> timed()
112     {
113         return Queries.forSupplier(timeouts, new Supplier<Iterable<E>>()
114         {
115             @Override
116             public Iterable<E> get()
117             {
118                 return getResultNow();
119             }
120         });
121     }
122 
123     @Nonnull
124     protected abstract Q newInstance(@Nonnull Supplier<Iterable<E>> supplier);
125 
126     @Nonnull
127     protected abstract <F> AnyQuery<F> newAnyQueryInstance(@Nonnull Supplier<Iterable<F>> supplier);
128 
129     protected final <F> Supplier<Iterable<F>> flatMapSupplier(@Nonnull final Function<? super E, Iterable<F>> mapper)
130     {
131         return new Supplier<Iterable<F>>()
132         {
133             @Override
134             public Iterable<F> get()
135             {
136                 return FluentIterable.from(querySupplier.get()).transformAndConcat(mapper);
137             }
138         };
139     }
140 
141     protected final <F> Supplier<Iterable<F>> mapSupplier(@Nonnull final Function<? super E, F> mapper)
142     {
143         return new Supplier<Iterable<F>>()
144         {
145             @Override
146             public Iterable<F> get()
147             {
148                 return Iterables.transform(querySupplier.get(), mapper);
149             }
150         };
151     }
152 
153     private Iterable<E> getResultNow()
154     {
155         return querySupplier.get();
156     }
157 
158     private boolean hasResultNow()
159     {
160         return !Iterables.isEmpty(getResultNow());
161     }
162 }