/*
 * The contents of this file are subject to the terms 
 * of the Common Development and Distribution License 
 * (the License).  You may not use this file except in
 * compliance with the License.
 * 
 * You can obtain a copy of the license at 
 * https://glassfish.dev.java.net/public/CDDLv1.0.html or
 * glassfish/bootstrap/legal/CDDLv1.0.txt.
 * See the License for the specific language governing 
 * permissions and limitations under the License.
 * 
 * When distributing Covered Code, include this CDDL 
 * Header Notice in each file and include the License file 
 * at glassfish/bootstrap/legal/CDDLv1.0.txt.  
 * If applicable, add the following below the CDDL Header, 
 * with the fields enclosed by brackets [] replaced by
 * you own identifying information: 
 * "Portions Copyrighted [year] [name of copyright owner]"
 * 
 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
 */

package com.sun.enterprise.tools.admingui.handlers;

import com.iplanet.jato.RequestContext;
import com.iplanet.jato.view.ContainerView;
import com.iplanet.jato.view.View;
import com.iplanet.jato.view.ViewBase;

import com.sun.enterprise.tools.admingui.util.MBeanUtil;
import com.sun.enterprise.tools.guiframework.exception.FrameworkException;
import com.sun.enterprise.tools.guiframework.view.HandlerContext;
import com.sun.enterprise.tools.guiframework.view.ViewDescriptorManager;
import com.sun.enterprise.tools.guiframework.view.descriptors.ViewDescriptor;
import com.sun.enterprise.tools.guiframework.view.DescriptorContainerView;

import java.util.ArrayList;
import java.util.Properties;
import java.util.Iterator;
import java.util.List;
import java.util.HashMap;
import java.util.Map;
import java.util.Date;
import java.util.StringTokenizer;

import javax.management.Attribute;
import javax.management.AttributeList;
import javax.management.MBeanServer;

import com.sun.enterprise.tools.admingui.util.Util;

/**
 *
 */
public class MBeanHandlers {

    /**
     *	retrieves attribute values from mbean identified by "objectName"
     *	parameter.
     *
     *	@param	reqCtx		The RequestContext
     *	@param	handlerCtx	The HandlerContext
     *
     *	@return	attributeList
     */
    public void getAttributeListFromMBean(RequestContext reqCtx, HandlerContext handlerCtx) {
	ArrayList attributeNames =
	    (ArrayList)handlerCtx.getInputValue(ATTRIBUTE_NAMES);
	if (attributeNames == null) {
	    throw new IllegalArgumentException(
		"The parameter map did not contain " + ATTRIBUTE_NAMES);
	}
	Object objectName = handlerCtx.getInputValue(OBJECT_NAME);
	if (objectName == null) {
	    throw new IllegalArgumentException(
		"The parameter map did not contain " + OBJECT_NAME);
	}
        AttributeList values = null;
	try {
            values = (AttributeList)MBeanUtil.getAttributes(
		    objectName.toString(),
		    (String[])attributeNames.toArray(new String[attributeNames.size()]));
	    // Set the output value
	} catch (Exception ex) {
            if (ex.getCause() instanceof javax.management.InstanceNotFoundException) {
                // ignore, just return null; 
                // important for the monitoring code; don't know if monitor MBean is there or not
                if (Util.isLoggableFINE()) {
                    Util.logFINE("caught: InstanceNotFoundException");
                }
            } else {
                throw new FrameworkException(
                    "Unable to get MBean attributes for object name: '"+
                    objectName+"'.", ex,
                    null, null);
            }
	}
	handlerCtx.setOutputValue(VALUE, values);
    }

    /**
     *	retrieves attribute value from mbean identified by "objectName"
     *	parameter.
     *
     *	@param	reqCtx		The RequestContext
     *	@param	handlerCtx	The HandlerContext
     *
     *	@return	attributeValue
     */
    public void getAttributeValueFromMBean(RequestContext reqCtx, HandlerContext handlerCtx) {
	String attributeName =
	    (String)handlerCtx.getInputValue(ATTRIBUTE_NAME);
	if (attributeName == null) {
	    throw new IllegalArgumentException(
		"The parameter map did not contain " + ATTRIBUTE_NAME);
	}
	Object objectName = handlerCtx.getInputValue(OBJECT_NAME);
	if (objectName == null) {
	    throw new IllegalArgumentException(
		"The parameter map did not contain " + OBJECT_NAME);
	}
	try {
            handlerCtx.setOutputValue(VALUE, MBeanUtil.getAttribute(
                        objectName.toString(), attributeName));
	    // Set the output value
	} catch (Exception ex) {
            if (ex.getCause() instanceof javax.management.InstanceNotFoundException) {
                // ignore, just return null; 
                // important for the monitoring code; don't know if monitor MBean is there or not
                if (Util.isLoggableFINE()) {
                    Util.logFINE("caught: InstanceNotFoundException");
                }
            } else {
                throw new FrameworkException(
                    "Unable to get MBean attribute for object name: '"+
                    objectName+"'.", ex,
                    null, null);
            }
	}
    }

    /**
     *	This method calls setAttributes on mbean specified by "objectName"
     *	parameter.
     *
     *	@param	reqCtx		The RequestContext
     *	@param	handlerCtx	The HandlerContext
     */
    public void setAttributeListToMBean(RequestContext reqCtx, HandlerContext handlerCtx) {
	AttributeList value = (AttributeList)handlerCtx.getInputValue(VALUE);
	Object objectName = handlerCtx.getInputValue(OBJECT_NAME);
	if (objectName == null) {
	    throw new IllegalArgumentException(
		"The parameter map did not contain " + OBJECT_NAME);
	}
	try {
	    MBeanUtil.setAttributes(objectName.toString(), value);
	} catch (Exception ex) {
	    throw new FrameworkException(
		"Error while setting attributes on MBean '"+objectName+
		"'!", ex, handlerCtx.getViewDescriptor(),
		handlerCtx.getView());
	}
    }
    
    /**
     *	This method calls setAttribute on mbean specified by "objectName"
     *	parameter. KEY has the name of the MBean attribute, and value has 
     *  the value to be saved.  If th6e value is an array, it will be converted to a
     *  comma seperated list before saving.
     *
     *	@param	reqCtx		The RequestContext
     *	@param	handlerCtx	The HandlerContext
     */
    public void setAttributeToMBean(RequestContext reqCtx, HandlerContext handlerCtx) {
	Object value = handlerCtx.getInputValue(VALUE);
	String name = (String)handlerCtx.getInputValue(KEY);
        String val = null;
        
        if (value instanceof Object[]){
            val = convertToCommaSeperatedList((Object[] ) value);
        }else{
            val = (String) value;
        }
        
	Attribute attr = new Attribute(name, val);
        
	Object objectName = handlerCtx.getInputValue(OBJECT_NAME);
	if (objectName == null) {
	    throw new IllegalArgumentException(
		"The parameter map did not contain " + OBJECT_NAME);
	}
	if (name == null) {
	    throw new IllegalArgumentException(
		"The parameter map did not contain AttributeName");
	}
	try {
	    MBeanUtil.setAttribute(objectName.toString(), attr);
	} catch (Exception ex) {
	    throw new FrameworkException(
		"Error while setting attributes on MBean '"+objectName+
		"'!", ex, handlerCtx.getViewDescriptor(),
		handlerCtx.getView());
	}
    }

    private String convertToCommaSeperatedList(Object[] values){
        String allValues = null;
         if (values != null) {
	    int len = ((Object[])values).length;
	    for (int count=0; count<len; count++) {
		String val = (String) (((Object[])values)[count]);
		if ((val == null) || (val.toString().trim().length() == 0)) {
		    continue;
		}
		allValues = (allValues == null) ? val : allValues+ ","+ val;
	    }
	 }
        return allValues;
    }
    
    /**
     *	retrieves attribute values from mbean identified by "objectName" parameter.
     *
     *	@param	reqCtx		The RequestContext
     *	@param	handlerCtx	The HandlerContext
     *
     *	@return	attributeList
     *
     */
    private Attribute split(Attribute attr, String splitChar) {
	if (attr == null || attr.getValue() == null) {
	    return attr;
	}
	String newline = System.getProperty("line.separator");
	String strValue = attr.getValue().toString();
        boolean changed = false;
	if (strValue.indexOf(splitChar) > -1) {
	    strValue = strValue.replaceAll(splitChar, newline);
            changed = true;
        }
	if (strValue.indexOf("${path.separator}") > -1) {
	    strValue = strValue.replaceAll("\\$\\{path.separator\\}", newline);
            changed = true;
	}
        return (changed) ? new Attribute(attr.getName(), strValue) : attr;
    }


    /**
     *
     */
    private Attribute unsplit(Attribute attr, String splitChar) {
	if (attr == null || attr.getValue() == null) {
	    return attr;
	}
	String strValue = attr.getValue().toString();

	String result = "";
	StringTokenizer st = new StringTokenizer(strValue, "\n\r");
	while (st.hasMoreTokens()) {
	    if (result.equals("") == false) {
		result += "${path.separator}"; //splitChar;
	    }
	    result += st.nextToken();
	}
	return new Attribute(attr.getName(), result);
    }


    /**
     *	@param	reqCtx		The RequestContext
     *	@param	handlerCtx	The HandlerContext
     */
    public void split(RequestContext reqCtx, HandlerContext handlerCtx) {
	Object value = null;
        
        Object inputList = handlerCtx.getInputValue(IN);

	String splitChar = System.getProperty("path.separator");
	if (!splitChar.equals("") && (inputList instanceof AttributeList)) {
	    AttributeList list = (AttributeList)inputList;
	    AttributeList newList = new AttributeList();
	    for (int i=0; i<list.size(); i++) {
		newList.add(i, split((Attribute)list.get(i), splitChar));
	    }
	    value = newList;
	}

	// Set the output value
	handlerCtx.setOutputValue(OUT, value);
    }


    /**
     *	This method calls setAttributes on mbean specified by "objectName" parameter
     *
     *	@param	reqCtx		The RequestContext
     *	@param	handlerCtx	The HandlerContext
     */
    public void unsplit(RequestContext reqCtx, HandlerContext handlerCtx) {
	Object value = handlerCtx.getInputValue(IN);
	String splitChar = System.getProperty("path.separator");
	if (!splitChar.equals("") && (value instanceof AttributeList)) {
	    AttributeList list = (AttributeList)value;
	    AttributeList newList = new AttributeList();
	    for (int i=0; i<list.size(); i++) {
		newList.add(i, unsplit((Attribute)list.get(i), splitChar));
	    }
	    value = newList;
	}
	handlerCtx.setOutputValue(OUT, value);
    }

    /**
     *
     *	@param	reqCtx		The RequestContext
     *	@param	handlerCtx	The HandlerContext
     *
     *	@return	attributeList
     *  returns "AttributeList" for values of all displayFields, identified by "displayNames".
     *   ignores displayFields that have null value.
     */
    public void getAttributeListFromDisplayFields(RequestContext reqCtx, HandlerContext handlerCtx) {
	ArrayList attributeNames = (ArrayList)handlerCtx.getInputValue(ATTRIBUTE_NAMES);
	if (attributeNames == null) {
	    throw new IllegalArgumentException(
		"The parameter map did not contain " + ATTRIBUTE_NAMES);
	}

	ArrayList displayNames = (ArrayList)handlerCtx.getInputValue(DISPLAY_NAMES);
	if (displayNames == null) {
	    throw new IllegalArgumentException(
	    "The parameter map did not contain " + DISPLAY_NAMES);
	}

	if (displayNames.size() != attributeNames.size()) {
	    throw new IllegalArgumentException(
	    "displayNames and attributeNames should have same number of entries!");
	}
	ContainerView view = getView(reqCtx, handlerCtx);

	AttributeList attrList = new AttributeList();
	for (int i = 0; i < attributeNames.size(); i++) {
	    Object fieldValue = view.getDisplayFieldValue((String)displayNames.get(i));
	    if (fieldValue != null) {
		attrList.add(new Attribute((String)attributeNames.get(i), fieldValue));
	    }
	}
	// Set the output value
	handlerCtx.setOutputValue(VALUE, attrList);
    }
    
     /**
     *
     *	@param	reqCtx		The RequestContext
     *	@param	handlerCtx	The HandlerContext
     *
     *	@return	attributeList
     *  returns "AttributeList" for values of all displayFields, identified by "displayNames".
     *   ignores displayFields that have null value.
     */
    public void getPropertiesListFromDisplayFields(RequestContext reqCtx, HandlerContext handlerCtx) {
	ArrayList propertyNames = (ArrayList)handlerCtx.getInputValue(PROPERTY_NAMES);
	if (propertyNames == null) {
	    throw new IllegalArgumentException(
		"The parameter map did not contain " + PROPERTY_NAMES);
	}

	ArrayList displayNames = (ArrayList)handlerCtx.getInputValue(DISPLAY_NAMES);
	if (displayNames == null) {
	    throw new IllegalArgumentException(
	    "The parameter map did not contain " + DISPLAY_NAMES);
	}

	if (displayNames.size() != propertyNames.size()) {
	    throw new IllegalArgumentException(
	    "displayNames and attributeNames should have same number of entries!");
	}
	ContainerView view = getView(reqCtx, handlerCtx);

	Properties props = new Properties();
	for (int i = 0; i < propertyNames.size(); i++) {
	    String fieldValue = (String)view.getDisplayFieldValue((String)displayNames.get(i));
	    if (fieldValue != null && fieldValue != "") {
		props.put((String)propertyNames.get(i), fieldValue);
	    }
	}
	// Set the output value
	handlerCtx.setOutputValue(VALUE, props);
    }


    // makes and attribute list out of name value pairs. names and values should be ArrayList
    public void getAttributeListFromNameValues(RequestContext reqCtx, HandlerContext handlerCtx) {
	ArrayList attributeNames = (ArrayList)handlerCtx.getInputValue(ATTRIBUTE_NAMES);
	ArrayList attributeValues = (ArrayList)handlerCtx.getInputValue(ATTRIBUTE_VALUES);
	if (attributeNames == null || attributeValues == null) {
	    throw new IllegalArgumentException(
		"The parameter map must contain " + ATTRIBUTE_NAMES + " and " + ATTRIBUTE_VALUES);
	}

	if (attributeValues.size() != attributeNames.size()) {
	    throw new IllegalArgumentException(
                ATTRIBUTE_NAMES + "and " + ATTRIBUTE_VALUES + " should have same number of entries!");
	}
        
	AttributeList attrList = new AttributeList();
	for (int i = 0; i < attributeNames.size(); i++) {
            attrList.add(new Attribute((String)attributeNames.get(i), attributeValues.get(i)));
	}
	// Set the output value
	handlerCtx.setOutputValue(VALUE, attrList);
    }
    
    /**
     *
     *	@param	reqCtx		The RequestContext
     *	@param	handlerCtx	The HandlerContext
     *
     *	@return	arrayList
     *  returns "ArrayList" for values of all displayFields, identified by "displayNames".
     *   ignores displayFields that have null value.
     */
    public void getArrayListFromDisplayFields(RequestContext reqCtx, HandlerContext handlerCtx) {
	ArrayList displayNames = (ArrayList)handlerCtx.getInputValue(DISPLAY_NAMES);
	if (displayNames == null) {
	    throw new IllegalArgumentException(
	    "The parameter map did not contain " + DISPLAY_NAMES);
	}

	ContainerView view = getView(reqCtx, handlerCtx);

	ArrayList arrayList = new ArrayList();
	for (int i = 0; i < displayNames.size(); i++) {
	    Object fieldValue = view.getDisplayFieldValue((String)displayNames.get(i));
            if (fieldValue instanceof String && ((String)(fieldValue)).length() == 0) 
                fieldValue = null;
            arrayList.add(fieldValue);
	}
	// Set the output value
	handlerCtx.setOutputValue(VALUE, arrayList);
    }
    
    /**
     *
     *	@param	reqCtx		The RequestContext
     *	@param	handlerCtx	The HandlerContext
     *
     *	@return	map
     *  returns "Map" of all displayFields, identified by "displayNames".
     *   ignores displayFields that have null value.  Use the "attributeNames" as keys.
     */
    public void getMapFromDisplayFields(RequestContext reqCtx, HandlerContext handlerCtx) {
	ArrayList displayNames = (ArrayList)handlerCtx.getInputValue(DISPLAY_NAMES);
        ArrayList keyNames = (ArrayList)handlerCtx.getInputValue(ATTRIBUTE_NAMES);
	if (displayNames == null) {
	    throw new IllegalArgumentException(
	    "The parameter map did not contain " + DISPLAY_NAMES);
	}
	ContainerView view = getView(reqCtx, handlerCtx);
        Map map = new HashMap();
	for (int i = 0; i < displayNames.size(); i++) {
	    Object fieldValue = view.getDisplayFieldValue((String)displayNames.get(i));
            if (fieldValue instanceof String && ((String)(fieldValue)).length() == 0) 
                fieldValue = null;
            map.put((String)keyNames.get(i),fieldValue);
	}
	handlerCtx.setOutputValue(VALUE, map);
    }



    /**
     *	This method calls setAttributes on mbean specified by "objectName"
     *	parameter.
     *
     *	@param	reqCtx		The RequestContext
     *	@param	handlerCtx	The HandlerContext
     */
    public void setDisplayFieldsFromAttributeList(RequestContext reqCtx, HandlerContext handlerCtx) {
	Object value = handlerCtx.getInputValue(VALUE);
	if (value == null) {
	    return;
	}

	// Get the attribute names
	ArrayList attributeNames = (ArrayList)handlerCtx.getInputValue(ATTRIBUTE_NAMES);
	if (attributeNames == null) {
	    throw new IllegalArgumentException(
		"The parameter map did not contain " + ATTRIBUTE_NAMES);
	}

	// Get the display field names
	ArrayList displayNames = (ArrayList)handlerCtx.getInputValue(DISPLAY_NAMES);
	if (displayNames == null) {
	    throw new IllegalArgumentException(
		"The parameter map did not contain " + DISPLAY_NAMES);
	}

	// Make sure they match in size
	if (displayNames.size() != attributeNames.size()) {
	    throw new IllegalArgumentException(
		"displayNames and attributeNames should have same number of entries!");
	}

	// Get the view which holds the display fields to set
	ContainerView view = getView(reqCtx, handlerCtx);
	AttributeList attrList = (AttributeList)value;
        for (int i=0; i<displayNames.size(); i++) {
            String attrName = (String)attributeNames.get(i);
            int j=0;
            while ((j<attrList.size()) &&
                   !((Attribute)attrList.get(j)).getName().equals(attrName)) {
                j++;
            }
            if (j < attrList.size()) {
                Object attrValue = ((Attribute)attrList.get(j)).getValue();
		view.setDisplayFieldValue((String)displayNames.get(i), attrValue);
            }
        }
    }
    
    /**
     *	This method calls setDisplayFields from java.util.Properties Object"
     *	parameter.
     *
     *	@param	reqCtx		The RequestContext
     *	@param	handlerCtx	The HandlerContext
     */
    public void setDisplayFieldsFromPropertiesList(RequestContext reqCtx, HandlerContext handlerCtx) {
	Object value = handlerCtx.getInputValue(VALUE);
	if (value == null) {
	    return;
	}

	// Get the attribute names
	ArrayList propertyNames = (ArrayList)handlerCtx.getInputValue(PROPERTY_NAMES);
	if (propertyNames == null) {
	    throw new IllegalArgumentException(
		"The parameter map did not contain " + PROPERTY_NAMES);
	}

	// Get the display field names
	ArrayList displayNames = (ArrayList)handlerCtx.getInputValue(DISPLAY_NAMES);
	if (displayNames == null) {
	    throw new IllegalArgumentException(
		"The parameter map did not contain " + DISPLAY_NAMES);
	}

	// Make sure they match in size
	if (displayNames.size() != propertyNames.size()) {
	    throw new IllegalArgumentException(
		"displayNames and attributeNames should have same number of entries!");
	}

	// Get the view which holds the display fields to set
	ContainerView view = getView(reqCtx, handlerCtx);
        Properties props = (Properties)value;
        for (int i=0; i<displayNames.size(); i++) {
            String propertyValue = props.getProperty(propertyNames.get(i).toString());
            view.setDisplayFieldValue((String)displayNames.get(i), propertyValue);
            
        }
    }
    
    
    /**
     *	This method calls setDisplayFields from List "
     *	parameter.
     *
     *	@param	reqCtx		The RequestContext
     *	@param	handlerCtx	The HandlerContext
     */
    public void setDisplayFieldsFromList(RequestContext reqCtx, HandlerContext handlerCtx) {
	
	ArrayList valueList = (ArrayList)handlerCtx.getInputValue("valueList");
	if (valueList == null) {
	    throw new IllegalArgumentException(
		"The parameter map did not contain valueList" );
	}

	// Get the display field names
	ArrayList displayNames = (ArrayList)handlerCtx.getInputValue(DISPLAY_NAMES);
	if (displayNames == null) {
	    throw new IllegalArgumentException(
		"The parameter map did not contain " + DISPLAY_NAMES);
	}

	// Make sure they match in size
	if (displayNames.size() != valueList.size()) {
	    throw new IllegalArgumentException(
		"displayNames and valueList should have same number of entries!");
	}

	// Get the view which holds the display fields to set
	ContainerView view = getView(reqCtx, handlerCtx);
        for (int i=0; i < valueList.size(); i++) {
            view.setDisplayFieldValue((String)displayNames.get(i), (String)valueList.get(i));
        }
    }
    

//	for (int i = 0;  i<attrList.size(); i++) {
//	    Attribute attr = (Attribute)attrList.get(i);
//	    int j = 0;
//	    while ((j < attributeNames.size()) &&
//		    !attr.getName().equals(attributeNames.get(j))) {
//		j++;
//	    }
//	    if (j < attributeNames.size()) {
//		Object attrValue = attr.getValue();
////		if (attrValue != null) {
////		    attrValue = attrValue.toString();
////		}
//		view.setDisplayFieldValue((String)displayNames.get(j), attrValue);
//	    }
//	}
//    }

    /**
     *	@param	reqCtx		The RequestContext
     *	@param	handlerCtx	The HandlerContext
     */
    public static ContainerView getView(RequestContext reqCtx, HandlerContext handlerCtx) {
	ViewDescriptor viewDesc = null;
	Object value = handlerCtx.getInputValue(VIEW_DESCRIPTOR_NAME);
	if (value == null) {
	    viewDesc = handlerCtx.getViewDescriptor();
	} else {
	    // Get the ViewDescriptorManager
	    ViewDescriptorManager mgr = ViewDescriptorManager.getInstance();

	    // Get the ViewDescriptor using a List or a dotted name.
	    if (value instanceof List) {
		// Iterate through the keys to find the child ViewDescriptor
		Iterator it = ((List)value).iterator();
		String key = it.next().toString();
		viewDesc = mgr.getViewDescriptor(key);
		if (viewDesc == null) {
		    throw new IllegalArgumentException(
			"Top-level ViewDescriptor '"+key+"' not found!");
		}
		while (it.hasNext()) {
		    key = it.next().toString();
		    viewDesc = viewDesc.getChildDescriptor(key);
		    if (viewDesc == null) {
			throw new IllegalArgumentException(
			    "Child ViewDescriptor '"+key+"' not found!");
		    }
		}
	    } else if (value instanceof String) {
                View view = handlerCtx.getView();
                DescriptorContainerView descView = (DescriptorContainerView)
                    (((ViewBase)view).getParentViewBean());
                return (ContainerView)descView.getChild((String)value);

//                String viewName = (String)value;
//                
//                StringTokenizer st = new StringTokenizer(viewName, ".");
//                if (st.hasMoreTokens()) {
//                    String key = st.nextToken();
//                    viewDesc = mgr.getViewDescriptor(key);
//                    // the name didn't start at the top level, look in current top.
//                    if (viewDesc == null) {
//                        View view = handlerCtx.getView();
//                        DescriptorContainerView descContainerView = (DescriptorContainerView)
//                            (((ViewBase)view).getParentViewBean());
//                        viewDesc = descContainerView.getViewDescriptor();
//                        if (viewDesc != null) 
//                            viewDesc = viewDesc.getChildDescriptor(key);
//                        if (viewDesc == null) {
//                            throw new IllegalArgumentException(
//                                "Bad value for '"+VIEW_DESCRIPTOR_NAME+"'....("+value.toString()+")");
//                        }
//                    }
//                }
//                while (st.hasMoreTokens()) {
//                    viewDesc = viewDesc.getChildDescriptor(st.nextToken());
//                    if (viewDesc == null) {
//                        throw new IllegalArgumentException(
//                            "Bad value for '"+VIEW_DESCRIPTOR_NAME+"'. ("+value.toString()+")");
//                    }
//                }
	    } else {
                throw new IllegalArgumentException(
                    "Unknown type for "+VIEW_DESCRIPTOR_NAME+". ("+value.toString()+")");
            }
	}
        View view = viewDesc.getView(reqCtx);
        while ((view instanceof ContainerView) == false)
            view = view.getParent();
	return (ContainerView)view;
    }
    

    /**
     *	Retrieves a JMX Attribute value.  The Attribute should be stored in a
     *	request attribute with key identified by the "key" parameter.
     *
     *	@param	reqCtx		The RequestContext
     *	@param	handlerCtx	The HandlerContext
     *
     *	@return	The attributes value (or null) 
     */
    public void getJMXAttributeValue(RequestContext reqCtx, HandlerContext handlerCtx) {
	// Get the Request attribute key that is holding the JMX Attribute
    	Object val = handlerCtx.getInputValue("JMXAttribute");
	if (val == null) {
	    throw new FrameworkException(
		"The input value for 'JMXAttribute' was not specified.",
		null, null);
	}
	
// FIXME: This method should not pull the value from an attribute, it should
// FIXME: expect the value itself!
	// Get the Attribute (or AttributeList)

    	Attribute att = null;
	if (val instanceof AttributeList) {
	    AttributeList list = ((AttributeList)val);
	    // Only get the 1st element of an array
	    if (list.size() > 0) {
		att = (Attribute)list.get(0);
	    }
	} else {
	    // Expect the request parameter to be an attribute
	    att = (Attribute)val;
	}

	// Set the output value
	handlerCtx.setOutputValue(VALUE, (att != null) ? att.getValue() : null);
    }

    public void restoreDefaultValues(RequestContext reqCtx, HandlerContext handlerCtx) {
	ContainerView view = getView(reqCtx, handlerCtx);
        
        ArrayList displayNames = (ArrayList)handlerCtx.getInputValue(DISPLAY_NAMES);
        ArrayList modelNames = (ArrayList)handlerCtx.getInputValue(ATTRIBUTE_NAMES);
        String objectName = (String)handlerCtx.getInputValue(OBJECT_NAME);
        String[] params = new String[1];
        String[] types = {"java.lang.String"};
        for (int i = 0; i < modelNames.size(); i++) {
            params[0] = (String)modelNames.get(i);
            String displayName = (String)displayNames.get(i);
            if (view.getDisplayFieldValue(displayName) == null) {
                view.setDisplayFieldValue(displayName,                
                    MBeanUtil.getAttribute(objectName, params[0]));
            } else {
                view.setDisplayFieldValue(displayName,
                    MBeanUtil.invoke(objectName, "getDefaultAttributeValue", params, types));  
            }
        }
    }
        

    public static final String IN			= "in";
    public static final String OUT			= "out";
    public static final String KEY			= "key";
    public static final String VALUE			= "value";
    public static final String OBJECT_NAME		= "objectName";
    public static final String DISPLAY_NAMES		= "displayNames";
    public static final String ATTRIBUTE_NAMES		= "attributeNames";
    public static final String PROPERTY_NAMES		= "propertyNames";
    public static final String ATTRIBUTE_NAME		= "attributeName";
    public static final String ATTRIBUTE_VALUES		= "attributeValues";
    public static final String DATA_CONVERSION_TYPE     = "dataConversionType";
    public static final String VIEW_DESCRIPTOR_NAME	= "viewDescriptorName";
}
