public static String getPropertyCategory(String property) {
    int lastPathSep = -1;

    if( !containsArguments(property) ){
      lastPathSep = property.lastIndexOf(EXTERNAL_PATH_SEP);
      return lastPathSep == -1 ? null : property.substring(0, lastPathSep);
    }

    // attempt to split the property into its parts
    String[] tokens = METRIC_CATEGORY_TOKENIZE_REGEX.split(property);
    if (null == tokens || tokens.length == 0) {
      return null;
    }

    StringBuilder categoryBuilder = new StringBuilder();
    for (int i = 0; i < tokens.length - 1; i++) {
      String token = tokens[i];

      // if the token contains arguments, turn $1.method() into $1,
      if (containsArguments(token)) {
        int methodIndex = token.indexOf('.');

        if (methodIndex != -1) {
          // normally knowing where $1.method() is would be enough, but some
          // properties may omit the / (like FLUME) so the property would look
          // like /$1.method()FailureCount instead of /$1.method()/FailureCount
          int parensIndex = token.lastIndexOf(')');
          if (parensIndex < token.length() - 1) {
            // cut out $1
            String temp = token.substring(0, methodIndex);

            // append FailureCount
            temp += token.substring(parensIndex + 1);

            // $1.method()FailureCount -> $1FailureCount
            token = temp;
          } else {
            token = token.substring(0, methodIndex);
          }
        }
      }

      // only append a / if this is not the last part of the parent category
      categoryBuilder.append(token);
      if (i < tokens.length - 2) {
        categoryBuilder.append('/');
      }
    }

    String category = categoryBuilder.toString();
    return category;
  }
Gets the parent category from a given property string. This method is used
in many places by many different consumers. In general, it will check to
see if the property contains arguments. If not, then a simple
{@link String#substring(int, int)} is used along with
{@link #EXTERNAL_PATH_SEP}.
<p/>
In the event that a property contains a $d parameter, it will attempt to
strip out any embedded methods in the various tokens. For example, if a
property of {@code foo/$1.substring(5)/bar/$2.substring(1)/baz} is given,
the expected recursive categories would be:
<ul>
<li>foo</li>
<li>foo/$1</li>
<li>foo/$1/bar</li>
<li>foo/$1/bar</li>
<li>foo/$1/bar/$2</li>
</ul>

{@code foo/$1.substring(5)/bar} is incorrect as a category.

@param property
         the fully qualified property

@return the property category; null if there is no category
ambari-server/src/main/java/org/apache/ambari/server/controller/utilities/PropertyHelper.java