/******************************************************************************* * Copyright (c) 2013 EclipseSource and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * EclipseSource - initial API and implementation ******************************************************************************/ package com.eclipsesource.tabris.internal; import static com.eclipsesource.tabris.internal.Clauses.whenNull; import static com.eclipsesource.tabris.internal.Constants.PROPERTY_CAPABILITIES; import static com.eclipsesource.tabris.internal.Constants.PROPERTY_CONNECTION_TYPE; import static com.eclipsesource.tabris.internal.Constants.PROPERTY_MODEL; import static com.eclipsesource.tabris.internal.Constants.PROPERTY_ORIENTATION; import static com.eclipsesource.tabris.internal.Constants.PROPERTY_OS_VERSION; import static com.eclipsesource.tabris.internal.Constants.PROPERTY_SCALE_FACTOR; import static com.eclipsesource.tabris.internal.Constants.PROPERTY_TIMEZONE_OFFSET; import static com.eclipsesource.tabris.internal.Constants.PROPERTY_VENDOR; import static com.eclipsesource.tabris.internal.Constants.TYPE_CLIENT_DEVICE; import java.util.ArrayList; import java.util.Collections; import java.util.Enumeration; import java.util.List; import java.util.Locale; import javax.servlet.http.HttpServletRequest; import org.eclipse.rap.json.JsonArray; import org.eclipse.rap.json.JsonObject; import org.eclipse.rap.json.JsonValue; import org.eclipse.rap.rwt.RWT; import org.eclipse.rap.rwt.internal.lifecycle.ProcessActionRunner; import org.eclipse.rap.rwt.internal.remote.ConnectionImpl; import org.eclipse.rap.rwt.internal.service.ContextProvider; import org.eclipse.rap.rwt.remote.AbstractOperationHandler; import org.eclipse.rap.rwt.remote.RemoteObject; import com.eclipsesource.tabris.device.ClientDevice; import com.eclipsesource.tabris.device.ClientDeviceListener; @SuppressWarnings("restriction") public class ClientDeviceImpl extends AbstractOperationHandler implements ClientDevice { private final RemoteObject remoteObject; private final List<ClientDeviceListener> clientDeviceListeners; private Locale[] locales; private Integer timezoneOffset; private ConnectionType connectionType; private Orientation orientation; private List<Capability> capabilities; private String vendor; private String model; private String osVersion; private float scaleFactor; public ClientDeviceImpl() { remoteObject = ( ( ConnectionImpl )RWT.getUISession().getConnection() ).createServiceObject( TYPE_CLIENT_DEVICE ); remoteObject.setHandler( this ); clientDeviceListeners = new ArrayList<ClientDeviceListener>(); readLocales(); } private void readLocales() { HttpServletRequest request = ContextProvider.getRequest(); if( request.getHeader( "Accept-Language" ) != null ) { Enumeration<Locale> locales = request.getLocales(); this.locales = Collections.list( locales ).toArray( new Locale[ 1 ] ); } } @Override public String getVendor() { return vendor; } @Override public String getModel() { return model; } @Override public String getOSVersion() { return osVersion; } @Override public float getScaleFactor() { return scaleFactor; } @Override public Platform getPlatform() { return DeviceUtil.getPlatform(); } @Override public void handleSet( JsonObject properties ) { setTimezoneOffset( properties ); setConnectionType( properties ); setCapabilities( properties ); setOrientation( properties ); setVendor( properties ); setModel( properties ); setOsVersion( properties ); setScaleFactor( properties ); } private void setTimezoneOffset( JsonObject properties ) { if( properties.get( PROPERTY_TIMEZONE_OFFSET ) != null ) { timezoneOffset = Integer.valueOf( properties.get( PROPERTY_TIMEZONE_OFFSET ).asInt() ); } } private void setConnectionType( JsonObject properties ) { if( properties.get( PROPERTY_CONNECTION_TYPE ) != null ) { connectionType = ConnectionType.valueOf( properties.get( PROPERTY_CONNECTION_TYPE ).asString() ); fireConnectionTypeChange(); } } private void setCapabilities( JsonObject properties ) { if( properties.get( PROPERTY_CAPABILITIES ) != null ) { setCapabilities( properties.get( PROPERTY_CAPABILITIES ).asArray() ); } } private void setOrientation( JsonObject properties ) { if( properties.get( PROPERTY_ORIENTATION ) != null ) { orientation = Orientation.valueOf( properties.get( PROPERTY_ORIENTATION ).asString() ); fireOrientationChange(); } } private void setVendor( JsonObject properties ) { if( properties.get( PROPERTY_VENDOR ) != null ) { vendor = properties.get( PROPERTY_VENDOR ).asString(); } } private void setModel( JsonObject properties ) { if( properties.get( PROPERTY_MODEL ) != null ) { model = properties.get( PROPERTY_MODEL ).asString(); } } private void setOsVersion( JsonObject properties ) { if( properties.get( PROPERTY_OS_VERSION ) != null ) { osVersion = properties.get( PROPERTY_OS_VERSION ).asString(); } } private void setScaleFactor( JsonObject properties ) { if( properties.get( PROPERTY_SCALE_FACTOR ) != null ) { scaleFactor = properties.get( PROPERTY_SCALE_FACTOR ).asFloat(); } } private void setCapabilities( JsonArray jsonArray ) { capabilities = new ArrayList<Capability>(); for( JsonValue capability : jsonArray ) { capabilities.add( Capability.valueOf( capability.asString() ) ); } } @Override public int getTimezoneOffset() { whenNull( timezoneOffset ).throwIllegalState( "timezoneOffset is not set." ); return timezoneOffset.intValue(); } @Override public Locale getLocale() { return locales == null ? null : locales[ 0 ]; } @Override public Locale[] getLocales() { return locales == null ? new Locale[ 0 ] : locales.clone(); } @Override public Orientation getOrientation() { whenNull( orientation ).throwIllegalState( "orientation is not set." ); return orientation; } @Override public boolean hasCapability( Capability capability ) { whenNull( capabilities ).throwIllegalState( "capabilities is not set." ); return capabilities.contains( capability ); } @Override public ConnectionType getConnectionType() { whenNull( connectionType ).throwIllegalState( "connectionType is not set." ); return connectionType; } @Override public void addClientDeviceListener( ClientDeviceListener listener ) { whenNull( listener ).throwIllegalArgument( "listener is not set." ); clientDeviceListeners.add( listener ); } @Override public void removeClientDeviceListener( ClientDeviceListener listener ) { whenNull( listener ).throwIllegalArgument( "listener is not set." ); clientDeviceListeners.remove( listener ); } private void fireOrientationChange() { ProcessActionRunner.add( new Runnable() { @Override public void run() { List<ClientDeviceListener> listeners = new ArrayList<ClientDeviceListener>( clientDeviceListeners ); for( ClientDeviceListener listener : listeners ) { listener.orientationChange( orientation ); } } } ); } private void fireConnectionTypeChange() { ProcessActionRunner.add( new Runnable() { @Override public void run() { List<ClientDeviceListener> listeners = new ArrayList<ClientDeviceListener>( clientDeviceListeners ); for( ClientDeviceListener listener : listeners ) { listener.connectionTypeChanged( connectionType ); } } } ); } }