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 |
|
26 package com.sun.jmx.namespace; |
|
27 |
|
28 import static javax.management.namespace.JMXNamespaces.NAMESPACE_SEPARATOR; |
|
29 |
|
30 import javax.management.ObjectInstance; |
|
31 import javax.management.ObjectName; |
|
32 |
|
33 /** |
|
34 * The ObjectNameRouter is used to rewrite routing object names. |
|
35 * <p><b> |
|
36 * This API is a Sun internal API and is subject to changes without notice. |
|
37 * </b></p> |
|
38 * @since 1.7 |
|
39 */ |
|
40 public class ObjectNameRouter { |
|
41 |
|
42 private static final int NAMESPACE_SEPARATOR_LENGTH = |
|
43 NAMESPACE_SEPARATOR.length(); |
|
44 |
|
45 final String targetPrefix; |
|
46 final String sourcePrefix; |
|
47 final int slen; |
|
48 final int tlen; |
|
49 final boolean identity; |
|
50 |
|
51 /** Creates a new instance of ObjectNameRouter */ |
|
52 public ObjectNameRouter(final String remove, final String add) { |
|
53 this.targetPrefix = (remove==null?"":remove); |
|
54 this.sourcePrefix = (add==null?"":add); |
|
55 tlen = targetPrefix.length(); |
|
56 slen = sourcePrefix.length(); |
|
57 identity = targetPrefix.equals(sourcePrefix); |
|
58 } |
|
59 |
|
60 public final ObjectName toTargetContext(ObjectName sourceName, |
|
61 boolean removeLeadingSeparators) { |
|
62 if (sourceName == null) return null; |
|
63 if (identity) return sourceName; |
|
64 String srcDomain = sourceName.getDomain(); |
|
65 |
|
66 // if the ObjectName starts with // and removeLeadingSeparators is |
|
67 // true, then recursively strip leading //. |
|
68 // Otherwise, do not rewrite ObjectName. |
|
69 // |
|
70 if (srcDomain.startsWith(NAMESPACE_SEPARATOR)) { |
|
71 if (!removeLeadingSeparators) return sourceName; |
|
72 else srcDomain = normalizeDomain(srcDomain,true); |
|
73 } |
|
74 if (slen != 0) { |
|
75 if (!srcDomain.startsWith(sourcePrefix) || |
|
76 !srcDomain.startsWith(NAMESPACE_SEPARATOR,slen)) |
|
77 throw new IllegalArgumentException( |
|
78 "ObjectName does not start with expected prefix " |
|
79 + sourcePrefix + ": " + |
|
80 String.valueOf(sourceName)); |
|
81 srcDomain = srcDomain.substring(slen+NAMESPACE_SEPARATOR_LENGTH); |
|
82 } |
|
83 final String targetDomain = |
|
84 (tlen>0?targetPrefix+NAMESPACE_SEPARATOR+srcDomain:srcDomain); |
|
85 return sourceName.withDomain(targetDomain); |
|
86 } |
|
87 |
|
88 public final ObjectName toSourceContext(ObjectName targetName, |
|
89 boolean removeLeadingSeparators) { |
|
90 if (targetName == null) return null; |
|
91 if (identity) return targetName; |
|
92 String targetDomain = targetName.getDomain(); |
|
93 if (targetDomain.startsWith(NAMESPACE_SEPARATOR)) { |
|
94 if (!removeLeadingSeparators) return targetName; |
|
95 else targetDomain = |
|
96 normalizeDomain(targetDomain,true); |
|
97 } |
|
98 if (tlen != 0) { |
|
99 if (!targetDomain.startsWith(targetPrefix) || |
|
100 !targetDomain.startsWith(NAMESPACE_SEPARATOR,tlen)) |
|
101 throw new IllegalArgumentException( |
|
102 "ObjectName does not start with expected prefix " |
|
103 + targetPrefix + ": " + |
|
104 String.valueOf(targetName)); |
|
105 targetDomain = targetDomain. |
|
106 substring(tlen+NAMESPACE_SEPARATOR_LENGTH); |
|
107 } |
|
108 final String sourceDomain = |
|
109 (slen>0?sourcePrefix+NAMESPACE_SEPARATOR+targetDomain: |
|
110 targetDomain); |
|
111 return targetName.withDomain(sourceDomain); |
|
112 } |
|
113 |
|
114 public final ObjectInstance toTargetContext(ObjectInstance sourceMoi, |
|
115 boolean removeLeadingSeparators) { |
|
116 if (sourceMoi == null) return null; |
|
117 if (identity) return sourceMoi; |
|
118 return new ObjectInstance( |
|
119 toTargetContext(sourceMoi.getObjectName(), |
|
120 removeLeadingSeparators), |
|
121 sourceMoi.getClassName()); |
|
122 } |
|
123 |
|
124 /** |
|
125 * Removes leading, trailing, or duplicate // in a name space path. |
|
126 **/ |
|
127 public static String normalizeDomain(String domain, |
|
128 boolean removeLeadingSep) { |
|
129 return normalizeNamespacePath(domain,removeLeadingSep,false,true); |
|
130 } |
|
131 |
|
132 /** |
|
133 * Removes leading, trailing, or duplicate // in a name space path. |
|
134 **/ |
|
135 public static String normalizeNamespacePath(String namespacePath, |
|
136 boolean removeLeadingSep, |
|
137 boolean removeTrailingSep, |
|
138 boolean endsWithDomain) { |
|
139 if (namespacePath.equals("")) |
|
140 return ""; |
|
141 final String[] components = namespacePath.split(NAMESPACE_SEPARATOR); |
|
142 final StringBuilder b = |
|
143 new StringBuilder(namespacePath.length()+NAMESPACE_SEPARATOR_LENGTH); |
|
144 String sep = null; |
|
145 if (!removeLeadingSep && namespacePath.startsWith(NAMESPACE_SEPARATOR)) |
|
146 b.append(NAMESPACE_SEPARATOR); |
|
147 int count = 0; |
|
148 for (int i=0; i<components.length; i++) { |
|
149 final String n=components[i]; |
|
150 if (n.equals("")) continue; |
|
151 if (n.startsWith("/")||n.endsWith("/")) { |
|
152 // throw exception unless we're looking at the last domain |
|
153 // part of the ObjectName |
|
154 if (! (endsWithDomain && i==(components.length-1))) { |
|
155 throw new IllegalArgumentException(n+ |
|
156 " is not a valid name space identifier"); |
|
157 } else { |
|
158 // There's a dirty little corner case when the domain |
|
159 // part (last item) is exactly '/' - in that case we must |
|
160 // not append '//' |
|
161 // |
|
162 removeTrailingSep = removeTrailingSep || n.equals("/"); |
|
163 } |
|
164 } |
|
165 if (sep != null) b.append(sep); |
|
166 b.append(n); |
|
167 sep = NAMESPACE_SEPARATOR; |
|
168 count++; |
|
169 } |
|
170 if (!removeTrailingSep && namespacePath.endsWith(NAMESPACE_SEPARATOR) |
|
171 && count > 0) |
|
172 b.append(NAMESPACE_SEPARATOR); |
|
173 return b.toString(); |
|
174 } |
|
175 } |
|