]> git.basschouten.com Git - openhab-addons.git/blob
f70b51d95f92bbcc17a9a9bb12161628ca6dd645
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2020 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
7  * This program and the accompanying materials are made available under the
8  * terms of the Eclipse Public License 2.0 which is available at
9  * http://www.eclipse.org/legal/epl-2.0
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.binding.tr064.internal.phonebook;
14
15 import static java.util.Comparator.comparing;
16
17 import java.net.URI;
18 import java.util.ArrayList;
19 import java.util.Collection;
20 import java.util.List;
21 import java.util.Locale;
22 import java.util.Map;
23 import java.util.Set;
24 import java.util.concurrent.ConcurrentHashMap;
25 import java.util.stream.Collectors;
26
27 import org.eclipse.jdt.annotation.NonNullByDefault;
28 import org.eclipse.jdt.annotation.Nullable;
29 import org.openhab.core.config.core.ConfigOptionProvider;
30 import org.openhab.core.config.core.ParameterOption;
31 import org.openhab.core.i18n.LocalizedKey;
32 import org.openhab.core.thing.ThingUID;
33 import org.openhab.core.thing.profiles.Profile;
34 import org.openhab.core.thing.profiles.ProfileCallback;
35 import org.openhab.core.thing.profiles.ProfileContext;
36 import org.openhab.core.thing.profiles.ProfileFactory;
37 import org.openhab.core.thing.profiles.ProfileType;
38 import org.openhab.core.thing.profiles.ProfileTypeProvider;
39 import org.openhab.core.thing.profiles.ProfileTypeUID;
40 import org.openhab.core.thing.profiles.i18n.ProfileTypeI18nLocalizationService;
41 import org.openhab.core.util.BundleResolver;
42 import org.openhab.core.util.UIDUtils;
43 import org.osgi.framework.Bundle;
44 import org.osgi.service.component.annotations.Activate;
45 import org.osgi.service.component.annotations.Component;
46 import org.osgi.service.component.annotations.Reference;
47 import org.slf4j.Logger;
48 import org.slf4j.LoggerFactory;
49
50 /**
51  * The {@link PhonebookProfileFactory} class is used to create phonebook profiles
52  *
53  * @author Jan N. Klug - Initial contribution
54  */
55 @NonNullByDefault
56 @Component(service = { ProfileFactory.class, ProfileTypeProvider.class, PhonebookProfileFactory.class,
57         ConfigOptionProvider.class })
58 public class PhonebookProfileFactory implements ProfileFactory, ProfileTypeProvider, ConfigOptionProvider {
59     private final Logger logger = LoggerFactory.getLogger(PhonebookProfileFactory.class);
60     private final Map<ThingUID, PhonebookProvider> phonebookProviders = new ConcurrentHashMap<>();
61
62     private final Map<LocalizedKey, ProfileType> localizedProfileTypeCache = new ConcurrentHashMap<>();
63
64     private final ProfileTypeI18nLocalizationService profileTypeI18nLocalizationService;
65     private final Bundle bundle;
66
67     @Activate
68     public PhonebookProfileFactory(
69             final @Reference ProfileTypeI18nLocalizationService profileTypeI18nLocalizationService,
70             final @Reference BundleResolver bundleResolver) {
71         this.profileTypeI18nLocalizationService = profileTypeI18nLocalizationService;
72         this.bundle = bundleResolver.resolveBundle(PhonebookProfileFactory.class);
73     }
74
75     @Override
76     public @Nullable Profile createProfile(ProfileTypeUID profileTypeUID, ProfileCallback callback,
77             ProfileContext profileContext) {
78         return new PhonebookProfile(callback, profileContext, phonebookProviders);
79     }
80
81     @Override
82     public Collection<ProfileTypeUID> getSupportedProfileTypeUIDs() {
83         return Set.of(PhonebookProfile.PHONEBOOK_PROFILE_TYPE_UID);
84     }
85
86     @Override
87     public Collection<ProfileType> getProfileTypes(@Nullable Locale locale) {
88         return Set.of(createLocalizedProfileType(PhonebookProfile.PHONEBOOK_PROFILE_TYPE, locale));
89     }
90
91     private ProfileType createLocalizedProfileType(ProfileType profileType, @Nullable Locale locale) {
92         final LocalizedKey localizedKey = new LocalizedKey(profileType.getUID(),
93                 locale != null ? locale.toLanguageTag() : null);
94
95         final ProfileType cachedlocalizedProfileType = localizedProfileTypeCache.get(localizedKey);
96         if (cachedlocalizedProfileType != null) {
97             return cachedlocalizedProfileType;
98         }
99
100         final ProfileType localizedProfileType = profileTypeI18nLocalizationService.createLocalizedProfileType(bundle,
101                 profileType, locale);
102         if (localizedProfileType != null) {
103             localizedProfileTypeCache.put(localizedKey, localizedProfileType);
104             return localizedProfileType;
105         } else {
106             return profileType;
107         }
108     }
109
110     /**
111      * register a phonebook provider
112      *
113      * @param phonebookProvider the provider that shall be added
114      */
115     public void registerPhonebookProvider(PhonebookProvider phonebookProvider) {
116         if (phonebookProviders.put(phonebookProvider.getUID(), phonebookProvider) != null) {
117             logger.warn("Tried to register a phonebook provider with UID '{}' for the second time.",
118                     phonebookProvider.getUID());
119         }
120     }
121
122     /**
123      * unregister a phonebook provider
124      *
125      * @param phonebookProvider the provider that shall be removed
126      */
127     public void unregisterPhonebookProvider(PhonebookProvider phonebookProvider) {
128         if (phonebookProviders.remove(phonebookProvider.getUID()) == null) {
129             logger.warn("Tried to unregister a phonebook provider with UID '{}' but it was not found.",
130                     phonebookProvider.getUID());
131         }
132     }
133
134     private List<ParameterOption> createPhonebookList(Map.Entry<ThingUID, PhonebookProvider> entry) {
135         String thingUid = UIDUtils.encode(entry.getKey().toString());
136         String thingName = entry.getValue().getFriendlyName();
137
138         List<ParameterOption> parameterOptions = entry.getValue().getPhonebooks().stream()
139                 .map(phonebook -> new ParameterOption(thingUid + ":" + UIDUtils.encode(phonebook.getName()),
140                         thingName + " - " + phonebook.getName()))
141                 .collect(Collectors.toList());
142
143         if (parameterOptions.size() > 0) {
144             parameterOptions.add(new ParameterOption(thingUid, thingName));
145         }
146
147         return parameterOptions;
148     }
149
150     @Override
151     public @Nullable Collection<ParameterOption> getParameterOptions(URI uri, String s, @Nullable String s1,
152             @Nullable Locale locale) {
153         if (uri.getSchemeSpecificPart().equals(PhonebookProfile.PHONEBOOK_PROFILE_TYPE_UID.toString())
154                 && s.equals(PhonebookProfile.PHONEBOOK_PARAM)) {
155             List<ParameterOption> parameterOptions = new ArrayList<>();
156             for (Map.Entry<ThingUID, PhonebookProvider> entry : phonebookProviders.entrySet()) {
157                 parameterOptions.addAll(createPhonebookList(entry));
158             }
159             parameterOptions.sort(comparing(o -> o.getLabel()));
160             return parameterOptions;
161         }
162         return null;
163     }
164 }