/*
 * Copyright 2008 the original author or authors.
 *
 * 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 org.rioproject.fdh;

import net.jini.core.lookup.ServiceID;
import org.rioproject.associations.AssociationDescriptor;
import org.rioproject.opstring.ClassBundle;
import org.rioproject.opstring.ServiceElement;
import org.rioproject.loader.ClassBundleLoader;

import java.util.List;

/**
 * The FaultDetectionHandlerFactory class provides static methods to 
 * create FaultDetectionHandler instances
 *
 * @author Dennis Reedy
 */
public class FaultDetectionHandlerFactory {
    
    /**
     * Get a FaultDetectionHandler from the ServiceElement
     * 
     * @param sElem The ServiceElement
     * @param cl The delegation ClassLoader used to load the 
     * FaultDetectionHandler, or the current thread's context class 
     * loader if cl is null. 
     * @return A FaultDetectionHandler created and
     * initialized. A new FaultDetectionHandler will be created each time.
     * If there are problems creating the FaultDetectionHandler a null will
     * be returned
     *
     * @throws Exception If there are errors creating the FaultDetectionHandler
     */
    public static FaultDetectionHandler<ServiceID>
        getFaultDetectionHandler(ServiceElement sElem, ClassLoader cl)
    throws Exception {
        return (getFaultDetectionHandler(sElem.getFaultDetectionHandlerBundle(),
                                         cl));
    }
    
   
    /**
     * Get a FaultDetectionHandler from the AssociationDescriptor
     * 
     * @param aDesc The AssociationDescriptor
     * @param cl The delegation ClassLoader used to load the 
     * FaultDetectionHandler, or the current thread's context class 
     * loader if cl is null. 
     * @return A FaultDetectionHandler created and
     * initialized. A new FaultDetectionHandler will be created each time.
     * If there are problems creating the FaultDetectionHandler a null will
     * be returned
     *
     * @throws Exception If there are errors creating the FaultDetectionHandler
     */
    public static FaultDetectionHandler<ServiceID>
        getFaultDetectionHandler(AssociationDescriptor aDesc, ClassLoader cl)
    throws Exception {        
        return (getFaultDetectionHandler(aDesc.getFaultDetectionHandlerBundle(),
                                         cl));
    }
    
    /**
     * Load the FaultDetectionHandler from a ClassBundle
     *   
     * @param fdhBundle The ClassBundle
     * @param cl The delegation ClassLoader used to load the 
     * FaultDetectionHandler, or the current thread's context class 
     * loader if cl is null. 
     * @return A FaultDetectionHandler created and
     * initialized. A new FaultDetectionHandler will be created each time. If
     * the fdhBundle is null, an
     * {@link AdminFaultDetectionHandler} will be
     * created. If there are problems creating the FaultDetectionHandler a
     * null will be returned
     *
     * @throws Exception If there are errors creating the FaultDetectionHandler
     */
    @SuppressWarnings("unchecked")
    public static FaultDetectionHandler<ServiceID>
        getFaultDetectionHandler(ClassBundle fdhBundle, ClassLoader cl)
    throws Exception {
           
        Class fdhClass;
        if(fdhBundle==null) {
            fdhBundle = new ClassBundle(
                "org.rioproject.fdh.AdminFaultDetectionHandler");
        }
        if(cl==null)
            fdhClass = ClassBundleLoader.loadClass(fdhBundle);
        else
            fdhClass = ClassBundleLoader.loadClass(fdhBundle);
        FaultDetectionHandler fdh =
            (FaultDetectionHandler)fdhClass.newInstance();
        fdhBundle.runKnownMethods(fdh);
        return (fdh);
    }

    /**
     * Get the ClassBundle for a FaultDetectionHandler declaration
     *
     * @param fdhClassName The class name of the FaultDetectionHandler
     * @param configuration Configuration arguments
     * @return A ClassBundle created based on the input arguments
     */
    public static ClassBundle
        getClassBundle(String fdhClassName, String configuration) {
        ClassBundle bundle = new ClassBundle(fdhClassName);
        bundle.addMethod("setConfiguration",
                         new Object[] {new String[]{configuration}});
        return(bundle);
    }

    /**
     * Get the ClassBundle for a FaultDetectionHandler declaration
     *
     * @param fdhClassName The class name of the FaultDetectionHandler
     * @param configArgs Configuration arguments
     * @return A ClassBundle created based on the input arguments
     */
    public static ClassBundle
        getClassBundle(String fdhClassName, String[] configArgs) {
        ClassBundle bundle = new ClassBundle(fdhClassName);
        bundle.addMethod("setConfiguration",
                         new Object[] {configArgs});
        return(bundle);
    }

    /**
     * Get the ClassBundle for a FaultDetectionHandler declaration
     *
     * @param fdhClassName The class name of the FaultDetectionHandler
     * @param configArgs List of configuration arguments
     * @return A ClassBundle created based on the input arguments
     */
    public static ClassBundle
        getClassBundle(String fdhClassName, List<String> configArgs) {
        String[] args = configArgs.toArray(new String[configArgs.size()]);
        ClassBundle bundle = new ClassBundle(fdhClassName);
        bundle.addMethod("setConfiguration", new Object[] {args});
        return(bundle);
    }

}

@@ -1732,32 +1732,24 @@
 r%3CServiceID%3E
-%0A       
  getFaultDet
@@ -1907,49 +1907,8 @@
 e(),
-%0A                                        
  cl)
@@ -2576,32 +2576,24 @@
 r%3CServiceID%3E
-%0A       
  getFaultDet
@@ -2673,24 +2673,16 @@
 eption %7B
-        
 %0A       
@@ -2758,49 +2758,8 @@
 e(),
-%0A                                        
  cl)
@@ -3544,24 +3544,16 @@
 rviceID%3E
-%0A       
  getFaul
@@ -3636,20 +3636,8 @@
 n %7B%0A
-           %0A
     
@@ -3726,33 +3726,16 @@
 sBundle(
-%0A                
 %22org.rio
@@ -3926,32 +3926,36 @@
 oader.loadClass(
+cl, 
 fdhBundle);%0A    
@@ -3985,28 +3985,16 @@
 er fdh =
-%0A           
  (FaultD
@@ -4406,32 +4406,24 @@
  ClassBundle
-%0A       
  getClassBun

Improve readability