import java.util.*;
import java.lang.*;
import java.io.*;
class TestFailedException
extends Exception { }
class OtherTypeIDoNotOwn {
public void doD
() { System.
out.
println("doD"); } public String doE
() { System.
out.
println("doE"); return "doE"; } public OtherTypeIDoNotOwn doF
(String string
) {System.
out.
println("doF"); return new OtherTypeIDoNotOwn
();}
}
class IDoNotOwnThisType {
public void doA
(String string
) { System.
out.
println("doA"); } public String doB
() {System.
out.
println("doB"); return "doB";} public OtherTypeIDoNotOwn doC
() {System.
out.
println("doC"); return new OtherTypeIDoNotOwn
();}
}
interface OperationManipulator {
void beforeOperation(); //called before operation
void handleSuccess(); //called after success
void handleSoftFailure
(Exception e
); //called after every failure in every try void handleFailure
(Exception e
) throws TestFailedException
; //called after reaching time limit
}
interface IWrapper<T extends IType> extends OperationManipulator {
public void doA
(String string
) throws TestFailedException
; public String doB
() throws TestFailedException
; public T doC() throws TestFailedException;
}
interface IType<T extends IType> extends OperationManipulator {
public void doD() throws TestFailedException;
public String doE
() throws TestFailedException
; public T doF
(String string
) throws TestFailedException
;
}
abstract class AType<T extends IType> implements IType{
Object element
; // I do not own type of this object, cant modify it. Class typeClass;
long TIMEOUT = 5000;
long WAIT_FOR_NEXT_TRY = 100;
public AType
(Object element
) { this.element = element;
typeClass = this.getClass();
}
@Override
public void doD() throws TestFailedException {
long startTime
= System.
currentTimeMillis(); while (true) {
try {
beforeOperation();
((OtherTypeIDoNotOwn) element).doD();
handleSuccess();
break;
handleSoftFailure(e);
if (System.
currentTimeMillis() - startTime
> TIMEOUT
) { handleFailure(e);
break;
} else {
try {
Thread.
sleep(WAIT_FOR_NEXT_TRY
); }
}
}
}
}
@Override
public String doE
() throws TestFailedException
{ long startTime
= System.
currentTimeMillis(); while (true) {
try {
beforeOperation();
result = ((OtherTypeIDoNotOwn) element).doE();
handleSuccess();
break;
handleSoftFailure(e);
if (System.
currentTimeMillis() - startTime
> TIMEOUT
) { handleFailure(e);
break;
} else {
try {
Thread.
sleep(WAIT_FOR_NEXT_TRY
); }
}
}
}
return result;
}
@Override
public T doF
(String string
) throws TestFailedException
{ T result = null;
long startTime
= System.
currentTimeMillis(); while (true) {
try {
beforeOperation();
OtherTypeIDoNotOwn temp = ((OtherTypeIDoNotOwn) element).doF(string);
result
= (T
) typeClass.
getDeclaredConstructor(Object.
class).
newInstance(temp
); handleSuccess();
break;
handleSoftFailure(e);
if (System.
currentTimeMillis() - startTime
> TIMEOUT
) { handleFailure(e);
break;
} else {
try {
Thread.
sleep(WAIT_FOR_NEXT_TRY
); }
}
}
}
return result;
}
}
abstract class AWrapper<T extends IType> implements IWrapper{
Object element
; // I do not own type of this object, cant modify it. Class typeClass;
long TIMEOUT = 5000;
long WAIT_FOR_NEXT_TRY = 100;
public AWrapper
(Object element,
Class typeClass
) { this.element = element;
this.typeClass = typeClass;
}
@Override
public void doA
(String string
) throws TestFailedException
{ long startTime
= System.
currentTimeMillis(); while (true) {
try {
beforeOperation();
((IDoNotOwnThisType) element).doA(string);
handleSuccess();
break;
handleSoftFailure(e);
if (System.
currentTimeMillis() - startTime
> TIMEOUT
) { handleFailure(e);
break;
} else {
try {
Thread.
sleep(WAIT_FOR_NEXT_TRY
); }
}
}
}
}
@Override
public String doB
() throws TestFailedException
{ long startTime
= System.
currentTimeMillis(); while (true) {
try {
beforeOperation();
result = ((IDoNotOwnThisType) element).doB();
handleSuccess();
break;
handleSoftFailure(e);
if (System.
currentTimeMillis() - startTime
> TIMEOUT
) { handleFailure(e);
break;
} else {
try {
Thread.
sleep(WAIT_FOR_NEXT_TRY
); }
}
}
}
return result;
}
@Override
public T doC() throws TestFailedException {
T result = null;
long startTime
= System.
currentTimeMillis(); while (true) {
try {
beforeOperation();
OtherTypeIDoNotOwn temp = ((IDoNotOwnThisType) element).doC();
result
= (T
) typeClass.
getDeclaredConstructor(Object.
class).
newInstance(temp
); handleSuccess();
break;
handleSoftFailure(e);
if (System.
currentTimeMillis() - startTime
> TIMEOUT
) { handleFailure(e);
break;
} else {
try {
Thread.
sleep(WAIT_FOR_NEXT_TRY
); }
}
}
}
return result;
}
}
class AssertingType extends AType<AssertingType> {
public AssertingType
(Object element
) { super(element);
}
@Override
public void beforeOperation() {
System.
out.
println("Asserting type before operation!"); }
@Override
public void handleSuccess() {
//TODO: add to log file and log to output
System.
out.
println("Asserting type success!"); }
@Override
public void handleFailure
(Exception e
) throws TestFailedException
{ //TODO: add to log file, log to output and throw exception
System.
out.
println("Asserting type failure!"); e.printStackTrace();
throw new TestFailedException();
}
@Override
//TODO: add to log file, log to output
System.
out.
println("Asserting type soft failure!"); e.printStackTrace();
}
}
class AssertingWrapper extends AWrapper<AssertingType> {
public AssertingWrapper
(Object driver
) { super(driver, AssertingType.class);
}
@Override
public void beforeOperation() {
//TODO
System.
out.
println("Asserting wrapper before operation!"); }
@Override
public void handleSuccess() {
//TODO: add to log file and log to output
System.
out.
println("Asserting wrapper success!"); }
@Override
public void handleFailure
(Exception e
) throws TestFailedException
{ //TODO: add to log file, log to output and throw exception
System.
out.
println("Asserting wrapper failure!"); throw new TestFailedException();
}
@Override
//TODO: add to log file, log to output
System.
out.
println("Asserting wrapper soft failure!"); e.printStackTrace();
}
}
class Ideone {
public static void main
(String[] args
) throws TestFailedException
{
AssertingWrapper wrapper = new AssertingWrapper(new IDoNotOwnThisType());
AssertingType type = wrapper.doC();
AssertingType type2 = type.doF("arg");
}
}