001/** 002 * Copyright (C) 2014 Universidade de Aveiro, DETI/IEETA, Bioinformatics Group - http://bioinformatics.ua.pt/ 003 * 004 * This file is part of Dicoogle/dicoogle. 005 * 006 * Dicoogle/dicoogle is free software: you can redistribute it and/or modify 007 * it under the terms of the GNU General Public License as published by 008 * the Free Software Foundation, either version 3 of the License, or 009 * (at your option) any later version. 010 * 011 * Dicoogle/dicoogle is distributed in the hope that it will be useful, 012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 014 * GNU General Public License for more details. 015 * 016 * You should have received a copy of the GNU General Public License 017 * along with Dicoogle. If not, see <http://www.gnu.org/licenses/>. 018 */ 019/* 020 * To change this template, choose Tools | Templates 021 * and open the template in the editor. 022 */ 023 024package pt.ua.dicoogle.rGUI; 025 026import java.io.IOException; 027import java.io.Serializable; 028import java.net.InetSocketAddress; 029import java.net.Socket; 030import java.net.SocketAddress; 031import java.net.SocketException; 032import java.nio.channels.Channel; 033import java.nio.channels.SelectionKey; 034import java.nio.channels.Selector; 035import java.nio.channels.SocketChannel; 036import java.rmi.RMISecurityManager; 037import java.rmi.server.RMIClientSocketFactory; 038import java.util.ArrayList; 039import java.util.List; 040import java.util.Set; 041import javax.rmi.ssl.SslRMIClientSocketFactory; 042 043/** 044 * 045 * @author Samuel Campos <samuelcampos@ua.pt> 046 */ 047@Deprecated 048public class MultihomeSslRMIClientSocketFactory extends SslRMIClientSocketFactory 049 implements RMIClientSocketFactory, Serializable { 050 private static final long serialVersionUID = 11L; 051 052 //private final SslRMIClientSocketFactory factory; 053 054 public MultihomeSslRMIClientSocketFactory() { 055 super(); 056 } 057 058 @Override 059 public Socket createSocket(String hostString, int port) throws IOException { 060 final String[] hosts = hostString.split("!"); 061 final int nhosts = hosts.length; 062 063 if (nhosts < 2) 064 return super.createSocket(hostString, port); 065 066 List<IOException> exceptions = new ArrayList<IOException>(); 067 068 Selector selector = Selector.open(); 069 070 for (String host : hosts) { 071 SocketChannel channel = SocketChannel.open(); 072 channel.configureBlocking(false); 073 channel.register(selector, SelectionKey.OP_CONNECT); 074 SocketAddress addr = new InetSocketAddress(host, port); 075 076 077 try{ 078 channel.connect(addr); 079 }catch(SocketException e){ 080 //System.err.println("Sockect Exception: "+ e.getMessage() + ", Host: " + host + ", Port: "+ port); 081 } 082 } 083 SocketChannel connectedChannel = null; 084 085 connect: 086 while (true) { 087 if (selector.keys().isEmpty()) { 088 throw new IOException("Connection failed for " + hostString + 089 ": " + exceptions); 090 } 091 selector.select(); // you can add a timeout parameter in millseconds 092 Set<SelectionKey> keys = selector.selectedKeys(); 093 if (keys.isEmpty()) { 094 throw new IOException("Selection keys unexpectedly empty for " + 095 hostString + "[exceptions: " + exceptions + "]"); 096 } 097 for (SelectionKey key : keys) { 098 SocketChannel channel = (SocketChannel) key.channel(); 099 key.cancel(); 100 try { 101 channel.configureBlocking(true); 102 channel.finishConnect(); 103 connectedChannel = channel; 104 break connect; 105 } catch (IOException e) { 106 exceptions.add(e); 107 } 108 } 109 } 110 111 assert connectedChannel != null; 112 113 // Close the channels that didn't connect 114 for (SelectionKey key : selector.keys()) { 115 Channel channel = key.channel(); 116 if (channel != connectedChannel) 117 channel.close(); 118 } 119 120 final Socket socket = connectedChannel.socket(); 121 122 // We've determined that we can connect to this host but we didn't use 123 // the right factory so we have to reconnect with the factory. 124 String host = socket.getInetAddress().getHostAddress(); 125 socket.close(); 126 return super.createSocket(host, port); 127 } 128 129}