/* * Copyright (c) 2008-2009 "Neo Technology," * Network Engine for Objects in Lund AB [http://neotechnology.com] * * This file is part of Neo4j. * * Neo4j is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.neo4j.remote; import java.net.URI; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import org.neo4j.helpers.Service; final class ProtocolService { ConnectionTarget get( URI resourceUri ) { return getSiteFactory( resourceUri ).create( resourceUri ); } synchronized void register( Transport factory ) { if ( factory == null ) { throw new IllegalArgumentException( "the RemoteSiteFactory may not be null." ); } for ( String protocol : factory.protocols ) { @SuppressWarnings( "hiding" ) Set<Transport> factories = implementations.get( protocol ); if ( factories == null ) { factories = new HashSet<Transport>(); implementations.put( protocol, factories ); } factories.add( factory ); } } private final Map<String, Set<Transport>> implementations = new HashMap<String, Set<Transport>>(); private final Iterable<Transport> factories; ProtocolService() { factories = Service.load( Transport.class ); } private synchronized Transport getSiteFactory( URI resourceUri ) { Transport result = loadSiteFactory( resourceUri ); if ( result == null ) { for ( Transport factory : factories ) { register( factory ); } result = loadSiteFactory( resourceUri ); } if ( result != null ) { return result; } throw new RuntimeException( "No implementation available to handle resource URI: " + resourceUri + "\nSupported protocolls are: " + allProtocols() ); } private Transport loadSiteFactory( URI resourceUri ) { String protocol = resourceUri.getScheme(); Iterable<Transport> factories = implementations.get( protocol ); if ( factories == null ) { return null; } for ( Transport factory : factories ) { try { if ( factory.handlesUri( resourceUri ) ) { return factory; } } catch ( Exception ex ) { // Silently drop } } return null; } private String allProtocols() { boolean comma = false; StringBuilder result = new StringBuilder(); for ( Iterable<Transport> factories : implementations.values() ) { for ( Transport factory : factories ) { for ( String protocol : factory.protocols ) { if ( comma ) { result.append( ", " ); } result.append( protocol ); comma = true; } } } if ( comma ) { return result.toString(); } else { return "None!"; } } }