1/*
2 * Copyright 2007 Netflix, Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *     http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package net.oauth;
18
19import java.io.IOException;
20import java.io.InputStream;
21import java.net.MalformedURLException;
22import java.net.URL;
23import java.util.HashMap;
24import java.util.Map;
25import java.util.Properties;
26
27/**
28 * A pool of OAuthConsumers that are constructed from Properties. Each consumer
29 * has a name, which is a property of the OAuthConsumer. Other properties come
30 * from Properties whose names are prefixed with the consumer's name. For
31 * example, a consumer's credentials come from properties named
32 * [name].consumerKey and [name].consumerSecret.
33 *
34 * @author John Kristian
35 * @hide
36 */
37public class ConsumerProperties {
38
39    public static URL getResource(String name, ClassLoader loader)
40            throws IOException {
41        URL resource = loader.getResource(name);
42        if (resource == null) {
43            throw new IOException("resource not found: " + name);
44        }
45        return resource;
46    }
47
48    public static Properties getProperties(URL source) throws IOException {
49        InputStream input = source.openStream();
50        try {
51            Properties p = new Properties();
52            p.load(input);
53            return p;
54        } finally {
55            input.close();
56        }
57    }
58
59    public ConsumerProperties(String resourceName, ClassLoader loader)
60            throws IOException {
61        this(getProperties(getResource(resourceName, loader)));
62    }
63
64    public ConsumerProperties(Properties consumerProperties) {
65        this.consumerProperties = consumerProperties;
66    }
67
68    private final Properties consumerProperties;
69
70    private final Map<String, OAuthConsumer> pool = new HashMap<String, OAuthConsumer>();
71
72    /** Get the consumer with the given name. */
73    public OAuthConsumer getConsumer(String name) throws MalformedURLException {
74        OAuthConsumer consumer;
75        synchronized (pool) {
76            consumer = pool.get(name);
77        }
78        if (consumer == null) {
79            consumer = newConsumer(name);
80        }
81        synchronized (pool) {
82            OAuthConsumer first = pool.get(name);
83            if (first == null) {
84                pool.put(name, consumer);
85            } else {
86                /*
87                 * Another thread just constructed an identical OAuthConsumer.
88                 * Use that one (and discard the one we just constructed).
89                 */
90                consumer = first;
91            }
92        }
93        return consumer;
94    }
95
96    protected OAuthConsumer newConsumer(String name)
97            throws MalformedURLException {
98        String base = consumerProperties.getProperty(name
99                + ".serviceProvider.baseURL");
100        URL baseURL = (base == null) ? null : new URL(base);
101        OAuthServiceProvider serviceProvider = new OAuthServiceProvider(getURL(
102                baseURL, name + ".serviceProvider.requestTokenURL"), getURL(
103                baseURL, name + ".serviceProvider.userAuthorizationURL"),
104                getURL(baseURL, name + ".serviceProvider.accessTokenURL"));
105        OAuthConsumer consumer = new OAuthConsumer(consumerProperties
106                .getProperty(name + ".callbackURL"), consumerProperties
107                .getProperty(name + ".consumerKey"), consumerProperties
108                .getProperty(name + ".consumerSecret"), serviceProvider);
109        consumer.setProperty("name", name);
110        if (baseURL != null) {
111            consumer.setProperty("serviceProvider.baseURL", baseURL);
112        }
113        for (Map.Entry prop : consumerProperties.entrySet()) {
114            String propName = (String) prop.getKey();
115            if (propName.startsWith(name + ".consumer.")) {
116                String c = propName.substring(name.length() + 10);
117                consumer.setProperty(c, prop.getValue());
118            }
119        }
120        return consumer;
121    }
122
123    private String getURL(URL base, String name) throws MalformedURLException {
124        String url = consumerProperties.getProperty(name);
125        if (base != null) {
126            url = (new URL(base, url)).toExternalForm();
127        }
128        return url;
129    }
130
131}
132