How to handle design errors in a Custom Control in XPages? - error-handling

In a custom control there is this repeat control that refers to a column in a folder (not a view). The folder's default design can be changed in time, in combination with the custom control. So it could happen that the code of the custom control is newer than the design of the folder, and hence the design doesn't match and the XPage errors out.
What I specifically want is that the custom control handles errors related to a missing view/folder column or similar design errors. The error is to be reported somewhere, informing the user that he/she can activate something that will repair the situation.
I know how to trap JavaScript errors, unfortunately all column values are in Expression Language. I could recode them, of course, but I'd like to know if there's a better way.
In short: how can I trap Expression Language errors?

You can trap EL language errors by adding your own VariableResolverand your own PropertyResolver. To do this, you have to create two Java classes:
The Variable resolver
package ch.hasselba.xpages.demo;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.el.EvaluationException;
import javax.faces.el.VariableResolver;
public class ELErrVariableResolver extends VariableResolver {
private final VariableResolver delegate;
public ELErrVariableResolver(VariableResolver resolver) {
delegate = resolver;
}
#Override
public Object resolveVariable(FacesContext context, String name) throws EvaluationException {
Object variable = null;
try{
variable = delegate.resolveVariable(context, name);
}catch( EvaluationException ee ){
addResolveErrMessage( context, name );
}
return variable;
}
public void addResolveErrMessage( FacesContext context , String name ){
FacesMessage msg = new FacesMessage();
msg.setSummary( "BAD EL! Variable '" + name + "' not found." );
msg.setSeverity( FacesMessage.SEVERITY_FATAL );
context.addMessage("BAD EL!", msg);
}
}
The Property resolver
package ch.hasselba.xpages.demo;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.el.EvaluationException;
import javax.faces.el.PropertyNotFoundException;
import javax.faces.el.PropertyResolver;
public class ELErrPropertyResolver extends PropertyResolver{
private final PropertyResolver delegate;
public ELErrPropertyResolver(PropertyResolver resolver) {
delegate = resolver;
}
#Override
public Class getType(Object paramObject1, Object paramObject2)
throws EvaluationException, PropertyNotFoundException {
Class c = null;
try{
c = delegate.getType(paramObject1, paramObject2);
}catch(Exception e){
addResolveErrMessage( FacesContext.getCurrentInstance(), paramObject1.toString() + "." + paramObject2.toString() );
}
return c;
}
#Override
public Class getType(Object paramObject, int paramInt)
throws EvaluationException, PropertyNotFoundException {
Class c = null;
try{
c = delegate.getType(paramObject, paramInt);
}catch(Exception e){
addResolveErrMessage( FacesContext.getCurrentInstance(), paramObject.toString() + "." + paramInt );
}
return c;
}
#Override
public Object getValue(Object paramObject1, Object paramObject2)
throws EvaluationException, PropertyNotFoundException {
Object c = null;
try{
c = delegate.getValue(paramObject1, paramObject2);
}catch(Exception e){
addResolveErrMessage( FacesContext.getCurrentInstance(), paramObject1.toString() + "." + paramObject2.toString() );
}
return c;
}
#Override
public Object getValue(Object paramObject, int paramInt)
throws EvaluationException, PropertyNotFoundException {
Object c = null;
try{
c = delegate.getValue(paramObject, paramInt);
}catch(Exception e){
addResolveErrMessage( FacesContext.getCurrentInstance(), paramObject.toString() + "." + paramInt );
}
return c;
}
#Override
public boolean isReadOnly(Object paramObject1, Object paramObject2)
throws EvaluationException, PropertyNotFoundException {
boolean c = false;
try{
c = delegate.isReadOnly(paramObject1, paramObject2);
}catch(Exception e){
addResolveErrMessage( FacesContext.getCurrentInstance(), paramObject1.toString() + "." + paramObject2.toString() );
}
return c;
}
#Override
public boolean isReadOnly(Object paramObject, int paramInt)
throws EvaluationException, PropertyNotFoundException {
boolean c = false;
try{
c = delegate.isReadOnly(paramObject, paramInt);
}catch(Exception e){
addResolveErrMessage( FacesContext.getCurrentInstance(), paramObject.toString() + "." + paramInt );
}
return c;
}
#Override
public void setValue(Object paramObject1, Object paramObject2,
Object paramObject3) throws EvaluationException,
PropertyNotFoundException {
try{
delegate.setValue(paramObject1, paramObject2, paramObject3);
}catch(Exception e){
addResolveErrMessage( FacesContext.getCurrentInstance(), paramObject1.toString() + "." + paramObject2.toString() );
}
}
#Override
public void setValue(Object paramObject1, int paramInt, Object paramObject2)
throws EvaluationException, PropertyNotFoundException {
try{
delegate.setValue(paramObject1, paramInt, paramObject2);
}catch(Exception e){
addResolveErrMessage( FacesContext.getCurrentInstance(), paramObject1.toString() + "." + paramInt );
}
}
public void addResolveErrMessage( FacesContext context , String name ){
FacesMessage msg = new FacesMessage();
msg.setSummary( "BAD EL! Property '" + name + "' not found." );
msg.setSeverity( FacesMessage.SEVERITY_FATAL );
context.addMessage("BAD EL!", msg);
}
}
Add the new resolvers to your faces-config.xml:
<?xml version="1.0" encoding="UTF-8"?>
<faces-config>
<application>
<variable-resolver>ch.hasselba.xpages.demo.ELErrVariableResolver
</variable-resolver>
<property-resolver>ch.hasselba.xpages.demo.ELErrPropertyResolver
</property-resolver>
</application>
</faces-config>
On your CC add a xp:messages component to display your message (or change the error routine in the classes to add whatever you want.

In the custom control you can check if the folder/view you are going to work with is correct. Aka has the correct design. This can be done in the beforepageload event. When the design check reports an error it should be written to a log file and a 'nice' message should be displayed to the user.
The error logging could be done with the various logging projects on openntf like xlogger
When your code reports an error you can than set a scoped value called 'displayRepeat' to false. The repeat control ( and other controls ) should be rendered according to this displayRepeat value.
To display the nice error message to the user. Place a errors control on the top of your control and add the following code:
facesContext.addMessage( null,
new javax.faces.application.FacesMessage( "your error message" ) );

Related

C3P0, rawConnectionOperation() & java.lang.IllegalArgumentException

I am attempting to use a non-standard method, getServerJobIdentifier(), that is part of the IBM Java Tool Box (jt400.jar) and class com.ibm.as400.access.AS400JDBCConnection with C3P0 & rawConnectionOperation(). I am getting "java.lang.IllegalArgumentException: object is not an instance of declaring class". I have tried numerous options but have not stumbled upon the correct parameters to pass. I am using C3P0 0.9.5.4. Code snippet follows:
// The method I want to call.
// getServerJobIdentifier, public abstract java.lang.String com.ibm.as400.access.AS400JDBCConnection.getServerJobIdentifier()
String driverClassName = "com.ibm.as400.access.AS400JDBCDriver";
String m_DatabaseConnectionString = "jdbc:db2:*local;naming=sql;extended metadata=true";
Connection m_dbConnection;
ComboPooledDataSource m_cpds;
m_cpds = new ComboPooledDataSource();
try {
m_cpds.setDriverClass(driverClassName); //loads the jdbc driver
}
catch (Exception e) {
e.printStackTrace();
System.exit(0);
}
m_cpds.setJdbcUrl(m_DatabaseConnectionString);
m_dbConnection = m_cpds.getConnection();
String qualifiedName = "";
C3P0ProxyConnection castCon = (C3P0ProxyConnection)m_dbConnection;
Method m = AS400JDBCConnection.class.getDeclaredMethod("getServerJobIdentifier");
// This does return what I want. getServerJobIdentified() has no parameters.
System.out.println("method=" + m.toString());
Object[] args = new Object[] {};
System.out.println("calling rawConnectionOperation");
qualifiedName = (String) castCon.rawConnectionOperation(m, C3P0ProxyConnection.RAW_CONNECTION, args);
// never gets here
System.out.println("qualifiedName=" + qualifiedName);
I know I'm that close or I think I am. Thanks!
import java.util.*;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException;
import com.mchange.v2.c3p0.*;
import com.ibm.as400.access.AS400;
import com.ibm.as400.access.AS400JDBCConnection;
import com.ibm.as400.access.AS400SecurityException;
import com.ibm.db2.jdbc.app.DB2Connection;
// javac -cp :./c3p0-0.9.5.4.jar:./mchange-commons-java-0.2.15.jar:./jt400.jar C3P0Main.java
// /QIBM/ProdData/OS400/jt400/lib/jt400Native.jar
// java -cp :./c3p0-0.9.5.4.jar:./mchange-commons-java-0.2.15.jar:./jt400.jar C3P0Main
// or
// java -cp :./c3p0-0.9.5.4.jar:./mchange-commons-java-0.2.15.jar:/QIBM/ProdData/OS400/jt400/lib/jt400Native.jar C3P0Main
// c3p0.acquireRetryAttempts=0
// c3p0.acquireRetryDelay=5000
// c3p0.breakAfterAcquireFailure=false
// c3p0.maxConnectionAge=10800
// c3p0.maxIdleTime=3600
// c3p0.maxIdleTimeExcessConnections=600
// c3p0.automaticTestTable=c3p0test
// c3p0.idleConnectionTestPeriod=600
// c3p0.testConnectionOnCheckout=true
// java -cp :./c3p0-0.9.5.4.jar:./mchange-commons-java-0.2.15.jar:./jt400.jar -Dc3p0.acquireRetryAttempts=0 -Dc3p0.acquireRetryDelay=5000 -Dc3p0.breakAfterAcquireFailure=false -Dc3p0.maxConnectionAge=10800 -Dc3p0.maxIdleTime=3600 -Dc3p0.maxIdleTimeExcessConnections=600 -Dc3p0.automaticTestTable=c3p0test -Dc3p0.idleConnectionTestPeriod=600 -Dc3p0.testConnectionOnCheckout=true C3P0Main
public class C3P0Main {
private Connection m_dbConnection;
private ComboPooledDataSource m_cpds;
private String driverClassName = "com.ibm.as400.access.AS400JDBCDriver";
//private String m_DatabaseConnectionString = "jdbc:as400:BNADEV;naming=sql;extended metadata=true;user=beak;password=roatan12";
private String m_DatabaseConnectionString = "jdbc:as400:BNADEV;naming=sql;extended metadata=true";
private String m_databaseServerJobID;
public C3P0Main() throws SQLException
{
m_cpds = new ComboPooledDataSource();
try {
m_cpds.setDriverClass(driverClassName); //loads the jdbc driver
}
catch (Exception e) {
e.printStackTrace();
System.exit(0);
}
m_cpds.setJdbcUrl(m_DatabaseConnectionString);
}
public void run(String[] args) throws Exception
{
m_dbConnection = m_cpds.getConnection();
System.out.println("m_dbConnection=" + m_dbConnection.toString());
String qualifiedName = "";
try {
// To use it, first cast the returned Connection to a C3P0ProxyConnection.
// Then call the method rawConnectionOperation, supplying the java.lang.reflect.Method object
// for the non-standard method you wish to call as an argument. The Method you supply will
// be invoked on the target you provide on the second argument (null for static methods),
// and using the arguments you supply in the third argument to that function. For the target,
// and for any of the method arguments, you can supply the special token
// C3P0ProxyConnection.RAW_CONNECTION, which will be replaced with the
// underlying vendor-specific Connection object before the Method is invoked.
//
// C3P0ProxyConnection castCon = (C3P0ProxyConnection) c3p0DataSource.getConnection();
// Method m = CLOB.class.getMethod("createTemporary", new Class[]{Connection.class, boolean.class, int.class});
// Object[] args = new Object[] {C3P0ProxyConnection.RAW_CONNECTION, Boolean.valueOf( true ), new Integer( 10 )};
// CLOB oracleCLOB = (CLOB) castCon.rawConnectionOperation(m, null, args);
// getServerJobIdentifier, public abstract java.lang.String com.ibm.as400.access.AS400JDBCConnection.getServerJobIdentifier()
System.out.println("Is a wrapper for DB2Connection=" + m_dbConnection.isWrapperFor(com.ibm.db2.jdbc.app.DB2Connection.class));
System.out.println("Is a wrapper for AS400JDBCConnection=" + m_dbConnection.isWrapperFor(AS400JDBCConnection.class));
C3P0ProxyConnection castCon = (C3P0ProxyConnection)m_dbConnection;
System.out.println("C3P0ProxyConnection.RAW_CONNECTION=" + C3P0ProxyConnection.RAW_CONNECTION.getClass().getName());
Method method = AS400JDBCConnection.class.getMethod("getServerJobIdentifier");
System.out.println("method=" + method.toString());
Object[] method_args = new Object[] {};
System.out.println("calling rawConnectionOperation");
try {
qualifiedName = (String) castCon.rawConnectionOperation(method, m_dbConnection, method_args);
System.out.println("qualifiedName=" + qualifiedName);
}
catch (IllegalArgumentException | SQLException | InvocationTargetException | IllegalAccessException e) {
System.out.println(e);
System.out.println("oh well #1.");
}
try {
Object[] method_args = new Object[] {};
qualifiedName = (String) castCon.rawConnectionOperation(method, m_dbConnection, method_args);
System.out.println("qualifiedName=" + qualifiedName);
}
catch (IllegalArgumentException | SQLException | InvocationTargetException | IllegalAccessException e) {
System.out.println(e);
System.out.println("oh well #2.");
}
if (castCon instanceof AS400JDBCConnection) {
System.out.println("YES");
qualifiedName = ((AS400JDBCConnection)C3P0ProxyConnection.RAW_CONNECTION).getServerJobIdentifier();
String jobName = qualifiedName.substring(0, 10).trim();
String jobUser = qualifiedName.substring(10, 20).trim();
String jobNumber = qualifiedName.substring(20).trim();
m_databaseServerJobID = jobNumber + '/' + jobUser + '/' + jobName;
System.out.println("SQL Server Job ID: " + m_databaseServerJobID);
}
else {
System.out.println("m_dbConnection is not an instance of DB2Connection.");
}
}
catch (IllegalArgumentException | SQLException | NoSuchMethodException e) {
System.out.println(e);
System.out.println("oh well.");
}
}
public static void main(java.lang.String args[])
{
try {
C3P0Main app = new C3P0Main();
app.run(args);
}
catch (Exception e) {
e.printStackTrace();
}
}
}

Implement Infinite scroll with ViewModel And Retrofit in recyclerview

Before adding viewmodel & livedata , i successfully implemented infinity scroll with retrofit. But after adding viewmodel & livedata with Retrofit, My can't update recyclerview with new data call or viewmodel observer not update the list.
I simply want to infinite scrolling as my code does before. I add a global variable to reuse next page token. Am i missing anything or any sample to implement infinite recyclerview with viewmodel & retrofit will be awesome.
public static String NEXT_PAGE_URL = null;
I coded like that.
My Activity -> PlaceListActivity
placeRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
LogMe.d(tag, "onScrollStateChanged:: " + "called");
// check scrolling started or not
if (newState == AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) {
isScrolling = true;
}
}
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
LogMe.d(tag, "onScrolled:: " + "called");
super.onScrolled(recyclerView, dx, dy);
currentItem = layoutManager.getChildCount();
totalItems = layoutManager.getItemCount();
scrolledOutItems = ((LinearLayoutManager) recyclerView.getLayoutManager()).findFirstVisibleItemPosition();
LogMe.d(tag, "currentItem:: " + currentItem);
LogMe.d(tag, "totalItems:: " + totalItems);
LogMe.d(tag, "scrolledOutItems:: " + scrolledOutItems);
if (isScrolling && (currentItem + scrolledOutItems == totalItems)) {
LogMe.d(tag, "view:: " + "finished");
isScrolling = false;
if (ApplicationData.NEXT_PAGE_URL != null) {
LogMe.d(tag, "place adding:: " + " onScrolled called");
ll_loading_more.setVisibility(View.VISIBLE);
// todo: call web api here
callDataFromLocationAPi(type, ApplicationData.NEXT_PAGE_URL, currentLatLng);
} else {
LogMe.d(tag, "next_page_url:: " + " is null");
}
}
}
});
private void callDataFromLocationAPi(String type, String next_page_url, LatLng latLng) {
if (Connectivity.isConnected(activity)) {
showProgressDialog();
model.getNearestPlaces(type, next_page_url, latLng).
observe(activity, new Observer<List<PlaceDetails>>() {
#Override
public void onChanged(#Nullable List<PlaceDetails> placeDetails) {
ll_loading_more.setVisibility(View.GONE);
LogMe.i(tag, "callDataFromLocationAPi: onChanged called !");
hideProgressDialog();
if (placeDetails != null) {
placeDetailsList = placeDetails;
placeListAdapter.setPlaceList(placeDetails);
}
}
});
} else {
showAlertForInternet(activity);
}
}
In PlaceViewModel
public class PlaceViewModel extends AndroidViewModel {
//this is the data that we will fetch asynchronously
private MutableLiveData<List<PlaceDetails>> placeList;
private PlaceRepository placeRepository;
private String tag = getClass().getName();
public PlaceViewModel(Application application) {
super(application);
placeRepository = new PlaceRepository(application);
}
//we will call this method to get the data
public MutableLiveData<List<PlaceDetails>> getNearestPlaces(String type,
String next_page_token,
LatLng latLng) {
//if the list is null
if (placeList == null) {
placeList = new MutableLiveData<>();
//we will load it asynchronously from server in this method
//loadPlaces(type, next_page_token, latLng);
placeList = placeRepository.getNearestPlacesFromAPI(type, next_page_token, latLng);
}
//finally we will return the list
return placeList;
}
}
In my PlaceRepository.java looks
public class PlaceRepository {
private static final Migration MIGRATION_1_2 = new Migration(1, 2) {
#Override
public void migrate(SupportSQLiteDatabase database) {
// Since we didn't alter the table, there's nothing else to do here.
}
};
private PlaceDatabase placeDatabase;
private CurrentLocation currentLocation = null;
private String tag = getClass().getName();
//this is the data that we will fetch asynchronously
private MutableLiveData<List<PlaceDetails>> placeList;
public PlaceRepository(Context context) {
placeDatabase = PlaceDatabase.getDatabase(context);
//addMigrations(MIGRATION_1_2)
placeList =
new MutableLiveData<>();
}
public MutableLiveData<List<PlaceDetails>> getNearestPlacesFromAPI(String type, final String next_page_token, LatLng latLng) {
List<PlaceDetails> placeDetailsList = new ArrayList<>();
try {
ApiInterface apiService = ApiClient.getClient().create(ApiInterface.class);
Call<Example> call = apiService.getNearbyPlaces(type,
latLng.latitude + "," +
latLng.longitude, ApplicationData.PROXIMITY_RADIUS,
ApplicationData.PLACE_API_KEY, next_page_token);
call.enqueue(new Callback<Example>() {
#Override
public void onResponse(Call<Example> call, Response<Example> response) {
try {
Example example = response.body();
ApplicationData.NEXT_PAGE_URL = example.getNextPageToken();
// next_page_url = example.getNextPageToken();
LogMe.i(tag, "next_page_url:" + ApplicationData.NEXT_PAGE_URL);
if (example.getStatus().equals("OK")) {
LogMe.i("getNearbyPlaces::", " --- " + response.toString() +
response.message() + response.body().toString());
// This loop will go through all the results and add marker on each location.
for (int i = 0; i < example.getResults().size(); i++) {
Double lat = example.getResults().get(i).getGeometry().getLocation().getLat();
Double lng = example.getResults().get(i).getGeometry().getLocation().getLng();
String placeName = example.getResults().get(i).getName();
String vicinity = example.getResults().get(i).getVicinity();
String icon = example.getResults().get(i).getIcon();
String place_id = example.getResults().get(i).getPlaceId();
PlaceDetails placeDetails = new PlaceDetails();
if (example.getResults().get(i).getRating() != null) {
Double rating = example.getResults().get(i).getRating();
placeDetails.setRating(rating);
}
//List<Photo> photoReference = example.getResults().
// get(i).getPhotos();
placeDetails.setName(placeName);
placeDetails.setAddress(vicinity);
placeDetails.setLatitude(lat);
placeDetails.setLongitude(lng);
placeDetails.setIcon(icon);
placeDetails.setPlace_id(place_id);
//placeDetails.setPlace_type(place_type_title);
double value = ApplicationData.
DISTANCE_OF_TWO_LOCATION_IN_KM(latLng.latitude, latLng.longitude, lat, lng);
//new DecimalFormat("##.##").format(value);
placeDetails.setDistance(new DecimalFormat("##.##").format(value));
String ph = "";
if (example.getResults().
get(i).getPhotos() != null) {
try {
List<Photo> photos = example.getResults().
get(i).getPhotos();
//JSONArray array = new JSONArray(example.getResults().
//get(i).getPhotos());
//JSONObject jsonObj = new JSONObject(array.toString());
//ph = jsonObj.getString("photo_reference");
ph = photos.get(0).getPhotoReference();
//LogMe.i(tag, "\n" + ph);
} catch (Exception e) {
e.printStackTrace();
//placeDetails.setPicture_reference(ph);
//PLACE_DETAILS_LIST.add(placeDetails);
//LogMe.i(tag, "#### Exception Occureed ####");
ph = "";
//continue;
}
}
placeDetails.setPicture_reference(ph);
placeDetailsList.add(placeDetails);
placeList.postValue(placeDetailsList);
}
} else {
}
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void onFailure(Call<Example> call, Throwable t) {
Log.e("onFailure", t.toString());
}
});
} catch (RuntimeException e) {
//hideProgressDialog();
Log.d("onResponse", "RuntimeException is an error");
e.printStackTrace();
} catch (Exception e) {
Log.d("onResponse", "Exception is an error");
}
return placeList;
}
}
I precise code due to question simplicity.
Though you already use android-jetpack, take a look at Paging library. It's specially designed for building infinite lists using RecyclerView.
Based on your source code, I'd say that you need PageKeyedDataSource, here is some example which includes info about how to implement PageKeyedDataSource -
7 steps to implement Paging library in Android
If talking about cons of this approach:
You don't need anymore to observe list scrolling (library doing it for you), you just need to specify your page size in the next way:
PagedList.Config myPagingConfig = new PagedList.Config.Builder()
.setPageSize(50)
.build();
From documentation:
Page size: The number of items in each page.
Your code will be more clear, you'll get rid of your RecyclerView.OnScrollListener
ViewModel code will be shorter, it's will provide only PagedList:
#NonNull
LiveData<PagedList<ReviewSection>> getReviewsLiveData() {
return reviewsLiveData;
}

testNg Factory, DataProvider reading from excel sheet, tests pass only with instance with last row parameters, others get NPE

I am using factory with data provider reading my data from an excel sheet. The issue is that my tests are passing when the last row from the excel sheet is provided through data providers. Preceding rows are giving me NPE.
I am pasting my code here. Thanks for taking a look.
Here is my factory class:
//Factory test class
public class testFactory {
#Factory(dataProviderClass=dataProvider.MyDataProvider.class,dataProvider="userDataProvider")
public Object[] factoryMethod(String email,String password,String firstName, String lastName) {
TestFaceBookUsingExcelSheetAsDataProvider instance = new TestFaceBookUsingExcelSheetAsDataProvider(email,password,firstName, lastName);
return new Object[] { instance };
}
}
This is my data provider class
//Data Provider class
public class MyDataProvider {
#DataProvider(name = "userDataProvider")
public static Object[][] getUserData() {
return ExcelUtils.fileDataProvider("user");//TODO: currently this value is not in use, hard coded in method
}
}
Here is the method which my data provider class method is calling to read data from excel sheet
//Utility Class's helper method to read test data from excel sheet
//#DataProvider(name = "fileDataProvider")
public static Object[][] fileDataProvider(String sheetName) { //TODO: sheetname
try {
//ExcelUtils.setExcelFile(Constant.Path_TestData + Constant.File_TestData,"user");
System.out.println(Constant.Path_TestData + Constant.File_TestData); //TODO
//XSSFWorkbook workbook = new XSSFWorkbook(Constant.Path_TestData + Constant.File_TestData);
XSSFWorkbook workbook = new XSSFWorkbook("<path_to_file>\\TestData.xlsx");
XSSFSheet sheet = workbook.getSheet("user");
Iterator<Row> rowIterator = sheet.iterator();
ArrayList<ArrayList<String>> rowdata = new ArrayList<ArrayList<String>>();
boolean isHeader = true;
while (rowIterator.hasNext()) {
ArrayList<String> columndata = new ArrayList<String>();
Row row = rowIterator.next();
Iterator<Cell> cellIterator = row.cellIterator();
while (cellIterator.hasNext()) {
Cell cell = cellIterator.next();
if (row.getRowNum() > 0) { // To filter column headings
isHeader = false;
if(cell.getCellType() == org.apache.poi.ss.usermodel.Cell.CELL_TYPE_NUMERIC) {
columndata.add(cell.getNumericCellValue() + "");
} else if (cell.getCellType() == org.apache.poi.ss.usermodel.Cell.CELL_TYPE_STRING) {
columndata.add(cell.getStringCellValue());
} else if (cell.getCellType() == org.apache.poi.ss.usermodel.Cell.CELL_TYPE_BOOLEAN) {
columndata.add(cell.getBooleanCellValue() + "");
}
}
}
if (isHeader == false ) {
rowdata.add(columndata); // to make sure we don't add an empty array for header row
}
}
workbook.close();
String[][] return_array = new String[rowdata.size()][];
for (int i = 0; i < rowdata.size(); i++) {
ArrayList<String> row = rowdata.get(i);
return_array[i] = row.toArray(new String[row.size()]);
}
return return_array;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
}
And this, finally, is my test code
//My testclass
package test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.testng.Assert;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
import pgFactory.fb.HomePage;
import pgFactory.fb.LandingPage;
import pgFactory.fb.TimeLine;
public class TestFaceBookUsingExcelSheetAsDataProvider {
// Constructor to be called from factory class
public TestFaceBookUsingExcelSheetAsDataProvider(String email, String password, String firstName, String lastName) {
this.email = email;
this.password = password;
this.firstName = firstName;
this.lastName = lastName;
}
// class variables to be used in the tests
WebDriver driver;
LandingPage lp;
HomePage hp;
TimeLine tl;
// Variables from data provider which in turn is reading from excel sheet
private String email = null;
private String password = null;
private String firstName = null;
private String lastName = null;
#Override
public String toString()
{
return this.email+ " " + this.password + " " + this.firstName + " " + this.lastName;
}
#BeforeTest
public void setup() {
// Driver
driver = new FirefoxDriver();
// Pages
lp = new LandingPage(driver).get();
hp = new HomePage(driver).get();
tl = new TimeLine(driver).get();
}
// Test methods
#Test()
public void testLogin() {
lp.login(email, password);
// Assert that after login you will see your home page
Assert.assertEquals(hp.getUserLeftNavName().getAttribute("innerHTML"), firstName + " " + lastName,
"The full name is not correct on the left side user navigation frame");
Assert.assertEquals(hp.getUserUpperNavName().getAttribute("innerHTML"), firstName,
"The first is not correct on the upper user navigation bar");
hp.logOut();
}
#Test
public void testMyPage() {
lp.login(email, password);
hp.getUserLeftNavName().click();
String name = (new WebDriverWait(driver, 5))
.until(ExpectedConditions.presenceOfElementLocated(By.id("fb-timeline-cover-name"))).getText();
Assert.assertEquals(name, firstName + " " + lastName, "The fullname on timeline cover is not correct");
hp.logOut();
}
#AfterTest
public void teardown() {
driver.quit();
}
}
BTW, I am learning selenium by automating a few tests on facebook page. So, if I am making a silly mistake, please be patient with me.
I found the solution by debugging the code. The issue is when factory is used then I don't have any control over the BeforeTest annotated methods. These are not being run before tests start to execute. So, NPE is thrown because my pageObject is not instantiated yet.
Workaround. I annotated setup method with #Test and made other tests dependent on this test and it worked like a charm. Its not the best solution because now I have to make every existing and future tests with this dependsOnMethods parameter in annotation.
If you know of a better solution, please reply.

How to add and configure asmack in android

Please can you help with a break down of how you got asmack working in your android. I cant get it to work for my application. I keep geting java.lang.verifyError.
Be sure to include latest version i.e. asmack-android-17-0.8.3 of asmack library in libs folder.
Adding this might remove java.lang.VerifyError.
I do it the following way, it works perfectly.
public void login(View view)
{
new Connection().execute("username", "password");
}
private class Connection extends AsyncTask<String, Void, Integer>
{
private static final int CONNECTION_FAILURE = 0;
private static final int LOGIN_FAILURE = 1;
private static final int SUCCESS = 2;
#Override
protected Integer doInBackground(String... strings)
{
ConnectionConfiguration conConfig = new ConnectionConfiguration("192.168.1.100", 5222, "domain");
connection = new XMPPConnection(conConfig);
try
{
connection.connect();
Log.i("AppName", "CONNECTED TO " + connection.getHost());
}
catch(Exception e)
{
Log.e("AppName", e.getMessage());
return CONNECTION_FAILURE;
}
try
{
connection.login(strings[0], strings[1]);
Log.i("AppName", "LOGGED IN AS " + connection.getUser());
Presence presence = new Presence(Presence.Type.available);
connection.sendPacket(presence);
}
catch(Exception e)
{
Log.e("AppName", e.getMessage());
return LOGIN_FAILURE;
}
return SUCCESS;
}
}

Implementation of simple Java IDE using Runtime Process and JTextArea

I am developing a simple Java IDE like Netbeans/Eclipse. My GUI includes two JTextArea component, one used as a TextEditor where the end user can type in his programs and the other used as an output window.
I am running the users programs by invoking the windows command prompt through Java Runtime and Process classes. I am also catching the IO streams of the process using the methods getInputStream(), getErrorStream(), getOutputStream().
If the program contains only the statements to print something onto the screen, I am able to display the output on the output window(JTextArea). But if it includes statements to read input from the user, then it must be possible for the user to type the expected input value via the output window and it must be sent to the process just as in Netbeans/Eclipse.
I also checked the following link
java: work with stdin/stdout of process in same time
Using this code, I am able to display only the statements waiting for input and not simple output statements. Also, only a single line is displayed on the output window at a time.
It would be great if anybody can help me to resolve this issue.
Thanks
Haleema
I've found the solution with little modification to the earlier post java: work with stdin/stdout of process in same time
class RunFile implements Runnable{
public Thread program = null;
public Process process = null;
private JTextArea console;
private String fn;
public RunFile(JTextArea cons,String filename){
console = cons;
fn=filename;
program = new Thread(this);
program.start();
}
#Override
public void run() {
try {
String commandj[] = new String[4];
commandj[0] = "cmd";
commandj[1]="/C";
commandj[2]="java";
commandj[3] = fn;
String envp[] = new String[1];
envp[0]="path=C:/Program Files (x86)/Java/jdk1.6.0/bin";
File dir = new File("Path to File");
Runtime rt = Runtime.getRuntime();
process = rt.exec(commandj,envp,dir);
ReadStdout read = new ReadStdout(process,console);
WriteStdin write = new WriteStdin(process, console);
int x=process.waitFor();
console.append("\nExit value: " + process.exitValue() + "\n");
}
catch (InterruptedException e) {}
catch (IOException e1) {}
}
}
class WriteStdin implements Runnable{
private Process process = null;
private JTextArea console = null;
public Thread write = null;
private String input = null;
private BufferedWriter writer = null;
public WriteStdin(Process p, JTextArea t){
process = p;
console = t;
writer = new BufferedWriter(new OutputStreamWriter(process.getOutputStream()));
write = new Thread(this);
write.start();
console.addKeyListener(new java.awt.event.KeyAdapter() {
#Override
public void keyTyped(java.awt.event.KeyEvent e){
//save the last lines for console to variable input
if(e.getKeyChar() == '\n'){
try {
int line = console.getLineCount() -2;
int start = console.getLineStartOffset(line);
int end = console.getLineEndOffset(line);
input = console.getText(start, end - start);
write.resume();
} catch (BadLocationException e1) {}
}
}
});
console.addCaretListener(new javax.swing.event.CaretListener() {
#Override
public void caretUpdate(CaretEvent e) {
console.setCaretPosition(console.getDocument().getLength());
throw new UnsupportedOperationException("Not supported yet.");
}
});
console.addFocusListener(new java.awt.event.FocusAdapter() {
#Override
public void focusGained(java.awt.event.FocusEvent e)
{
console.setCaretPosition(console.getDocument().getLength());
}
});
}
#Override
public void run(){
write.suspend();
while(true){
try {
//send variable input in stdin of process
writer.write(input);
writer.flush();
} catch (IOException e) {}
write.suspend();
}
}
}
class ReadStdout implements Runnable{
public Thread read = null;
private BufferedReader reader = null;
private Process process = null;
private JTextArea console = null;
public ReadStdout(Process p,JTextArea t){
process = p;
reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
console = t;
read = new Thread(this);
read.start();
}
public void run() {
String line;
try {
while((line = reader.readLine())!=null)
console.append(line+"\n");
}catch (IOException e) {}
}
}