Java tutorial
/* * CGateInterface - A library to allow interaction with Clipsal C-Gate. * * Copyright 2008, 2009, 2012, 2017 Dave Oxley <dave@daveoxley.co.uk> * * 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 License 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 com.daveoxley.cbus; import com.workplacesystems.utilsj.threadpool.ThreadObjectFactory; import com.workplacesystems.utilsj.threadpool.ThreadPool; import com.workplacesystems.utilsj.threadpool.ThreadPoolCreator; import com.workplacesystems.utilsj.threadpool.WorkerThread; import java.io.BufferedReader; import java.io.IOException; import java.util.ArrayList; import java.util.Iterator; import java.util.NoSuchElementException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.commons.pool.impl.GenericObjectPool; import org.apache.commons.pool.impl.GenericObjectPool.Config; /** * * @author Dave Oxley <dave@daveoxley.co.uk> */ public class Response implements Iterable<String> { private final static Log log = LogFactory.getLog(Response.class); private final static ThreadPool response_pool; static { ThreadPoolCreator tp_creator = new ThreadPoolCreator() { public ThreadObjectFactory getThreadObjectFactory() { return new ThreadObjectFactory() { @Override public void initialiseThread(Thread thread) { thread.setName("Response"); } @Override public void activateThread(Thread thread) { } @Override public void passivateThread(Thread thread) { } }; } public Config getThreadPoolConfig() { Config config = new Config(); config.minIdle = 2; config.maxIdle = 5; config.testOnBorrow = false; config.testOnReturn = true; config.whenExhaustedAction = GenericObjectPool.WHEN_EXHAUSTED_GROW; return config; } public String getThreadPoolName() { return "ResponsePool"; } }; response_pool = new ThreadPool(tp_creator.getThreadObjectFactory(), tp_creator.getThreadPoolConfig()); } private final Object response_mutex = new Object(); private final Object iterator_mutex = new Object(); private BufferedReader response_reader; private WorkerThread response_thread; private ArrayList<String> array_response; private boolean response_generated = false; Response(BufferedReader response_reader) throws CGateException { try { this.response_reader = response_reader; this.response_thread = (WorkerThread) response_pool.borrowObject(); this.response_thread.execute(new Runnable() { public void run() { synchronized (iterator_mutex) { array_response = new ArrayList<String>(); } try { boolean has_more = true; while (has_more) { String response = Response.this.response_reader.readLine(); synchronized (Response.this.iterator_mutex) { array_response.add(response); Response.this.iterator_mutex.notifyAll(); } has_more = responseHasMore(response); } if (log.isDebugEnabled()) { for (String response : array_response) { log.debug("response: " + response); } } } catch (IOException e) { new CGateException(e); } finally { Response.this.response_reader = null; Response.this.response_thread = null; synchronized (Response.this.response_mutex) { synchronized (Response.this.iterator_mutex) { Response.this.response_generated = true; Response.this.response_mutex.notifyAll(); Response.this.iterator_mutex.notifyAll(); } } } } }, null); } catch (Exception e) { throw new CGateException(e); } } static boolean responseHasMore(String response) { return response.substring(3, 4).equals("-"); } ArrayList<String> toArray() { synchronized (response_mutex) { while (!response_generated) { try { response_mutex.wait(); } catch (InterruptedException ie) { } } } return array_response; } public Iterator<String> iterator() { return new Iterator<String>() { private int index = 0; public boolean hasNext() { synchronized (iterator_mutex) { while (array_response == null || (index >= array_response.size() && !response_generated)) { try { iterator_mutex.wait(); } catch (InterruptedException ie) { } } if (index < array_response.size()) return true; if (response_generated) return false; throw new IllegalStateException("Impossible"); } } public String next() { synchronized (iterator_mutex) { if (index >= array_response.size()) throw new NoSuchElementException(); return array_response.get(index++); } } public void remove() { throw new UnsupportedOperationException("remove not supported"); } }; } public void handle200() throws CGateException { ArrayList<String> resp_array = toArray(); if (resp_array.isEmpty()) throw new CGateException(); String resp_str = resp_array.get(resp_array.size() - 1); String result_code = resp_str.substring(0, 3).trim(); if (!result_code.equals("200")) throw new CGateException(resp_str); } }