jdk/src/share/classes/com/sun/jmx/namespace/NamespaceInterceptor.java
changeset 4156 acaa49a2768a
parent 4155 460e37d40f12
child 4159 9e3aae7675f1
equal deleted inserted replaced
4155:460e37d40f12 4156:acaa49a2768a
     1 /*
       
     2  * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.  Sun designates this
       
     8  * particular file as subject to the "Classpath" exception as provided
       
     9  * by Sun in the LICENSE file that accompanied this code.
       
    10  *
       
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    14  * version 2 for more details (a copy is included in the LICENSE file that
       
    15  * accompanied this code).
       
    16  *
       
    17  * You should have received a copy of the GNU General Public License version
       
    18  * 2 along with this work; if not, write to the Free Software Foundation,
       
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    20  *
       
    21  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
       
    22  * CA 95054 USA or visit www.sun.com if you need additional information or
       
    23  * have any questions.
       
    24  */
       
    25 package com.sun.jmx.namespace;
       
    26 
       
    27 import java.util.ArrayList;
       
    28 import java.util.List;
       
    29 
       
    30 import javax.management.Attribute;
       
    31 import javax.management.AttributeList;
       
    32 import javax.management.MBeanServer;
       
    33 import javax.management.ObjectName;
       
    34 import javax.management.namespace.JMXNamespace;
       
    35 import javax.management.namespace.JMXNamespacePermission;
       
    36 
       
    37 /**
       
    38  * A NamespaceInterceptor wraps a JMXNamespace, performing
       
    39  * ObjectName rewriting.
       
    40  * <p><b>
       
    41  * This API is a Sun internal API and is subject to changes without notice.
       
    42  * </b></p>
       
    43  * @since 1.7
       
    44  */
       
    45 public class NamespaceInterceptor extends HandlerInterceptor<JMXNamespace> {
       
    46 
       
    47 
       
    48     // The target name space in which the NamepsaceHandler is mounted.
       
    49     private final String           targetNs;
       
    50 
       
    51     private final String           serverName;
       
    52 
       
    53     private final ObjectNameRouter proc;
       
    54 
       
    55     /**
       
    56      * Creates a new instance of NamespaceInterceptor
       
    57      */
       
    58     public NamespaceInterceptor(
       
    59             String serverName,
       
    60             JMXNamespace handler,
       
    61             String targetNamespace) {
       
    62         super(handler);
       
    63         this.serverName = serverName;
       
    64         this.targetNs =
       
    65                 ObjectNameRouter.normalizeNamespacePath(targetNamespace,
       
    66                 true, true, false);
       
    67         proc = new ObjectNameRouter(targetNamespace, "");
       
    68     }
       
    69 
       
    70     @Override
       
    71     public String toString() {
       
    72         return this.getClass().getName()+"(parent="+serverName+
       
    73                 ", namespace="+this.targetNs+")";
       
    74     }
       
    75 
       
    76     /**
       
    77      * This method will send a probe to detect self-linking name spaces.
       
    78      * A self linking namespace is a namespace that links back directly
       
    79      * on itslef. Calling a method on such a name space always results
       
    80      * in an infinite loop going through:
       
    81      * [1]MBeanServer -> [2]NamespaceDispatcher -> [3]NamespaceInterceptor
       
    82      * [4]JMXNamespace -> { network // or cd // or ... } -> [5]MBeanServer
       
    83      * with exactly the same request than [1]...
       
    84      *
       
    85      * The namespace interceptor [2] tries to detect such condition the
       
    86      * *first time* that the connection is used. It does so by setting
       
    87      * a flag, and sending a queryNames() through the name space. If the
       
    88      * queryNames comes back, it knows that there's a loop.
       
    89      *
       
    90      * The DynamicProbe interface can also be used by a Sun JMXNamespace
       
    91      * implementation to request the emission of a probe at any time
       
    92      * (see JMXRemoteNamespace implementation).
       
    93      */
       
    94     private MBeanServer connection() {
       
    95         final MBeanServer c = super.source();
       
    96         if (c != null) return c;
       
    97         // should not come here
       
    98         throw new NullPointerException("getMBeanServerConnection");
       
    99     }
       
   100 
       
   101 
       
   102     @Override
       
   103     protected MBeanServer source() {
       
   104         return connection();
       
   105     }
       
   106 
       
   107     @Override
       
   108     protected MBeanServer getServerForLoading() {
       
   109         // don't want to send probe on getClassLoader/getClassLoaderFor
       
   110         return super.source();
       
   111     }
       
   112 
       
   113     @Override
       
   114     protected ObjectName toSource(ObjectName targetName) {
       
   115         return proc.toSourceContext(targetName, true);
       
   116     }
       
   117 
       
   118     @Override
       
   119     protected ObjectName toTarget(ObjectName sourceName) {
       
   120         return proc.toTargetContext(sourceName, false);
       
   121     }
       
   122 
       
   123     //
       
   124     // Implements permission checks.
       
   125     //
       
   126     @Override
       
   127     void check(ObjectName routingName, String member, String action) {
       
   128         final SecurityManager sm = System.getSecurityManager();
       
   129         if (sm == null) return;
       
   130         if ("getDomains".equals(action)) return;
       
   131         final JMXNamespacePermission perm =
       
   132                 new  JMXNamespacePermission(serverName,member,
       
   133                 routingName,action);
       
   134         sm.checkPermission(perm);
       
   135     }
       
   136 
       
   137     @Override
       
   138     void checkCreate(ObjectName routingName, String className, String action) {
       
   139         final SecurityManager sm = System.getSecurityManager();
       
   140         if (sm == null) return;
       
   141         final JMXNamespacePermission perm =
       
   142                 new  JMXNamespacePermission(serverName,className,
       
   143                 routingName,action);
       
   144         sm.checkPermission(perm);
       
   145     }
       
   146 
       
   147     //
       
   148     // Implements permission filters for attributes...
       
   149     //
       
   150     @Override
       
   151     AttributeList checkAttributes(ObjectName routingName,
       
   152             AttributeList attributes, String action) {
       
   153         check(routingName,null,action);
       
   154         if (attributes == null || attributes.isEmpty()) return attributes;
       
   155         final SecurityManager sm = System.getSecurityManager();
       
   156         if (sm == null) return attributes;
       
   157         final AttributeList res = new AttributeList();
       
   158         for (Attribute at : attributes.asList()) {
       
   159             try {
       
   160                 check(routingName,at.getName(),action);
       
   161                 res.add(at);
       
   162             } catch (SecurityException x) { // DLS: OK
       
   163                 continue;
       
   164             }
       
   165         }
       
   166         return res;
       
   167     }
       
   168 
       
   169     //
       
   170     // Implements permission filters for attributes...
       
   171     //
       
   172     @Override
       
   173     String[] checkAttributes(ObjectName routingName, String[] attributes,
       
   174             String action) {
       
   175         check(routingName,null,action);
       
   176         if (attributes == null || attributes.length==0) return attributes;
       
   177         final SecurityManager sm = System.getSecurityManager();
       
   178         if (sm == null) return attributes;
       
   179         final List<String> res = new ArrayList<String>(attributes.length);
       
   180         for (String at : attributes) {
       
   181             try {
       
   182                 check(routingName,at,action);
       
   183                 res.add(at);
       
   184             } catch (SecurityException x) { // DLS: OK
       
   185                 continue;
       
   186             }
       
   187         }
       
   188         return res.toArray(new String[res.size()]);
       
   189     }
       
   190 
       
   191     //
       
   192     // Implements permission filters for domains...
       
   193     //
       
   194     @Override
       
   195     String[] checkDomains(String[] domains, String action) {
       
   196         // in principle, this method is never called because
       
   197         // getDomains() will never be called - since there's
       
   198         // no way that MBeanServer.getDomains() can be routed
       
   199         // to a NamespaceInterceptor.
       
   200         //
       
   201         // This is also why there's no getDomains() in a
       
   202         // JMXNamespacePermission...
       
   203         //
       
   204         return super.checkDomains(domains, action);
       
   205     }
       
   206 
       
   207     //
       
   208     // Implements permission filters for queries...
       
   209     //
       
   210     @Override
       
   211     boolean checkQuery(ObjectName routingName, String action) {
       
   212         try {
       
   213             check(routingName,null,action);
       
   214             return true;
       
   215         } catch (SecurityException x) { // DLS: OK
       
   216             return false;
       
   217         }
       
   218     }
       
   219 
       
   220 }