View Javadoc

1   /**
2    * Licensed to jclouds, Inc. (jclouds) under one or more
3    * contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  jclouds licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  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,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.jclouds.rest;
20  
21  import static com.google.common.base.Preconditions.checkArgument;
22  import static com.google.common.base.Predicates.notNull;
23  import static com.google.common.base.Throwables.propagate;
24  import static com.google.common.collect.Iterables.filter;
25  import static com.google.common.collect.Iterables.get;
26  import static com.google.common.collect.Iterables.transform;
27  
28  import java.io.IOException;
29  import java.lang.reflect.InvocationTargetException;
30  import java.util.Map;
31  import java.util.Map.Entry;
32  import java.util.Properties;
33  
34  import org.jclouds.javax.annotation.Nullable;
35  
36  import org.jclouds.PropertiesBuilder;
37  import org.jclouds.util.SaxUtils;
38  
39  import com.google.common.base.Function;
40  import com.google.common.base.Predicate;
41  import com.google.common.base.Splitter;
42  
43  /**
44   * 
45   * @author Adrian Cole
46   */
47  public class Providers {
48  
49     /**
50      * Gets a set of supported providers. Idea stolen from pallets (supported-clouds). Uses
51      * rest.properties to populate the set.
52      * 
53      */
54     public static Iterable<String> getSupportedProviders() {
55        return Providers.getSupportedProvidersOfType(RestContextBuilder.class);
56     }
57  
58     /**
59      * Gets a set of supported providers. Idea stolen from pallets (supported-clouds). Uses
60      * rest.properties to populate the set.
61      * 
62      */
63     public static Iterable<String> getSupportedProvidersOfType(
64           @SuppressWarnings("rawtypes") Class<? extends RestContextBuilder> type) {
65        Properties properties = new Properties();
66        try {
67           properties.load(SaxUtils.class.getResourceAsStream("/rest.properties"));
68        } catch (IOException e) {
69           throw new RuntimeException(e);
70        }
71        return Providers.getSupportedProvidersOfTypeInProperties(type, properties);
72     }
73  
74     public static Iterable<String> getSupportedProvidersOfTypeInProperties(
75           @SuppressWarnings("rawtypes") final Class<? extends RestContextBuilder> type, final Properties properties) {
76        return filter(transform(filter(properties.entrySet(), new Predicate<Map.Entry<Object, Object>>() {
77  
78           @Override
79           public boolean apply(Entry<Object, Object> input) {
80              String keyString = input.getKey().toString();
81              return keyString.endsWith(".contextbuilder") || keyString.endsWith(".sync");
82           }
83  
84        }), new Function<Map.Entry<Object, Object>, String>() {
85  
86           @Override
87           public String apply(Entry<Object, Object> from) {
88              String keyString = from.getKey().toString();
89              try {
90                 String provider = get(Splitter.on('.').split(keyString), 0);
91                 Class<RestContextBuilder<Object, Object>> clazz = Providers.resolveContextBuilderClass(provider,
92                       properties);
93                 if (type.isAssignableFrom(clazz))
94                    return provider;
95              } catch (ClassNotFoundException e) {
96              } catch (Exception e) {
97                 propagate(e);
98              }
99              return null;
100          }
101 
102       }), notNull());
103    }
104 
105    @SuppressWarnings("unchecked")
106    public static <S, A> Class<RestContextBuilder<S, A>> resolveContextBuilderClass(String provider,
107          Properties properties) throws ClassNotFoundException, IllegalArgumentException, SecurityException,
108          InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
109       String contextBuilderClassName = properties.getProperty(provider + ".contextbuilder");
110       String syncClassName = properties.getProperty(provider + ".sync");
111       String asyncClassName = properties.getProperty(provider + ".async");
112       if (syncClassName != null) {
113          checkArgument(asyncClassName != null, "please configure async class for " + syncClassName);
114          Class.forName(syncClassName);
115          Class.forName(asyncClassName);
116          return (Class<RestContextBuilder<S, A>>) (contextBuilderClassName != null ? Class
117                .forName(contextBuilderClassName) : RestContextBuilder.class);
118       } else {
119          checkArgument(contextBuilderClassName != null, "please configure contextbuilder class for " + provider);
120          return (Class<RestContextBuilder<S, A>>) Class.forName(contextBuilderClassName);
121       }
122    }
123 
124    public static <S, A> RestContextBuilder<S, A> initContextBuilder(
125          Class<RestContextBuilder<S, A>> contextBuilderClass, @Nullable Class<S> sync, @Nullable Class<A> async,
126          Properties properties) throws ClassNotFoundException, IllegalArgumentException, SecurityException,
127          InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
128       checkArgument(properties != null, "please configure properties for " + contextBuilderClass);
129       try {
130          return (RestContextBuilder<S, A>) contextBuilderClass.getConstructor(Properties.class).newInstance(properties);
131       } catch (NoSuchMethodException e) {
132          checkArgument(sync != null, "please configure sync class for " + contextBuilderClass);
133          checkArgument(async != null, "please configure async class for " + contextBuilderClass);
134          return (RestContextBuilder<S, A>) contextBuilderClass.getConstructor(sync.getClass(), async.getClass(),
135                Properties.class).newInstance(sync, async, properties);
136       }
137    }
138 
139    @SuppressWarnings("unchecked")
140    public static Class<PropertiesBuilder> resolvePropertiesBuilderClass(String providerName, Properties props)
141          throws ClassNotFoundException, InstantiationException, IllegalAccessException, InvocationTargetException,
142          NoSuchMethodException {
143       String propertiesBuilderClassName = props.getProperty(providerName + ".propertiesbuilder", null);
144       if (propertiesBuilderClassName != null) {
145          return (Class<PropertiesBuilder>) Class.forName(propertiesBuilderClassName);
146       } else {
147          return PropertiesBuilder.class;
148       }
149    }
150 
151 }