Package com.sun.jdmk.comm

Source Code of com.sun.jdmk.comm.HtmlObjectPage

/*
* @(#)file      HtmlObjectPage.java
* @(#)author    Sun Microsystems, Inc.
* @(#)version   1.44
* @(#)lastedit      07/03/08
*
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 2007 Sun Microsystems, Inc. All Rights Reserved.
*
* The contents of this file are subject to the terms of either the GNU General
* Public License Version 2 only ("GPL") or the Common Development and
* Distribution License("CDDL")(collectively, the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy of the
* License at http://opendmk.dev.java.net/legal_notices/licenses.txt or in the
* LEGAL_NOTICES folder that accompanied this code. See the License for the
* specific language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file found at
*     http://opendmk.dev.java.net/legal_notices/licenses.txt
* or in the LEGAL_NOTICES folder that accompanied this code.
* Sun designates this particular file as subject to the "Classpath" exception
* as provided by Sun in the GPL Version 2 section of the License file that
* accompanied this code.
*
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
*
*       "Portions Copyrighted [year] [name of copyright owner]"
*
* Contributor(s):
*
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding
*
*       "[Contributor] elects to include this software in this distribution
*        under the [CDDL or GPL Version 2] license."
*
* If you don't indicate a single choice of license, a recipient has the option
* to distribute your version of this file under either the CDDL or the GPL
* Version 2, or to extend the choice of license to its licensees as provided
* above. However, if you add GPL Version 2 code and therefore, elected the
* GPL Version 2 license, then the option applies only if the new code is made
* subject to such option by the copyright holder.
*
*
*/


package com.sun.jdmk.comm;



// java import
//
import java.util.Date;
import java.util.TimeZone;
import java.text.DateFormat;
import java.util.Set;
import java.util.ArrayList;
import java.util.Enumeration;
import java.net.URLEncoder;
import java.lang.reflect.Constructor;

// jmx import
//
import javax.management.MBeanServer;
import javax.management.MBeanInfo;
import javax.management.MBeanAttributeInfo;
import javax.management.MBeanOperationInfo;
import javax.management.MBeanParameterInfo;
import javax.management.MalformedObjectNameException;
import javax.management.InstanceNotFoundException;
import javax.management.MBeanException;
import javax.management.ReflectionException;
import javax.management.IntrospectionException;
import javax.management.JMRuntimeException;
import javax.management.ObjectName;
import javax.management.AttributeList;
import javax.management.Attribute;
import javax.management.AttributeNotFoundException;
import javax.management.MBeanServerFactory;
import javax.management.loading.ClassLoaderRepository;


// jmx RI import
//
import com.sun.jdmk.Enumerated;

class HtmlObjectPage extends HtmlPage {

    // --------------------------------------------------------
    // CONSTRUCTORS
    // --------------------------------------------------------
    /**
     * Constructs a new HtmlObjectPage.
     */
    public HtmlObjectPage(MBeanServer f, boolean r, boolean w, HtmlAdaptorServer server) {
        super(f,r,w);
        this.server = server;
    }


    // --------------------------------------------------------
    // PUBLIC METHODS
    // --------------------------------------------------------

    public void buildPage(String req) {
        if (logger.finerOn()) {
            logger.finer("buildPage","Handle request = "+req);
        }

        String objNameStr = req;
        int disp = req.indexOf("?");

        if (disp >= 0){
            objNameStr = req.substring(0,disp);
        }
        objNameStr = fromUrlName(objNameStr);

        if (!analyseObj(objNameStr)) {
            return;
        }

        // Start the object(MBean) page.
        //
        if (!startPage(objNameStr)) {
            return;
        }

        // Build the attribute part of the object(MBean) page.
        //       
        buildAttributes(objNameStr);

        // Build the operations part of the object(MBean) page.
        //
        buildOperations();

        // End the object(MBean) page.
        //
        endPage();
    }

    /**
     * Ends the object(MBean) page.
     */
    public void endPage() {
        if (logger.finerOn()) {
            logger.finer("endPage","End the object(MBean) page.");
        }
        add2Page(stopBody());
    }

    /**
     * Starts the object(MBean) page.
     */
    public boolean startPage(String objNameStr) {
        if (logger.finerOn()) {
            logger.finer("startPage","Start the object(MBean) page for = "+objNameStr);
        }
 
  String safeObjNameStr = translateNameToHtmlFormat(objNameStr);

        if (meta != null){
            htmlPage.append(buildHeadMeta(HtmlDef.objectPageTitle +" of "+ safeObjNameStr, meta));
        } else {
            htmlPage.append(buildHead(HtmlDef.objectPageTitle +" of "+ safeObjNameStr));
        }
        htmlPage.append(startBody(null)); // Null for color.

        // Build the title of the page.
        //
        add2Page("<TABLE WIDTH=100%>");
        add2Page("<TR>");
        add2Page("<TD ALIGN=left><H2>"+HtmlDef.objectPageTitle+"</H2></TD>");
        add2Page("<TD ALIGN=right VALIGN=top>["+HtmlDef.jdmkVersion+"]</TD>");
        add2Page("</TR></TABLE>");

        // Build the MBean object name and class information
        //
        add2Page("<UL type=disc><LI><B>MBean Name:</B> " + safeObjNameStr);
        add2Page("<LI><B>MBean Java Class:</B> "+manipulatedObj.getClassName());
        add2Page("</UL>");

        add2Page("<TABLE WIDTH=100%><TR>");
        add2Page("<TD ALIGN=LEFT>"+HtmlDef.LISTOFMBEAN+"</TD>");

        add2Page("<TD ALIGN=CENTER>");
        add2Page("<FORM ACTION=" + HtmlDef.AUTOREFRESH + toUrlName(objNameStr) + " METHOD=GET>");
        add2Page("Reload Period in seconds:<BR><INPUT type=text name=period value="+autoRefresh+" SIZE=2>"+
                 "<INPUT TYPE=submit VALUE=\"Reload\"></FORM></TD>");


        add2Page("<TD ALIGN=RIGHT><BR><FORM ACTION=\"" +
                 HtmlDef.ADMIN+
                 HtmlDef.ADMIN_OBJECT+
                 HtmlDef.ADMIN_QUEST2+
                 "&keysName="+URLEncoder.encode(manipulatedObjName.getKeyPropertyListString())+
                 "&domainName="+URLEncoder.encode(manipulatedObjName.getDomain())+
                 "&className="+URLEncoder.encode(manipulatedObj.getClassName())+
                 "&action="+HtmlDef.actionDelete + "&\" METHOD=GET>");
        add2Page("<FONT SIZE=-1><INPUT type=submit VALUE=\""+HtmlDef.actionDelete+"\" ></FONT></FORM></TD>");
        add2Page("</TR></TABLE>");
        return true;
    }

    public boolean setObjectValue(String objNameStr, String reqStr) {

        if (logger.finerOn()) {
            logger.finer("setObjectValue","[name="+objNameStr+", request="+reqStr+"]");
        }


        StringBuffer errBuf = new StringBuffer();
        boolean      error  = false;

        objNameStr = fromUrlName(objNameStr);
  String safeObjNameStr = translateNameToHtmlFormat(objNameStr);

        // Parse the request and build 3 lists
        // one for the property name.
        // one for the string value.
        // one for the type name of this value.
        //
        if (! reqStr.startsWith("?")) {
            buildError("Incorrect request form, must start with ?",
           HtmlDef.HTTP_ERROR_BAD_REQUEST_ID + " " + HtmlDef.HTTP_ERROR_BAD_REQUEST);
            return false;
        }

        reqStr = reqStr.substring(1);

        int index;
        int indexValue;
        ArrayList anArray = null;           ;
        AttributeList attlist = new AttributeList();

        String  propReqStr  = reqStr;
        boolean done = false;
        String  propStr = null;
        String  typeStr = null;
        String  valueStr;
        String ind = null;

        try {
            manipulatedObjName = getObjectNameByObjNameStr(objNameStr);
        } catch (MalformedObjectNameException e) {
            if (logger.finestOn()) {
                logger.finest("setObjectValue","Exception = "+e);
            }
            buildError("The format of the string ["+ safeObjNameStr +"] does not correspond to a valid ObjectName <P>"+ e.toString() +"<P>",
           HtmlDef.HTTP_ERROR_MALFORMED_OBJECTNAME_ID +" "+ HtmlDef.HTTP_ERROR_MALFORMED_OBJECTNAME);
            return false;
        }

        while (!done) {
            // A property name separator is always "&".
            //
            index = reqStr.indexOf('&');
            if (index < 0) {
                // No more entries, after this one
                //
                propReqStr = reqStr;
                done       = true;
            } else {
                propReqStr = reqStr.substring(0, index);
                reqStr     = reqStr.substring(index + 1);
            }

            // Parse this one.
            //
            index = propReqStr.indexOf('=');

            if (index < 0) {
                done = true;
                // We cannot continue.
                //
                buildError("Syntax error in request ["+propReqStr+"]",
         HtmlDef.HTTP_ERROR_BAD_REQUEST_ID + " " + HtmlDef.HTTP_ERROR_BAD_REQUEST);
                return false;
            }

            propStr  = propReqStr.substring(0, index);
            valueStr = propReqStr.substring(index + 1);

            if ((valueStr != null) && (propStr != null) &&
                (valueStr.length() != 0) && (propStr.length() != 0)) {
                // Remove %0D in the begining of property name.
                //
                //if (propStr.startsWith("%0D") || propStr.startsWith("%0d")) {
                while (propStr.startsWith("%")) {
                    propStr = propStr.substring(3);
                }
                // Substitute the %HH character on valueStr.
                //
                valueStr = decodeUrl(valueStr);

                // The propertyName is built with <propertyName>%2B<value type>.
                //

                if (logger.finerOn()) {
                    logger.finer("setObjectValue","Parsing property name ["+propStr+"]");
                }

                index = propStr.indexOf("%2B", 0);
                if (index < 0) {
                    index = propStr.indexOf("%2b", 0);
                }
                if (index >= 0) {
                    typeStr = propStr.substring(index + 3);
                    propStr = propStr.substring(0, index);
                } else {
                    typeStr = "String";
                }

                // This is an indexed property, format AnArray%5B0%5D.
                //
                ind = "";
                if (propStr.indexOf("%5B") > 0) { 
                    ind = propStr.substring(propStr.indexOf("%5B")+3,propStr.indexOf("%5D"));
                    propStr = propStr.substring(0, propStr.indexOf("%5B"));
                }
                else if(propStr.indexOf("%5b") > 0) {
                    ind = propStr.substring(propStr.indexOf("%5b")+3,propStr.indexOf("%5d"));
                    propStr = propStr.substring(0, propStr.indexOf("%5b"));
                }

                if (logger.finerOn()) {
                    logger.finer("setObjectValue",
        "Get Name = ["+propStr+"] "+(ind.length()>0?"["+ind+"] ":" ")+"Type = ["+typeStr+"]"+" Value = ["+valueStr+"]");
                }


    // Now let's build the value for this attribute
    //
                Object attvalue = null;

    // Case for an Enumerated
    //
                if (propStr.startsWith("Enumerated%29")) {
                    propStr = propStr.substring(13);
        // do not set this Enumerated's value if it is the dummy display "---" for WO Enumerated
        if (!valueStr.equals(HtmlDef.HTML_WO_DEFAULT)) {
      try {
          // get info on this attribute to know if it is readable
          MBeanAttributeInfo[] attrInfos = mbs.getMBeanInfo(manipulatedObjName).getAttributes();
          int i = 0;
          boolean found = false;
          while ( (i < attrInfos.length) && ( !(found=attrInfos[i].getName().equals(propStr))) ) {
        i++ ;
          }
          // Get the class for this attribute
          Class ocl;
          if (found == true) {
        if (attrInfos[i].isReadable()) {
            ocl = mbs.getAttribute(manipulatedObjName, propStr).getClass();
        } else {
            ocl = loadClass(typeStr);
        }
        if (logger.finerOn()) {
            logger.finer("setObjectValue","Got Class for Enumerated attribute["+ propStr +"] is ["+ ocl.getName() +"]");
        }
          } else {
        throw new AttributeNotFoundException("Could not find attribute ["+ propStr +
                     "] in MBean ["+ manipulatedObjName +"]");
          }

          Class sc = ocl.getSuperclass();
          if ( (sc != null) && (com.sun.jdmk.Enumerated.class.isAssignableFrom(sc)) ) {
        Constructor[] cons = ocl.getDeclaredConstructors();
        for (int consi = 0 ;consi <cons.length;consi++) {
            Class[] cl = cons[consi].getParameterTypes();
            if (cl.length == 1
          && cl[0].getName().endsWith("String")) {
          if (logger.finerOn()) {
              logger.finer("setObjectValue","Found constructor for Enumerated = "+ocl.getName());
          }
          Object[] param = new Object[1];
          param[0] = valueStr;
          attvalue = cons[consi].newInstance(param);
            }
        }
          } else {
        buildError("Cannot get constructor of "+typeStr+" for setting "+propStr+": Invalid Enumerated.",
             HtmlDef.HTTP_ERROR_INVALID_PROP_VALUE_ID+" "+HtmlDef.HTTP_ERROR_INVALID_PROP_VALUE);
        return false;
          }
      } catch (Exception e) {
          if (logger.finestOn()) {
        logger.finest("setObjectValue","Exception = "+e);
          }
          buildError("Cannot get constructor of "+ typeStr +" for setting "+ propStr +" of MBean "+
               manipulatedObjName.toString()+"<P>The following exception has been produced:<BR>"+e.toString()+"<P>",
               HtmlDef.HTTP_ERROR_INVALID_PROP_VALUE_ID+" "+HtmlDef.HTTP_ERROR_INVALID_PROP_VALUE);
          return false;
      }
        }
                } else {
                    // Convert to the new type if needed.
                    //
                    attvalue = stringToObject(typeStr,valueStr);
                }

    // Value will be added to list to be set only if not null
                if (attvalue != null) {
        if (ind.length() > 0) {
      // This is an array,
      // treat each element as value of an array.
      //
      if (anArray == null) {
          anArray = new ArrayList();
      }
      try {
          indexValue = java.lang.Integer.parseInt(ind);
      } catch (NumberFormatException e) {
          if (logger.finestOn()) {
        logger.finest("setObjectValue","Exception = "+e);
          }
          buildError("Invalid Index value ["+ind+"] for property ["+propStr+"]<P>",
               HtmlDef.HTTP_ERROR_BAD_REQUEST_ID+" "+HtmlDef.HTTP_ERROR_BAD_REQUEST);
          return false;
      }                       
      anArray.add(indexValue, attvalue);
      if (logger.finerOn()) {
          logger.finer("setObjectValue","Add element "+indexValue+" to arrayList "+propStr+" type = "+attvalue.getClass().getName());
      }
        } else {
      // This is not an array,
      // treat values as independant attributes.
      //
      Attribute myAttr = new Attribute(propStr, attvalue);
      attlist.add(myAttr);

      indexValue = -1;
      if (logger.finerOn()) {
          logger.finer("setObjectValue",
          "added [name="+ myAttr.getName() +",value="+ myAttr.getValue() +",type="+ typeStr +
          "] to list of attributes to set");
      }
        }
    }
            } else {
                if (logger.finerOn()) {
                    logger.finer("setObjectValue","Got null value or property");
                }
            }
        } // END while (!done) LOOP

        if (anArray != null) {
            attlist.add(new Attribute(propStr,getArray(typeStr,anArray)));
        }

        // Call MBeanServer to set the values.
        //
        AttributeList resAttList = null;
        try {
            resAttList = mbs.setAttributes(manipulatedObjName,attlist);
      if (logger.finerOn()) {
    logger.finer("setObjectValue","Invoked setAttributes() on "+ manipulatedObjName +". Checking result.");
      }
        } catch (InstanceNotFoundException e) {
            if (logger.finestOn()) {
                logger.finest("setObjectValue","Exception = "+e);
            }
            buildError("Setting of attributes has produced an exception <P>"+e.toString()+"<P>",
           HtmlDef.HTTP_ERROR_INSTANCE_NOT_FOUND_ID+" "+HtmlDef.HTTP_ERROR_INSTANCE_NOT_FOUND);
            return false;
        } catch (ReflectionException e) {
            if (logger.finestOn()) {
                logger.finest("setObjectValue","Exception = "+e);
            }
            buildError("Setting of attributes has produced an exception <P>" +e.toString() + "<P>",
           HtmlDef.HTTP_ERROR_REFLECTION_ID + " " + HtmlDef.HTTP_ERROR_REFLECTION);
            return false;
        } catch (JMRuntimeException e) {
            if (logger.finestOn()) {
                logger.finest("setObjectValue","Exception = "+e);
            }
            buildError("The MBeanServer throws a JMRuntimeException when setting attributes for ["+ safeObjNameStr +"] :<BR>"+e,
           HtmlDef.HTTP_ERROR_MBEAN_ID+" "+HtmlDef.HTTP_ERROR_MBEAN);
            return false;
        }

        if (attlist.size() != resAttList.size()) {
            if (logger.finerOn()) {
                logger.finer("setObjectValue","Initial Number of attribute to set = "+attlist.size()+" and effectively set = "+resAttList.size());
            }
            int noset = attlist.size()-resAttList.size();
            String mess = noset+"/"+attlist.size()+" attribute(s) were not set:<BR><UL>";
            int k,l;
            for (k = attlist.size()-1 ; k >=; k--){
                for ( l = resAttList.size()-1 ; l >= 0 ; l--){
                    if (((Attribute)attlist.get(k)).getName().equals(((Attribute)resAttList.get(l)).getName()))
                        break;
                }
                if (l == -1)
                    mess += "<LI>"+((Attribute)(attlist.get(k))).getName();
            }
            mess += "</UL><HR>";
            buildError(mess, HtmlDef.HTTP_ERROR_SET_ATTRIBUTES_ID + " " + HtmlDef.HTTP_ERROR_SET_ATTRIBUTES);
            return false;
        }
        return true;
    }

    public String getMeta(){
        return (meta);
    }

    public void buildMeta(String objName) {
        String objNameStr = objName.substring(0,objName.indexOf("?"));

        try {
            autoRefresh = Integer.parseInt(objName.substring(objName.indexOf("period=")+7));
        } catch (NumberFormatException e){
            autoRefresh = minAutoRefresh;
        }
        if (autoRefresh == 0) {
            meta = " ";
        } else {
            if (autoRefresh < minAutoRefresh) {
                autoRefresh = minAutoRefresh;
            }
            meta = "<META HTTP-EQUIV=REFRESH CONTENT=\"";
            meta += autoRefresh+"; URL="+HtmlDef.AUTOREFRESH+objName+"\">";
        }
    }


    // --------------------------------------------------------
    // PROTECTED METHODS
    // --------------------------------------------------------

    /**
     * Returns the Html representation of an instance of com.sun.jdmk.Enumerated,
     * depending on the access rights of this attribute.
     */
    protected String enumToHtml(Enumerated o, MBeanAttributeInfo attrInfo) {

  if (attrInfo == null) {
      if (logger.finestOn()) {
                logger.finest("enumToHtml","Got null MBeanAttributeInfo parameter. Returning empty string");
            }
      return "";
  }

  String attrName = attrInfo.getName();
  String attrType = attrInfo.getType();
  boolean r = attrInfo.isReadable();
  boolean w = attrInfo.isWritable();

  // o can be null for a Write-Only attribute,
  // so we need to handle this case:
  //
  if (o == null) {
      if (logger.finestOn()) {
                logger.finest("enumToHtml","Got null Enumerated object for ["+ attrName +"]. attrInfo says [READ="+ r +",WRITE="+ w +"]");
            }
      // make sure it is considered not readable
      r = false;
      if (w == true) {
    // try to build an instance of this attribute to display to the user selectable values
    try {
        final Class cl = loadClass(attrType);
        o = (Enumerated) cl.newInstance() ;
    } catch (Exception e) {
        // could not instantiate: won't be able to build list of selectable values
        w = false;
        if (logger.finestOn()) {
      logger.finest("enumToHtml","Could not create instance of ["+ attrType +"] : "+ e);
        }
    }
      }
  }

        StringBuffer html = new StringBuffer(100);
        String ele = "";

  if (w == true) {
      // if writable, we display a select box to allow to change the value
      html.append("<SELECT NAME=\"") ;
      html.append("(Enumerated)"+ attrName +"+"+ attrType +"\" >");
      if (r == false) {
    html.append("<OPTION SELECTED>"+ HtmlDef.HTML_WO_DEFAULT);
      }
      for (Enumeration e = o.valueStrings(); e.hasMoreElements(); ) {
    ele = (String)e.nextElement();
    html.append("<OPTION");
    if ( (r == true) && (o.toString() != null) && (o.toString().equals(ele)) ) {
        // if it is also readable we display the current value as the one initially selected    
        html.append(" SELECTED ");
    }
    html.append( ">" + ele);
      }
      html.append( "</SELECT>" );
  } else if (r == true) {
      // read-only case: we display only the current string value
      html.append("Enumerated"+ o.toString()); // "Enumerated" tag will be removed by buildAttributes method
  } else {
      // if it happens there has been a bug: debug msg + html will be returned empty
      if (logger.finestOn()) {
                logger.finest("enumToHtml","Attribute is unreadable and unwritable. Returning empty string");
            }
  }
        return html.toString();
    }


    /**
     * Replace inverses of HtmlPage.
     */
    protected void inverseS(String[] a ,int lo, int hi){
        MBeanAttributeInfo ti = attinfo[lo];
        attinfo[lo] = attinfo[hi];
        attinfo[hi] = ti;       
        String t = a[lo];
        a[lo] = a[hi];
        a[hi] = t;
    }


    // --------------------------------------------------------
    // PRIVATE METHODS
    // --------------------------------------------------------

    /**
     * Gets the MBean information.
     */
    private boolean analyseObj(String objNameStr) {
        if (logger.finerOn()) {
            logger.finer("analyseObj","Collect MBean information for = "+objNameStr);
        }

  String safeObjNameStr = translateNameToHtmlFormat(objNameStr);

        // Verify the given object name for an MBean.
        //
        try {
            manipulatedObjName = getObjectNameByObjNameStr(objNameStr);
        } catch (MalformedObjectNameException e) {
            if (logger.finestOn()) {
                logger.finest("analyseObj","Exception = "+e);
            }
            buildError("The format of the string ["+safeObjNameStr+"] does not correspond to a valid ObjectName <P>" +e.toString() + "<P>",
           HtmlDef.HTTP_ERROR_MALFORMED_OBJECTNAME_ID + " " + HtmlDef.HTTP_ERROR_MALFORMED_OBJECTNAME);
            return false;
        }

        // Get the m-bean information.
        //
        if (manipulatedObjName != null) {
            try {
                manipulatedObj = mbs.getMBeanInfo(manipulatedObjName);
            } catch(InstanceNotFoundException e) {
                if (logger.finestOn()) {
                    logger.finest("analyseObj","Exception = "+e);
                }
                buildError("Unable to get MBeanInfo for ["+safeObjNameStr+"]",
         HtmlDef.HTTP_ERROR_INSTANCE_NOT_FOUND_ID + " " + HtmlDef.HTTP_ERROR_INSTANCE_NOT_FOUND);
                return false;
            } catch(IntrospectionException e) {
                if (logger.finestOn()) {
                    logger.finest("analyseObj","Exception = "+e);
                }
                buildError("Unable to get MBeanInfo for ["+safeObjNameStr+"]",
         HtmlDef.HTTP_ERROR_INTROSPECTION_ID + " " + HtmlDef.HTTP_ERROR_INTROSPECTION);
                return false;
            } catch (ReflectionException e) {
                if (logger.finestOn()) {
                    logger.finest("analyseObj","Exception = "+e);
                }
                buildError("Unable to get MBeanInfo for ["+safeObjNameStr+"]",
         HtmlDef.HTTP_ERROR_REFLECTION_ID + " " + HtmlDef.HTTP_ERROR_REFLECTION);
                return false;
            }
        }

        // No MBean information, return with an error.
        //
        if (manipulatedObj == null) {
            buildError("Unable to get MBeanInfo for ["+manipulatedObjName+"]",
           HtmlDef.HTTP_ERROR_INSTANCE_NOT_FOUND_ID + " " + HtmlDef.HTTP_ERROR_INSTANCE_NOT_FOUND);
            return false;
        }

  // Get attributes info
        //
        attinfo = checkedAttributeInfo(manipulatedObj.getAttributes());
        propertyName = new String[attinfo.length];
        propertyView = new String[attinfo.length];
        for (int j = propertyName.length-1; j >=0 ; j--) {
            propertyName[j] = attinfo[j].getName();
        }
        // Sort the attributes by name.
        quicksort(propertyName,0,propertyName.length-1);

        // Build the list of displayable attributes string values
        //
        for (int j = propertyName.length-1; j >=0 ; j--) {
      // call getStringValue even for WO attr, as it returns what we want to display
            propertyView[j] = getStringValue(manipulatedObjName, attinfo[j]);
            if (logger.finerOn()) {
                logger.finer("analyseObj","MBean attribute: "+propertyName[j] +"=" +propertyView[j]);
            }
        }
        return true;
    }

    private MBeanAttributeInfo[] checkedAttributeInfo(MBeanAttributeInfo[] orig) {
  if(orig == null)
      return null;
 
  MBeanAttributeInfo[] attr = new MBeanAttributeInfo[orig.length];
  for(int i = 0; i < attr.length; i++) {
      if(orig[i]!= null)
    attr[i] = orig[i];
      else
    attr[i] = new MBeanAttributeInfo("null_MBeanAttributeInfo",
             null,
             "The attribute info at index"+
             "[" + i + "] is null. Please"+
             " check the MBeanInfo.",
             true,
             false,
             false);
  }
 
  return attr;
    }
   
    private MBeanOperationInfo[] checkedOperationInfo(MBeanOperationInfo[] orig) {
  if(orig == null)
      return null;
 
  MBeanOperationInfo[] oper = new MBeanOperationInfo[orig.length];
  for(int i = 0; i < oper.length; i++) {
      if(orig[i]!= null)
    oper[i] = orig[i];
      else
    oper[i] = new MBeanOperationInfo("null_MBeanOperationInfo",
             "The operation info at index"+
             "[" + i + "] is null. Please"+
             " check the MBeanInfo.",
             null,
             null,
             MBeanOperationInfo.INFO);
  }
 
  return oper;
    }
   
    /**
     * Builds the attribute part of the object(MBean) page.
     */
    private void buildAttributes(String objNameStr) {
        if (logger.finerOn()) {
            logger.finer("buildAttributes","Build attribute part for = "+objNameStr);
        }

        // Add the MBean description to the page,
        // if one is provided.
        //
        String desc = manipulatedObj.getDescription();
        if (desc != null && desc.length() > 0 ) {
            add2Page("<HR><H3>MBean description:</H3><P>"+desc+"<P>");
        }

        // Build a attribute table.
        // Table format:
        //
        // +----------+------+--------+-------+
        // | Name | Type | Access | Value |
        // +----------+------+--------+-------+
        // ...
        // +----------+------+--------+------+
        //
        // Then a apply button for sending the modifications.
        //
        add2Page("<HR><H3>List of MBean attributes:</H3>"+HtmlDef.PF);

        if (logger.finerOn()) {
            logger.finer("buildAttributes","Found "+attinfo.length+" attributes(s)");
        }

        /*
         * No attributes to process.
         * Return with an appropriate message in the html page.
         */
        if (attinfo.length == 0) {
            add2Page("<I>No Attributes</I><P>");
            return;
        }

        /*
         * Found attributes to process.
         * Return with the list of attributes in the html page.
         */

        // Build a form.
        // The name of INPUT field is propertyName[i] '+' propertyType[i]
        // We can be sure about the type, when receiving the form request.
        //
        add2Page("<FORM ACTION=" + HtmlDef.SETFORM + toUrlName(objNameStr) + " METHOD=GET>");

        boolean hasInput = false;

        // Add the table header.
        //
        add2Page("<TABLE ALIGN=center BORDER=1 WIDTH=100% CELLPADDING=3>" );
        add2Page("<TR>");
        add2Page("<TH WIDTH=23%> Name </TH><TH WIDTH=35%> Type </TH><TH WIDTH=7%> Access </TH><TH WIDTH=35%> Value </TH>");
        add2Page("</TR>");

        for (int i = 0; i < propertyName.length; i++) {

            if (propertyName[i] == null ) {
                continue; // next iter of for loop (ie next attribute)
            }

            String attType = usualType(attinfo[i].getType());

            // Start an attribute entry for the table.
            //
            add2Page("<TR>");

            // Add the property cell to the attribute entry.
            //
            String ai = attinfo[i].getDescription();
            if (ai != null && ai.length() >0) {
                add2Page("<TD><A HREF=\"javascript:alert('"+translateNameToHtmlFormat(ai)+"');\"><B>" + propertyName[i] + "</B></A></TD>" );
            } else {
                add2Page("<TD><B>" + propertyName[i] + "</B></TD>" );
            }

            // Add the property type cell to the attribute entry.
            //
            add2Page("<TD ALIGN=RIGHT>" + attType + "</TD>" );

            // Add the access cell and value cell to the attribute entry.
            // NOTE: The choice of representation for the value depends
            // on the property access.
            //
            // READ ONLY
            if (attinfo[i].isReadable() && ! attinfo[i].isWritable()){
                add2Page("<TD ALIGN=center> RO </TD>");

    if (propertyView[i].startsWith("Enumerated")) {      // handle Enumerated case first as Enumerated is not
                    add2Page("<TD>" +propertyView[i]. substring(10) + "</TD>"); // recognized by the checkType method.
    } else if (propertyView[i].startsWith(HtmlDef.HTML_UNAVAILABLE)) {
                    add2Page("<TD>" + propertyView[i] + "</TD>");
                } else if (attType != null &&
         attType.equals("javax.management.ObjectName")) {
                    add2Page("<TD><A HREF=\""+ HtmlDef.VIEWOBJECTRES+toUrlName(propertyView[i]) +"\">"+ propertyView[i] +"</A></TD>");
                } else if (isArrayType(attType)) {
                    add2Page(buildArrayRef(propertyName[i], objNameStr, "view the values of "+propertyName[i]));
    } else if (!checkType(attType)) {
                    add2Page("<TD><I>Type Not Supported</I>: ["+ translateNameToHtmlFormat(propertyView[i]) +"]</TD>"); // toString() output
                } else {
                    add2Page("<TD><PRE>" + translateNameToHtmlFormat(propertyView[i]) + "</PRE></TD>");
                }
            }
            // WRITE ONLY
            else if (!attinfo[i].isReadable() && attinfo[i].isWritable()){
                hasInput = true; // flag: we will need to add an "Apply" button

                add2Page("<TD ALIGN=center> WO </TD>");

    if (propertyView[i].startsWith("<SELECT NAME=\"(Enumerated)")) {
        add2Page("<TD>"+propertyView[i]+"</TD>");
    } else if (!checkType(attType)) {
                    add2Page("<TD><I>Type Not Supported</I></TD>");
                } else if (attType.endsWith("Boolean") || attType.endsWith("boolean")) {
                    add2Page("<TD>"+boolToHtml(propertyName[i],attType,propertyView[i],false)+"</TD>");
                } else {
                    if (isArrayType(attType)) {
                        if (!checkType(attType)) {
                            propertyView[i] = "Write only for "+propertyName[i]+"[] Not supported ";
                        }
                        add2Page("<TD>"+propertyView[i]+"</TD>");
                    } else {
                        add2Page("<TD><INPUT TYPE=\"text\" NAME=\""+ propertyName[i] +"+"+ attType +"\" SIZE=34%></TD>");
                    }
                }

            }
            // READ WRITE
            else if (attinfo[i].isReadable() && attinfo[i].isWritable()){
                hasInput = true; // flag: we will need to add an "Apply" button

                add2Page("<TD ALIGN=center> RW </TD>");

    if (propertyView[i].startsWith("<SELECT NAME=\"(Enumerated)")) {
        add2Page("<TD>"+propertyView[i]+"</TD>");
    } else if (propertyView[i].startsWith(HtmlDef.HTML_UNAVAILABLE)) {
                    add2Page("<TD>" + propertyView[i] + "</TD>");
    } else if (!checkType(attType)) {
                    add2Page("<TD><I>Type Not Supported</I>: ["+ translateNameToHtmlFormat(propertyView[i]) +"]</TD>"); // toString() output
                } else if (propertyView[i].startsWith("<SELECT NAME=\"(Enumerated)")) {
                    add2Page("<TD>"+propertyView[i]+"</TD>");
                } else if (attType.endsWith("Boolean") || attType.endsWith("boolean")) {
                    add2Page("<TD>" + boolToHtml(propertyName[i],attType,propertyView[i],true)+ "</TD>");
                } else if (isArrayType(attType)) {
                    add2Page(buildArrayRef(propertyName[i], objNameStr, "view the values of "+propertyName[i]));
                } else {
                    htmlPage.append("<TD><INPUT TYPE=\"text\" NAME=\"" +
                                    propertyName[i] "+" + attType + "\" ");
                    htmlPage.append("VALUE=\"" + translateNameToHtmlFormat(propertyView[i]) + "\" ");
                    htmlPage.append("SIZE=34%");
                    add2Page(">");
                    if (attType.equals("javax.management.ObjectName")) {
                        if (propertyView[i].equals(" ") || propertyView[i].equals("")) {
                            htmlPage.append("<A HREF=\""+HtmlDef.VIEWOBJECTRES+toUrlName(propertyView[i])+"\"></A>");
                        } else {
                            htmlPage.append("<A HREF=\""+HtmlDef.VIEWOBJECTRES+toUrlName(propertyView[i])+"\">view</A>");
                        }
                    }
                    add2Page("</TD>");
                }
            } else {
                add2Page("<TD> ?? </TD>");
                add2Page("<TD>" + propertyView[i] + "</TD>");
            }
            // End of the attribute entry.
            //
            add2Page("</TR>");

        } // END for LOOP

        // End of the attribute table.
        //
        add2Page("</TABLE>");

        // Add the button to send back the modifications,
        // if there is any input fields.
        //
        add2Page("<P>");
        add2Page("<TABLE WIDTH=100%><TR>");
        if (hasInput) {
            add2Page("<TD ALIGN=LEFT><INPUT TYPE=submit VALUE=\""+HtmlDef.setChangesBut+"\"></TD>");
        } else {
            add2Page("<TD ALIGN=LEFT></TD>");
        }
        add2Page("</TR></TABLE></FORM>");
    }


    /**
     * Builds the operations part of the object(MBean) page.
     */
    private void buildOperations() {
        if (logger.finerOn()) {
            logger.finer("buildOperations","Build operations part");
        }

        String actionStr = null;
        String ai = null;
        MBeanOperationInfo[] op =
      checkedOperationInfo(manipulatedObj.getOperations());

        // Build a list of MBean operations.
        // List format:
        //
        // operation description
        //
        // +-------------+-----------+------------+
        // | return type | operation | parameters |
        // |             |           |  ...       |
        // +-------------+-----------+------------+
        // ...
        // +-------------+-----------+------------+
        //
        add2Page("<HR><H3>List of MBean operations:</H3>"+HtmlDef.PF);

        if (logger.finerOn()) {
            logger.finer("buildOperations","Found "+op.length+" operation(s)");
        }

        /*
         * No operations to process.
         * Return with an appropriate message in html page.
         */
        if (op.length == 0) {
            add2Page("<I>No Operations</I><P>");
            return;
        }

        /*
         * Found operations to process.
         * Return with the list of operations in the html page.
         */
        for (int i = op.length-1; i >=0 ; i--) {
            ai = op[i].getDescription();

            // Build the operation button and input fields form.
            //
            actionStr = buildOperationWithParam(op[i].getReturnType(), op[i].getName(), op[i].getSignature());

            // Add the operation description and
            // the operation button and input fields form.
            //
            if (actionStr != null) {
                if (ai != null && ai.length() > 0) {
                    add2Page("<HR><A HREF=\"javascript:alert('"+translateNameToHtmlFormat(ai)+"');\"><B>Description of " +op[i].getName() + "</B></A>");
                } else {
                    add2Page("<HR><B>"+op[i].getName()+"</B>");
                }
                add2Page(actionStr);
            }
        }
    }


    /**
     * Builds a form containing an operation with its possible parameters.
     */
    private String buildOperationWithParam(String returnType, String action, MBeanParameterInfo[] paramList) {
        if (logger.finerOn()) {
            logger.finer("buildOperationWithParam","Build operation for = "+action);
        }

        boolean support = true;
        String propType = null;
        String param = null;
        StringBuffer str = new StringBuffer(50);

        // Do we support the operation ?
        //
        int max = paramList.length;
        for (int i = 0; i < max; i++) {
            propType = paramList[i].getType();
            if (propType == null ||
    !checkType(propType) ||
    isArrayType(propType)) {
                support = false;
                break;
            }
        }
        if (!support) {
            str.append("  <I>(Operation Not Supported)</I><P>");
        }

        // Start a form, containing the operation table.
        //
        if (support) {
            str.append("<FORM ACTION=" + HtmlDef.INVOKEACTION + toUrlName(manipulatedObjName.toString())+"/action="+action);
            str.append( " METHOD=GET>" + HtmlDef.PF);
        }
        str.append("<TABLE>" + HtmlDef.PF);

        // Add the operation return type entry to the operation table.
        //
        str.append("<TR><TD>"+returnType+"</TD>"+HtmlDef.PF);

        // Add the operation name to the operation table.
        //
        if (!support) {
            str.append("<TD>"+action+"</TD>"+HtmlDef.PF);
        } else {
            str.append("<TD><INPUT TYPE=SUBMIT NAME=\"action\" VALUE=\""+action+"\"></TD>"+HtmlDef.PF);
        }

        // Analyse the parameters and add them to operation table.
        //
        for (int i = 0; i < max; i++) {
            propType = paramList[i].getType();

            // Build the paramaters.
            //
            if (paramList[i].getName() != null &&
    paramList[i].getName().length() > 0) {
                param = paramList[i].getName();
            } else {
                param = "param"+i;
            }
            if (i != 0) str.append("<TD></TD>");
            String ai = paramList[i].getDescription();
            if (ai != null && ai.length() > 0) {
                str.append("<TD>("+propType+")<A HREF=\"javascript:alert('"+translateNameToHtmlFormat(ai)+"');\">" +param+"</A></TD>"+HtmlDef.PF);
            } else {
                str.append("<TD>("+propType+")" +param+"</TD>"+HtmlDef.PF);
            }

            if (!support) {
                str.append("<TD></TD>" + HtmlDef.PF);
            } else if (propType.endsWith("Boolean") || propType.endsWith("boolean")) {
                str.append("<TD>" + boolToHtml(param, propType,"true",true) + "</TD>" + HtmlDef.PF);
            } else {
                // Add input to the form.
                //
                str.append("<TD><INPUT TYPE=\"text\" NAME=\"" + param +  "+" + propType + "\" ");
                str.append("SIZE=50%");
                str.append( "></TD>" + HtmlDef.PF);   
            }
            str.append("</TR><TR><TD></TD>" + HtmlDef.PF);
        }

        // End the form and operation table.
        //
        str.append("</TR></TABLE>" + HtmlDef.PF);
        if (support) {
            str.append("</FORM>" + HtmlDef.PF);
        }

        return str.toString();
    }


    /**
     * Builds the link to the array page.
     */   
    private String buildArrayRef(String name, String objName, String value) {
        return new String("<TD> <A HREF=\"" + HtmlDef.VIEWPROPERTY + "/" +
                          name + toUrlName(objName) + "\">" + value + "</A> </TD>");
    }


    private String getStringValue(ObjectName o, MBeanAttributeInfo attrInfo) {

        Object result = null;
  boolean r = attrInfo.isReadable();
  boolean w = attrInfo.isWritable();

        // Get the attribute value.
        //
        try {
            if (logger.finerOn()) {
                logger.finer("getStringValue","Build displayable value for attribute ["+ attrInfo.getName() +"] of object ["+o.toString()+"]");
            }
      if (r == true) {
            result = mbs.getAttribute(o, attrInfo.getName()) ;
      }
        } catch (Exception e) {
      Exception ee = null ;
      if (e instanceof javax.management.RuntimeMBeanException) {
    ee = ((javax.management.RuntimeMBeanException) e).getTargetException();
      } else if (e instanceof javax.management.MBeanException) {
    ee = ((javax.management.MBeanException) e).getTargetException();
      }
      if (logger.finestOn()) {
    logger.finest("getStringValue","Cannot get value: "+ e +" [wrapped exception: "+ ee +"]");
      }
      if (ee == null) {
    return (HtmlDef.HTML_UNAVAILABLE +": ["+ e.toString() +"]");
      } else {
    return (HtmlDef.HTML_UNAVAILABLE +": "+ e.getClass().getName() +" wraps ["+ ee.toString() +"]");
      }
        }
 
        // Date to representable HTML format.
        //
        if (result instanceof Date){
            DateFormat df = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG);
            // java BUG : the TZ of the DateFormat is not set correctly with the method getDateTimeInstance.
            // By default, the DateFormat use the TZ of the system.
            //
            df.setTimeZone(TimeZone.getDefault());
            return df.format( (Date) result );
        }

        // com.sun.jdmk.Enumerated to representable HTML format.
        //
  try {
      Class c ;
      if (result != null) {
    c = result.getClass();
      } else {
    c = loadClass(attrInfo.getType());
      }
      Class sc   = c.getSuperclass();
      // [JF] begin debug
//             if (logger.finestOn()) {
//     boolean t1 = (sc != null);
//     boolean t2 = (Class.forName("com.sun.jdmk.Enumerated").isAssignableFrom(sc));
//                 logger.finest("getStringValue","Attribute ["+ attrInfo.getName() +"] is of type["+ c +"] and inherits from ["+ sc +
//           "]. Enum tests return ["+ t1 +", "+ t2 +"]");
//             }
      // [JF] end debug
      if ( (sc != null) && (com.sun.jdmk.Enumerated.class.isAssignableFrom(sc)) ) {
                return enumToHtml((Enumerated)result, attrInfo) ;
      }
  } catch (ClassNotFoundException e) {
            if (logger.finestOn()) {
                logger.finest("getStringValue","Cannot find class "+ attrInfo.getType() +":"+ e);
            }
  }

        // If the value is null (case for WO attr), returns empty string.
        //
        if (result == null) {
            return ("");
        }

        return result.toString() ; // so, even for unsupported types we return the output of toString()
    }

    private Object stringToObject(String typeStr, String valueStr){
        Object value = null;
        try {
            if (typeStr.endsWith("String")) {
                value = valueStr;
            }
            else if (typeStr.endsWith("Byte") || typeStr.endsWith("byte")) {
                value = new Byte(valueStr);
            }
            else if (typeStr.endsWith("Long") || typeStr.endsWith("long")) {
                value = new Long(valueStr);
            }
            else if (typeStr.endsWith("Integer") || typeStr.endsWith("int")) {
                value = new Integer(valueStr);
            }
            else if (typeStr.endsWith("Date")) {
                try {
                    DateFormat df = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG);
                    // BUG : the TZ of the DateFormat is not set correctly with the method getDateTimeInstance.
                    // By default, the DateFormat use the TZ of the system.
                    df.setTimeZone(TimeZone.getDefault());
                    value = df.parse(valueStr);
                } catch (java.text.ParseException e){
                    buildError("Cannot convert String \""+ valueStr +"\" to " +
                               typeStr +
                               ".<P>",HtmlDef.HTTP_ERROR_BAD_REQUEST_ID + " " + HtmlDef.HTTP_ERROR_BAD_REQUEST);
                    return null;
                }
            }
            else if (typeStr.endsWith("Boolean") || typeStr.endsWith("boolean")) {
                value = new Boolean(valueStr);
            }
            else if (typeStr.endsWith("Number")) {
                try {
                    value = new Integer(valueStr) ;
                }
                catch(NumberFormatException e1) {
                    try {
                        value = new Long(valueStr) ;
                    }
                    catch(NumberFormatException e2) {
                        try {
                            value = new Float(valueStr) ;
                        }
                        catch(NumberFormatException e3) {
                            try {
                                value = new Double(valueStr) ;
                            }
                            catch(NumberFormatException e4){
                                buildError("Cannot convert String \""+ valueStr +"\" to " + typeStr +".<P>",
                                           HtmlDef.HTTP_ERROR_BAD_REQUEST_ID + " " + HtmlDef.HTTP_ERROR_BAD_REQUEST);
                                return null;
                            }
                        }
                    }
                }
            }
            else if (typeStr.equals("javax.management.ObjectName")) {
                try {
                    value = new ObjectName(valueStr);
                } catch (MalformedObjectNameException e) {
                    buildError("Cannot convert String \""+ valueStr +"\" to " + typeStr + ".<P>",
                               HtmlDef.HTTP_ERROR_MALFORMED_OBJECTNAME_ID + " " + HtmlDef.HTTP_ERROR_MALFORMED_OBJECTNAME);
                    return null;
                }
            }
            else if (typeStr.endsWith("Character") || typeStr.endsWith("char") ){
                value = new Character(valueStr.charAt(0));
            }
            else if (typeStr.endsWith("Double") || typeStr.endsWith("double")) {
                value = new Double(valueStr);
            }
            else if (typeStr.endsWith("Float") || typeStr.endsWith("float")) {
                value = new Float(valueStr);
            }
            else if (typeStr.endsWith("Short") || typeStr.endsWith("short")) {
                value = new Short(valueStr);
            }
            else {
                // Unknown conversion mechanism for this.
                //
                buildError("Cannot convert the String \""+ valueStr +"\" to " + typeStr,
                           HtmlDef.HTTP_ERROR_INVALID_PROP_VALUE_ID + " " + HtmlDef.HTTP_ERROR_INVALID_PROP_VALUE);
                return null;
            }
        } catch (NumberFormatException e) {
            buildError("Cannot convert the String \""+ valueStr +"\" to " + typeStr + ".<P>",
                       HtmlDef.HTTP_ERROR_BAD_REQUEST_ID + " " + HtmlDef.HTTP_ERROR_BAD_REQUEST);
            return null;
        }
        return value;
    }
   
    private Object getArray(String typeStr, ArrayList a){
        Object value = null;
        int l = a.size();
        int i;
        if (typeStr.endsWith("String")) {
            value = a.toArray(new String[l]);
        }
        else if (typeStr.endsWith("Byte") ){
            value = a.toArray(new Byte[l]);
        }
        else if (typeStr.endsWith("byte")) {
            value = new byte[l];
            for (i=l-1;i>=0;i--)
                ((byte[])value)[i]=((Byte)a.get(i)).byteValue();
        }
        else if (typeStr.endsWith("Long")){
            value = a.toArray(new Long[l]);
        }
        else if (typeStr.endsWith("long")) {
            value = new long[l];
            for (i=l-1;i>=0;i--)
                ((long[])value)[i]=((Long)a.get(i)).longValue();
        }
        else if (typeStr.endsWith("Integer")) {
            value = a.toArray(new Integer[l]);
        }
        else if (typeStr.endsWith("int")) {
            value = new int[l];
            for (i=l-1;i>=0;i--)
                ((int[])value)[i]=((Integer)a.get(i)).intValue();
        }
        else if (typeStr.endsWith("Date")) {
            value = a.toArray(new Date[l]);
        }
        else if (typeStr.endsWith("Boolean")) {
            value = a.toArray(new Boolean[l]);
        }
        else if (typeStr.endsWith("boolean")) {
            value = new boolean[l];           
            for (i=l-1;i>=0;i--)
                ((boolean[])value)[i]=((Boolean)a.get(i)).booleanValue();
        }
        else if (typeStr.equals("javax.management.ObjectName")) {
            value = a.toArray(new ObjectName[l]);
        }
        else if (typeStr.equals("Character")){
            value = a.toArray(new Character[l]);
        }
        else if (typeStr.equals("char")) {
            value = new char[l];
            for (i=l-1;i>=0;i--)
                ((char[])value)[i]=((Character)a.get(i)).charValue();
        }
        else if (typeStr.equals("Double")) {
            value = a.toArray(new Double[l]);
        }
        else if (typeStr.equals("double")) {
            value = new double[l];
            for (i=l-1;i>=0;i--)
                ((double[])value)[i]=((Double)a.get(i)).doubleValue();
        }
        else if (typeStr.equals("Float")) {
            value = a.toArray(new Float[l]);
        }
        else if (typeStr.equals("float")) {
            value = new float[l];
            for (i=l-1;i>=0;i--)
                ((float[])value)[i]=((Float)a.get(i)).floatValue();
        }         
        else {
            // Unknown conversion mechanism for this
            //
            return null;
        }
        return value;
    }

    private Class loadClass(String className)
  throws ClassNotFoundException {
  try {
      return Class.forName(className);
  } catch (ClassNotFoundException e) {
      final ClassLoaderRepository clr =
    MBeanServerFactory.getClassLoaderRepository(mbs);
      if (clr == null) throw new ClassNotFoundException(className);
      return clr.loadClass(className);
  }
    }


    // --------------------------------------------------------
    // PRIVATE VARIABLES
    // --------------------------------------------------------
   
    private MBeanAttributeInfo[] attinfo = null;
    private String propertyName[] = null;
    private String propertyView[] = null;
    private ObjectName manipulatedObjName = null;
    private MBeanInfo manipulatedObj = null;   
    private String meta = null;
    private int autoRefresh = 0;
    private final int minAutoRefresh = 5;
    private HtmlAdaptorServer server = null;
}
TOP

Related Classes of com.sun.jdmk.comm.HtmlObjectPage

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.