package org.jolokia.request; /* * Copyright 2009-2013 Roland Huss * * 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. */ import java.util.*; import javax.management.MalformedObjectNameException; import org.jolokia.config.ProcessingParameters; import org.jolokia.util.EscapeUtil; import org.jolokia.util.RequestType; import org.json.simple.JSONObject; /** * A JMX request for <code>read</code> operations, i.e. for reading JMX attributes * on MBeans. * * @author roland * @since 15.03.11 */ public class JmxReadRequest extends JmxObjectNameRequest { // One or more attribute names private List<String> attributeNames; // Whether multiple attributes are to be fetched private boolean multiAttributeMode = false; /** * Constructor for GET requests * * @param pObjectName object name of MBean to read attributes from * @param pAttribute a one or more attribute to lookup. Can be null in which case all attributes * are to be fetched. More than one attribute can be provided by giving it a comma * separated list (attribute names with commas can not be use here, though). * @param pPathParts optional path parts from for filtering the return value * @param pInitParams optional processing parameters * @throws MalformedObjectNameException if the name is not a proper object name. */ JmxReadRequest(String pObjectName,String pAttribute,List<String> pPathParts, ProcessingParameters pInitParams) throws MalformedObjectNameException { super(RequestType.READ, pObjectName, pPathParts, pInitParams); initAttribute(pAttribute); } /** * Constructor for creating a JmxRequest resulting from an HTTP POST request * * @param pRequestMap request in object format * @param pParams optional processing parameters * @throws MalformedObjectNameException if the object name extracted is not a proper object name. */ JmxReadRequest(Map<String, ?> pRequestMap, ProcessingParameters pParams) throws MalformedObjectNameException { super(pRequestMap, pParams); initAttribute(pRequestMap.get("attribute")); } /** * Get a single attribute name. If this request was initialized with more than one attribute this * methods throws an exception. * @return the attribute's name or null * @throws IllegalStateException if this request was initialized with more than one attribute. */ public String getAttributeName() { if (attributeNames == null) { return null; } if (isMultiAttributeMode()) { throw new IllegalStateException("Request contains more than one attribute (attrs = " + "" + attributeNames + "). Use getAttributeNames() instead."); } return attributeNames.get(0); } /** * Get the list of all attribute names. * * @return list of attributes names or null */ public List<String> getAttributeNames() { return attributeNames; } /** * Whether this is a multi-attribute request, i.e. whether it contains one ore more attributes to fetch * @return true if this is a multi attribute request, false otherwise. */ public boolean isMultiAttributeMode() { return multiAttributeMode; } /** * Whether this request has not multiple attribute names associated (which normally means, that all attributes should be fetched). * @return true if not multiple attribute names are contained. */ public boolean hasAttribute() { return isMultiAttributeMode() || getAttributeName() != null; } /** {@inheritDoc} */ public JSONObject toJSON() { JSONObject ret = super.toJSON(); if (attributeNames != null && attributeNames.size() > 0) { if (attributeNames.size() > 1) { ret.put("attribute", attributeNames); } else { ret.put("attribute", attributeNames.get(0)); } } if (getPathParts() != null && getPathParts().size() > 0) { ret.put("path", getPath()); } return ret; } /** {@inheritDoc} */ @Override public String toString() { StringBuffer ret = new StringBuffer("JmxReadRequest["); appendReadParameters(ret); String baseInfo = getInfo(); if (baseInfo != null) { ret.append(", ").append(baseInfo); } ret.append("]"); return ret.toString(); } // ================================================================= /** * Creator for {@link JmxReadRequest}s * * @return the creator implementation */ static RequestCreator<JmxReadRequest> newCreator() { return new RequestCreator<JmxReadRequest>() { /** {@inheritDoc} */ public JmxReadRequest create(Stack<String> pStack, ProcessingParameters pParams) throws MalformedObjectNameException { return new JmxReadRequest( pStack.pop(), // object name popOrNull(pStack), // attribute(s) (can be null) prepareExtraArgs(pStack), // path pParams); } /** {@inheritDoc} */ public JmxReadRequest create(Map<String, ?> requestMap, ProcessingParameters pParams) throws MalformedObjectNameException { return new JmxReadRequest(requestMap,pParams); } }; } // ================================================================= private void appendReadParameters(StringBuffer pRet) { if (isMultiAttributeMode()) { pRet.append("attribute=["); for (int i = 0;i<attributeNames.size();i++) { pRet.append(attributeNames.get(i)); if (i < attributeNames.size() - 1) { pRet.append(","); } } pRet.append("]"); } else { pRet.append("attribute=").append(getAttributeName()); } } // initialize and detect multi attribute mode private void initAttribute(Object pAttrval) { if (pAttrval instanceof String) { attributeNames = EscapeUtil.split((String) pAttrval,EscapeUtil.CSV_ESCAPE,","); multiAttributeMode = attributeNames.size() > 1; } else if (pAttrval instanceof Collection) { Collection<String> attributes = (Collection<String>) pAttrval; if (attributes.size() == 1 && attributes.iterator().next() == null) { attributeNames = null; multiAttributeMode = false; } else { attributeNames = new ArrayList<String>(attributes); multiAttributeMode = true; } } else if (pAttrval == null) { attributeNames = null; multiAttributeMode = false; } else { throw new IllegalArgumentException("Attribute names must be either a String, Collection or null (and not " + pAttrval.getClass() + ")"); } } }