EMMA Coverage Report (generated Tue Jun 21 05:51:52 EDT 2011)
[all classes][org.jclouds.compute.domain.internal]

COVERAGE SUMMARY FOR SOURCE FILE [TemplateBuilderImpl.java]

nameclass, %method, %block, %line, %
TemplateBuilderImpl.java100% (24/24)61%  (61/100)59%  (1137/1920)58%  (173.9/302)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class TemplateBuilderImpl$11100% (1/1)33%  (1/3)10%  (6/58)12%  (1/8)
apply (Image): boolean 0%   (0/1)0%   (0/39)0%   (0/6)
toString (): String 0%   (0/1)0%   (0/13)0%   (0/1)
TemplateBuilderImpl$11 (TemplateBuilderImpl): void 100% (1/1)100% (6/6)100% (1/1)
     
class TemplateBuilderImpl$10100% (1/1)33%  (1/3)12%  (6/51)12%  (1/8)
apply (Image): boolean 0%   (0/1)0%   (0/32)0%   (0/6)
toString (): String 0%   (0/1)0%   (0/13)0%   (0/1)
TemplateBuilderImpl$10 (TemplateBuilderImpl): void 100% (1/1)100% (6/6)100% (1/1)
     
class TemplateBuilderImpl$4100% (1/1)33%  (1/3)12%  (6/51)12%  (1/8)
apply (OperatingSystem): boolean 0%   (0/1)0%   (0/32)0%   (0/6)
toString (): String 0%   (0/1)0%   (0/13)0%   (0/1)
TemplateBuilderImpl$4 (TemplateBuilderImpl): void 100% (1/1)100% (6/6)100% (1/1)
     
class TemplateBuilderImpl$5100% (1/1)33%  (1/3)12%  (6/51)12%  (1/8)
apply (OperatingSystem): boolean 0%   (0/1)0%   (0/32)0%   (0/6)
toString (): String 0%   (0/1)0%   (0/13)0%   (0/1)
TemplateBuilderImpl$5 (TemplateBuilderImpl): void 100% (1/1)100% (6/6)100% (1/1)
     
class TemplateBuilderImpl$6100% (1/1)33%  (1/3)12%  (6/51)12%  (1/8)
apply (OperatingSystem): boolean 0%   (0/1)0%   (0/32)0%   (0/6)
toString (): String 0%   (0/1)0%   (0/13)0%   (0/1)
TemplateBuilderImpl$6 (TemplateBuilderImpl): void 100% (1/1)100% (6/6)100% (1/1)
     
class TemplateBuilderImpl$9100% (1/1)33%  (1/3)12%  (6/51)12%  (1/8)
apply (Image): boolean 0%   (0/1)0%   (0/32)0%   (0/6)
toString (): String 0%   (0/1)0%   (0/13)0%   (0/1)
TemplateBuilderImpl$9 (TemplateBuilderImpl): void 100% (1/1)100% (6/6)100% (1/1)
     
class TemplateBuilderImpl$15100% (1/1)50%  (1/2)14%  (3/21)50%  (1/2)
compare (Hardware, Hardware): int 0%   (0/1)0%   (0/18)0%   (0/1)
TemplateBuilderImpl$15 (): void 100% (1/1)100% (3/3)100% (1/1)
     
class TemplateBuilderImpl$7100% (1/1)33%  (1/3)14%  (6/42)12%  (1/8)
apply (OperatingSystem): boolean 0%   (0/1)0%   (0/23)0%   (0/6)
toString (): String 0%   (0/1)0%   (0/13)0%   (0/1)
TemplateBuilderImpl$7 (TemplateBuilderImpl): void 100% (1/1)100% (6/6)100% (1/1)
     
class TemplateBuilderImpl$3100% (1/1)33%  (1/3)18%  (6/34)17%  (1/6)
apply (OperatingSystem): boolean 0%   (0/1)0%   (0/15)0%   (0/4)
toString (): String 0%   (0/1)0%   (0/13)0%   (0/1)
TemplateBuilderImpl$3 (TemplateBuilderImpl): void 100% (1/1)100% (6/6)100% (1/1)
     
class TemplateBuilderImpl$16100% (1/1)50%  (1/2)33%  (3/9)50%  (1/2)
compare (Hardware, Hardware): int 0%   (0/1)0%   (0/6)0%   (0/1)
TemplateBuilderImpl$16 (): void 100% (1/1)100% (3/3)100% (1/1)
     
class TemplateBuilderImpl$12100% (1/1)67%  (2/3)34%  (14/41)50%  (4/8)
toString (): String 0%   (0/1)0%   (0/13)0%   (0/1)
apply (Hardware): boolean 100% (1/1)36%  (8/22)50%  (3/6)
TemplateBuilderImpl$12 (TemplateBuilderImpl): void 100% (1/1)100% (6/6)100% (1/1)
     
class TemplateBuilderImpl$1100% (1/1)67%  (2/3)39%  (27/69)71%  (4.2/6)
toString (): String 0%   (0/1)0%   (0/13)0%   (0/1)
apply (ComputeMetadata): boolean 100% (1/1)42%  (21/50)81%  (3.2/4)
TemplateBuilderImpl$1 (TemplateBuilderImpl): void 100% (1/1)100% (6/6)100% (1/1)
     
class TemplateBuilderImpl$21100% (1/1)67%  (2/3)48%  (12/25)67%  (2/3)
toString (): String 0%   (0/1)0%   (0/13)0%   (0/1)
TemplateBuilderImpl$21 (TemplateBuilderImpl): void 100% (1/1)100% (6/6)100% (1/1)
apply (Image): boolean 100% (1/1)100% (6/6)100% (1/1)
     
class TemplateBuilderImpl$14100% (1/1)67%  (2/3)52%  (15/29)63%  (1.9/3)
toString (): String 0%   (0/1)0%   (0/13)0%   (0/1)
apply (Hardware): boolean 100% (1/1)90%  (9/10)90%  (0.9/1)
TemplateBuilderImpl$14 (TemplateBuilderImpl): void 100% (1/1)100% (6/6)100% (1/1)
     
class TemplateBuilderImpl$18100% (1/1)67%  (2/3)56%  (15/27)67%  (2/3)
toString (): String 0%   (0/1)0%   (0/12)0%   (0/1)
TemplateBuilderImpl$18 (TemplateBuilderImpl, String): void 100% (1/1)100% (9/9)100% (1/1)
apply (Location): boolean 100% (1/1)100% (6/6)100% (1/1)
     
class TemplateBuilderImpl$19$1100% (1/1)67%  (2/3)56%  (15/27)67%  (2/3)
toString (): String 0%   (0/1)0%   (0/12)0%   (0/1)
TemplateBuilderImpl$19$1 (TemplateBuilderImpl$19, Hardware): void 100% (1/1)100% (9/9)100% (1/1)
apply (Image): boolean 100% (1/1)100% (6/6)100% (1/1)
     
class TemplateBuilderImpl$20100% (1/1)67%  (2/3)56%  (15/27)67%  (2/3)
toString (): String 0%   (0/1)0%   (0/12)0%   (0/1)
TemplateBuilderImpl$20 (TemplateBuilderImpl, Hardware): void 100% (1/1)100% (9/9)100% (1/1)
apply (Image): boolean 100% (1/1)100% (6/6)100% (1/1)
     
class TemplateBuilderImpl$13100% (1/1)67%  (2/3)56%  (18/32)73%  (2.9/4)
toString (): String 0%   (0/1)0%   (0/13)0%   (0/1)
apply (Hardware): boolean 100% (1/1)92%  (12/13)96%  (1.9/2)
TemplateBuilderImpl$13 (TemplateBuilderImpl): void 100% (1/1)100% (6/6)100% (1/1)
     
class TemplateBuilderImpl$8100% (1/1)67%  (2/3)69%  (35/51)75%  (6/8)
toString (): String 0%   (0/1)0%   (0/13)0%   (0/1)
apply (OperatingSystem): boolean 100% (1/1)91%  (29/32)83%  (5/6)
TemplateBuilderImpl$8 (TemplateBuilderImpl): void 100% (1/1)100% (6/6)100% (1/1)
     
class TemplateBuilderImpl100% (1/1)69%  (24/35)76%  (788/1039)72%  (144.9/202)
any (): TemplateBuilder 0%   (0/1)0%   (0/5)0%   (0/1)
biggest (): TemplateBuilder 0%   (0/1)0%   (0/5)0%   (0/2)
fastest (): TemplateBuilder 0%   (0/1)0%   (0/5)0%   (0/2)
fromHardware (Hardware): TemplateBuilder 0%   (0/1)0%   (0/19)0%   (0/5)
fromTemplate (Template): TemplateBuilder 0%   (0/1)0%   (0/12)0%   (0/3)
hardwareId (String): TemplateBuilder 0%   (0/1)0%   (0/5)0%   (0/2)
minCores (double): TemplateBuilder 0%   (0/1)0%   (0/5)0%   (0/2)
minRam (int): TemplateBuilder 0%   (0/1)0%   (0/5)0%   (0/2)
os64Bit (boolean): TemplateBuilder 0%   (0/1)0%   (0/6)0%   (0/2)
osNameMatches (String): TemplateBuilder 0%   (0/1)0%   (0/5)0%   (0/2)
osVersionMatches (String): TemplateBuilder 0%   (0/1)0%   (0/5)0%   (0/2)
copyTemplateOptions (TemplateOptions, TemplateOptions): void 100% (1/1)42%  (35/83)52%  (11/21)
resolveImage (Hardware, Iterable): Image 100% (1/1)44%  (30/68)60%  (6/10)
fromImage (Image): TemplateBuilder 100% (1/1)51%  (42/83)55%  (11/20)
buildImagePredicate (): Predicate 100% (1/1)66%  (77/117)70%  (19/27)
hardwareSorter (): Ordering 100% (1/1)72%  (13/18)83%  (5/6)
currentLocationWiderThan (Location): boolean 100% (1/1)88%  (14/16)87%  (0.9/1)
<static initializer> 100% (1/1)100% (13/13)100% (3/3)
TemplateBuilderImpl (Supplier, Supplier, Supplier, Supplier, Provider, Provid... 100% (1/1)100% (133/133)100% (24/24)
access$000 (TemplateBuilderImpl): Predicate 100% (1/1)100% (3/3)100% (1/1)
build (): Template 100% (1/1)100% (108/108)100% (19/19)
getImages (): Set 100% (1/1)100% (5/5)100% (1/1)
imageDescriptionMatches (String): TemplateBuilder 100% (1/1)100% (5/5)100% (2/2)
imageId (String): TemplateBuilder 100% (1/1)100% (32/32)100% (11/11)
imageNameMatches (String): TemplateBuilder 100% (1/1)100% (5/5)100% (2/2)
imageVersionMatches (String): TemplateBuilder 100% (1/1)100% (5/5)100% (2/2)
locationId (String): TemplateBuilder 100% (1/1)100% (35/35)100% (6/6)
nothingChangedExceptOptions (): boolean 100% (1/1)100% (54/54)100% (1/1)
options (TemplateOptions): TemplateBuilder 100% (1/1)100% (16/16)100% (3/3)
osArchMatches (String): TemplateBuilder 100% (1/1)100% (5/5)100% (2/2)
osDescriptionMatches (String): TemplateBuilder 100% (1/1)100% (5/5)100% (2/2)
osFamily (OsFamily): TemplateBuilder 100% (1/1)100% (5/5)100% (2/2)
resolveSize (Ordering, Iterable): Hardware 100% (1/1)100% (56/56)100% (8/8)
smallest (): TemplateBuilder 100% (1/1)100% (5/5)100% (2/2)
toString (): String 100% (1/1)100% (87/87)100% (1/1)
     
class TemplateBuilderImpl$22100% (1/1)67%  (2/3)76%  (16/21)67%  (2/3)
toString (): String 0%   (0/1)0%   (0/5)0%   (0/1)
TemplateBuilderImpl$22 (TemplateBuilderImpl, List): void 100% (1/1)100% (9/9)100% (1/1)
apply (Image): boolean 100% (1/1)100% (7/7)100% (1/1)
     
class TemplateBuilderImpl$17100% (1/1)100% (2/2)100% (54/54)100% (2/2)
TemplateBuilderImpl$17 (): void 100% (1/1)100% (3/3)100% (1/1)
compare (Image, Image): int 100% (1/1)100% (51/51)100% (1/1)
     
class TemplateBuilderImpl$19100% (1/1)100% (2/2)100% (18/18)100% (2/2)
TemplateBuilderImpl$19 (TemplateBuilderImpl, Iterable): void 100% (1/1)100% (9/9)100% (1/1)
apply (Hardware): boolean 100% (1/1)100% (9/9)100% (1/1)
     
class TemplateBuilderImpl$2100% (1/1)100% (3/3)100% (41/41)100% (8/8)
TemplateBuilderImpl$2 (TemplateBuilderImpl): void 100% (1/1)100% (6/6)100% (1/1)
apply (Image): boolean 100% (1/1)100% (22/22)100% (6/6)
toString (): String 100% (1/1)100% (13/13)100% (1/1)

1/**
2 *
3 * Copyright (C) 2011 Cloud Conscious, LLC. <info@cloudconscious.com>
4 *
5 * ====================================================================
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 * ====================================================================
18 */
19package org.jclouds.compute.domain.internal;
20 
21import static com.google.common.base.Preconditions.checkNotNull;
22import static com.google.common.base.Predicates.and;
23import static com.google.common.collect.Iterables.filter;
24import static com.google.common.collect.Lists.newArrayList;
25import static org.jclouds.compute.util.ComputeServiceUtils.getCores;
26import static org.jclouds.compute.util.ComputeServiceUtils.getCoresAndSpeed;
27import static org.jclouds.compute.util.ComputeServiceUtils.getSpace;
28 
29import java.util.Arrays;
30import java.util.List;
31import java.util.NoSuchElementException;
32import java.util.Set;
33 
34import javax.annotation.Resource;
35import javax.inject.Inject;
36import javax.inject.Named;
37import javax.inject.Provider;
38 
39import org.jclouds.collect.Memoized;
40import org.jclouds.compute.domain.ComputeMetadata;
41import org.jclouds.compute.domain.Hardware;
42import org.jclouds.compute.domain.Image;
43import org.jclouds.compute.domain.OperatingSystem;
44import org.jclouds.compute.domain.OsFamily;
45import org.jclouds.compute.domain.Template;
46import org.jclouds.compute.domain.TemplateBuilder;
47import org.jclouds.compute.options.TemplateOptions;
48import org.jclouds.compute.reference.ComputeServiceConstants;
49import org.jclouds.domain.Location;
50import org.jclouds.logging.Logger;
51import org.jclouds.util.Lists2;
52 
53import com.google.common.annotations.VisibleForTesting;
54import com.google.common.base.Predicate;
55import com.google.common.base.Predicates;
56import com.google.common.base.Supplier;
57import com.google.common.collect.ComparisonChain;
58import com.google.common.collect.ImmutableList;
59import com.google.common.collect.Iterables;
60import com.google.common.collect.Ordering;
61import com.google.common.primitives.Doubles;
62 
63/**
64 * 
65 * @author Adrian Cole
66 */
67@SuppressWarnings("unchecked")
68public class TemplateBuilderImpl implements TemplateBuilder {
69 
70   @Resource
71   @Named(ComputeServiceConstants.COMPUTE_LOGGER)
72   protected Logger logger = Logger.NULL;
73 
74   protected final Supplier<Set<? extends Image>> images;
75   protected final Supplier<Set<? extends Hardware>> hardwares;
76   protected final Supplier<Set<? extends Location>> locations;
77   protected final Supplier<Location> defaultLocation;
78   protected final Provider<TemplateOptions> optionsProvider;
79   protected final Provider<TemplateBuilder> defaultTemplateProvider;
80 
81   @VisibleForTesting
82   protected Location location;
83   @VisibleForTesting
84   protected String imageId;
85   @VisibleForTesting
86   protected String hardwareId;
87   @VisibleForTesting
88   protected String imageVersion;
89   @VisibleForTesting
90   protected OsFamily osFamily;
91   @VisibleForTesting
92   protected String osVersion;
93   @VisibleForTesting
94   protected Boolean os64Bit;
95   @VisibleForTesting
96   protected String osName;
97   @VisibleForTesting
98   protected String osDescription;
99   @VisibleForTesting
100   protected String osArch;
101   @VisibleForTesting
102   protected String imageName;
103   @VisibleForTesting
104   protected String imageDescription;
105   @VisibleForTesting
106   protected double minCores;
107   @VisibleForTesting
108   protected int minRam;
109   @VisibleForTesting
110   protected boolean biggest;
111   @VisibleForTesting
112   protected boolean fastest;
113   @VisibleForTesting
114   protected TemplateOptions options;
115 
116   @Inject
117   protected TemplateBuilderImpl(@Memoized Supplier<Set<? extends Location>> locations,
118            @Memoized Supplier<Set<? extends Image>> images, @Memoized Supplier<Set<? extends Hardware>> hardwares,
119            Supplier<Location> defaultLocation2, Provider<TemplateOptions> optionsProvider,
120            @Named("DEFAULT") Provider<TemplateBuilder> defaultTemplateProvider) {
121      this.locations = locations;
122      this.images = images;
123      this.hardwares = hardwares;
124      this.defaultLocation = defaultLocation2;
125      this.optionsProvider = optionsProvider;
126      this.defaultTemplateProvider = defaultTemplateProvider;
127   }
128 
129   /**
130    * If the current location id is null, then we don't care where to launch a node.
131    * 
132    * If the input location is null, then the data isn't location sensitive
133    * 
134    * If the input location is a parent of the specified location, then we are ok.
135    */
136   private final Predicate<ComputeMetadata> locationPredicate = new Predicate<ComputeMetadata>() {
137      @Override
138      public boolean apply(ComputeMetadata input) {
139         boolean returnVal = true;
140         if (location != null && input.getLocation() != null)
141            returnVal = location.equals(input.getLocation()) || location.getParent() != null
142                     && location.getParent().equals(input.getLocation()) || location.getParent().getParent() != null
143                     && location.getParent().getParent().equals(input.getLocation());
144         return returnVal;
145      }
146 
147      @Override
148      public String toString() {
149         return "location(" + location + ")";
150      }
151   };
152 
153   private final Predicate<Image> idPredicate = new Predicate<Image>() {
154      @Override
155      public boolean apply(Image input) {
156         boolean returnVal = true;
157         if (imageId != null) {
158            returnVal = imageId.equals(input.getId());
159            // match our input params so that the later predicates pass.
160            if (returnVal) {
161               fromImage(input);
162            }
163         }
164         return returnVal;
165      }
166 
167      @Override
168      public String toString() {
169         return "imageId(" + imageId + ")";
170      }
171   };
172 
173   private final Predicate<OperatingSystem> osFamilyPredicate = new Predicate<OperatingSystem>() {
174 
175      @Override
176      public boolean apply(OperatingSystem input) {
177         boolean returnVal = true;
178         if (osFamily != null)
179            returnVal = osFamily.equals(input.getFamily());
180         return returnVal;
181      }
182 
183      @Override
184      public String toString() {
185         return "osFamily(" + osFamily + ")";
186      }
187   };
188 
189   private final Predicate<OperatingSystem> osNamePredicate = new Predicate<OperatingSystem>() {
190      @Override
191      public boolean apply(OperatingSystem input) {
192         boolean returnVal = true;
193         if (osName != null) {
194            if (input.getName() == null)
195               returnVal = false;
196            else
197               returnVal = input.getName().contains(osName) || input.getName().matches(osName);
198         }
199         return returnVal;
200      }
201 
202      @Override
203      public String toString() {
204         return "osName(" + osName + ")";
205      }
206   };
207 
208   private final Predicate<OperatingSystem> osDescriptionPredicate = new Predicate<OperatingSystem>() {
209      @Override
210      public boolean apply(OperatingSystem input) {
211         boolean returnVal = true;
212         if (osDescription != null) {
213            if (input.getDescription() == null)
214               returnVal = false;
215            else
216               returnVal = input.getDescription().contains(osDescription)
217                        || input.getDescription().matches(osDescription);
218         }
219         return returnVal;
220      }
221 
222      @Override
223      public String toString() {
224         return "osDescription(" + osDescription + ")";
225      }
226   };
227 
228   private final Predicate<OperatingSystem> osVersionPredicate = new Predicate<OperatingSystem>() {
229      @Override
230      public boolean apply(OperatingSystem input) {
231         boolean returnVal = true;
232         if (osVersion != null) {
233            if (input.getVersion() == null)
234               returnVal = false;
235            else
236               returnVal = input.getVersion().contains(osVersion) || input.getVersion().matches(osVersion);
237         }
238         return returnVal;
239      }
240 
241      @Override
242      public String toString() {
243         return "osVersion(" + osVersion + ")";
244      }
245   };
246 
247   private final Predicate<OperatingSystem> os64BitPredicate = new Predicate<OperatingSystem>() {
248      @Override
249      public boolean apply(OperatingSystem input) {
250         boolean returnVal = true;
251         if (os64Bit != null) {
252            if (os64Bit)
253               return input.is64Bit();
254            else
255               return !input.is64Bit();
256         }
257         return returnVal;
258      }
259 
260      @Override
261      public String toString() {
262         return "os64Bit(" + os64Bit + ")";
263      }
264   };
265 
266   private final Predicate<OperatingSystem> osArchPredicate = new Predicate<OperatingSystem>() {
267      @Override
268      public boolean apply(OperatingSystem input) {
269         boolean returnVal = true;
270         if (osArch != null) {
271            if (input.getArch() == null)
272               returnVal = false;
273            else
274               returnVal = input.getArch().contains(osArch) || input.getArch().matches(osArch);
275         }
276         return returnVal;
277      }
278 
279      @Override
280      public String toString() {
281         return "osArch(" + osArch + ")";
282      }
283   };
284 
285   private final Predicate<Image> imageVersionPredicate = new Predicate<Image>() {
286      @Override
287      public boolean apply(Image input) {
288         boolean returnVal = true;
289         if (imageVersion != null) {
290            if (input.getVersion() == null)
291               returnVal = false;
292            else
293               returnVal = input.getVersion().contains(imageVersion) || input.getVersion().matches(imageVersion);
294         }
295         return returnVal;
296      }
297 
298      @Override
299      public String toString() {
300         return "imageVersion(" + imageVersion + ")";
301      }
302   };
303 
304   private final Predicate<Image> imageNamePredicate = new Predicate<Image>() {
305      @Override
306      public boolean apply(Image input) {
307         boolean returnVal = true;
308         if (imageName != null) {
309            if (input.getName() == null)
310               returnVal = false;
311            else
312               returnVal = input.getName().contains(imageName) || input.getName().matches(imageName);
313         }
314         return returnVal;
315      }
316 
317      @Override
318      public String toString() {
319         return "imageName(" + imageName + ")";
320      }
321   };
322   private final Predicate<Image> imageDescriptionPredicate = new Predicate<Image>() {
323      @Override
324      public boolean apply(Image input) {
325         boolean returnVal = true;
326         if (imageDescription != null) {
327            if (input.getDescription() == null)
328               returnVal = false;
329            else
330               returnVal = input.getDescription().equals(imageDescription)
331                        || input.getDescription().contains(imageDescription)
332                        || input.getDescription().matches(imageDescription);
333         }
334         return returnVal;
335      }
336 
337      @Override
338      public String toString() {
339         return "imageDescription(" + imageDescription + ")";
340      }
341   };
342   private final Predicate<Hardware> hardwareIdPredicate = new Predicate<Hardware>() {
343      @Override
344      public boolean apply(Hardware input) {
345         boolean returnVal = true;
346         if (hardwareId != null) {
347            returnVal = hardwareId.equals(input.getId());
348            // match our input params so that the later predicates pass.
349            if (returnVal) {
350               fromHardware(input);
351            }
352         }
353         return returnVal;
354      }
355 
356      @Override
357      public String toString() {
358         return "hardwareId(" + hardwareId + ")";
359      }
360   };
361 
362   private final Predicate<Hardware> hardwareCoresPredicate = new Predicate<Hardware>() {
363      @Override
364      public boolean apply(Hardware input) {
365         double cores = getCores(input);
366         return cores >= TemplateBuilderImpl.this.minCores;
367      }
368 
369      @Override
370      public String toString() {
371         return "minCores(" + minCores + ")";
372      }
373   };
374 
375   private final Predicate<Hardware> hardwareRamPredicate = new Predicate<Hardware>() {
376      @Override
377      public boolean apply(Hardware input) {
378         return input.getRam() >= TemplateBuilderImpl.this.minRam;
379      }
380 
381      @Override
382      public String toString() {
383         return "minRam(" + minRam + ")";
384      }
385   };
386   private final Predicate<Hardware> hardwarePredicate = and(hardwareIdPredicate, locationPredicate,
387            hardwareCoresPredicate, hardwareRamPredicate);
388 
389   static final Ordering<Hardware> DEFAULT_SIZE_ORDERING = new Ordering<Hardware>() {
390      public int compare(Hardware left, Hardware right) {
391         return ComparisonChain.start().compare(getCores(left), getCores(right)).compare(left.getRam(), right.getRam())
392                  .compare(getSpace(left), getSpace(right)).result();
393      }
394   };
395   static final Ordering<Hardware> BY_CORES_ORDERING = new Ordering<Hardware>() {
396      public int compare(Hardware left, Hardware right) {
397         return Doubles.compare(getCoresAndSpeed(left), getCoresAndSpeed(right));
398      }
399   };
400   static final Ordering<Image> DEFAULT_IMAGE_ORDERING = new Ordering<Image>() {
401      public int compare(Image left, Image right) {
402         return ComparisonChain.start().compare(left.getName(), right.getName(),
403                  Ordering.<String> natural().nullsLast()).compare(left.getVersion(), right.getVersion(),
404                  Ordering.<String> natural().nullsLast()).compare(left.getOperatingSystem().getName(),
405                  right.getOperatingSystem().getName(),//
406                  Ordering.<String> natural().nullsLast()).compare(left.getOperatingSystem().getVersion(),
407                  right.getOperatingSystem().getVersion(),//
408                  Ordering.<String> natural().nullsLast()).compare(left.getOperatingSystem().getDescription(),
409                  right.getOperatingSystem().getDescription(),//
410                  Ordering.<String> natural().nullsLast()).compare(left.getOperatingSystem().getArch(),
411                  right.getOperatingSystem().getArch()).result();
412      }
413   };
414 
415   /**
416    * {@inheritDoc}
417    */
418   @Override
419   public TemplateBuilder fromTemplate(Template template) {
420      fromHardware(template.getHardware());
421      fromImage(template.getImage());
422      return this;
423   }
424 
425   /**
426    * {@inheritDoc}
427    */
428   @Override
429   public TemplateBuilder fromHardware(Hardware hardware) {
430      if (currentLocationWiderThan(hardware.getLocation()))
431         this.location = hardware.getLocation();
432      this.minCores = getCores(hardware);
433      this.minRam = hardware.getRam();
434      return this;
435   }
436 
437   private boolean currentLocationWiderThan(Location location) {
438      return this.location == null || (location != null && this.location.getScope().compareTo(location.getScope()) < 0);
439   }
440 
441   /**
442    * {@inheritDoc}
443    */
444   @Override
445   public TemplateBuilder fromImage(Image image) {
446      if (currentLocationWiderThan(image.getLocation()))
447         this.location = image.getLocation();
448      if (image.getOperatingSystem().getFamily() != null)
449         this.osFamily = image.getOperatingSystem().getFamily();
450      if (image.getName() != null)
451         this.imageName = image.getName();
452      if (image.getDescription() != null)
453         this.imageDescription = image.getDescription();
454      if (image.getOperatingSystem().getName() != null)
455         this.osName = image.getOperatingSystem().getName();
456      if (image.getOperatingSystem().getDescription() != null)
457         this.osDescription = image.getOperatingSystem().getDescription();
458      if (image.getVersion() != null)
459         this.imageVersion = image.getVersion();
460      if (image.getOperatingSystem().getVersion() != null)
461         this.osVersion = image.getOperatingSystem().getVersion();
462      this.os64Bit = image.getOperatingSystem().is64Bit();
463      if (image.getOperatingSystem().getArch() != null)
464         this.osArch = image.getOperatingSystem().getArch();
465      return this;
466   }
467 
468   /**
469    * {@inheritDoc}
470    */
471   @Override
472   public TemplateBuilder smallest() {
473      this.biggest = false;
474      return this;
475   }
476 
477   /**
478    * {@inheritDoc}
479    */
480   @Override
481   public TemplateBuilder biggest() {
482      this.biggest = true;
483      return this;
484   }
485 
486   /**
487    * {@inheritDoc}
488    */
489   @Override
490   public TemplateBuilder fastest() {
491      this.fastest = true;
492      return this;
493   }
494 
495   /**
496    * {@inheritDoc}
497    */
498   @Override
499   public TemplateBuilder locationId(final String locationId) {
500      Set<? extends Location> locations = this.locations.get();
501      try {
502         this.location = Iterables.find(locations, new Predicate<Location>() {
503 
504            @Override
505            public boolean apply(Location input) {
506               return input.getId().equals(locationId);
507            }
508 
509            @Override
510            public String toString() {
511               return "locationId(" + locationId + ")";
512            }
513 
514         });
515      } catch (NoSuchElementException e) {
516         throw new NoSuchElementException(String.format("location id %s not found in: %s", locationId, locations));
517      }
518      return this;
519   }
520 
521   /**
522    * {@inheritDoc}
523    */
524   @Override
525   public TemplateBuilder osFamily(OsFamily os) {
526      this.osFamily = os;
527      return this;
528   }
529 
530   /**
531    * {@inheritDoc}
532    */
533   @Override
534   public Template build() {
535      if (nothingChangedExceptOptions()) {
536         TemplateBuilder defaultTemplate = defaultTemplateProvider.get();
537         if (options != null)
538            defaultTemplate.options(options);
539         return defaultTemplate.build();
540      }
541      if (location == null)
542         location = defaultLocation.get();
543      if (options == null)
544         options = optionsProvider.get();
545      logger.debug(">> searching params(%s)", this);
546      Set<? extends Image> images = getImages();
547      Predicate<Image> imagePredicate = buildImagePredicate();
548      Iterable<? extends Image> supportedImages = filter(images, buildImagePredicate());
549      if (Iterables.size(supportedImages) == 0)
550         throw new NoSuchElementException(String.format(
551                  "no image matched predicate %s images that didn't match below:\n%s", imagePredicate, images));
552      Hardware hardware = resolveSize(hardwareSorter(), supportedImages);
553      Image image = resolveImage(hardware, supportedImages);
554      logger.debug("<<   matched image(%s)", image);
555 
556      return new TemplateImpl(image, hardware, location, options);
557   }
558 
559   protected Hardware resolveSize(Ordering<Hardware> hardwareOrdering, final Iterable<? extends Image> images) {
560      Set<? extends Hardware> hardwaresl = hardwares.get();
561      Hardware hardware;
562      try {
563         Iterable<? extends Hardware> hardwaresThatAreCompatibleWithOurImages = filter(hardwaresl,
564                  new Predicate<Hardware>() {
565                     @Override
566                     public boolean apply(final Hardware hardware) {
567                        return Iterables.any(images, new Predicate<Image>() {
568 
569                           @Override
570                           public boolean apply(Image input) {
571                              return hardware.supportsImage().apply(input);
572                           }
573 
574                           @Override
575                           public String toString() {
576                              return "hardware(" + hardware + ").supportsImage()";
577                           }
578 
579                        });
580 
581                     }
582                  });
583         hardware = hardwareOrdering.max(filter(hardwaresThatAreCompatibleWithOurImages, hardwarePredicate));
584      } catch (NoSuchElementException exception) {
585         throw new NoSuchElementException("hardwares don't support any images: " + toString() + "\n" + hardwaresl
586                  + "\n" + images);
587      }
588      logger.debug("<<   matched hardware(%s)", hardware);
589      return hardware;
590   }
591 
592   protected Ordering<Hardware> hardwareSorter() {
593      Ordering<Hardware> hardwareOrdering = DEFAULT_SIZE_ORDERING;
594      if (!biggest)
595         hardwareOrdering = hardwareOrdering.reverse();
596      if (fastest)
597         hardwareOrdering = Ordering.compound(ImmutableList.of(BY_CORES_ORDERING, hardwareOrdering));
598      return hardwareOrdering;
599   }
600 
601   /**
602    * 
603    * @param hardware
604    * @param supportedImages
605    * @throws NoSuchElementException
606    *            if there's no image that matches the predicate
607    */
608   protected Image resolveImage(final Hardware hardware, Iterable<? extends Image> supportedImages) {
609      Predicate<Image> imagePredicate = new Predicate<Image>() {
610 
611         @Override
612         public boolean apply(Image arg0) {
613            return hardware.supportsImage().apply(arg0);
614         }
615 
616         @Override
617         public String toString() {
618            return "hardware(" + hardware + ").supportsImage()";
619         }
620      };
621      try {
622         Iterable<? extends Image> matchingImages = filter(supportedImages, imagePredicate);
623         if (logger.isTraceEnabled())
624            logger.trace("<<   matched images(%s)", matchingImages);
625         List<? extends Image> maxImages = Lists2.multiMax(DEFAULT_IMAGE_ORDERING, matchingImages);
626         if (logger.isTraceEnabled())
627            logger.trace("<<   best images(%s)", maxImages);
628         return maxImages.get(maxImages.size() - 1);
629      } catch (NoSuchElementException exception) {
630         throw new NoSuchElementException("image didn't match: " + toString() + "\n" + supportedImages);
631      }
632   }
633 
634   protected Set<? extends Image> getImages() {
635      return images.get();
636   }
637 
638   private Predicate<Image> buildImagePredicate() {
639      List<Predicate<Image>> predicates = newArrayList();
640      if (imageId != null) {
641         predicates.add(idPredicate);
642      } else {
643         if (location != null)
644            predicates.add(new Predicate<Image>() {
645 
646               @Override
647               public boolean apply(Image input) {
648                  return locationPredicate.apply(input);
649               }
650 
651               @Override
652               public String toString() {
653                  return "location(" + location + ")";
654               }
655            });
656 
657         final List<Predicate<OperatingSystem>> osPredicates = newArrayList();
658         if (osFamily != null)
659            osPredicates.add(osFamilyPredicate);
660         if (osName != null)
661            osPredicates.add(osNamePredicate);
662         if (osDescription != null)
663            osPredicates.add(osDescriptionPredicate);
664         if (osVersion != null)
665            osPredicates.add(osVersionPredicate);
666         if (os64Bit != null)
667            osPredicates.add(os64BitPredicate);
668         if (osArch != null)
669            osPredicates.add(osArchPredicate);
670         predicates.add(new Predicate<Image>() {
671 
672            @Override
673            public boolean apply(Image input) {
674               return Predicates.and(osPredicates).apply(input.getOperatingSystem());
675            }
676 
677            @Override
678            public String toString() {
679               return Predicates.and(osPredicates).toString();
680            }
681 
682         });
683         if (imageVersion != null)
684            predicates.add(imageVersionPredicate);
685         if (imageName != null)
686            predicates.add(imageNamePredicate);
687         if (imageDescription != null)
688            predicates.add(imageDescriptionPredicate);
689      }
690 
691      // looks verbose, but explicit <Image> type needed for this to compile
692      // properly
693      Predicate<Image> imagePredicate = predicates.size() == 1 ? Iterables.<Predicate<Image>> get(predicates, 0)
694               : Predicates.<Image> and(predicates);
695      return imagePredicate;
696   }
697 
698   /**
699    * {@inheritDoc}
700    */
701   @Override
702   public TemplateBuilder imageId(String imageId) {
703      this.imageId = imageId;
704      this.imageName = null;
705      this.imageDescription = null;
706      this.imageVersion = null;
707      this.osFamily = null;
708      this.osName = null;
709      this.osDescription = null;
710      this.osVersion = null;
711      this.os64Bit = null;
712      this.osArch = null;
713      return this;
714   }
715 
716   /**
717    * {@inheritDoc}
718    */
719   @Override
720   public TemplateBuilder imageNameMatches(String nameRegex) {
721      this.imageName = nameRegex;
722      return this;
723   }
724 
725   /**
726    * {@inheritDoc}
727    */
728   @Override
729   public TemplateBuilder imageDescriptionMatches(String descriptionRegex) {
730      this.imageDescription = descriptionRegex;
731      return this;
732   }
733 
734   /**
735    * {@inheritDoc}
736    */
737   @Override
738   public TemplateBuilder imageVersionMatches(String imageVersionRegex) {
739      this.imageVersion = imageVersionRegex;
740      return this;
741   }
742 
743   /**
744    * {@inheritDoc}
745    */
746   @Override
747   public TemplateBuilder osVersionMatches(String osVersionRegex) {
748      this.osVersion = osVersionRegex;
749      return this;
750   }
751 
752   /**
753    * {@inheritDoc}
754    */
755   @Override
756   public TemplateBuilder osArchMatches(String osArchitectureRegex) {
757      this.osArch = osArchitectureRegex;
758      return this;
759   }
760 
761   /**
762    * {@inheritDoc}
763    */
764   @Override
765   public TemplateBuilder minCores(double minCores) {
766      this.minCores = minCores;
767      return this;
768   }
769 
770   /**
771    * {@inheritDoc}
772    */
773   @Override
774   public TemplateBuilder minRam(int megabytes) {
775      this.minRam = megabytes;
776      return this;
777   }
778 
779   /**
780    * {@inheritDoc}
781    */
782   @Override
783   public TemplateBuilder osNameMatches(String osNameRegex) {
784      this.osName = osNameRegex;
785      return this;
786   }
787 
788   /**
789    * {@inheritDoc}
790    */
791   @Override
792   public TemplateBuilder osDescriptionMatches(String osDescriptionRegex) {
793      this.osDescription = osDescriptionRegex;
794      return this;
795   }
796 
797   /**
798    * {@inheritDoc}
799    */
800   @Override
801   public TemplateBuilder hardwareId(String hardwareId) {
802      this.hardwareId = hardwareId;
803      return this;
804   }
805 
806   /**
807    * {@inheritDoc}
808    */
809   @Override
810   public TemplateBuilder options(TemplateOptions options) {
811      this.options = optionsProvider.get();
812      copyTemplateOptions(checkNotNull(options, "options"), this.options);
813      return this;
814   }
815 
816   protected void copyTemplateOptions(TemplateOptions from, TemplateOptions to) {
817      if (!Arrays.equals(to.getInboundPorts(), from.getInboundPorts()))
818         to.inboundPorts(from.getInboundPorts());
819      if (from.getRunScript() != null)
820         to.runScript(from.getRunScript());
821      if (from.getPrivateKey() != null)
822         to.installPrivateKey(from.getPrivateKey());
823      if (from.getPublicKey() != null)
824         to.authorizePublicKey(from.getPublicKey());
825      if (from.getPort() != -1)
826         to.blockOnPort(from.getPort(), from.getSeconds());
827      if (from.isIncludeMetadata())
828         to.withMetadata();
829      if (!from.shouldBlockUntilRunning())
830         to.blockUntilRunning(false);
831      if (!from.shouldBlockOnComplete())
832         to.blockOnComplete(false);
833      if (from.getOverrideCredentials() != null)
834         to.withOverridingCredentials(from.getOverrideCredentials());
835      if (from.getTaskName() != null)
836         to.nameTask(from.getTaskName());
837   }
838 
839   @VisibleForTesting
840   boolean nothingChangedExceptOptions() {
841      return osFamily == null && location == null && imageId == null && hardwareId == null && osName == null
842               && osDescription == null && imageVersion == null && osVersion == null && osArch == null
843               && os64Bit == null && imageName == null && imageDescription == null && minCores == 0 && minRam == 0
844               && !biggest && !fastest;
845   }
846 
847   /**
848    * {@inheritDoc}
849    */
850   @Override
851   public TemplateBuilder any() {
852      return defaultTemplateProvider.get();
853   }
854 
855   @Override
856   public String toString() {
857      return "[biggest=" + biggest + ", fastest=" + fastest + ", imageName=" + imageName + ", imageDescription="
858               + imageDescription + ", imageId=" + imageId + ", imageVersion=" + imageVersion + ", location="
859               + location + ", minCores=" + minCores + ", minRam=" + minRam + ", osFamily=" + osFamily + ", osName="
860               + osName + ", osDescription=" + osDescription + ", osVersion=" + osVersion + ", osArch=" + osArch
861               + ", os64Bit=" + os64Bit + ", hardwareId=" + hardwareId + "]";
862   }
863 
864   @Override
865   public TemplateBuilder os64Bit(boolean is64Bit) {
866      this.os64Bit = is64Bit;
867      return this;
868   }
869 
870}

[all classes][org.jclouds.compute.domain.internal]
EMMA 2.0.5312 (C) Vladimir Roubtsov