org.uiautomation.ios.wkrdp.ResponseFinderList.java Source code

Java tutorial

Introduction

Here is the source code for org.uiautomation.ios.wkrdp.ResponseFinderList.java

Source

/*
 * Copyright 2013 ios-driver committers.
 *
 *  Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 *  in compliance with the License. You may obtain a copy of the Licence at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software distributed under the License
 *  is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 *  or implied. See the License for the specific language governing permissions and limitations under
 *  the License.
 */

package org.uiautomation.ios.wkrdp;

import org.json.JSONObject;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.logging.Logger;

/**
 * orchestrate all the ResponseFinders. Run all of them in parallel, return the first response found
 * after gracefully waiting for all of them to finish.
 */
// TODO freynaud fix that class.
public class ResponseFinderList {

    private static final Logger log = Logger.getLogger(ResponseFinderList.class.getName());
    private final List<ResponseFinder> finders;
    private final Lock lock = new ReentrantLock();
    private final Condition foundIt = lock.newCondition();
    private final List<Thread> threads = new ArrayList<Thread>();
    private final long timeoutInMs;

    public ResponseFinderList(List<ResponseFinder> finders, long timeoutInMs) {
        this.finders = finders;
        this.timeoutInMs = timeoutInMs;
    }

    public JSONObject findResponse(final int id) {
        final long start = System.currentTimeMillis();
        // start all the finders.
        for (final ResponseFinder finder : finders) {
            Thread t = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        finder.startSearch(id);
                        log.fine("finder " + finder.getClass() + " found something - "
                                + (System.currentTimeMillis() - start) + "ms");
                        try {
                            lock.lock();
                            foundIt.signal();
                        } finally {
                            lock.unlock();
                        }
                    } catch (InterruptedException e) {
                        log.fine("search was interrupted.");
                    }

                }
            });
            threads.add(t);
            t.start();
        }

        // when for one to finish
        try {
            try {
                lock.lock();
                foundIt.await(timeoutInMs, TimeUnit.MILLISECONDS);
                log.fine("await returns " + (System.currentTimeMillis() - start) + "ms");
            } finally {
                lock.unlock();
            }

        } catch (InterruptedException e) {
        }

        for (Thread t : threads) {
            t.interrupt();
        }
        // stop the others
        for (ResponseFinder finder : finders) {
            finder.interruptSearch();
        }
        log.fine("all finders interrupted " + (System.currentTimeMillis() - start) + "ms");
        for (ResponseFinder finder : finders) {
            JSONObject response = finder.getResponse();
            if (response != null) {
                log.fine("returns response  " + (System.currentTimeMillis() - start) + "ms");
                return response;
            }
        }

        throw new RuntimeException("bug.One of the finder should have got something.");
    }

}