All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.glassfish.admin.amx.impl.mbean.PathnamesImpl Maven / Gradle / Ivy

There is a newer version: 4.1.2.181
Show newest version
/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright (c) 1997-2012 Oracle and/or its affiliates. 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
 * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
 * or packager/legal/LICENSE.txt.  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 at packager/legal/LICENSE.txt.
 *
 * GPL Classpath Exception:
 * Oracle designates this particular file as subject to the "Classpath"
 * exception as provided by Oracle in the GPL Version 2 section of the License
 * file that accompanied this code.
 *
 * Modifications:
 * If applicable, add the following below the License Header, with the fields
 * enclosed by brackets [] replaced by your own identifying information:
 * "Portions Copyright [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, 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 org.glassfish.admin.amx.impl.mbean;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.logging.Level;
import javax.management.InstanceNotFoundException;
import javax.management.MBeanInfo;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import org.glassfish.admin.amx.base.DomainRoot;
import org.glassfish.admin.amx.base.Pathnames;
import org.glassfish.admin.amx.core.AMXProxy;
import org.glassfish.admin.amx.core.PathnameParser;
import org.glassfish.admin.amx.core.Util;
import org.glassfish.admin.amx.core.proxy.AMXProxyHandler;
import org.glassfish.admin.amx.impl.util.ImplUtil;
import org.glassfish.admin.amx.util.AMXLoggerInfo;
import org.glassfish.admin.amx.util.CollectionUtil;
import org.glassfish.admin.amx.util.ExceptionUtil;
import org.glassfish.admin.amx.util.ListUtil;
import org.glassfish.admin.amx.util.jmx.JMXUtil;
import org.glassfish.admin.amx.util.stringifier.SmartStringifier;
import static org.glassfish.external.amx.AMX.ATTR_PARENT;
import static org.glassfish.external.amx.AMX.PARENT_PATH_KEY;

/**
GlassFish V3 dotted names implementation (MBean).
 */
public final class PathnamesImpl extends AMXImplBase // implements Pathnames  (can't directly implement the interface)
{

    private static final int MAX_CACHE_SIZE = 1024;
    private final ConcurrentMap mPathnameCache = new ConcurrentHashMap();

    public PathnamesImpl(final ObjectName parentObjectName) {
        super(parentObjectName, Pathnames.class);
    }

    public ObjectName resolvePath(final String path) {
        ObjectName result = mPathnameCache.get(path);
        if (result != null) {
            return result;
        }

        if (path.equals(DomainRoot.PATH)) {
            return getDomainRoot();
        }

        final PathnameParser parser = new PathnameParser(path);

        final String parentPath = parser.parentPath();

        //cdebug( "resolvePath: " + parser.toString() + ", parentPath = " + parentPath );

        // fixed query based on the path, which will find all MBeans with that parent path
        final String props = Util.makeProp(PARENT_PATH_KEY, Util.quoteIfNeeded(parentPath));
        final ObjectName pattern = JMXUtil.newObjectNamePattern(getObjectName().getDomain(), props);
        final Set s = getMBeanServer().queryNames(pattern, null);

        //cdebug( "resolvePath: " + path + " = query for parent path: " + pattern + " yields children: " + s.size() );

        ObjectName objectName = null;
        final String type = parser.type();
        final String name = parser.name();
        // find the matching child
        for (final ObjectName child : s) {
            if (type.equals(Util.getTypeProp(child))) {
                final String nameProp = Util.getNameProp(child);

                //cdebug( "type match for " + path + ", objectName = " + child);

                if (nameProp == null) {
                    if (name == null) {
                        // no name, we matched on type alone
                        objectName = child;
                        break;
                    }
                    // badly formed: a name is specified, but none is present for this type
                    //cdebug( "A name is specified in path, but the type has none: path = " + path + ", objectName = " + child);
                    continue;
                }

                // there is a name in the ObjectName (nameProp)
                // the nameProp could exist, but the item might be a singleton
                if (name != null && name.equals(nameProp)) {
                    objectName = child;
                    break;
                }

                // careful: name should be used only if it's not a singleton
                final MBeanInfo mbeanInfo = getProxyFactory().getMBeanInfo(child);
                if (mbeanInfo == null) {
                    continue;
                }

                final boolean singleton = AMXProxyHandler.singleton(mbeanInfo);
                // match only if it's a singleton with no name; the check above handled the other cases
                if (singleton && name == null) {
                    objectName = child;
                    break;
                }
            } else {
                //cdebug( "No match on type: " + type + " != " + Util.getTypeProp(child) );
            }
        }

        // limit the memory use; non-existent paths could otherwise build up
        if (mPathnameCache.keySet().size() > MAX_CACHE_SIZE) {
            // clears out old stuff we might not need anyway
            mPathnameCache.clear();
        }

        if (objectName != null) {
            //cdebug( "Matched " + path + " to " + objectName);
            mPathnameCache.put(path, objectName);
        }

        return objectName;
    }

    private AMXProxy resolveToProxy(final String path) {
        final ObjectName objectName = resolvePath(path);
        if (objectName == null) {
            return null;
        }

        return getProxyFactory().getProxy(objectName, AMXProxy.class);
    }

    public ObjectName[] resolvePaths(final String[] paths) {
        final ObjectName[] objectNames = new ObjectName[paths.length];

        int i = 0;
        for (final String path : paths) {
            try {
                objectNames[i] = resolvePath(path);
            } catch (final Exception e) {
                objectNames[i] = null;
            }
            ++i;
        }
        return objectNames;
    }

    public ObjectName[] ancestors(final String path) {
        final ObjectName objectName = resolvePath(path);
        if (objectName == null) {
            return null;
        }
        return ancestors(objectName);
    }

    public ObjectName[] ancestors(final ObjectName mbean) {
        final List objectNames = new ArrayList();
        final MBeanServer server = getMBeanServer();

        ObjectName cur = mbean;
        while (cur != null) {
            objectNames.add(cur);
            cur = (ObjectName) JMXUtil.getAttribute(server, cur, ATTR_PARENT);
        }

        final List reversed = ListUtil.reverse(objectNames);
        final ObjectName[] ancestors = new ObjectName[reversed.size()];
        reversed.toArray(ancestors);
        return ancestors;
    }

    private boolean isInstanceNotFound(final Throwable t) {
        return ExceptionUtil.getRootCause(t) instanceof InstanceNotFoundException;
    }

    private void listChildren(final AMXProxy top, final List list, boolean recursive) {
        Set children = null;
        try {
            children = top.childrenSet();
            if (children == null) {
                return;
            }
        } catch (final Exception e) {
            if (!isInstanceNotFound(e)) {
                AMXLoggerInfo.getLogger().log(Level.WARNING,
                        AMXLoggerInfo.cantGetChildren, 
                        new Object[] {top.objectName(), ExceptionUtil.getRootCause(e).getLocalizedMessage()});
                // just return, nothing we can do.  Typically it could be InstanceNotFoundException
            }
            return;
        }

        for (final AMXProxy child : children) {
            try {
                list.add(child);
                if (recursive) {
                    listChildren(child, list, true);
                }
            } catch (final Exception e) {
                if (!isInstanceNotFound(e)) {
                    AMXLoggerInfo.getLogger().log(Level.WARNING, AMXLoggerInfo.problemWithMbean,
                            new Object[] { child.objectName(), ExceptionUtil.getRootCause(e).getLocalizedMessage()});
                    // nothing we can do.
                }
            }
        }
    }

    private List listChildren(final String path, boolean recursive) {
        final AMXProxy topProxy = resolveToProxy(path);
        if (topProxy == null) {
            return null;
        }

        final List list = new ArrayList();
        listChildren(topProxy, list, recursive);

        return list;
    }

    public String[] getAllPathnames() {
        try {
            final String[] allButRoot = listPaths(DomainRoot.PATH, true);

            final String[] all = new String[allButRoot.length + 1];
            all[0] = DomainRoot.PATH;
            System.arraycopy(allButRoot, 0, all, 1, allButRoot.length);

            return all;
        } catch (final Throwable t) {
            AMXLoggerInfo.getLogger().log(Level.WARNING, AMXLoggerInfo.unexpectedThrowable,
                    ExceptionUtil.getRootCause(t).getLocalizedMessage());
        }
        return new String[]{DomainRoot.PATH};
    }

    public ObjectName[] listObjectNames(final String path, final boolean recursive) {
        final List list = listChildren(path, recursive);
        final List objectNames = Util.toObjectNameList(list);
        return CollectionUtil.toArray(objectNames, ObjectName.class);
    }

    public String[] listPaths(final String path, final boolean recursive) {
        final List list = listChildren(path, recursive);

        final List paths = new ArrayList();
        for (final AMXProxy amx : list) {
            try {
                paths.add(amx.path());
            } catch (final Exception e) {
                AMXLoggerInfo.getLogger().log(Level.WARNING, AMXLoggerInfo.cantGetPath,
                        new Object[]{amx.objectName(), e.getLocalizedMessage()});
            }
        }

        return CollectionUtil.toArray(paths, String.class);
    }

    public String dump(final String path) {
        final ObjectName top = resolvePath(path);
        if (top == null) {
            return null;
        }

        final AMXProxy topProxy = getProxyFactory().getProxy(top, AMXProxy.class);
        final List list = new ArrayList();
        list.add(topProxy);
        listChildren(topProxy, list, true);

        final String NL = "\n";
        final StringBuffer buf = new StringBuffer();
        for (final AMXProxy amx : list) {
            final String p = amx.path();
            buf.append(p);
            buf.append(NL);

            final Map attributesMap = amx.attributesMap();
            for (final Map.Entry e : attributesMap.entrySet()) {
                buf.append("\t");
                buf.append(e.getKey());
                buf.append(" = ");
                buf.append("").append(SmartStringifier.toString(e.getValue()));
                buf.append(NL);
            }
            buf.append(NL);
        }
        return buf.toString();
    }
}





















© 2015 - 2024 Weber Informatics LLC | Privacy Policy