I am beginner in Selenium, there are two separate .xls file file one for GmailTestSuite.xls and other for objectrepository.xls.
I have created MainClass, in it I have written a code which read both .xls file, also I've open the driver in it and perform operation. But problem is that it continuously open new driver but don't perform any operation.
Please suggest and let me know where I'm going wrong.
public class MainClass {
static Properties properties= null;
public static void main(String[] args) throws IOException, BiffException{
// TODO Auto-generated method stub
ReadPropertyFile readConfigFile= new ReadPropertyFile();
properties= readConfigFile.loadPropertiess();
ExcelHandler testSuite= new ExcelHandler("D:\\GmailTestSuite.xls", "Suite");
testSuite.columnData();
int rowCount= testSuite.rowCount();
System.out.println("Total Rows="+rowCount);
for(int i=1;i<rowCount;i++)
{
String executable= testSuite.readCell(testSuite.getCell("Executable"), i);
System.out.println("Executable="+executable);
if(executable.equalsIgnoreCase("y")){
// exe. the process
String scenarioName= testSuite.readCell(testSuite.getCell("TestScenario"), i);
System.out.println("Scenario Name="+scenarioName);
ExcelHandler testScenarios= new ExcelHandler("D:\\GmailTestSuite.xls", scenarioName);
int rowWorkBook1= testScenarios.rowCount();
for(int j=1; j<rowWorkBook1;j++){
String framWork= testScenarios.readCell(testScenarios.getCell("FrameworkName"), j);
String operation = testScenarios.readCell(testScenarios.getCell("Operation"), j); //SendKey
String value= testScenarios.readCell(testScenarios.getCell("Value"), j);
System.out.println("FRMName="+framWork+",Operation="+operation+",Value="+value);
ExcelHandler objectRepository= new ExcelHandler("D:\\objectrepository.xls", "OR");
objectRepository.columnData();
int rowCount1= testSuite.rowCount();
System.out.println("Total Rows="+rowCount1);
for(int k=1;k<rowCount;k++){
String frameWorkName= objectRepository.readCell(objectRepository.getCell("Executable"), k);
String ObjectName= objectRepository.readCell(testScenarios.getCell("ObjectName"), k);
String Locator = objectRepository.readCell(testScenarios.getCell("Locator"), k); //SendKey
System.out.println("FrameWorkName="+frameWorkName+",ObjectName="+ObjectName+",Locator="+Locator);
//ExcelHandler executeOperation = new ExcelHandler(ObjectName, operation, value);
File file= new File("D:\\softs\\FF installed\\FF18\\firefox.exe");
FirefoxBinary fb = new FirefoxBinary(file);
WebDriver driver = new FirefoxDriver(fb,new FirefoxProfile());
driver.get("https://www.gmail.com");
WebElement we = driver.findElement(By.id("Email"));
if(operation.equalsIgnoreCase("SendKey"))
{
we.sendKeys("abc#gmail.com");
we.sendKeys("si#2013");
}
if(operation.equalsIgnoreCase("Click"))
we.click();
}
}
}
}
}
A couple of guide lines for better formed code:
Break your code into methods that only do one thing each. That way it's easier to manage and nicely compartmentalized, plus you don't enter into indentation hell with such embedded loop and if structures as the one you have over here.
Use class variables for things like the WebDriver instance, so you can initialize it once and keep calling on it later.
Don't hard code text into the application, use constants. Then you only need to define the text once and can refer to it multiple times. Makes the code much easier to maintain and change, when you don't have to search and replace through entire class, after some details (like a file path) change.
Also, I'm guessing you meant to do the following:
loop the rows in objectRepository in the k-loop, instead of looping the rows in the testSuite again.
get cells from objectRepository rather than from testScenarios when reading the cells from objectRepository
Example:
public class MainClass {
private static final String BROWSER_PATH = "D:\\softs\\FF installed\\FF18\\firefox.exe";
private static final String TEST_SUITE_PATH = "D:\\GmailTestSuite.xls";
private static final String OBJECT_REPOSITORY_PATH = "D:\\objectrepository.xls";
private static final String ADDRESS_TO_TEST = "https://www.gmail.com";
private static final By EMAIL_INPUT = By.id("Email");
// other constants
private WebDriver driver;
private Properties properties;
public MainClass() {
File file = new File(BROWSER_PATH);
FirefoxBinary fb = new FirefoxBinary(file);
driver = new FirefoxDriver(fb, new FirefoxProfile());
driver.get(ADDRESS_TO_TEST);
}
public static void main(String[] args) throws IOException, BiffException {
MainClass main = new MainClass();
main.handleTestSuite();
}
private void handleTestSuite() {
ReadPropertyFile readConfigFile = new ReadPropertyFile();
properties = readConfigFile.loadPropertiess();
ExcelHandler testSuite = new ExcelHandler(TEST_SUITE_PATH, "Suite");
testSuite.columnData();
int rowCount = testSuite.rowCount();
System.out.println("Total Rows=" + rowCount);
for (int i = 1; i < rowCount; i++) {
String executable = testSuite.readCell(testSuite.getCell("Executable"), i);
System.out.println("Executable=" + executable);
if (executable.equalsIgnoreCase("y")) {
// exe. the process
String scenarioName = testSuite.readCell(testSuite.getCell("TestScenario"), i);
System.out.println("Scenario Name=" + scenarioName);
handleScenario(scenarioName);
}
}
}
private void handleScenario(String scenarioName) {
ExcelHandler testScenarios = new ExcelHandler(TEST_SUITE_PATH, scenarioName);
int rowWorkBook1 = testScenarios.rowCount();
for (int j = 1; j < rowWorkBook1; j++) {
String framWork = testScenarios.readCell(testScenarios.getCell("FrameworkName"), j);
String operation = testScenarios.readCell(testScenarios.getCell("Operation"), j); // SendKey
String value = testScenarios.readCell(testScenarios.getCell("Value"), j);
System.out.println("FRMName=" + framWork + ",Operation=" + operation +
",Value=" + value);
handleObjects(operation);
}
}
private void handleObjects(String operation) {
ExcelHandler objectRepository = new ExcelHandler(OBJECT_REPOSITORY_PATH, "OR");
objectRepository.columnData();
int rowCount = objectRepository.rowCount();
System.out.println("Total Rows=" + rowCount);
for (int k = 1; k < rowCount; k++) {
String frameWorkName = objectRepository.readCell(objectRepository.getCell("Executable"), k);
String ObjectName = objectRepository.readCell(objectRepository.getCell("ObjectName"), k);
String Locator = objectRepository.readCell(objectRepository.getCell("Locator"), k); // SendKey
System.out.println("FrameWorkName=" + frameWorkName +
",ObjectName=" + ObjectName + ",Locator=" + Locator);
operateWebDriver(operation);
}
}
private void operateWebDriver(String operation) {
WebElement we = driver.findElement(EMAIL_INPUT);
if (operation.equalsIgnoreCase("SendKey")) {
we.sendKeys("abc#gmail.com");
we.sendKeys("si#2013");
} else if (operation.equalsIgnoreCase("Click")) {
we.click();
}
}
}
If ExcelHandler is your own implementation, you really should move the getCell(String s) method inside the readCell() method to change the call pattern of handler.readCell(handler.getCell("foo"), i) into handler.readCell("foo", i). If it's a library you're using, you can always make a helper method:
private static String readCell(ExcelHandler handler, String cellName, int row) {
return handler.readCell(handler.getCell(cellName), row);
}
EDIT
Since you're having problems with getting WebDriver to work, simplify things and take everything else out of the equation for now. In order to do that let's ignore all the reading data from .xls files. This is where having different methods for different things makes your design shine, since you can just comment one method call instead of having to comment out 50 lines of code from your one mega method.
Changed the above code a bit (just commented call to the other methods out and omitted them from the snippet, moved the line opening the correct page into constructor and rewrote the operateWebDriver() method a bit):
public class MainClass {
private static final String ADDRESS_TO_TEST = "https://www.gmail.com";
private static final By EMAIL_INPUT = By.id("Email");
private static final By PASSWORD_INPUT = By.id("Passwd");
private static final By SIGN_IN_BUTTON = By.id("signIn");
private static final String EMAIL = "test#abc.com";
private static final String PASSWORD = "test123";
private WebDriver driver;
public MainClass() {
File file = new File(BROWSER_PATH);
FirefoxBinary fb = new FirefoxBinary(file);
driver = new FirefoxDriver(fb, new FirefoxProfile());
driver.get(ADDRESS_TO_TEST);
}
public static void main(String[] args) throws IOException, BiffException {
MainClass main = new MainClass();
//main.handleTestSuite();
main.operateWebDriver("Click", EMAIL_INPUT);
main.operateWebDriver("SendKey", EMAIL_INPUT, EMAIL);
main.operateWebDriver("Click", PASSWORD_INPUT);
main.operateWebDriver("SendKey", PASSWORD_INPUT, PASSWORD);
main.operateWebDriver("Click", SIGN_IN_BUTTON);
}
private void operateWebDriver(String operation, By element) {
operateWebDriver(operation, element, null);
}
private void operateWebDriver(String operation, By element, String keys) {
WebElement we = driver.findElement(element);
if (operation.equalsIgnoreCase("SendKey")) {
we.sendKeys(keys);
} else if (operation.equalsIgnoreCase("Click")) {
we.click();
}
}
}
Then once you get WebDriver working, you can start reading the data from the files and using it to operate WebDriver.
#user2092132- You require to make changes on two places in your code
1: Insert new line after line- System.out.println("Total Rows="+rowCount);
WebDriver driver = null;
2:Change line from: WebDriver driver = new FirefoxDriver(fb,new FirefoxProfile());
To: driver = new FirefoxDriver(fb,new FirefoxProfile());
Above two changes should resolve initiating new instacne of FF each time.
Related
I'm working with Stacks in Java at the moment.
The problem I'm facing is that I want to create a Stack which stores items of the type "candy".
I want to add that "candy" at the Producer.java
But when I run the code shown below I get the error:
Exception in thread "main" java.util.EmptyStackException
at java.util.Stack.peek(Stack.java:102)
at java.util.Stack.pop(Stack.java:84)
at app.fachinformatiker.myMashup.Model.Consumer.(Consumer.java:10)
at app.fachinformatiker.myMashup.Main.Main.initializeConsumers(Main.java:84)
at app.fachinformatiker.myMashup.Main.Main.main(Main.java:42)
These are the corresponding lines
Consumer.java:10
String Candy = candyStack.pop();
Main.java:84
consumerList.add(new Consumer(candyStack));
Main.java:42
initializeConsumers();
I don't get it why my stack isn't properly filled.
Below you will find some snippets of my code.
If you want to download my whole code and run it in an IDE of your choice (I use IntelliJ IDEA), here's a direct link to the archive on GitHub (specific commit) : https://github.com/fachinformatiker/myMashup/archive/97e3ffb.zip
Here's some snippets of my code:
In my Main.java
private static final Stack<String> candyStack = new Stack<>();
private static final ArrayList<Producer> producerList = new ArrayList<>();
private static final ArrayList<Consumer> consumerList = new ArrayList<>();
...
private static void startProducers() {
for (int i = 0; i < producerList.size(); i++) {
System.out.println("I would start producer Nr. " + i + " now.");
producerList.get(i).start();
}
}
private static void startConsumer() {
for (int i = 0; i < consumerList.size(); i++) {
Debug.gebeInfoAus("I would start consumer Nr. " + i + " now.");
consumerList.get(i).start();
}
}
private static void initializeProducers() {
if (ArgController.istAusgewertet) {
Debug.gebeInfoAus("Producer istAusgewertet");
return;
}
for (int i = 0; i < ArgController.getAnzahlProduzenten(); i++) {
Debug.gebeInfoAus("Producer Nr. " + i + " added to candyStack");
producerList.add(new Producer(candyStack, i));
}
}
in my Producer.java
public class Producer {
private Candy candy = new Candy();
private String myCandy;
int hell = candy.getHell();
String hope = candy.getHope();
public Producer(Stack<String> candyStack, int i) {
myCandy = i + ";" + hell + ";" + hope;
candyStack.push(myCandy);
Debug.gebeInfoAus(myCandy);
}
public void start() {
}
}
In my Consumer.java
public class Consumer {
public Consumer(Stack<String> candyStack) {
String Candy = candyStack.pop();
Debug.gebeInfoAus(Candy);
}
public void start() {
}
}
I need to automate links in my website. I want to pass xpath values once in each iteration of loop. So that I can minimize my coding
public class Popup
{
private WebDriver driver;
private String baseUrl;
//private boolean acceptNextAlert = true;
private StringBuffer verificationErrors = new StringBuffer();
#Before
public void setUp() throws Exception {
driver = new FirefoxDriver();
baseUrl = "http://www.example.com/info.php";
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
}
#Test
public void testPopup() throws Exception {
driver.findElement(By.xpath("//div[#id='info-list']/div[2]/div/div/div/div/a[2]/i")).click();
driver.findElement(By.xpath("//div[#id='info-list']/div[2]/div/div/div/div/a[3]/i")).click();
driver.findElement(By.xpath("//div[#id='info-list']/div[2]/div/div/div/div/a[4]/i")).click();
driver.findElement(By.xpath("//div[#id='info-list']/div[2]/div/div/div/div/a[5]/i")).click();
Can you try this?
for(int j=2; j<=5; j++) {
driver.findElement(By.xpath("//div[#id='info-list']/div[2]/div/div/div/div/a["+j+"]/i")).click();
}
Hi Sanchit Khera Try this one :
int i = 0;
//extract the link texts of each link element
for (WebElement e : linkElements)
{
linkTitles[i] = e.getText();
i++;
}
//Test each link
for (String t : linkTitles)
{
// Titles Click
driver.findElement(By.linkText(t)).click();
In my play-framework-based web application users can download all the rows of different database tables in csv or json format. Tables are relatively large (100k+ rows) and I am trying to stream back the result using chunking in Play 2.2.
However the problem is although println statements shows that the rows get written to the Chunks.Out object, they do not show up in the client side! If I limit the rows getting sent back it will work, but it also has a big delay in the beginning which gets bigger if I try to send back all the rows and causes a time-out or the server runs out of memory.
I use Ebean ORM and the tables are indexed and querying from psql doesn't take much time. Does anyone have any idea what might be the problem?
I appreciate your help a lot!
Here is the code for one of the controllers:
#SecureSocial.UserAwareAction
public static Result showEpex() {
User user = getUser();
if(user == null || user.getRole() == null)
return ok(views.html.profile.render(user, Application.NOT_CONFIRMED_MSG));
DynamicForm form = DynamicForm.form().bindFromRequest();
final UserRequest req = UserRequest.getRequest(form);
if(req.getFormat().equalsIgnoreCase("html")) {
Page<EpexEntry> page = EpexEntry.page(req.getStart(), req.getFinish(), req.getPage());
return ok(views.html.epex.render(page, req));
}
// otherwise chunk result and send back
final ResultStreamer<EpexEntry> streamer = new ResultStreamer<EpexEntry>();
Chunks<String> chunks = new StringChunks() {
#Override
public void onReady(play.mvc.Results.Chunks.Out<String> out) {
Page<EpexEntry> page = EpexEntry.page(req.getStart(), req.getFinish(), 0);
ResultStreamer<EpexEntry> streamer = new ResultStreamer<EpexEntry>();
streamer.stream(out, page, req);
}
};
return ok(chunks).as("text/plain");
}
And the streamer:
public class ResultStreamer<T extends Entry> {
private static ALogger logger = Logger.of(ResultStreamer.class);
public void stream(Out<String> out, Page<T> page, UserRequest req) {
if(req.getFormat().equalsIgnoreCase("json")) {
JsonContext context = Ebean.createJsonContext();
out.write("[\n");
for(T e: page.getList())
out.write(context.toJsonString(e) + ", ");
while(page.hasNext()) {
page = page.next();
for(T e: page.getList())
out.write(context.toJsonString(e) + ", ");
}
out.write("]\n");
out.close();
} else if(req.getFormat().equalsIgnoreCase("csv")) {
for(T e: page.getList())
out.write(e.toCsv(CSV_SEPARATOR) + "\n");
while(page.hasNext()) {
page = page.next();
for(T e: page.getList())
out.write(e.toCsv(CSV_SEPARATOR) + "\n");
}
out.close();
}else {
out.write("Invalid format! Only CSV, JSON and HTML can be generated!");
out.close();
}
}
public static final String CSV_SEPARATOR = ";";
}
And the model:
#Entity
#Table(name="epex")
public class EpexEntry extends Model implements Entry {
#Id
#Column(columnDefinition = "pg-uuid")
private UUID id;
private DateTime start;
private DateTime finish;
private String contract;
private String market;
private Double low;
private Double high;
private Double last;
#Column(name="weight_avg")
private Double weightAverage;
private Double index;
private Double buyVol;
private Double sellVol;
private static final String START_COL = "start";
private static final String FINISH_COL = "finish";
private static final String CONTRACT_COL = "contract";
private static final String MARKET_COL = "market";
private static final String ORDER_BY = MARKET_COL + "," + CONTRACT_COL + "," + START_COL;
public static final int PAGE_SIZE = 100;
public static final String HOURLY_CONTRACT = "hourly";
public static final String MIN15_CONTRACT = "15min";
public static final String FRANCE_MARKET = "france";
public static final String GER_AUS_MARKET = "germany/austria";
public static final String SWISS_MARKET = "switzerland";
public static Finder<UUID, EpexEntry> find =
new Finder(UUID.class, EpexEntry.class);
public EpexEntry() {
}
public EpexEntry(UUID id, DateTime start, DateTime finish, String contract,
String market, Double low, Double high, Double last,
Double weightAverage, Double index, Double buyVol, Double sellVol) {
this.id = id;
this.start = start;
this.finish = finish;
this.contract = contract;
this.market = market;
this.low = low;
this.high = high;
this.last = last;
this.weightAverage = weightAverage;
this.index = index;
this.buyVol = buyVol;
this.sellVol = sellVol;
}
public static Page<EpexEntry> page(DateTime from, DateTime to, int page) {
if(from == null && to == null)
return find.order(ORDER_BY).findPagingList(PAGE_SIZE).getPage(page);
ExpressionList<EpexEntry> exp = find.where();
if(from != null)
exp = exp.ge(START_COL, from);
if(to != null)
exp = exp.le(FINISH_COL, to.plusHours(24));
return exp.order(ORDER_BY).findPagingList(PAGE_SIZE).getPage(page);
}
#Override
public String toCsv(String s) {
return id + s + start + s + finish + s + contract +
s + market + s + low + s + high + s +
last + s + weightAverage + s +
index + s + buyVol + s + sellVol;
}
1. Most of browsers wait for 1-5 kb of data before showing any results. You can check if Play Framework actually sends data with command curl http://localhost:9000.
2. You create streamer twice, remove first final ResultStreamer<EpexEntry> streamer = new ResultStreamer<EpexEntry>();
3. - You use Page class for retrieving large data set - this is incorrect. Actually you do one big initial request and then one request per iteration. This is SLOW. Use simple findIterate().
add this to EpexEntry (feel free to change it as you need)
public static QueryIterator<EpexEntry> all() {
return find.order(ORDER_BY).findIterate();
}
your new stream method implementation:
public void stream(Out<String> out, QueryIterator<T> iterator, UserRequest req) {
if(req.getFormat().equalsIgnoreCase("json")) {
JsonContext context = Ebean.createJsonContext();
out.write("[\n");
while (iterator.hasNext()) {
out.write(context.toJsonString(iterator.next()) + ", ");
}
iterator.close(); // its important to close iterator
out.write("]\n");
out.close();
} else // csv implementation here
And your onReady method:
QueryIterator<EpexEntry> iterator = EpexEntry.all();
ResultStreamer<EpexEntry> streamer = new ResultStreamer<EpexEntry>();
streamer.stream(new BuffOut(out, 10000), iterator, req); // notice buffering here
4. Another problem is - you call Out<String>.write() too often. Call of write() means that server needs to send new chunk of data to client immediately. Every call of Out<String>.write() have significant overhead.
Overhead appears because server needs to wrap response into chunked result - 6-7 bytes for each message Chunked response Format. Since you send small messages, overhead is significant.
Also, server needs to wrap your reply in TCP packet which size will be far less from optimal.
And, server needs to perform some internal action to send an chunk, this is also require some resources. As result, download bandwidth will be far from optimal.
Here is simple test: send 10000 lines of text TEST0 to TEST9999 in chunks. This takes 3 sec on my computer in average. But with buffering this takes 65 ms. Also, download sizes are 136 kb and 87.5 kb.
Example with buffering:
Controller
public class Application extends Controller {
public static Result showEpex() {
Chunks<String> chunks = new StringChunks() {
#Override
public void onReady(play.mvc.Results.Chunks.Out<String> out) {
new ResultStreamer().stream(out);
}
};
return ok(chunks).as("text/plain");
}
}
new BuffOut class. It's dumb, I know
public class BuffOut {
private StringBuilder sb;
private Out<String> dst;
public BuffOut(Out<String> dst, int bufSize) {
this.dst = dst;
this.sb = new StringBuilder(bufSize);
}
public void write(String data) {
if ((sb.length() + data.length()) > sb.capacity()) {
dst.write(sb.toString());
sb.setLength(0);
}
sb.append(data);
}
public void close() {
if (sb.length() > 0)
dst.write(sb.toString());
dst.close();
}
}
This implementation have 3 second download time and 136 kb size
public class ResultStreamer {
public void stream(Out<String> out) {
for (int i = 0; i < 10000; i++) {
out.write("TEST" + i + "\n");
}
out.close();
}
}
This implementation have 65 ms download time and 87.5 kb size
public class ResultStreamer {
public void stream(Out<String> out) {
BuffOut out2 = new BuffOut(out, 1000);
for (int i = 0; i < 10000; i++) {
out2.write("TEST" + i + "\n");
}
out2.close();
}
}
This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
I'm working since short time with Hadoop and trying to implement a join in Java. It doesn't matter if Map-Side or Reduce-Side. I took Reduce-Side join since it was supposed to be easier to implement. I know that Java is not the best choice for joins, aggregations etc. and should better pick Hive or Pig which I have done already. However I'm working on a research project and I have to use all of those 3 languages in order to deliver a comparison.
Anyway, I have two input files with different structure. One is key|value and the other one is key|value1;value2;value3;value4. One record from each input file looks like following:
Input1: 1;2010-01-10T00:00:01
Input2: 1;23;Blue;2010-01-11T00:00:01;9999-12-31T23:59:59
I followed the example in the Hadoop Definitve Guide book, but it didn't work for me. I'm posting my java files here, so you can see what's wrong.
public class LookupReducer extends Reducer<TextPair,Text,Text,Text> {
private String result = "";
private String msisdn;
private String attribute, product;
private long trans_dt_long, start_dt_long, end_dt_long;
private String trans_dt, start_dt, end_dt;
#Override
public void reduce(TextPair key, Iterable<Text> values, Context context)
throws IOException, InterruptedException {
context.progress();
//value without key to remember
Iterator<Text> iter = values.iterator();
for (Text val : values) {
Text recordNoKey = val; //new Text(iter.next());
String valSplitted[] = recordNoKey.toString().split(";");
//if the input is coming from CDR set corresponding values
if(key.getSecond().toString().equals(CDR.CDR_TAG))
{
trans_dt = recordNoKey.toString();
trans_dt_long = dateToLong(recordNoKey.toString());
}
//if the input is coming from Attributes set corresponding values
else if(key.getSecond().toString().equals(Attribute.ATT_TAG))
{
attribute = valSplitted[0];
product = valSplitted[1];
start_dt = valSplitted[2];
start_dt_long = dateToLong(valSplitted[2]);
end_dt = valSplitted[3];
end_dt_long = dateToLong(valSplitted[3]);;
}
Text record = val; //iter.next();
//System.out.println("RECORD: " + record);
Text outValue = new Text(recordNoKey.toString() + ";" + record.toString());
if(start_dt_long < trans_dt_long && trans_dt_long < end_dt_long)
{
//concat output columns
result = attribute + ";" + product + ";" + trans_dt;
context.write(key.getFirst(), new Text(result));
System.out.println("KEY: " + key);
}
}
}
private static long dateToLong(String date){
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date parsedDate = null;
try {
parsedDate = formatter.parse(date);
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
long dateInLong = parsedDate.getTime();
return dateInLong;
}
public static class TextPair implements WritableComparable<TextPair> {
private Text first;
private Text second;
public TextPair(){
set(new Text(), new Text());
}
public TextPair(String first, String second){
set(new Text(first), new Text(second));
}
public TextPair(Text first, Text second){
set(first, second);
}
public void set(Text first, Text second){
this.first = first;
this.second = second;
}
public Text getFirst() {
return first;
}
public void setFirst(Text first) {
this.first = first;
}
public Text getSecond() {
return second;
}
public void setSecond(Text second) {
this.second = second;
}
#Override
public void readFields(DataInput in) throws IOException {
// TODO Auto-generated method stub
first.readFields(in);
second.readFields(in);
}
#Override
public void write(DataOutput out) throws IOException {
// TODO Auto-generated method stub
first.write(out);
second.write(out);
}
#Override
public int hashCode(){
return first.hashCode() * 163 + second.hashCode();
}
#Override
public boolean equals(Object o){
if(o instanceof TextPair)
{
TextPair tp = (TextPair) o;
return first.equals(tp.first) && second.equals(tp.second);
}
return false;
}
#Override
public String toString(){
return first + ";" + second;
}
#Override
public int compareTo(TextPair tp) {
// TODO Auto-generated method stub
int cmp = first.compareTo(tp.first);
if(cmp != 0)
return cmp;
return second.compareTo(tp.second);
}
public static class FirstComparator extends WritableComparator {
protected FirstComparator(){
super(TextPair.class, true);
}
#Override
public int compare(WritableComparable comp1, WritableComparable comp2){
TextPair pair1 = (TextPair) comp1;
TextPair pair2 = (TextPair) comp2;
int cmp = pair1.getFirst().compareTo(pair2.getFirst());
if(cmp != 0)
return cmp;
return -pair1.getSecond().compareTo(pair2.getSecond());
}
}
public static class GroupComparator extends WritableComparator {
protected GroupComparator()
{
super(TextPair.class, true);
}
#Override
public int compare(WritableComparable comp1, WritableComparable comp2)
{
TextPair pair1 = (TextPair) comp1;
TextPair pair2 = (TextPair) comp2;
return pair1.compareTo(pair2);
}
}
}
}
public class Joiner extends Configured implements Tool {
public static final String DATA_SEPERATOR =";"; //Define the symbol for seperating the output data
public static final String NUMBER_OF_REDUCER = "1"; //Define the number of the used reducer jobs
public static final String COMPRESS_MAP_OUTPUT = "true"; //if the output from the mapping process should be compressed, set COMPRESS_MAP_OUTPUT = "true" (if not set it to "false")
public static final String
USED_COMPRESSION_CODEC = "org.apache.hadoop.io.compress.SnappyCodec"; //set the used codec for the data compression
public static final boolean JOB_RUNNING_LOCAL = true; //if you run the Hadoop job on your local machine, you have to set JOB_RUNNING_LOCAL = true
//if you run the Hadoop job on the Telefonica Cloud, you have to set JOB_RUNNING_LOCAL = false
public static final String OUTPUT_PATH = "/home/hduser"; //set the folder, where the output is saved. Only needed, if JOB_RUNNING_LOCAL = false
public static class KeyPartitioner extends Partitioner<TextPair, Text> {
#Override
public int getPartition(/*[*/TextPair key/*]*/, Text value, int numPartitions) {
System.out.println("numPartitions: " + numPartitions);
return (/*[*/key.getFirst().hashCode()/*]*/ & Integer.MAX_VALUE) % numPartitions;
}
}
private static Configuration hadoopconfig() {
Configuration conf = new Configuration();
conf.set("mapred.textoutputformat.separator", DATA_SEPERATOR);
conf.set("mapred.compress.map.output", COMPRESS_MAP_OUTPUT);
//conf.set("mapred.map.output.compression.codec", USED_COMPRESSION_CODEC);
conf.set("mapred.reduce.tasks", NUMBER_OF_REDUCER);
return conf;
}
#Override
public int run(String[] args) throws Exception {
// TODO Auto-generated method stub
if ((args.length != 3) && (JOB_RUNNING_LOCAL)) {
System.err.println("Usage: Lookup <CDR-inputPath> <Attribute-inputPath> <outputPath>");
System.exit(2);
}
//starting the Hadoop job
Configuration conf = hadoopconfig();
Job job = new Job(conf, "Join cdrs and attributes");
job.setJarByClass(Joiner.class);
MultipleInputs.addInputPath(job, new Path(args[0]), TextInputFormat.class, CDRMapper.class);
MultipleInputs.addInputPath(job, new Path(args[1]), TextInputFormat.class, AttributeMapper.class);
//FileInputFormat.addInputPath(job, new Path(otherArgs[0])); //expecting a folder instead of a file
if(JOB_RUNNING_LOCAL)
FileOutputFormat.setOutputPath(job, new Path(args[2]));
else
FileOutputFormat.setOutputPath(job, new Path(OUTPUT_PATH));
job.setPartitionerClass(KeyPartitioner.class);
job.setGroupingComparatorClass(TextPair.FirstComparator.class);
job.setReducerClass(LookupReducer.class);
job.setMapOutputKeyClass(TextPair.class);
job.setMapOutputValueClass(Text.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(Text.class);
return job.waitForCompletion(true) ? 0 : 1;
}
public static void main(String[] args) throws Exception {
int exitCode = ToolRunner.run(new Joiner(), args);
System.exit(exitCode);
}
}
public class Attribute {
public static final String ATT_TAG = "1";
public static class AttributeMapper
extends Mapper<LongWritable, Text, TextPair, Text>{
private static Text values = new Text();
//private Object output = new Text();
#Override
public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
//partition the input line by the separator semicolon
String[] attributes = value.toString().split(";");
String valuesInString = "";
if(attributes.length != 5)
System.err.println("Input column number not correct. Expected 5, provided " + attributes.length
+ "\n" + "Check the input file");
if(attributes.length == 5)
{
//setting the values with the input values read above
valuesInString = attributes[1] + ";" + attributes[2] + ";" + attributes[3] + ";" + attributes[4];
values.set(valuesInString);
//writing out the key and value pair
context.write( new TextPair(new Text(String.valueOf(attributes[0])), new Text(ATT_TAG)), values);
}
}
}
}
public class CDR {
public static final String CDR_TAG = "0";
public static class CDRMapper
extends Mapper<LongWritable, Text, TextPair, Text>{
private static Text values = new Text();
private Object output = new Text();
#Override
public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
//partition the input line by the separator semicolon
String[] cdr = value.toString().split(";");
//setting the values with the input values read above
values.set(cdr[1]);
//output = CDR_TAG + cdr[1];
//writing out the key and value pair
context.write( new TextPair(new Text(String.valueOf(cdr[0])), new Text(CDR_TAG)), values);
}
}
}
I would be glad if anyone could at least post a link for a tutorial or a simple example where such a join functionality is implemented. I searched a lot, but either the code was not complete or there was not enough explanation.
To be honest, I have no idea what your code is trying to do, but that's probably because I'd do it in a different way and not familiar with the API's you're using.
I would start from scratch as follows:
Create a mapper to read one of the files. For each line read, write a key value pair to the context. The key is a Text created from the key and the value is another Text created by concatenating a "1" with the entire input record.
Create another mapper for the other file. This mapper acts just like the first mapper, but the value is a Text created by concatenating a "2" with the entire input record.
Write a reducer to do the join. The reduce() method will get all records written for a specific key. You can tell which input file (and therefore the data format for the record) by looking to see whether the value starts with a "1" or a "2". Once you know whether or not you have one, the other or both record types, you can write whatever logic you need to merge the data from the one or two records.
By the way, you use the MultipleInputs class to configure more than one mapper in your job/driver class.
I have done some sample code to select a combobox using webdriver in a Flash page but Select(...) and type(....) methods are not working but click(....) method works fine.
Please help to resolve this.
Type-1: Below methods are not working.
public void type(String locator, String value)
{
((JavascriptExecutor) webDriver).executeScript("document.getElementById('" + flashObjectId + "').fp_type({" + locator +", 'text':'"+ value +"'})");
}
public void select(String locator, String value)
{
((JavascriptExecutor) webDriver).executeScript("document.getElementById('" + flashObjectId + "').fp_select({" + locator +", 'label':'"+ value +"'})");
}
Its working fine in below click(....) method.
public String click(final String objectId, final String optionalButtonLabel)
{
return call("doFlexClick", objectId, optionalButtonLabel);
}
private String call(final String functionName, final String... args)
{
final Object result =
((JavascriptExecutor)webDriver).executeScript(
makeJsFunction(functionName, args),
new Object[0]);
return result != null ? result.toString() : null;
}
private String makeJsFunction(final String functionName, final String... args)
{
final StringBuffer functionArgs = new StringBuffer();
if (args.length > 0)
{
for (int i = 0; i < args.length; i++)
{
if (i > 0)
{
functionArgs.append(",");
}
functionArgs.append(String.format("'%1$s'", args[i]));
System.out.println("functionArgs: "+functionArgs);
}
}
return String.format(
"return document.%1$s.%2$s(%3$s);",
flashObjectId,
functionName,
functionArgs);
}
Please help to fix this in select box and tyep operation using webdriver in Flash.
Thanks in Advance,
Gopal
Watir-Webdriver does not support flash pages.