/*
 * This software is distributed under following license based on modified BSD
 * style license.
 * ----------------------------------------------------------------------
 * 
 * Copyright 2009 The Nimbus2 Project. All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * 
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer. 
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE NIMBUS PROJECT ``AS IS'' AND ANY EXPRESS
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
 * NO EVENT SHALL THE NIMBUS PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * 
 * The views and conclusions contained in the software and documentation are
 * those of the authors and should not be interpreted as representing official
 * policies, either expressed or implied, of the Nimbus2 Project.
 */
package jp.ossc.nimbus.service.repository;

import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.NotBoundException;
import java.rmi.AlreadyBoundException;
import java.rmi.registry.Registry;
import java.rmi.registry.LocateRegistry;
import java.util.Set;
import java.util.HashSet;
import java.util.Iterator;

import jp.ossc.nimbus.core.ServiceBase;

/**
 * RMIリポジトリサービス。<p>
 *
 * @author M.Takata
 */
public class RMIRepositoryService extends ServiceBase implements Repository, RMIRepositoryServiceMBean{
    
    private static final long serialVersionUID = -6700424417078458836L;
    
    private String host;
    private int port = Registry.REGISTRY_PORT;
    private boolean isCreateRegistry;
    
    private Registry registry;
    
    public void setHostName(String host){
        this.host = host;
    }
    public String getHostName(){
        return host;
    }
    
    public void setPort(int port){
        this.port = port;
    }
    public int getPort(){
        return port;
    }
    
    public boolean isCreateRegistry(){
        return isCreateRegistry;
    }
    public void setCreateRegistry(boolean isCreate){
        isCreateRegistry = isCreate;
    }
    
    public void startService() throws Exception{
        if(isCreateRegistry){
            try{
                registry = LocateRegistry.createRegistry(port);
            }catch(RemoteException e){
                registry = LocateRegistry.getRegistry(port);
            }
        }else{
            registry = LocateRegistry.getRegistry(host, port);
        }
    }
    
    @SuppressWarnings("unchecked")
    public <T> T get(String name){
        try{
            return (T)registry.lookup(name);
        }catch(RemoteException e){
            return null;
        }catch(NotBoundException e){
            return null;
        }
    }
    
    public boolean register(String name, Object obj){
        if(!(obj instanceof Remote)){
            return false;
        }
        try{
            registry.bind(name, (Remote)obj);
            return true;
        }catch(AlreadyBoundException e){
            return false;
        }catch(RemoteException e){
            return false;
        }
    }
    
    public boolean unregister(String name){
        try{
            registry.unbind(name);
            return true;
        }catch(NotBoundException e){
            return false;
        }catch(RemoteException e){
            return false;
        }
    }
    
    public boolean isRegistered(String name){
        return get(name) != null;
    }
    
    public Set<String> nameSet(){
        Set<String> result = new HashSet<String>();
        try{
            String[] names = registry.list();
            if(names != null){
                for(int i = 0; i < names.length; i++){
                    result.add(names[i]);
                }
            }
        }catch(RemoteException e){
        }
        return result;
    }
    
    public <T> Set<T> registeredSet(){
        Set<T> result = new HashSet<T>();
        Iterator<String> names = nameSet().iterator();
        while(names.hasNext()){
            T obj = get(names.next());
            if(obj != null){
                result.add(obj);
            }
        }
        return result;
    }
}