/** * Copyright (c) 2014-2017 by the respective copyright holders. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ package org.eclipse.smarthome.core.thing.firmware; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Locale; import java.util.Set; import java.util.TreeSet; import java.util.concurrent.CopyOnWriteArrayList; import org.eclipse.smarthome.core.i18n.LocaleProvider; import org.eclipse.smarthome.core.thing.ThingTypeUID; import org.eclipse.smarthome.core.thing.binding.firmware.Firmware; import org.eclipse.smarthome.core.thing.binding.firmware.FirmwareUID; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.base.Preconditions; import com.google.common.collect.Iterables; /** * The {@link FirmwareRegistry} is registered as an OSGi service and is responsible for tracking all * {@link FirmwareProvider}s. For this reason it is the central instance to get access to all available firmwares. If a * locale is given to one of its operations then the following firmware attributes are localized: * <ul> * <li>{@link Firmware#getDescription()}</li> * <li>{@link Firmware#getChangelog()}</li> * <li>{@link Firmware#getOnlineChangelog()}</li> * <ul> * * @author Thomas Höfer - Initial contribution */ public final class FirmwareRegistry { private final Logger logger = LoggerFactory.getLogger(FirmwareRegistry.class); private final List<FirmwareProvider> firmwareProviders = new CopyOnWriteArrayList<>(); private LocaleProvider localeProvider; /** * Returns the firmware for the given UID using the locale provided by the {@link LocaleProvider}. * * @param firmwareUID the firmware UID (must not be null) * * @return the corresponding firmware or null if no firmware was found * * @throws NullPointerException if given firmware UID is null */ public Firmware getFirmware(FirmwareUID firmwareUID) { return getFirmware(firmwareUID, localeProvider.getLocale()); } /** * Returns the firmware for the given UID. * * @param firmwareUID the firmware UID (must not be null) * @param locale the locale to be used (if null then the locale provided by the {@link LocaleProvider} is used) * * @return the corresponding firmware or null if no firmware was found * * @throws NullPointerException if given firmware UID is null */ public Firmware getFirmware(FirmwareUID firmwareUID, Locale locale) { Preconditions.checkNotNull(firmwareUID, "Firmware UID must not be null"); Locale loc = locale != null ? locale : localeProvider.getLocale(); for (FirmwareProvider firmwareProvider : firmwareProviders) { try { Firmware firmware = firmwareProvider.getFirmware(firmwareUID, loc); if (firmware != null) { return firmware; } } catch (Exception e) { logger.warn(String.format( "Unexpected exception occurred for firmware provider %s while getting firmware for firmware UID %s.", firmwareProvider.getClass().getSimpleName(), firmwareUID), e); } } return null; } /** * Returns the latest firmware for the given thing type UID using the locale provided by the {@link LocaleProvider}. * * @param thingTypeUID the thing type UID (must not be null) * * @return the corresponding latest firmware or null if no firmware was found * * @throws NullPointerException if given thing type UID is null */ public Firmware getLatestFirmware(ThingTypeUID thingTypeUID) { return getLatestFirmware(thingTypeUID, localeProvider.getLocale()); } /** * Returns the latest firmware for the given thing type UID and locale. * * @param thingTypeUID the thing type UID (must not be null) * @param locale the locale to be used (if null then the locale provided by the {@link LocaleProvider} is used) * * @return the corresponding latest firmware or null if no firmware was found * * @throws NullPointerException if given thing type UID is null */ public Firmware getLatestFirmware(ThingTypeUID thingTypeUID, Locale locale) { Locale loc = locale != null ? locale : localeProvider.getLocale(); return Iterables.getFirst(getFirmwares((thingTypeUID), loc), null); } /** * Returns the collection of available firmwares for the given thing type UID using the locale provided by the * {@link LocaleProvider}. The collection is sorted in descending order, i.e. the latest firmware will be the first * element in the collection. * * @param thingTypeUID the thing type UID for which the firmwares are to be provided (not null) * * @return the collection of available firmwares for the given thing type UID (not null) * * @throws NullPointerException if given thing type UID is null */ public Collection<Firmware> getFirmwares(ThingTypeUID thingTypeUID) { return getFirmwares(thingTypeUID, localeProvider.getLocale()); } /** * Returns the collection of available firmwares for the given thing type UID and locale. The collection is * sorted in descending order, i.e. the latest firmware will be the first element in the collection. * * @param thingTypeUID the thing type UID for which the firmwares are to be provided (not null) * @param locale the locale to be used (if null then the locale provided by the {@link LocaleProvider} is used) * * @return the collection of available firmwares for the given thing type UID (not null) * * @throws NullPointerException if given thing type UID is null */ public Collection<Firmware> getFirmwares(ThingTypeUID thingTypeUID, Locale locale) { Preconditions.checkNotNull(thingTypeUID, "Thing type UID must not be null"); Locale loc = locale != null ? locale : localeProvider.getLocale(); Set<Firmware> firmwares = new TreeSet<>(); for (FirmwareProvider firmwareProvider : firmwareProviders) { try { Collection<Firmware> result = firmwareProvider.getFirmwares(thingTypeUID, loc); if (result != null) { firmwares.addAll(result); } } catch (Exception e) { logger.warn(String.format( "Unexpected exception occurred for firmware provider %s while getting firmwares for thing type UID %s.", firmwareProvider.getClass().getSimpleName(), thingTypeUID), e); } } return Collections.unmodifiableCollection(firmwares); } protected void addFirmwareProvider(FirmwareProvider firmwareProvider) { firmwareProviders.add(firmwareProvider); } protected void removeFirmwareProvider(FirmwareProvider firmwareProvider) { firmwareProviders.remove(firmwareProvider); } protected void setLocaleProvider(final LocaleProvider localeProvider) { this.localeProvider = localeProvider; } protected void unsetLocaleProvider(final LocaleProvider localeProvider) { this.localeProvider = null; } }