I am doing one android application, for that I used com.android.internal API's. They are Call.java, CallManger.java. For these classes I created subclass for Call.java. You can find these two classes here http://hi-android.info/src/com/android/internal/telephony/Call.java.html and http://hi-android.info/src/com/android/internal/telephony/CallManager.java.html.
Subclass of Call.java is:
public class MyCall extends Call{
1. CallManager cm = CallManager.getInstance();
2. Phone.State state;
3.
4. Phone mDefaultPhone;
5. private final ArrayList<Connection> emptyConnections = new ArrayList<Connection>();
6. List<Call> ringingCall;
7.
8. #Override
9. public List<Connection> getConnections() {
10.
11.
12. state = cm.getState();
13. ringingCall = cm.getForegroundCalls();
14. System.out.println("**inside getConnections="+state);
15. System.out.println("**inside getConnections="+ringingCall);
16. if ( ringingCall == null) {
17.
18. System.out.println("**call is null***");
19. return emptyConnections;
20. }
21. else
22. {
23. System.out.println("**call is not null***");
24. return ((Call) ringingCall).getConnections();
}
}
#Override
public Phone getPhone() {
// TODO Auto-generated method stub
return null;
}
#Override
public void hangup() throws CallStateException {
// TODO Auto-generated method stub
}
#Override
public boolean isMultiparty() {
// TODO Auto-generated method stub
return false;
}
public Connection
getEarliestConnection() {
List l;
long time = Long.MAX_VALUE;
Connection c;
Connection earliest = null;
l = getConnections();
if (l == null) {
return null;
}else if ( l.size() == 0)
{
return null;
}
for (int i = 0, s = l.size() ; i < s ; i++) {
c = (Connection) l.get(i);
long t;
t = c.getCreateTime();
if (t < time) {
earliest = c;
time = t;
}
}
return earliest;
}
}
I called instance of CallManger Like this:
CallManager cm = CallManager.getInstance();
Bcoz this is a final modifier class. My another class is CallUpdate.java.
public class CallUpdate {
Call myCall = new MyCall();
Connection myConn = new MyConnection();
CallManager cm = CallManager.getInstance();
public Object getCallFailedString(){
myConn = myCall.getEarliestConnection();
System.out.println("myConn is ******"+myConn);
System.out.println("myCall is ******"+myCall);
if(myConn == null){
System.out.println("myConn is null ******");
return null;
}
else
{
Connection.DisconnectCause cause = myConn.getDisconnectCause();
System.out.println("myconn is not null ******"+cause);
}
}
I am getting myConn value is null. For this I added some piece of code in getConnection method of MyCall class to get a non-null value of myConn. i.e
state = cm.getState();
ringingCall = cm.getForegroundCalls();
System.out.println("**inside getConnections="+state);
System.out.println("**inside getConnections="+ringingCall);
if ( ringingCall == null) {
System.out.println("**call is null***");
return emptyConnections;
}
else
{
System.out.println("**call is not null***");
return ((Call) ringingCall).getConnections();
}
But it is throwing ClassCastException error on Line No:24 and on line
l = getConnections();.
And also I need at least one outgoing call to get a value of myConn. How to resolve this error?
Thx in advance.
ringingCall is a List<Call> - not a single call. You probably want something like:
if (ringingCall != null && !ringingCall.isEmpty()) {
Call call = ringingCall.get(0);
// Use call
}
... but you should also consider what you want to do if there's more than one call.
In general, if you find yourself casting that's because you think you know better than the compiler. It should always at least make you think - and in the case where you want a Call but you've got a List<Call>, the natural approach should be to use an element from the list.
It's not clear whether you really want to be subclassing Call in the first place, to be honest.
Related
Given the code below - how the readAllValuesFuture() method should be implemented?
Make a call and depending on the result of its Future:
either make the next call and pass the result of the previous one
or return an aggregated result of all previous calls.
package com.example.demo;
import org.junit.jupiter.api.Test;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
public class TestFuture
{
#Test
public void testReadAllValues() throws Exception
{
counter = 0;
var list = readAllValues();
assert list.size() == 10;
assert counter == 11;
}
#Test
public void testReadAllValuesFuture() throws Exception
{
counter = 0;
var list = readAllValuesFuture().get();
assert list.size() == 10;
assert counter == 11;
}
// Synchronous logic - plain and simple
private List<Integer> readAllValues()
{
List<Integer> list = new ArrayList<>();
Integer res = makeFirstRequest();
while (res != null)
{
list.add(res);
res = makeNextRequest(res);
}
return list;
}
// Futures - how to implement it?
private CompletableFuture<List<Integer>> readAllValuesFuture()
{
return CompletableFuture.failedFuture(new UnsupportedOperationException());
}
private int counter = 0;
// Assuming this is external code which cannot be changed
private Integer makeFirstRequest()
{
counter++;
return 0;
}
// Assuming this is external code which cannot be changed
private Integer makeNextRequest(Integer prevValue)
{
counter++;
if (++prevValue < 10)
{
return prevValue;
}
return null;
}
// Assuming this is external code which cannot be changed
private CompletableFuture<Integer> makeFirstRequestFuture()
{
counter++;
return CompletableFuture.completedFuture(0);
}
// Assuming this is external code which cannot be changed
private CompletableFuture<Integer> makeNextRequestFuture(Integer prevValue)
{
counter++;
if (++prevValue < 10)
{
return CompletableFuture.completedFuture(prevValue);
}
return CompletableFuture.completedFuture(null);
}
}
Real-life use-case:
Implement listAllTables() from the example below using DynamoDbAsyncClient (DynamoDbAsyncClient.listTables() returns CompletableFuture<ListTablesResponse> instead of ListTablesResponse as DynamoDbClient.listTables() does):
https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/examples-dynamodb-tables.html
One way to achieve this is via Stream.iterate:
var values = Stream.iterate(
makeFirstRequestFuture().get(),
Objects::nonNull,
previous -> {
try {
return makeNextRequestFuture(previous).get();
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException(e);
}
}
).toList();
I use it to check for null.DataSet has a structure of both String Integer and Bigdecimal data types.
How to shorten the condition code? Is there any way? To shorten my code. Thank you.
public void ConfrimData(DataSet data) {
if (StringUtils.isEmpty(data.getA())
|| StringUtils.isEmpty(data.getB())
|| StringUtils.isEmpty(data.getC())
|| StringUtils.isEmpty(data.getD())
|| StringUtils.isEmpty(data.getE())
|| StringUtils.isEmpty(data.getF())
){
if (StringUtils.isEmpty(data.getA())) {
loggerTransaction.info(Var.VALUE_A);
}
if (StringUtils.isEmpty(data.getB())) {
loggerTransaction.info(Var.VALUE_B);
}
if (StringUtils.isEmpty(data.getC())) {
loggerTransaction.info(Var.VALUE_C);
}
if (StringUtils.isEmpty(data.getD())) {
loggerTransaction.info(Var.VALUE_D);
}
if (StringUtils.isEmpty(data.getE())) {
loggerTransaction.info(Var.VALUE_E);
}
if (StringUtils.isEmpty(data.getF())) {
loggerTransaction.info(Var.VALUE_F);
}
return;
}
_DataSet
private String A = null;
private Integer B = null;
private String C= null;
private String D = null;
private BigDecimal E= null;
private String F= null;
Well, you could make it slightly less repeaty using streams, but it won't make it necessarily better, let alone faster:
LinkedHashMap<Supplier, String> map = new LinkedHashMap<>();
map.put(data::getA, Var.VALUE_A);
map.put(data::getB, Var.VALUE_B);
map.put(data::getC, Var.VALUE_C);
map.put(data::getD, Var.VALUE_D);
map.put(data::getE, Var.VALUE_E);
map.put(data::getF, Var.VALUE_F);
List<String> logMessages = map.entrySet().stream()
.filter(entry -> StringUtils.isEmpty(entry.getKey().get()))
.map(Map.Entry::getValue)
.collect(Collectors.toList());
if (!logMessages.isEmpty()) {
logMessages.forEach(loggerTransaction::info);
}
else {
// Remaining code
}
In your first if statement you check all the parameters to see if any of them are empty.
Then, in the inner if statements, you check them again. The first check is redundant. The return statement is also not necessary since it does not end the method early or returns any data.
Here is a shorter version that should give the same result:
public void confirmData(DataSet data) {
if (StringUtils.isEmpty(data.getA())) {
loggerTransaction.info(Var.VALUE_A);
}
if (StringUtils.isEmpty(data.getB())) {
loggerTransaction.info(Var.VALUE_B);
}
if (StringUtils.isEmpty(data.getC())) {
loggerTransaction.info(Var.VALUE_C);
}
if (StringUtils.isEmpty(data.getD())) {
loggerTransaction.info(Var.VALUE_D);
}
if (StringUtils.isEmpty(data.getE())) {
loggerTransaction.info(Var.VALUE_E);
}
if (StringUtils.isEmpty(data.getF())) {
loggerTransaction.info(Var.VALUE_F);
}
}
EDIT
Here is a slightly prettier solution with less code repetition:
public void confirmData(DataSet data) {
logIfEmpty(data.getA(), Var.VALUE_A);
logIfEmpty(data.getB(), Var.VALUE_B);
logIfEmpty(data.getC(), Var.VALUE_C);
logIfEmpty(data.getD(), Var.VALUE_D);
logIfEmpty(data.getE(), Var.VALUE_E);
logIfEmpty(data.getF(), Var.VALUE_F);
}
private void logIfEmpty(Object check, String log) {
if (StringUtils.isEmpty(check)) {
loggerTransaction.info(log);
}
}
EDIT #2
And if you have other code you want to execute if you did not find any empty values, you can do this:
public void confirmData(DataSet data) {
boolean foundEmpty;
foundEmpty = logIfEmpty(data.getA(), Var.VALUE_A);
foundEmpty = logIfEmpty(data.getB(), Var.VALUE_B) || foundEmpty;
foundEmpty = logIfEmpty(data.getC(), Var.VALUE_C) || foundEmpty;
foundEmpty = logIfEmpty(data.getD(), Var.VALUE_D) || foundEmpty;
foundEmpty = logIfEmpty(data.getE(), Var.VALUE_E) || foundEmpty;
foundEmpty = logIfEmpty(data.getF(), Var.VALUE_F) || foundEmpty;
if(foundEmpty) {
return;
}
}
private boolean logIfEmpty(String check, String log) {
if (StringUtils.isEmpty(check)) {
loggerTransaction.info(log);
return true;
}
return false;
}
Maybe assigning a flag...
public void ConfrimData(DataSet data) {
boolean flag;
if (flag = StringUtils.isEmpty(data.getA())) {
loggerTransaction.info(Var.VALUE_A);
}
if (flag = StringUtils.isEmpty(data.getB()) || flag) {
loggerTransaction.info(Var.VALUE_B);
}
if (flag = StringUtils.isEmpty(data.getC()) || flag) {
loggerTransaction.info(Var.VALUE_C);
}
if (flag = StringUtils.isEmpty(data.getD()) || flag) {
loggerTransaction.info(Var.VALUE_D);
}
if (flag = StringUtils.isEmpty(data.getE()) || flag) {
loggerTransaction.info(Var.VALUE_E);
}
if (flag = StringUtils.isEmpty(data.getF()) || flag) {
loggerTransaction.info(Var.VALUE_F);
}
if (flag) return;
I have a method to unit test called addSong(song,userId) in service class. I am calling three methods inside it from Dao class. I am using Easy mock to mock dao class. In the setup I first mock all the methods I am calling in addSong(song,userId), and then calling the service.addsong(song,userId) method fot test.
But I am getting the following error:
Java.lang.IllegalStateException: missing behavior definition for the preceding method call:
MusicPlayerDao.addSong(song)
Usage is: expect(a.foo()).andXXX()
at org.easymock.internal.MockInvocationHandler.invoke(MockInvocationHandler.java:42)
at org.easymock.internal.ObjectMethodsFilter.invoke(ObjectMethodsFilter.java:94)
at org.easymock.internal.ClassProxyFactory$MockMethodInterceptor.intercept(ClassProxyFactory.java:97)
at service.MusicPlayerDao$$EnhancerByCGLIB$$45bc3ca1.addSong(<generated>)
at service.MusicPlayerServiceImpl.addSong(MusicPlayerServiceImpl.java:43)
at AddSongTest.addSongs(AddSongTest.java:90)
Here is my code:
private void addSongSetup() throws SQLException{
this.album = new Album();
album.setAlbumName("album");
this.genre = new Genre();
genre.setGenreName("genre");
this.song = new Song("song",this.album,3,"artist","composer",this.genre);
EasyMock.expect(this.dao.addSong(song)).andReturn(1).anyTimes();
EasyMock.expect(this.dao.addGenre(genre, 1)).andReturn(1).anyTimes();
EasyMock.expect(this.dao.addAlbum(album, 1)).andReturn(1).anyTimes();
EasyMock.expect(this.dao.userIdSongsMapping(1,1)).andReturn(1).anyTimes();
}
#Test
public void addSongs(){
this.album = new Album();
album.setAlbumName("album");
this.genre = new Genre();
genre.setGenreName("genre");
this.song = new Song("song",this.album,3,"artist","composer",this.genre);
try {
System.out.println(this.dao.addSong(song));
boolean status = this.service.addSong(song, 1);
assertEquals(true,status);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
My addSong method in service class:
public boolean addSong(Song song, int userId) throws Exception {
MusicPlayerDaoInterface musicPlayerDao = MusicPlayerDao.getInstance();
boolean status = false;
int songId = 0;
TransactionManager transactionManager = TransactionManagerImpl
.getInstance();
try {
if (song != null) {
if (song.getTitle() != null) {
transactionManager.begin();
songId = musicPlayerDao.addSong(song);
song.setSongId(songId);
if (song.getGenre() != null
&& song.getGenre().getGenreName() != null) {
musicPlayerDao.addGenre(song.getGenre(),
song.getSongId());
}
if (song.getAlbum() != null
&& song.getAlbum().getAlbumName() != null) {
musicPlayerDao.addAlbum(song.getAlbum(),
song.getSongId());
}
if (userId != 0 && songId != 0) {
musicPlayerDao.userIdSongsMapping(userId,
song.getSongId());
}
transactionManager.commit();
status = true;
}
}
} catch (SQLException | RollbackException | HeuristicMixedException
| HeuristicRollbackException e) {
transactionManager.rollback();
status = false;
throw e;
}
return status;
}
I don't know were I am going wrong. Please help.
I think you are missing a EasyMock.replay statement after you record the expected behaviour. Something like
EasyMock.replay(this.dao);
From the EasyMock guide:
To get a Mock Object, we need to
create a Mock Object for the interface we would like to simulate
record the expected behavior
switch the Mock Object to replay state
try removing the following lines from the addSongs test case:
this.album = new Album();
album.setAlbumName("album");
this.genre = new Genre();
genre.setGenreName("genre");
this.song = new Song("song",this.album,3,"artist","composer",this.genre);
I assume that addSongSetup is invoked before addSongs (e.g.; #Before). You are reassigning values to your variables album, genre and song in addSong, which, I suppose, EasyMock cannot match to your mock setup in addSongSetup as (depending on how EasyMock implemented this)
you forgot to implement hashcode or equals in Song, Album, Genre or,
EasyMock uses Object identity (i.e., reference comparison)
I guess it's 1.
Scenario:
final CatalogRuleExample example = new CatalogRuleExample();
example.createCriteria().andCatalogIdEqualTo(catalogId);
example.setOrderByClause("position ASC");
final List<CatalogRuleRecord> records = new ArrayList<CatalogRuleRecord>();
final CatalogRuleRecord firstRecord = new CatalogRuleRecord();
final CatalogRuleRecord secondRecord = new CatalogRuleRecord();
records.add(firstRecord);
records.add(secondRecord);
mockery.checking(new Expectations() {
{
oneOf(catalogRuleDAO).selectByExample(example);
will(returnValue(records));
...
Problem:
The final example of CatalogRuleExample is not the same in my mockery.checking by selectByExample. If i override the equals() it will work. But i wanted to know, if there is a better solution for this case. Thanks in advance
PS: this same code worked bevor i migrate from Ibatis to Mybtis
final CatalogRuleExample example = new CatalogRuleExample() {
#Override
public boolean equals(Object that) {
if (that instanceof CatalogRuleExample) {
CatalogRuleExample other = (CatalogRuleExample) that;
if (other.getOredCriteria().size() != 1) {
return false;
}
if (other.getOredCriteria().get(0).getCriteria().size() != 1) {
return false;
}
if (!other.getOredCriteria().get(0).getCriteria().get(0).getValue().equals(catalogId)) {
return false;
}
if (!other.getOrderByClause().equals("position ASC")) {
return false;
}
return true;
}
return false;
}
};
ERROR:
unexpected invocation: catalogRuleDAO.selectByExample(<com.protogo.persistence.dao.CatalogRuleExample#a6ca0ea9>)
expectations:
expected once, never invoked: catalogRuleDAO.selectByExample(<com.protogo.persistence.dao.CatalogRuleExample#66e1beb1>); returns <[com.protogo.persistence.data.CatalogRuleRecord#4f7d02c2, com.protogo.persistence.data.CatalogRuleRecord#4f7d02c2]>
My code throwing java.lang.ClassCastException exception error, Why this error will get?. I am using com.android.internal.telephony API's. i.e You can find classes I am using here Call.java<http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/1.5_r4/com/android/internal/telephony/Call.java>, CallManger.java <http://hi-android.info/src/com/android/internal/telephony/CallManager.java.html> I have created a Subclaas of Call.java like this:
public class MyCall extends Call{
CallManager cm = CallManager.getInstance();
Phone.State state;
Connection c;
Phone mDefaultPhone;
private final ArrayList<Connection> emptyConnections = new ArrayList<Connection>();
MyCall ringingCall;
#Override
public List<Connection> getConnections() {
state = cm.getState();
ringingCall = (MyCall) cm.getRingingCalls();
System.out.println("**inside getConnections="+ringingCall);
if ( ringingCall != null && !ringingCall.isIdle()) {
System.out.println("**call is not null***");
return ((MyCall) ringingCall).getConnections();
}
else
{
System.out.println("**list is null***");
return emptyConnections;
}
}
#Override
public Phone getPhone() {
// TODO Auto-generated method stub
return null;
}
#Override
public void hangup() throws CallStateException {
// TODO Auto-generated method stub
}
#Override
public boolean isMultiparty() {
// TODO Auto-generated method stub
return false;
}
public Connection
getEarliestConnection() {
System.out.println("inside EarliestConnection");
List l;
long time = Long.MAX_VALUE;
Connection c;
Connection earliest = null;
l = getConnections();
if (l == null) {
return null;
}else if ( l.size() == 0)
{
return null;
}
System.out.println("value of connection is=="+l);
for (int i = 0, s = l.size() ; i < s ; i++) {
c = (Connection) l.get(i);
long t;
t = c.getCreateTime();
if (t < time) {
earliest = c;
time = t;
}
}
return earliest;
}
}
I called CallManger.java like this in my own class
CallManager cm = CallManager.getInstance();
My another class is CallUpdate, it should give me a OutgoingCall states (i.e other side phone is Busy, Power-off, not-reachable etc.) The code is like this:
public class CallUpdate {
Call myCall = new MyCall();
Connection myConn = new MyConnection();
CallManager cm = CallManager.getInstance();
public Object getCallFailedString(){
myConn = myCall.getEarliestConnection();
System.out.println("myConn is ******"+myConn);
System.out.println("myCall is ******"+myCall);
if(myConn == null){
System.out.println("myConn is null ******");
return null;
}
else
{
Connection.DisconnectCause cause = myConn.getDisconnectCause();
System.out.println("myconn is not null ******"+cause);
switch(cause){
case BUSY :
System.out.println("inside busy");
break;
case NUMBER_UNREACHABLE :
System.out.println("inside un-reachable");
break;
case POWER_OFF :
System.out.println("inside power off");
break;
}
}
return myConn;
}
I called this class in BroadCastReceiver(). But i am getting connection is null. My code is not getting inside else part. So that I added some code in getConnection method of MyCall class like this:
public List<Connection> getConnections() {
state = cm.getState();
ringingCall = (MyCall) cm.getRingingCalls();
System.out.println("**inside getConnections="+ringingCall);
if ( ringingCall != null && !ringingCall.isIdle()) {
System.out.println("**call is not null***");
return ((MyCall) ringingCall).getConnections();
}
else
{
System.out.println("**list is null***");
return emptyConnections;
}
}
But I am getting java.lang.ClassCastException: on Line:
ringingCall = (MyCall) cm.getRingingCalls();
And also on l = getConnection();
How to solve this ??
Thx in advance.
Change your code as below
List<MyCall> ringingCall = cm.getRingingCalls();
I believe your cm.getRingingCalls(); returning ArrayList of Call / MyCall
getRingingCalls returns a List<Call> i.e. a list of Call objects. You're trying to cast it to a single MyCall, instead of a List, so you get a ClassCastException.
You need to correct your type to a List:
List<MyCall> ringingCall;
ringingCall = cm.getRingingCalls();
or, use the first element in the list:
MyCall ringingCall;
if(!cm.getRingingCalls().isEmpty()){
ringingCall = cm.getRingingCalls().get(0);
}