001package com.pi4j.platform;
002
003/*
004 * #%L
005 * **********************************************************************
006 * ORGANIZATION  :  Pi4J
007 * PROJECT       :  Pi4J :: Java Library (Core)
008 * FILENAME      :  PlatformManager.java
009 *
010 * This file is part of the Pi4J project. More information about
011 * this project can be found here:  https://www.pi4j.com/
012 * **********************************************************************
013 * %%
014 * Copyright (C) 2012 - 2021 Pi4J
015 * %%
016 * This program is free software: you can redistribute it and/or modify
017 * it under the terms of the GNU Lesser General Public License as
018 * published by the Free Software Foundation, either version 3 of the
019 * License, or (at your option) any later version.
020 *
021 * This program is distributed in the hope that it will be useful,
022 * but WITHOUT ANY WARRANTY; without even the implied warranty of
023 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
024 * GNU General Lesser Public License for more details.
025 *
026 * You should have received a copy of the GNU General Lesser Public
027 * License along with this program.  If not, see
028 * <http://www.gnu.org/licenses/lgpl-3.0.html>.
029 * #L%
030 */
031
032/**
033 * <p>
034 * This class provides static methods to configure the Pi4J library's default
035 * platform.  Pi4J supports the following platforms:  RaspberryPi, BananaPi, BananaPro, Odroid.
036 * </p>
037 *
038 * @see <a href="https://www.pi4j.com/">https://www.pi4j.com/</a>
039 * @author Robert Savage (<a
040 *         href="http://www.savagehomeautomation.com">http://www.savagehomeautomation.com</a>)
041 */
042public class PlatformManager {
043
044    // selected platform
045    private static Platform platform = null;
046
047    /**
048     * Get the selected system platform.  If
049     * a platform has not explicitly been set, then
050     * the default platform: 'RASPBERRY_PI' will be
051     * selected and returned.
052     *
053     * @return selected platform
054     */
055    public static Platform getPlatform(){
056        // if a platform instance has not explicitly been
057        // selected, then get the default platform
058        if(platform == null){
059            try {
060                setPlatform(getDefaultPlatform());
061            } catch (PlatformAlreadyAssignedException e) {
062                // we are eating this exception because it should never be thrown in this case
063                e.printStackTrace();
064                return null;
065            }
066        }
067        return platform;
068    }
069
070    /**
071     * Set the runtime platform for Pi4J to use.  This platform selection
072     * will be used to determine the default GPIO providers and I2C providers
073     * specific to the selected platform.  A platform assignment can only
074     * be set once.  If a second attempt to set a platform is attempted,
075     * the 'PlatformAlreadyAssignedException' will be thrown.  Please
076     * note that platform assignment can be made automatically if you
077     * use a provider class prior to manually assigning a platform.
078     *
079     * @param platform platform to assign
080     * @throws PlatformAlreadyAssignedException
081     */
082    public static void setPlatform(Platform platform) throws PlatformAlreadyAssignedException {
083        // prevent changing the platform once it has been initially set
084        if(PlatformManager.platform != null){
085            throw new PlatformAlreadyAssignedException(PlatformManager.platform);
086        }
087
088        // set internal platform instance
089        PlatformManager.platform = platform;
090
091        // apply Pi4J platform system property
092        System.setProperty("pi4j.platform", platform.id());
093    }
094
095
096    /**
097     * Internal method to get the default platform.  It will attempt to first
098     * get the platform using the 'PI4J_PLATFORM' environment variable, if the
099     * environment variable is not configured, then it will attempt to use the
100     * system property "pi4j.platform".  If the system property is not found or
101     * the value is not legal, then return the default 'RASPBERRY_PI' platform.
102     *
103     * @return default platform enumeration
104     */
105    protected static Platform getDefaultPlatform(){
106        // attempt to get assigned platform identifier from the environment variables
107        String envPlatformId = System.getenv("PI4J_PLATFORM");
108
109        // attempt to get assigned platform identifier from the system properties
110        String platformId = System.getProperty("pi4j.platform", envPlatformId);
111
112        // if a platform id was found in the system properties, then
113        // attempt to lookup the platform enumeration using the platform
114        // identifier string.  If found then return the platform enum.
115        if(platformId != null && !platformId.isEmpty()){
116            Platform pltfrm = Platform.fromId(platformId);
117            if(pltfrm != null){
118                return pltfrm;
119            }
120        }
121
122        // the RASPBERRY_PI is the default platform;
123        // (... in time perhaps some auto-platform detection could be implemented here ...)
124        return Platform.RASPBERRYPI;
125    }
126}