001/*
002 The contents of this file are subject to the Mozilla Public License Version 1.1
003 (the "License"); you may not use this file except in compliance with the License.
004 You may obtain a copy of the License at http://www.mozilla.org/MPL/
005 Software distributed under the License is distributed on an "AS IS" basis,
006 WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the
007 specific language governing rights and limitations under the License.
008
009 The Original Code is "LazyConnection.java".  Description:
010 "Connection that lazily connects right before sending the first message"
011
012 The Initial Developer of the Original Code is University Health Network. Copyright (C)
013 2013.  All Rights Reserved.
014
015 Contributor(s): ______________________________________.
016
017 Alternatively, the contents of this file may be used under the terms of the
018 GNU General Public License (the "GPL"), in which case the provisions of the GPL are
019 applicable instead of those above.  If you wish to allow use of your version of this
020 file only under the terms of the GPL and not to allow others to use your version
021 of this file under the MPL, indicate your decision by deleting  the provisions above
022 and replace  them with the notice and other provisions required by the GPL License.
023 If you do not delete the provisions above, a recipient may use your version of
024 this file under either the MPL or the GPL.
025 */
026
027package ca.uhn.hl7v2.app;
028
029import java.io.IOException;
030import java.net.InetAddress;
031import java.util.concurrent.ExecutorService;
032import java.util.concurrent.TimeUnit;
033
034import ca.uhn.hl7v2.HL7Exception;
035import ca.uhn.hl7v2.llp.LLPException;
036import ca.uhn.hl7v2.model.Message;
037
038/**
039 * A LazyConnection behaves like an ordinary connection except for the fact
040 * that the actual socket connection is created lazily right before the
041 * first message is sent over the associated Initiator. Server-side connections
042 * are always non-lazy.
043 */
044public class LazyConnection implements Connection {
045
046    private ConnectionData data;
047    private ExecutorService executor;
048    private Connection activeConnection;
049    private LazyInitiator initiator;
050
051    public LazyConnection(ConnectionData data, ExecutorService executor) {
052        this.data = data;
053        this.executor = executor;
054        this.initiator = new LazyInitiator(this);
055    }
056
057    public void activate() {
058        if (isEstablished()) activeConnection.activate();
059    }
060
061    public Initiator getInitiator() {
062        if (isEstablished()) return activeConnection.getInitiator();
063        return initiator;
064    }
065
066    public void close() {
067        if (isEstablished()) {
068            activeConnection.close();
069            activeConnection = null;
070        }
071    }
072
073    public boolean isOpen() {
074        return isEstablished() && activeConnection.isOpen();
075    }
076
077    public ExecutorService getExecutorService() {
078        if (isEstablished()) return activeConnection.getExecutorService();
079        return executor;
080    }
081
082    public InetAddress getRemoteAddress() {
083        if (isEstablished())
084            return activeConnection.getRemoteAddress();
085        return null;
086    }
087
088        public Integer getRemotePort() {
089        if (isEstablished()) {
090            return activeConnection.getRemotePort();
091        }
092        return null;
093        }
094
095    boolean isEstablished() {
096        return activeConnection != null && activeConnection.isOpen();
097    }
098
099    void establishConnection() throws HL7Exception {
100        try {
101            activeConnection = ConnectionFactory.openEagerly(data, executor);
102        } catch (Exception e) {
103            throw new HL7Exception(e);
104        }
105    }
106
107
108    static class LazyInitiator implements Initiator {
109
110        private LazyConnection connection;
111        private long timeoutMillis = 10000;
112
113        LazyInitiator(LazyConnection connection) {
114            this.connection = connection;
115        }
116
117        public synchronized Message sendAndReceive(Message out) throws HL7Exception, LLPException, IOException {
118            if (!connection.isEstablished()) {
119                connection.establishConnection();
120                setTimeout(timeoutMillis, TimeUnit.MILLISECONDS);
121            }
122            return connection.getInitiator().sendAndReceive(out);
123        }
124
125        public synchronized void setTimeout(long timeout, TimeUnit timeunit) {
126            if (connection.isEstablished())
127                connection.getInitiator().setTimeout(timeout, timeunit);
128            else
129                this.timeoutMillis = timeunit.toMillis(timeout);
130        }
131
132        public void setTimeoutMillis(int timeout) {
133            setTimeout(timeout, TimeUnit.MILLISECONDS);
134        }
135    }
136
137}