/**
* Copyright 2014 Comcast Cable Communications Management, LLC
*
* This file is part of CATS.
*
* CATS is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CATS is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with CATS. If not, see <http://www.gnu.org/licenses/>.
*/
package com.comcast.cats.provider;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.jboss.resteasy.client.ProxyFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.comcast.cats.RemoteCommand;
import com.comcast.cats.RemoteCommandShortcutResolver;
import com.comcast.cats.RemoteLayout;
import com.comcast.cats.info.RemoteCommandSequence;
import com.comcast.cats.keymanager.domain.Remote;
import com.comcast.cats.service.IR;
/**
* This class implements REST based provider for IR service. This makes use of
* resteasy client provided by jboss.
*
* @author nishapk
*
*/
public class RemoteRest implements RemoteProvider
{
/**
* Local variables
*/
private static final long serialVersionUID = 1L;
private Logger logger = LoggerFactory.getLogger( RemoteRest.class );
private IR irRest;
private Object parent;
private String type;
private String keySet;
private URI irURI;
private boolean autoTuneEnabled = false;
private Integer delay = 0;
/**
* RemoteRest constructor which takes the service URL as one of the inputs
*
* @param irServiceURL
* @param host
* @param port
* @param type
* @param keySet
* @throws URISyntaxException
*/
public RemoteRest( String irServiceURL, String host, Integer port, String type, String keySet )
throws URISyntaxException
{
irServiceURL = irServiceURL + type + "/" + host + "/" + port;
logger.info( "[IR Service REST URL][" + irServiceURL + "]" );
this.irRest = ProxyFactory.create( IR.class, irServiceURL );
this.type = type;
this.keySet = keySet;
this.irURI = new URI( type + "://" + host + "/?port=" + port );
}
/**
* RemoteRest constructor which takes the REST interface as one of the
* inputs
*
* @param irServiceURL
* @param host
* @param port
* @param type
* @param keySet
* @throws URISyntaxException
*/
public RemoteRest( IR irRest, String host, Integer port, String type, String keySet ) throws URISyntaxException
{
this( irRest, host, port, type, keySet, null );
}
/**
* RemoteRest constructor
*
* @param irServiceURL
* @param host
* @param port
* @param type
* @param keySet
* @throws URISyntaxException
*/
public RemoteRest( IR irRest, String host, Integer port, String type, String keySet, Object parent )
throws URISyntaxException
{
this.irRest = irRest;
this.type = type;
this.keySet = keySet;
this.irURI = new URI( type + "://" + host + "/?port=" + port );
this.parent = parent;
}
/**
* This method suggests whether a delay is required or not.
*
* @return boolean
*/
private boolean mustDelay()
{
return ( delay > 0 );
}
/**
* This method sleeps as per the condition provided as input.
*
* @param condition
* - boolean
* @return boolean
*/
private boolean sleepOnTrue( boolean condition )
{
if ( condition && mustDelay() )
{
sleep( this.delay );
}
return condition;
}
/**
* This method is called by sleepOnTrue to actually do the sleep function.
*
* @param delay
*/
protected void sleep( int delay )
{
try
{
Thread.sleep( delay );
}
catch ( InterruptedException e )
{
logger.warn( "Interrupted during sleep operation." );
}
}
/**
* Check whether the delay provided is within the allowed range.
*
* @param delay
*/
protected void verifyDelay( int delay )
{
if ( delay < 0 || delay > MAX_DELAY )
{
throw new IllegalArgumentException( "Remote delay must be 0 >= delay <= " + MAX_DELAY );
}
}
/**
* This method takes a list of Remote commands, list of repeat counts and
* list of delays between each remote command.
*
* @see com.comcast.cats.provider.RemoteProvider#enterCustomKeySequence(java.util.List,
* java.util.List, java.util.List)
*/
@Override
public boolean enterCustomKeySequence( List< RemoteCommand > commands, List< Integer > repeatCount,
List< Integer > delay )
{
String commandStr = "";
for ( RemoteCommand command : commands )
{
commandStr = commandStr + "," + command.name();
}
String delayStr = "";
for ( Integer delayInt : delay )
{
delayStr = delayStr + "," + delayInt;
}
String countStr = "";
for ( Integer cnt : repeatCount )
{
countStr = countStr + "," + cnt;
}
return sleepOnTrue( irRest.enterCustomKeySequence( keySet, commandStr, delayStr, countStr ) );
}
/**
* This method takes a list of remote command sequences.
*
* @see com.comcast.cats.provider.RemoteProvider#enterRemoteCommandSequence(java.util.List)
*/
@Override
public boolean enterRemoteCommandSequence( List< RemoteCommandSequence > commands )
{
List< String > commandList = new ArrayList< String >();
for ( RemoteCommandSequence remCommand : commands )
{
String command = remCommand.getCommand().name();
command = command + "," + remCommand.getRepeatCount();
command = command + "," + remCommand.getDelay();
commandList.add( command );
}
return sleepOnTrue( irRest.enterRemoteCommandSequence( keySet, commandList ) );
}
/**
* This method lists all the remote types available
*
* @see com.comcast.cats.provider.RemoteProvider#getAllRemoteTypes()
*/
@Override
public List< String > getAllRemoteTypes()
{
List< Remote > remotes = irRest.getRemotes();
List< String > remoteTypes = new ArrayList< String >();
for ( Remote remote : remotes )
{
remoteTypes.add( remote.getName() );
}
return remoteTypes;
}
/**
* Getter method for delay
*
* @see com.comcast.cats.provider.RemoteProvider#getDelay()
*/
@Override
public Integer getDelay()
{
return this.delay;
}
/**
* Getter method for remote locator
*
* @see com.comcast.cats.provider.RemoteProvider#getRemoteLocator()
*/
@Override
public URI getRemoteLocator()
{
return this.irURI;
}
/**
* Getter method for remote type
*
* @see com.comcast.cats.provider.RemoteProvider#getRemoteType()
*/
@Override
public String getRemoteType()
{
return this.type;
}
/**
* Getter method for valid keys
*
* @see com.comcast.cats.provider.RemoteProvider#getValidKeys()
*/
@Override
public List< RemoteLayout > getValidKeys()
{
throw new UnsupportedOperationException( "getValidKeys not supported yet." );
}
/**
* Check whether auto tune is enabled
*
* @see com.comcast.cats.provider.RemoteProvider#isAutoTuneEnabled()
*/
@Override
public boolean isAutoTuneEnabled()
{
return this.autoTuneEnabled;
}
/**
* This method does the pressKey for a particular command
*
* @see com.comcast.cats.provider.RemoteProvider#pressKey(com.comcast.cats.RemoteCommand)
*/
@Override
public boolean pressKey( RemoteCommand command )
{
return sleepOnTrue( irRest.pressKey( keySet, command.toString() ) );
}
/**
* This method does the pressKey for a particular command with a specific
* delay
*
* @see com.comcast.cats.provider.RemoteProvider#pressKey(com.comcast.cats.RemoteCommand,java.lang.Integer)
*/
@Override
public boolean pressKey( RemoteCommand command, Integer delay )
{
setDelay( delay );
return sleepOnTrue( irRest.pressKey( keySet, command.toString() ) );
}
/**
* This method does the pressKey for a particular command with a repeat
* count
*
* @see com.comcast.cats.provider.RemoteProvider#pressKey(java.lang.Integer,com.comcast.cats.RemoteCommand)
*/
@Override
public boolean pressKey( Integer count, RemoteCommand command )
{
boolean returnValue = true;
for ( int index = 0; index < count; index++ )
{
returnValue = sleepOnTrue( irRest.pressKey( keySet, command.toString() ) );
if ( !returnValue )
{
break;
}
}
return returnValue;
}
/**
* This method does the pressKey for a particular command with a repeat
* count and delay
*
* @see com.comcast.cats.provider.RemoteProvider#pressKey(java.lang.Integer,com.comcast.cats.RemoteCommand,java.lang.Integer)
*/
@Override
public boolean pressKey( Integer count, RemoteCommand command, Integer delay )
{
boolean returnValue = true;
setDelay( delay );
for ( int index = 0; index < count; index++ )
{
returnValue = sleepOnTrue( irRest.pressKey( keySet, command.toString() ) );
if ( !returnValue )
{
break;
}
}
return returnValue;
}
/**
* This method does the pressKey for a particular array of commands with a
* repeat count and delay
*
* @see com.comcast.cats.provider.RemoteProvider#pressKey(java.lang.Integer,
* java.lang.Integer, com.comcast.cats.RemoteCommand[])
*/
@Override
public boolean pressKey( Integer count, Integer delay, RemoteCommand[] commands )
{
boolean returnValue = false;
for ( int index = 0; index < count; index++ )
{
returnValue = pressKeys( Arrays.asList( commands ), delay );
}
return returnValue;
}
/**
* This method does the pressKey for a set of commands.
*
* @see com.comcast.cats.provider.RemoteProvider#pressKey(com.comcast.cats.RemoteCommand[])
*/
@Override
public boolean pressKey( RemoteCommand[] commands )
{
return pressKeys( Arrays.asList( commands ) );
}
/**
* This method does the pressKey for an integer command
*
* @see com.comcast.cats.provider.RemoteProvider#pressKey(java.lang.Integer)
*/
@Override
public boolean pressKey( Integer command )
{
return sleepOnTrue( irRest.pressKey( keySet, String.valueOf( command ) ) );
}
/**
* This method does the pressKey for a command and holds it for count time.
*
* @see com.comcast.cats.provider.RemoteProvider#pressKeyAndHold(com.comcast.cats.RemoteCommand,
* java.lang.Integer)
*/
@Override
public boolean pressKeyAndHold( RemoteCommand command, Integer count )
{
return irRest.pressKeyAndHold( keySet, command.toString(), String.valueOf( count ) );
}
/**
* This method does the pressKeys for a list of remote commands.
*
* @see com.comcast.cats.provider.RemoteProvider#pressKeys(java.util.List)
*/
@Override
public boolean pressKeys( List< RemoteCommand > commands )
{
String commandStr = "";
for ( RemoteCommand command : commands )
{
commandStr = commandStr + "," + command.name();
}
return sleepOnTrue( irRest.pressKeys( keySet, commandStr, 0 ) );
}
/**
* This method does the pressKey for a list of commands with a given delay
* between the commands.
*
* @see com.comcast.cats.provider.RemoteProvider#pressKeys(java.util.List,
* java.lang.Integer)
*/
@Override
public boolean pressKeys( List< RemoteCommand > commands, Integer delay )
{
String commandStr = "";
for ( RemoteCommand command : commands )
{
commandStr = commandStr + "," + command.name();
}
return sleepOnTrue( irRest.pressKeys( keySet, commandStr, delay ) );
}
/**
* This method sends text. Note that the text has to be a numeric string.
*
* @see com.comcast.cats.provider.RemoteProvider#sendText(java.lang.String)
*/
@Override
public boolean sendText( String text )
{
return irRest.sendText( keySet, text );
}
/**
* Setter method for auto tune enable
*
* @see com.comcast.cats.provider.RemoteProvider#setAutoTuneEnabled(boolean)
*/
@Override
public void setAutoTuneEnabled( boolean autoTuneEnabled )
{
this.autoTuneEnabled = autoTuneEnabled;
}
/**
* Setter method for delay
*
* @see com.comcast.cats.provider.RemoteProvider#setDelay(java.lang.Integer)
*/
@Override
public void setDelay( Integer delay )
{
verifyDelay( delay );
this.delay = delay;
}
/**
* Setter method for remote type
*
* @see com.comcast.cats.provider.RemoteProvider#setRemoteType(java.lang.String)
*/
@Override
public void setRemoteType( String remoteType )
{
this.type = remoteType;
}
/**
* This method tunes the channel (given in string format)
*
* @see com.comcast.cats.provider.RemoteProvider#tune(java.lang.String)
*/
@Override
public boolean tune( String channel )
{
return irRest.tune( keySet, channel, String.valueOf( autoTuneEnabled ), String.valueOf( delay ) );
}
/**
* This method tunes the channel (given in integer format)
*
* @see com.comcast.cats.provider.RemoteProvider#tune(java.lang.Integer)
*/
@Override
public boolean tune( Integer channel )
{
return irRest.tune( keySet, String.valueOf( channel ), String.valueOf( autoTuneEnabled ),
String.valueOf( delay ) );
}
/**
* Getter method for parent object
*
* @see com.comcast.cats.provider.BaseProvider#getParent()
*/
@Override
public Object getParent()
{
return parent;
}
/**
* This method is to send the IR code. Note that the code is sent as the
* payload of the REST request.
*
* @param irCode
* - the raw IR code string
* @return true/false
*/
public boolean sendIR( String irCode )
{
return irRest.sendIR( irCode );
}
@Override
public boolean performShorthandCommandSequence( String text )
{
return performShorthandCommandSequence( text, 500 );
}
@Override
public boolean performShorthandCommandSequence( String text, Integer delay )
{
boolean returnVal = false;
if ( !( null == text || text.isEmpty() ) )
{
char[] chars = text.toCharArray();
List< RemoteCommand > commands = new ArrayList< RemoteCommand >();
for ( char character : chars )
{
commands.add( RemoteCommandShortcutResolver.resolveRemoteCommand( character ) );
}
logger.info( "sendText : commands:" + commands );
returnVal = pressKeys( commands, delay );
}
return returnVal;
}
}