added migrated 2.x add-ons

Signed-off-by: Kai Kreuzer <kai@openhab.org>
This commit is contained in:
Kai Kreuzer
2020-09-21 01:58:32 +02:00
parent bbf1a7fd29
commit 6df6783b60
11662 changed files with 1302875 additions and 11 deletions

View File

@@ -0,0 +1,162 @@
/**
* Copyright 2017-2018 Gregory Moyer and contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openhab.binding.lametrictime.api;
import org.openhab.binding.lametrictime.api.cloud.CloudConfiguration;
import org.openhab.binding.lametrictime.api.local.LocalConfiguration;
public class Configuration
{
private String deviceHost;
private String deviceApiKey;
private boolean ignoreDeviceCertificateValidation = true;
private boolean ignoreDeviceHostnameValidation = true;
private boolean logging = false;
private String logLevel = "INFO";
private int logMax = 104857600; // 100kb
public String getDeviceHost()
{
return deviceHost;
}
public void setDeviceHost(String deviceHost)
{
this.deviceHost = deviceHost;
}
public Configuration withDeviceHost(String deviceHost)
{
this.deviceHost = deviceHost;
return this;
}
public String getDeviceApiKey()
{
return deviceApiKey;
}
public void setDeviceApiKey(String deviceApiKey)
{
this.deviceApiKey = deviceApiKey;
}
public Configuration withDeviceApiKey(String deviceApiKey)
{
this.deviceApiKey = deviceApiKey;
return this;
}
public boolean isIgnoreDeviceCertificateValidation()
{
return ignoreDeviceCertificateValidation;
}
public void setIgnoreDeviceCertificateValidation(boolean ignoreDeviceCertificateValidation)
{
this.ignoreDeviceCertificateValidation = ignoreDeviceCertificateValidation;
}
public Configuration withIgnoreDeviceCertificateValidation(boolean ignoreDeviceCertificateValidation)
{
this.ignoreDeviceCertificateValidation = ignoreDeviceCertificateValidation;
return this;
}
public boolean isIgnoreDeviceHostnameValidation()
{
return ignoreDeviceHostnameValidation;
}
public void setIgnoreDeviceHostnameValidation(boolean ignoreDeviceHostnameValidation)
{
this.ignoreDeviceHostnameValidation = ignoreDeviceHostnameValidation;
}
public Configuration withIgnoreDeviceHostnameValidation(boolean ignoreDeviceHostnameValidation)
{
this.ignoreDeviceHostnameValidation = ignoreDeviceHostnameValidation;
return this;
}
public boolean isLogging()
{
return logging;
}
public void setLogging(boolean logging)
{
this.logging = logging;
}
public Configuration withLogging(boolean logging)
{
this.logging = logging;
return this;
}
public String getLogLevel()
{
return logLevel;
}
public void setLogLevel(String logLevel)
{
this.logLevel = logLevel;
}
public Configuration withLogLevel(String logLevel)
{
this.logLevel = logLevel;
return this;
}
public int getLogMax()
{
return logMax;
}
public void setLogMax(int logMax)
{
this.logMax = logMax;
}
public Configuration withLogMax(int logMax)
{
this.logMax = logMax;
return this;
}
public LocalConfiguration getLocalConfig()
{
return new LocalConfiguration().withHost(deviceHost)
.withApiKey(deviceApiKey)
.withIgnoreCertificateValidation(ignoreDeviceCertificateValidation)
.withIgnoreHostnameValidation(ignoreDeviceHostnameValidation)
.withLogging(logging)
.withLogLevel(logLevel)
.withLogMax(logMax);
}
public CloudConfiguration getCloudConfig()
{
return new CloudConfiguration().withLogging(logging)
.withLogLevel(logLevel)
.withLogMax(logMax);
}
}

View File

@@ -0,0 +1,449 @@
/**
* Copyright 2017-2018 Gregory Moyer and contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openhab.binding.lametrictime.api;
import javax.ws.rs.client.ClientBuilder;
import org.openhab.binding.lametrictime.api.cloud.CloudConfiguration;
import org.openhab.binding.lametrictime.api.cloud.LaMetricTimeCloud;
import org.openhab.binding.lametrictime.api.impl.LaMetricTimeImpl;
import org.openhab.binding.lametrictime.api.local.ApplicationActionException;
import org.openhab.binding.lametrictime.api.local.ApplicationActivationException;
import org.openhab.binding.lametrictime.api.local.ApplicationNotFoundException;
import org.openhab.binding.lametrictime.api.local.LaMetricTimeLocal;
import org.openhab.binding.lametrictime.api.local.LocalConfiguration;
import org.openhab.binding.lametrictime.api.local.NotificationCreationException;
import org.openhab.binding.lametrictime.api.local.UpdateException;
import org.openhab.binding.lametrictime.api.local.model.Application;
import org.openhab.binding.lametrictime.api.local.model.Audio;
import org.openhab.binding.lametrictime.api.local.model.Bluetooth;
import org.openhab.binding.lametrictime.api.local.model.Display;
import org.openhab.binding.lametrictime.api.local.model.UpdateAction;
import org.openhab.binding.lametrictime.api.local.model.Widget;
import org.openhab.binding.lametrictime.api.model.CoreAction;
import org.openhab.binding.lametrictime.api.model.CoreApplication;
import org.openhab.binding.lametrictime.api.model.CoreApps;
import org.openhab.binding.lametrictime.api.model.Icon;
import org.openhab.binding.lametrictime.api.model.enums.BrightnessMode;
import org.openhab.binding.lametrictime.api.model.enums.Priority;
import org.openhab.binding.lametrictime.api.model.enums.Sound;
public interface LaMetricTime
{
/**
* Get the version identifier reported by the device.
*
* @return the version
*/
public String getVersion();
/**
* Send a low priority message to the device.
*
* @param message
* the text to display
* @return the identifier of the newly created notification
* @throws NotificationCreationException
* if there is a communication error or malformed data
*/
public String notifyInfo(String message) throws NotificationCreationException;
/**
* Send a medium priority message to the device.
*
* @param message
* the text to display
* @return the identifier of the newly created notification
* @throws NotificationCreationException
* if there is a communication error or malformed data
*/
public String notifyWarning(String message) throws NotificationCreationException;
/**
* Send an urgent message to the device. The notification will not be
* automatically removed. The user will be required to dismiss this
* notification or it must be deleted through he API.
*
* @param message
* the text to display
* @return the identifier of the newly created notification
* @throws NotificationCreationException
* if there is a communication error or malformed data
*/
public String notifyCritical(String message) throws NotificationCreationException;
/**
* Send a notification to the device.
*
* Priority is important. It defines the urgency of this notification as
* related to others in the queue and the current state of the device.
* <ol>
* <li>{@link Priority#INFO}: lowest priority; not shown when the
* screensaver is active; waits for its turn in the queue
* <li>{@link Priority#WARNING}: middle priority; not shown when the
* screensaver is active; preempts {@link Priority#INFO}
* <li>{@link Priority#CRITICAL}: highest priority; shown even when the
* screensaver is active; preempts all other notifications (to be used
* sparingly)
* </ol>
*
* @param message
* the text to display
* @param priority
* the urgency of this notification; defaults to
* {@link Priority#INFO}
* @param icon
* the icon to display next to the message; can be
* <code>null</code>
* @param sound
* the sound to play when the notification is displayed; can be
* <code>null</code>
* @param messageRepeat
* the number of times the message should be displayed before
* being removed (use <code>0</code> to leave the notification on
* the device until it is dismissed by the user or deleted
* through the API)
* @param soundRepeat
* the number of times to repeat the sound (use <code>0</code> to
* keep the sound looping until the notification is dismissed by
* the user or deleted through the API)
* @return the identifier of the newly created notification
* @throws NotificationCreationException
* if there is a communication error or malformed data
*/
public String notify(String message,
Priority priority,
Icon icon,
Sound sound,
int messageRepeat,
int soundRepeat) throws NotificationCreationException;
/**
* Get the built-in clock application. This applications displays the time
* and date. It also provides an alarm feature.
*
* @return the clock app
*/
public Application getClock();
/**
* Get the built-in countdown timer application. This application counts
* time down to zero when it sets off a beeper until it is reset. The
* countdown can also be paused.
*
* @return the countdown app
*/
public Application getCountdown();
/**
* Get the built-in radio application. The radio can play streams from the
* Internet. The streams are set up in a list and can be navigated using
* 'next' and 'previous' actions. The music can be started and stopped.
*
* @return the radio app
*/
public Application getRadio();
/**
* Get the built-in stopwatch application. The stopwatch counts time
* forwards and can be started, paused, and reset.
*
* @return the stopwatch app
*/
public Application getStopwatch();
/**
* Get the built-in weather application. This application displays the
* current weather conditions. It can also display the forecast for today
* and tomorrow.
*
* @return the weather app
*/
public Application getWeather();
/**
* Get any of the built-in applications.
*
* @param coreApp
* the app to retrieve
* @return the requested app
*/
public Application getApplication(CoreApplication coreApp);
/**
* Get any application installed on the device.
*
* @param name
* the name of the app to retrieve
* @return the requested app
* @throws ApplicationNotFoundException
* if the requested app is not found on the device
*/
public Application getApplication(String name) throws ApplicationNotFoundException;
/**
* Display the given built-in application on the device.
*
* @param coreApp
* the app to activate
*/
public void activateApplication(CoreApplication coreApp);
/**
* Display the first instance (widget) of the given application on the
* device.
*
* @param app
* the app to activate
* @throws ApplicationActivationException
* if the app fails to activate
*/
public void activateApplication(Application app) throws ApplicationActivationException;
/**
* Display the given widget on the device. A widget is simply an instance of
* an application. Some applications can be installed more than once (e.g.
* the {@link CoreApps#weather() weather} app) and each instance is assigned
* a widget.
*
* @param widget
* the application instance (widget) to activate
* @throws ApplicationActivationException
* if the app fails to activate
*/
public void activateWidget(Widget widget) throws ApplicationActivationException;
/**
* Perform the given action on the first instance (widget) of the
* corresponding built-in application. The widget will activate
* automatically before carrying out the action.
*
* @param coreAction
* the action to perform
*/
public void doAction(CoreAction coreAction);
/**
* Perform the given action on the first instance (widget) of the given
* application. The widget will activate automatically before carrying out
* the action.
*
* @param app
* the app which understands the requested action
* @param action
* the action to perform
* @throws ApplicationActionException
* if the action cannot be performed
*/
public void doAction(Application app, UpdateAction action) throws ApplicationActionException;
/**
* Perform the given core action on the given widget. A widget is simply an
* instance of an application. Some applications can be installed more than
* once (e.g. the {@link CoreApps#weather() weather} app) and each instance
* is assigned a widget. The widget will activate automatically before
* carrying out the action.
*
* @param widget
* the widget which understands the requested core action
* @param action
* the action to perform
* @throws ApplicationActionException
* if the action cannot be performed
*/
public void doAction(Widget widget, CoreAction action) throws ApplicationActionException;
/**
* Perform the given action on the given widget. A widget is simply an
* instance of an application. Some applications can be installed more than
* once (e.g. the {@link CoreApps#weather() weather} app) and each instance
* is assigned a widget. The widget will activate automatically before
* carrying out the action.
*
* @param widget
* the widget which understands the requested action
* @param action
* the action to perform
* @throws ApplicationActionException
* if the action cannot be performed
*/
public void doAction(Widget widget, UpdateAction action) throws ApplicationActionException;
/**
* Set the display brightness. The {@link #setBrightnessMode(BrightnessMode)
* brightness mode} will also be set to {@link BrightnessMode#MANUAL}.
*
* @param brightness
* the brightness value to set (must be between 0 and 100,
* inclusive)
* @return the updated state of the display
* @throws UpdateException
* if the update failed
*/
public Display setBrightness(int brightness) throws UpdateException;
/**
* Set the brightness mode on the display. {@link BrightnessMode#MANUAL}
* will immediately respect the current brightness value while
* {@link BrightnessMode#AUTO} will ignore the brightness value and set the
* brightness based on ambient light intensity.
*
* @param mode
* the mode to set
* @return the updated state of the display
* @throws UpdateException
* if the update failed
*/
public Display setBrightnessMode(BrightnessMode mode) throws UpdateException;
/**
* Set the speaker volume on the device.
*
* @param volume
* the volume to set (must be between 0 and 100, inclusive)
* @return the update audio state
* @throws UpdateException
* if the update failed
*/
public Audio setVolume(int volume) throws UpdateException;
/**
* Mute the device's speakers. The current volume will be stored so that
* {@link #unmute()} will restored it. If the volume is currently at zero,
* no action will be taken.
*
* @return the update audio state
* @throws UpdateException
* if the update failed
*/
public Audio mute() throws UpdateException;
/**
* Restore the volume prior to {@link #mute()}. If the volume has not been
* muted previously and the volume is currently zero, it will be set to 50%.
*
* @return the update audio state
* @throws UpdateException
* if the update failed
*/
public Audio unmute() throws UpdateException;
/**
* Set the active state of the Bluetooth radio on the device.
*
* @param active
* <code>true</code> to activate Bluetooth; <code>false</code> to
* deactive it
* @return the updated state of Bluetooth on the device
* @throws UpdateException
* if the update failed
*/
public Bluetooth setBluetoothActive(boolean active) throws UpdateException;
/**
* Set the device name as seen via Bluetooth connectivity.
*
* @param name
* the name to display on other devices
* @return the updated state of Bluetooth on the device
* @throws UpdateException
* if the update failed
*/
public Bluetooth setBluetoothName(String name) throws UpdateException;
/**
* Get the local API for more advanced interactions as well device inquiry.
*
* @return the local API
*/
public LaMetricTimeLocal getLocalApi();
/**
* Get the cloud API for interacting with LaMetric's services.
*
* @return the cloud API
*/
public LaMetricTimeCloud getCloudApi();
/**
* Create an instance of this API. For greater control over the
* configuration, see {@link #create(Configuration, ClientBuilder)},
* {@link #create(LocalConfiguration, CloudConfiguration)}, and
* {@link #create(LocalConfiguration, CloudConfiguration, ClientBuilder)}.
*
* @param config
* the configuration parameters that the new instance will use
* @return the API instance
*/
public static LaMetricTime create(Configuration config)
{
return new LaMetricTimeImpl(config);
}
/**
* Create an instance of this API. For greater control over the
* configuration, see
* {@link #create(LocalConfiguration, CloudConfiguration, ClientBuilder)}.
*
* @param config
* the configuration parameters that the new instance will use
* @param clientBuilder
* the builder that will be used to create clients for
* communicating with the device and cloud services
* @return the API instance
*/
public static LaMetricTime create(Configuration config, ClientBuilder clientBuilder)
{
return new LaMetricTimeImpl(config, clientBuilder);
}
/**
* Create an instance of this API specifying detailed configuration for both
* the local and cloud APIs. See also
* {@link #create(LocalConfiguration, CloudConfiguration, ClientBuilder)}.
*
* @param localConfig
* the local API configuration for the new instance
* @param cloudConfig
* the cloud API configuration for the new instance
* @return the API instance
*/
public static LaMetricTime create(LocalConfiguration localConfig,
CloudConfiguration cloudConfig)
{
return new LaMetricTimeImpl(localConfig, cloudConfig);
}
/**
* Create an instance of this API specifying detailed configuration for both
* the local and cloud APIs as well as the generic client.
*
* @param localConfig
* the local API configuration for the new instance
* @param cloudConfig
* the cloud API configuration for the new instance
* @param clientBuilder
* the builder that will be used to create clients for
* communicating with the device and cloud services
* @return the API instance
*/
public static LaMetricTime create(LocalConfiguration localConfig,
CloudConfiguration cloudConfig,
ClientBuilder clientBuilder)
{
return new LaMetricTimeImpl(localConfig, cloudConfig, clientBuilder);
}
}

View File

@@ -0,0 +1,128 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 2013-2015 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* http://glassfish.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package org.openhab.binding.lametrictime.api.authentication;
import java.util.Base64;
import javax.ws.rs.client.ClientRequestContext;
import javax.ws.rs.client.ClientResponseContext;
import javax.ws.rs.core.HttpHeaders;
/**
* Implementation of Basic Http Authentication method (RFC 2617).
*
* @author Miroslav Fuksa
* @author Jakub Podlesak (jakub.podlesak at oracle.com)
* @author Craig McClanahan
*/
final class BasicAuthenticator {
private final HttpAuthenticationFilter.Credentials defaultCredentials;
/**
* Creates a new instance of basic authenticator.
*
* @param defaultCredentials Credentials. Can be {@code null} if no default credentials should be
* used.
*/
BasicAuthenticator(HttpAuthenticationFilter.Credentials defaultCredentials) {
this.defaultCredentials = defaultCredentials;
}
private String calculateAuthentication(HttpAuthenticationFilter.Credentials credentials) {
String username = credentials.getUsername();
byte[] password = credentials.getPassword();
if (username == null) {
username = "";
}
if (password == null) {
password = new byte[0];
}
final byte[] prefix = (username + ":").getBytes(HttpAuthenticationFilter.CHARACTER_SET);
final byte[] usernamePassword = new byte[prefix.length + password.length];
System.arraycopy(prefix, 0, usernamePassword, 0, prefix.length);
System.arraycopy(password, 0, usernamePassword, prefix.length, password.length);
return "Basic " + Base64.getEncoder().encodeToString(usernamePassword);
}
/**
* Adds authentication information to the request.
*
* @param request Request context.
* @throws RequestAuthenticationException in case that basic credentials missing or are in invalid format
*/
public void filterRequest(ClientRequestContext request) throws RequestAuthenticationException {
HttpAuthenticationFilter.Credentials credentials = HttpAuthenticationFilter.getCredentials(request,
defaultCredentials, HttpAuthenticationFilter.Type.BASIC);
if (credentials == null) {
throw new RequestAuthenticationException("BasicAuth credentials are missing.");
}
request.getHeaders().add(HttpHeaders.AUTHORIZATION, calculateAuthentication(credentials));
}
/**
* Checks the response and if basic authentication is required then performs a new request
* with basic authentication.
*
* @param request Request context.
* @param response Response context (will be updated with newest response data if the request was repeated).
* @return {@code true} if response does not require authentication or if authentication is required,
* new request was done with digest authentication information and authentication was successful.
* @throws ResponseAuthenticationException in case that basic credentials missing or are in invalid format
*/
public boolean filterResponseAndAuthenticate(ClientRequestContext request, ClientResponseContext response) {
final String authenticate = response.getHeaders().getFirst(HttpHeaders.WWW_AUTHENTICATE);
if (authenticate != null && authenticate.trim().toUpperCase().startsWith("BASIC")) {
HttpAuthenticationFilter.Credentials credentials = HttpAuthenticationFilter.getCredentials(request,
defaultCredentials, HttpAuthenticationFilter.Type.BASIC);
if (credentials == null) {
throw new ResponseAuthenticationException(null, "BasicAuth credentials are missing.");
}
return HttpAuthenticationFilter.repeatRequest(request, response, calculateAuthentication(credentials));
}
return false;
}
}

View File

@@ -0,0 +1,595 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 2013-2015 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* http://glassfish.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package org.openhab.binding.lametrictime.api.authentication;
import javax.ws.rs.core.Feature;
import javax.ws.rs.core.FeatureContext;
/**
* Features that provides Http Basic and Digest client authentication (based on RFC 2617).
* <p>
* The feature can work in following modes:
* <ul>
* <li><b>BASIC:</b> Basic preemptive authentication. In preemptive mode the authentication information
* is send always with each HTTP request. This mode is more usual than the following non-preemptive mode
* (if you require BASIC authentication you will probably use this preemptive mode). This mode must
* be combined with usage of SSL/TLS as the password is send only BASE64 encoded.</li>
* <li><i>BASIC NON-PREEMPTIVE:</i> Basic non-preemptive authentication. In non-preemptive mode the
* authentication information is added only when server refuses the request with {@code 401} status code and
* then the request is repeated with authentication information. This mode has negative impact on the performance.
* The advantage is that it does not send credentials when they are not needed. This mode must
* be combined with usage of SSL/TLS as the password is send only BASE64 encoded.
* </li>
* <li><b>DIGEST:</b> Http digest authentication. Does not require usage of SSL/TLS.</li>
* <li><b>UNIVERSAL:</b> Combination of basic and digest authentication. The feature works in non-preemptive
* mode which means that it sends requests without authentication information. If {@code 401} status
* code is returned, the request is repeated and an appropriate authentication is used based on the
* authentication requested in the response (defined in {@code WWW-Authenticate} HTTP header. The feature
* remembers which authentication requests were successful for given URI and next time tries to preemptively
* authenticate against this URI with latest successful authentication method.
* </li>
* </ul>
* </p>
* <p>
* To initialize the feature use static method of this feature.
* </p>
* <p>
* Example of building the feature in
* Basic authentication mode:
*
* <pre>
* HttpAuthenticationFeature feature = HttpAuthenticationFeature.basic("user", "superSecretPassword");
* </pre>
* </p>
* <p>
* Example of building the feature in basic non-preemptive mode:
*
* <pre>
* HttpAuthenticationFeature feature = HttpAuthenticationFeature.basicBuilder().nonPreemptive()
* .credentials("user", "superSecretPassword").build();
* </pre>
* </p>
* <p>
* Example of building the feature in universal mode:
*
* <pre>
* HttpAuthenticationFeature feature = HttpAuthenticationFeature.universal("user", "superSecretPassword");
* </pre>
* </p>
* <p>
* Example of building the feature in universal mode with different credentials for basic and digest:
*
* <pre>
* HttpAuthenticationFeature feature = HttpAuthenticationFeature.universalBuilder()
* .credentialsForBasic("user", "123456").credentials("adminuser", "hello").build();
* </pre>
* </p>
* Example of building the feature in basic preemptive mode with no default credentials. Credentials will have
* to be supplied with each request using request properties (see below):
*
* <pre>
* HttpAuthenticationFeature feature = HttpAuthenticationFeature.basicBuilder().build();
* </pre>
* </p>
* <p>
* Once the feature is built it needs to be registered into the {@link javax.ws.rs.client.Client},
* {@link javax.ws.rs.client.WebTarget} or other client configurable object. Example:
*
* <pre>
* final Client client = ClientBuilder.newClient();
* client.register(feature);
* </pre>
* </p>
*
* Then you invoke requests as usual and authentication will be handled by the feature.
* You can change the credentials for each request using properties
*
* <pre>
* final Response response = client.target("http://localhost:8080/rest/homer/contact").request()
* .property(HTTP_AUTHENTICATION_BASIC_USERNAME, "homer")
* .property(HTTP_AUTHENTICATION_BASIC_PASSWORD, "p1swd745").get();
* </pre>
* <p>
* This class also contains property key definitions for overriding only specific basic or digest credentials:
* </p>
*
* @author Miroslav Fuksa
*
* @since 2.5
*/
public class HttpAuthenticationFeature implements Feature {
/**
* Feature authentication mode.
*/
static enum Mode {
/**
* Basic preemptive.
**/
BASIC_PREEMPTIVE,
/**
* Basic non preemptive
*/
BASIC_NON_PREEMPTIVE,
/**
* Digest.
*/
DIGEST,
/**
* Universal.
*/
UNIVERSAL
}
/**
* Builder that creates instances of {@link HttpAuthenticationFeature}.
*/
public static interface Builder {
/**
* Set credentials.
*
* @param username Username.
* @param password Password as byte array.
* @return This builder.
*/
public Builder credentials(String username, byte[] password);
/**
* Set credentials.
*
* @param username Username.
* @param password Password as {@link String}.
* @return This builder.
*/
public Builder credentials(String username, String password);
/**
* Build the feature.
*
* @return Http authentication feature configured from this builder.
*/
public HttpAuthenticationFeature build();
}
/**
* Extension of {@link org.glassfish.jersey.client.authentication.HttpAuthenticationFeature.Builder}
* that builds the http authentication feature configured for basic authentication.
*/
public static interface BasicBuilder extends Builder {
/**
* Configure the builder to create features in non-preemptive basic authentication mode.
*
* @return This builder.
*/
public BasicBuilder nonPreemptive();
}
/**
* that builds the http authentication feature configured in universal mode that supports
* basic and digest authentication.
*/
public static interface UniversalBuilder extends Builder {
/**
* Set credentials that will be used for basic authentication only.
*
* @param username Username.
* @param password Password as {@link String}.
* @return This builder.
*/
public UniversalBuilder credentialsForBasic(String username, String password);
/**
* Set credentials that will be used for basic authentication only.
*
* @param username Username.
* @param password Password as {@code byte array}.
* @return This builder.
*/
public UniversalBuilder credentialsForBasic(String username, byte[] password);
/**
* Set credentials that will be used for digest authentication only.
*
* @param username Username.
* @param password Password as {@link String}.
* @return This builder.
*/
public UniversalBuilder credentialsForDigest(String username, String password);
/**
* Set credentials that will be used for digest authentication only.
*
* @param username Username.
* @param password Password as {@code byte array}.
* @return This builder.
*/
public UniversalBuilder credentialsForDigest(String username, byte[] password);
}
/**
* Implementation of all authentication builders.
*/
static class BuilderImpl implements UniversalBuilder, BasicBuilder {
private String usernameBasic;
private byte[] passwordBasic;
private String usernameDigest;
private byte[] passwordDigest;
private Mode mode;
/**
* Create a new builder.
*
* @param mode Mode in which the final authentication feature should work.
*/
public BuilderImpl(Mode mode) {
this.mode = mode;
}
@Override
public Builder credentials(String username, String password) {
return credentials(username,
password == null ? null : password.getBytes(HttpAuthenticationFilter.CHARACTER_SET));
}
@Override
public Builder credentials(String username, byte[] password) {
credentialsForBasic(username, password);
credentialsForDigest(username, password);
return this;
}
@Override
public UniversalBuilder credentialsForBasic(String username, String password) {
return credentialsForBasic(username,
password == null ? null : password.getBytes(HttpAuthenticationFilter.CHARACTER_SET));
}
@Override
public UniversalBuilder credentialsForBasic(String username, byte[] password) {
this.usernameBasic = username;
this.passwordBasic = password;
return this;
}
@Override
public UniversalBuilder credentialsForDigest(String username, String password) {
return credentialsForDigest(username,
password == null ? null : password.getBytes(HttpAuthenticationFilter.CHARACTER_SET));
}
@Override
public UniversalBuilder credentialsForDigest(String username, byte[] password) {
this.usernameDigest = username;
this.passwordDigest = password;
return this;
}
@Override
public HttpAuthenticationFeature build() {
return new HttpAuthenticationFeature(mode,
usernameBasic == null ? null
: new HttpAuthenticationFilter.Credentials(usernameBasic, passwordBasic),
usernameDigest == null ? null
: new HttpAuthenticationFilter.Credentials(usernameDigest, passwordDigest));
}
@Override
public BasicBuilder nonPreemptive() {
if (mode == Mode.BASIC_PREEMPTIVE) {
this.mode = Mode.BASIC_NON_PREEMPTIVE;
}
return this;
}
}
/**
* Key of the property that can be set into the {@link javax.ws.rs.client.ClientRequestContext client request}
* using {@link javax.ws.rs.client.ClientRequestContext#setProperty(String, Object)} in order to override
* the username for http authentication feature for the request.
* <p>
* Example:
*
* <pre>
* Response response = client.target("http://localhost:8080/rest/joe/orders").request()
* .property(HTTP_AUTHENTICATION_USERNAME, "joe").property(HTTP_AUTHENTICATION_PASSWORD, "p1swd745").get();
* </pre>
* </p>
* The property must be always combined with configuration of {@link #HTTP_AUTHENTICATION_PASSWORD} property
* (as shown in the example). This property pair overrides all password settings of the authentication
* feature for the current request.
* <p>
* The default value must be instance of {@link String}.
* </p>
* <p>
* The name of the configuration property is <tt>{@value}</tt>.
* </p>
*/
public static final String HTTP_AUTHENTICATION_USERNAME = "jersey.config.client.http.auth.username";
/**
* Key of the property that can be set into the {@link javax.ws.rs.client.ClientRequestContext client request}
* using {@link javax.ws.rs.client.ClientRequestContext#setProperty(String, Object)} in order to override
* the password for http authentication feature for the request.
* <p>
* Example:
*
* <pre>
* Response response = client.target("http://localhost:8080/rest/joe/orders").request()
* .property(HTTP_AUTHENTICATION_USERNAME, "joe").property(HTTP_AUTHENTICATION_PASSWORD, "p1swd745").get();
* </pre>
* </p>
* The property must be always combined with configuration of {@link #HTTP_AUTHENTICATION_USERNAME} property
* (as shown in the example). This property pair overrides all password settings of the authentication
* feature for the current request.
* <p>
* The value must be instance of {@link String} or {@code byte} array ({@code byte[]}).
* </p>
* <p>
* The name of the configuration property is <tt>{@value}</tt>.
* </p>
*/
public static final String HTTP_AUTHENTICATION_PASSWORD = "jersey.config.client.http.auth.password";
/**
* Key of the property that can be set into the {@link javax.ws.rs.client.ClientRequestContext client request}
* using {@link javax.ws.rs.client.ClientRequestContext#setProperty(String, Object)} in order to override
* the username for http basic authentication feature for the request.
* <p>
* Example:
*
* <pre>
* Response response = client.target("http://localhost:8080/rest/joe/orders").request()
* .property(HTTP_AUTHENTICATION_BASIC_USERNAME, "joe").property(HTTP_AUTHENTICATION_BASIC_PASSWORD, "p1swd745")
* .get();
* </pre>
* </p>
* The property must be always combined with configuration of {@link #HTTP_AUTHENTICATION_PASSWORD} property
* (as shown in the example). The property pair influence only credentials used during basic authentication.
*
* <p>
* The value must be instance of {@link String}.
* </p>
* <p>
* The name of the configuration property is <tt>{@value}</tt>.
* </p>
*
*/
public static final String HTTP_AUTHENTICATION_BASIC_USERNAME = "jersey.config.client.http.auth.basic.username";
/**
* Key of the property that can be set into the {@link javax.ws.rs.client.ClientRequestContext client request}
* using {@link javax.ws.rs.client.ClientRequestContext#setProperty(String, Object)} in order to override
* the password for http basic authentication feature for the request.
* <p>
* Example:
*
* <pre>
* Response response = client.target("http://localhost:8080/rest/joe/orders").request()
* .property(HTTP_AUTHENTICATION_BASIC_USERNAME, "joe").property(HTTP_AUTHENTICATION_BASIC_PASSWORD, "p1swd745")
* .get();
* </pre>
* </p>
* The property must be always combined with configuration of {@link #HTTP_AUTHENTICATION_USERNAME} property
* (as shown in the example). The property pair influence only credentials used during basic authentication.
* <p>
* The value must be instance of {@link String} or {@code byte} array ({@code byte[]}).
* </p>
* <p>
* The name of the configuration property is <tt>{@value}</tt>.
* </p>
*/
public static final String HTTP_AUTHENTICATION_BASIC_PASSWORD = "jersey.config.client.http.auth.basic.password";
/**
* Key of the property that can be set into the {@link javax.ws.rs.client.ClientRequestContext client request}
* using {@link javax.ws.rs.client.ClientRequestContext#setProperty(String, Object)} in order to override
* the username for http digest authentication feature for the request.
* <p>
* Example:
*
* <pre>
* Response response = client.target("http://localhost:8080/rest/joe/orders").request()
* .property(HTTP_AUTHENTICATION_DIGEST_USERNAME, "joe")
* .property(HTTP_AUTHENTICATION_DIGEST_PASSWORD, "p1swd745").get();
* </pre>
* </p>
* The property must be always combined with configuration of {@link #HTTP_AUTHENTICATION_PASSWORD} property
* (as shown in the example). The property pair influence only credentials used during digest authentication.
* <p>
* The value must be instance of {@link String}.
* </p>
* <p>
* The name of the configuration property is <tt>{@value}</tt>.
* </p>
*/
public static final String HTTP_AUTHENTICATION_DIGEST_USERNAME = "jersey.config.client.http.auth.digest.username";
/**
* Key of the property that can be set into the {@link javax.ws.rs.client.ClientRequestContext client request}
* using {@link javax.ws.rs.client.ClientRequestContext#setProperty(String, Object)} in order to override
* the password for http digest authentication feature for the request.
* <p>
* Example:
*
* <pre>
* Response response = client.target("http://localhost:8080/rest/joe/orders").request()
* .property(HTTP_AUTHENTICATION_DIGEST_USERNAME, "joe")
* .property(HTTP_AUTHENTICATION_DIGEST_PASSWORD, "p1swd745").get();
* </pre>
* </p>
* The property must be always combined with configuration of {@link #HTTP_AUTHENTICATION_PASSWORD} property
* (as shown in the example). The property pair influence only credentials used during digest authentication.
* <p>
* The value must be instance of {@link String} or {@code byte} array ({@code byte[]}).
* </p>
* <p>
* The name of the configuration property is <tt>{@value}</tt>.
* </p>
*/
public static final String HTTP_AUTHENTICATION_DIGEST_PASSWORD = "jersey.config.client.http.auth.digest.password";
/**
* Create the builder of the http authentication feature working in basic authentication mode. The builder
* can build preemptive and non-preemptive basic authentication features.
*
* @return Basic http authentication builder.
*/
public static BasicBuilder basicBuilder() {
return new BuilderImpl(Mode.BASIC_PREEMPTIVE);
}
/**
* Create the http authentication feature in basic preemptive authentication mode initialized with credentials.
*
* @param username Username.
* @param password Password as {@code byte array}.
* @return Http authentication feature configured in basic mode.
*/
public static HttpAuthenticationFeature basic(String username, byte[] password) {
return build(Mode.BASIC_PREEMPTIVE, username, password);
}
/**
* Create the http authentication feature in basic preemptive authentication mode initialized with credentials.
*
* @param username Username.
* @param password Password as {@link String}.
* @return Http authentication feature configured in basic mode.
*/
public static HttpAuthenticationFeature basic(String username, String password) {
return build(Mode.BASIC_PREEMPTIVE, username, password);
}
/**
* Create the http authentication feature in digest authentication mode initialized without default
* credentials. Credentials will have to be supplied using request properties for each request.
*
* @return Http authentication feature configured in digest mode.
*/
public static HttpAuthenticationFeature digest() {
return build(Mode.DIGEST);
}
/**
* Create the http authentication feature in digest authentication mode initialized with credentials.
*
* @param username Username.
* @param password Password as {@code byte array}.
* @return Http authentication feature configured in digest mode.
*/
public static HttpAuthenticationFeature digest(String username, byte[] password) {
return build(Mode.DIGEST, username, password);
}
/**
* Create the http authentication feature in digest authentication mode initialized with credentials.
*
* @param username Username.
* @param password Password as {@link String}.
* @return Http authentication feature configured in digest mode.
*/
public static HttpAuthenticationFeature digest(String username, String password) {
return build(Mode.DIGEST, username, password);
}
/**
* Create the builder that builds http authentication feature in combined mode supporting both,
* basic and digest authentication.
*
* @return Universal builder.
*/
public static UniversalBuilder universalBuilder() {
return new BuilderImpl(Mode.UNIVERSAL);
}
/**
* Create the http authentication feature in combined mode supporting both,
* basic and digest authentication.
*
* @param username Username.
* @param password Password as {@code byte array}.
* @return Http authentication feature configured in digest mode.
*/
public static HttpAuthenticationFeature universal(String username, byte[] password) {
return build(Mode.UNIVERSAL, username, password);
}
/**
* Create the http authentication feature in combined mode supporting both,
* basic and digest authentication.
*
* @param username Username.
* @param password Password as {@link String}.
* @return Http authentication feature configured in digest mode.
*/
public static HttpAuthenticationFeature universal(String username, String password) {
return build(Mode.UNIVERSAL, username, password);
}
private static HttpAuthenticationFeature build(Mode mode) {
return new BuilderImpl(mode).build();
}
private static HttpAuthenticationFeature build(Mode mode, String username, byte[] password) {
return new BuilderImpl(mode).credentials(username, password).build();
}
private static HttpAuthenticationFeature build(Mode mode, String username, String password) {
return new BuilderImpl(mode).credentials(username, password).build();
}
private final Mode mode;
private final HttpAuthenticationFilter.Credentials basicCredentials;
private HttpAuthenticationFeature(Mode mode, HttpAuthenticationFilter.Credentials basicCredentials,
HttpAuthenticationFilter.Credentials digestCredentials) {
this.mode = mode;
this.basicCredentials = basicCredentials;
}
@Override
public boolean configure(FeatureContext context) {
context.register(new HttpAuthenticationFilter(mode, basicCredentials, context.getConfiguration()));
return true;
}
}

View File

@@ -0,0 +1,349 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 2013-2015 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* http://glassfish.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package org.openhab.binding.lametrictime.api.authentication;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.nio.charset.Charset;
import java.util.List;
import java.util.Map;
import javax.annotation.Priority;
import javax.ws.rs.Priorities;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.ClientRequestContext;
import javax.ws.rs.client.ClientRequestFilter;
import javax.ws.rs.client.ClientResponseContext;
import javax.ws.rs.client.ClientResponseFilter;
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.Invocation;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.Configuration;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedHashMap;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
/**
* Http Authentication filter that provides basic and digest authentication (based on RFC 2617).
*
* @author Miroslav Fuksa
*/
@Priority(Priorities.AUTHENTICATION)
class HttpAuthenticationFilter implements ClientRequestFilter, ClientResponseFilter {
/**
* Authentication type.
*/
enum Type {
/**
* Basic authentication.
*/
BASIC
}
private static final String REQUEST_PROPERTY_FILTER_REUSED = "org.openhab.binding.lametrictime.api.authentication.HttpAuthenticationFilter.reused";
private static final String REQUEST_PROPERTY_OPERATION = "org.openhab.binding.lametrictime.api.authentication.HttpAuthenticationFilter.operation";
/**
* Encoding used for authentication calculations.
*/
static final Charset CHARACTER_SET = Charset.forName("iso-8859-1");
private final HttpAuthenticationFeature.Mode mode;
private final BasicAuthenticator basicAuth;
/**
* Create a new filter instance.
*
* @param mode Mode.
* @param basicCredentials Basic credentials (can be {@code null} if this filter does not work in the
* basic mode or if no default credentials are defined).
* @param digestCredentials Digest credentials (can be {@code null} if this filter does not work in the
* digest mode or if no default credentials are defined).
* @param configuration Configuration (non-{@code null}).
*/
HttpAuthenticationFilter(HttpAuthenticationFeature.Mode mode, Credentials basicCredentials,
Configuration configuration) {
this.mode = mode;
switch (mode) {
case BASIC_PREEMPTIVE:
case BASIC_NON_PREEMPTIVE:
this.basicAuth = new BasicAuthenticator(basicCredentials);
break;
case UNIVERSAL:
this.basicAuth = new BasicAuthenticator(basicCredentials);
break;
default:
throw new IllegalStateException("Not implemented.");
}
}
@Override
public void filter(ClientRequestContext request) throws IOException {
if ("true".equals(request.getProperty(REQUEST_PROPERTY_FILTER_REUSED))) {
return;
}
if (request.getHeaders().containsKey(HttpHeaders.AUTHORIZATION)) {
return;
}
Type operation = null;
if (mode == HttpAuthenticationFeature.Mode.BASIC_PREEMPTIVE) {
basicAuth.filterRequest(request);
operation = Type.BASIC;
} else if (mode == HttpAuthenticationFeature.Mode.BASIC_NON_PREEMPTIVE) {
// do nothing
}
if (operation != null) {
request.setProperty(REQUEST_PROPERTY_OPERATION, operation);
}
}
@Override
public void filter(ClientRequestContext request, ClientResponseContext response) throws IOException {
if ("true".equals(request.getProperty(REQUEST_PROPERTY_FILTER_REUSED))) {
return;
}
Type result = null; // which authentication is requested: BASIC or DIGEST
boolean authenticate;
if (response.getStatus() == Response.Status.UNAUTHORIZED.getStatusCode()) {
String authString = response.getHeaders().getFirst(HttpHeaders.WWW_AUTHENTICATE);
if (authString != null) {
final String upperCaseAuth = authString.trim().toUpperCase();
if (upperCaseAuth.startsWith("BASIC")) {
result = Type.BASIC;
} else {
// unknown authentication -> this filter cannot authenticate with this method
return;
}
}
authenticate = true;
} else {
authenticate = false;
}
if (mode == HttpAuthenticationFeature.Mode.BASIC_PREEMPTIVE) {
// do nothing -> 401 will be returned to the client
} else if (mode == HttpAuthenticationFeature.Mode.BASIC_NON_PREEMPTIVE) {
if (authenticate && result == Type.BASIC) {
basicAuth.filterResponseAndAuthenticate(request, response);
}
} else if (mode == HttpAuthenticationFeature.Mode.UNIVERSAL) {
if (authenticate) {
boolean success = false;
// now we have the challenge response and we can authenticate
if (result == Type.BASIC) {
success = basicAuth.filterResponseAndAuthenticate(request, response);
}
}
}
}
private String getCacheKey(ClientRequestContext request) {
return request.getUri().toString() + ":" + request.getMethod();
}
/**
* Repeat the {@code request} with provided {@code newAuthorizationHeader}
* and update the {@code response} with newest response data.
*
* @param request Request context.
* @param response Response context (will be updated with the new response data).
* @param newAuthorizationHeader {@code Authorization} header that should be added to the new request.
* @return {@code true} is the authentication was successful ({@code true} if 401 response code was not returned;
* {@code false} otherwise).
*/
static boolean repeatRequest(ClientRequestContext request, ClientResponseContext response,
String newAuthorizationHeader) {
Client client = ClientBuilder.newClient(request.getConfiguration());
String method = request.getMethod();
MediaType mediaType = request.getMediaType();
URI lUri = request.getUri();
WebTarget resourceTarget = client.target(lUri);
Invocation.Builder builder = resourceTarget.request(mediaType);
MultivaluedMap<String, Object> newHeaders = new MultivaluedHashMap<String, Object>();
for (Map.Entry<String, List<Object>> entry : request.getHeaders().entrySet()) {
if (HttpHeaders.AUTHORIZATION.equals(entry.getKey())) {
continue;
}
newHeaders.put(entry.getKey(), entry.getValue());
}
newHeaders.add(HttpHeaders.AUTHORIZATION, newAuthorizationHeader);
builder.headers(newHeaders);
builder.property(REQUEST_PROPERTY_FILTER_REUSED, "true");
Invocation invocation;
if (request.getEntity() == null) {
invocation = builder.build(method);
} else {
invocation = builder.build(method, Entity.entity(request.getEntity(), request.getMediaType()));
}
Response nextResponse = invocation.invoke();
if (nextResponse.hasEntity()) {
response.setEntityStream(nextResponse.readEntity(InputStream.class));
}
MultivaluedMap<String, String> headers = response.getHeaders();
headers.clear();
headers.putAll(nextResponse.getStringHeaders());
response.setStatus(nextResponse.getStatus());
return response.getStatus() != Response.Status.UNAUTHORIZED.getStatusCode();
}
/**
* Credentials (username + password).
*/
static class Credentials {
private final String username;
private final byte[] password;
/**
* Create a new credentials from username and password as byte array.
*
* @param username Username.
* @param password Password as byte array.
*/
Credentials(String username, byte[] password) {
this.username = username;
this.password = password;
}
/**
* Create a new credentials from username and password as {@link String}.
*
* @param username Username.
* @param password {@code String} password.
*/
Credentials(String username, String password) {
this.username = username;
this.password = password == null ? null : password.getBytes(CHARACTER_SET);
}
/**
* Return username.
*
* @return username.
*/
String getUsername() {
return username;
}
/**
* Return password as byte array.
*
* @return Password string in byte array representation.
*/
byte[] getPassword() {
return password;
}
}
private static Credentials extractCredentials(ClientRequestContext request, Type type) {
String usernameKey = null;
String passwordKey = null;
if (type == null) {
usernameKey = HttpAuthenticationFeature.HTTP_AUTHENTICATION_USERNAME;
passwordKey = HttpAuthenticationFeature.HTTP_AUTHENTICATION_PASSWORD;
} else if (type == Type.BASIC) {
usernameKey = HttpAuthenticationFeature.HTTP_AUTHENTICATION_BASIC_USERNAME;
passwordKey = HttpAuthenticationFeature.HTTP_AUTHENTICATION_BASIC_PASSWORD;
}
String userName = (String) request.getProperty(usernameKey);
if (userName != null && !userName.equals("")) {
byte[] pwdBytes;
Object password = request.getProperty(passwordKey);
if (password instanceof byte[]) {
pwdBytes = ((byte[]) password);
} else if (password instanceof String) {
pwdBytes = ((String) password).getBytes(CHARACTER_SET);
} else {
throw new RequestAuthenticationException("Passwort invalid.");
}
return new Credentials(userName, pwdBytes);
}
return null;
}
/**
* Get credentials actual for the current request. Priorities in credentials selection are the following:
* <ol>
* <li>Basic/digest specific credentials defined in the request properties</li>
* <li>Common credentials defined in the request properties</li>
* <li>{@code defaultCredentials}</li>
* </ol>
*
* @param request Request from which credentials should be extracted.
* @param defaultCredentials Default credentials (can be {@code null}).
* @param type Type of requested credentials.
* @return Credentials or {@code null} if no credentials are found and {@code defaultCredentials} are {@code null}.
* @throws RequestAuthenticationException in case the {@code username} or {@code password} is invalid.
*/
static Credentials getCredentials(ClientRequestContext request, Credentials defaultCredentials, Type type) {
Credentials commonCredentials = extractCredentials(request, type);
if (commonCredentials != null) {
return commonCredentials;
} else {
Credentials specificCredentials = extractCredentials(request, null);
return specificCredentials != null ? specificCredentials : defaultCredentials;
}
}
}

View File

@@ -0,0 +1,79 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* http://glassfish.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package org.openhab.binding.lametrictime.api.authentication;
import javax.ws.rs.ProcessingException;
/**
* Exception thrown by security request authentication.
*
* @author Petr Bouda (petr.bouda at oracle.com)
*/
public class RequestAuthenticationException extends ProcessingException {
/**
* Creates new instance of this exception with exception cause.
*
* @param cause Exception cause.
*/
public RequestAuthenticationException(Throwable cause) {
super(cause);
}
/**
* Creates new instance of this exception with exception message.
*
* @param message Exception message.
*/
public RequestAuthenticationException(String message) {
super(message);
}
/**
* Creates new instance of this exception with exception message and exception cause.
*
* @param message Exception message.
* @param cause Exception cause.
*/
public RequestAuthenticationException(String message, Throwable cause) {
super(message, cause);
}
}

View File

@@ -0,0 +1,83 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* http://glassfish.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package org.openhab.binding.lametrictime.api.authentication;
import javax.ws.rs.client.ResponseProcessingException;
import javax.ws.rs.core.Response;
/**
* Exception thrown by security response authentication.
*
* @author Petr Bouda (petr.bouda at oracle.com)
*/
public class ResponseAuthenticationException extends ResponseProcessingException {
/**
* Creates new instance of this exception with exception cause.
*
* @param response the response instance for which the processing failed.
* @param cause Exception cause.
*/
public ResponseAuthenticationException(Response response, Throwable cause) {
super(response, cause);
}
/**
* Creates new instance of this exception with exception message.
*
* @param response the response instance for which the processing failed.
* @param message Exception message.
*/
public ResponseAuthenticationException(Response response, String message) {
super(response, message);
}
/**
* Creates new instance of this exception with exception message and exception cause.
*
* @param response the response instance for which the processing failed.
* @param message Exception message.
* @param cause Exception cause.
*/
public ResponseAuthenticationException(Response response, String message, Throwable cause) {
super(response, message, cause);
}
}

View File

@@ -0,0 +1,91 @@
/**
* Copyright 2017-2018 Gregory Moyer and contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openhab.binding.lametrictime.api.cloud;
import java.net.URI;
public class CloudConfiguration
{
private URI baseUri = URI.create("https://developer.lametric.com/api/v2");
private boolean logging = false;
private String logLevel = "INFO";
private int logMax = 104857600; // 100kb
public URI getBaseUri()
{
return baseUri;
}
public void setBaseUri(URI baseUri)
{
this.baseUri = baseUri;
}
public CloudConfiguration withBaseUri(URI baseUri)
{
this.baseUri = baseUri;
return this;
}
public boolean isLogging()
{
return logging;
}
public void setLogging(boolean logging)
{
this.logging = logging;
}
public CloudConfiguration withLogging(boolean logging)
{
this.logging = logging;
return this;
}
public String getLogLevel()
{
return logLevel;
}
public void setLogLevel(String logLevel)
{
this.logLevel = logLevel;
}
public CloudConfiguration withLogLevel(String logLevel)
{
this.logLevel = logLevel;
return this;
}
public int getLogMax()
{
return logMax;
}
public void setLogMax(int logMax)
{
this.logMax = logMax;
}
public CloudConfiguration withLogMax(int logMax)
{
this.logMax = logMax;
return this;
}
}

View File

@@ -0,0 +1,39 @@
/**
* Copyright 2017-2018 Gregory Moyer and contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openhab.binding.lametrictime.api.cloud;
import javax.ws.rs.client.ClientBuilder;
import org.openhab.binding.lametrictime.api.cloud.impl.LaMetricTimeCloudImpl;
import org.openhab.binding.lametrictime.api.cloud.model.IconFilter;
import org.openhab.binding.lametrictime.api.cloud.model.Icons;
public interface LaMetricTimeCloud
{
public Icons getIcons();
public Icons getIcons(IconFilter filter);
public static LaMetricTimeCloud create(CloudConfiguration config)
{
return new LaMetricTimeCloudImpl(config);
}
public static LaMetricTimeCloud create(CloudConfiguration config, ClientBuilder clientBuilder)
{
return new LaMetricTimeCloudImpl(config, clientBuilder);
}
}

View File

@@ -0,0 +1,73 @@
/**
* Copyright 2017-2018 Gregory Moyer and contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openhab.binding.lametrictime.api.cloud.impl;
import java.util.logging.Logger;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.core.MediaType;
import org.openhab.binding.lametrictime.api.cloud.CloudConfiguration;
import org.openhab.binding.lametrictime.api.cloud.LaMetricTimeCloud;
import org.openhab.binding.lametrictime.api.cloud.model.IconFilter;
import org.openhab.binding.lametrictime.api.cloud.model.Icons;
import org.openhab.binding.lametrictime.api.common.impl.AbstractClient;
import org.openhab.binding.lametrictime.api.filter.LoggingFilter;
import org.openhab.binding.lametrictime.internal.GsonProvider;
public class LaMetricTimeCloudImpl extends AbstractClient implements LaMetricTimeCloud {
private final CloudConfiguration config;
public LaMetricTimeCloudImpl(CloudConfiguration config) {
this.config = config;
}
public LaMetricTimeCloudImpl(CloudConfiguration config, ClientBuilder clientBuilder) {
super(clientBuilder);
this.config = config;
}
@Override
public Icons getIcons() {
return getClient().target(config.getBaseUri()).path("/icons").request(MediaType.APPLICATION_JSON_TYPE)
.get(Icons.class);
}
@Override
public Icons getIcons(IconFilter filter) {
return getClient().target(config.getBaseUri()).path("/icons").queryParam("page", filter.getPage())
.queryParam("page_size", filter.getPageSize()).queryParam("fields", filter.getFieldsString())
.queryParam("order", filter.getOrderString()).request(MediaType.APPLICATION_JSON_TYPE).get(Icons.class);
}
@Override
protected Client createClient() {
ClientBuilder builder = getClientBuilder();
// setup Gson (de)serialization
GsonProvider<Object> gsonProvider = new GsonProvider<>();
builder.register(gsonProvider);
// turn on logging if requested
if (config.isLogging()) {
builder.register(
new LoggingFilter(Logger.getLogger(LaMetricTimeCloudImpl.class.getName()), config.getLogMax()));
}
return builder.build();
}
}

View File

@@ -0,0 +1,139 @@
/**
* Copyright 2017-2018 Gregory Moyer and contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openhab.binding.lametrictime.api.cloud.model;
public class Icon
{
private Integer id;
private String title;
private String code;
private IconType type;
private String category;
private String url;
private Thumb thumb;
public Integer getId()
{
return id;
}
public void setId(Integer id)
{
this.id = id;
}
public Icon withId(Integer id)
{
this.id = id;
return this;
}
public String getTitle()
{
return title;
}
public void setTitle(String title)
{
this.title = title;
}
public Icon withTitle(String title)
{
this.title = title;
return this;
}
public String getCode()
{
return code;
}
public void setCode(String code)
{
this.code = code;
}
public Icon withCode(String code)
{
this.code = code;
return this;
}
public IconType getType()
{
return type;
}
public void setType(IconType type)
{
this.type = type;
}
public Icon withType(IconType type)
{
this.type = type;
return this;
}
public String getCategory()
{
return category;
}
public void setCategory(String category)
{
this.category = category;
}
public Icon withCategory(String category)
{
this.category = category;
return this;
}
public String getUrl()
{
return url;
}
public void setUrl(String url)
{
this.url = url;
}
public Icon withUrl(String url)
{
this.url = url;
return this;
}
public Thumb getThumb()
{
return thumb;
}
public void setThumb(Thumb thumb)
{
this.thumb = thumb;
}
public Icon withThumb(Thumb thumb)
{
this.thumb = thumb;
return this;
}
}

View File

@@ -0,0 +1,34 @@
/**
* Copyright 2017-2018 Gregory Moyer and contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openhab.binding.lametrictime.api.cloud.model;
import com.google.gson.annotations.SerializedName;
public enum IconField
{
@SerializedName("id")
ID,
@SerializedName("title")
TITLE,
@SerializedName("code")
CODE,
@SerializedName("type")
TYPE,
@SerializedName("url")
URL,
@SerializedName("thumb")
THUMB
}

View File

@@ -0,0 +1,113 @@
/**
* Copyright 2017-2018 Gregory Moyer and contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openhab.binding.lametrictime.api.cloud.model;
import java.util.List;
public class IconFilter
{
private Integer page;
private Integer pageSize;
private List<IconField> fields;
private IconOrder order;
public Integer getPage()
{
return page;
}
public void setPage(Integer page)
{
this.page = page;
}
public IconFilter withPage(Integer page)
{
this.page = page;
return this;
}
public Integer getPageSize()
{
return pageSize;
}
public void setPageSize(Integer pageSize)
{
this.pageSize = pageSize;
}
public IconFilter withPageSize(Integer pageSize)
{
this.pageSize = pageSize;
return this;
}
public List<IconField> getFields()
{
return fields;
}
public String getFieldsString()
{
if (fields == null || fields.isEmpty())
{
return null;
}
StringBuilder builder = new StringBuilder();
builder.append(fields.get(0).name().toLowerCase());
for (int i = 1; i < fields.size(); i++)
{
builder.append(',').append(fields.get(i).name().toLowerCase());
}
return builder.toString();
}
public void setFields(List<IconField> fields)
{
this.fields = fields;
}
public IconFilter withFields(List<IconField> fields)
{
this.fields = fields;
return this;
}
public IconOrder getOrder()
{
return order;
}
public String getOrderString()
{
return order == null ? null : order.name().toLowerCase();
}
public void setOrder(IconOrder order)
{
this.order = order;
}
public IconFilter withOrder(IconOrder order)
{
this.order = order;
return this;
}
}

View File

@@ -0,0 +1,28 @@
/**
* Copyright 2017-2018 Gregory Moyer and contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openhab.binding.lametrictime.api.cloud.model;
import com.google.gson.annotations.SerializedName;
public enum IconOrder
{
@SerializedName("popular")
POPULAR,
@SerializedName("newest")
NEWEST,
@SerializedName("title")
TITLE
}

View File

@@ -0,0 +1,26 @@
/**
* Copyright 2017-2018 Gregory Moyer and contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openhab.binding.lametrictime.api.cloud.model;
import com.google.gson.annotations.SerializedName;
public enum IconType
{
@SerializedName("picture")
PICTURE,
@SerializedName("movie")
MOVIE
}

View File

@@ -0,0 +1,57 @@
/**
* Copyright 2017-2018 Gregory Moyer and contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openhab.binding.lametrictime.api.cloud.model;
import java.util.ArrayList;
import java.util.List;
public class Icons
{
private IconsMetadata meta;
private List<Icon> data = new ArrayList<Icon>();
public IconsMetadata getMeta()
{
return meta;
}
public void setMeta(IconsMetadata meta)
{
this.meta = meta;
}
public Icons withMeta(IconsMetadata meta)
{
this.meta = meta;
return this;
}
public List<Icon> getData()
{
return data;
}
public void setData(List<Icon> data)
{
this.data = data;
}
public Icons withData(List<Icon> data)
{
this.data = data;
return this;
}
}

View File

@@ -0,0 +1,88 @@
/**
* Copyright 2017-2018 Gregory Moyer and contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openhab.binding.lametrictime.api.cloud.model;
public class IconsMetadata
{
private Integer totalIconCount;
private Integer page;
private Integer pageSize;
private Integer pageCount;
public Integer getTotalIconCount()
{
return totalIconCount;
}
public void setTotalIconCount(Integer totalIconCount)
{
this.totalIconCount = totalIconCount;
}
public IconsMetadata withTotalIconCount(Integer totalIconCount)
{
this.totalIconCount = totalIconCount;
return this;
}
public Integer getPage()
{
return page;
}
public void setPage(Integer page)
{
this.page = page;
}
public IconsMetadata withPage(Integer page)
{
this.page = page;
return this;
}
public Integer getPageSize()
{
return pageSize;
}
public void setPageSize(Integer pageSize)
{
this.pageSize = pageSize;
}
public IconsMetadata withPageSize(Integer pageSize)
{
this.pageSize = pageSize;
return this;
}
public Integer getPageCount()
{
return pageCount;
}
public void setPageCount(Integer pageCount)
{
this.pageCount = pageCount;
}
public IconsMetadata withPageCount(Integer pageCount)
{
this.pageCount = pageCount;
return this;
}
}

View File

@@ -0,0 +1,88 @@
/**
* Copyright 2017-2018 Gregory Moyer and contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openhab.binding.lametrictime.api.cloud.model;
public class Thumb
{
private String original;
private String small;
private String large;
private String xlarge;
public String getOriginal()
{
return original;
}
public void setOriginal(String original)
{
this.original = original;
}
public Thumb withOriginal(String original)
{
this.original = original;
return this;
}
public String getSmall()
{
return small;
}
public void setSmall(String small)
{
this.small = small;
}
public Thumb withSmall(String small)
{
this.small = small;
return this;
}
public String getLarge()
{
return large;
}
public void setLarge(String large)
{
this.large = large;
}
public Thumb withLarge(String large)
{
this.large = large;
return this;
}
public String getXlarge()
{
return xlarge;
}
public void setXlarge(String xlarge)
{
this.xlarge = xlarge;
}
public Thumb withXlarge(String xlarge)
{
this.xlarge = xlarge;
return this;
}
}

View File

@@ -0,0 +1,70 @@
/**
* Copyright 2017-2018 Gregory Moyer and contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openhab.binding.lametrictime.api.common.impl;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import com.google.gson.Gson;
public abstract class AbstractClient {
protected final ClientBuilder clientBuilder;
private volatile Client client;
private volatile Gson gson;
public AbstractClient() {
this(ClientBuilder.newBuilder());
}
public AbstractClient(ClientBuilder clientBuilder) {
this.clientBuilder = clientBuilder;
}
protected Client getClient() {
if (client == null) {
synchronized (this) {
if (client == null) {
client = createClient();
}
}
}
return client;
}
protected Gson getGson() {
if (gson == null) {
synchronized (this) {
if (gson == null) {
gson = createGson();
}
}
}
return gson;
}
protected abstract Client createClient();
protected Gson createGson() {
return GsonGenerator.create();
}
protected ClientBuilder getClientBuilder() {
return clientBuilder;
}
}

View File

@@ -0,0 +1,68 @@
/**
* Copyright 2017-2018 Gregory Moyer and contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openhab.binding.lametrictime.api.common.impl;
import org.openhab.binding.lametrictime.api.common.impl.typeadapters.ActionTypeAdapterFactory;
import org.openhab.binding.lametrictime.api.common.impl.typeadapters.ApplicationTypeAdapterFactory;
import org.openhab.binding.lametrictime.api.common.impl.typeadapters.UpdateActionTypeAdapterFactory;
import org.openhab.binding.lametrictime.api.common.impl.typeadapters.imported.JSR310TypeAdapters;
import org.openhab.binding.lametrictime.api.common.impl.typeadapters.imported.RuntimeTypeAdapterFactory;
import org.openhab.binding.lametrictime.api.local.model.BooleanParameter;
import org.openhab.binding.lametrictime.api.local.model.IntegerParameter;
import org.openhab.binding.lametrictime.api.local.model.Parameter;
import org.openhab.binding.lametrictime.api.local.model.StringParameter;
import com.google.gson.FieldNamingPolicy;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
public class GsonGenerator
{
public static Gson create()
{
return create(false);
}
public static Gson create(boolean prettyPrint)
{
GsonBuilder builder = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
.registerTypeAdapterFactory(new ApplicationTypeAdapterFactory())
.registerTypeAdapterFactory(new ActionTypeAdapterFactory())
.registerTypeAdapterFactory(new UpdateActionTypeAdapterFactory())
.registerTypeAdapterFactory(RuntimeTypeAdapterFactory.of(Parameter.class,
"data_type")
.registerSubtype(BooleanParameter.class,
"bool")
.registerSubtype(StringParameter.class,
"string")
.registerSubtype(IntegerParameter.class,
"int"));
// add Java 8 Time API support
JSR310TypeAdapters.registerJSR310TypeAdapters(builder);
if (prettyPrint)
{
builder.setPrettyPrinting();
}
return builder.create();
}
// @formatter:off
private GsonGenerator() {}
// @formatter:on
}

View File

@@ -0,0 +1,110 @@
/**
* Copyright 2017-2018 Gregory Moyer and contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openhab.binding.lametrictime.api.common.impl.typeadapters;
import java.util.ArrayList;
import java.util.List;
import java.util.Map.Entry;
import org.openhab.binding.lametrictime.api.common.impl.typeadapters.imported.CustomizedTypeAdapterFactory;
import org.openhab.binding.lametrictime.api.local.model.Action;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
public class ActionTypeAdapterFactory extends CustomizedTypeAdapterFactory<Action>
{
private static final String PROPERTY_ID = "id";
private static final String PROPERTY_PARAMETERS = "params";
public ActionTypeAdapterFactory()
{
super(Action.class);
}
@Override
protected void beforeWrite(Action source, JsonElement toSerialize)
{
if (toSerialize == null || toSerialize.isJsonNull())
{
return;
}
JsonObject actionObj = toSerialize.getAsJsonObject();
if (actionObj == null || actionObj.isJsonNull())
{
return;
}
// rewrite parameters from a nested object (map) to properties on the action
JsonElement paramsElem = actionObj.get(PROPERTY_PARAMETERS);
if (paramsElem != null && !paramsElem.isJsonNull())
{
JsonObject paramsObj = paramsElem.getAsJsonObject();
actionObj.remove(PROPERTY_PARAMETERS);
for (Entry<String, JsonElement> entry : paramsObj.entrySet())
{
actionObj.add(entry.getKey(), entry.getValue());
}
}
}
@Override
protected void afterRead(JsonElement deserialized)
{
if (deserialized == null || deserialized.isJsonNull())
{
return;
}
JsonObject actionObj = deserialized.getAsJsonObject();
if (actionObj == null || actionObj.isJsonNull())
{
return;
}
if (actionObj.has(PROPERTY_PARAMETERS))
{
throw new IllegalArgumentException("Attempting to deserialize Action that contains a colliding "
+ PROPERTY_PARAMETERS
+ " property");
}
// temporary list of field names
List<String> fields = new ArrayList<>();
// rewrite parameters to a nested object (map)
JsonObject paramsObj = new JsonObject();
for (Entry<String, JsonElement> entry : actionObj.entrySet())
{
// skip ID field
if (PROPERTY_ID.equals(entry.getKey()))
{
continue;
}
String paramId = entry.getKey();
fields.add(paramId); // to be removed later
paramsObj.add(paramId, entry.getValue());
}
actionObj.add(PROPERTY_PARAMETERS, paramsObj);
// remove all fields other than the list
fields.forEach(field -> actionObj.remove(field));
}
}

View File

@@ -0,0 +1,126 @@
/**
* Copyright 2017-2018 Gregory Moyer and contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openhab.binding.lametrictime.api.common.impl.typeadapters;
import java.util.Map.Entry;
import org.openhab.binding.lametrictime.api.common.impl.typeadapters.imported.CustomizedTypeAdapterFactory;
import org.openhab.binding.lametrictime.api.local.model.Application;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
public class ApplicationTypeAdapterFactory extends CustomizedTypeAdapterFactory<Application>
{
private static final String PROPERTY_ID = "id";
private static final String PROPERTY_WIDGETS = "widgets";
private static final String PROPERTY_ACTIONS = "actions";
public ApplicationTypeAdapterFactory()
{
super(Application.class);
}
@Override
protected void beforeWrite(Application source, JsonElement toSerialize)
{
if (toSerialize == null || toSerialize.isJsonNull())
{
return;
}
JsonObject appObj = toSerialize.getAsJsonObject();
if (appObj == null || appObj.isJsonNull())
{
return;
}
// remove widget IDs
JsonElement widgetsElem = appObj.get(PROPERTY_WIDGETS);
if (widgetsElem != null && !widgetsElem.isJsonNull())
{
for (Entry<String, JsonElement> entry : widgetsElem.getAsJsonObject().entrySet())
{
JsonElement widgetElem = entry.getValue();
if (widgetElem == null || widgetElem.isJsonNull())
{
continue;
}
widgetElem.getAsJsonObject().remove(PROPERTY_ID);
}
}
// remove action IDs
JsonElement actionsElem = appObj.get(PROPERTY_ACTIONS);
if (actionsElem != null && !actionsElem.isJsonNull())
{
for (Entry<String, JsonElement> entry : actionsElem.getAsJsonObject().entrySet())
{
JsonElement actionElem = entry.getValue();
if (actionElem == null || actionElem.isJsonNull())
{
continue;
}
actionElem.getAsJsonObject().remove(PROPERTY_ID);
}
}
}
@Override
protected void afterRead(JsonElement deserialized)
{
if (deserialized == null || deserialized.isJsonNull())
{
return;
}
JsonObject appObj = deserialized.getAsJsonObject();
if (appObj == null || appObj.isJsonNull())
{
return;
}
// inject widget IDs
JsonElement widgetsElem = appObj.get(PROPERTY_WIDGETS);
if (widgetsElem != null && !widgetsElem.isJsonNull())
{
for (Entry<String, JsonElement> entry : widgetsElem.getAsJsonObject().entrySet())
{
JsonElement widgetElem = entry.getValue();
if (widgetElem == null || widgetElem.isJsonNull())
{
continue;
}
widgetElem.getAsJsonObject().addProperty(PROPERTY_ID, entry.getKey());
}
}
// inject action IDs
JsonElement actionsElem = appObj.get(PROPERTY_ACTIONS);
if (actionsElem != null && !actionsElem.isJsonNull())
{
for (Entry<String, JsonElement> entry : actionsElem.getAsJsonObject().entrySet())
{
JsonElement actionElem = entry.getValue();
if (actionElem == null || actionElem.isJsonNull())
{
continue;
}
actionElem.getAsJsonObject().addProperty(PROPERTY_ID, entry.getKey());
}
}
}
}

View File

@@ -0,0 +1,75 @@
/**
* Copyright 2017-2018 Gregory Moyer and contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openhab.binding.lametrictime.api.common.impl.typeadapters;
import java.util.Map.Entry;
import org.openhab.binding.lametrictime.api.common.impl.typeadapters.imported.CustomizedTypeAdapterFactory;
import org.openhab.binding.lametrictime.api.local.model.UpdateAction;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
public class UpdateActionTypeAdapterFactory extends CustomizedTypeAdapterFactory<UpdateAction>
{
private static final String PROPERTY_PARAMETERS = "params";
private static final String PROPERTY_VALUE = "value";
public UpdateActionTypeAdapterFactory()
{
super(UpdateAction.class);
}
@Override
protected void beforeWrite(UpdateAction source, JsonElement toSerialize)
{
if (toSerialize == null || toSerialize.isJsonNull())
{
return;
}
JsonObject actionObj = toSerialize.getAsJsonObject();
if (actionObj == null || actionObj.isJsonNull())
{
return;
}
// rewrite parameters map from {name => Parameter} to {name => value}
JsonElement paramsElem = actionObj.get(PROPERTY_PARAMETERS);
if (paramsElem != null && !paramsElem.isJsonNull())
{
JsonObject paramsObj = paramsElem.getAsJsonObject();
actionObj.remove(PROPERTY_PARAMETERS);
JsonObject newParamsObj = new JsonObject();
for (Entry<String, JsonElement> entry : paramsObj.entrySet())
{
newParamsObj.add(entry.getKey(),
entry.getValue()
.getAsJsonObject()
.getAsJsonPrimitive(PROPERTY_VALUE));
}
actionObj.add(PROPERTY_PARAMETERS, newParamsObj);
}
}
@Override
protected void afterRead(JsonElement deserialized)
{
throw new UnsupportedOperationException(UpdateAction.class.getName()
+ " cannot be derialized");
}
}

View File

@@ -0,0 +1,74 @@
/*
* Pulled from Stack Overflow answer located here: http://stackoverflow.com/a/11272452
* and placed in an appropriate package within this library.
*/
package org.openhab.binding.lametrictime.api.common.impl.typeadapters.imported;
import java.io.IOException;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.TypeAdapter;
import com.google.gson.TypeAdapterFactory;
import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
public abstract class CustomizedTypeAdapterFactory<C> implements TypeAdapterFactory
{
private final Class<C> customizedClass;
public CustomizedTypeAdapterFactory(Class<C> customizedClass)
{
this.customizedClass = customizedClass;
}
@Override
@SuppressWarnings("unchecked") // we use a runtime check to guarantee that 'C' and 'T' are equal
public final <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type)
{
return type.getRawType() == customizedClass
? (TypeAdapter<T>)customizeMyClassAdapter(gson, (TypeToken<C>)type)
: null;
}
private TypeAdapter<C> customizeMyClassAdapter(Gson gson, TypeToken<C> type)
{
final TypeAdapter<C> delegate = gson.getDelegateAdapter(this, type);
final TypeAdapter<JsonElement> elementAdapter = gson.getAdapter(JsonElement.class);
return new TypeAdapter<C>()
{
@Override
public void write(JsonWriter out, C value) throws IOException
{
JsonElement tree = delegate.toJsonTree(value);
beforeWrite(value, tree);
elementAdapter.write(out, tree);
}
@Override
public C read(JsonReader in) throws IOException
{
JsonElement tree = elementAdapter.read(in);
afterRead(tree);
return delegate.fromJsonTree(tree);
}
};
}
/**
* Override this to muck with {@code toSerialize} before it is written to
* the outgoing JSON stream.
*/
protected void beforeWrite(C source, JsonElement toSerialize)
{
}
/**
* Override this to muck with {@code deserialized} before it parsed into the
* application type.
*/
protected void afterRead(JsonElement deserialized)
{
}
}

View File

@@ -0,0 +1,43 @@
/*
* Copyright (C) 2016 Gson Type Adapter Authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* Imported from https://github.com/google-gson/typeadapters/tree/master/jsr310/src
* and repackaged to avoid the default package.
*/
package org.openhab.binding.lametrictime.api.common.impl.typeadapters.imported;
import java.util.function.Function;
/**
* Abstract type adapter for jsr310 date-time types.
*
* @author Christophe Bornet
*/
abstract class DateTimeTypeAdapter<T> extends TemporalTypeAdapter<T> {
DateTimeTypeAdapter(Function<String, T> parseFunction) {
super(parseFunction);
}
@Override
public String preProcess(String in) {
if (in.endsWith("+0000")) {
return in.substring(0, in.length()-5) + "Z";
}
return in;
}
}

View File

@@ -0,0 +1,35 @@
/*
* Copyright (C) 2016 Gson Type Adapter Authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* Imported from https://github.com/google-gson/typeadapters/tree/master/jsr310/src
* and repackaged to avoid the default package.
*/
package org.openhab.binding.lametrictime.api.common.impl.typeadapters.imported;
import java.time.Duration;
/**
* Type adapter for jsr310 {@link Duration} class.
*
* @author Christophe Bornet
*/
public class DurationTypeAdapter extends TemporalTypeAdapter<Duration> {
public DurationTypeAdapter() {
super(Duration::parse);
}
}

View File

@@ -0,0 +1,35 @@
/*
* Copyright (C) 2016 Gson Type Adapter Authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* Imported from https://github.com/google-gson/typeadapters/tree/master/jsr310/src
* and repackaged to avoid the default package.
*/
package org.openhab.binding.lametrictime.api.common.impl.typeadapters.imported;
import java.time.Instant;
/**
* Type adapter for jsr310 {@link Instant} class.
*
* @author Christophe Bornet
*/
public class InstantTypeAdapter extends DateTimeTypeAdapter<Instant> {
public InstantTypeAdapter() {
super(Instant::parse);
}
}

View File

@@ -0,0 +1,109 @@
/*
* Copyright (C) 2016 Gson Type Adapter Authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* Imported from https://github.com/google-gson/typeadapters/tree/master/jsr310/src
* and repackaged to avoid the default package.
*/
package org.openhab.binding.lametrictime.api.common.impl.typeadapters.imported;
import com.google.gson.GsonBuilder;
import java.time.*;
/**
* Helper methods to register JSR310 type adapters.
*
* @author Christophe Bornet
*/
public class JSR310TypeAdapters {
private JSR310TypeAdapters() {
}
public static GsonBuilder registerDurationTypeAdapter(GsonBuilder gsonBuilder) {
return gsonBuilder.registerTypeAdapter(Duration.class, new DurationTypeAdapter());
}
public static GsonBuilder registerInstantTypeAdapter(GsonBuilder gsonBuilder) {
return gsonBuilder.registerTypeAdapter(Instant.class, new InstantTypeAdapter());
}
public static GsonBuilder registerLocalDateTimeTypeAdapter(GsonBuilder gsonBuilder) {
return gsonBuilder.registerTypeAdapter(LocalDateTime.class, new LocalDateTimeTypeAdapter());
}
public static GsonBuilder registerLocalDateTypeAdapter(GsonBuilder gsonBuilder) {
return gsonBuilder.registerTypeAdapter(LocalDate.class, new LocalDateTypeAdapter());
}
public static GsonBuilder registerLocalTimeTypeAdapter(GsonBuilder gsonBuilder) {
return gsonBuilder.registerTypeAdapter(LocalTime.class, new LocalTimeTypeAdapter());
}
public static GsonBuilder registerMonthDayTypeAdapter(GsonBuilder gsonBuilder) {
return gsonBuilder.registerTypeAdapter(MonthDay.class, new MonthDayTypeAdapter());
}
public static GsonBuilder registerOffsetDateTimeTypeAdapter(GsonBuilder gsonBuilder) {
return gsonBuilder.registerTypeAdapter(OffsetDateTime.class, new OffsetDateTimeTypeAdapter());
}
public static GsonBuilder registerOffsetTimeTypeAdapter(GsonBuilder gsonBuilder) {
return gsonBuilder.registerTypeAdapter(OffsetTime.class, new OffsetTimeTypeAdapter());
}
public static GsonBuilder registerPeriodTypeAdapter(GsonBuilder gsonBuilder) {
return gsonBuilder.registerTypeAdapter(Period.class, new PeriodTypeAdapter());
}
public static GsonBuilder registerYearMonthTypeAdapter(GsonBuilder gsonBuilder) {
return gsonBuilder.registerTypeAdapter(YearMonth.class, new YearMonthTypeAdapter());
}
public static GsonBuilder registerYearTypeAdapter(GsonBuilder gsonBuilder) {
return gsonBuilder.registerTypeAdapter(Year.class, new YearTypeAdapter());
}
public static GsonBuilder registerZonedDateTimeTypeAdapter(GsonBuilder gsonBuilder) {
return gsonBuilder.registerTypeAdapter(ZonedDateTime.class, new ZonedDateTimeTypeAdapter());
}
/**
* Helper method to register all the available JSR310 adapters at once.
* @param gsonBuilder the gsonBuilder on which all the JSR310 adapters must be registered.
* @return the gsonBuilder with the JSR310 adapters registered.
*/
public static GsonBuilder registerJSR310TypeAdapters(GsonBuilder gsonBuilder) {
registerDurationTypeAdapter(gsonBuilder);
registerInstantTypeAdapter(gsonBuilder);
registerLocalDateTimeTypeAdapter(gsonBuilder);
registerLocalDateTypeAdapter(gsonBuilder);
registerLocalTimeTypeAdapter(gsonBuilder);
registerMonthDayTypeAdapter(gsonBuilder);
registerOffsetDateTimeTypeAdapter(gsonBuilder);
registerOffsetTimeTypeAdapter(gsonBuilder);
registerPeriodTypeAdapter(gsonBuilder);
registerYearMonthTypeAdapter(gsonBuilder);
registerYearTypeAdapter(gsonBuilder);
registerZonedDateTimeTypeAdapter(gsonBuilder);
return gsonBuilder;
}
}

View File

@@ -0,0 +1,35 @@
/*
* Copyright (C) 2016 Gson Type Adapter Authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* Imported from https://github.com/google-gson/typeadapters/tree/master/jsr310/src
* and repackaged to avoid the default package.
*/
package org.openhab.binding.lametrictime.api.common.impl.typeadapters.imported;
import java.time.LocalDateTime;
/**
* Type adapter for jsr310 {@link LocalDateTime} class.
*
* @author Christophe Bornet
*/
public class LocalDateTimeTypeAdapter extends DateTimeTypeAdapter<LocalDateTime> {
public LocalDateTimeTypeAdapter() {
super(LocalDateTime::parse);
}
}

View File

@@ -0,0 +1,35 @@
/*
* Copyright (C) 2016 Gson Type Adapter Authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* Imported from https://github.com/google-gson/typeadapters/tree/master/jsr310/src
* and repackaged to avoid the default package.
*/
package org.openhab.binding.lametrictime.api.common.impl.typeadapters.imported;
import java.time.LocalDate;
/**
* Type adapter for jsr310 {@link LocalDate} class.
*
* @author Christophe Bornet
*/
public class LocalDateTypeAdapter extends TemporalTypeAdapter<LocalDate> {
public LocalDateTypeAdapter() {
super(LocalDate::parse);
}
}

View File

@@ -0,0 +1,36 @@
/*
* Copyright (C) 2016 Gson Type Adapter Authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* Imported from https://github.com/google-gson/typeadapters/tree/master/jsr310/src
* and repackaged to avoid the default package.
*/
package org.openhab.binding.lametrictime.api.common.impl.typeadapters.imported;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
/**
* Type adapter for jsr310 {@link LocalTime} class.
*
* @author Christophe Bornet
*/
public class LocalTimeTypeAdapter extends TemporalTypeAdapter<LocalTime> {
public LocalTimeTypeAdapter() {
super(LocalTime::parse);
}
}

View File

@@ -0,0 +1,35 @@
/*
* Copyright (C) 2016 Gson Type Adapter Authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* Imported from https://github.com/google-gson/typeadapters/tree/master/jsr310/src
* and repackaged to avoid the default package.
*/
package org.openhab.binding.lametrictime.api.common.impl.typeadapters.imported;
import java.time.MonthDay;
/**
* Type adapter for jsr310 {@link MonthDay} class.
*
* @author Christophe Bornet
*/
public class MonthDayTypeAdapter extends TemporalTypeAdapter<MonthDay> {
public MonthDayTypeAdapter() {
super(MonthDay::parse);
}
}

View File

@@ -0,0 +1,36 @@
/*
* Copyright (C) 2016 Gson Type Adapter Authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* Imported from https://github.com/google-gson/typeadapters/tree/master/jsr310/src
* and repackaged to avoid the default package.
*/
package org.openhab.binding.lametrictime.api.common.impl.typeadapters.imported;
import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
/**
* Type adapter for jsr310 {@link OffsetDateTime} class.
*
* @author Christophe Bornet
*/
public class OffsetDateTimeTypeAdapter extends DateTimeTypeAdapter<OffsetDateTime> {
public OffsetDateTimeTypeAdapter() {
super(OffsetDateTime::parse);
}
}

View File

@@ -0,0 +1,36 @@
/*
* Copyright (C) 2016 Gson Type Adapter Authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* Imported from https://github.com/google-gson/typeadapters/tree/master/jsr310/src
* and repackaged to avoid the default package.
*/
package org.openhab.binding.lametrictime.api.common.impl.typeadapters.imported;
import java.time.OffsetTime;
import java.time.format.DateTimeFormatter;
/**
* Type adapter for jsr310 {@link OffsetTime} class.
*
* @author Christophe Bornet
*/
public class OffsetTimeTypeAdapter extends TemporalTypeAdapter<OffsetTime> {
public OffsetTimeTypeAdapter() {
super(OffsetTime::parse);
}
}

View File

@@ -0,0 +1,35 @@
/*
* Copyright (C) 2016 Gson Type Adapter Authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* Imported from https://github.com/google-gson/typeadapters/tree/master/jsr310/src
* and repackaged to avoid the default package.
*/
package org.openhab.binding.lametrictime.api.common.impl.typeadapters.imported;
import java.time.Period;
/**
* Type adapter for jsr310 {@link Period} class.
*
* @author Christophe Bornet
*/
public class PeriodTypeAdapter extends TemporalTypeAdapter<Period> {
public PeriodTypeAdapter() {
super(Period::parse);
}
}

View File

@@ -0,0 +1,420 @@
/*
* Copyright (C) 2011 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* Copied from
* https://raw.githubusercontent.com/google/gson/master/extras/src/main/java/com/google/gson/typeadapters/RuntimeTypeAdapterFactory.java
* and repackaged here with additional content from
* com.google.gson.internal.{Streams,TypeAdapters,LazilyParsedNumber}
* to avoid using the internal package.
*/
package org.openhab.binding.lametrictime.api.common.impl.typeadapters.imported;
import java.io.EOFException;
import java.io.IOException;
import java.io.ObjectStreamException;
import java.math.BigDecimal;
import java.util.LinkedHashMap;
import java.util.Map;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonIOException;
import com.google.gson.JsonNull;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSyntaxException;
import com.google.gson.TypeAdapter;
import com.google.gson.TypeAdapterFactory;
import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
import com.google.gson.stream.MalformedJsonException;
/**
* Adapts values whose runtime type may differ from their declaration type. This
* is necessary when a field's type is not the same type that GSON should create
* when deserializing that field. For example, consider these types:
* <pre> {@code
* abstract class Shape {
* int x;
* int y;
* }
* class Circle extends Shape {
* int radius;
* }
* class Rectangle extends Shape {
* int width;
* int height;
* }
* class Diamond extends Shape {
* int width;
* int height;
* }
* class Drawing {
* Shape bottomShape;
* Shape topShape;
* }
* }</pre>
* <p>Without additional type information, the serialized JSON is ambiguous. Is
* the bottom shape in this drawing a rectangle or a diamond? <pre> {@code
* {
* "bottomShape": {
* "width": 10,
* "height": 5,
* "x": 0,
* "y": 0
* },
* "topShape": {
* "radius": 2,
* "x": 4,
* "y": 1
* }
* }}</pre>
* This class addresses this problem by adding type information to the
* serialized JSON and honoring that type information when the JSON is
* deserialized: <pre> {@code
* {
* "bottomShape": {
* "type": "Diamond",
* "width": 10,
* "height": 5,
* "x": 0,
* "y": 0
* },
* "topShape": {
* "type": "Circle",
* "radius": 2,
* "x": 4,
* "y": 1
* }
* }}</pre>
* Both the type field name ({@code "type"}) and the type labels ({@code
* "Rectangle"}) are configurable.
*
* <h3>Registering Types</h3>
* Create a {@code RuntimeTypeAdapterFactory} by passing the base type and type field
* name to the {@link #of} factory method. If you don't supply an explicit type
* field name, {@code "type"} will be used. <pre> {@code
* RuntimeTypeAdapterFactory<Shape> shapeAdapterFactory
* = RuntimeTypeAdapterFactory.of(Shape.class, "type");
* }</pre>
* Next register all of your subtypes. Every subtype must be explicitly
* registered. This protects your application from injection attacks. If you
* don't supply an explicit type label, the type's simple name will be used.
* <pre> {@code
* shapeAdapter.registerSubtype(Rectangle.class, "Rectangle");
* shapeAdapter.registerSubtype(Circle.class, "Circle");
* shapeAdapter.registerSubtype(Diamond.class, "Diamond");
* }</pre>
* Finally, register the type adapter factory in your application's GSON builder:
* <pre> {@code
* Gson gson = new GsonBuilder()
* .registerTypeAdapterFactory(shapeAdapterFactory)
* .create();
* }</pre>
* Like {@code GsonBuilder}, this API supports chaining: <pre> {@code
* RuntimeTypeAdapterFactory<Shape> shapeAdapterFactory = RuntimeTypeAdapterFactory.of(Shape.class)
* .registerSubtype(Rectangle.class)
* .registerSubtype(Circle.class)
* .registerSubtype(Diamond.class);
* }</pre>
*/
public final class RuntimeTypeAdapterFactory<T> implements TypeAdapterFactory {
private final Class<?> baseType;
private final String typeFieldName;
private final Map<String, Class<?>> labelToSubtype = new LinkedHashMap<String, Class<?>>();
private final Map<Class<?>, String> subtypeToLabel = new LinkedHashMap<Class<?>, String>();
private RuntimeTypeAdapterFactory(Class<?> baseType, String typeFieldName) {
if (typeFieldName == null || baseType == null) {
throw new NullPointerException();
}
this.baseType = baseType;
this.typeFieldName = typeFieldName;
}
/**
* Creates a new runtime type adapter using for {@code baseType} using {@code
* typeFieldName} as the type field name. Type field names are case sensitive.
*/
public static <T> RuntimeTypeAdapterFactory<T> of(Class<T> baseType, String typeFieldName) {
return new RuntimeTypeAdapterFactory<T>(baseType, typeFieldName);
}
/**
* Creates a new runtime type adapter for {@code baseType} using {@code "type"} as
* the type field name.
*/
public static <T> RuntimeTypeAdapterFactory<T> of(Class<T> baseType) {
return new RuntimeTypeAdapterFactory<T>(baseType, "type");
}
/**
* Registers {@code type} identified by {@code label}. Labels are case
* sensitive.
*
* @throws IllegalArgumentException if either {@code type} or {@code label}
* have already been registered on this type adapter.
*/
public RuntimeTypeAdapterFactory<T> registerSubtype(Class<? extends T> type, String label) {
if (type == null || label == null) {
throw new NullPointerException();
}
if (subtypeToLabel.containsKey(type) || labelToSubtype.containsKey(label)) {
throw new IllegalArgumentException("types and labels must be unique");
}
labelToSubtype.put(label, type);
subtypeToLabel.put(type, label);
return this;
}
/**
* Registers {@code type} identified by its {@link Class#getSimpleName simple
* name}. Labels are case sensitive.
*
* @throws IllegalArgumentException if either {@code type} or its simple name
* have already been registered on this type adapter.
*/
public RuntimeTypeAdapterFactory<T> registerSubtype(Class<? extends T> type) {
return registerSubtype(type, type.getSimpleName());
}
public <R> TypeAdapter<R> create(Gson gson, TypeToken<R> type) {
if (type.getRawType() != baseType) {
return null;
}
final Map<String, TypeAdapter<?>> labelToDelegate
= new LinkedHashMap<String, TypeAdapter<?>>();
final Map<Class<?>, TypeAdapter<?>> subtypeToDelegate
= new LinkedHashMap<Class<?>, TypeAdapter<?>>();
for (Map.Entry<String, Class<?>> entry : labelToSubtype.entrySet()) {
TypeAdapter<?> delegate = gson.getDelegateAdapter(this, TypeToken.get(entry.getValue()));
labelToDelegate.put(entry.getKey(), delegate);
subtypeToDelegate.put(entry.getValue(), delegate);
}
return new TypeAdapter<R>() {
@Override public R read(JsonReader in) throws IOException {
JsonElement jsonElement = RuntimeTypeAdapterFactory.parse(in);
JsonElement labelJsonElement = jsonElement.getAsJsonObject().remove(typeFieldName);
if (labelJsonElement == null) {
throw new JsonParseException("cannot deserialize " + baseType
+ " because it does not define a field named " + typeFieldName);
}
String label = labelJsonElement.getAsString();
@SuppressWarnings("unchecked") // registration requires that subtype extends T
TypeAdapter<R> delegate = (TypeAdapter<R>) labelToDelegate.get(label);
if (delegate == null) {
throw new JsonParseException("cannot deserialize " + baseType + " subtype named "
+ label + "; did you forget to register a subtype?");
}
return delegate.fromJsonTree(jsonElement);
}
@Override public void write(JsonWriter out, R value) throws IOException {
Class<?> srcType = value.getClass();
String label = subtypeToLabel.get(srcType);
@SuppressWarnings("unchecked") // registration requires that subtype extends T
TypeAdapter<R> delegate = (TypeAdapter<R>) subtypeToDelegate.get(srcType);
if (delegate == null) {
throw new JsonParseException("cannot serialize " + srcType.getName()
+ "; did you forget to register a subtype?");
}
JsonObject jsonObject = delegate.toJsonTree(value).getAsJsonObject();
if (jsonObject.has(typeFieldName)) {
throw new JsonParseException("cannot serialize " + srcType.getName()
+ " because it already defines a field named " + typeFieldName);
}
JsonObject clone = new JsonObject();
clone.add(typeFieldName, new JsonPrimitive(label));
for (Map.Entry<String, JsonElement> e : jsonObject.entrySet()) {
clone.add(e.getKey(), e.getValue());
}
RuntimeTypeAdapterFactory.write(clone, out);
}
}.nullSafe();
}
/**
* Takes a reader in any state and returns the next value as a JsonElement.
*/
private static JsonElement parse(JsonReader reader) throws JsonParseException {
boolean isEmpty = true;
try {
reader.peek();
isEmpty = false;
return RuntimeTypeAdapterFactory.JSON_ELEMENT.read(reader);
} catch (EOFException e) {
/*
* For compatibility with JSON 1.5 and earlier, we return a JsonNull for
* empty documents instead of throwing.
*/
if (isEmpty) {
return JsonNull.INSTANCE;
}
// The stream ended prematurely so it is likely a syntax error.
throw new JsonSyntaxException(e);
} catch (MalformedJsonException e) {
throw new JsonSyntaxException(e);
} catch (IOException e) {
throw new JsonIOException(e);
} catch (NumberFormatException e) {
throw new JsonSyntaxException(e);
}
}
/**
* Writes the JSON element to the writer, recursively.
*/
private static void write(JsonElement element, JsonWriter writer) throws IOException {
RuntimeTypeAdapterFactory.JSON_ELEMENT.write(writer, element);
}
private static final TypeAdapter<JsonElement> JSON_ELEMENT = new TypeAdapter<JsonElement>() {
@Override public JsonElement read(JsonReader in) throws IOException {
switch (in.peek()) {
case STRING:
return new JsonPrimitive(in.nextString());
case NUMBER:
String number = in.nextString();
return new JsonPrimitive(new LazilyParsedNumber(number));
case BOOLEAN:
return new JsonPrimitive(in.nextBoolean());
case NULL:
in.nextNull();
return JsonNull.INSTANCE;
case BEGIN_ARRAY:
JsonArray array = new JsonArray();
in.beginArray();
while (in.hasNext()) {
array.add(read(in));
}
in.endArray();
return array;
case BEGIN_OBJECT:
JsonObject object = new JsonObject();
in.beginObject();
while (in.hasNext()) {
object.add(in.nextName(), read(in));
}
in.endObject();
return object;
case END_DOCUMENT:
case NAME:
case END_OBJECT:
case END_ARRAY:
default:
throw new IllegalArgumentException();
}
}
@Override public void write(JsonWriter out, JsonElement value) throws IOException {
if (value == null || value.isJsonNull()) {
out.nullValue();
} else if (value.isJsonPrimitive()) {
JsonPrimitive primitive = value.getAsJsonPrimitive();
if (primitive.isNumber()) {
out.value(primitive.getAsNumber());
} else if (primitive.isBoolean()) {
out.value(primitive.getAsBoolean());
} else {
out.value(primitive.getAsString());
}
} else if (value.isJsonArray()) {
out.beginArray();
for (JsonElement e : value.getAsJsonArray()) {
write(out, e);
}
out.endArray();
} else if (value.isJsonObject()) {
out.beginObject();
for (Map.Entry<String, JsonElement> e : value.getAsJsonObject().entrySet()) {
out.name(e.getKey());
write(out, e.getValue());
}
out.endObject();
} else {
throw new IllegalArgumentException("Couldn't write " + value.getClass());
}
}
};
/**
* This class holds a number value that is lazily converted to a specific number type
*
* @author Inderjeet Singh
*/
public static final class LazilyParsedNumber extends Number {
private final String value;
public LazilyParsedNumber(String value) {
this.value = value;
}
@Override
public int intValue() {
try {
return Integer.parseInt(value);
} catch (NumberFormatException e) {
try {
return (int) Long.parseLong(value);
} catch (NumberFormatException nfe) {
return new BigDecimal(value).intValue();
}
}
}
@Override
public long longValue() {
try {
return Long.parseLong(value);
} catch (NumberFormatException e) {
return new BigDecimal(value).longValue();
}
}
@Override
public float floatValue() {
return Float.parseFloat(value);
}
@Override
public double doubleValue() {
return Double.parseDouble(value);
}
@Override
public String toString() {
return value;
}
/**
* If somebody is unlucky enough to have to serialize one of these, serialize
* it as a BigDecimal so that they won't need Gson on the other side to
* deserialize it.
*/
private Object writeReplace() throws ObjectStreamException {
return new BigDecimal(value);
}
}
}

View File

@@ -0,0 +1,69 @@
/*
* Copyright (C) 2016 Gson Type Adapter Authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* Imported from https://github.com/google-gson/typeadapters/tree/master/jsr310/src
* and repackaged to avoid the default package.
*/
package org.openhab.binding.lametrictime.api.common.impl.typeadapters.imported;
import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;
import java.io.IOException;
import java.time.temporal.TemporalAccessor;
import java.util.Objects;
import java.util.function.Function;
/**
* Abstract type adapter for jsr310 date-time types.
*
* @author Christophe Bornet
*/
abstract class TemporalTypeAdapter<T> extends TypeAdapter<T> {
Function<String, T> parseFunction;
TemporalTypeAdapter(Function<String, T> parseFunction) {
Objects.requireNonNull(parseFunction);
this.parseFunction = parseFunction;
}
@Override
public void write(JsonWriter out, T value) throws IOException {
if (value == null) {
out.nullValue();
} else {
out.value(value.toString());
}
}
@Override
public T read(JsonReader in) throws IOException {
if (in.peek() == JsonToken.NULL) {
in.nextNull();
return null;
}
String temporalString = preProcess(in.nextString());
return parseFunction.apply(temporalString);
}
public String preProcess(String in) {
return in;
}
}

View File

@@ -0,0 +1,35 @@
/*
* Copyright (C) 2016 Gson Type Adapter Authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* Imported from https://github.com/google-gson/typeadapters/tree/master/jsr310/src
* and repackaged to avoid the default package.
*/
package org.openhab.binding.lametrictime.api.common.impl.typeadapters.imported;
import java.time.YearMonth;
/**
* Type adapter for jsr310 {@link YearMonth} class.
*
* @author Christophe Bornet
*/
public class YearMonthTypeAdapter extends TemporalTypeAdapter<YearMonth> {
public YearMonthTypeAdapter() {
super(YearMonth::parse);
}
}

View File

@@ -0,0 +1,35 @@
/*
* Copyright (C) 2016 Gson Type Adapter Authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* Imported from https://github.com/google-gson/typeadapters/tree/master/jsr310/src
* and repackaged to avoid the default package.
*/
package org.openhab.binding.lametrictime.api.common.impl.typeadapters.imported;
import java.time.Year;
/**
* Type adapter for jsr310 {@link Year} class.
*
* @author Christophe Bornet
*/
public class YearTypeAdapter extends TemporalTypeAdapter<Year> {
public YearTypeAdapter() {
super(Year::parse);
}
}

View File

@@ -0,0 +1,36 @@
/*
* Copyright (C) 2016 Gson Type Adapter Authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* Imported from https://github.com/google-gson/typeadapters/tree/master/jsr310/src
* and repackaged to avoid the default package.
*/
package org.openhab.binding.lametrictime.api.common.impl.typeadapters.imported;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
/**
* Type adapter for jsr310 {@link ZonedDateTime} class.
*
* @author Christophe Bornet
*/
public class ZonedDateTimeTypeAdapter extends DateTimeTypeAdapter<ZonedDateTime> {
public ZonedDateTimeTypeAdapter() {
super(ZonedDateTime::parse);
}
}

View File

@@ -0,0 +1,355 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 2011-2015 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* http://glassfish.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package org.openhab.binding.lametrictime.api.filter;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;
import java.nio.charset.Charset;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.concurrent.atomic.AtomicLong;
import java.util.logging.Logger;
import javax.annotation.Priority;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.client.ClientRequestContext;
import javax.ws.rs.client.ClientRequestFilter;
import javax.ws.rs.client.ClientResponseContext;
import javax.ws.rs.client.ClientResponseFilter;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.container.ContainerResponseContext;
import javax.ws.rs.container.ContainerResponseFilter;
import javax.ws.rs.container.PreMatching;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.ext.WriterInterceptor;
import javax.ws.rs.ext.WriterInterceptorContext;
/**
* Universal logging filter.
* <p/>
* Can be used on client or server side. Has the highest priority.
*
* @author Pavel Bucek (pavel.bucek at oracle.com)
* @author Martin Matula
*/
@PreMatching
@Priority(Integer.MIN_VALUE)
public final class LoggingFilter implements ContainerRequestFilter, ClientRequestFilter, ContainerResponseFilter,
ClientResponseFilter, WriterInterceptor {
public static final Charset UTF8 = Charset.forName("UTF-8");
private static final Logger LOGGER = Logger.getLogger(LoggingFilter.class.getName());
private static final String NOTIFICATION_PREFIX = "* ";
private static final String REQUEST_PREFIX = "> ";
private static final String RESPONSE_PREFIX = "< ";
private static final String ENTITY_LOGGER_PROPERTY = LoggingFilter.class.getName() + ".entityLogger";
private static final String LOGGING_ID_PROPERTY = LoggingFilter.class.getName() + ".id";
private static final Comparator<Map.Entry<String, List<String>>> COMPARATOR = new Comparator<Map.Entry<String, List<String>>>() {
@Override
public int compare(final Map.Entry<String, List<String>> o1, final Map.Entry<String, List<String>> o2) {
return o1.getKey().compareToIgnoreCase(o2.getKey());
}
};
private static final int DEFAULT_MAX_ENTITY_SIZE = 8 * 1024;
//
private final Logger logger;
private final AtomicLong _id = new AtomicLong(0);
private final boolean printEntity;
private final int maxEntitySize;
/**
* Create a logging filter logging the request and response to a default JDK
* logger, named as the fully qualified class name of this class. Entity
* logging is turned off by default.
*/
public LoggingFilter() {
this(LOGGER, false);
}
/**
* Create a logging filter with custom logger and custom settings of entity
* logging.
*
* @param logger the logger to log requests and responses.
* @param printEntity if true, entity will be logged as well up to the default maxEntitySize, which is 8KB
*/
public LoggingFilter(final Logger logger, final boolean printEntity) {
this.logger = logger;
this.printEntity = printEntity;
this.maxEntitySize = DEFAULT_MAX_ENTITY_SIZE;
}
/**
* Creates a logging filter with custom logger and entity logging turned on, but potentially limiting the size
* of entity to be buffered and logged.
*
* @param logger the logger to log requests and responses.
* @param maxEntitySize maximum number of entity bytes to be logged (and buffered) - if the entity is larger,
* logging filter will print (and buffer in memory) only the specified number of bytes
* and print "...more..." string at the end. Negative values are interpreted as zero.
*/
public LoggingFilter(final Logger logger, final int maxEntitySize) {
this.logger = logger;
this.printEntity = true;
this.maxEntitySize = Math.max(0, maxEntitySize);
}
private void log(final StringBuilder b) {
if (logger != null) {
logger.info(b.toString());
}
}
private StringBuilder prefixId(final StringBuilder b, final long id) {
b.append(Long.toString(id)).append(" ");
return b;
}
private void printRequestLine(final StringBuilder b, final String note, final long id, final String method,
final URI uri) {
prefixId(b, id).append(NOTIFICATION_PREFIX).append(note).append(" on thread ")
.append(Thread.currentThread().getName()).append("\n");
prefixId(b, id).append(REQUEST_PREFIX).append(method).append(" ").append(uri.toASCIIString()).append("\n");
}
private void printResponseLine(final StringBuilder b, final String note, final long id, final int status) {
prefixId(b, id).append(NOTIFICATION_PREFIX).append(note).append(" on thread ")
.append(Thread.currentThread().getName()).append("\n");
prefixId(b, id).append(RESPONSE_PREFIX).append(Integer.toString(status)).append("\n");
}
private void printPrefixedHeaders(final StringBuilder b, final long id, final String prefix,
final MultivaluedMap<String, String> headers) {
for (final Map.Entry<String, List<String>> headerEntry : getSortedHeaders(headers.entrySet())) {
final List<?> val = headerEntry.getValue();
final String header = headerEntry.getKey();
if (val.size() == 1) {
prefixId(b, id).append(prefix).append(header).append(": ").append(val.get(0)).append("\n");
} else {
final StringBuilder sb = new StringBuilder();
boolean add = false;
for (final Object s : val) {
if (add) {
sb.append(',');
}
add = true;
sb.append(s);
}
prefixId(b, id).append(prefix).append(header).append(": ").append(sb.toString()).append("\n");
}
}
}
private Set<Map.Entry<String, List<String>>> getSortedHeaders(final Set<Map.Entry<String, List<String>>> headers) {
final TreeSet<Map.Entry<String, List<String>>> sortedHeaders = new TreeSet<Map.Entry<String, List<String>>>(
COMPARATOR);
sortedHeaders.addAll(headers);
return sortedHeaders;
}
private InputStream logInboundEntity(final StringBuilder b, InputStream stream, final Charset charset)
throws IOException {
if (!stream.markSupported()) {
stream = new BufferedInputStream(stream);
}
stream.mark(maxEntitySize + 1);
final byte[] entity = new byte[maxEntitySize + 1];
final int entitySize = stream.read(entity);
b.append(new String(entity, 0, Math.min(entitySize, maxEntitySize), charset));
if (entitySize > maxEntitySize) {
b.append("...more...");
}
b.append('\n');
stream.reset();
return stream;
}
@Override
public void filter(final ClientRequestContext context) throws IOException {
final long id = _id.incrementAndGet();
context.setProperty(LOGGING_ID_PROPERTY, id);
final StringBuilder b = new StringBuilder();
printRequestLine(b, "Sending client request", id, context.getMethod(), context.getUri());
printPrefixedHeaders(b, id, REQUEST_PREFIX, context.getStringHeaders());
if (printEntity && context.hasEntity()) {
final OutputStream stream = new LoggingStream(b, context.getEntityStream());
context.setEntityStream(stream);
context.setProperty(ENTITY_LOGGER_PROPERTY, stream);
// not calling log(b) here - it will be called by the interceptor
} else {
log(b);
}
}
@Override
public void filter(final ClientRequestContext requestContext, final ClientResponseContext responseContext)
throws IOException {
final Object requestId = requestContext.getProperty(LOGGING_ID_PROPERTY);
final long id = requestId != null ? (Long) requestId : _id.incrementAndGet();
final StringBuilder b = new StringBuilder();
printResponseLine(b, "Client response received", id, responseContext.getStatus());
printPrefixedHeaders(b, id, RESPONSE_PREFIX, responseContext.getHeaders());
if (printEntity && responseContext.hasEntity()) {
responseContext.setEntityStream(
logInboundEntity(b, responseContext.getEntityStream(), getCharset(responseContext.getMediaType())));
}
log(b);
}
@Override
public void filter(final ContainerRequestContext context) throws IOException {
final long id = _id.incrementAndGet();
context.setProperty(LOGGING_ID_PROPERTY, id);
final StringBuilder b = new StringBuilder();
printRequestLine(b, "Server has received a request", id, context.getMethod(),
context.getUriInfo().getRequestUri());
printPrefixedHeaders(b, id, REQUEST_PREFIX, context.getHeaders());
if (printEntity && context.hasEntity()) {
context.setEntityStream(logInboundEntity(b, context.getEntityStream(), getCharset(context.getMediaType())));
}
log(b);
}
@Override
public void filter(final ContainerRequestContext requestContext, final ContainerResponseContext responseContext)
throws IOException {
final Object requestId = requestContext.getProperty(LOGGING_ID_PROPERTY);
final long id = requestId != null ? (Long) requestId : _id.incrementAndGet();
final StringBuilder b = new StringBuilder();
printResponseLine(b, "Server responded with a response", id, responseContext.getStatus());
printPrefixedHeaders(b, id, RESPONSE_PREFIX, responseContext.getStringHeaders());
if (printEntity && responseContext.hasEntity()) {
final OutputStream stream = new LoggingStream(b, responseContext.getEntityStream());
responseContext.setEntityStream(stream);
requestContext.setProperty(ENTITY_LOGGER_PROPERTY, stream);
// not calling log(b) here - it will be called by the interceptor
} else {
log(b);
}
}
@Override
public void aroundWriteTo(final WriterInterceptorContext writerInterceptorContext)
throws IOException, WebApplicationException {
final LoggingStream stream = (LoggingStream) writerInterceptorContext.getProperty(ENTITY_LOGGER_PROPERTY);
writerInterceptorContext.proceed();
if (stream != null) {
log(stream.getStringBuilder(getCharset(writerInterceptorContext.getMediaType())));
}
}
private class LoggingStream extends FilterOutputStream {
private final StringBuilder b;
private final ByteArrayOutputStream baos = new ByteArrayOutputStream();
LoggingStream(final StringBuilder b, final OutputStream inner) {
super(inner);
this.b = b;
}
StringBuilder getStringBuilder(final Charset charset) {
// write entity to the builder
final byte[] entity = baos.toByteArray();
b.append(new String(entity, 0, Math.min(entity.length, maxEntitySize), charset));
if (entity.length > maxEntitySize) {
b.append("...more...");
}
b.append('\n');
return b;
}
@Override
public void write(final int i) throws IOException {
if (baos.size() <= maxEntitySize) {
baos.write(i);
}
out.write(i);
}
}
/**
* Get the character set from a media type.
* <p>
* The character set is obtained from the media type parameter "charset".
* If the parameter is not present the {@link #UTF8} charset is utilized.
*
* @param m the media type.
* @return the character set.
*/
public static Charset getCharset(MediaType m) {
String name = (m == null) ? null : m.getParameters().get(MediaType.CHARSET_PARAMETER);
return (name == null) ? UTF8 : Charset.forName(name);
}
}

View File

@@ -0,0 +1,76 @@
/**
* Copyright 2017-2018 Gregory Moyer and contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openhab.binding.lametrictime.api.impl;
import java.util.Base64;
import org.openhab.binding.lametrictime.api.model.Icon;
public abstract class AbstractDataIcon implements Icon
{
private volatile Object CONFIGURE_FLAG;
private String type;
private byte[] data;
protected void configure()
{
if (CONFIGURE_FLAG == null)
{
synchronized (this)
{
if (CONFIGURE_FLAG == null)
{
populateFields();
}
}
}
}
protected String getType()
{
configure();
return type;
}
protected void setType(String type)
{
this.type = type;
}
protected byte[] getData()
{
configure();
return data;
}
protected void setData(byte[] data)
{
this.data = data;
}
@Override
public String toRaw()
{
return new StringBuilder().append("data:")
.append(getType())
.append(";base64,")
.append(Base64.getEncoder().encodeToString(getData()))
.toString();
}
protected abstract void populateFields();
}

View File

@@ -0,0 +1,37 @@
/**
* Copyright 2017-2018 Gregory Moyer and contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openhab.binding.lametrictime.api.impl;
public class DataIcon extends AbstractDataIcon
{
public DataIcon(String mimeType, byte[] data)
{
setType(mimeType);
setData(data);
}
@Override
protected void configure()
{
// noop
}
@Override
protected void populateFields()
{
// noop
}
}

View File

@@ -0,0 +1,55 @@
/**
* Copyright 2017-2018 Gregory Moyer and contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openhab.binding.lametrictime.api.impl;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import javax.activation.MimetypesFileTypeMap;
public class FileIcon extends AbstractDataIcon
{
private final MimetypesFileTypeMap mimeTypeMap = new MimetypesFileTypeMap();
private final Path path;
public FileIcon(File file)
{
this(file.toPath());
}
public FileIcon(Path path)
{
this.path = path;
mimeTypeMap.addMimeTypes("image/png png PNG");
}
@Override
protected void populateFields()
{
setType(mimeTypeMap.getContentType(path.toFile()));
try
{
setData(Files.readAllBytes(path));
}
catch (IOException e)
{
throw new RuntimeException(e);
}
}
}

View File

@@ -0,0 +1,47 @@
/**
* Copyright 2017-2018 Gregory Moyer and contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openhab.binding.lametrictime.api.impl;
import java.net.URI;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.core.Response;
public class HTTPIcon extends AbstractDataIcon
{
private final URI uri;
public HTTPIcon(String uri)
{
this(URI.create(uri));
}
public HTTPIcon(URI uri)
{
this.uri = uri;
}
@Override
protected void populateFields()
{
Client client = ClientBuilder.newBuilder().build();
Response response = client.target(uri).request().get();
setType(response.getMediaType().toString());
setData(response.readEntity(byte[].class));
}
}

View File

@@ -0,0 +1,34 @@
/**
* Copyright 2017-2018 Gregory Moyer and contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openhab.binding.lametrictime.api.impl;
import org.openhab.binding.lametrictime.api.model.Icon;
public class KeyIcon implements Icon
{
private final String key;
public KeyIcon(String key)
{
this.key = key;
}
@Override
public String toRaw()
{
return key;
}
}

View File

@@ -0,0 +1,334 @@
/**
* Copyright 2017-2018 Gregory Moyer and contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openhab.binding.lametrictime.api.impl;
import static org.openhab.binding.lametrictime.api.model.ApiValue.raw;
import java.util.Arrays;
import javax.ws.rs.client.ClientBuilder;
import org.openhab.binding.lametrictime.api.Configuration;
import org.openhab.binding.lametrictime.api.LaMetricTime;
import org.openhab.binding.lametrictime.api.cloud.CloudConfiguration;
import org.openhab.binding.lametrictime.api.cloud.LaMetricTimeCloud;
import org.openhab.binding.lametrictime.api.local.ApplicationActionException;
import org.openhab.binding.lametrictime.api.local.ApplicationActivationException;
import org.openhab.binding.lametrictime.api.local.ApplicationNotFoundException;
import org.openhab.binding.lametrictime.api.local.LaMetricTimeLocal;
import org.openhab.binding.lametrictime.api.local.LocalConfiguration;
import org.openhab.binding.lametrictime.api.local.NotificationCreationException;
import org.openhab.binding.lametrictime.api.local.UpdateException;
import org.openhab.binding.lametrictime.api.local.model.Application;
import org.openhab.binding.lametrictime.api.local.model.Audio;
import org.openhab.binding.lametrictime.api.local.model.Bluetooth;
import org.openhab.binding.lametrictime.api.local.model.Display;
import org.openhab.binding.lametrictime.api.local.model.Frame;
import org.openhab.binding.lametrictime.api.local.model.Notification;
import org.openhab.binding.lametrictime.api.local.model.NotificationModel;
import org.openhab.binding.lametrictime.api.local.model.UpdateAction;
import org.openhab.binding.lametrictime.api.local.model.Widget;
import org.openhab.binding.lametrictime.api.model.CoreAction;
import org.openhab.binding.lametrictime.api.model.CoreApplication;
import org.openhab.binding.lametrictime.api.model.CoreApps;
import org.openhab.binding.lametrictime.api.model.Icon;
import org.openhab.binding.lametrictime.api.model.Icons;
import org.openhab.binding.lametrictime.api.model.enums.BrightnessMode;
import org.openhab.binding.lametrictime.api.model.enums.Priority;
import org.openhab.binding.lametrictime.api.model.enums.Sound;
public class LaMetricTimeImpl implements LaMetricTime
{
private final LaMetricTimeLocal local;
private final LaMetricTimeCloud cloud;
private final Object muteLock = new Object();
private Integer volumeSaveState;
public LaMetricTimeImpl(Configuration config)
{
this(config.getLocalConfig(), config.getCloudConfig());
}
public LaMetricTimeImpl(Configuration config, ClientBuilder clientBuilder)
{
this(config.getLocalConfig(), config.getCloudConfig(), clientBuilder);
}
public LaMetricTimeImpl(LocalConfiguration localConfig, CloudConfiguration cloudConfig)
{
this.local = LaMetricTimeLocal.create(localConfig);
this.cloud = LaMetricTimeCloud.create(cloudConfig);
}
public LaMetricTimeImpl(LocalConfiguration localConfig,
CloudConfiguration cloudConfig,
ClientBuilder clientBuilder)
{
this.local = LaMetricTimeLocal.create(localConfig, clientBuilder);
this.cloud = LaMetricTimeCloud.create(cloudConfig, clientBuilder);
}
@Override
public String getVersion()
{
return local.getApi().getApiVersion();
}
@Override
public String notifyInfo(String message) throws NotificationCreationException
{
return notify(message, Priority.INFO, Icons.key("i1248"), Sound.NOTIFICATION, 1, 1);
}
@Override
public String notifyWarning(String message) throws NotificationCreationException
{
return notify(message, Priority.WARNING, Icons.key("a2098"), Sound.NOTIFICATION2, 2, 2);
}
@Override
public String notifyCritical(String message) throws NotificationCreationException
{
return notify(message, Priority.CRITICAL, Icons.key("a4787"), Sound.ALARM1, 0, 0);
}
@Override
public String notify(String message,
Priority priority,
Icon icon,
Sound sound,
int messageRepeat,
int soundRepeat) throws NotificationCreationException
{
// @formatter:off
NotificationModel model = new NotificationModel()
.withCycles(messageRepeat)
.withFrames(Arrays.asList(new Frame().withText(message)
.withIcon(raw(icon))));
if (sound != null)
{
model.setSound(new org.openhab.binding.lametrictime.api.local.model.Sound()
.withCategory(raw(sound.getCategory()))
.withId(raw(sound))
.withRepeat(soundRepeat));
}
// @formatter:on
Notification notification = new Notification().withPriority(raw(priority)).withModel(model);
return local.createNotification(notification);
}
@Override
public Application getClock()
{
return getApplication(CoreApps.clock());
}
@Override
public Application getCountdown()
{
return getApplication(CoreApps.countdown());
}
@Override
public Application getRadio()
{
return getApplication(CoreApps.radio());
}
@Override
public Application getStopwatch()
{
return getApplication(CoreApps.stopwatch());
}
@Override
public Application getWeather()
{
return getApplication(CoreApps.weather());
}
@Override
public Application getApplication(CoreApplication coreApp)
{
try
{
return getLocalApi().getApplication(coreApp.getPackageName());
}
catch (ApplicationNotFoundException e)
{
// core apps should never throw errors
throw new RuntimeException("Failed to retrieve core application: "
+ coreApp.getPackageName(),
e);
}
}
@Override
public Application getApplication(String name) throws ApplicationNotFoundException
{
return getLocalApi().getApplication(name);
}
@Override
public void activateApplication(CoreApplication coreApp)
{
try
{
activateApplication(getApplication(coreApp));
}
catch (ApplicationActivationException e)
{
// core apps should never throw errors
throw new RuntimeException("Failed to activate core application: "
+ coreApp.getPackageName(),
e);
}
}
@Override
public void activateApplication(Application app) throws ApplicationActivationException
{
getLocalApi().activateApplication(app.getPackageName(), getFirstWidgetId(app));
}
@Override
public void activateWidget(Widget widget) throws ApplicationActivationException
{
getLocalApi().activateApplication(widget.getPackageName(), widget.getId());
}
@Override
public void doAction(CoreAction coreAction)
{
try
{
doAction(getApplication(coreAction.getApp()), coreAction.getAction());
}
catch (ApplicationActionException e)
{
// core apps should never throw errors
throw new RuntimeException("Failed to execute weather forecast action", e);
}
}
@Override
public void doAction(Application app, UpdateAction action) throws ApplicationActionException
{
getLocalApi().doAction(app.getPackageName(), getFirstWidgetId(app), action);
}
@Override
public void doAction(Widget widget, CoreAction coreAction) throws ApplicationActionException
{
doAction(widget, coreAction.getAction());
}
@Override
public void doAction(Widget widget, UpdateAction action) throws ApplicationActionException
{
getLocalApi().doAction(widget.getPackageName(), widget.getId(), action);
}
protected String getFirstWidgetId(Application app)
{
return app.getWidgets().firstKey();
}
@Override
public Display setBrightness(int brightness) throws UpdateException
{
return local.updateDisplay(new Display().withBrightness(brightness)
.withBrightnessMode(raw(BrightnessMode.MANUAL)));
}
@Override
public Display setBrightnessMode(BrightnessMode mode) throws UpdateException
{
return local.updateDisplay(new Display().withBrightnessMode(raw(mode)));
}
@Override
public Audio setVolume(int volume) throws UpdateException
{
return local.updateAudio(new Audio().withVolume(volume));
}
@Override
public Audio mute() throws UpdateException
{
synchronized (muteLock)
{
Audio audio = local.getAudio();
if (audio.getVolume() == 0)
{
return audio;
}
volumeSaveState = audio.getVolume();
return setVolume(0);
}
}
@Override
public Audio unmute() throws UpdateException
{
synchronized (muteLock)
{
if (volumeSaveState == null)
{
Audio audio = local.getAudio();
if (audio.getVolume() == 0)
{
return setVolume(50);
}
else
{
return audio;
}
}
Audio audio = setVolume(volumeSaveState);
volumeSaveState = null;
return audio;
}
}
@Override
public Bluetooth setBluetoothActive(boolean active) throws UpdateException
{
return local.updateBluetooth(new Bluetooth().withActive(active));
}
@Override
public Bluetooth setBluetoothName(String name) throws UpdateException
{
return local.updateBluetooth(new Bluetooth().withName(name));
}
@Override
public LaMetricTimeLocal getLocalApi()
{
return local;
}
@Override
public LaMetricTimeCloud getCloudApi()
{
return cloud;
}
}

View File

@@ -0,0 +1,56 @@
/**
* Copyright 2017-2018 Gregory Moyer and contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openhab.binding.lametrictime.api.local;
import org.openhab.binding.lametrictime.api.local.model.Failure;
public class ApplicationActionException extends LaMetricTimeException
{
private static final long serialVersionUID = 1L;
public ApplicationActionException()
{
super();
}
public ApplicationActionException(String message)
{
super(message);
}
public ApplicationActionException(Throwable cause)
{
super(cause);
}
public ApplicationActionException(String message, Throwable cause)
{
super(message, cause);
}
public ApplicationActionException(String message,
Throwable cause,
boolean enableSuppression,
boolean writableStackTrace)
{
super(message, cause, enableSuppression, writableStackTrace);
}
public ApplicationActionException(Failure failure)
{
super(failure);
}
}

View File

@@ -0,0 +1,56 @@
/**
* Copyright 2017-2018 Gregory Moyer and contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openhab.binding.lametrictime.api.local;
import org.openhab.binding.lametrictime.api.local.model.Failure;
public class ApplicationActivationException extends LaMetricTimeException
{
private static final long serialVersionUID = 1L;
public ApplicationActivationException()
{
super();
}
public ApplicationActivationException(String message)
{
super(message);
}
public ApplicationActivationException(Throwable cause)
{
super(cause);
}
public ApplicationActivationException(String message, Throwable cause)
{
super(message, cause);
}
public ApplicationActivationException(String message,
Throwable cause,
boolean enableSuppression,
boolean writableStackTrace)
{
super(message, cause, enableSuppression, writableStackTrace);
}
public ApplicationActivationException(Failure failure)
{
super(failure);
}
}

View File

@@ -0,0 +1,56 @@
/**
* Copyright 2017-2018 Gregory Moyer and contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openhab.binding.lametrictime.api.local;
import org.openhab.binding.lametrictime.api.local.model.Failure;
public class ApplicationNotFoundException extends LaMetricTimeException
{
private static final long serialVersionUID = 1L;
public ApplicationNotFoundException()
{
super();
}
public ApplicationNotFoundException(String message)
{
super(message);
}
public ApplicationNotFoundException(Throwable cause)
{
super(cause);
}
public ApplicationNotFoundException(String message, Throwable cause)
{
super(message, cause);
}
public ApplicationNotFoundException(String message,
Throwable cause,
boolean enableSuppression,
boolean writableStackTrace)
{
super(message, cause, enableSuppression, writableStackTrace);
}
public ApplicationNotFoundException(Failure failure)
{
super(failure);
}
}

View File

@@ -0,0 +1,77 @@
/**
* Copyright 2017-2018 Gregory Moyer and contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openhab.binding.lametrictime.api.local;
import java.util.List;
import org.openhab.binding.lametrictime.api.local.model.Error;
import org.openhab.binding.lametrictime.api.local.model.Failure;
public class LaMetricTimeException extends Exception
{
private static final long serialVersionUID = 1L;
public LaMetricTimeException()
{
super();
}
public LaMetricTimeException(String message)
{
super(message);
}
public LaMetricTimeException(Throwable cause)
{
super(cause);
}
public LaMetricTimeException(String message, Throwable cause)
{
super(message, cause);
}
public LaMetricTimeException(String message,
Throwable cause,
boolean enableSuppression,
boolean writableStackTrace)
{
super(message, cause, enableSuppression, writableStackTrace);
}
public LaMetricTimeException(Failure failure)
{
super(buildMessage(failure));
}
private static String buildMessage(Failure failure)
{
StringBuilder builder = new StringBuilder();
List<Error> errors = failure.getErrors();
if (!errors.isEmpty())
{
builder.append(errors.get(0).getMessage());
}
for (int i = 1; i < errors.size(); i++)
{
builder.append("; ").append(errors.get(i).getMessage());
}
return builder.toString();
}
}

View File

@@ -0,0 +1,93 @@
/**
* Copyright 2017-2018 Gregory Moyer and contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openhab.binding.lametrictime.api.local;
import java.util.List;
import java.util.SortedMap;
import javax.ws.rs.client.ClientBuilder;
import org.openhab.binding.lametrictime.api.local.impl.LaMetricTimeLocalImpl;
import org.openhab.binding.lametrictime.api.local.model.Api;
import org.openhab.binding.lametrictime.api.local.model.Application;
import org.openhab.binding.lametrictime.api.local.model.Audio;
import org.openhab.binding.lametrictime.api.local.model.Bluetooth;
import org.openhab.binding.lametrictime.api.local.model.Device;
import org.openhab.binding.lametrictime.api.local.model.Display;
import org.openhab.binding.lametrictime.api.local.model.Notification;
import org.openhab.binding.lametrictime.api.local.model.UpdateAction;
import org.openhab.binding.lametrictime.api.local.model.WidgetUpdates;
import org.openhab.binding.lametrictime.api.local.model.Wifi;
public interface LaMetricTimeLocal
{
public Api getApi();
public Device getDevice();
public String createNotification(Notification notification) throws NotificationCreationException;
public List<Notification> getNotifications();
public Notification getCurrentNotification();
public Notification getNotification(String id) throws NotificationNotFoundException;
public void deleteNotification(String id) throws NotificationNotFoundException;
public Display getDisplay();
public Display updateDisplay(Display display) throws UpdateException;
public Audio getAudio();
public Audio updateAudio(Audio audio) throws UpdateException;
public Bluetooth getBluetooth();
public Bluetooth updateBluetooth(Bluetooth bluetooth) throws UpdateException;
public Wifi getWifi();
public void updateApplication(String packageName,
String accessToken,
WidgetUpdates widgetUpdates) throws UpdateException;
public SortedMap<String, Application> getApplications();
public Application getApplication(String packageName) throws ApplicationNotFoundException;
public void activatePreviousApplication();
public void activateNextApplication();
public void activateApplication(String packageName,
String widgetId) throws ApplicationActivationException;
public void doAction(String packageName,
String widgetId,
UpdateAction action) throws ApplicationActionException;
public static LaMetricTimeLocal create(LocalConfiguration config)
{
return new LaMetricTimeLocalImpl(config);
}
public static LaMetricTimeLocal create(LocalConfiguration config, ClientBuilder clientBuilder)
{
return new LaMetricTimeLocalImpl(config, clientBuilder);
}
}

View File

@@ -0,0 +1,281 @@
/**
* Copyright 2017-2018 Gregory Moyer and contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openhab.binding.lametrictime.api.local;
import java.net.URI;
import java.net.URISyntaxException;
public class LocalConfiguration
{
private String host;
private String apiKey;
private boolean secure = true;
private boolean ignoreCertificateValidation = true;
private boolean ignoreHostnameValidation = true;
private String insecureScheme = "http";
private int insecurePort = 8080;
private String secureScheme = "https";
private int securePort = 4343;
private String basePath = "/api/v2";
private String authUser = "dev";
private boolean logging = false;
private String logLevel = "INFO";
private int logMax = 104857600; // 100kb
public String getHost()
{
return host;
}
public void setHost(String host)
{
this.host = host;
}
public LocalConfiguration withHost(String host)
{
this.host = host;
return this;
}
public String getApiKey()
{
return apiKey;
}
public void setApiKey(String apiKey)
{
this.apiKey = apiKey;
}
public LocalConfiguration withApiKey(String apiKey)
{
this.apiKey = apiKey;
return this;
}
public boolean isSecure()
{
return secure;
}
public void setSecure(boolean secure)
{
this.secure = secure;
}
public LocalConfiguration withSecure(boolean secure)
{
this.secure = secure;
return this;
}
public boolean isIgnoreCertificateValidation()
{
return ignoreCertificateValidation;
}
public void setIgnoreCertificateValidation(boolean ignoreCertificateValidation)
{
this.ignoreCertificateValidation = ignoreCertificateValidation;
}
public LocalConfiguration withIgnoreCertificateValidation(boolean ignoreCertificateValidation)
{
this.ignoreCertificateValidation = ignoreCertificateValidation;
return this;
}
public boolean isIgnoreHostnameValidation()
{
return ignoreHostnameValidation;
}
public void setIgnoreHostnameValidation(boolean ignoreHostnameValidation)
{
this.ignoreHostnameValidation = ignoreHostnameValidation;
}
public LocalConfiguration withIgnoreHostnameValidation(boolean ignoreHostnameValidation)
{
this.ignoreHostnameValidation = ignoreHostnameValidation;
return this;
}
public String getInsecureScheme()
{
return insecureScheme;
}
public void setInsecureScheme(String insecureScheme)
{
this.insecureScheme = insecureScheme;
}
public LocalConfiguration withInsecureScheme(String insecureScheme)
{
this.insecureScheme = insecureScheme;
return this;
}
public int getInsecurePort()
{
return insecurePort;
}
public void setInsecurePort(int insecurePort)
{
this.insecurePort = insecurePort;
}
public LocalConfiguration withInsecurePort(int insecurePort)
{
this.insecurePort = insecurePort;
return this;
}
public String getSecureScheme()
{
return secureScheme;
}
public void setSecureScheme(String secureScheme)
{
this.secureScheme = secureScheme;
}
public LocalConfiguration withSecureScheme(String secureScheme)
{
this.secureScheme = secureScheme;
return this;
}
public int getSecurePort()
{
return securePort;
}
public void setSecurePort(int securePort)
{
this.securePort = securePort;
}
public LocalConfiguration withSecurePort(int securePort)
{
this.securePort = securePort;
return this;
}
public String getBasePath()
{
return basePath;
}
public void setBasePath(String basePath)
{
this.basePath = basePath;
}
public LocalConfiguration withBasePath(String basePath)
{
this.basePath = basePath;
return this;
}
public String getAuthUser()
{
return authUser;
}
public void setAuthUser(String authUser)
{
this.authUser = authUser;
}
public LocalConfiguration withAuthUser(String authUser)
{
this.authUser = authUser;
return this;
}
public boolean isLogging()
{
return logging;
}
public void setLogging(boolean logging)
{
this.logging = logging;
}
public LocalConfiguration withLogging(boolean logging)
{
this.logging = logging;
return this;
}
public String getLogLevel()
{
return logLevel;
}
public void setLogLevel(String logLevel)
{
this.logLevel = logLevel;
}
public LocalConfiguration withLogLevel(String logLevel)
{
this.logLevel = logLevel;
return this;
}
public int getLogMax()
{
return logMax;
}
public void setLogMax(int logMax)
{
this.logMax = logMax;
}
public LocalConfiguration withLogMax(int logMax)
{
this.logMax = logMax;
return this;
}
public URI getBaseUri()
{
String scheme = secure ? secureScheme : insecureScheme;
int port = secure ? securePort : insecurePort;
try
{
return new URI(scheme, null, host, port, basePath, null, null);
}
catch (URISyntaxException e)
{
throw new RuntimeException("Invalid configuration", e);
}
}
}

View File

@@ -0,0 +1,56 @@
/**
* Copyright 2017-2018 Gregory Moyer and contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openhab.binding.lametrictime.api.local;
import org.openhab.binding.lametrictime.api.local.model.Failure;
public class NotificationCreationException extends LaMetricTimeException
{
private static final long serialVersionUID = 1L;
public NotificationCreationException()
{
super();
}
public NotificationCreationException(String message)
{
super(message);
}
public NotificationCreationException(Throwable cause)
{
super(cause);
}
public NotificationCreationException(String message, Throwable cause)
{
super(message, cause);
}
public NotificationCreationException(String message,
Throwable cause,
boolean enableSuppression,
boolean writableStackTrace)
{
super(message, cause, enableSuppression, writableStackTrace);
}
public NotificationCreationException(Failure failure)
{
super(failure);
}
}

View File

@@ -0,0 +1,56 @@
/**
* Copyright 2017-2018 Gregory Moyer and contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openhab.binding.lametrictime.api.local;
import org.openhab.binding.lametrictime.api.local.model.Failure;
public class NotificationNotFoundException extends LaMetricTimeException
{
private static final long serialVersionUID = 1L;
public NotificationNotFoundException()
{
super();
}
public NotificationNotFoundException(String message,
Throwable cause,
boolean enableSuppression,
boolean writableStackTrace)
{
super(message, cause, enableSuppression, writableStackTrace);
}
public NotificationNotFoundException(String message, Throwable cause)
{
super(message, cause);
}
public NotificationNotFoundException(String message)
{
super(message);
}
public NotificationNotFoundException(Throwable cause)
{
super(cause);
}
public NotificationNotFoundException(Failure failure)
{
super(failure);
}
}

View File

@@ -0,0 +1,56 @@
/**
* Copyright 2017-2018 Gregory Moyer and contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openhab.binding.lametrictime.api.local;
import org.openhab.binding.lametrictime.api.local.model.Failure;
public class UpdateException extends LaMetricTimeException
{
private static final long serialVersionUID = 1L;
public UpdateException()
{
super();
}
public UpdateException(String message)
{
super(message);
}
public UpdateException(Throwable cause)
{
super(cause);
}
public UpdateException(String message, Throwable cause)
{
super(message, cause);
}
public UpdateException(String message,
Throwable cause,
boolean enableSuppression,
boolean writableStackTrace)
{
super(message, cause, enableSuppression, writableStackTrace);
}
public UpdateException(Failure failure)
{
super(failure);
}
}

View File

@@ -0,0 +1,392 @@
/**
* Copyright 2017-2018 Gregory Moyer and contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openhab.binding.lametrictime.api.local.impl;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.nio.charset.StandardCharsets;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.List;
import java.util.SortedMap;
import java.util.logging.Logger;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import org.openhab.binding.lametrictime.api.authentication.HttpAuthenticationFeature;
import org.openhab.binding.lametrictime.api.cloud.impl.LaMetricTimeCloudImpl;
import org.openhab.binding.lametrictime.api.common.impl.AbstractClient;
import org.openhab.binding.lametrictime.api.filter.LoggingFilter;
import org.openhab.binding.lametrictime.api.local.ApplicationActionException;
import org.openhab.binding.lametrictime.api.local.ApplicationActivationException;
import org.openhab.binding.lametrictime.api.local.ApplicationNotFoundException;
import org.openhab.binding.lametrictime.api.local.LaMetricTimeLocal;
import org.openhab.binding.lametrictime.api.local.LocalConfiguration;
import org.openhab.binding.lametrictime.api.local.NotificationCreationException;
import org.openhab.binding.lametrictime.api.local.NotificationNotFoundException;
import org.openhab.binding.lametrictime.api.local.UpdateException;
import org.openhab.binding.lametrictime.api.local.model.Api;
import org.openhab.binding.lametrictime.api.local.model.Application;
import org.openhab.binding.lametrictime.api.local.model.Audio;
import org.openhab.binding.lametrictime.api.local.model.AudioUpdateResult;
import org.openhab.binding.lametrictime.api.local.model.Bluetooth;
import org.openhab.binding.lametrictime.api.local.model.BluetoothUpdateResult;
import org.openhab.binding.lametrictime.api.local.model.Device;
import org.openhab.binding.lametrictime.api.local.model.Display;
import org.openhab.binding.lametrictime.api.local.model.DisplayUpdateResult;
import org.openhab.binding.lametrictime.api.local.model.Failure;
import org.openhab.binding.lametrictime.api.local.model.Notification;
import org.openhab.binding.lametrictime.api.local.model.NotificationResult;
import org.openhab.binding.lametrictime.api.local.model.UpdateAction;
import org.openhab.binding.lametrictime.api.local.model.WidgetUpdates;
import org.openhab.binding.lametrictime.api.local.model.Wifi;
import org.openhab.binding.lametrictime.internal.GsonProvider;
import com.google.gson.reflect.TypeToken;
public class LaMetricTimeLocalImpl extends AbstractClient implements LaMetricTimeLocal {
private static final String HEADER_ACCESS_TOKEN = "X-Access-Token";
private final LocalConfiguration config;
private volatile Api api;
public LaMetricTimeLocalImpl(LocalConfiguration config) {
this.config = config;
}
public LaMetricTimeLocalImpl(LocalConfiguration config, ClientBuilder clientBuilder) {
super(clientBuilder);
this.config = config;
}
@Override
public Api getApi() {
if (api == null) {
synchronized (this) {
if (api == null) {
api = getClient().target(config.getBaseUri()).request(MediaType.APPLICATION_JSON_TYPE)
.get(Api.class);
}
}
}
// remove support for v2.0.0 which has several errors in returned endpoints
if ("2.0.0".equals(api.getApiVersion())) {
throw new IllegalStateException(
"API version 2.0.0 detected, but 2.1.0 or greater is required. Please upgrade LaMetric Time firmware to version 1.7.7 or later. See http://lametric.com/firmware for more information.");
}
return api;
}
@Override
public Device getDevice() {
return getClient().target(getApi().getEndpoints().getDeviceUrl()).request(MediaType.APPLICATION_JSON_TYPE)
.get(Device.class);
}
@Override
public String createNotification(Notification notification) throws NotificationCreationException {
Response response = getClient().target(getApi().getEndpoints().getNotificationsUrl())
.request(MediaType.APPLICATION_JSON_TYPE).post(Entity.json(notification));
if (!Status.Family.SUCCESSFUL.equals(response.getStatusInfo().getFamily())) {
throw new NotificationCreationException(response.readEntity(Failure.class));
}
try {
return response.readEntity(NotificationResult.class).getSuccess().getId();
} catch (Exception e) {
throw new NotificationCreationException("Invalid JSON returned from service", e);
}
}
@Override
public List<Notification> getNotifications() {
Response response = getClient().target(getApi().getEndpoints().getNotificationsUrl())
.request(MediaType.APPLICATION_JSON_TYPE).get();
Reader entity = new BufferedReader(
new InputStreamReader((InputStream) response.getEntity(), StandardCharsets.UTF_8));
// @formatter:off
return getGson().fromJson(entity, new TypeToken<List<Notification>>(){}.getType());
// @formatter:on
}
@Override
public Notification getCurrentNotification() {
Notification notification = getClient().target(getApi().getEndpoints().getCurrentNotificationUrl())
.request(MediaType.APPLICATION_JSON_TYPE).get(Notification.class);
// when there is no current notification, return null
if (notification.getId() == null) {
return null;
}
return notification;
}
@Override
public Notification getNotification(String id) throws NotificationNotFoundException {
Response response = getClient()
.target(getApi().getEndpoints().getConcreteNotificationUrl().replace("{:id}", id))
.request(MediaType.APPLICATION_JSON_TYPE).get();
if (!Status.Family.SUCCESSFUL.equals(response.getStatusInfo().getFamily())) {
throw new NotificationNotFoundException(response.readEntity(Failure.class));
}
return response.readEntity(Notification.class);
}
@Override
public void deleteNotification(String id) throws NotificationNotFoundException {
Response response = getClient()
.target(getApi().getEndpoints().getConcreteNotificationUrl().replace("{:id}", id))
.request(MediaType.APPLICATION_JSON_TYPE).delete();
if (!Status.Family.SUCCESSFUL.equals(response.getStatusInfo().getFamily())) {
throw new NotificationNotFoundException(response.readEntity(Failure.class));
}
response.close();
}
@Override
public Display getDisplay() {
return getClient().target(getApi().getEndpoints().getDisplayUrl()).request(MediaType.APPLICATION_JSON_TYPE)
.get(Display.class);
}
@Override
public Display updateDisplay(Display display) throws UpdateException {
Response response = getClient().target(getApi().getEndpoints().getDisplayUrl())
.request(MediaType.APPLICATION_JSON_TYPE).put(Entity.json(display));
if (!Status.Family.SUCCESSFUL.equals(response.getStatusInfo().getFamily())) {
throw new UpdateException(response.readEntity(Failure.class));
}
return response.readEntity(DisplayUpdateResult.class).getSuccess().getData();
}
@Override
public Audio getAudio() {
return getClient().target(getApi().getEndpoints().getAudioUrl()).request(MediaType.APPLICATION_JSON_TYPE)
.get(Audio.class);
}
@Override
public Audio updateAudio(Audio audio) throws UpdateException {
Response response = getClient().target(getApi().getEndpoints().getAudioUrl())
.request(MediaType.APPLICATION_JSON_TYPE).put(Entity.json(audio));
if (!Status.Family.SUCCESSFUL.equals(response.getStatusInfo().getFamily())) {
throw new UpdateException(response.readEntity(Failure.class));
}
return response.readEntity(AudioUpdateResult.class).getSuccess().getData();
}
@Override
public Bluetooth getBluetooth() {
return getClient().target(getApi().getEndpoints().getBluetoothUrl()).request(MediaType.APPLICATION_JSON_TYPE)
.get(Bluetooth.class);
}
@Override
public Bluetooth updateBluetooth(Bluetooth bluetooth) throws UpdateException {
Response response = getClient().target(getApi().getEndpoints().getBluetoothUrl())
.request(MediaType.APPLICATION_JSON_TYPE).put(Entity.json(bluetooth));
if (!Status.Family.SUCCESSFUL.equals(response.getStatusInfo().getFamily())) {
throw new UpdateException(response.readEntity(Failure.class));
}
return response.readEntity(BluetoothUpdateResult.class).getSuccess().getData();
}
@Override
public Wifi getWifi() {
return getClient().target(getApi().getEndpoints().getWifiUrl()).request(MediaType.APPLICATION_JSON_TYPE)
.get(Wifi.class);
}
@Override
public void updateApplication(String packageName, String accessToken, WidgetUpdates widgetUpdates)
throws UpdateException {
Response response = getClient()
.target(getApi().getEndpoints().getWidgetUpdateUrl().replace("{:id}", packageName))
.request(MediaType.APPLICATION_JSON_TYPE).header(HEADER_ACCESS_TOKEN, accessToken)
.post(Entity.json(widgetUpdates));
if (!Status.Family.SUCCESSFUL.equals(response.getStatusInfo().getFamily())) {
throw new UpdateException(response.readEntity(Failure.class));
}
response.close();
}
@Override
public SortedMap<String, Application> getApplications() {
Response response = getClient().target(getApi().getEndpoints().getAppsListUrl())
.request(MediaType.APPLICATION_JSON_TYPE).get();
Reader entity = new BufferedReader(
new InputStreamReader((InputStream) response.getEntity(), StandardCharsets.UTF_8));
// @formatter:off
return getGson().fromJson(entity,
new TypeToken<SortedMap<String, Application>>(){}.getType());
// @formatter:on
}
@Override
public Application getApplication(String packageName) throws ApplicationNotFoundException {
Response response = getClient().target(getApi().getEndpoints().getAppsGetUrl().replace("{:id}", packageName))
.request(MediaType.APPLICATION_JSON_TYPE).get();
if (!Status.Family.SUCCESSFUL.equals(response.getStatusInfo().getFamily())) {
throw new ApplicationNotFoundException(response.readEntity(Failure.class));
}
return response.readEntity(Application.class);
}
@Override
public void activatePreviousApplication() {
getClient().target(getApi().getEndpoints().getAppsSwitchPrevUrl()).request(MediaType.APPLICATION_JSON_TYPE)
.put(Entity.json(new Object()));
}
@Override
public void activateNextApplication() {
getClient().target(getApi().getEndpoints().getAppsSwitchNextUrl()).request(MediaType.APPLICATION_JSON_TYPE)
.put(Entity.json(new Object()));
}
@Override
public void activateApplication(String packageName, String widgetId) throws ApplicationActivationException {
Response response = getClient().target(getApi().getEndpoints().getAppsSwitchUrl().replace("{:id}", packageName)
.replace("{:widget_id}", widgetId)).request(MediaType.APPLICATION_JSON_TYPE)
.put(Entity.json(new Object()));
if (!Status.Family.SUCCESSFUL.equals(response.getStatusInfo().getFamily())) {
throw new ApplicationActivationException(response.readEntity(Failure.class));
}
response.close();
}
@Override
public void doAction(String packageName, String widgetId, UpdateAction action) throws ApplicationActionException {
Response response = getClient().target(getApi().getEndpoints().getAppsActionUrl().replace("{:id}", packageName)
.replace("{:widget_id}", widgetId)).request(MediaType.APPLICATION_JSON_TYPE).post(Entity.json(action));
if (!Status.Family.SUCCESSFUL.equals(response.getStatusInfo().getFamily())) {
throw new ApplicationActionException(response.readEntity(Failure.class));
}
response.close();
}
@Override
protected Client createClient() {
ClientBuilder builder = clientBuilder;
// setup Gson (de)serialization
GsonProvider<Object> gsonProvider = new GsonProvider<>();
builder.register(gsonProvider);
if (config.isSecure()) {
/*
* The certificate presented by LaMetric time is self-signed.
* Therefore, unless the user takes action by adding the certificate
* chain to the Java keystore, HTTPS will fail.
*
* By setting the ignoreCertificateValidation configuration option
* to true (default), HTTPS will be used and the connection will be
* encrypted, but the validity of the certificate is not confirmed.
*/
if (config.isIgnoreCertificateValidation()) {
try {
SSLContext sslcontext = SSLContext.getInstance("TLS");
sslcontext.init(null, new TrustManager[] { new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] arg0, String arg1)
throws CertificateException {
// noop
}
@Override
public void checkServerTrusted(X509Certificate[] arg0, String arg1)
throws CertificateException {
// noop
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
} }, new java.security.SecureRandom());
builder.sslContext(sslcontext);
} catch (KeyManagementException | NoSuchAlgorithmException e) {
throw new RuntimeException("Failed to setup secure communication", e);
}
}
/*
* The self-signed certificate used by LaMetric time does not match
* the host when configured on a network. This makes the HTTPS
* handshake fail.
*
* By setting the ignoreHostnameValidation configuration option to
* true (default), HTTPS will be used and the connection will be
* encrypted, but the validity of the hostname in the certificate is
* not confirmed.
*/
if (config.isIgnoreHostnameValidation()) {
builder.hostnameVerifier((host, session) -> true);
}
}
// turn on logging if requested
if (config.isLogging()) {
builder.register(
new LoggingFilter(Logger.getLogger(LaMetricTimeCloudImpl.class.getName()), config.getLogMax()));
}
// setup basic auth
builder.register(HttpAuthenticationFeature.basic(config.getAuthUser(), config.getApiKey()));
return builder.build();
}
}

View File

@@ -0,0 +1,122 @@
/**
* Copyright 2017-2018 Gregory Moyer and contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openhab.binding.lametrictime.api.local.model;
import java.util.SortedMap;
import com.google.gson.annotations.SerializedName;
public class Action
{
private String id;
@SerializedName("params")
private SortedMap<String, Parameter> parameters;
public String getId()
{
return id;
}
public void setId(String id)
{
this.id = id;
}
public Action withId(String id)
{
setId(id);
return this;
}
public SortedMap<String, Parameter> getParameters()
{
return parameters;
}
public void setParameters(SortedMap<String, Parameter> parameters)
{
this.parameters = parameters;
}
public Action withParameters(SortedMap<String, Parameter> parameters)
{
setParameters(parameters);
return this;
}
@Override
public int hashCode()
{
final int prime = 31;
int result = 1;
result = prime * result + ((id == null) ? 0 : id.hashCode());
result = prime * result + ((parameters == null) ? 0 : parameters.hashCode());
return result;
}
@Override
public boolean equals(Object obj)
{
if (this == obj)
{
return true;
}
if (obj == null)
{
return false;
}
if (getClass() != obj.getClass())
{
return false;
}
Action other = (Action)obj;
if (id == null)
{
if (other.id != null)
{
return false;
}
}
else if (!id.equals(other.id))
{
return false;
}
if (parameters == null)
{
if (other.parameters != null)
{
return false;
}
}
else if (!parameters.equals(other.parameters))
{
return false;
}
return true;
}
@Override
public String toString()
{
StringBuilder builder = new StringBuilder();
builder.append("Action [id=");
builder.append(id);
builder.append(", parameters=");
builder.append(parameters);
builder.append("]");
return builder.toString();
}
}

View File

@@ -0,0 +1,66 @@
/**
* Copyright 2017-2018 Gregory Moyer and contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openhab.binding.lametrictime.api.local.model;
public class Api
{
private String apiVersion;
private Endpoints endpoints;
public String getApiVersion()
{
return apiVersion;
}
public void setApiVersion(String apiVersion)
{
this.apiVersion = apiVersion;
}
public Api withApiVersion(String apiVersion)
{
this.apiVersion = apiVersion;
return this;
}
public Endpoints getEndpoints()
{
return endpoints;
}
public void setEndpoints(Endpoints endpoints)
{
this.endpoints = endpoints;
}
public Api withEndpoints(Endpoints endpoints)
{
this.endpoints = endpoints;
return this;
}
@Override
public String toString()
{
StringBuilder builder = new StringBuilder();
builder.append("Api [apiVersion=");
builder.append(apiVersion);
builder.append(", endpoints=");
builder.append(endpoints);
builder.append("]");
return builder.toString();
}
}

View File

@@ -0,0 +1,198 @@
/**
* Copyright 2017-2018 Gregory Moyer and contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openhab.binding.lametrictime.api.local.model;
import java.util.SortedMap;
import com.google.gson.annotations.SerializedName;
public class Application
{
private SortedMap<String, Action> actions;
@SerializedName("package")
private String packageName;
private String vendor;
private String version;
private String versionCode;
private SortedMap<String, Widget> widgets;
public SortedMap<String, Action> getActions()
{
return actions;
}
public void setActions(SortedMap<String, Action> actions)
{
this.actions = actions;
}
public Application withActions(SortedMap<String, Action> actions)
{
setActions(actions);
return this;
}
public String getPackageName()
{
return packageName;
}
public void setPackageName(String packageName)
{
this.packageName = packageName;
}
public Application withPackageName(String packageName)
{
setPackageName(packageName);
return this;
}
public String getVendor()
{
return vendor;
}
public void setVendor(String vendor)
{
this.vendor = vendor;
}
public Application withVendor(String vendor)
{
setVendor(vendor);
return this;
}
public String getVersion()
{
return version;
}
public void setVersion(String version)
{
this.version = version;
}
public Application withVersion(String version)
{
setVersion(version);
return this;
}
public String getVersionCode()
{
return versionCode;
}
public void setVersionCode(String versionCode)
{
this.versionCode = versionCode;
}
public Application withVersionCode(String versionCode)
{
setVersionCode(versionCode);
return this;
}
public SortedMap<String, Widget> getWidgets()
{
return widgets;
}
public void setWidgets(SortedMap<String, Widget> widgets)
{
this.widgets = widgets;
}
public Application withWidgets(SortedMap<String, Widget> widgets)
{
setWidgets(widgets);
return this;
}
@Override
public int hashCode()
{
final int prime = 31;
int result = 1;
result = prime * result + ((packageName == null) ? 0 : packageName.hashCode());
result = prime * result + ((versionCode == null) ? 0 : versionCode.hashCode());
return result;
}
@Override
public boolean equals(Object obj)
{
if (this == obj)
{
return true;
}
if (obj == null)
{
return false;
}
if (getClass() != obj.getClass())
{
return false;
}
Application other = (Application)obj;
if (packageName == null)
{
if (other.packageName != null)
{
return false;
}
}
else if (!packageName.equals(other.packageName))
{
return false;
}
if (versionCode == null)
{
if (other.versionCode != null)
{
return false;
}
}
else if (!versionCode.equals(other.versionCode))
{
return false;
}
return true;
}
@Override
public String toString()
{
StringBuilder builder = new StringBuilder();
builder.append("Application [actions=");
builder.append(actions);
builder.append(", packageName=");
builder.append(packageName);
builder.append(", vendor=");
builder.append(vendor);
builder.append(", version=");
builder.append(version);
builder.append(", versionCode=");
builder.append(versionCode);
builder.append(", widgets=");
builder.append(widgets);
builder.append("]");
return builder.toString();
}
}

View File

@@ -0,0 +1,47 @@
/**
* Copyright 2017-2018 Gregory Moyer and contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openhab.binding.lametrictime.api.local.model;
public class Audio
{
private Integer volume;
public Integer getVolume()
{
return volume;
}
public void setVolume(Integer volume)
{
this.volume = volume;
}
public Audio withVolume(Integer volume)
{
this.volume = volume;
return this;
}
@Override
public String toString()
{
StringBuilder builder = new StringBuilder();
builder.append("Audio [volume=");
builder.append(volume);
builder.append("]");
return builder.toString();
}
}

View File

@@ -0,0 +1,58 @@
/**
* Copyright 2017-2018 Gregory Moyer and contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openhab.binding.lametrictime.api.local.model;
public class AudioUpdateResult
{
private Success success;
public Success getSuccess()
{
return success;
}
public void setSuccess(Success success)
{
this.success = success;
}
public AudioUpdateResult withSuccess(Success success)
{
this.success = success;
return this;
}
public static class Success
{
private Audio data;
public Audio getData()
{
return data;
}
public void setData(Audio data)
{
this.data = data;
}
public Success withData(Audio data)
{
this.data = data;
return this;
}
}
}

View File

@@ -0,0 +1,153 @@
/**
* Copyright 2017-2018 Gregory Moyer and contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openhab.binding.lametrictime.api.local.model;
public class Bluetooth
{
private Boolean active;
/*
* API sometimes calls this field 'mac' and other times calls it 'address'.
* Additionally, Gson uses fields only (not methods). Therefore, if use the
* same instance of this class to read one value and then try to write the
* other without calling the setter, it won't work (the other value will be
* null).
*/
private String mac;
private String address;
private Boolean available;
private Boolean discoverable;
private String name;
private Boolean pairable;
public Boolean isActive()
{
return active;
}
public void setActive(Boolean active)
{
this.active = active;
}
public Bluetooth withActive(Boolean active)
{
this.active = active;
return this;
}
public String getMac()
{
return mac == null ? address : mac;
}
public void setMac(String mac)
{
this.mac = mac;
this.address = mac;
}
public Bluetooth withMac(String mac)
{
setMac(mac);
return this;
}
public Boolean isAvailable()
{
return available;
}
public void setAvailable(Boolean available)
{
this.available = available;
}
public Bluetooth withAvailable(Boolean available)
{
this.available = available;
return this;
}
public Boolean isDiscoverable()
{
return discoverable;
}
public void setDiscoverable(Boolean discoverable)
{
this.discoverable = discoverable;
}
public Bluetooth withDiscoverable(Boolean discoverable)
{
this.discoverable = discoverable;
return this;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public Bluetooth withName(String name)
{
this.name = name;
return this;
}
public Boolean isPairable()
{
return pairable;
}
public void setPairable(Boolean pairable)
{
this.pairable = pairable;
}
public Bluetooth withPairable(Boolean pairable)
{
this.pairable = pairable;
return this;
}
@Override
public String toString()
{
StringBuilder builder = new StringBuilder();
builder.append("Bluetooth [active=");
builder.append(active);
builder.append(", mac=");
builder.append(getMac());
builder.append(", available=");
builder.append(available);
builder.append(", discoverable=");
builder.append(discoverable);
builder.append(", name=");
builder.append(name);
builder.append(", pairable=");
builder.append(pairable);
builder.append("]");
return builder.toString();
}
}

View File

@@ -0,0 +1,58 @@
/**
* Copyright 2017-2018 Gregory Moyer and contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openhab.binding.lametrictime.api.local.model;
public class BluetoothUpdateResult
{
private Success success;
public Success getSuccess()
{
return success;
}
public void setSuccess(Success success)
{
this.success = success;
}
public BluetoothUpdateResult withSuccess(Success success)
{
this.success = success;
return this;
}
public static class Success
{
private Bluetooth data;
public Bluetooth getData()
{
return data;
}
public void setData(Bluetooth data)
{
this.data = data;
}
public Success withData(Bluetooth data)
{
this.data = data;
return this;
}
}
}

View File

@@ -0,0 +1,65 @@
/**
* Copyright 2017-2018 Gregory Moyer and contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openhab.binding.lametrictime.api.local.model;
public class BooleanParameter extends Parameter
{
private Boolean value;
@Override
public BooleanParameter withName(String name)
{
super.withName(name);
return this;
}
@Override
public BooleanParameter withRequired(Boolean required)
{
super.withRequired(required);
return this;
}
public Boolean getValue()
{
return value;
}
public void setValue(Boolean value)
{
this.value = value;
}
public BooleanParameter withValue(Boolean value)
{
setValue(value);
return this;
}
@Override
public String toString()
{
StringBuilder builder = new StringBuilder();
builder.append("BooleanParameter [value=");
builder.append(value);
builder.append(", getName()=");
builder.append(getName());
builder.append(", getRequired()=");
builder.append(getRequired());
builder.append("]");
return builder.toString();
}
}

View File

@@ -0,0 +1,218 @@
/**
* Copyright 2017-2018 Gregory Moyer and contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openhab.binding.lametrictime.api.local.model;
public class Device
{
private Audio audio;
private Bluetooth bluetooth;
private Display display;
private String id;
private String mode;
private String model;
private String name;
private String osVersion;
private String serialNumber;
private Wifi wifi;
public Audio getAudio()
{
return audio;
}
public void setAudio(Audio audio)
{
this.audio = audio;
}
public Device withAudio(Audio audio)
{
this.audio = audio;
return this;
}
public Bluetooth getBluetooth()
{
return bluetooth;
}
public void setBluetooth(Bluetooth bluetooth)
{
this.bluetooth = bluetooth;
}
public Device withBluetooth(Bluetooth bluetooth)
{
this.bluetooth = bluetooth;
return this;
}
public Display getDisplay()
{
return display;
}
public void setDisplay(Display display)
{
this.display = display;
}
public Device withDisplay(Display display)
{
this.display = display;
return this;
}
public String getId()
{
return id;
}
public void setId(String id)
{
this.id = id;
}
public Device withId(String id)
{
this.id = id;
return this;
}
public String getMode()
{
return mode;
}
public void setMode(String mode)
{
this.mode = mode;
}
public Device withMode(String mode)
{
this.mode = mode;
return this;
}
public String getModel()
{
return model;
}
public void setModel(String model)
{
this.model = model;
}
public Device withModel(String model)
{
this.model = model;
return this;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public Device withName(String name)
{
this.name = name;
return this;
}
public String getOsVersion()
{
return osVersion;
}
public void setOsVersion(String osVersion)
{
this.osVersion = osVersion;
}
public Device withOsVersion(String osVersion)
{
this.osVersion = osVersion;
return this;
}
public String getSerialNumber()
{
return serialNumber;
}
public void setSerialNumber(String serialNumber)
{
this.serialNumber = serialNumber;
}
public Device withSerialNumber(String serialNumber)
{
this.serialNumber = serialNumber;
return this;
}
public Wifi getWifi()
{
return wifi;
}
public void setWifi(Wifi wifi)
{
this.wifi = wifi;
}
public Device withWifi(Wifi wifi)
{
this.wifi = wifi;
return this;
}
@Override
public String toString()
{
StringBuilder builder = new StringBuilder();
builder.append("Device [audio=");
builder.append(audio);
builder.append(", bluetooth=");
builder.append(bluetooth);
builder.append(", display=");
builder.append(display);
builder.append(", id=");
builder.append(id);
builder.append(", mode=");
builder.append(mode);
builder.append(", model=");
builder.append(model);
builder.append(", name=");
builder.append(name);
builder.append(", osVersion=");
builder.append(osVersion);
builder.append(", serialNumber=");
builder.append(serialNumber);
builder.append(", wifi=");
builder.append(wifi);
builder.append("]");
return builder.toString();
}
}

View File

@@ -0,0 +1,142 @@
/**
* Copyright 2017-2018 Gregory Moyer and contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openhab.binding.lametrictime.api.local.model;
public class Display
{
private Integer brightness;
private String brightnessMode;
private Integer height;
private Screensaver screensaver;
private String type;
private Integer width;
public Integer getBrightness()
{
return brightness;
}
public void setBrightness(Integer brightness)
{
this.brightness = brightness;
}
public Display withBrightness(Integer brightness)
{
this.brightness = brightness;
return this;
}
public String getBrightnessMode()
{
return brightnessMode;
}
public void setBrightnessMode(String brightnessMode)
{
this.brightnessMode = brightnessMode;
}
public Display withBrightnessMode(String brightnessMode)
{
this.brightnessMode = brightnessMode;
return this;
}
public Integer getHeight()
{
return height;
}
public void setHeight(Integer height)
{
this.height = height;
}
public Display withHeight(Integer height)
{
this.height = height;
return this;
}
public Screensaver getScreensaver()
{
return screensaver;
}
public void setScreensaver(Screensaver screensaver)
{
this.screensaver = screensaver;
}
public Display withScreensaver(Screensaver screensaver)
{
this.screensaver = screensaver;
return this;
}
public String getType()
{
return type;
}
public void setType(String type)
{
this.type = type;
}
public Display withType(String type)
{
this.type = type;
return this;
}
public Integer getWidth()
{
return width;
}
public void setWidth(Integer width)
{
this.width = width;
}
public Display withWidth(Integer width)
{
this.width = width;
return this;
}
@Override
public String toString()
{
StringBuilder builder = new StringBuilder();
builder.append("Display [brightness=");
builder.append(brightness);
builder.append(", brightnessMode=");
builder.append(brightnessMode);
builder.append(", height=");
builder.append(height);
builder.append(", screensaver=");
builder.append(screensaver);
builder.append(", type=");
builder.append(type);
builder.append(", width=");
builder.append(width);
builder.append("]");
return builder.toString();
}
}

View File

@@ -0,0 +1,58 @@
/**
* Copyright 2017-2018 Gregory Moyer and contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openhab.binding.lametrictime.api.local.model;
public class DisplayUpdateResult
{
private Success success;
public Success getSuccess()
{
return success;
}
public void setSuccess(Success success)
{
this.success = success;
}
public DisplayUpdateResult withSuccess(Success success)
{
this.success = success;
return this;
}
public static class Success
{
private Display data;
public Display getData()
{
return data;
}
public void setData(Display data)
{
this.data = data;
}
public Success withData(Display data)
{
this.data = data;
return this;
}
}
}

View File

@@ -0,0 +1,313 @@
/**
* Copyright 2017-2018 Gregory Moyer and contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openhab.binding.lametrictime.api.local.model;
public class Endpoints
{
private String appsActionUrl;
private String appsGetUrl;
private String appsListUrl;
private String appsSwitchNextUrl;
private String appsSwitchPrevUrl;
private String appsSwitchUrl;
private String audioUrl;
private String bluetoothUrl;
private String concreteNotificationUrl;
private String currentNotificationUrl;
private String deviceUrl;
private String displayUrl;
private String notificationsUrl;
private String widgetUpdateUrl;
private String wifiUrl;
public String getAppsActionUrl()
{
return appsActionUrl;
}
public void setAppsActionUrl(String appsActionUrl)
{
this.appsActionUrl = appsActionUrl;
}
public Endpoints withAppsActionUrl(String appsActionUrl)
{
this.appsActionUrl = appsActionUrl;
return this;
}
public String getAppsGetUrl()
{
return appsGetUrl;
}
public void setAppsGetUrl(String appsGetUrl)
{
this.appsGetUrl = appsGetUrl;
}
public Endpoints withAppsGetUrl(String appsGetUrl)
{
this.appsGetUrl = appsGetUrl;
return this;
}
public String getAppsListUrl()
{
return appsListUrl;
}
public void setAppsListUrl(String appsListUrl)
{
this.appsListUrl = appsListUrl;
}
public Endpoints withAppsListUrl(String appsListUrl)
{
this.appsListUrl = appsListUrl;
return this;
}
public String getAppsSwitchNextUrl()
{
return appsSwitchNextUrl;
}
public void setAppsSwitchNextUrl(String appsSwitchNextUrl)
{
this.appsSwitchNextUrl = appsSwitchNextUrl;
}
public Endpoints withAppsSwitchNextUrl(String appsSwitchNextUrl)
{
this.appsSwitchNextUrl = appsSwitchNextUrl;
return this;
}
public String getAppsSwitchPrevUrl()
{
return appsSwitchPrevUrl;
}
public void setAppsSwitchPrevUrl(String appsSwitchPrevUrl)
{
this.appsSwitchPrevUrl = appsSwitchPrevUrl;
}
public Endpoints withAppsSwitchPrevUrl(String appsSwitchPrevUrl)
{
this.appsSwitchPrevUrl = appsSwitchPrevUrl;
return this;
}
public String getAppsSwitchUrl()
{
return appsSwitchUrl;
}
public void setAppsSwitchUrl(String appsSwitchUrl)
{
this.appsSwitchUrl = appsSwitchUrl;
}
public Endpoints withAppsSwitchUrl(String appsSwitchUrl)
{
this.appsSwitchUrl = appsSwitchUrl;
return this;
}
public String getAudioUrl()
{
return audioUrl;
}
public void setAudioUrl(String audioUrl)
{
this.audioUrl = audioUrl;
}
public Endpoints withAudioUrl(String audioUrl)
{
this.audioUrl = audioUrl;
return this;
}
public String getBluetoothUrl()
{
return bluetoothUrl;
}
public void setBluetoothUrl(String bluetoothUrl)
{
this.bluetoothUrl = bluetoothUrl;
}
public Endpoints withBluetoothUrl(String bluetoothUrl)
{
this.bluetoothUrl = bluetoothUrl;
return this;
}
public String getConcreteNotificationUrl()
{
return concreteNotificationUrl;
}
public void setConcreteNotificationUrl(String concreteNotificationUrl)
{
this.concreteNotificationUrl = concreteNotificationUrl;
}
public Endpoints withConcreteNotificationUrl(String concreteNotificationUrl)
{
this.concreteNotificationUrl = concreteNotificationUrl;
return this;
}
public String getCurrentNotificationUrl()
{
return currentNotificationUrl;
}
public void setCurrentNotificationUrl(String currentNotificationUrl)
{
this.currentNotificationUrl = currentNotificationUrl;
}
public Endpoints withCurrentNotificationUrl(String currentNotificationUrl)
{
this.currentNotificationUrl = currentNotificationUrl;
return this;
}
public String getDeviceUrl()
{
return deviceUrl;
}
public void setDeviceUrl(String deviceUrl)
{
this.deviceUrl = deviceUrl;
}
public Endpoints withDeviceUrl(String deviceUrl)
{
this.deviceUrl = deviceUrl;
return this;
}
public String getDisplayUrl()
{
return displayUrl;
}
public void setDisplayUrl(String displayUrl)
{
this.displayUrl = displayUrl;
}
public Endpoints withDisplayUrl(String displayUrl)
{
this.displayUrl = displayUrl;
return this;
}
public String getNotificationsUrl()
{
return notificationsUrl;
}
public void setNotificationsUrl(String notificationsUrl)
{
this.notificationsUrl = notificationsUrl;
}
public Endpoints withNotificationsUrl(String notificationsUrl)
{
this.notificationsUrl = notificationsUrl;
return this;
}
public String getWidgetUpdateUrl()
{
return widgetUpdateUrl;
}
public void setWidgetUpdateUrl(String widgetUpdateUrl)
{
this.widgetUpdateUrl = widgetUpdateUrl;
}
public Endpoints withWidgetUpdateUrl(String widgetUpdateUrl)
{
this.widgetUpdateUrl = widgetUpdateUrl;
return this;
}
public String getWifiUrl()
{
return wifiUrl;
}
public void setWifiUrl(String wifiUrl)
{
this.wifiUrl = wifiUrl;
}
public Endpoints withWifiUrl(String wifiUrl)
{
this.wifiUrl = wifiUrl;
return this;
}
@Override
public String toString()
{
StringBuilder builder = new StringBuilder();
builder.append("Endpoints [appsActionUrl=");
builder.append(appsActionUrl);
builder.append(", appsGetUrl=");
builder.append(appsGetUrl);
builder.append(", appsListUrl=");
builder.append(appsListUrl);
builder.append(", appsSwitchNextUrl=");
builder.append(appsSwitchNextUrl);
builder.append(", appsSwitchPrevUrl=");
builder.append(appsSwitchPrevUrl);
builder.append(", appsSwitchUrl=");
builder.append(appsSwitchUrl);
builder.append(", audioUrl=");
builder.append(audioUrl);
builder.append(", bluetoothUrl=");
builder.append(bluetoothUrl);
builder.append(", concreteNotificationUrl=");
builder.append(concreteNotificationUrl);
builder.append(", currentNotificationUrl=");
builder.append(currentNotificationUrl);
builder.append(", deviceUrl=");
builder.append(deviceUrl);
builder.append(", displayUrl=");
builder.append(displayUrl);
builder.append(", notificationsUrl=");
builder.append(notificationsUrl);
builder.append(", widgetUpdateUrl=");
builder.append(widgetUpdateUrl);
builder.append(", wifiUrl=");
builder.append(wifiUrl);
builder.append("]");
return builder.toString();
}
}

View File

@@ -0,0 +1,47 @@
/**
* Copyright 2017-2018 Gregory Moyer and contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openhab.binding.lametrictime.api.local.model;
public class Error
{
private String message;
public String getMessage()
{
return message;
}
public void setMessage(String message)
{
this.message = message;
}
public Error withMessage(String message)
{
this.message = message;
return this;
}
@Override
public String toString()
{
StringBuilder builder = new StringBuilder();
builder.append("Error [message=");
builder.append(message);
builder.append("]");
return builder.toString();
}
}

View File

@@ -0,0 +1,50 @@
/**
* Copyright 2017-2018 Gregory Moyer and contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openhab.binding.lametrictime.api.local.model;
import java.util.ArrayList;
import java.util.List;
public class Failure
{
private List<Error> errors = new ArrayList<Error>();
public List<Error> getErrors()
{
return errors;
}
public void setErrors(List<Error> errors)
{
this.errors = errors;
}
public Failure withErrors(List<Error> errors)
{
this.errors = errors;
return this;
}
@Override
public String toString()
{
StringBuilder builder = new StringBuilder();
builder.append("Failure [errors=");
builder.append(errors);
builder.append("]");
return builder.toString();
}
}

View File

@@ -0,0 +1,129 @@
/**
* Copyright 2017-2018 Gregory Moyer and contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openhab.binding.lametrictime.api.local.model;
import java.util.List;
import com.google.gson.annotations.SerializedName;
public class Frame
{
private String icon;
private String text;
@SerializedName("goalData")
private GoalData goalData;
@SerializedName("chartData")
private List<Integer> chartData;
private Integer index;
public String getIcon()
{
return icon;
}
public void setIcon(String icon)
{
this.icon = icon;
}
public Frame withIcon(String icon)
{
this.icon = icon;
return this;
}
public String getText()
{
return text;
}
public void setText(String text)
{
this.text = text;
}
public Frame withText(String text)
{
this.text = text;
return this;
}
public GoalData getGoalData()
{
return goalData;
}
public void setGoalData(GoalData goalData)
{
this.goalData = goalData;
}
public Frame withGoalData(GoalData goalData)
{
this.goalData = goalData;
return this;
}
public List<Integer> getChartData()
{
return chartData;
}
public void setChartData(List<Integer> chartData)
{
this.chartData = chartData;
}
public Frame withChartData(List<Integer> chartData)
{
this.chartData = chartData;
return this;
}
public Integer getIndex()
{
return index;
}
public void setIndex(Integer index)
{
this.index = index;
}
public Frame withIndex(Integer index)
{
this.index = index;
return this;
}
@Override
public String toString()
{
StringBuilder builder = new StringBuilder();
builder.append("Frame [icon=");
builder.append(icon);
builder.append(", text=");
builder.append(text);
builder.append(", goalData=");
builder.append(goalData);
builder.append(", chartData=");
builder.append(chartData);
builder.append(", index=");
builder.append(index);
builder.append("]");
return builder.toString();
}
}

View File

@@ -0,0 +1,179 @@
/**
* Copyright 2017-2018 Gregory Moyer and contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openhab.binding.lametrictime.api.local.model;
public class GoalData
{
private Integer start;
private Integer current;
private Integer end;
private String unit;
public Integer getStart()
{
return start;
}
public void setStart(Integer start)
{
this.start = start;
}
public GoalData withStart(Integer start)
{
this.start = start;
return this;
}
public Integer getCurrent()
{
return current;
}
public void setCurrent(Integer current)
{
this.current = current;
}
public GoalData withCurrent(Integer current)
{
this.current = current;
return this;
}
public Integer getEnd()
{
return end;
}
public void setEnd(Integer end)
{
this.end = end;
}
public GoalData withEnd(Integer end)
{
this.end = end;
return this;
}
public String getUnit()
{
return unit;
}
public void setUnit(String unit)
{
this.unit = unit;
}
public GoalData withUnit(String unit)
{
this.unit = unit;
return this;
}
@Override
public int hashCode()
{
final int prime = 31;
int result = 1;
result = prime * result + ((current == null) ? 0 : current.hashCode());
result = prime * result + ((end == null) ? 0 : end.hashCode());
result = prime * result + ((start == null) ? 0 : start.hashCode());
result = prime * result + ((unit == null) ? 0 : unit.hashCode());
return result;
}
@Override
public boolean equals(Object obj)
{
if (this == obj)
{
return true;
}
if (obj == null)
{
return false;
}
if (getClass() != obj.getClass())
{
return false;
}
GoalData other = (GoalData)obj;
if (current == null)
{
if (other.current != null)
{
return false;
}
}
else if (!current.equals(other.current))
{
return false;
}
if (end == null)
{
if (other.end != null)
{
return false;
}
}
else if (!end.equals(other.end))
{
return false;
}
if (start == null)
{
if (other.start != null)
{
return false;
}
}
else if (!start.equals(other.start))
{
return false;
}
if (unit == null)
{
if (other.unit != null)
{
return false;
}
}
else if (!unit.equals(other.unit))
{
return false;
}
return true;
}
@Override
public String toString()
{
StringBuilder builder = new StringBuilder();
builder.append("GoalData [start=");
builder.append(start);
builder.append(", current=");
builder.append(current);
builder.append(", end=");
builder.append(end);
builder.append(", unit=");
builder.append(unit);
builder.append("]");
return builder.toString();
}
}

View File

@@ -0,0 +1,65 @@
/**
* Copyright 2017-2018 Gregory Moyer and contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openhab.binding.lametrictime.api.local.model;
public class IntegerParameter extends Parameter
{
private Integer value;
@Override
public IntegerParameter withName(String name)
{
super.withName(name);
return this;
}
@Override
public IntegerParameter withRequired(Boolean required)
{
super.withRequired(required);
return this;
}
public Integer getValue()
{
return value;
}
public void setValue(Integer value)
{
this.value = value;
}
public IntegerParameter withValue(Integer value)
{
setValue(value);
return this;
}
@Override
public String toString()
{
StringBuilder builder = new StringBuilder();
builder.append("IntegerParameter [value=");
builder.append(value);
builder.append(", getName()=");
builder.append(getName());
builder.append(", getRequired()=");
builder.append(getRequired());
builder.append("]");
return builder.toString();
}
}

View File

@@ -0,0 +1,66 @@
/**
* Copyright 2017-2018 Gregory Moyer and contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openhab.binding.lametrictime.api.local.model;
public class Modes
{
private TimeBased timeBased;
private WhenDark whenDark;
public TimeBased getTimeBased()
{
return timeBased;
}
public void setTimeBased(TimeBased timeBased)
{
this.timeBased = timeBased;
}
public Modes withTimeBased(TimeBased timeBased)
{
this.timeBased = timeBased;
return this;
}
public WhenDark getWhenDark()
{
return whenDark;
}
public void setWhenDark(WhenDark whenDark)
{
this.whenDark = whenDark;
}
public Modes withWhenDark(WhenDark whenDark)
{
this.whenDark = whenDark;
return this;
}
@Override
public String toString()
{
StringBuilder builder = new StringBuilder();
builder.append("Modes [timeBased=");
builder.append(timeBased);
builder.append(", whenDark=");
builder.append(whenDark);
builder.append("]");
return builder.toString();
}
}

View File

@@ -0,0 +1,182 @@
/**
* Copyright 2017-2018 Gregory Moyer and contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openhab.binding.lametrictime.api.local.model;
import java.time.LocalDateTime;
public class Notification
{
private String id;
private String type;
private LocalDateTime created;
private LocalDateTime expirationDate;
private String priority;
private String iconType;
private Integer lifetime;
private NotificationModel model;
public String getId()
{
return id;
}
public void setId(String id)
{
this.id = id;
}
public Notification withId(String id)
{
this.id = id;
return this;
}
public String getType()
{
return type;
}
public void setType(String type)
{
this.type = type;
}
public Notification withType(String type)
{
this.type = type;
return this;
}
public LocalDateTime getCreated()
{
return created;
}
public void setCreated(LocalDateTime created)
{
this.created = created;
}
public Notification withCreated(LocalDateTime created)
{
this.created = created;
return this;
}
public LocalDateTime getExpirationDate()
{
return expirationDate;
}
public void setExpirationDate(LocalDateTime expirationDate)
{
this.expirationDate = expirationDate;
}
public Notification withExpirationDate(LocalDateTime expirationDate)
{
this.expirationDate = expirationDate;
return this;
}
public String getPriority()
{
return priority;
}
public void setPriority(String priority)
{
this.priority = priority;
}
public Notification withPriority(String priority)
{
this.priority = priority;
return this;
}
public String getIconType()
{
return iconType;
}
public void setIconType(String iconType)
{
this.iconType = iconType;
}
public Notification withIconType(String iconType)
{
this.iconType = iconType;
return this;
}
public Integer getLifetime()
{
return lifetime;
}
public void setLifetime(Integer lifetime)
{
this.lifetime = lifetime;
}
public Notification withLifetime(Integer lifetime)
{
this.lifetime = lifetime;
return this;
}
public NotificationModel getModel()
{
return model;
}
public void setModel(NotificationModel model)
{
this.model = model;
}
public Notification withModel(NotificationModel model)
{
this.model = model;
return this;
}
@Override
public String toString()
{
StringBuilder builder = new StringBuilder();
builder.append("Notification [id=");
builder.append(id);
builder.append(", type=");
builder.append(type);
builder.append(", created=");
builder.append(created);
builder.append(", expirationDate=");
builder.append(expirationDate);
builder.append(", priority=");
builder.append(priority);
builder.append(", iconType=");
builder.append(iconType);
builder.append(", lifetime=");
builder.append(lifetime);
builder.append(", model=");
builder.append(model);
builder.append("]");
return builder.toString();
}
}

View File

@@ -0,0 +1,87 @@
/**
* Copyright 2017-2018 Gregory Moyer and contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openhab.binding.lametrictime.api.local.model;
import java.util.List;
public class NotificationModel
{
private Integer cycles;
private List<Frame> frames;
private Sound sound;
public Integer getCycles()
{
return cycles;
}
public void setCycles(Integer cycles)
{
this.cycles = cycles;
}
public NotificationModel withCycles(Integer cycles)
{
this.cycles = cycles;
return this;
}
public List<Frame> getFrames()
{
return frames;
}
public void setFrames(List<Frame> frames)
{
this.frames = frames;
}
public NotificationModel withFrames(List<Frame> frames)
{
this.frames = frames;
return this;
}
public Sound getSound()
{
return sound;
}
public void setSound(Sound sound)
{
this.sound = sound;
}
public NotificationModel withSound(Sound sound)
{
this.sound = sound;
return this;
}
@Override
public String toString()
{
StringBuilder builder = new StringBuilder();
builder.append("NotificationModel [cycles=");
builder.append(cycles);
builder.append(", frames=");
builder.append(frames);
builder.append(", sound=");
builder.append(sound);
builder.append("]");
return builder.toString();
}
}

View File

@@ -0,0 +1,58 @@
/**
* Copyright 2017-2018 Gregory Moyer and contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openhab.binding.lametrictime.api.local.model;
public class NotificationResult
{
private Success success;
public Success getSuccess()
{
return success;
}
public void setSuccess(Success success)
{
this.success = success;
}
public NotificationResult withSuccess(Success success)
{
this.success = success;
return this;
}
public static class Success
{
private String id;
public String getId()
{
return id;
}
public void setId(String id)
{
this.id = id;
}
public Success withId(String id)
{
this.id = id;
return this;
}
}
}

View File

@@ -0,0 +1,54 @@
/**
* Copyright 2017-2018 Gregory Moyer and contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openhab.binding.lametrictime.api.local.model;
public abstract class Parameter
{
private String name;
private Boolean required;
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public Parameter withName(String name)
{
setName(name);
return this;
}
public Boolean getRequired()
{
return required;
}
public void setRequired(Boolean required)
{
this.required = required;
}
public Parameter withRequired(Boolean required)
{
setRequired(required);
return this;
}
}

View File

@@ -0,0 +1,85 @@
/**
* Copyright 2017-2018 Gregory Moyer and contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openhab.binding.lametrictime.api.local.model;
public class Screensaver
{
private Boolean enabled;
private Modes modes;
private String widget;
public Boolean isEnabled()
{
return enabled;
}
public void setEnabled(Boolean enabled)
{
this.enabled = enabled;
}
public Screensaver withEnabled(Boolean enabled)
{
this.enabled = enabled;
return this;
}
public Modes getModes()
{
return modes;
}
public void setModes(Modes modes)
{
this.modes = modes;
}
public Screensaver withModes(Modes modes)
{
this.modes = modes;
return this;
}
public String getWidget()
{
return widget;
}
public void setWidget(String widget)
{
this.widget = widget;
}
public Screensaver withWidget(String widget)
{
this.widget = widget;
return this;
}
@Override
public String toString()
{
StringBuilder builder = new StringBuilder();
builder.append("Screensaver [enabled=");
builder.append(enabled);
builder.append(", modes=");
builder.append(modes);
builder.append(", widget=");
builder.append(widget);
builder.append("]");
return builder.toString();
}
}

View File

@@ -0,0 +1,85 @@
/**
* Copyright 2017-2018 Gregory Moyer and contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openhab.binding.lametrictime.api.local.model;
public class Sound
{
private String category;
private String id;
private Integer repeat;
public String getCategory()
{
return category;
}
public void setCategory(String category)
{
this.category = category;
}
public Sound withCategory(String category)
{
this.category = category;
return this;
}
public String getId()
{
return id;
}
public void setId(String id)
{
this.id = id;
}
public Sound withId(String id)
{
this.id = id;
return this;
}
public Integer getRepeat()
{
return repeat;
}
public void setRepeat(Integer repeat)
{
this.repeat = repeat;
}
public Sound withRepeat(Integer repeat)
{
this.repeat = repeat;
return this;
}
@Override
public String toString()
{
StringBuilder builder = new StringBuilder();
builder.append("Sound [category=");
builder.append(category);
builder.append(", id=");
builder.append(id);
builder.append(", repeat=");
builder.append(repeat);
builder.append("]");
return builder.toString();
}
}

View File

@@ -0,0 +1,84 @@
/**
* Copyright 2017-2018 Gregory Moyer and contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openhab.binding.lametrictime.api.local.model;
public class StringParameter extends Parameter
{
private String format;
private String value;
@Override
public StringParameter withName(String name)
{
super.withName(name);
return this;
}
@Override
public StringParameter withRequired(Boolean required)
{
super.withRequired(required);
return this;
}
public String getFormat()
{
return format;
}
public void setFormat(String format)
{
this.format = format;
}
public StringParameter withFormat(String format)
{
setFormat(format);
return this;
}
public String getValue()
{
return value;
}
public void setValue(String value)
{
this.value = value;
}
public StringParameter withValue(String value)
{
setValue(value);
return this;
}
@Override
public String toString()
{
StringBuilder builder = new StringBuilder();
builder.append("StringParameter [format=");
builder.append(format);
builder.append(", value=");
builder.append(value);
builder.append(", getName()=");
builder.append(getName());
builder.append(", getRequired()=");
builder.append(getRequired());
builder.append("]");
return builder.toString();
}
}

View File

@@ -0,0 +1,47 @@
/**
* Copyright 2017-2018 Gregory Moyer and contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openhab.binding.lametrictime.api.local.model;
public class TimeBased
{
private Boolean enabled;
public Boolean isEnabled()
{
return enabled;
}
public void setEnabled(Boolean enabled)
{
this.enabled = enabled;
}
public TimeBased withEnabled(Boolean enabled)
{
this.enabled = enabled;
return this;
}
@Override
public String toString()
{
StringBuilder builder = new StringBuilder();
builder.append("TimeBased [enabled=");
builder.append(enabled);
builder.append("]");
return builder.toString();
}
}

View File

@@ -0,0 +1,35 @@
/**
* Copyright 2017-2018 Gregory Moyer and contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openhab.binding.lametrictime.api.local.model;
import java.util.SortedMap;
public class UpdateAction extends Action
{
@Override
public UpdateAction withId(String id)
{
super.setId(id);
return this;
}
@Override
public UpdateAction withParameters(SortedMap<String, Parameter> parameters)
{
super.setParameters(parameters);
return this;
}
}

View File

@@ -0,0 +1,47 @@
/**
* Copyright 2017-2018 Gregory Moyer and contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openhab.binding.lametrictime.api.local.model;
public class WhenDark
{
private Boolean enabled;
public Boolean isEnabled()
{
return enabled;
}
public void setEnabled(Boolean enabled)
{
this.enabled = enabled;
}
public WhenDark withEnabled(Boolean enabled)
{
this.enabled = enabled;
return this;
}
@Override
public String toString()
{
StringBuilder builder = new StringBuilder();
builder.append("WhenDark [enabled=");
builder.append(enabled);
builder.append("]");
return builder.toString();
}
}

View File

@@ -0,0 +1,185 @@
/**
* Copyright 2017-2018 Gregory Moyer and contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openhab.binding.lametrictime.api.local.model;
import java.util.Map;
import com.google.gson.JsonPrimitive;
import com.google.gson.annotations.SerializedName;
public class Widget
{
private String id;
@SerializedName("package")
private String packageName;
private Integer index;
private Map<String, JsonPrimitive> settings;
public String getId()
{
return id;
}
public void setId(String id)
{
this.id = id;
}
public Widget withId(String id)
{
setId(id);
return this;
}
public String getPackageName()
{
return packageName;
}
public void setPackageName(String packageName)
{
this.packageName = packageName;
}
public Widget withPackageName(String packageName)
{
setPackageName(packageName);
return this;
}
public Integer getIndex()
{
return index;
}
public void setIndex(Integer index)
{
this.index = index;
}
public Widget withIndex(Integer index)
{
setIndex(index);
return this;
}
public Map<String, JsonPrimitive> getSettings()
{
return settings;
}
public void setSettings(Map<String, JsonPrimitive> settings)
{
this.settings = settings;
}
public Widget withSettings(Map<String, JsonPrimitive> settings)
{
setSettings(settings);
return this;
}
@Override
public int hashCode()
{
final int prime = 31;
int result = 1;
result = prime * result + ((id == null) ? 0 : id.hashCode());
result = prime * result + ((index == null) ? 0 : index.hashCode());
result = prime * result + ((packageName == null) ? 0 : packageName.hashCode());
result = prime * result + ((settings == null) ? 0 : settings.hashCode());
return result;
}
@Override
public boolean equals(Object obj)
{
if (this == obj)
{
return true;
}
if (obj == null)
{
return false;
}
if (getClass() != obj.getClass())
{
return false;
}
Widget other = (Widget)obj;
if (id == null)
{
if (other.id != null)
{
return false;
}
}
else if (!id.equals(other.id))
{
return false;
}
if (index == null)
{
if (other.index != null)
{
return false;
}
}
else if (!index.equals(other.index))
{
return false;
}
if (packageName == null)
{
if (other.packageName != null)
{
return false;
}
}
else if (!packageName.equals(other.packageName))
{
return false;
}
if (settings == null)
{
if (other.settings != null)
{
return false;
}
}
else if (!settings.equals(other.settings))
{
return false;
}
return true;
}
@Override
public String toString()
{
StringBuilder builder = new StringBuilder();
builder.append("Widget [id=");
builder.append(id);
builder.append(", packageName=");
builder.append(packageName);
builder.append(", index=");
builder.append(index);
builder.append(", settings=");
builder.append(settings);
builder.append("]");
return builder.toString();
}
}

View File

@@ -0,0 +1,49 @@
/**
* Copyright 2017-2018 Gregory Moyer and contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openhab.binding.lametrictime.api.local.model;
import java.util.List;
public class WidgetUpdates
{
private List<Frame> frames;
public List<Frame> getFrames()
{
return frames;
}
public void setFrames(List<Frame> frames)
{
this.frames = frames;
}
public WidgetUpdates withFrames(List<Frame> frames)
{
this.frames = frames;
return this;
}
@Override
public String toString()
{
StringBuilder builder = new StringBuilder();
builder.append("WidgetUpdates [frames=");
builder.append(frames);
builder.append("]");
return builder.toString();
}
}

View File

@@ -0,0 +1,241 @@
/**
* Copyright 2017-2018 Gregory Moyer and contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openhab.binding.lametrictime.api.local.model;
public class Wifi
{
private Boolean active;
/*
* API sometimes calls this field 'mac' and other times calls it 'address'.
* Additionally, Gson uses fields only (not methods). Therefore, if use the
* same instance of this class to read one value and then try to write the
* other without calling the setter, it won't work (the other value will be
* null).
*/
private String mac;
private String address;
private Boolean available;
private String encryption;
/*
* API sometimes calls this field 'ssid' and other times calls it 'essid'.
* Additionally, Gson uses fields only (not methods). Therefore, if use the
* same instance of this class to read one value and then try to write the
* other without calling the setter, it won't work (the other value will be
* null).
*/
private String ssid;
private String essid;
/*
* API sometimes calls this field 'ip' and other times calls it 'ipv4'.
* Additionally, Gson uses fields only (not methods). Therefore, if use the
* same instance of this class to read one value and then try to write the
* other without calling the setter, it won't work (the other value will be
* null).
*/
private String ip;
private String ipv4;
private String mode;
private String netmask;
/*
* API sometimes calls this field 'signal_strength' and other times calls it
* 'strength'. Additionally, Gson uses fields only (not methods). Therefore,
* if use the same instance of this class to read one value and then try to
* write the other without calling the setter, it won't work (the other
* value will be null).
*/
private Integer signalStrength;
private Integer strength;
public Boolean isActive()
{
return active;
}
public void setActive(Boolean active)
{
this.active = active;
}
public Wifi withActive(Boolean active)
{
this.active = active;
return this;
}
public String getMac()
{
return mac == null ? address : mac;
}
public void setMac(String mac)
{
this.mac = mac;
this.address = mac;
}
public Wifi withMac(String mac)
{
setMac(mac);
return this;
}
public Boolean isAvailable()
{
return available;
}
public void setAvailable(Boolean available)
{
this.available = available;
}
public Wifi withAvailable(Boolean available)
{
this.available = available;
return this;
}
public String getEncryption()
{
return encryption;
}
public void setEncryption(String encryption)
{
this.encryption = encryption;
}
public Wifi withEncryption(String encryption)
{
this.encryption = encryption;
return this;
}
public String getSsid()
{
return ssid == null ? essid : ssid;
}
public void setSsid(String ssid)
{
this.ssid = ssid;
this.essid = ssid;
}
public Wifi withSsid(String ssid)
{
setSsid(ssid);
return this;
}
public String getIp()
{
return ip == null ? ipv4 : ip;
}
public void setIp(String ip)
{
this.ip = ip;
this.ipv4 = ip;
}
public Wifi withIp(String ip)
{
setIp(ip);
return this;
}
public String getMode()
{
return mode;
}
public void setMode(String mode)
{
this.mode = mode;
}
public Wifi withMode(String mode)
{
this.mode = mode;
return this;
}
public String getNetmask()
{
return netmask;
}
public void setNetmask(String netmask)
{
this.netmask = netmask;
}
public Wifi withNetmask(String netmask)
{
this.netmask = netmask;
return this;
}
public Integer getSignalStrength()
{
return signalStrength == null ? strength : signalStrength;
}
public void setSignalStrength(Integer signalStrength)
{
this.signalStrength = signalStrength;
this.strength = signalStrength;
}
public Wifi withSignalStrength(Integer signalStrength)
{
setSignalStrength(signalStrength);
return this;
}
@Override
public String toString()
{
StringBuilder builder = new StringBuilder();
builder.append("Wifi [active=");
builder.append(active);
builder.append(", mac=");
builder.append(getMac());
builder.append(", available=");
builder.append(available);
builder.append(", encryption=");
builder.append(encryption);
builder.append(", ssid=");
builder.append(getSsid());
builder.append(", ip=");
builder.append(getIp());
builder.append(", mode=");
builder.append(mode);
builder.append(", netmask=");
builder.append(netmask);
builder.append(", signalStrength=");
builder.append(getSignalStrength());
builder.append("]");
return builder.toString();
}
}

View File

@@ -0,0 +1,31 @@
/**
* Copyright 2017-2018 Gregory Moyer and contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openhab.binding.lametrictime.api.model;
public interface ApiValue
{
public String toRaw();
public static String raw(ApiValue value)
{
if (value == null)
{
return null;
}
return value.toRaw();
}
}

View File

@@ -0,0 +1,78 @@
/**
* Copyright 2017-2018 Gregory Moyer and contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openhab.binding.lametrictime.api.model;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.SortedMap;
import java.util.TreeMap;
import org.openhab.binding.lametrictime.api.local.model.BooleanParameter;
import org.openhab.binding.lametrictime.api.local.model.Parameter;
import org.openhab.binding.lametrictime.api.local.model.StringParameter;
import org.openhab.binding.lametrictime.api.local.model.UpdateAction;
public class ClockApp extends CoreApplication
{
private static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern("HH:mm:ss");
private static final String NAME = "com.lametric.clock";
private static final String ACTION_ALARM = "clock.alarm";
private static final String PARAMETER_ENABLED = "enabled";
private static final String PARAMETER_TIME = "time";
private static final String PARAMETER_WAKE_WITH_RADIO = "wake_with_radio";
public ClockApp()
{
super(NAME);
}
public CoreAction setAlarm(Boolean enabled, LocalTime time, Boolean wakeWithRadio)
{
SortedMap<String, Parameter> parameters = new TreeMap<>();
if (enabled != null)
{
parameters.put(PARAMETER_ENABLED, new BooleanParameter().withValue(enabled));
}
if (time != null)
{
parameters.put(PARAMETER_TIME,
new StringParameter().withValue(time.format(TIME_FORMATTER)));
}
if (wakeWithRadio != null)
{
parameters.put(PARAMETER_WAKE_WITH_RADIO,
new BooleanParameter().withValue(wakeWithRadio));
}
return new CoreAction(this,
new UpdateAction().withId(ACTION_ALARM).withParameters(parameters));
}
public CoreAction stopAlarm()
{
SortedMap<String, Parameter> parameters = new TreeMap<>();
parameters.put(PARAMETER_ENABLED, new BooleanParameter().withValue(false));
return new CoreAction(this,
new UpdateAction().withId(ACTION_ALARM).withParameters(parameters));
}
}

View File

@@ -0,0 +1,40 @@
/**
* Copyright 2017-2018 Gregory Moyer and contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openhab.binding.lametrictime.api.model;
import org.openhab.binding.lametrictime.api.local.model.UpdateAction;
public class CoreAction
{
private final CoreApplication app;
private final UpdateAction action;
protected CoreAction(CoreApplication app, UpdateAction action)
{
this.app = app;
this.action = action;
}
public CoreApplication getApp()
{
return app;
}
public UpdateAction getAction()
{
return action;
}
}

View File

@@ -0,0 +1,31 @@
/**
* Copyright 2017-2018 Gregory Moyer and contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openhab.binding.lametrictime.api.model;
public abstract class CoreApplication
{
private final String packageName;
public CoreApplication(String packageName)
{
this.packageName = packageName;
}
public String getPackageName()
{
return packageName;
}
}

View File

@@ -0,0 +1,54 @@
/**
* Copyright 2017-2018 Gregory Moyer and contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openhab.binding.lametrictime.api.model;
public class CoreApps
{
private static final ClockApp CLOCK = new ClockApp();
private static final CountdownApp COUNTDOWN = new CountdownApp();
private static final RadioApp RADIO = new RadioApp();
private static final StopwatchApp STOPWATCH = new StopwatchApp();
private static final WeatherApp WEATHER = new WeatherApp();
public static ClockApp clock()
{
return CLOCK;
}
public static CountdownApp countdown()
{
return COUNTDOWN;
}
public static RadioApp radio()
{
return RADIO;
}
public static StopwatchApp stopwatch()
{
return STOPWATCH;
}
public static WeatherApp weather()
{
return WEATHER;
}
// @formatter:off
private CoreApps() {}
// @formatter:on
}

View File

@@ -0,0 +1,68 @@
/**
* Copyright 2017-2018 Gregory Moyer and contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openhab.binding.lametrictime.api.model;
import java.util.SortedMap;
import java.util.TreeMap;
import org.openhab.binding.lametrictime.api.local.model.BooleanParameter;
import org.openhab.binding.lametrictime.api.local.model.IntegerParameter;
import org.openhab.binding.lametrictime.api.local.model.Parameter;
import org.openhab.binding.lametrictime.api.local.model.UpdateAction;
public class CountdownApp extends CoreApplication
{
private static final String NAME = "com.lametric.countdown";
private static final String ACTION_CONFIGURE = "countdown.configure";
private static final String ACTION_PAUSE = "countdown.pause";
private static final String ACTION_RESET = "countdown.reset";
private static final String ACTION_START = "countdown.start";
private static final String PARAMETER_DURATION = "duration";
private static final String PARAMETER_START_NOW = "start_now";
public CountdownApp()
{
super(NAME);
}
public CoreAction configure(int duration, boolean startNow)
{
SortedMap<String, Parameter> parameters = new TreeMap<>();
parameters.put(PARAMETER_DURATION, new IntegerParameter().withValue(duration));
parameters.put(PARAMETER_START_NOW, new BooleanParameter().withValue(startNow));
return new CoreAction(this,
new UpdateAction().withId(ACTION_CONFIGURE)
.withParameters(parameters));
}
public CoreAction pause()
{
return new CoreAction(this, new UpdateAction().withId(ACTION_PAUSE));
}
public CoreAction reset()
{
return new CoreAction(this, new UpdateAction().withId(ACTION_RESET));
}
public CoreAction start()
{
return new CoreAction(this, new UpdateAction().withId(ACTION_START));
}
}

View File

@@ -0,0 +1,21 @@
/**
* Copyright 2017-2018 Gregory Moyer and contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openhab.binding.lametrictime.api.model;
public interface Icon extends ApiValue
{
// marker interface
}

View File

@@ -0,0 +1,90 @@
/**
* Copyright 2017-2018 Gregory Moyer and contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openhab.binding.lametrictime.api.model;
import java.io.File;
import java.net.URI;
import java.nio.file.Path;
import org.openhab.binding.lametrictime.api.impl.DataIcon;
import org.openhab.binding.lametrictime.api.impl.FileIcon;
import org.openhab.binding.lametrictime.api.impl.HTTPIcon;
import org.openhab.binding.lametrictime.api.impl.KeyIcon;
public class Icons
{
public static Icon key(String key)
{
return new KeyIcon(key);
}
public static Icon http(String uri)
{
return http(URI.create(uri));
}
public static Icon http(URI uri)
{
return new HTTPIcon(uri);
}
public static Icon path(Path path)
{
return new FileIcon(path);
}
public static Icon file(File file)
{
return new FileIcon(file);
}
public static Icon data(String mimeType, byte[] data)
{
return new DataIcon(mimeType, data);
}
// @formatter:off
public static Icon dollar() { return key("i34"); }
public static Icon gmail() { return key("i43"); }
public static Icon confirm() { return key("i59"); }
public static Icon goOut() { return key("a68"); }
public static Icon dog() { return key("a76"); }
public static Icon clock() { return key("a82"); }
public static Icon smile() { return key("a87"); }
public static Icon lightning() { return key("i95"); }
public static Icon facebook() { return key("a128"); }
public static Icon home() { return key("i96"); }
public static Icon girl() { return key("a178"); }
public static Icon stop() { return key("i184"); }
public static Icon heart() { return key("a230"); }
public static Icon fade() { return key("a273"); }
public static Icon terminal() { return key("a315"); }
public static Icon usa() { return key("a413"); }
public static Icon switzerland() { return key("i469"); }
public static Icon attention() { return key("i555"); }
public static Icon theMatrix() { return key("a653"); }
public static Icon pizza() { return key("i1324"); }
public static Icon christmasTree() { return key("a1782"); }
public static Icon night() { return key("a2285"); }
public static Icon fireworks() { return key("a2867"); }
public static Icon beer() { return key("i3253"); }
public static Icon tetris() { return key("a3793"); }
public static Icon halloween() { return key("a4033"); }
public static Icon pacman() { return key("a4584"); }
private Icons() {}
// @formatter:on
}

View File

@@ -0,0 +1,53 @@
/**
* Copyright 2017-2018 Gregory Moyer and contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openhab.binding.lametrictime.api.model;
import org.openhab.binding.lametrictime.api.local.model.UpdateAction;
public class RadioApp extends CoreApplication
{
private static final String NAME = "com.lametric.radio";
private static final String ACTION_NEXT = "radio.next";
private static final String ACTION_PLAY = "radio.play";
private static final String ACTION_PREV = "radio.prev";
private static final String ACTION_STOP = "radio.stop";
public RadioApp()
{
super(NAME);
}
public CoreAction next()
{
return new CoreAction(this, new UpdateAction().withId(ACTION_NEXT));
}
public CoreAction play()
{
return new CoreAction(this, new UpdateAction().withId(ACTION_PLAY));
}
public CoreAction previous()
{
return new CoreAction(this, new UpdateAction().withId(ACTION_PREV));
}
public CoreAction stop()
{
return new CoreAction(this, new UpdateAction().withId(ACTION_STOP));
}
}

View File

@@ -0,0 +1,47 @@
/**
* Copyright 2017-2018 Gregory Moyer and contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openhab.binding.lametrictime.api.model;
import org.openhab.binding.lametrictime.api.local.model.UpdateAction;
public class StopwatchApp extends CoreApplication
{
private static final String NAME = "com.lametric.stopwatch";
private static final String ACTION_PAUSE = "stopwatch.pause";
private static final String ACTION_RESET = "stopwatch.reset";
private static final String ACTION_START = "stopwatch.start";
public StopwatchApp()
{
super(NAME);
}
public CoreAction pause()
{
return new CoreAction(this, new UpdateAction().withId(ACTION_PAUSE));
}
public CoreAction reset()
{
return new CoreAction(this, new UpdateAction().withId(ACTION_RESET));
}
public CoreAction start()
{
return new CoreAction(this, new UpdateAction().withId(ACTION_START));
}
}

View File

@@ -0,0 +1,35 @@
/**
* Copyright 2017-2018 Gregory Moyer and contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openhab.binding.lametrictime.api.model;
import org.openhab.binding.lametrictime.api.local.model.UpdateAction;
public class WeatherApp extends CoreApplication
{
private static final String NAME = "com.lametric.weather";
private static final String ACTION_FORECAST = "weather.forecast";
public WeatherApp()
{
super(NAME);
}
public CoreAction forecast()
{
return new CoreAction(this, new UpdateAction().withId(ACTION_FORECAST));
}
}

View File

@@ -0,0 +1,48 @@
/**
* Copyright 2017-2018 Gregory Moyer and contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openhab.binding.lametrictime.api.model.enums;
import org.openhab.binding.lametrictime.api.model.ApiValue;
public enum BrightnessMode implements ApiValue
{
AUTO,
MANUAL;
@Override
public String toRaw()
{
return name().toLowerCase();
}
public static BrightnessMode toEnum(String raw)
{
if (raw == null)
{
return null;
}
try
{
return valueOf(raw.toUpperCase());
}
catch (IllegalArgumentException e)
{
// not a valid raw string
return null;
}
}
}

Some files were not shown because too many files have changed in this diff Show More