Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_jdk
提交
3e149c7f
D
dragonwell8_jdk
项目概览
openanolis
/
dragonwell8_jdk
通知
4
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
dragonwell8_jdk
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
3e149c7f
编写于
6月 06, 2008
作者:
T
tbell
浏览文件
操作
浏览文件
下载
差异文件
Merge
上级
78173514
fd36303c
变更
44
隐藏空白更改
内联
并排
Showing
44 changed file
with
2853 addition
and
762 deletion
+2853
-762
make/common/Release.gmk
make/common/Release.gmk
+4
-0
make/common/internal/Defs-langtools.gmk
make/common/internal/Defs-langtools.gmk
+5
-3
src/share/classes/com/sun/jmx/mbeanserver/ConvertingMethod.java
...are/classes/com/sun/jmx/mbeanserver/ConvertingMethod.java
+46
-30
src/share/classes/com/sun/jmx/mbeanserver/DefaultMXBeanMappingFactory.java
.../com/sun/jmx/mbeanserver/DefaultMXBeanMappingFactory.java
+382
-328
src/share/classes/com/sun/jmx/mbeanserver/Introspector.java
src/share/classes/com/sun/jmx/mbeanserver/Introspector.java
+25
-11
src/share/classes/com/sun/jmx/mbeanserver/MBeanAnalyzer.java
src/share/classes/com/sun/jmx/mbeanserver/MBeanAnalyzer.java
+22
-19
src/share/classes/com/sun/jmx/mbeanserver/MBeanIntrospector.java
...re/classes/com/sun/jmx/mbeanserver/MBeanIntrospector.java
+32
-13
src/share/classes/com/sun/jmx/mbeanserver/MBeanSupport.java
src/share/classes/com/sun/jmx/mbeanserver/MBeanSupport.java
+12
-10
src/share/classes/com/sun/jmx/mbeanserver/MXBeanIntrospector.java
...e/classes/com/sun/jmx/mbeanserver/MXBeanIntrospector.java
+57
-9
src/share/classes/com/sun/jmx/mbeanserver/MXBeanLookup.java
src/share/classes/com/sun/jmx/mbeanserver/MXBeanLookup.java
+183
-49
src/share/classes/com/sun/jmx/mbeanserver/MXBeanProxy.java
src/share/classes/com/sun/jmx/mbeanserver/MXBeanProxy.java
+29
-9
src/share/classes/com/sun/jmx/mbeanserver/MXBeanSupport.java
src/share/classes/com/sun/jmx/mbeanserver/MXBeanSupport.java
+25
-19
src/share/classes/com/sun/jmx/mbeanserver/NotificationMBeanSupport.java
...ses/com/sun/jmx/mbeanserver/NotificationMBeanSupport.java
+2
-1
src/share/classes/com/sun/jmx/mbeanserver/PerInterface.java
src/share/classes/com/sun/jmx/mbeanserver/PerInterface.java
+1
-1
src/share/classes/com/sun/jmx/mbeanserver/StandardMBeanSupport.java
...classes/com/sun/jmx/mbeanserver/StandardMBeanSupport.java
+3
-4
src/share/classes/javax/management/JMX.java
src/share/classes/javax/management/JMX.java
+367
-20
src/share/classes/javax/management/MBeanServerInvocationHandler.java
...lasses/javax/management/MBeanServerInvocationHandler.java
+49
-16
src/share/classes/javax/management/MXBean.java
src/share/classes/javax/management/MXBean.java
+88
-8
src/share/classes/javax/management/MatchQueryExp.java
src/share/classes/javax/management/MatchQueryExp.java
+1
-30
src/share/classes/javax/management/ObjectName.java
src/share/classes/javax/management/ObjectName.java
+1
-1
src/share/classes/javax/management/Query.java
src/share/classes/javax/management/Query.java
+6
-13
src/share/classes/javax/management/QueryNotificationFilter.java
...are/classes/javax/management/QueryNotificationFilter.java
+0
-6
src/share/classes/javax/management/QueryParser.java
src/share/classes/javax/management/QueryParser.java
+1
-38
src/share/classes/javax/management/StandardMBean.java
src/share/classes/javax/management/StandardMBean.java
+139
-29
src/share/classes/javax/management/openmbean/CompositeDataInvocationHandler.java
.../management/openmbean/CompositeDataInvocationHandler.java
+16
-7
src/share/classes/javax/management/openmbean/CompositeType.java
...are/classes/javax/management/openmbean/CompositeType.java
+2
-2
src/share/classes/javax/management/openmbean/MXBeanMapping.java
...are/classes/javax/management/openmbean/MXBeanMapping.java
+207
-0
src/share/classes/javax/management/openmbean/MXBeanMappingClass.java
...lasses/javax/management/openmbean/MXBeanMappingClass.java
+61
-0
src/share/classes/javax/management/openmbean/MXBeanMappingFactory.java
...sses/javax/management/openmbean/MXBeanMappingFactory.java
+162
-0
src/share/classes/javax/management/openmbean/MXBeanMappingFactoryClass.java
...javax/management/openmbean/MXBeanMappingFactoryClass.java
+72
-0
src/share/classes/javax/management/openmbean/OpenType.java
src/share/classes/javax/management/openmbean/OpenType.java
+1
-1
src/share/classes/sun/nio/cs/CharsetMapping.java
src/share/classes/sun/nio/cs/CharsetMapping.java
+5
-3
src/share/classes/sun/nio/cs/ext/SJIS_0213.java
src/share/classes/sun/nio/cs/ext/SJIS_0213.java
+14
-10
src/share/native/java/lang/System.c
src/share/native/java/lang/System.c
+1
-1
src/solaris/hpi/src/linker_md.c
src/solaris/hpi/src/linker_md.c
+0
-9
test/java/lang/System/Versions.java
test/java/lang/System/Versions.java
+1
-1
test/javax/management/mxbean/CustomTypeTest.java
test/javax/management/mxbean/CustomTypeTest.java
+590
-0
test/javax/management/mxbean/customtypes/CustomLongMXBean.java
...javax/management/mxbean/customtypes/CustomLongMXBean.java
+31
-0
test/javax/management/mxbean/customtypes/CustomMXBean.java
test/javax/management/mxbean/customtypes/CustomMXBean.java
+7
-15
test/javax/management/mxbean/customtypes/IntegerIsLongFactory.java
...x/management/mxbean/customtypes/IntegerIsLongFactory.java
+74
-0
test/javax/management/mxbean/customtypes/IntegerIsStringFactory.java
...management/mxbean/customtypes/IntegerIsStringFactory.java
+76
-0
test/javax/management/mxbean/customtypes/package-info.java
test/javax/management/mxbean/customtypes/package-info.java
+27
-0
test/javax/management/query/QueryExpStringTest.java
test/javax/management/query/QueryExpStringTest.java
+8
-31
test/javax/management/query/QueryParseTest.java
test/javax/management/query/QueryParseTest.java
+18
-15
未找到文件。
make/common/Release.gmk
浏览文件 @
3e149c7f
...
@@ -369,6 +369,7 @@ TOOLS = \
...
@@ -369,6 +369,7 @@ TOOLS = \
com/sun/jarsigner \
com/sun/jarsigner \
com/sun/mirror \
com/sun/mirror \
com/sun/source \
com/sun/source \
com/sun/tools/classfile \
com/sun/tools/doclets \
com/sun/tools/doclets \
com/sun/tools/example/debug/expr \
com/sun/tools/example/debug/expr \
com/sun/tools/example/debug/tty \
com/sun/tools/example/debug/tty \
...
@@ -378,6 +379,7 @@ TOOLS = \
...
@@ -378,6 +379,7 @@ TOOLS = \
com/sun/tools/javadoc \
com/sun/tools/javadoc \
com/sun/tools/apt \
com/sun/tools/apt \
com/sun/tools/javah \
com/sun/tools/javah \
com/sun/tools/javap \
com/sun/tools/corba \
com/sun/tools/corba \
com/sun/tools/internal/xjc \
com/sun/tools/internal/xjc \
com/sun/tools/internal/ws \
com/sun/tools/internal/ws \
...
@@ -568,6 +570,8 @@ $(NOT_RT_JAR_LIST): FRC
...
@@ -568,6 +570,8 @@ $(NOT_RT_JAR_LIST): FRC
$(ECHO) "sun/tools/java/" >> $@
$(ECHO) "sun/tools/java/" >> $@
$(ECHO) "sun/tools/javac/" >> $@
$(ECHO) "sun/tools/javac/" >> $@
$(ECHO) "sun/tools/javap/" >> $@
$(ECHO) "sun/tools/javap/" >> $@
$(ECHO) "com/sun/tools/classfile/" >> $@
$(ECHO) "com/sun/tools/javap/" >> $@
$(ECHO) "sun/tools/jconsole/" >> $@
$(ECHO) "sun/tools/jconsole/" >> $@
$(ECHO) "sun/tools/jps/" >> $@
$(ECHO) "sun/tools/jps/" >> $@
$(ECHO) "sun/tools/jstat/" >> $@
$(ECHO) "sun/tools/jstat/" >> $@
...
...
make/common/internal/Defs-langtools.gmk
浏览文件 @
3e149c7f
...
@@ -31,13 +31,15 @@ IMPORT_RT_PACKAGES += \
...
@@ -31,13 +31,15 @@ IMPORT_RT_PACKAGES += \
javax/tools
javax/tools
IMPORT_TOOLS_PACKAGES += \
IMPORT_TOOLS_PACKAGES += \
com/sun/javadoc \
com/sun/mirror \
com/sun/mirror \
com/sun/source \
com/sun/source \
com/sun/tools/apt \
com/sun/tools/apt \
com/sun/tools/classfile \
com/sun/tools/doclets \
com/sun/tools/javac \
com/sun/tools/javac \
com/sun/tools/javah \
com/sun/tools/javadoc \
com/sun/tools/javadoc \
com/sun/tools/
doclets
\
com/sun/tools/
javah
\
com/sun/
javadoc
\
com/sun/
tools/javap
\
sun/tools/javap
sun/tools/javap
src/share/classes/com/sun/jmx/mbeanserver/ConvertingMethod.java
浏览文件 @
3e149c7f
...
@@ -31,13 +31,15 @@ import java.lang.reflect.Type;
...
@@ -31,13 +31,15 @@ import java.lang.reflect.Type;
import
javax.management.Descriptor
;
import
javax.management.Descriptor
;
import
javax.management.MBeanException
;
import
javax.management.MBeanException
;
import
javax.management.openmbean.MXBeanMapping
;
import
javax.management.openmbean.MXBeanMappingFactory
;
import
javax.management.openmbean.OpenDataException
;
import
javax.management.openmbean.OpenDataException
;
import
javax.management.openmbean.OpenType
;
import
javax.management.openmbean.OpenType
;
final
class
ConvertingMethod
{
final
class
ConvertingMethod
{
static
ConvertingMethod
from
(
Method
m
)
{
static
ConvertingMethod
from
(
Method
m
,
MXBeanMappingFactory
mappingFactory
)
{
try
{
try
{
return
new
ConvertingMethod
(
m
);
return
new
ConvertingMethod
(
m
,
mappingFactory
);
}
catch
(
OpenDataException
ode
)
{
}
catch
(
OpenDataException
ode
)
{
final
String
msg
=
"Method "
+
m
.
getDeclaringClass
().
getName
()
+
final
String
msg
=
"Method "
+
m
.
getDeclaringClass
().
getName
()
+
"."
+
m
.
getName
()
+
" has parameter or return type that "
+
"."
+
m
.
getName
()
+
" has parameter or return type that "
+
...
@@ -67,13 +69,13 @@ final class ConvertingMethod {
...
@@ -67,13 +69,13 @@ final class ConvertingMethod {
}
}
OpenType
getOpenReturnType
()
{
OpenType
getOpenReturnType
()
{
return
return
Converter
.
getOpenType
();
return
return
Mapping
.
getOpenType
();
}
}
OpenType
[]
getOpenParameterTypes
()
{
OpenType
[]
getOpenParameterTypes
()
{
final
OpenType
[]
types
=
new
OpenType
[
param
Converter
s
.
length
];
final
OpenType
[]
types
=
new
OpenType
[
param
Mapping
s
.
length
];
for
(
int
i
=
0
;
i
<
param
Converter
s
.
length
;
i
++)
for
(
int
i
=
0
;
i
<
param
Mapping
s
.
length
;
i
++)
types
[
i
]
=
param
Converter
s
[
i
].
getOpenType
();
types
[
i
]
=
param
Mapping
s
[
i
].
getOpenType
();
return
types
;
return
types
;
}
}
...
@@ -85,9 +87,9 @@ final class ConvertingMethod {
...
@@ -85,9 +87,9 @@ final class ConvertingMethod {
* value will be converted to an Open Type, so if it is convertible
* value will be converted to an Open Type, so if it is convertible
* at all there is no further check needed.
* at all there is no further check needed.
*/
*/
void
checkCallFromOpen
()
throws
IllegalArgumentException
{
void
checkCallFromOpen
()
{
try
{
try
{
for
(
OpenConverter
paramConverter
:
paramConverter
s
)
for
(
MXBeanMapping
paramConverter
:
paramMapping
s
)
paramConverter
.
checkReconstructible
();
paramConverter
.
checkReconstructible
();
}
catch
(
InvalidObjectException
e
)
{
}
catch
(
InvalidObjectException
e
)
{
throw
new
IllegalArgumentException
(
e
);
throw
new
IllegalArgumentException
(
e
);
...
@@ -102,32 +104,32 @@ final class ConvertingMethod {
...
@@ -102,32 +104,32 @@ final class ConvertingMethod {
* open types, so if it is convertible at all there is no further
* open types, so if it is convertible at all there is no further
* check needed.
* check needed.
*/
*/
void
checkCallToOpen
()
throws
IllegalArgumentException
{
void
checkCallToOpen
()
{
try
{
try
{
return
Converter
.
checkReconstructible
();
return
Mapping
.
checkReconstructible
();
}
catch
(
InvalidObjectException
e
)
{
}
catch
(
InvalidObjectException
e
)
{
throw
new
IllegalArgumentException
(
e
);
throw
new
IllegalArgumentException
(
e
);
}
}
}
}
String
[]
getOpenSignature
()
{
String
[]
getOpenSignature
()
{
if
(
param
Converter
s
.
length
==
0
)
if
(
param
Mapping
s
.
length
==
0
)
return
noStrings
;
return
noStrings
;
String
[]
sig
=
new
String
[
param
Converter
s
.
length
];
String
[]
sig
=
new
String
[
param
Mapping
s
.
length
];
for
(
int
i
=
0
;
i
<
param
Converter
s
.
length
;
i
++)
for
(
int
i
=
0
;
i
<
param
Mapping
s
.
length
;
i
++)
sig
[
i
]
=
param
Converter
s
[
i
].
getOpenClass
().
getName
();
sig
[
i
]
=
param
Mapping
s
[
i
].
getOpenClass
().
getName
();
return
sig
;
return
sig
;
}
}
final
Object
toOpenReturnValue
(
MXBeanLookup
lookup
,
Object
ret
)
final
Object
toOpenReturnValue
(
MXBeanLookup
lookup
,
Object
ret
)
throws
OpenDataException
{
throws
OpenDataException
{
return
return
Converter
.
toOpenValue
(
lookup
,
ret
);
return
return
Mapping
.
toOpenValue
(
ret
);
}
}
final
Object
fromOpenReturnValue
(
MXBeanLookup
lookup
,
Object
ret
)
final
Object
fromOpenReturnValue
(
MXBeanLookup
lookup
,
Object
ret
)
throws
InvalidObjectException
{
throws
InvalidObjectException
{
return
return
Converter
.
fromOpenValue
(
lookup
,
ret
);
return
return
Mapping
.
fromOpenValue
(
ret
);
}
}
final
Object
[]
toOpenParameters
(
MXBeanLookup
lookup
,
Object
[]
params
)
final
Object
[]
toOpenParameters
(
MXBeanLookup
lookup
,
Object
[]
params
)
...
@@ -136,17 +138,17 @@ final class ConvertingMethod {
...
@@ -136,17 +138,17 @@ final class ConvertingMethod {
return
params
;
return
params
;
final
Object
[]
oparams
=
new
Object
[
params
.
length
];
final
Object
[]
oparams
=
new
Object
[
params
.
length
];
for
(
int
i
=
0
;
i
<
params
.
length
;
i
++)
for
(
int
i
=
0
;
i
<
params
.
length
;
i
++)
oparams
[
i
]
=
param
Converters
[
i
].
toOpenValue
(
lookup
,
params
[
i
]);
oparams
[
i
]
=
param
Mappings
[
i
].
toOpenValue
(
params
[
i
]);
return
oparams
;
return
oparams
;
}
}
final
Object
[]
fromOpenParameters
(
MXBeanLookup
lookup
,
Object
[]
params
)
final
Object
[]
fromOpenParameters
(
Object
[]
params
)
throws
InvalidObjectException
{
throws
InvalidObjectException
{
if
(
paramConversionIsIdentity
||
params
==
null
)
if
(
paramConversionIsIdentity
||
params
==
null
)
return
params
;
return
params
;
final
Object
[]
jparams
=
new
Object
[
params
.
length
];
final
Object
[]
jparams
=
new
Object
[
params
.
length
];
for
(
int
i
=
0
;
i
<
params
.
length
;
i
++)
for
(
int
i
=
0
;
i
<
params
.
length
;
i
++)
jparams
[
i
]
=
param
Converters
[
i
].
fromOpenValue
(
lookup
,
params
[
i
]);
jparams
[
i
]
=
param
Mappings
[
i
].
fromOpenValue
(
params
[
i
]);
return
jparams
;
return
jparams
;
}
}
...
@@ -154,23 +156,35 @@ final class ConvertingMethod {
...
@@ -154,23 +156,35 @@ final class ConvertingMethod {
Object
param
,
Object
param
,
int
paramNo
)
int
paramNo
)
throws
OpenDataException
{
throws
OpenDataException
{
return
param
Converters
[
paramNo
].
toOpenValue
(
lookup
,
param
);
return
param
Mappings
[
paramNo
].
toOpenValue
(
param
);
}
}
final
Object
fromOpenParameter
(
MXBeanLookup
lookup
,
final
Object
fromOpenParameter
(
MXBeanLookup
lookup
,
Object
param
,
Object
param
,
int
paramNo
)
int
paramNo
)
throws
InvalidObjectException
{
throws
InvalidObjectException
{
return
param
Converters
[
paramNo
].
fromOpenValue
(
lookup
,
param
);
return
param
Mappings
[
paramNo
].
fromOpenValue
(
param
);
}
}
Object
invokeWithOpenReturn
(
MXBeanLookup
lookup
,
Object
invokeWithOpenReturn
(
MXBeanLookup
lookup
,
Object
obj
,
Object
[]
params
)
Object
obj
,
Object
[]
params
)
throws
MBeanException
,
IllegalAccessException
,
throws
MBeanException
,
IllegalAccessException
,
InvocationTargetException
{
InvocationTargetException
{
MXBeanLookup
old
=
MXBeanLookup
.
getLookup
();
try
{
MXBeanLookup
.
setLookup
(
lookup
);
return
invokeWithOpenReturn
(
obj
,
params
);
}
finally
{
MXBeanLookup
.
setLookup
(
old
);
}
}
private
Object
invokeWithOpenReturn
(
Object
obj
,
Object
[]
params
)
throws
MBeanException
,
IllegalAccessException
,
InvocationTargetException
{
final
Object
[]
javaParams
;
final
Object
[]
javaParams
;
try
{
try
{
javaParams
=
fromOpenParameters
(
lookup
,
params
);
javaParams
=
fromOpenParameters
(
params
);
}
catch
(
InvalidObjectException
e
)
{
}
catch
(
InvalidObjectException
e
)
{
// probably can't happen
// probably can't happen
final
String
msg
=
methodName
()
+
": cannot convert parameters "
+
final
String
msg
=
methodName
()
+
": cannot convert parameters "
+
...
@@ -179,7 +193,7 @@ final class ConvertingMethod {
...
@@ -179,7 +193,7 @@ final class ConvertingMethod {
}
}
final
Object
javaReturn
=
method
.
invoke
(
obj
,
javaParams
);
final
Object
javaReturn
=
method
.
invoke
(
obj
,
javaParams
);
try
{
try
{
return
return
Converter
.
toOpenValue
(
lookup
,
javaReturn
);
return
return
Mapping
.
toOpenValue
(
javaReturn
);
}
catch
(
OpenDataException
e
)
{
}
catch
(
OpenDataException
e
)
{
// probably can't happen
// probably can't happen
final
String
msg
=
methodName
()
+
": cannot convert return "
+
final
String
msg
=
methodName
()
+
": cannot convert return "
+
...
@@ -192,15 +206,17 @@ final class ConvertingMethod {
...
@@ -192,15 +206,17 @@ final class ConvertingMethod {
return
method
.
getDeclaringClass
()
+
"."
+
method
.
getName
();
return
method
.
getDeclaringClass
()
+
"."
+
method
.
getName
();
}
}
private
ConvertingMethod
(
Method
m
)
throws
OpenDataException
{
private
ConvertingMethod
(
Method
m
,
MXBeanMappingFactory
mappingFactory
)
throws
OpenDataException
{
this
.
method
=
m
;
this
.
method
=
m
;
returnConverter
=
OpenConverter
.
toConverter
(
m
.
getGenericReturnType
());
returnMapping
=
mappingFactory
.
mappingForType
(
m
.
getGenericReturnType
(),
mappingFactory
);
Type
[]
params
=
m
.
getGenericParameterTypes
();
Type
[]
params
=
m
.
getGenericParameterTypes
();
param
Converters
=
new
OpenConverter
[
params
.
length
];
param
Mappings
=
new
MXBeanMapping
[
params
.
length
];
boolean
identity
=
true
;
boolean
identity
=
true
;
for
(
int
i
=
0
;
i
<
params
.
length
;
i
++)
{
for
(
int
i
=
0
;
i
<
params
.
length
;
i
++)
{
param
Converters
[
i
]
=
OpenConverter
.
toConverter
(
params
[
i
]
);
param
Mappings
[
i
]
=
mappingFactory
.
mappingForType
(
params
[
i
],
mappingFactory
);
identity
&=
paramConverters
[
i
].
isIdentity
(
);
identity
&=
DefaultMXBeanMappingFactory
.
isIdentity
(
paramMappings
[
i
]
);
}
}
paramConversionIsIdentity
=
identity
;
paramConversionIsIdentity
=
identity
;
}
}
...
@@ -208,7 +224,7 @@ final class ConvertingMethod {
...
@@ -208,7 +224,7 @@ final class ConvertingMethod {
private
static
final
String
[]
noStrings
=
new
String
[
0
];
private
static
final
String
[]
noStrings
=
new
String
[
0
];
private
final
Method
method
;
private
final
Method
method
;
private
final
OpenConverter
returnConverter
;
private
final
MXBeanMapping
returnMapping
;
private
final
OpenConverter
[]
paramConverter
s
;
private
final
MXBeanMapping
[]
paramMapping
s
;
private
final
boolean
paramConversionIsIdentity
;
private
final
boolean
paramConversionIsIdentity
;
}
}
src/share/classes/com/sun/jmx/mbeanserver/
OpenConverter
.java
→
src/share/classes/com/sun/jmx/mbeanserver/
DefaultMXBeanMappingFactory
.java
浏览文件 @
3e149c7f
...
@@ -26,6 +26,8 @@
...
@@ -26,6 +26,8 @@
package
com.sun.jmx.mbeanserver
;
package
com.sun.jmx.mbeanserver
;
import
static
com
.
sun
.
jmx
.
mbeanserver
.
Util
.*;
import
static
com
.
sun
.
jmx
.
mbeanserver
.
Util
.*;
import
java.lang.annotation.ElementType
;
import
javax.management.openmbean.MXBeanMappingClass
;
import
static
javax
.
management
.
openmbean
.
SimpleType
.*;
import
static
javax
.
management
.
openmbean
.
SimpleType
.*;
...
@@ -66,6 +68,8 @@ import javax.management.openmbean.CompositeDataInvocationHandler;
...
@@ -66,6 +68,8 @@ import javax.management.openmbean.CompositeDataInvocationHandler;
import
javax.management.openmbean.CompositeDataSupport
;
import
javax.management.openmbean.CompositeDataSupport
;
import
javax.management.openmbean.CompositeDataView
;
import
javax.management.openmbean.CompositeDataView
;
import
javax.management.openmbean.CompositeType
;
import
javax.management.openmbean.CompositeType
;
import
javax.management.openmbean.MXBeanMapping
;
import
javax.management.openmbean.MXBeanMappingFactory
;
import
javax.management.openmbean.OpenDataException
;
import
javax.management.openmbean.OpenDataException
;
import
javax.management.openmbean.OpenType
;
import
javax.management.openmbean.OpenType
;
import
javax.management.openmbean.SimpleType
;
import
javax.management.openmbean.SimpleType
;
...
@@ -74,137 +78,118 @@ import javax.management.openmbean.TabularDataSupport;
...
@@ -74,137 +78,118 @@ import javax.management.openmbean.TabularDataSupport;
import
javax.management.openmbean.TabularType
;
import
javax.management.openmbean.TabularType
;
/**
/**
<p>A converter between Java types and the limited set of classes
*
<p>A converter between Java types and the limited set of classes
defined by Open MBeans.</p>
*
defined by Open MBeans.</p>
*
<p>A Java type is an instance of java.lang.reflect.Type. For our
*
<p>A Java type is an instance of java.lang.reflect.Type. For our
purposes, it is either a Class, such as String.class or int.class;
*
purposes, it is either a Class, such as String.class or int.class;
or a ParameterizedType, such as List<String> or Map<Integer,
*
or a ParameterizedType, such as List<String> or Map<Integer,
String[]>. On J2SE 1.4 and earlier, it can only be a Class.</p>
*
String[]>. On J2SE 1.4 and earlier, it can only be a Class.</p>
*
<p>Each Type is associated with an OpenConverter
. The
* <p>Each Type is associated with an DefaultMXBeanMappingFactory
. The
OpenConverter
defines an OpenType corresponding to the Type, plus a
* DefaultMXBeanMappingFactory
defines an OpenType corresponding to the Type, plus a
Java class corresponding to the OpenType. For example:</p>
*
Java class corresponding to the OpenType. For example:</p>
*
<pre>
*
<pre>
Type Open class OpenType
*
Type Open class OpenType
---- ---------- --------
*
---- ---------- --------
Integer
Integer SimpleType.INTEGER
* Integer
Integer SimpleType.INTEGER
int
int SimpleType.INTEGER
* int
int SimpleType.INTEGER
Integer[]
Integer[] ArrayType(1, SimpleType.INTEGER)
* Integer[]
Integer[] ArrayType(1, SimpleType.INTEGER)
int[]
Integer[] ArrayType(SimpleType.INTEGER, true)
* int[]
Integer[] ArrayType(SimpleType.INTEGER, true)
String[][]
String[][] ArrayType(2, SimpleType.STRING)
* String[][]
String[][] ArrayType(2, SimpleType.STRING)
List<String>
String[] ArrayType(1, SimpleType.STRING)
* List<String>
String[] ArrayType(1, SimpleType.STRING)
ThreadState (an Enum) String SimpleType.STRING
*
ThreadState (an Enum) String SimpleType.STRING
Map<Integer, String[]> TabularData
TabularType(
* Map<Integer, String[]> TabularData
TabularType(
CompositeType(
*
CompositeType(
{"key", SimpleType.INTEGER},
*
{"key", SimpleType.INTEGER},
{"value",
*
{"value",
ArrayType(1,
*
ArrayType(1,
SimpleType.STRING)}),
*
SimpleType.STRING)}),
indexNames={"key"})
*
indexNames={"key"})
</pre>
*
</pre>
*
<p>Apart from simple types, arrays, and collections, Java types are
*
<p>Apart from simple types, arrays, and collections, Java types are
converted through introspection into CompositeType. The Java type
*
converted through introspection into CompositeType. The Java type
must have at least one getter (method such as "int getSize()" or
*
must have at least one getter (method such as "int getSize()" or
"boolean isBig()"), and we must be able to deduce how to
*
"boolean isBig()"), and we must be able to deduce how to
reconstruct an instance of the Java class from the values of the
*
reconstruct an instance of the Java class from the values of the
getters using one of various heuristics.</p>
*
getters using one of various heuristics.</p>
*
@since 1.6
*
@since 1.6
*/
*/
public
abstract
class
OpenConverter
{
public
class
DefaultMXBeanMappingFactory
extends
MXBeanMappingFactory
{
private
OpenConverter
(
Type
targetType
,
OpenType
openType
,
static
abstract
class
NonNullMXBeanMapping
extends
MXBeanMapping
{
Class
openClass
)
{
NonNullMXBeanMapping
(
Type
javaType
,
OpenType
openType
)
{
this
.
targetType
=
targetType
;
super
(
javaType
,
openType
);
this
.
openType
=
openType
;
}
this
.
openClass
=
openClass
;
}
/** <p>Convert an instance of openClass into an instance of targetType. */
public
final
Object
fromOpenValue
(
MXBeanLookup
lookup
,
Object
value
)
throws
InvalidObjectException
{
if
(
value
==
null
)
return
null
;
else
return
fromNonNullOpenValue
(
lookup
,
value
);
}
abstract
Object
fromNonNullOpenValue
(
MXBeanLookup
lookup
,
Object
value
)
throws
InvalidObjectException
;
/** <p>Throw an appropriate InvalidObjectException if we will not be able
to convert back from the open data to the original Java object.</p> */
void
checkReconstructible
()
throws
InvalidObjectException
{
// subclasses override if action necessary
}
/** <p>Convert an instance of targetType into an instance of openClass. */
@Override
final
Object
toOpenValue
(
MXBeanLookup
lookup
,
Object
v
alue
)
public
final
Object
fromOpenValue
(
Object
openV
alue
)
throws
OpenData
Exception
{
throws
InvalidObject
Exception
{
if
(
v
alue
==
null
)
if
(
openV
alue
==
null
)
return
null
;
return
null
;
else
else
return
toNonNullOpenValue
(
lookup
,
v
alue
);
return
fromNonNullOpenValue
(
openV
alue
);
}
}
abstract
Object
toNonNullOpenValue
(
MXBeanLookup
lookup
,
Object
value
)
@Override
throws
OpenDataException
;
public
final
Object
toOpenValue
(
Object
javaValue
)
throws
OpenDataException
{
if
(
javaValue
==
null
)
return
null
;
else
return
toNonNullOpenValue
(
javaValue
);
}
/** <p>True if and only if this OpenConverter's toOpenValue and fromOpenValue
abstract
Object
fromNonNullOpenValue
(
Object
openValue
)
methods are the identity function.</p> */
throws
InvalidObjectException
;
boolean
isIdentity
()
{
return
false
;
}
/** <p>True if and only if isIdentity() and even an array of the underlying type
abstract
Object
toNonNullOpenValue
(
Object
javaValue
)
is transformed as the identity. This is true for Integer and
throws
OpenDataException
;
ObjectName, for instance, but not for int.</p> */
final
Type
getTargetType
()
{
return
targetType
;
}
final
OpenType
getOpenType
()
{
/**
return
openType
;
* <p>True if and only if this MXBeanMapping's toOpenValue and
* fromOpenValue methods are the identity function.</p>
*/
boolean
isIdentity
()
{
return
false
;
}
}
}
/* The Java class corresponding to getOpenType(). This is the class
static
boolean
isIdentity
(
MXBeanMapping
mapping
)
{
named by getOpenType().getClassName(), except that it may be a
return
(
mapping
instanceof
NonNullMXBeanMapping
&&
primitive type or an array of primitive type. */
((
NonNullMXBeanMapping
)
mapping
).
isIdentity
());
final
Class
getOpenClass
()
{
return
openClass
;
}
}
private
final
Type
targetType
;
private
static
final
class
Mappings
private
final
OpenType
openType
;
extends
WeakHashMap
<
Type
,
WeakReference
<
MXBeanMapping
>>
{}
private
final
Class
openClass
;
private
static
final
class
ConverterMap
private
static
final
Map
<
MXBeanMappingFactory
,
Mappings
>
factoryMappings
=
extends
WeakHashMap
<
Type
,
WeakReference
<
OpenConverter
>>
{}
new
WeakHashMap
<
MXBeanMappingFactory
,
Mappings
>();
private
static
final
ConverterMap
converterMap
=
new
Converter
Map
();
private
static
final
Map
<
Type
,
MXBeanMapping
>
permanentMappings
=
new
Map
();
/** Following List simply serves to keep a reference to predefined
private
static
synchronized
MXBeanMapping
getMapping
(
OpenConverters so they don't get garbage collected. */
Type
type
,
MXBeanMappingFactory
factory
)
{
private
static
final
List
<
OpenConverter
>
permanentConverters
=
newList
();
Mappings
mappings
=
factoryMappings
.
get
(
factory
);
if
(
mappings
==
null
)
{
private
static
synchronized
OpenConverter
getConverter
(
Type
type
)
{
mappings
=
new
Mappings
();
WeakReference
<
OpenConverter
>
wr
=
converterMap
.
get
(
type
);
factoryMappings
.
put
(
factory
,
mappings
);
}
WeakReference
<
MXBeanMapping
>
wr
=
mappings
.
get
(
type
);
return
(
wr
==
null
)
?
null
:
wr
.
get
();
return
(
wr
==
null
)
?
null
:
wr
.
get
();
}
}
private
static
synchronized
void
putConverter
(
Type
type
,
private
static
synchronized
void
putMapping
(
OpenConverter
conv
)
{
Type
type
,
MXBeanMapping
mapping
,
MXBeanMappingFactory
factory
)
{
WeakReference
<
OpenConverter
>
wr
=
Mappings
mappings
=
factoryMappings
.
get
(
factory
);
new
WeakReference
<
OpenConverter
>(
conv
);
if
(
mappings
==
null
)
{
converterMap
.
put
(
type
,
wr
);
mappings
=
new
Mappings
();
}
factoryMappings
.
put
(
factory
,
mappings
);
}
private
static
synchronized
void
putPermanentConverter
(
Type
type
,
WeakReference
<
MXBeanMapping
>
wr
=
OpenConverter
conv
)
{
new
WeakReference
<
MXBeanMapping
>(
mapping
);
putConverter
(
type
,
conv
);
mappings
.
put
(
type
,
wr
);
permanentConverters
.
add
(
conv
);
}
}
static
{
static
{
...
@@ -226,28 +211,26 @@ public abstract class OpenConverter {
...
@@ -226,28 +211,26 @@ public abstract class OpenConverter {
// the classes that these predefined types declare must exist!
// the classes that these predefined types declare must exist!
throw
new
Error
(
e
);
throw
new
Error
(
e
);
}
}
final
OpenConverter
conv
=
new
IdentityConverter
(
c
,
t
,
c
);
final
MXBeanMapping
mapping
=
new
IdentityMapping
(
c
,
t
);
p
utPermanentConverter
(
c
,
conv
);
p
ermanentMappings
.
put
(
c
,
mapping
);
if
(
c
.
getName
().
startsWith
(
"java.lang."
))
{
if
(
c
.
getName
().
startsWith
(
"java.lang."
))
{
try
{
try
{
final
Field
typeField
=
c
.
getField
(
"TYPE"
);
final
Field
typeField
=
c
.
getField
(
"TYPE"
);
final
Class
primitiveType
=
(
Class
)
typeField
.
get
(
null
);
final
Class
<?>
primitiveType
=
(
Class
<?>)
typeField
.
get
(
null
);
final
OpenConverter
primitiveConv
=
final
MXBeanMapping
primitiveMapping
=
new
IdentityConverter
(
primitiveType
,
t
,
primitiveType
);
new
IdentityMapping
(
primitiveType
,
t
);
putPermanentConverter
(
primitiveType
,
permanentMappings
.
put
(
primitiveType
,
primitiveMapping
);
primitiveConv
);
if
(
primitiveType
!=
void
.
class
)
{
if
(
primitiveType
!=
void
.
class
)
{
final
Class
<?>
primitiveArrayType
=
final
Class
<?>
primitiveArrayType
=
Array
.
newInstance
(
primitiveType
,
0
).
getClass
();
Array
.
newInstance
(
primitiveType
,
0
).
getClass
();
final
OpenType
primitiveArrayOpenType
=
final
OpenType
primitiveArrayOpenType
=
ArrayType
.
getPrimitiveArrayType
(
primitiveArrayType
);
ArrayType
.
getPrimitiveArrayType
(
primitiveArrayType
);
final
OpenConverter
primitiveArrayConv
=
final
MXBeanMapping
primitiveArrayMapping
=
new
IdentityConverter
(
primitiveArrayType
,
new
IdentityMapping
(
primitiveArrayType
,
primitiveArrayOpenType
,
primitiveArrayOpenType
);
primitiveArrayType
);
permanentMappings
.
put
(
primitiveArrayType
,
putPermanentConverter
(
primitiveArrayType
,
primitiveArrayMapping
);
primitiveArrayConv
);
}
}
}
catch
(
NoSuchFieldException
e
)
{
}
catch
(
NoSuchFieldException
e
)
{
// OK: must not be a primitive wrapper
// OK: must not be a primitive wrapper
...
@@ -260,64 +243,119 @@ public abstract class OpenConverter {
...
@@ -260,64 +243,119 @@ public abstract class OpenConverter {
}
}
/** Get the converter for the given Java type, creating it if necessary. */
/** Get the converter for the given Java type, creating it if necessary. */
public
static
synchronized
OpenConverter
toConverter
(
Type
objType
)
@Override
public
synchronized
MXBeanMapping
mappingForType
(
Type
objType
,
MXBeanMappingFactory
factory
)
throws
OpenDataException
{
throws
OpenDataException
{
if
(
inProgress
.
containsKey
(
objType
))
if
(
inProgress
.
containsKey
(
objType
))
throw
new
OpenDataException
(
"Recursive data structure"
);
throw
new
OpenDataException
(
"Recursive data structure"
);
OpenConverter
conv
;
MXBeanMapping
mapping
;
conv
=
getConverter
(
objType
);
mapping
=
getMapping
(
objType
,
null
);
if
(
conv
!=
null
)
if
(
mapping
!=
null
)
return
conv
;
return
mapping
;
inProgress
.
put
(
objType
,
objType
);
inProgress
.
put
(
objType
,
objType
);
try
{
try
{
conv
=
makeConverter
(
objType
);
mapping
=
makeMapping
(
objType
,
factory
);
}
finally
{
}
finally
{
inProgress
.
remove
(
objType
);
inProgress
.
remove
(
objType
);
}
}
put
Converter
(
objType
,
conv
);
put
Mapping
(
objType
,
mapping
,
factory
);
return
conv
;
return
mapping
;
}
}
private
static
OpenConverter
makeConverter
(
Type
objType
)
private
MXBeanMapping
makeMapping
(
Type
objType
,
MXBeanMappingFactory
factory
)
throws
OpenDataException
{
throws
OpenDataException
{
/* It's not yet worth formalizing these tests by having for example
/* It's not yet worth formalizing these tests by having for example
an array of factory classes, each of which says whether it
an array of factory classes, each of which says whether it
recognizes the Type (Chain of Responsibility pattern). */
recognizes the Type (Chain of Responsibility pattern). */
MXBeanMapping
mapping
=
permanentMappings
.
get
(
objType
);
if
(
mapping
!=
null
)
return
mapping
;
Class
<?>
erasure
=
erasure
(
objType
);
MXBeanMappingClass
mappingClass
=
erasure
.
getAnnotation
(
MXBeanMappingClass
.
class
);
if
(
mappingClass
!=
null
)
return
makeAnnotationMapping
(
mappingClass
,
objType
,
factory
);
if
(
objType
instanceof
GenericArrayType
)
{
if
(
objType
instanceof
GenericArrayType
)
{
Type
componentType
=
Type
componentType
=
((
GenericArrayType
)
objType
).
getGenericComponentType
();
((
GenericArrayType
)
objType
).
getGenericComponentType
();
return
makeArrayOrCollection
Converter
(
objType
,
componentType
);
return
makeArrayOrCollection
Mapping
(
objType
,
componentType
,
factory
);
}
else
if
(
objType
instanceof
Class
)
{
}
else
if
(
objType
instanceof
Class
)
{
Class
<?>
objClass
=
(
Class
<?>)
objType
;
Class
<?>
objClass
=
(
Class
<?>)
objType
;
if
(
objClass
.
isEnum
())
{
if
(
objClass
.
isEnum
())
{
// Huge hack to avoid compiler warnings here. The ElementType
// Huge hack to avoid compiler warnings here. The ElementType
// parameter is ignored but allows us to obtain a type variable
// parameter is ignored but allows us to obtain a type variable
// T that matches <T extends Enum<T>>.
// T that matches <T extends Enum<T>>.
return
makeEnum
Converter
(
objClass
,
ElementType
.
class
);
return
makeEnum
Mapping
((
Class
)
objClass
,
ElementType
.
class
);
}
else
if
(
objClass
.
isArray
())
{
}
else
if
(
objClass
.
isArray
())
{
Type
componentType
=
objClass
.
getComponentType
();
Type
componentType
=
objClass
.
getComponentType
();
return
makeArrayOrCollectionConverter
(
objClass
,
componentType
);
return
makeArrayOrCollectionMapping
(
objClass
,
componentType
,
factory
);
}
else
if
(
JMX
.
isMXBeanInterface
(
objClass
))
{
}
else
if
(
JMX
.
isMXBeanInterface
(
objClass
))
{
return
makeMXBean
Converter
(
objClass
);
return
makeMXBean
RefMapping
(
objClass
);
}
else
{
}
else
{
return
makeComposite
Converter
(
objClass
);
return
makeComposite
Mapping
(
objClass
,
factory
);
}
}
}
else
if
(
objType
instanceof
ParameterizedType
)
{
}
else
if
(
objType
instanceof
ParameterizedType
)
{
return
makeParameterizedConverter
((
ParameterizedType
)
objType
);
return
makeParameterizedTypeMapping
((
ParameterizedType
)
objType
,
factory
);
}
else
}
else
throw
new
OpenDataException
(
"Cannot map type: "
+
objType
);
throw
new
OpenDataException
(
"Cannot map type: "
+
objType
);
}
}
private
static
<
T
extends
Enum
<
T
>>
OpenConverter
private
static
MXBeanMapping
makeEnumConverter
(
Class
<?>
enumClass
,
Class
<
T
>
fake
)
{
makeAnnotationMapping
(
MXBeanMappingClass
mappingClass
,
Class
<
T
>
enumClassT
=
Util
.
cast
(
enumClass
);
Type
objType
,
return
new
EnumConverter
<
T
>(
enumClassT
);
MXBeanMappingFactory
factory
)
throws
OpenDataException
{
Class
<?
extends
MXBeanMapping
>
c
=
mappingClass
.
value
();
Constructor
<?
extends
MXBeanMapping
>
cons
;
try
{
cons
=
c
.
getConstructor
(
Type
.
class
);
}
catch
(
NoSuchMethodException
e
)
{
final
String
msg
=
"Annotation @"
+
MXBeanMappingClass
.
class
.
getName
()
+
" must name a class with a public constructor that has a "
+
"single "
+
Type
.
class
.
getName
()
+
" argument"
;
OpenDataException
ode
=
new
OpenDataException
(
msg
);
ode
.
initCause
(
e
);
throw
ode
;
}
try
{
return
cons
.
newInstance
(
objType
);
}
catch
(
Exception
e
)
{
final
String
msg
=
"Could not construct a "
+
c
.
getName
()
+
" for @"
+
MXBeanMappingClass
.
class
.
getName
();
OpenDataException
ode
=
new
OpenDataException
(
msg
);
ode
.
initCause
(
e
);
throw
ode
;
}
}
private
static
Class
<?>
erasure
(
Type
t
)
{
if
(
t
instanceof
Class
<?>)
return
(
Class
<?>)
t
;
if
(
t
instanceof
ParameterizedType
)
return
erasure
(((
ParameterizedType
)
t
).
getRawType
());
/* Other cases: GenericArrayType, TypeVariable, WildcardType.
* Returning the erasure of GenericArrayType is not necessary because
* anyway we will be recursing on the element type, and we'll erase
* then. Returning the erasure of the other two would mean returning
* the type bound (e.g. Foo in <T extends Foo> or <? extends Foo>)
* and since we don't treat this as Foo elsewhere we shouldn't here.
*/
return
Object
.
class
;
}
private
static
<
T
extends
Enum
<
T
>>
MXBeanMapping
makeEnumMapping
(
Class
enumClass
,
Class
<
T
>
fake
)
{
return
new
EnumMapping
<
T
>(
Util
.<
Class
<
T
>>
cast
(
enumClass
));
}
}
/* Make the converter for an array type, or a collection such as
/* Make the converter for an array type, or a collection such as
...
@@ -325,14 +363,15 @@ public abstract class OpenConverter {
...
@@ -325,14 +363,15 @@ public abstract class OpenConverter {
* primitive arrays (e.g. int[]) here because they use the identity
* primitive arrays (e.g. int[]) here because they use the identity
* converter and are registered as such in the static initializer.
* converter and are registered as such in the static initializer.
*/
*/
private
static
OpenConverter
private
MXBeanMapping
makeArrayOrCollectionConverter
(
Type
collectionType
,
Type
elementType
)
makeArrayOrCollectionMapping
(
Type
collectionType
,
Type
elementType
,
MXBeanMappingFactory
factory
)
throws
OpenDataException
{
throws
OpenDataException
{
final
OpenConverter
elementConverter
=
toConverter
(
elementType
);
final
MXBeanMapping
elementMapping
=
factory
.
mappingForType
(
elementType
,
factory
);
final
OpenType
<?>
elementOpenType
=
element
Converter
.
getOpenType
();
final
OpenType
<?>
elementOpenType
=
element
Mapping
.
getOpenType
();
final
ArrayType
<?>
openType
=
ArrayType
.
getArrayType
(
elementOpenType
);
final
ArrayType
<?>
openType
=
ArrayType
.
getArrayType
(
elementOpenType
);
final
Class
<?>
elementOpenClass
=
element
Converter
.
getOpenClass
();
final
Class
<?>
elementOpenClass
=
element
Mapping
.
getOpenClass
();
final
Class
<?>
openArrayClass
;
final
Class
<?>
openArrayClass
;
final
String
openArrayClassName
;
final
String
openArrayClassName
;
...
@@ -347,19 +386,18 @@ public abstract class OpenConverter {
...
@@ -347,19 +386,18 @@ public abstract class OpenConverter {
}
}
if
(
collectionType
instanceof
ParameterizedType
)
{
if
(
collectionType
instanceof
ParameterizedType
)
{
return
new
Collection
Converter
(
collectionType
,
return
new
Collection
Mapping
(
collectionType
,
openType
,
openArrayClass
,
openType
,
openArrayClass
,
elementConverter
);
elementMapping
);
}
else
{
}
else
{
if
(
elementConverter
.
isIdentity
())
{
if
(
isIdentity
(
elementMapping
))
{
return
new
IdentityConverter
(
collectionType
,
return
new
IdentityMapping
(
collectionType
,
openType
,
openType
);
openArrayClass
);
}
else
{
}
else
{
return
new
Array
Converter
(
collectionType
,
return
new
Array
Mapping
(
collectionType
,
openType
,
openType
,
openArrayClass
,
openArrayClass
,
element
Converter
);
element
Mapping
);
}
}
}
}
}
}
...
@@ -367,16 +405,17 @@ public abstract class OpenConverter {
...
@@ -367,16 +405,17 @@ public abstract class OpenConverter {
private
static
final
String
[]
keyArray
=
{
"key"
};
private
static
final
String
[]
keyArray
=
{
"key"
};
private
static
final
String
[]
keyValueArray
=
{
"key"
,
"value"
};
private
static
final
String
[]
keyValueArray
=
{
"key"
,
"value"
};
private
static
OpenConverter
private
MXBeanMapping
makeTabularConverter
(
Type
objType
,
boolean
sortedMap
,
makeTabularMapping
(
Type
objType
,
boolean
sortedMap
,
Type
keyType
,
Type
valueType
)
Type
keyType
,
Type
valueType
,
MXBeanMappingFactory
factory
)
throws
OpenDataException
{
throws
OpenDataException
{
final
String
objTypeName
=
objType
.
toString
();
final
String
objTypeName
=
objType
.
toString
();
final
OpenConverter
keyConverter
=
toConverter
(
keyType
);
final
MXBeanMapping
keyMapping
=
factory
.
mappingForType
(
keyType
,
factory
);
final
OpenConverter
valueConverter
=
toConverter
(
valueType
);
final
MXBeanMapping
valueMapping
=
factory
.
mappingForType
(
valueType
,
factory
);
final
OpenType
keyOpenType
=
key
Converter
.
getOpenType
();
final
OpenType
keyOpenType
=
key
Mapping
.
getOpenType
();
final
OpenType
valueOpenType
=
value
Converter
.
getOpenType
();
final
OpenType
valueOpenType
=
value
Mapping
.
getOpenType
();
final
CompositeType
rowType
=
final
CompositeType
rowType
=
new
CompositeType
(
objTypeName
,
new
CompositeType
(
objTypeName
,
objTypeName
,
objTypeName
,
...
@@ -385,8 +424,8 @@ public abstract class OpenConverter {
...
@@ -385,8 +424,8 @@ public abstract class OpenConverter {
new
OpenType
[]
{
keyOpenType
,
valueOpenType
});
new
OpenType
[]
{
keyOpenType
,
valueOpenType
});
final
TabularType
tabularType
=
final
TabularType
tabularType
=
new
TabularType
(
objTypeName
,
objTypeName
,
rowType
,
keyArray
);
new
TabularType
(
objTypeName
,
objTypeName
,
rowType
,
keyArray
);
return
new
Tabular
Converter
(
objType
,
sortedMap
,
tabularType
,
return
new
Tabular
Mapping
(
objType
,
sortedMap
,
tabularType
,
key
Converter
,
valueConverter
);
key
Mapping
,
valueMapping
);
}
}
/* We know how to translate List<E>, Set<E>, SortedSet<E>,
/* We know how to translate List<E>, Set<E>, SortedSet<E>,
...
@@ -394,8 +433,10 @@ public abstract class OpenConverter {
...
@@ -394,8 +433,10 @@ public abstract class OpenConverter {
subtypes of those because we wouldn't know how to deserialize
subtypes of those because we wouldn't know how to deserialize
them. We don't accept Queue<E> because it is unlikely people
them. We don't accept Queue<E> because it is unlikely people
would use that as a parameter or return type in an MBean. */
would use that as a parameter or return type in an MBean. */
private
static
OpenConverter
private
MXBeanMapping
makeParameterizedConverter
(
ParameterizedType
objType
)
throws
OpenDataException
{
makeParameterizedTypeMapping
(
ParameterizedType
objType
,
MXBeanMappingFactory
factory
)
throws
OpenDataException
{
final
Type
rawType
=
objType
.
getRawType
();
final
Type
rawType
=
objType
.
getRawType
();
...
@@ -406,7 +447,7 @@ public abstract class OpenConverter {
...
@@ -406,7 +447,7 @@ public abstract class OpenConverter {
assert
(
actuals
.
length
==
1
);
assert
(
actuals
.
length
==
1
);
if
(
c
==
SortedSet
.
class
)
if
(
c
==
SortedSet
.
class
)
mustBeComparable
(
c
,
actuals
[
0
]);
mustBeComparable
(
c
,
actuals
[
0
]);
return
makeArrayOrCollection
Converter
(
objType
,
actuals
[
0
]
);
return
makeArrayOrCollection
Mapping
(
objType
,
actuals
[
0
],
factory
);
}
else
{
}
else
{
boolean
sortedMap
=
(
c
==
SortedMap
.
class
);
boolean
sortedMap
=
(
c
==
SortedMap
.
class
);
if
(
c
==
Map
.
class
||
sortedMap
)
{
if
(
c
==
Map
.
class
||
sortedMap
)
{
...
@@ -414,20 +455,21 @@ public abstract class OpenConverter {
...
@@ -414,20 +455,21 @@ public abstract class OpenConverter {
assert
(
actuals
.
length
==
2
);
assert
(
actuals
.
length
==
2
);
if
(
sortedMap
)
if
(
sortedMap
)
mustBeComparable
(
c
,
actuals
[
0
]);
mustBeComparable
(
c
,
actuals
[
0
]);
return
makeTabular
Converter
(
objType
,
sortedMap
,
return
makeTabular
Mapping
(
objType
,
sortedMap
,
actuals
[
0
],
actuals
[
1
]);
actuals
[
0
],
actuals
[
1
]
,
factory
);
}
}
}
}
}
}
throw
new
OpenDataException
(
"Cannot convert type: "
+
objType
);
throw
new
OpenDataException
(
"Cannot convert type: "
+
objType
);
}
}
private
static
OpenConverter
makeMXBeanConverter
(
Type
t
)
private
static
MXBeanMapping
makeMXBeanRefMapping
(
Type
t
)
throws
OpenDataException
{
throws
OpenDataException
{
return
new
MXBean
Converter
(
t
);
return
new
MXBean
RefMapping
(
t
);
}
}
private
static
OpenConverter
makeCompositeConverter
(
Class
c
)
private
MXBeanMapping
makeCompositeMapping
(
Class
c
,
MXBeanMappingFactory
factory
)
throws
OpenDataException
{
throws
OpenDataException
{
// For historical reasons GcInfo implements CompositeData but we
// For historical reasons GcInfo implements CompositeData but we
...
@@ -479,7 +521,7 @@ public abstract class OpenConverter {
...
@@ -479,7 +521,7 @@ public abstract class OpenConverter {
final
Method
getter
=
entry
.
getValue
();
final
Method
getter
=
entry
.
getValue
();
getters
[
i
]
=
getter
;
getters
[
i
]
=
getter
;
final
Type
retType
=
getter
.
getGenericReturnType
();
final
Type
retType
=
getter
.
getGenericReturnType
();
openTypes
[
i
]
=
toConverter
(
retType
).
getOpenType
();
openTypes
[
i
]
=
factory
.
mappingForType
(
retType
,
factory
).
getOpenType
();
i
++;
i
++;
}
}
...
@@ -490,52 +532,55 @@ public abstract class OpenConverter {
...
@@ -490,52 +532,55 @@ public abstract class OpenConverter {
itemNames
,
// field descriptions
itemNames
,
// field descriptions
openTypes
);
openTypes
);
return
new
CompositeConverter
(
c
,
return
new
CompositeMapping
(
c
,
compositeType
,
compositeType
,
itemNames
,
itemNames
,
getters
);
getters
,
factory
);
}
}
/* Converter for classes where the open data is identical to the
/* Converter for classes where the open data is identical to the
original data. This is true for any of the SimpleType types,
original data. This is true for any of the SimpleType types,
and for an any-dimension array of those. It is also true for
and for an any-dimension array of those. It is also true for
primitive types as of JMX 1.3, since an int[]
needs to
primitive types as of JMX 1.3, since an int[]
can be directly represented by an ArrayType, and an int needs no mapping
can be directly represented by an ArrayType, and an int needs no mapping
because reflection takes care of it. */
because reflection takes care of it. */
private
static
final
class
IdentityConverter
extends
OpenConverter
{
private
static
final
class
IdentityMapping
extends
NonNullMXBeanMapping
{
IdentityConverter
(
Type
targetType
,
OpenType
openType
,
IdentityMapping
(
Type
targetType
,
OpenType
openType
)
{
Class
openClass
)
{
super
(
targetType
,
openType
);
super
(
targetType
,
openType
,
openClass
);
}
}
boolean
isIdentity
()
{
boolean
isIdentity
()
{
return
true
;
return
true
;
}
}
final
Object
toNonNullOpenValue
(
MXBeanLookup
lookup
,
Object
value
)
{
@Override
return
value
;
Object
fromNonNullOpenValue
(
Object
openValue
)
throws
InvalidObjectException
{
return
openValue
;
}
}
public
final
Object
fromNonNullOpenValue
(
MXBeanLookup
lookup
,
Object
value
)
{
@Override
return
value
;
Object
toNonNullOpenValue
(
Object
javaValue
)
throws
OpenDataException
{
return
javaValue
;
}
}
}
}
private
static
final
class
Enum
Converter
<
T
extends
Enum
<
T
>>
private
static
final
class
Enum
Mapping
<
T
extends
Enum
<
T
>>
extends
OpenConverter
{
extends
NonNullMXBeanMapping
{
Enum
Converter
(
Class
<
T
>
enumClass
)
{
Enum
Mapping
(
Class
<
T
>
enumClass
)
{
super
(
enumClass
,
SimpleType
.
STRING
,
String
.
class
);
super
(
enumClass
,
SimpleType
.
STRING
);
this
.
enumClass
=
enumClass
;
this
.
enumClass
=
enumClass
;
}
}
final
Object
toNonNullOpenValue
(
MXBeanLookup
lookup
,
Object
value
)
{
@Override
final
Object
toNonNullOpenValue
(
Object
value
)
{
return
((
Enum
)
value
).
name
();
return
((
Enum
)
value
).
name
();
}
}
// return type could be T, but after erasure that would be
@Override
// java.lang.Enum, which doesn't exist on J2SE 1.4
final
T
fromNonNullOpenValue
(
Object
value
)
public
final
Object
fromNonNullOpenValue
(
MXBeanLookup
lookup
,
Object
value
)
throws
InvalidObjectException
{
throws
InvalidObjectException
{
try
{
try
{
return
Enum
.
valueOf
(
enumClass
,
(
String
)
value
);
return
Enum
.
valueOf
(
enumClass
,
(
String
)
value
);
...
@@ -548,69 +593,69 @@ public abstract class OpenConverter {
...
@@ -548,69 +593,69 @@ public abstract class OpenConverter {
private
final
Class
<
T
>
enumClass
;
private
final
Class
<
T
>
enumClass
;
}
}
private
static
final
class
Array
Converter
extends
OpenConverter
{
private
static
final
class
Array
Mapping
extends
NonNullMXBeanMapping
{
Array
Converter
(
Type
targetType
,
Array
Mapping
(
Type
targetType
,
ArrayType
openArrayType
,
Class
openArrayClass
,
ArrayType
openArrayType
,
Class
openArrayClass
,
OpenConverter
elementConverter
)
{
MXBeanMapping
elementMapping
)
{
super
(
targetType
,
openArrayType
,
openArrayClass
);
super
(
targetType
,
openArrayType
);
this
.
element
Converter
=
elementConverter
;
this
.
element
Mapping
=
elementMapping
;
}
}
final
Object
toNonNullOpenValue
(
MXBeanLookup
lookup
,
Object
value
)
@Override
final
Object
toNonNullOpenValue
(
Object
value
)
throws
OpenDataException
{
throws
OpenDataException
{
Object
[]
valueArray
=
(
Object
[])
value
;
Object
[]
valueArray
=
(
Object
[])
value
;
final
int
len
=
valueArray
.
length
;
final
int
len
=
valueArray
.
length
;
final
Object
[]
openArray
=
(
Object
[])
final
Object
[]
openArray
=
(
Object
[])
Array
.
newInstance
(
getOpenClass
().
getComponentType
(),
len
);
Array
.
newInstance
(
getOpenClass
().
getComponentType
(),
len
);
for
(
int
i
=
0
;
i
<
len
;
i
++)
{
for
(
int
i
=
0
;
i
<
len
;
i
++)
openArray
[
i
]
=
openArray
[
i
]
=
elementMapping
.
toOpenValue
(
valueArray
[
i
]);
elementConverter
.
toOpenValue
(
lookup
,
valueArray
[
i
]);
}
return
openArray
;
return
openArray
;
}
}
public
final
Object
fromNonNullOpenValue
(
MXBeanLookup
lookup
,
Object
openValue
)
@Override
final
Object
fromNonNullOpenValue
(
Object
openValue
)
throws
InvalidObjectException
{
throws
InvalidObjectException
{
final
Object
[]
openArray
=
(
Object
[])
openValue
;
final
Object
[]
openArray
=
(
Object
[])
openValue
;
final
Type
targetType
=
getTarget
Type
();
final
Type
javaType
=
getJava
Type
();
final
Object
[]
valueArray
;
final
Object
[]
valueArray
;
final
Type
componentType
;
final
Type
componentType
;
if
(
target
Type
instanceof
GenericArrayType
)
{
if
(
java
Type
instanceof
GenericArrayType
)
{
componentType
=
componentType
=
((
GenericArrayType
)
target
Type
).
getGenericComponentType
();
((
GenericArrayType
)
java
Type
).
getGenericComponentType
();
}
else
if
(
target
Type
instanceof
Class
&&
}
else
if
(
java
Type
instanceof
Class
&&
((
Class
<?>)
target
Type
).
isArray
())
{
((
Class
<?>)
java
Type
).
isArray
())
{
componentType
=
((
Class
<?>)
target
Type
).
getComponentType
();
componentType
=
((
Class
<?>)
java
Type
).
getComponentType
();
}
else
{
}
else
{
throw
new
IllegalArgumentException
(
"Not an array: "
+
throw
new
IllegalArgumentException
(
"Not an array: "
+
target
Type
);
java
Type
);
}
}
valueArray
=
(
Object
[])
Array
.
newInstance
((
Class
<?>)
componentType
,
valueArray
=
(
Object
[])
Array
.
newInstance
((
Class
<?>)
componentType
,
openArray
.
length
);
openArray
.
length
);
for
(
int
i
=
0
;
i
<
openArray
.
length
;
i
++)
{
for
(
int
i
=
0
;
i
<
openArray
.
length
;
i
++)
valueArray
[
i
]
=
valueArray
[
i
]
=
elementMapping
.
fromOpenValue
(
openArray
[
i
]);
elementConverter
.
fromOpenValue
(
lookup
,
openArray
[
i
]);
}
return
valueArray
;
return
valueArray
;
}
}
void
checkReconstructible
()
throws
InvalidObjectException
{
public
void
checkReconstructible
()
throws
InvalidObjectException
{
element
Converter
.
checkReconstructible
();
element
Mapping
.
checkReconstructible
();
}
}
/** OpenConverter for the elements of this array. If this is an
/**
array of arrays, the converter converts the second-level arrays,
* DefaultMXBeanMappingFactory for the elements of this array. If this is an
not the deepest elements. */
* array of arrays, the converter converts the second-level arrays,
private
final
OpenConverter
elementConverter
;
* not the deepest elements.
*/
private
final
MXBeanMapping
elementMapping
;
}
}
private
static
final
class
Collection
Converter
extends
OpenConverter
{
private
static
final
class
Collection
Mapping
extends
NonNullMXBeanMapping
{
Collection
Converter
(
Type
targetType
,
Collection
Mapping
(
Type
targetType
,
ArrayType
openArrayType
,
ArrayType
openArrayType
,
Class
openArrayClass
,
Class
openArrayClass
,
OpenConverter
elementConverter
)
{
MXBeanMapping
elementMapping
)
{
super
(
targetType
,
openArrayType
,
openArrayClass
);
super
(
targetType
,
openArrayType
);
this
.
element
Converter
=
elementConverter
;
this
.
element
Mapping
=
elementMapping
;
/* Determine the concrete class to be used when converting
/* Determine the concrete class to be used when converting
back to this Java type. We convert all Lists to ArrayList
back to this Java type. We convert all Lists to ArrayList
...
@@ -630,7 +675,8 @@ public abstract class OpenConverter {
...
@@ -630,7 +675,8 @@ public abstract class OpenConverter {
}
}
}
}
final
Object
toNonNullOpenValue
(
MXBeanLookup
lookup
,
Object
value
)
@Override
final
Object
toNonNullOpenValue
(
Object
value
)
throws
OpenDataException
{
throws
OpenDataException
{
final
Collection
valueCollection
=
(
Collection
)
value
;
final
Collection
valueCollection
=
(
Collection
)
value
;
if
(
valueCollection
instanceof
SortedSet
)
{
if
(
valueCollection
instanceof
SortedSet
)
{
...
@@ -648,21 +694,22 @@ public abstract class OpenConverter {
...
@@ -648,21 +694,22 @@ public abstract class OpenConverter {
valueCollection
.
size
());
valueCollection
.
size
());
int
i
=
0
;
int
i
=
0
;
for
(
Object
o
:
valueCollection
)
for
(
Object
o
:
valueCollection
)
openArray
[
i
++]
=
element
Converter
.
toOpenValue
(
lookup
,
o
);
openArray
[
i
++]
=
element
Mapping
.
toOpenValue
(
o
);
return
openArray
;
return
openArray
;
}
}
public
final
Object
fromNonNullOpenValue
(
MXBeanLookup
lookup
,
Object
openValue
)
@Override
final
Object
fromNonNullOpenValue
(
Object
openValue
)
throws
InvalidObjectException
{
throws
InvalidObjectException
{
final
Object
[]
openArray
=
(
Object
[])
openValue
;
final
Object
[]
openArray
=
(
Object
[])
openValue
;
final
Collection
<
Object
>
valueCollection
;
final
Collection
<
Object
>
valueCollection
;
try
{
try
{
valueCollection
=
Util
.
cast
(
collectionClass
.
newInstance
());
valueCollection
=
cast
(
collectionClass
.
newInstance
());
}
catch
(
Exception
e
)
{
}
catch
(
Exception
e
)
{
throw
invalidObjectException
(
"Cannot create collection"
,
e
);
throw
invalidObjectException
(
"Cannot create collection"
,
e
);
}
}
for
(
Object
o
:
openArray
)
{
for
(
Object
o
:
openArray
)
{
Object
value
=
element
Converter
.
fromOpenValue
(
lookup
,
o
);
Object
value
=
element
Mapping
.
fromOpenValue
(
o
);
if
(!
valueCollection
.
add
(
value
))
{
if
(!
valueCollection
.
add
(
value
))
{
final
String
msg
=
final
String
msg
=
"Could not add "
+
o
+
" to "
+
"Could not add "
+
o
+
" to "
+
...
@@ -674,34 +721,36 @@ public abstract class OpenConverter {
...
@@ -674,34 +721,36 @@ public abstract class OpenConverter {
return
valueCollection
;
return
valueCollection
;
}
}
void
checkReconstructible
()
throws
InvalidObjectException
{
public
void
checkReconstructible
()
throws
InvalidObjectException
{
element
Converter
.
checkReconstructible
();
element
Mapping
.
checkReconstructible
();
}
}
private
final
Class
<?
extends
Collection
>
collectionClass
;
private
final
Class
<?
extends
Collection
>
collectionClass
;
private
final
OpenConverter
elementConverter
;
private
final
MXBeanMapping
elementMapping
;
}
}
private
static
final
class
MXBean
Converter
extends
OpenConverter
{
private
static
final
class
MXBean
RefMapping
extends
NonNullMXBeanMapping
{
MXBean
Converter
(
Type
intf
)
{
MXBean
RefMapping
(
Type
intf
)
{
super
(
intf
,
SimpleType
.
OBJECTNAME
,
ObjectName
.
class
);
super
(
intf
,
SimpleType
.
OBJECTNAME
);
}
}
final
Object
toNonNullOpenValue
(
MXBeanLookup
lookup
,
Object
value
)
@Override
final
Object
toNonNullOpenValue
(
Object
javaValue
)
throws
OpenDataException
{
throws
OpenDataException
{
lookupNotNull
(
lookup
,
OpenDataException
.
class
);
MXBeanLookup
lookup
=
lookupNotNull
(
OpenDataException
.
class
);
ObjectName
name
=
lookup
.
mxbeanToObjectName
(
v
alue
);
ObjectName
name
=
lookup
.
mxbeanToObjectName
(
javaV
alue
);
if
(
name
==
null
)
if
(
name
==
null
)
throw
new
OpenDataException
(
"No name for object: "
+
v
alue
);
throw
new
OpenDataException
(
"No name for object: "
+
javaV
alue
);
return
name
;
return
name
;
}
}
public
final
Object
fromNonNullOpenValue
(
MXBeanLookup
lookup
,
Object
value
)
@Override
final
Object
fromNonNullOpenValue
(
Object
openValue
)
throws
InvalidObjectException
{
throws
InvalidObjectException
{
lookupNotNull
(
lookup
,
InvalidObjectException
.
class
);
MXBeanLookup
lookup
=
lookupNotNull
(
InvalidObjectException
.
class
);
ObjectName
name
=
(
ObjectName
)
v
alue
;
ObjectName
name
=
(
ObjectName
)
openV
alue
;
Object
mxbean
=
Object
mxbean
=
lookup
.
objectNameToMXBean
(
name
,
(
Class
<?>)
get
Target
Type
());
lookup
.
objectNameToMXBean
(
name
,
(
Class
<?>)
get
Java
Type
());
if
(
mxbean
==
null
)
{
if
(
mxbean
==
null
)
{
final
String
msg
=
final
String
msg
=
"No MXBean for name: "
+
name
;
"No MXBean for name: "
+
name
;
...
@@ -710,9 +759,10 @@ public abstract class OpenConverter {
...
@@ -710,9 +759,10 @@ public abstract class OpenConverter {
return
mxbean
;
return
mxbean
;
}
}
private
<
T
extends
Exception
>
void
private
<
T
extends
Exception
>
MXBeanLookup
lookupNotNull
(
MXBeanLookup
lookup
,
Class
<
T
>
excClass
)
lookupNotNull
(
Class
<
T
>
excClass
)
throws
T
{
throws
T
{
MXBeanLookup
lookup
=
MXBeanLookup
.
getLookup
();
if
(
lookup
==
null
)
{
if
(
lookup
==
null
)
{
final
String
msg
=
final
String
msg
=
"Cannot convert MXBean interface in this context"
;
"Cannot convert MXBean interface in this context"
;
...
@@ -725,24 +775,25 @@ public abstract class OpenConverter {
...
@@ -725,24 +775,25 @@ public abstract class OpenConverter {
}
}
throw
exc
;
throw
exc
;
}
}
return
lookup
;
}
}
}
}
private
static
final
class
Tabular
Converter
extends
OpenConverter
{
private
static
final
class
Tabular
Mapping
extends
NonNullMXBeanMapping
{
Tabular
Converter
(
Type
targetType
,
Tabular
Mapping
(
Type
targetType
,
boolean
sortedMap
,
boolean
sortedMap
,
TabularType
tabularType
,
TabularType
tabularType
,
OpenConverter
keyConverter
,
MXBeanMapping
keyConverter
,
OpenConverter
valueConverter
)
{
MXBeanMapping
valueConverter
)
{
super
(
targetType
,
tabularType
,
TabularData
.
class
);
super
(
targetType
,
tabularType
);
this
.
sortedMap
=
sortedMap
;
this
.
sortedMap
=
sortedMap
;
this
.
key
Converter
=
keyConverter
;
this
.
key
Mapping
=
keyConverter
;
this
.
value
Converter
=
valueConverter
;
this
.
value
Mapping
=
valueConverter
;
}
}
final
Object
toNonNullOpenValue
(
MXBeanLookup
lookup
,
Object
value
)
@Override
throws
OpenDataException
{
final
Object
toNonNullOpenValue
(
Object
value
)
throws
OpenDataException
{
final
Map
<
Object
,
Object
>
valueMap
=
Util
.
cast
(
value
);
final
Map
<
Object
,
Object
>
valueMap
=
cast
(
value
);
if
(
valueMap
instanceof
SortedMap
)
{
if
(
valueMap
instanceof
SortedMap
)
{
Comparator
comparator
=
((
SortedMap
)
valueMap
).
comparator
();
Comparator
comparator
=
((
SortedMap
)
valueMap
).
comparator
();
if
(
comparator
!=
null
)
{
if
(
comparator
!=
null
)
{
...
@@ -756,10 +807,8 @@ public abstract class OpenConverter {
...
@@ -756,10 +807,8 @@ public abstract class OpenConverter {
final
TabularData
table
=
new
TabularDataSupport
(
tabularType
);
final
TabularData
table
=
new
TabularDataSupport
(
tabularType
);
final
CompositeType
rowType
=
tabularType
.
getRowType
();
final
CompositeType
rowType
=
tabularType
.
getRowType
();
for
(
Map
.
Entry
entry
:
valueMap
.
entrySet
())
{
for
(
Map
.
Entry
entry
:
valueMap
.
entrySet
())
{
final
Object
openKey
=
final
Object
openKey
=
keyMapping
.
toOpenValue
(
entry
.
getKey
());
keyConverter
.
toOpenValue
(
lookup
,
entry
.
getKey
());
final
Object
openValue
=
valueMapping
.
toOpenValue
(
entry
.
getValue
());
final
Object
openValue
=
valueConverter
.
toOpenValue
(
lookup
,
entry
.
getValue
());
final
CompositeData
row
;
final
CompositeData
row
;
row
=
row
=
new
CompositeDataSupport
(
rowType
,
keyValueArray
,
new
CompositeDataSupport
(
rowType
,
keyValueArray
,
...
@@ -770,17 +819,18 @@ public abstract class OpenConverter {
...
@@ -770,17 +819,18 @@ public abstract class OpenConverter {
return
table
;
return
table
;
}
}
public
final
Object
fromNonNullOpenValue
(
MXBeanLookup
lookup
,
Object
openValue
)
@Override
final
Object
fromNonNullOpenValue
(
Object
openValue
)
throws
InvalidObjectException
{
throws
InvalidObjectException
{
final
TabularData
table
=
(
TabularData
)
openValue
;
final
TabularData
table
=
(
TabularData
)
openValue
;
final
Collection
<
CompositeData
>
rows
=
Util
.
cast
(
table
.
values
());
final
Collection
<
CompositeData
>
rows
=
cast
(
table
.
values
());
final
Map
<
Object
,
Object
>
valueMap
=
final
Map
<
Object
,
Object
>
valueMap
=
sortedMap
?
newSortedMap
()
:
newMap
();
sortedMap
?
newSortedMap
()
:
newMap
();
for
(
CompositeData
row
:
rows
)
{
for
(
CompositeData
row
:
rows
)
{
final
Object
key
=
final
Object
key
=
key
Converter
.
fromOpenValue
(
lookup
,
row
.
get
(
"key"
));
key
Mapping
.
fromOpenValue
(
row
.
get
(
"key"
));
final
Object
value
=
final
Object
value
=
value
Converter
.
fromOpenValue
(
lookup
,
row
.
get
(
"value"
));
value
Mapping
.
fromOpenValue
(
row
.
get
(
"value"
));
if
(
valueMap
.
put
(
key
,
value
)
!=
null
)
{
if
(
valueMap
.
put
(
key
,
value
)
!=
null
)
{
final
String
msg
=
final
String
msg
=
"Duplicate entry in TabularData: key="
+
key
;
"Duplicate entry in TabularData: key="
+
key
;
...
@@ -790,35 +840,38 @@ public abstract class OpenConverter {
...
@@ -790,35 +840,38 @@ public abstract class OpenConverter {
return
valueMap
;
return
valueMap
;
}
}
void
checkReconstructible
()
throws
InvalidObjectException
{
@Override
keyConverter
.
checkReconstructible
();
public
void
checkReconstructible
()
throws
InvalidObjectException
{
valueConverter
.
checkReconstructible
();
keyMapping
.
checkReconstructible
();
valueMapping
.
checkReconstructible
();
}
}
private
final
boolean
sortedMap
;
private
final
boolean
sortedMap
;
private
final
OpenConverter
keyConverter
;
private
final
MXBeanMapping
keyMapping
;
private
final
OpenConverter
valueConverter
;
private
final
MXBeanMapping
valueMapping
;
}
}
private
static
final
class
CompositeConverter
extends
OpenConverter
{
private
final
class
CompositeMapping
extends
NonNullMXBeanMapping
{
CompositeConverter
(
Class
targetClass
,
CompositeMapping
(
Class
targetClass
,
CompositeType
compositeType
,
CompositeType
compositeType
,
String
[]
itemNames
,
String
[]
itemNames
,
Method
[]
getters
)
throws
OpenDataException
{
Method
[]
getters
,
super
(
targetClass
,
compositeType
,
CompositeData
.
class
);
MXBeanMappingFactory
factory
)
throws
OpenDataException
{
super
(
targetClass
,
compositeType
);
assert
(
itemNames
.
length
==
getters
.
length
);
assert
(
itemNames
.
length
==
getters
.
length
);
this
.
itemNames
=
itemNames
;
this
.
itemNames
=
itemNames
;
this
.
getters
=
getters
;
this
.
getters
=
getters
;
this
.
getter
Converters
=
new
OpenConverter
[
getters
.
length
];
this
.
getter
Mappings
=
new
MXBeanMapping
[
getters
.
length
];
for
(
int
i
=
0
;
i
<
getters
.
length
;
i
++)
{
for
(
int
i
=
0
;
i
<
getters
.
length
;
i
++)
{
Type
retType
=
getters
[
i
].
getGenericReturnType
();
Type
retType
=
getters
[
i
].
getGenericReturnType
();
getter
Converters
[
i
]
=
OpenConverter
.
toConverter
(
retType
);
getter
Mappings
[
i
]
=
factory
.
mappingForType
(
retType
,
factory
);
}
}
}
}
final
Object
toNonNullOpenValue
(
MXBeanLookup
lookup
,
Object
value
)
@Override
final
Object
toNonNullOpenValue
(
Object
value
)
throws
OpenDataException
{
throws
OpenDataException
{
CompositeType
ct
=
(
CompositeType
)
getOpenType
();
CompositeType
ct
=
(
CompositeType
)
getOpenType
();
if
(
value
instanceof
CompositeDataView
)
if
(
value
instanceof
CompositeDataView
)
...
@@ -830,7 +883,7 @@ public abstract class OpenConverter {
...
@@ -830,7 +883,7 @@ public abstract class OpenConverter {
for
(
int
i
=
0
;
i
<
getters
.
length
;
i
++)
{
for
(
int
i
=
0
;
i
<
getters
.
length
;
i
++)
{
try
{
try
{
Object
got
=
getters
[
i
].
invoke
(
value
,
(
Object
[])
null
);
Object
got
=
getters
[
i
].
invoke
(
value
,
(
Object
[])
null
);
values
[
i
]
=
getter
Converters
[
i
].
toOpenValue
(
lookup
,
got
);
values
[
i
]
=
getter
Mappings
[
i
].
toOpenValue
(
got
);
}
catch
(
Exception
e
)
{
}
catch
(
Exception
e
)
{
throw
openDataException
(
"Error calling getter for "
+
throw
openDataException
(
"Error calling getter for "
+
itemNames
[
i
]
+
": "
+
e
,
e
);
itemNames
[
i
]
+
": "
+
e
,
e
);
...
@@ -848,7 +901,7 @@ public abstract class OpenConverter {
...
@@ -848,7 +901,7 @@ public abstract class OpenConverter {
if
(
compositeBuilder
!=
null
)
if
(
compositeBuilder
!=
null
)
return
;
return
;
Class
targetClass
=
(
Class
<?>)
get
Target
Type
();
Class
targetClass
=
(
Class
<?>)
get
Java
Type
();
/* In this 2D array, each subarray is a set of builders where
/* In this 2D array, each subarray is a set of builders where
there is no point in consulting the ones after the first if
there is no point in consulting the ones after the first if
the first refuses. */
the first refuses. */
...
@@ -861,7 +914,7 @@ public abstract class OpenConverter {
...
@@ -861,7 +914,7 @@ public abstract class OpenConverter {
},
},
{
{
new
CompositeBuilderCheckGetters
(
targetClass
,
itemNames
,
new
CompositeBuilderCheckGetters
(
targetClass
,
itemNames
,
getter
Converter
s
),
getter
Mapping
s
),
new
CompositeBuilderViaSetters
(
targetClass
,
itemNames
),
new
CompositeBuilderViaSetters
(
targetClass
,
itemNames
),
new
CompositeBuilderViaProxy
(
targetClass
,
itemNames
),
new
CompositeBuilderViaProxy
(
targetClass
,
itemNames
),
},
},
...
@@ -898,22 +951,23 @@ public abstract class OpenConverter {
...
@@ -898,22 +951,23 @@ public abstract class OpenConverter {
compositeBuilder
=
foundBuilder
;
compositeBuilder
=
foundBuilder
;
}
}
void
checkReconstructible
()
throws
InvalidObjectException
{
@Override
public
void
checkReconstructible
()
throws
InvalidObjectException
{
makeCompositeBuilder
();
makeCompositeBuilder
();
}
}
public
final
Object
fromNonNullOpenValue
(
MXBeanLookup
lookup
,
Object
value
)
@Override
final
Object
fromNonNullOpenValue
(
Object
value
)
throws
InvalidObjectException
{
throws
InvalidObjectException
{
makeCompositeBuilder
();
makeCompositeBuilder
();
return
compositeBuilder
.
fromCompositeData
(
lookup
,
return
compositeBuilder
.
fromCompositeData
((
CompositeData
)
value
,
(
CompositeData
)
value
,
itemNames
,
itemNames
,
getter
Converter
s
);
getter
Mapping
s
);
}
}
private
final
String
[]
itemNames
;
private
final
String
[]
itemNames
;
private
final
Method
[]
getters
;
private
final
Method
[]
getters
;
private
final
OpenConverter
[]
getterConverter
s
;
private
final
MXBeanMapping
[]
getterMapping
s
;
private
CompositeBuilder
compositeBuilder
;
private
CompositeBuilder
compositeBuilder
;
}
}
...
@@ -940,9 +994,9 @@ public abstract class OpenConverter {
...
@@ -940,9 +994,9 @@ public abstract class OpenConverter {
abstract
String
applicable
(
Method
[]
getters
)
abstract
String
applicable
(
Method
[]
getters
)
throws
InvalidObjectException
;
throws
InvalidObjectException
;
abstract
Object
fromCompositeData
(
MXBeanLookup
lookup
,
CompositeData
cd
,
abstract
Object
fromCompositeData
(
CompositeData
cd
,
String
[]
itemNames
,
String
[]
itemNames
,
OpenConverter
[]
converters
)
MXBeanMapping
[]
converters
)
throws
InvalidObjectException
;
throws
InvalidObjectException
;
private
final
Class
<?>
targetClass
;
private
final
Class
<?>
targetClass
;
...
@@ -991,9 +1045,9 @@ public abstract class OpenConverter {
...
@@ -991,9 +1045,9 @@ public abstract class OpenConverter {
}
}
}
}
final
Object
fromCompositeData
(
MXBeanLookup
lookup
,
CompositeData
cd
,
final
Object
fromCompositeData
(
CompositeData
cd
,
String
[]
itemNames
,
String
[]
itemNames
,
OpenConverter
[]
converters
)
MXBeanMapping
[]
converters
)
throws
InvalidObjectException
{
throws
InvalidObjectException
{
try
{
try
{
return
fromMethod
.
invoke
(
null
,
cd
);
return
fromMethod
.
invoke
(
null
,
cd
);
...
@@ -1018,7 +1072,7 @@ public abstract class OpenConverter {
...
@@ -1018,7 +1072,7 @@ public abstract class OpenConverter {
an empty string and the other builders will be tried. */
an empty string and the other builders will be tried. */
private
static
class
CompositeBuilderCheckGetters
extends
CompositeBuilder
{
private
static
class
CompositeBuilderCheckGetters
extends
CompositeBuilder
{
CompositeBuilderCheckGetters
(
Class
targetClass
,
String
[]
itemNames
,
CompositeBuilderCheckGetters
(
Class
targetClass
,
String
[]
itemNames
,
OpenConverter
[]
getterConverters
)
{
MXBeanMapping
[]
getterConverters
)
{
super
(
targetClass
,
itemNames
);
super
(
targetClass
,
itemNames
);
this
.
getterConverters
=
getterConverters
;
this
.
getterConverters
=
getterConverters
;
}
}
...
@@ -1035,25 +1089,25 @@ public abstract class OpenConverter {
...
@@ -1035,25 +1089,25 @@ public abstract class OpenConverter {
return
""
;
return
""
;
}
}
final
Object
fromCompositeData
(
MXBeanLookup
lookup
,
CompositeData
cd
,
final
Object
fromCompositeData
(
CompositeData
cd
,
String
[]
itemNames
,
String
[]
itemNames
,
OpenConverter
[]
converters
)
{
MXBeanMapping
[]
converters
)
{
throw
new
Error
();
throw
new
Error
();
}
}
private
final
OpenConverter
[]
getterConverters
;
private
final
MXBeanMapping
[]
getterConverters
;
}
}
/** Builder for when the target class has a setter for every getter. */
/** Builder for when the target class has a setter for every getter. */
private
static
class
CompositeBuilderViaSetters
extends
CompositeBuilder
{
private
static
class
CompositeBuilderViaSetters
extends
CompositeBuilder
{
CompositeBuilderViaSetters
(
Class
targetClass
,
String
[]
itemNames
)
{
CompositeBuilderViaSetters
(
Class
<?>
targetClass
,
String
[]
itemNames
)
{
super
(
targetClass
,
itemNames
);
super
(
targetClass
,
itemNames
);
}
}
String
applicable
(
Method
[]
getters
)
{
String
applicable
(
Method
[]
getters
)
{
try
{
try
{
Constructor
<?>
c
=
getTargetClass
().
getConstructor
(
(
Class
[])
null
);
Constructor
<?>
c
=
getTargetClass
().
getConstructor
();
}
catch
(
Exception
e
)
{
}
catch
(
Exception
e
)
{
return
"does not have a public no-arg constructor"
;
return
"does not have a public no-arg constructor"
;
}
}
...
@@ -1079,9 +1133,9 @@ public abstract class OpenConverter {
...
@@ -1079,9 +1133,9 @@ public abstract class OpenConverter {
return
null
;
return
null
;
}
}
Object
fromCompositeData
(
MXBeanLookup
lookup
,
CompositeData
cd
,
Object
fromCompositeData
(
CompositeData
cd
,
String
[]
itemNames
,
String
[]
itemNames
,
OpenConverter
[]
converters
)
MXBeanMapping
[]
converters
)
throws
InvalidObjectException
{
throws
InvalidObjectException
{
Object
o
;
Object
o
;
try
{
try
{
...
@@ -1090,7 +1144,7 @@ public abstract class OpenConverter {
...
@@ -1090,7 +1144,7 @@ public abstract class OpenConverter {
if
(
cd
.
containsKey
(
itemNames
[
i
]))
{
if
(
cd
.
containsKey
(
itemNames
[
i
]))
{
Object
openItem
=
cd
.
get
(
itemNames
[
i
]);
Object
openItem
=
cd
.
get
(
itemNames
[
i
]);
Object
javaItem
=
Object
javaItem
=
converters
[
i
].
fromOpenValue
(
lookup
,
openItem
);
converters
[
i
].
fromOpenValue
(
openItem
);
setters
[
i
].
invoke
(
o
,
javaItem
);
setters
[
i
].
invoke
(
o
,
javaItem
);
}
}
}
}
...
@@ -1118,10 +1172,10 @@ public abstract class OpenConverter {
...
@@ -1118,10 +1172,10 @@ public abstract class OpenConverter {
final
Class
<
ConstructorProperties
>
propertyNamesClass
=
ConstructorProperties
.
class
;
final
Class
<
ConstructorProperties
>
propertyNamesClass
=
ConstructorProperties
.
class
;
Class
targetClass
=
getTargetClass
();
Class
targetClass
=
getTargetClass
();
Constructor
<?>
[]
constrs
=
targetClass
.
getConstructors
();
Constructor
[]
constrs
=
targetClass
.
getConstructors
();
// Applicable if and only if there are any annotated constructors
// Applicable if and only if there are any annotated constructors
List
<
Constructor
<?>
>
annotatedConstrList
=
newList
();
List
<
Constructor
>
annotatedConstrList
=
newList
();
for
(
Constructor
<?>
constr
:
constrs
)
{
for
(
Constructor
<?>
constr
:
constrs
)
{
if
(
Modifier
.
isPublic
(
constr
.
getModifiers
())
if
(
Modifier
.
isPublic
(
constr
.
getModifiers
())
&&
constr
.
getAnnotation
(
propertyNamesClass
)
!=
null
)
&&
constr
.
getAnnotation
(
propertyNamesClass
)
!=
null
)
...
@@ -1152,7 +1206,7 @@ public abstract class OpenConverter {
...
@@ -1152,7 +1206,7 @@ public abstract class OpenConverter {
// Also remember the set of properties in that constructor
// Also remember the set of properties in that constructor
// so we can test unambiguity.
// so we can test unambiguity.
Set
<
BitSet
>
getterIndexSets
=
newSet
();
Set
<
BitSet
>
getterIndexSets
=
newSet
();
for
(
Constructor
<?>
constr
:
annotatedConstrList
)
{
for
(
Constructor
constr
:
annotatedConstrList
)
{
String
[]
propertyNames
=
String
[]
propertyNames
=
constr
.
getAnnotation
(
propertyNamesClass
).
value
();
constr
.
getAnnotation
(
propertyNamesClass
).
value
();
...
@@ -1251,9 +1305,9 @@ public abstract class OpenConverter {
...
@@ -1251,9 +1305,9 @@ public abstract class OpenConverter {
return
null
;
// success!
return
null
;
// success!
}
}
Object
fromCompositeData
(
MXBeanLookup
lookup
,
CompositeData
cd
,
final
Object
fromCompositeData
(
CompositeData
cd
,
String
[]
itemNames
,
String
[]
itemNames
,
OpenConverter
[]
converter
s
)
MXBeanMapping
[]
mapping
s
)
throws
InvalidObjectException
{
throws
InvalidObjectException
{
// The CompositeData might come from an earlier version where
// The CompositeData might come from an earlier version where
// not all the items were present. We look for a constructor
// not all the items were present. We look for a constructor
...
@@ -1287,7 +1341,7 @@ public abstract class OpenConverter {
...
@@ -1287,7 +1341,7 @@ public abstract class OpenConverter {
if
(!
max
.
presentParams
.
get
(
i
))
if
(!
max
.
presentParams
.
get
(
i
))
continue
;
continue
;
Object
openItem
=
cd
.
get
(
itemNames
[
i
]);
Object
openItem
=
cd
.
get
(
itemNames
[
i
]);
Object
javaItem
=
converters
[
i
].
fromOpenValue
(
lookup
,
openItem
);
Object
javaItem
=
mappings
[
i
].
fromOpenValue
(
openItem
);
int
index
=
max
.
paramIndexes
[
i
];
int
index
=
max
.
paramIndexes
[
i
];
if
(
index
>=
0
)
if
(
index
>=
0
)
params
[
index
]
=
javaItem
;
params
[
index
]
=
javaItem
;
...
@@ -1309,10 +1363,10 @@ public abstract class OpenConverter {
...
@@ -1309,10 +1363,10 @@ public abstract class OpenConverter {
}
}
private
static
class
Constr
{
private
static
class
Constr
{
final
Constructor
<?>
constructor
;
final
Constructor
constructor
;
final
int
[]
paramIndexes
;
final
int
[]
paramIndexes
;
final
BitSet
presentParams
;
final
BitSet
presentParams
;
Constr
(
Constructor
<?>
constructor
,
int
[]
paramIndexes
,
Constr
(
Constructor
constructor
,
int
[]
paramIndexes
,
BitSet
presentParams
)
{
BitSet
presentParams
)
{
this
.
constructor
=
constructor
;
this
.
constructor
=
constructor
;
this
.
paramIndexes
=
paramIndexes
;
this
.
paramIndexes
=
paramIndexes
;
...
@@ -1365,9 +1419,9 @@ public abstract class OpenConverter {
...
@@ -1365,9 +1419,9 @@ public abstract class OpenConverter {
return
null
;
// success!
return
null
;
// success!
}
}
final
Object
fromCompositeData
(
MXBeanLookup
lookup
,
CompositeData
cd
,
final
Object
fromCompositeData
(
CompositeData
cd
,
String
[]
itemNames
,
String
[]
itemNames
,
OpenConverter
[]
converters
)
{
MXBeanMapping
[]
converters
)
{
final
Class
targetClass
=
getTargetClass
();
final
Class
targetClass
=
getTargetClass
();
return
return
Proxy
.
newProxyInstance
(
targetClass
.
getClassLoader
(),
Proxy
.
newProxyInstance
(
targetClass
.
getClassLoader
(),
...
...
src/share/classes/com/sun/jmx/mbeanserver/Introspector.java
浏览文件 @
3e149c7f
...
@@ -42,7 +42,6 @@ import javax.management.ImmutableDescriptor;
...
@@ -42,7 +42,6 @@ import javax.management.ImmutableDescriptor;
import
javax.management.MBeanInfo
;
import
javax.management.MBeanInfo
;
import
javax.management.NotCompliantMBeanException
;
import
javax.management.NotCompliantMBeanException
;
import
com.sun.jmx.mbeanserver.Util
;
import
com.sun.jmx.remote.util.EnvHelp
;
import
com.sun.jmx.remote.util.EnvHelp
;
import
java.beans.BeanInfo
;
import
java.beans.BeanInfo
;
import
java.beans.PropertyDescriptor
;
import
java.beans.PropertyDescriptor
;
...
@@ -50,6 +49,7 @@ import java.lang.reflect.Array;
...
@@ -50,6 +49,7 @@ import java.lang.reflect.Array;
import
java.lang.reflect.InvocationTargetException
;
import
java.lang.reflect.InvocationTargetException
;
import
javax.management.AttributeNotFoundException
;
import
javax.management.AttributeNotFoundException
;
import
javax.management.openmbean.CompositeData
;
import
javax.management.openmbean.CompositeData
;
import
javax.management.openmbean.MXBeanMappingFactory
;
/**
/**
* This class contains the methods for performing all the tests needed to verify
* This class contains the methods for performing all the tests needed to verify
...
@@ -165,30 +165,34 @@ public class Introspector {
...
@@ -165,30 +165,34 @@ public class Introspector {
throw
new
NotCompliantMBeanException
(
msg
);
throw
new
NotCompliantMBeanException
(
msg
);
}
}
public
static
DynamicMBean
makeDynamicMBean
(
Object
mbean
)
public
static
<
T
>
DynamicMBean
makeDynamicMBean
(
T
mbean
)
throws
NotCompliantMBeanException
{
throws
NotCompliantMBeanException
{
if
(
mbean
==
null
)
throw
new
NotCompliantMBeanException
(
"Null MBean object"
);
if
(
mbean
instanceof
DynamicMBean
)
if
(
mbean
instanceof
DynamicMBean
)
return
(
DynamicMBean
)
mbean
;
return
(
DynamicMBean
)
mbean
;
final
Class
mbeanClass
=
mbean
.
getClass
();
final
Class
mbeanClass
=
mbean
.
getClass
();
Class
<?>
c
=
null
;
Class
<?
super
T
>
c
=
null
;
try
{
try
{
c
=
getStandardMBeanInterface
(
mbeanClass
);
c
=
Util
.
cast
(
getStandardMBeanInterface
(
mbeanClass
)
);
}
catch
(
NotCompliantMBeanException
e
)
{
}
catch
(
NotCompliantMBeanException
e
)
{
// Ignore exception - we need to check whether
// Ignore exception - we need to check whether
// mbean is an MXBean first.
// mbean is an MXBean first.
}
}
if
(
c
!=
null
)
if
(
c
!=
null
)
return
new
StandardMBeanSupport
(
mbean
,
Util
.<
Class
<
Object
>>
cast
(
c
)
);
return
new
StandardMBeanSupport
(
mbean
,
c
);
try
{
try
{
c
=
getMXBeanInterface
(
mbeanClass
);
c
=
Util
.
cast
(
getMXBeanInterface
(
mbeanClass
)
);
}
catch
(
NotCompliantMBeanException
e
)
{
}
catch
(
NotCompliantMBeanException
e
)
{
// Ignore exception - we cannot decide whether mbean was supposed
// Ignore exception - we cannot decide whether mbean was supposed
// to be an MBean or an MXBean. We will call checkCompliance()
// to be an MBean or an MXBean. We will call checkCompliance()
// to generate the appropriate exception.
// to generate the appropriate exception.
}
}
if
(
c
!=
null
)
if
(
c
!=
null
)
{
return
new
MXBeanSupport
(
mbean
,
Util
.<
Class
<
Object
>>
cast
(
c
));
MXBeanMappingFactory
factory
=
MXBeanMappingFactory
.
forInterface
(
c
);
return
new
MXBeanSupport
(
mbean
,
c
,
factory
);
}
checkCompliance
(
mbeanClass
);
checkCompliance
(
mbeanClass
);
throw
new
NotCompliantMBeanException
(
"Not compliant"
);
// not reached
throw
new
NotCompliantMBeanException
(
"Not compliant"
);
// not reached
}
}
...
@@ -217,9 +221,10 @@ public class Introspector {
...
@@ -217,9 +221,10 @@ public class Introspector {
return
testCompliance
(
baseClass
,
null
);
return
testCompliance
(
baseClass
,
null
);
}
}
public
static
void
testComplianceMXBeanInterface
(
Class
interfaceClass
)
public
static
void
testComplianceMXBeanInterface
(
Class
interfaceClass
,
MXBeanMappingFactory
factory
)
throws
NotCompliantMBeanException
{
throws
NotCompliantMBeanException
{
MXBeanIntrospector
.
getInstance
().
getAnalyzer
(
interfaceClass
);
MXBeanIntrospector
.
getInstance
(
factory
).
getAnalyzer
(
interfaceClass
);
}
}
/**
/**
...
@@ -325,6 +330,15 @@ public class Introspector {
...
@@ -325,6 +330,15 @@ public class Introspector {
}
}
}
}
public
static
<
T
>
Class
<?
super
T
>
getStandardOrMXBeanInterface
(
Class
<
T
>
baseClass
,
boolean
mxbean
)
throws
NotCompliantMBeanException
{
if
(
mxbean
)
return
getMXBeanInterface
(
baseClass
);
else
return
getStandardMBeanInterface
(
baseClass
);
}
/*
/*
* ------------------------------------------
* ------------------------------------------
* PRIVATE METHODS
* PRIVATE METHODS
...
...
src/share/classes/com/sun/jmx/mbeanserver/MBeanAnalyzer.java
浏览文件 @
3e149c7f
...
@@ -29,13 +29,10 @@ import static com.sun.jmx.mbeanserver.Util.*;
...
@@ -29,13 +29,10 @@ import static com.sun.jmx.mbeanserver.Util.*;
import
java.lang.reflect.Method
;
import
java.lang.reflect.Method
;
import
java.util.Arrays
;
import
java.util.Arrays
;
import
java.util.Collection
;
import
java.util.Comparator
;
import
java.util.Comparator
;
import
java.util.HashSet
;
import
java.util.List
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Map
;
import
java.util.Set
;
import
java.util.Set
;
import
javax.management.NotCompliantMBeanException
;
import
javax.management.NotCompliantMBeanException
;
/**
/**
...
@@ -54,15 +51,15 @@ import javax.management.NotCompliantMBeanException;
...
@@ -54,15 +51,15 @@ import javax.management.NotCompliantMBeanException;
*/
*/
class
MBeanAnalyzer
<
M
>
{
class
MBeanAnalyzer
<
M
>
{
static
interface
MBeanVisitor
<
M
>
{
static
interface
MBeanVisitor
<
M
,
X
extends
Exception
>
{
public
void
visitAttribute
(
String
attributeName
,
public
void
visitAttribute
(
String
attributeName
,
M
getter
,
M
getter
,
M
setter
);
M
setter
)
throws
X
;
public
void
visitOperation
(
String
operationName
,
public
void
visitOperation
(
String
operationName
,
M
operation
);
M
operation
)
throws
X
;
}
}
void
visit
(
MBeanVisitor
<
M
>
visitor
)
{
<
X
extends
Exception
>
void
visit
(
MBeanVisitor
<
M
,
X
>
visitor
)
throws
X
{
// visit attributes
// visit attributes
for
(
Map
.
Entry
<
String
,
AttrMethods
<
M
>>
entry
:
attrMap
.
entrySet
())
{
for
(
Map
.
Entry
<
String
,
AttrMethods
<
M
>>
entry
:
attrMap
.
entrySet
())
{
String
name
=
entry
.
getKey
();
String
name
=
entry
.
getKey
();
...
@@ -98,21 +95,21 @@ class MBeanAnalyzer<M> {
...
@@ -98,21 +95,21 @@ class MBeanAnalyzer<M> {
// cached PerInterface object for an MBean interface means that
// cached PerInterface object for an MBean interface means that
// an analyzer will not be recreated for a second MBean using the
// an analyzer will not be recreated for a second MBean using the
// same interface.
// same interface.
static
<
M
>
MBeanAnalyzer
<
M
>
analyzer
(
Class
<?>
mbean
Interfac
e
,
static
<
M
>
MBeanAnalyzer
<
M
>
analyzer
(
Class
<?>
mbean
Typ
e
,
MBeanIntrospector
<
M
>
introspector
)
MBeanIntrospector
<
M
>
introspector
)
throws
NotCompliantMBeanException
{
throws
NotCompliantMBeanException
{
return
new
MBeanAnalyzer
<
M
>(
mbean
Interfac
e
,
introspector
);
return
new
MBeanAnalyzer
<
M
>(
mbean
Typ
e
,
introspector
);
}
}
private
MBeanAnalyzer
(
Class
<?>
mbean
Interfac
e
,
private
MBeanAnalyzer
(
Class
<?>
mbean
Typ
e
,
MBeanIntrospector
<
M
>
introspector
)
MBeanIntrospector
<
M
>
introspector
)
throws
NotCompliantMBeanException
{
throws
NotCompliantMBeanException
{
introspector
.
checkCompliance
(
mbean
Interfac
e
);
introspector
.
checkCompliance
(
mbean
Typ
e
);
try
{
try
{
initMaps
(
mbean
Interfac
e
,
introspector
);
initMaps
(
mbean
Typ
e
,
introspector
);
}
catch
(
Exception
x
)
{
}
catch
(
Exception
x
)
{
throw
Introspector
.
throwException
(
mbean
Interfac
e
,
x
);
throw
Introspector
.
throwException
(
mbean
Typ
e
,
x
);
}
}
}
}
...
@@ -126,7 +123,8 @@ class MBeanAnalyzer<M> {
...
@@ -126,7 +123,8 @@ class MBeanAnalyzer<M> {
/* Run through the methods to detect inconsistencies and to enable
/* Run through the methods to detect inconsistencies and to enable
us to give getter and setter together to visitAttribute. */
us to give getter and setter together to visitAttribute. */
for
(
Method
m
:
methods
)
{
for
(
Method
m
:
methods
)
{
String
name
=
m
.
getName
();
final
String
name
=
m
.
getName
();
final
int
nParams
=
m
.
getParameterTypes
().
length
;
final
M
cm
=
introspector
.
mFrom
(
m
);
final
M
cm
=
introspector
.
mFrom
(
m
);
...
@@ -137,7 +135,7 @@ class MBeanAnalyzer<M> {
...
@@ -137,7 +135,7 @@ class MBeanAnalyzer<M> {
&&
m
.
getReturnType
()
==
boolean
.
class
)
&&
m
.
getReturnType
()
==
boolean
.
class
)
attrName
=
name
.
substring
(
2
);
attrName
=
name
.
substring
(
2
);
if
(
attrName
.
length
()
!=
0
&&
m
.
getParameterTypes
().
length
==
0
if
(
attrName
.
length
()
!=
0
&&
nParams
==
0
&&
m
.
getReturnType
()
!=
void
.
class
)
{
&&
m
.
getReturnType
()
!=
void
.
class
)
{
// It's a getter
// It's a getter
// Check we don't have both isX and getX
// Check we don't have both isX and getX
...
@@ -154,7 +152,7 @@ class MBeanAnalyzer<M> {
...
@@ -154,7 +152,7 @@ class MBeanAnalyzer<M> {
am
.
getter
=
cm
;
am
.
getter
=
cm
;
attrMap
.
put
(
attrName
,
am
);
attrMap
.
put
(
attrName
,
am
);
}
else
if
(
name
.
startsWith
(
"set"
)
&&
name
.
length
()
>
3
}
else
if
(
name
.
startsWith
(
"set"
)
&&
name
.
length
()
>
3
&&
m
.
getParameterTypes
().
length
==
1
&&
&&
nParams
==
1
&&
m
.
getReturnType
()
==
void
.
class
)
{
m
.
getReturnType
()
==
void
.
class
)
{
// It's a setter
// It's a setter
attrName
=
name
.
substring
(
3
);
attrName
=
name
.
substring
(
3
);
...
@@ -228,7 +226,11 @@ class MBeanAnalyzer<M> {
...
@@ -228,7 +226,11 @@ class MBeanAnalyzer<M> {
but only the overriding one is of interest. We return the methods
but only the overriding one is of interest. We return the methods
in the same order they arrived in. This isn't required by the spec
in the same order they arrived in. This isn't required by the spec
but existing code may depend on it and users may be used to seeing
but existing code may depend on it and users may be used to seeing
operations or attributes appear in a particular order. */
operations or attributes appear in a particular order.
Because of the way this method works, if the same Method appears
more than once in the given List then it will be completely deleted!
So don't do that. */
static
List
<
Method
>
static
List
<
Method
>
eliminateCovariantMethods
(
List
<
Method
>
startMethods
)
{
eliminateCovariantMethods
(
List
<
Method
>
startMethods
)
{
// We are assuming that you never have very many methods with the
// We are assuming that you never have very many methods with the
...
@@ -243,7 +245,7 @@ class MBeanAnalyzer<M> {
...
@@ -243,7 +245,7 @@ class MBeanAnalyzer<M> {
final
Method
m0
=
sorted
[
i
-
1
];
final
Method
m0
=
sorted
[
i
-
1
];
final
Method
m1
=
sorted
[
i
];
final
Method
m1
=
sorted
[
i
];
// Methods that don't have the same name can't override each other
s
// Methods that don't have the same name can't override each other
if
(!
m0
.
getName
().
equals
(
m1
.
getName
()))
continue
;
if
(!
m0
.
getName
().
equals
(
m1
.
getName
()))
continue
;
// Methods that have the same name and same signature override
// Methods that have the same name and same signature override
...
@@ -251,7 +253,8 @@ class MBeanAnalyzer<M> {
...
@@ -251,7 +253,8 @@ class MBeanAnalyzer<M> {
// due to the way we have sorted them in MethodOrder.
// due to the way we have sorted them in MethodOrder.
if
(
Arrays
.
equals
(
m0
.
getParameterTypes
(),
if
(
Arrays
.
equals
(
m0
.
getParameterTypes
(),
m1
.
getParameterTypes
()))
{
m1
.
getParameterTypes
()))
{
overridden
.
add
(
m0
);
if
(!
overridden
.
add
(
m0
))
throw
new
RuntimeException
(
"Internal error: duplicate Method"
);
}
}
}
}
...
...
src/share/classes/com/sun/jmx/mbeanserver/MBeanIntrospector.java
浏览文件 @
3e149c7f
...
@@ -40,6 +40,7 @@ import java.util.WeakHashMap;
...
@@ -40,6 +40,7 @@ import java.util.WeakHashMap;
import
javax.management.Descriptor
;
import
javax.management.Descriptor
;
import
javax.management.ImmutableDescriptor
;
import
javax.management.ImmutableDescriptor
;
import
javax.management.IntrospectionException
;
import
javax.management.InvalidAttributeValueException
;
import
javax.management.InvalidAttributeValueException
;
import
javax.management.MBeanAttributeInfo
;
import
javax.management.MBeanAttributeInfo
;
import
javax.management.MBeanConstructorInfo
;
import
javax.management.MBeanConstructorInfo
;
...
@@ -53,8 +54,9 @@ import javax.management.ReflectionException;
...
@@ -53,8 +54,9 @@ import javax.management.ReflectionException;
/**
/**
* An introspector for MBeans of a certain type. There is one instance
* An introspector for MBeans of a certain type. There is one instance
* of this class for Standard MBeans and one for MXBeans, characterized
* of this class for Standard MBeans, and one for every MXBeanMappingFactory;
* by the two concrete subclasses of this abstract class.
* these two cases correspond to the two concrete subclasses of this abstract
* class.
*
*
* @param <M> the representation of methods for this kind of MBean:
* @param <M> the representation of methods for this kind of MBean:
* Method for Standard MBeans, ConvertingMethod for MXBeans.
* Method for Standard MBeans, ConvertingMethod for MXBeans.
...
@@ -119,7 +121,7 @@ abstract class MBeanIntrospector<M> {
...
@@ -119,7 +121,7 @@ abstract class MBeanIntrospector<M> {
* MXBean interface is not valid if one of its parameters cannot be
* MXBean interface is not valid if one of its parameters cannot be
* mapped to an Open Type.
* mapped to an Open Type.
*/
*/
abstract
void
checkMethod
(
M
m
)
throws
IllegalArgumentException
;
abstract
void
checkMethod
(
M
m
);
/**
/**
* Invoke the method with the given target and arguments.
* Invoke the method with the given target and arguments.
...
@@ -149,7 +151,8 @@ abstract class MBeanIntrospector<M> {
...
@@ -149,7 +151,8 @@ abstract class MBeanIntrospector<M> {
* may be null.
* may be null.
*/
*/
abstract
MBeanAttributeInfo
getMBeanAttributeInfo
(
String
attributeName
,
abstract
MBeanAttributeInfo
getMBeanAttributeInfo
(
String
attributeName
,
M
getter
,
M
setter
);
M
getter
,
M
setter
)
throws
IntrospectionException
;
/**
/**
* Construct an MBeanOperationInfo for the given operation based on
* Construct an MBeanOperationInfo for the given operation based on
* the M it was derived from.
* the M it was derived from.
...
@@ -170,6 +173,16 @@ abstract class MBeanIntrospector<M> {
...
@@ -170,6 +173,16 @@ abstract class MBeanIntrospector<M> {
*/
*/
abstract
Descriptor
getMBeanDescriptor
(
Class
<?>
resourceClass
);
abstract
Descriptor
getMBeanDescriptor
(
Class
<?>
resourceClass
);
/**
* Get any additional Descriptor entries for this introspector instance.
* If there is a non-default MXBeanMappingFactory, it will appear in
* this Descriptor.
* @return Additional Descriptor entries, or an empty Descriptor if none.
*/
Descriptor
getSpecificMBeanDescriptor
()
{
return
ImmutableDescriptor
.
EMPTY_DESCRIPTOR
;
}
void
checkCompliance
(
Class
<?>
mbeanType
)
throws
NotCompliantMBeanException
{
void
checkCompliance
(
Class
<?>
mbeanType
)
throws
NotCompliantMBeanException
{
if
(!
mbeanType
.
isInterface
())
{
if
(!
mbeanType
.
isInterface
())
{
throw
new
NotCompliantMBeanException
(
"Not an interface: "
+
throw
new
NotCompliantMBeanException
(
"Not an interface: "
+
...
@@ -216,7 +229,7 @@ abstract class MBeanIntrospector<M> {
...
@@ -216,7 +229,7 @@ abstract class MBeanIntrospector<M> {
* the MBeanInfo's Descriptor.
* the MBeanInfo's Descriptor.
*/
*/
private
MBeanInfo
makeInterfaceMBeanInfo
(
Class
<?>
mbeanInterface
,
private
MBeanInfo
makeInterfaceMBeanInfo
(
Class
<?>
mbeanInterface
,
MBeanAnalyzer
<
M
>
analyzer
)
{
MBeanAnalyzer
<
M
>
analyzer
)
throws
IntrospectionException
{
final
MBeanInfoMaker
maker
=
new
MBeanInfoMaker
();
final
MBeanInfoMaker
maker
=
new
MBeanInfoMaker
();
analyzer
.
visit
(
maker
);
analyzer
.
visit
(
maker
);
final
String
description
=
final
String
description
=
...
@@ -317,11 +330,12 @@ abstract class MBeanIntrospector<M> {
...
@@ -317,11 +330,12 @@ abstract class MBeanIntrospector<M> {
}
}
/** A visitor that constructs the per-interface MBeanInfo. */
/** A visitor that constructs the per-interface MBeanInfo. */
private
class
MBeanInfoMaker
implements
MBeanAnalyzer
.
MBeanVisitor
<
M
>
{
private
class
MBeanInfoMaker
implements
MBeanAnalyzer
.
MBeanVisitor
<
M
,
IntrospectionException
>
{
public
void
visitAttribute
(
String
attributeName
,
public
void
visitAttribute
(
String
attributeName
,
M
getter
,
M
getter
,
M
setter
)
{
M
setter
)
throws
IntrospectionException
{
MBeanAttributeInfo
mbai
=
MBeanAttributeInfo
mbai
=
getMBeanAttributeInfo
(
attributeName
,
getter
,
setter
);
getMBeanAttributeInfo
(
attributeName
,
getter
,
setter
);
...
@@ -346,13 +360,14 @@ abstract class MBeanIntrospector<M> {
...
@@ -346,13 +360,14 @@ abstract class MBeanIntrospector<M> {
ops
.
toArray
(
new
MBeanOperationInfo
[
0
]);
ops
.
toArray
(
new
MBeanOperationInfo
[
0
]);
final
String
interfaceClassName
=
final
String
interfaceClassName
=
"interfaceClassName="
+
mbeanInterface
.
getName
();
"interfaceClassName="
+
mbeanInterface
.
getName
();
final
Descriptor
interf
Descriptor
=
final
Descriptor
className
Descriptor
=
new
ImmutableDescriptor
(
interfaceClassName
);
new
ImmutableDescriptor
(
interfaceClassName
);
final
Descriptor
mbeanDescriptor
=
getBasicMBeanDescriptor
();
final
Descriptor
mbeanDescriptor
=
getBasicMBeanDescriptor
();
final
Descriptor
annotatedDescriptor
=
final
Descriptor
annotatedDescriptor
=
Introspector
.
descriptorForElement
(
mbeanInterface
);
Introspector
.
descriptorForElement
(
mbeanInterface
);
final
Descriptor
descriptor
=
final
Descriptor
descriptor
=
DescriptorCache
.
getInstance
().
union
(
interfDescriptor
,
DescriptorCache
.
getInstance
().
union
(
classNameDescriptor
,
mbeanDescriptor
,
mbeanDescriptor
,
annotatedDescriptor
);
annotatedDescriptor
);
...
@@ -388,20 +403,24 @@ abstract class MBeanIntrospector<M> {
...
@@ -388,20 +403,24 @@ abstract class MBeanIntrospector<M> {
* Return the MBeanInfo for the given resource, based on the given
* Return the MBeanInfo for the given resource, based on the given
* per-interface data.
* per-interface data.
*/
*/
final
MBeanInfo
getMBeanInfo
(
Object
resource
,
PerInterface
<
M
>
perInterface
)
{
final
MBeanInfo
getMBeanInfo
(
Object
resource
,
PerInterface
<
M
>
perInterface
)
throws
NotCompliantMBeanException
{
MBeanInfo
mbi
=
MBeanInfo
mbi
=
getClassMBeanInfo
(
resource
.
getClass
(),
perInterface
);
getClassMBeanInfo
(
resource
.
getClass
(),
perInterface
);
MBeanNotificationInfo
[]
notifs
=
findNotifications
(
resource
);
MBeanNotificationInfo
[]
notifs
=
findNotifications
(
resource
);
if
(
notifs
==
null
||
notifs
.
length
==
0
)
Descriptor
d
=
getSpecificMBeanDescriptor
();
boolean
anyNotifs
=
(
notifs
!=
null
&&
notifs
.
length
>
0
);
if
(!
anyNotifs
&&
ImmutableDescriptor
.
EMPTY_DESCRIPTOR
.
equals
(
d
))
return
mbi
;
return
mbi
;
else
{
else
{
d
=
ImmutableDescriptor
.
union
(
d
,
mbi
.
getDescriptor
());
return
new
MBeanInfo
(
mbi
.
getClassName
(),
return
new
MBeanInfo
(
mbi
.
getClassName
(),
mbi
.
getDescription
(),
mbi
.
getDescription
(),
mbi
.
getAttributes
(),
mbi
.
getAttributes
(),
mbi
.
getConstructors
(),
mbi
.
getConstructors
(),
mbi
.
getOperations
(),
mbi
.
getOperations
(),
notifs
,
notifs
,
mbi
.
getDescriptor
()
);
d
);
}
}
}
}
...
@@ -446,7 +465,7 @@ abstract class MBeanIntrospector<M> {
...
@@ -446,7 +465,7 @@ abstract class MBeanIntrospector<M> {
return
null
;
return
null
;
MBeanNotificationInfo
[]
mbn
=
MBeanNotificationInfo
[]
mbn
=
((
NotificationBroadcaster
)
moi
).
getNotificationInfo
();
((
NotificationBroadcaster
)
moi
).
getNotificationInfo
();
if
(
mbn
==
null
)
if
(
mbn
==
null
||
mbn
.
length
==
0
)
return
null
;
return
null
;
MBeanNotificationInfo
[]
result
=
MBeanNotificationInfo
[]
result
=
new
MBeanNotificationInfo
[
mbn
.
length
];
new
MBeanNotificationInfo
[
mbn
.
length
];
...
...
src/share/classes/com/sun/jmx/mbeanserver/MBeanSupport.java
浏览文件 @
3e149c7f
...
@@ -38,6 +38,7 @@ import javax.management.MBeanServer;
...
@@ -38,6 +38,7 @@ import javax.management.MBeanServer;
import
javax.management.NotCompliantMBeanException
;
import
javax.management.NotCompliantMBeanException
;
import
javax.management.ObjectName
;
import
javax.management.ObjectName
;
import
javax.management.ReflectionException
;
import
javax.management.ReflectionException
;
import
javax.management.openmbean.MXBeanMappingFactory
;
/**
/**
* Base class for MBeans. There is one instance of this class for
* Base class for MBeans. There is one instance of this class for
...
@@ -121,24 +122,26 @@ import javax.management.ReflectionException;
...
@@ -121,24 +122,26 @@ import javax.management.ReflectionException;
public
abstract
class
MBeanSupport
<
M
>
public
abstract
class
MBeanSupport
<
M
>
implements
DynamicMBean2
,
MBeanRegistration
{
implements
DynamicMBean2
,
MBeanRegistration
{
<
T
>
MBeanSupport
(
T
resource
,
Class
<
T
>
mbeanInterface
)
<
T
>
MBeanSupport
(
T
resource
,
Class
<
T
>
mbeanInterfaceType
,
MXBeanMappingFactory
mappingFactory
)
throws
NotCompliantMBeanException
{
throws
NotCompliantMBeanException
{
if
(
mbeanInterface
==
null
)
if
(
mbeanInterface
Type
==
null
)
throw
new
NotCompliantMBeanException
(
"Null MBean interface"
);
throw
new
NotCompliantMBeanException
(
"Null MBean interface"
);
if
(!
mbeanInterface
.
isInstance
(
resource
))
{
if
(!
mbeanInterface
Type
.
isInstance
(
resource
))
{
final
String
msg
=
final
String
msg
=
"Resource class "
+
resource
.
getClass
().
getName
()
+
"Resource class "
+
resource
.
getClass
().
getName
()
+
" is not an instance of "
+
mbeanInterface
.
getName
();
" is not an instance of "
+
mbeanInterface
Type
.
getName
();
throw
new
NotCompliantMBeanException
(
msg
);
throw
new
NotCompliantMBeanException
(
msg
);
}
}
this
.
resource
=
resource
;
this
.
resource
=
resource
;
MBeanIntrospector
<
M
>
introspector
=
getMBeanIntrospector
();
MBeanIntrospector
<
M
>
introspector
=
getMBeanIntrospector
(
mappingFactory
);
this
.
perInterface
=
introspector
.
getPerInterface
(
mbeanInterface
);
this
.
perInterface
=
introspector
.
getPerInterface
(
mbeanInterface
Type
);
this
.
mbeanInfo
=
introspector
.
getMBeanInfo
(
resource
,
perInterface
);
this
.
mbeanInfo
=
introspector
.
getMBeanInfo
(
resource
,
perInterface
);
}
}
/** Return the appropriate introspector for this type of MBean. */
/** Return the appropriate introspector for this type of MBean. */
abstract
MBeanIntrospector
<
M
>
getMBeanIntrospector
();
abstract
MBeanIntrospector
<
M
>
getMBeanIntrospector
(
MXBeanMappingFactory
mappingFactory
);
/**
/**
* Return a cookie for this MBean. This cookie will be passed to
* Return a cookie for this MBean. This cookie will be passed to
...
@@ -162,9 +165,8 @@ public abstract class MBeanSupport<M>
...
@@ -162,9 +165,8 @@ public abstract class MBeanSupport<M>
public
final
ObjectName
preRegister
(
MBeanServer
server
,
ObjectName
name
)
public
final
ObjectName
preRegister
(
MBeanServer
server
,
ObjectName
name
)
throws
Exception
{
throws
Exception
{
if
(
resource
instanceof
MBeanRegistration
)
if
(
resource
instanceof
MBeanRegistration
)
return
((
MBeanRegistration
)
resource
).
preRegister
(
server
,
name
);
name
=
((
MBeanRegistration
)
resource
).
preRegister
(
server
,
name
);
else
return
name
;
return
name
;
}
}
public
final
void
preRegister2
(
MBeanServer
server
,
ObjectName
name
)
public
final
void
preRegister2
(
MBeanServer
server
,
ObjectName
name
)
...
...
src/share/classes/com/sun/jmx/mbeanserver/MXBeanIntrospector.java
浏览文件 @
3e149c7f
...
@@ -25,18 +25,26 @@
...
@@ -25,18 +25,26 @@
package
com.sun.jmx.mbeanserver
;
package
com.sun.jmx.mbeanserver
;
import
com.sun.jmx.mbeanserver.MBeanIntrospector.MBeanInfoMap
;
import
com.sun.jmx.mbeanserver.MBeanIntrospector.PerInterfaceMap
;
import
java.lang.annotation.Annotation
;
import
java.lang.annotation.Annotation
;
import
java.lang.ref.WeakReference
;
import
java.lang.reflect.GenericArrayType
;
import
java.lang.reflect.GenericArrayType
;
import
java.lang.reflect.InvocationTargetException
;
import
java.lang.reflect.InvocationTargetException
;
import
java.lang.reflect.Method
;
import
java.lang.reflect.Method
;
import
java.lang.reflect.Type
;
import
java.lang.reflect.Type
;
import
java.util.Map
;
import
java.util.WeakHashMap
;
import
javax.management.Descriptor
;
import
javax.management.Descriptor
;
import
javax.management.ImmutableDescriptor
;
import
javax.management.ImmutableDescriptor
;
import
javax.management.IntrospectionException
;
import
javax.management.JMX
;
import
javax.management.MBeanAttributeInfo
;
import
javax.management.MBeanAttributeInfo
;
import
javax.management.MBeanException
;
import
javax.management.MBeanException
;
import
javax.management.MBeanOperationInfo
;
import
javax.management.MBeanOperationInfo
;
import
javax.management.MBeanParameterInfo
;
import
javax.management.MBeanParameterInfo
;
import
javax.management.NotCompliantMBeanException
;
import
javax.management.NotCompliantMBeanException
;
import
javax.management.openmbean.MXBeanMappingFactory
;
import
javax.management.openmbean.OpenMBeanAttributeInfoSupport
;
import
javax.management.openmbean.OpenMBeanAttributeInfoSupport
;
import
javax.management.openmbean.OpenMBeanOperationInfoSupport
;
import
javax.management.openmbean.OpenMBeanOperationInfoSupport
;
import
javax.management.openmbean.OpenMBeanParameterInfo
;
import
javax.management.openmbean.OpenMBeanParameterInfo
;
...
@@ -49,10 +57,36 @@ import javax.management.openmbean.OpenType;
...
@@ -49,10 +57,36 @@ import javax.management.openmbean.OpenType;
* @since 1.6
* @since 1.6
*/
*/
class
MXBeanIntrospector
extends
MBeanIntrospector
<
ConvertingMethod
>
{
class
MXBeanIntrospector
extends
MBeanIntrospector
<
ConvertingMethod
>
{
private
static
final
MXBeanIntrospector
instance
=
new
MXBeanIntrospector
();
/* We keep one MXBeanIntrospector per MXBeanMappingFactory, since the results
* of the introspection depend on the factory. The MXBeanIntrospector
* has a reference back to the factory, so we wrap it in a WeakReference.
* It will be strongly referenced by any MXBeanSupport instances using it;
* if there are none then it is OK to gc it.
*/
private
static
final
Map
<
MXBeanMappingFactory
,
WeakReference
<
MXBeanIntrospector
>>
map
=
new
WeakHashMap
<
MXBeanMappingFactory
,
WeakReference
<
MXBeanIntrospector
>>();
static
MXBeanIntrospector
getInstance
(
MXBeanMappingFactory
factory
)
{
if
(
factory
==
null
)
factory
=
MXBeanMappingFactory
.
DEFAULT
;
synchronized
(
map
)
{
MXBeanIntrospector
intro
;
WeakReference
<
MXBeanIntrospector
>
wr
=
map
.
get
(
factory
);
if
(
wr
!=
null
)
{
intro
=
wr
.
get
();
if
(
intro
!=
null
)
return
intro
;
}
intro
=
new
MXBeanIntrospector
(
factory
);
wr
=
new
WeakReference
<
MXBeanIntrospector
>(
intro
);
map
.
put
(
factory
,
wr
);
return
intro
;
}
}
static
MXBeanIntrospector
getInstance
(
)
{
private
MXBeanIntrospector
(
MXBeanMappingFactory
factory
)
{
return
instance
;
this
.
mappingFactory
=
factory
;
}
}
@Override
@Override
...
@@ -78,7 +112,7 @@ class MXBeanIntrospector extends MBeanIntrospector<ConvertingMethod> {
...
@@ -78,7 +112,7 @@ class MXBeanIntrospector extends MBeanIntrospector<ConvertingMethod> {
@Override
@Override
ConvertingMethod
mFrom
(
Method
m
)
{
ConvertingMethod
mFrom
(
Method
m
)
{
return
ConvertingMethod
.
from
(
m
);
return
ConvertingMethod
.
from
(
m
,
mappingFactory
);
}
}
@Override
@Override
...
@@ -139,7 +173,8 @@ class MXBeanIntrospector extends MBeanIntrospector<ConvertingMethod> {
...
@@ -139,7 +173,8 @@ class MXBeanIntrospector extends MBeanIntrospector<ConvertingMethod> {
@Override
@Override
MBeanAttributeInfo
getMBeanAttributeInfo
(
String
attributeName
,
MBeanAttributeInfo
getMBeanAttributeInfo
(
String
attributeName
,
ConvertingMethod
getter
,
ConvertingMethod
setter
)
{
ConvertingMethod
getter
,
ConvertingMethod
setter
)
throws
IntrospectionException
{
final
boolean
isReadable
=
(
getter
!=
null
);
final
boolean
isReadable
=
(
getter
!=
null
);
final
boolean
isWritable
=
(
setter
!=
null
);
final
boolean
isWritable
=
(
setter
!=
null
);
...
@@ -222,14 +257,14 @@ class MXBeanIntrospector extends MBeanIntrospector<ConvertingMethod> {
...
@@ -222,14 +257,14 @@ class MXBeanIntrospector extends MBeanIntrospector<ConvertingMethod> {
Introspector
.
descriptorForAnnotations
(
annots
[
i
]));
Introspector
.
descriptorForAnnotations
(
annots
[
i
]));
final
MBeanParameterInfo
pi
;
final
MBeanParameterInfo
pi
;
if
(
canUseOpenInfo
(
originalType
))
{
if
(
canUseOpenInfo
(
originalType
))
{
pi
=
new
OpenMBeanParameterInfoSupport
(
"p"
+
i
,
pi
=
new
OpenMBeanParameterInfoSupport
(
paramName
,
paramDescription
,
paramDescription
,
openType
,
openType
,
descriptor
);
descriptor
);
}
else
{
}
else
{
openParameterTypes
=
false
;
openParameterTypes
=
false
;
pi
=
new
MBeanParameterInfo
(
pi
=
new
MBeanParameterInfo
(
"p"
+
i
,
paramName
,
originalTypeString
(
originalType
),
originalTypeString
(
originalType
),
paramDescription
,
paramDescription
,
descriptor
);
descriptor
);
...
@@ -291,6 +326,17 @@ class MXBeanIntrospector extends MBeanIntrospector<ConvertingMethod> {
...
@@ -291,6 +326,17 @@ class MXBeanIntrospector extends MBeanIntrospector<ConvertingMethod> {
return
ImmutableDescriptor
.
EMPTY_DESCRIPTOR
;
return
ImmutableDescriptor
.
EMPTY_DESCRIPTOR
;
}
}
@Override
Descriptor
getSpecificMBeanDescriptor
()
{
if
(
mappingFactory
==
MXBeanMappingFactory
.
DEFAULT
)
return
ImmutableDescriptor
.
EMPTY_DESCRIPTOR
;
else
{
return
new
ImmutableDescriptor
(
JMX
.
MXBEAN_MAPPING_FACTORY_CLASS_FIELD
+
"="
+
mappingFactory
.
getClass
().
getName
());
}
}
private
static
Descriptor
typeDescriptor
(
OpenType
openType
,
private
static
Descriptor
typeDescriptor
(
OpenType
openType
,
Type
originalType
)
{
Type
originalType
)
{
return
new
ImmutableDescriptor
(
return
new
ImmutableDescriptor
(
...
@@ -331,8 +377,10 @@ class MXBeanIntrospector extends MBeanIntrospector<ConvertingMethod> {
...
@@ -331,8 +377,10 @@ class MXBeanIntrospector extends MBeanIntrospector<ConvertingMethod> {
return
type
.
toString
();
return
type
.
toString
();
}
}
private
static
final
PerInterfaceMap
<
ConvertingMethod
>
private
final
PerInterfaceMap
<
ConvertingMethod
>
perInterfaceMap
=
new
PerInterfaceMap
<
ConvertingMethod
>();
perInterfaceMap
=
new
PerInterfaceMap
<
ConvertingMethod
>();
private
static
final
MBeanInfoMap
mbeanInfoMap
=
new
MBeanInfoMap
();
private
final
MBeanInfoMap
mbeanInfoMap
=
new
MBeanInfoMap
();
private
final
MXBeanMappingFactory
mappingFactory
;
}
}
src/share/classes/com/sun/jmx/mbeanserver/MXBeanLookup.java
浏览文件 @
3e149c7f
...
@@ -25,15 +25,21 @@
...
@@ -25,15 +25,21 @@
package
com.sun.jmx.mbeanserver
;
package
com.sun.jmx.mbeanserver
;
import
com.sun.jmx.remote.util.EnvHelp
;
import
java.io.InvalidObjectException
;
import
static
com
.
sun
.
jmx
.
mbeanserver
.
Util
.*;
import
static
com
.
sun
.
jmx
.
mbeanserver
.
Util
.*;
import
java.util.Map
;
import
java.util.Map
;
import
java.lang.ref.WeakReference
;
import
java.lang.ref.WeakReference
;
import
java.lang.reflect.InvocationHandler
;
import
java.lang.reflect.InvocationHandler
;
import
java.lang.reflect.Proxy
;
import
java.lang.reflect.Proxy
;
import
java.security.AccessController
;
import
javax.management.InstanceAlreadyExistsException
;
import
javax.management.JMX
;
import
javax.management.JMX
;
import
javax.management.MBeanServerConnection
;
import
javax.management.MBeanServerConnection
;
import
javax.management.MBeanServerInvocationHandler
;
import
javax.management.MBeanServerInvocationHandler
;
import
javax.management.MalformedObjectNameException
;
import
javax.management.ObjectName
;
import
javax.management.ObjectName
;
import
javax.management.openmbean.OpenDataException
;
/**
/**
* @since 1.6
* @since 1.6
...
@@ -80,71 +86,199 @@ import javax.management.ObjectName;
...
@@ -80,71 +86,199 @@ import javax.management.ObjectName;
*
*
* From the above, it is clear that the logic for getX on an MXBean is
* From the above, it is clear that the logic for getX on an MXBean is
* the same as for setX on a proxy, and vice versa.
* the same as for setX on a proxy, and vice versa.
*
* The above describes the logic for "plain" MXBeanLookup, represented
* by MXBeanLookup.Plain. When namespaces enter the picture, we see
* MXBeanLookup.Prefix. Here, the idea is that the name of the ModuleMXBean
* might be a//m:m=m. In this case, we don't accept a reference to
* an MXBean object, since that would require different namespaces to know
* each others' objects. We only accept proxies. Suppose you have a proxy
* for a//m:m=m, call it moduleProxy, and you call
* moduleProxy.setProduct(productProxy). Then if productProxy is for
* a//p:p=p we should convert this to just p:p=p. If productProxy is for
* a//b//p:p=p we should convert it to b//p:p=p. Conversely, if getProduct
* returns an ObjectName like b//p:p=p then we should convert it into a proxy
* for a//b//p:p=p.
*/
*/
public
class
MXBeanLookup
{
public
abstract
class
MXBeanLookup
{
private
MXBeanLookup
(
MBeanServerConnection
mbsc
)
{
private
MXBeanLookup
(
MBeanServerConnection
mbsc
)
{
this
.
mbsc
=
mbsc
;
this
.
mbsc
=
mbsc
;
}
}
static
MXBeanLookup
lookupFor
(
MBeanServerConnection
mbsc
)
{
static
MXBeanLookup
lookupFor
(
MBeanServerConnection
mbsc
,
String
prefix
)
{
synchronized
(
mbscToLookup
)
{
if
(
prefix
==
null
)
WeakReference
<
MXBeanLookup
>
weakLookup
=
mbscToLookup
.
get
(
mbsc
);
return
Plain
.
lookupFor
(
mbsc
);
MXBeanLookup
lookup
=
(
weakLookup
==
null
)
?
null
:
weakLookup
.
get
();
else
if
(
lookup
==
null
)
{
return
new
Prefix
(
mbsc
,
prefix
);
lookup
=
new
MXBeanLookup
(
mbsc
);
}
mbscToLookup
.
put
(
mbsc
,
new
WeakReference
<
MXBeanLookup
>(
lookup
));
abstract
<
T
>
T
objectNameToMXBean
(
ObjectName
name
,
Class
<
T
>
type
)
throws
InvalidObjectException
;
abstract
ObjectName
mxbeanToObjectName
(
Object
mxbean
)
throws
OpenDataException
;
static
class
Plain
extends
MXBeanLookup
{
Plain
(
MBeanServerConnection
mbsc
)
{
super
(
mbsc
);
}
static
Plain
lookupFor
(
MBeanServerConnection
mbsc
)
{
synchronized
(
mbscToLookup
)
{
WeakReference
<
Plain
>
weakLookup
=
mbscToLookup
.
get
(
mbsc
);
Plain
lookup
=
(
weakLookup
==
null
)
?
null
:
weakLookup
.
get
();
if
(
lookup
==
null
)
{
lookup
=
new
Plain
(
mbsc
);
mbscToLookup
.
put
(
mbsc
,
new
WeakReference
<
Plain
>(
lookup
));
}
return
lookup
;
}
}
return
lookup
;
}
}
}
synchronized
<
T
>
T
objectNameToMXBean
(
ObjectName
name
,
Class
<
T
>
type
)
{
@Override
WeakReference
<
Object
>
wr
=
objectNameToProxy
.
get
(
name
);
synchronized
<
T
>
T
objectNameToMXBean
(
ObjectName
name
,
Class
<
T
>
type
)
{
if
(
wr
!=
null
)
{
WeakReference
<
Object
>
wr
=
objectNameToProxy
.
get
(
name
);
Object
proxy
=
wr
.
get
();
if
(
wr
!=
null
)
{
if
(
type
.
isInstance
(
proxy
))
Object
proxy
=
wr
.
get
();
return
type
.
cast
(
proxy
);
if
(
type
.
isInstance
(
proxy
))
return
type
.
cast
(
proxy
);
}
T
proxy
=
JMX
.
newMXBeanProxy
(
mbsc
,
name
,
type
);
objectNameToProxy
.
put
(
name
,
new
WeakReference
<
Object
>(
proxy
));
return
proxy
;
}
@Override
synchronized
ObjectName
mxbeanToObjectName
(
Object
mxbean
)
throws
OpenDataException
{
String
wrong
;
if
(
mxbean
instanceof
Proxy
)
{
InvocationHandler
ih
=
Proxy
.
getInvocationHandler
(
mxbean
);
if
(
ih
instanceof
MBeanServerInvocationHandler
)
{
MBeanServerInvocationHandler
mbsih
=
(
MBeanServerInvocationHandler
)
ih
;
if
(
mbsih
.
getMBeanServerConnection
().
equals
(
mbsc
))
return
mbsih
.
getObjectName
();
else
wrong
=
"proxy for a different MBeanServer"
;
}
else
wrong
=
"not a JMX proxy"
;
}
else
{
ObjectName
name
=
mxbeanToObjectName
.
get
(
mxbean
);
if
(
name
!=
null
)
return
name
;
wrong
=
"not an MXBean registered in this MBeanServer"
;
}
String
s
=
(
mxbean
==
null
)
?
"null"
:
"object of type "
+
mxbean
.
getClass
().
getName
();
throw
new
OpenDataException
(
"Could not convert "
+
s
+
" to an ObjectName: "
+
wrong
);
// Message will be strange if mxbean is null but it is not
// supposed to be.
}
synchronized
void
addReference
(
ObjectName
name
,
Object
mxbean
)
throws
InstanceAlreadyExistsException
{
ObjectName
existing
=
mxbeanToObjectName
.
get
(
mxbean
);
if
(
existing
!=
null
)
{
String
multiname
=
AccessController
.
doPrivileged
(
new
GetPropertyAction
(
"jmx.mxbean.multiname"
));
if
(!
"true"
.
equalsIgnoreCase
(
multiname
))
{
throw
new
InstanceAlreadyExistsException
(
"MXBean already registered with name "
+
existing
);
}
}
mxbeanToObjectName
.
put
(
mxbean
,
name
);
}
synchronized
boolean
removeReference
(
ObjectName
name
,
Object
mxbean
)
{
if
(
name
.
equals
(
mxbeanToObjectName
.
get
(
mxbean
)))
{
mxbeanToObjectName
.
remove
(
mxbean
);
return
true
;
}
else
return
false
;
/* removeReference can be called when the above condition fails,
* notably if you try to register the same MXBean twice.
*/
}
}
T
proxy
=
JMX
.
newMXBeanProxy
(
mbsc
,
name
,
type
);
objectNameToProxy
.
put
(
name
,
new
WeakReference
<
Object
>(
proxy
));
private
final
WeakIdentityHashMap
<
Object
,
ObjectName
>
return
proxy
;
mxbeanToObjectName
=
WeakIdentityHashMap
.
make
();
private
final
Map
<
ObjectName
,
WeakReference
<
Object
>>
objectNameToProxy
=
newMap
();
private
static
WeakIdentityHashMap
<
MBeanServerConnection
,
WeakReference
<
Plain
>>
mbscToLookup
=
WeakIdentityHashMap
.
make
();
}
}
synchronized
ObjectName
mxbeanToObjectName
(
Object
mxbean
)
{
private
static
class
Prefix
extends
MXBeanLookup
{
if
(
mxbean
instanceof
Proxy
)
{
private
final
String
prefix
;
InvocationHandler
ih
=
Proxy
.
getInvocationHandler
(
mxbean
);
if
(
ih
instanceof
MBeanServerInvocationHandler
)
{
Prefix
(
MBeanServerConnection
mbsc
,
String
prefix
)
{
MBeanServerInvocationHandler
mbsih
=
super
(
mbsc
);
(
MBeanServerInvocationHandler
)
ih
;
this
.
prefix
=
prefix
;
if
(
mbsih
.
getMBeanServerConnection
().
equals
(
mbsc
))
}
return
mbsih
.
getObjectName
();
@Override
<
T
>
T
objectNameToMXBean
(
ObjectName
name
,
Class
<
T
>
type
)
throws
InvalidObjectException
{
String
domain
=
prefix
+
name
.
getDomain
();
try
{
name
=
switchDomain
(
domain
,
name
);
}
catch
(
MalformedObjectNameException
e
)
{
throw
EnvHelp
.
initCause
(
new
InvalidObjectException
(
e
.
getMessage
()),
e
);
}
return
JMX
.
newMXBeanProxy
(
mbsc
,
name
,
type
);
}
@Override
ObjectName
mxbeanToObjectName
(
Object
mxbean
)
throws
OpenDataException
{
ObjectName
name
=
proxyToObjectName
(
mxbean
);
String
domain
=
name
.
getDomain
();
if
(!
domain
.
startsWith
(
prefix
))
{
throw
new
OpenDataException
(
"Proxy's name does not start with "
+
prefix
+
": "
+
name
);
}
}
return
null
;
try
{
}
else
name
=
switchDomain
(
domain
.
substring
(
prefix
.
length
()),
name
);
return
mxbeanToObjectName
.
get
(
mxbean
);
}
catch
(
MalformedObjectNameException
e
)
{
throw
EnvHelp
.
initCause
(
new
OpenDataException
(
e
.
getMessage
()),
e
);
}
return
name
;
}
}
ObjectName
proxyToObjectName
(
Object
proxy
)
{
InvocationHandler
ih
=
Proxy
.
getInvocationHandler
(
proxy
);
if
(
ih
instanceof
MBeanServerInvocationHandler
)
{
MBeanServerInvocationHandler
mbsih
=
(
MBeanServerInvocationHandler
)
ih
;
if
(
mbsih
.
getMBeanServerConnection
().
equals
(
mbsc
))
return
mbsih
.
getObjectName
();
}
return
null
;
}
static
MXBeanLookup
getLookup
()
{
return
currentLookup
.
get
();
}
}
s
ynchronized
void
addReference
(
ObjectName
name
,
Object
mxbean
)
{
s
tatic
void
setLookup
(
MXBeanLookup
lookup
)
{
mxbeanToObjectName
.
put
(
mxbean
,
name
);
currentLookup
.
set
(
lookup
);
}
}
synchronized
boolean
removeReference
(
ObjectName
name
,
Object
mxbean
)
{
// Method temporarily added until we have ObjectName.switchDomain in the
if
(
name
.
equals
(
mxbeanToObjectName
.
get
(
mxbean
)))
{
// public API. Note that this method DOES NOT PRESERVE the order of
mxbeanToObjectName
.
remove
(
mxbean
);
// keys in the ObjectName so it must not be used in the final release.
return
true
;
static
ObjectName
switchDomain
(
String
domain
,
ObjectName
name
)
}
else
throws
MalformedObjectNameException
{
return
false
;
return
new
ObjectName
(
domain
,
name
.
getKeyPropertyList
());
/* removeReference can be called when the above condition fails,
* notably if you try to register the same MXBean twice.
*/
}
}
private
final
MBeanServerConnection
mbsc
;
private
static
final
ThreadLocal
<
MXBeanLookup
>
currentLookup
=
private
final
WeakIdentityHashMap
<
Object
,
ObjectName
>
new
ThreadLocal
<
MXBeanLookup
>();
mxbeanToObjectName
=
WeakIdentityHashMap
.
make
();
private
final
Map
<
ObjectName
,
WeakReference
<
Object
>>
final
MBeanServerConnection
mbsc
;
objectNameToProxy
=
newMap
();
private
static
WeakIdentityHashMap
<
MBeanServerConnection
,
WeakReference
<
MXBeanLookup
>>
mbscToLookup
=
WeakIdentityHashMap
.
make
();
}
}
src/share/classes/com/sun/jmx/mbeanserver/MXBeanProxy.java
浏览文件 @
3e149c7f
...
@@ -27,14 +27,15 @@ package com.sun.jmx.mbeanserver;
...
@@ -27,14 +27,15 @@ package com.sun.jmx.mbeanserver;
import
static
com
.
sun
.
jmx
.
mbeanserver
.
Util
.*;
import
static
com
.
sun
.
jmx
.
mbeanserver
.
Util
.*;
import
java.lang.reflect.InvocationHandler
;
import
java.lang.reflect.Method
;
import
java.lang.reflect.Method
;
import
java.util.Map
;
import
java.util.Map
;
import
javax.management.Attribute
;
import
javax.management.Attribute
;
import
javax.management.MBeanServerConnection
;
import
javax.management.MBeanServerConnection
;
import
javax.management.MalformedObjectNameException
;
import
javax.management.NotCompliantMBeanException
;
import
javax.management.NotCompliantMBeanException
;
import
javax.management.ObjectName
;
import
javax.management.ObjectName
;
import
javax.management.openmbean.MXBeanMappingFactory
;
/**
/**
<p>Helper class for an {@link InvocationHandler} that forwards methods from an
<p>Helper class for an {@link InvocationHandler} that forwards methods from an
...
@@ -46,8 +47,7 @@ import javax.management.ObjectName;
...
@@ -46,8 +47,7 @@ import javax.management.ObjectName;
@since 1.6
@since 1.6
*/
*/
public
class
MXBeanProxy
{
public
class
MXBeanProxy
{
public
MXBeanProxy
(
Class
<?>
mxbeanInterface
)
public
MXBeanProxy
(
Class
<?>
mxbeanInterface
,
MXBeanMappingFactory
factory
)
{
throws
IllegalArgumentException
{
if
(
mxbeanInterface
==
null
)
if
(
mxbeanInterface
==
null
)
throw
new
IllegalArgumentException
(
"Null parameter"
);
throw
new
IllegalArgumentException
(
"Null parameter"
);
...
@@ -55,14 +55,15 @@ public class MXBeanProxy {
...
@@ -55,14 +55,15 @@ public class MXBeanProxy {
final
MBeanAnalyzer
<
ConvertingMethod
>
analyzer
;
final
MBeanAnalyzer
<
ConvertingMethod
>
analyzer
;
try
{
try
{
analyzer
=
analyzer
=
MXBeanIntrospector
.
getInstance
().
getAnalyzer
(
mxbeanInterface
);
MXBeanIntrospector
.
getInstance
(
factory
).
getAnalyzer
(
mxbeanInterface
);
}
catch
(
NotCompliantMBeanException
e
)
{
}
catch
(
NotCompliantMBeanException
e
)
{
throw
new
IllegalArgumentException
(
e
);
throw
new
IllegalArgumentException
(
e
);
}
}
analyzer
.
visit
(
new
Visitor
());
analyzer
.
visit
(
new
Visitor
());
}
}
private
class
Visitor
implements
MBeanAnalyzer
.
MBeanVisitor
<
ConvertingMethod
>
{
private
class
Visitor
implements
MBeanAnalyzer
.
MBeanVisitor
<
ConvertingMethod
,
RuntimeException
>
{
public
void
visitAttribute
(
String
attributeName
,
public
void
visitAttribute
(
String
attributeName
,
ConvertingMethod
getter
,
ConvertingMethod
getter
,
ConvertingMethod
setter
)
{
ConvertingMethod
setter
)
{
...
@@ -160,10 +161,29 @@ public class MXBeanProxy {
...
@@ -160,10 +161,29 @@ public class MXBeanProxy {
Handler
handler
=
handlerMap
.
get
(
method
);
Handler
handler
=
handlerMap
.
get
(
method
);
ConvertingMethod
cm
=
handler
.
getConvertingMethod
();
ConvertingMethod
cm
=
handler
.
getConvertingMethod
();
MXBeanLookup
lookup
=
MXBeanLookup
.
lookupFor
(
mbsc
);
String
prefix
=
extractPrefix
(
name
);
Object
[]
openArgs
=
cm
.
toOpenParameters
(
lookup
,
args
);
MXBeanLookup
lookup
=
MXBeanLookup
.
lookupFor
(
mbsc
,
prefix
);
Object
result
=
handler
.
invoke
(
mbsc
,
name
,
openArgs
);
MXBeanLookup
oldLookup
=
MXBeanLookup
.
getLookup
();
return
cm
.
fromOpenReturnValue
(
lookup
,
result
);
try
{
MXBeanLookup
.
setLookup
(
lookup
);
Object
[]
openArgs
=
cm
.
toOpenParameters
(
lookup
,
args
);
Object
result
=
handler
.
invoke
(
mbsc
,
name
,
openArgs
);
return
cm
.
fromOpenReturnValue
(
lookup
,
result
);
}
finally
{
MXBeanLookup
.
setLookup
(
oldLookup
);
}
}
private
static
String
extractPrefix
(
ObjectName
name
)
throws
MalformedObjectNameException
{
String
domain
=
name
.
getDomain
();
int
slashslash
=
domain
.
lastIndexOf
(
"//"
);
if
(
slashslash
>
0
&&
domain
.
charAt
(
slashslash
-
1
)
==
'/'
)
slashslash
--;
if
(
slashslash
>=
0
)
return
domain
.
substring
(
0
,
slashslash
+
2
);
else
return
null
;
}
}
private
final
Map
<
Method
,
Handler
>
handlerMap
=
newMap
();
private
final
Map
<
Method
,
Handler
>
handlerMap
=
newMap
();
...
...
src/share/classes/com/sun/jmx/mbeanserver/MXBeanSupport.java
浏览文件 @
3e149c7f
...
@@ -35,6 +35,8 @@ import javax.management.JMX;
...
@@ -35,6 +35,8 @@ import javax.management.JMX;
import
javax.management.MBeanServer
;
import
javax.management.MBeanServer
;
import
javax.management.NotCompliantMBeanException
;
import
javax.management.NotCompliantMBeanException
;
import
javax.management.ObjectName
;
import
javax.management.ObjectName
;
import
javax.management.openmbean.MXBeanMappingFactory
;
import
javax.management.openmbean.MXBeanMappingFactoryClass
;
/**
/**
* Base class for MXBeans.
* Base class for MXBeans.
...
@@ -61,14 +63,16 @@ public class MXBeanSupport extends MBeanSupport<ConvertingMethod> {
...
@@ -61,14 +63,16 @@ public class MXBeanSupport extends MBeanSupport<ConvertingMethod> {
if it does not implement the class {@code mxbeanInterface} or if
if it does not implement the class {@code mxbeanInterface} or if
that class is not a valid MXBean interface.
that class is not a valid MXBean interface.
*/
*/
public
<
T
>
MXBeanSupport
(
T
resource
,
Class
<
T
>
mxbeanInterface
)
public
<
T
>
MXBeanSupport
(
T
resource
,
Class
<
T
>
mxbeanInterface
,
MXBeanMappingFactory
mappingFactory
)
throws
NotCompliantMBeanException
{
throws
NotCompliantMBeanException
{
super
(
resource
,
mxbeanInterface
);
super
(
resource
,
mxbeanInterface
,
mappingFactory
);
}
}
@Override
@Override
MBeanIntrospector
<
ConvertingMethod
>
getMBeanIntrospector
()
{
MBeanIntrospector
<
ConvertingMethod
>
return
MXBeanIntrospector
.
getInstance
();
getMBeanIntrospector
(
MXBeanMappingFactory
mappingFactory
)
{
return
MXBeanIntrospector
.
getInstance
(
mappingFactory
);
}
}
@Override
@Override
...
@@ -76,8 +80,7 @@ public class MXBeanSupport extends MBeanSupport<ConvertingMethod> {
...
@@ -76,8 +80,7 @@ public class MXBeanSupport extends MBeanSupport<ConvertingMethod> {
return
mxbeanLookup
;
return
mxbeanLookup
;
}
}
static
Class
<?>
findMXBeanInterface
(
Class
<?>
resourceClass
)
static
<
T
>
Class
<?
super
T
>
findMXBeanInterface
(
Class
<
T
>
resourceClass
)
{
throws
IllegalArgumentException
{
if
(
resourceClass
==
null
)
if
(
resourceClass
==
null
)
throw
new
IllegalArgumentException
(
"Null resource class"
);
throw
new
IllegalArgumentException
(
"Null resource class"
);
final
Set
<
Class
<?>>
intfs
=
transitiveInterfaces
(
resourceClass
);
final
Set
<
Class
<?>>
intfs
=
transitiveInterfaces
(
resourceClass
);
...
@@ -104,7 +107,7 @@ public class MXBeanSupport extends MBeanSupport<ConvertingMethod> {
...
@@ -104,7 +107,7 @@ public class MXBeanSupport extends MBeanSupport<ConvertingMethod> {
throw
new
IllegalArgumentException
(
msg
);
throw
new
IllegalArgumentException
(
msg
);
}
}
if
(
candidates
.
iterator
().
hasNext
())
{
if
(
candidates
.
iterator
().
hasNext
())
{
return
candidates
.
iterator
().
next
(
);
return
Util
.
cast
(
candidates
.
iterator
().
next
()
);
}
else
{
}
else
{
final
String
msg
=
final
String
msg
=
"Class "
+
resourceClass
.
getName
()
+
"Class "
+
resourceClass
.
getName
()
+
...
@@ -116,7 +119,7 @@ public class MXBeanSupport extends MBeanSupport<ConvertingMethod> {
...
@@ -116,7 +119,7 @@ public class MXBeanSupport extends MBeanSupport<ConvertingMethod> {
/* Return all interfaces inherited by this class, directly or
/* Return all interfaces inherited by this class, directly or
* indirectly through the parent class and interfaces.
* indirectly through the parent class and interfaces.
*/
*/
private
static
Set
<
Class
<?>>
transitiveInterfaces
(
Class
c
)
{
private
static
Set
<
Class
<?>>
transitiveInterfaces
(
Class
<?>
c
)
{
Set
<
Class
<?>>
set
=
newSet
();
Set
<
Class
<?>>
set
=
newSet
();
transitiveInterfaces
(
c
,
set
);
transitiveInterfaces
(
c
,
set
);
return
set
;
return
set
;
...
@@ -127,7 +130,7 @@ public class MXBeanSupport extends MBeanSupport<ConvertingMethod> {
...
@@ -127,7 +130,7 @@ public class MXBeanSupport extends MBeanSupport<ConvertingMethod> {
if
(
c
.
isInterface
())
if
(
c
.
isInterface
())
intfs
.
add
(
c
);
intfs
.
add
(
c
);
transitiveInterfaces
(
c
.
getSuperclass
(),
intfs
);
transitiveInterfaces
(
c
.
getSuperclass
(),
intfs
);
for
(
Class
sup
:
c
.
getInterfaces
())
for
(
Class
<?>
sup
:
c
.
getInterfaces
())
transitiveInterfaces
(
sup
,
intfs
);
transitiveInterfaces
(
sup
,
intfs
);
}
}
...
@@ -157,12 +160,7 @@ public class MXBeanSupport extends MBeanSupport<ConvertingMethod> {
...
@@ -157,12 +160,7 @@ public class MXBeanSupport extends MBeanSupport<ConvertingMethod> {
// eventually we could have some logic to supply a default name
// eventually we could have some logic to supply a default name
synchronized
(
lock
)
{
synchronized
(
lock
)
{
if
(
this
.
objectName
!=
null
)
{
this
.
mxbeanLookup
=
MXBeanLookup
.
Plain
.
lookupFor
(
server
);
final
String
msg
=
"MXBean already registered with name "
+
this
.
objectName
;
throw
new
InstanceAlreadyExistsException
(
msg
);
}
this
.
mxbeanLookup
=
MXBeanLookup
.
lookupFor
(
server
);
this
.
mxbeanLookup
.
addReference
(
name
,
getResource
());
this
.
mxbeanLookup
.
addReference
(
name
,
getResource
());
this
.
objectName
=
name
;
this
.
objectName
=
name
;
}
}
...
@@ -171,12 +169,20 @@ public class MXBeanSupport extends MBeanSupport<ConvertingMethod> {
...
@@ -171,12 +169,20 @@ public class MXBeanSupport extends MBeanSupport<ConvertingMethod> {
@Override
@Override
public
void
unregister
()
{
public
void
unregister
()
{
synchronized
(
lock
)
{
synchronized
(
lock
)
{
if
(
mxbeanLookup
.
removeReference
(
objectName
,
getResource
()))
if
(
mxbeanLookup
!=
null
)
{
objectName
=
null
;
if
(
mxbeanLookup
.
removeReference
(
objectName
,
getResource
()))
objectName
=
null
;
}
// XXX: need to revisit the whole register/unregister logic in
// the face of wrapping. The mxbeanLookup!=null test is a hack.
// If you wrap an MXBean in a MyWrapperMBean and register it,
// the lookup table should contain the wrapped object. But that
// implies that MyWrapperMBean calls register, which today it
// can't within the public API.
}
}
}
}
private
final
Object
lock
=
new
Object
();
// for mxbeanLookup and objectName
private
Object
lock
=
new
Object
();
// for mxbeanLookup and objectName
private
MXBeanLookup
.
Plain
mxbeanLookup
;
private
MXBeanLookup
mxbeanLookup
;
private
ObjectName
objectName
;
private
ObjectName
objectName
;
}
}
src/share/classes/com/sun/jmx/mbeanserver/NotificationMBeanSupport.java
浏览文件 @
3e149c7f
...
@@ -30,6 +30,7 @@ import java.util.ArrayList;
...
@@ -30,6 +30,7 @@ import java.util.ArrayList;
import
java.util.List
;
import
java.util.List
;
import
javax.management.NotCompliantMBeanException
;
import
javax.management.NotCompliantMBeanException
;
import
javax.management.Notification
;
import
javax.management.Notification
;
import
javax.management.openmbean.MXBeanMappingFactory
;
/**
/**
* <p>A variant of {@code StandardMBeanSupport} where the only
* <p>A variant of {@code StandardMBeanSupport} where the only
...
@@ -48,7 +49,7 @@ public class NotificationMBeanSupport extends StandardMBeanSupport {
...
@@ -48,7 +49,7 @@ public class NotificationMBeanSupport extends StandardMBeanSupport {
}
}
@Override
@Override
MBeanIntrospector
<
Method
>
getMBeanIntrospector
()
{
MBeanIntrospector
<
Method
>
getMBeanIntrospector
(
MXBeanMappingFactory
ignored
)
{
return
introspector
;
return
introspector
;
}
}
...
...
src/share/classes/com/sun/jmx/mbeanserver/PerInterface.java
浏览文件 @
3e149c7f
...
@@ -231,7 +231,7 @@ final class PerInterface<M> {
...
@@ -231,7 +231,7 @@ final class PerInterface<M> {
/**
/**
* Visitor that sets up the method maps (operations, getters, setters).
* Visitor that sets up the method maps (operations, getters, setters).
*/
*/
private
class
InitMaps
implements
MBeanAnalyzer
.
MBeanVisitor
<
M
>
{
private
class
InitMaps
implements
MBeanAnalyzer
.
MBeanVisitor
<
M
,
RuntimeException
>
{
public
void
visitAttribute
(
String
attributeName
,
public
void
visitAttribute
(
String
attributeName
,
M
getter
,
M
getter
,
M
setter
)
{
M
setter
)
{
...
...
src/share/classes/com/sun/jmx/mbeanserver/StandardMBeanSupport.java
浏览文件 @
3e149c7f
...
@@ -25,14 +25,13 @@
...
@@ -25,14 +25,13 @@
package
com.sun.jmx.mbeanserver
;
package
com.sun.jmx.mbeanserver
;
import
static
com
.
sun
.
jmx
.
mbeanserver
.
Util
.*;
import
java.lang.reflect.Method
;
import
java.lang.reflect.Method
;
import
javax.management.MBeanInfo
;
import
javax.management.MBeanInfo
;
import
javax.management.MBeanServer
;
import
javax.management.MBeanServer
;
import
javax.management.NotCompliantMBeanException
;
import
javax.management.NotCompliantMBeanException
;
import
javax.management.ObjectName
;
import
javax.management.ObjectName
;
import
javax.management.openmbean.MXBeanMappingFactory
;
/**
/**
* Base class for Standard MBeans.
* Base class for Standard MBeans.
...
@@ -61,11 +60,11 @@ public class StandardMBeanSupport extends MBeanSupport<Method> {
...
@@ -61,11 +60,11 @@ public class StandardMBeanSupport extends MBeanSupport<Method> {
*/
*/
public
<
T
>
StandardMBeanSupport
(
T
resource
,
Class
<
T
>
mbeanInterface
)
public
<
T
>
StandardMBeanSupport
(
T
resource
,
Class
<
T
>
mbeanInterface
)
throws
NotCompliantMBeanException
{
throws
NotCompliantMBeanException
{
super
(
resource
,
mbeanInterface
);
super
(
resource
,
mbeanInterface
,
(
MXBeanMappingFactory
)
null
);
}
}
@Override
@Override
MBeanIntrospector
<
Method
>
getMBeanIntrospector
()
{
MBeanIntrospector
<
Method
>
getMBeanIntrospector
(
MXBeanMappingFactory
ignored
)
{
return
StandardMBeanIntrospector
.
getInstance
();
return
StandardMBeanIntrospector
.
getInstance
();
}
}
...
...
src/share/classes/javax/management/JMX.java
浏览文件 @
3e149c7f
...
@@ -26,8 +26,17 @@
...
@@ -26,8 +26,17 @@
package
javax.management
;
package
javax.management
;
import
com.sun.jmx.mbeanserver.Introspector
;
import
com.sun.jmx.mbeanserver.Introspector
;
import
com.sun.jmx.remote.util.ClassLogger
;
import
java.beans.BeanInfo
;
import
java.beans.PropertyDescriptor
;
import
java.io.Serializable
;
import
java.lang.reflect.InvocationHandler
;
import
java.lang.reflect.InvocationHandler
;
import
java.lang.reflect.InvocationTargetException
;
import
java.lang.reflect.Method
;
import
java.lang.reflect.Proxy
;
import
java.lang.reflect.Proxy
;
import
java.util.Map
;
import
java.util.TreeMap
;
import
javax.management.openmbean.MXBeanMappingFactory
;
/**
/**
* Static methods from the JMX API. There are no instances of this class.
* Static methods from the JMX API. There are no instances of this class.
...
@@ -39,6 +48,8 @@ public class JMX {
...
@@ -39,6 +48,8 @@ public class JMX {
* this class.
* this class.
*/
*/
static
final
JMX
proof
=
new
JMX
();
static
final
JMX
proof
=
new
JMX
();
private
static
final
ClassLogger
logger
=
new
ClassLogger
(
"javax.management.misc"
,
"JMX"
);
private
JMX
()
{}
private
JMX
()
{}
...
@@ -84,6 +95,14 @@ public class JMX {
...
@@ -84,6 +95,14 @@ public class JMX {
*/
*/
public
static
final
String
MXBEAN_FIELD
=
"mxbean"
;
public
static
final
String
MXBEAN_FIELD
=
"mxbean"
;
/**
* The name of the
* <a href="Descriptor.html#mxbeanMappingFactoryClass">{@code
* mxbeanMappingFactoryClass}</a> field.
*/
public
static
final
String
MXBEAN_MAPPING_FACTORY_CLASS_FIELD
=
"mxbeanMappingFactoryClass"
;
/**
/**
* The name of the <a href="Descriptor.html#openType">{@code
* The name of the <a href="Descriptor.html#openType">{@code
* openType}</a> field.
* openType}</a> field.
...
@@ -96,6 +115,264 @@ public class JMX {
...
@@ -96,6 +115,264 @@ public class JMX {
*/
*/
public
static
final
String
ORIGINAL_TYPE_FIELD
=
"originalType"
;
public
static
final
String
ORIGINAL_TYPE_FIELD
=
"originalType"
;
/**
* <p>Options to apply to an MBean proxy or to an instance of {@link
* StandardMBean}.</p>
*
* <p>For example, to specify a custom {@link MXBeanMappingFactory}
* for a {@code StandardMBean}, you might write this:</p>
*
* <pre>
* MXBeanMappingFactory factory = new MyMXBeanMappingFactory();
* JMX.MBeanOptions opts = new JMX.MBeanOptions();
* opts.setMXBeanMappingFactory(factory);
* StandardMBean mbean = new StandardMBean(impl, intf, opts);
* </pre>
*
* @see javax.management.JMX.ProxyOptions
*/
public
static
class
MBeanOptions
implements
Serializable
,
Cloneable
{
private
static
final
long
serialVersionUID
=
-
6380842449318177843L
;
static
final
MBeanOptions
MXBEAN
=
new
MBeanOptions
();
static
{
MXBEAN
.
setMXBeanMappingFactory
(
MXBeanMappingFactory
.
DEFAULT
);
}
private
MXBeanMappingFactory
mappingFactory
;
/**
* <p>Construct an {@code MBeanOptions} object where all options have
* their default values.</p>
*/
public
MBeanOptions
()
{}
@Override
public
MBeanOptions
clone
()
{
try
{
return
(
MBeanOptions
)
super
.
clone
();
}
catch
(
CloneNotSupportedException
e
)
{
throw
new
AssertionError
(
e
);
}
}
/**
* <p>True if this is an MXBean proxy or a StandardMBean instance
* that is an MXBean. The default value is false.</p>
*
* <p>This method is equivalent to {@link #getMXBeanMappingFactory()
* this.getMXBeanMappingFactory()}{@code != null}.</p>
*
* @return true if this is an MXBean proxy or a StandardMBean instance
* that is an MXBean.
*/
public
boolean
isMXBean
()
{
return
(
this
.
mappingFactory
!=
null
);
}
/**
* <p>The mappings between Java types and Open Types to be used in
* an MXBean proxy or a StandardMBean instance that is an MXBean,
* or null if this instance is not for an MXBean.
* The default value is null.</p>
*
* @return the mappings to be used in this proxy or StandardMBean,
* or null if this instance is not for an MXBean.
*/
public
MXBeanMappingFactory
getMXBeanMappingFactory
()
{
return
mappingFactory
;
}
/**
* <p>Set the {@link #getMXBeanMappingFactory() MXBeanMappingFactory} to
* the given value. The value should be null if this instance is not
* for an MXBean. If this instance is for an MXBean, the value should
* usually be either a custom mapping factory, or
* {@link MXBeanMappingFactory#forInterface
* MXBeanMappingFactory.forInterface}{@code (mxbeanInterface)}
* which signifies
* that the {@linkplain MXBeanMappingFactory#DEFAULT default} mapping
* factory should be used unless an {@code @}{@link
* javax.management.openmbean.MXBeanMappingFactoryClass
* MXBeanMappingFactoryClass} annotation on {@code mxbeanInterface}
* specifies otherwise.</p>
*
* <p>Examples:</p>
* <pre>
* MBeanOptions opts = new MBeanOptions();
* opts.setMXBeanMappingFactory(myMappingFactory);
* MyMXBean proxy = JMX.newMBeanProxy(
* mbeanServerConnection, objectName, MyMXBean.class, opts);
*
* // ...or...
*
* MBeanOptions opts = new MBeanOptions();
* MXBeanMappingFactory defaultFactoryForMyMXBean =
* MXBeanMappingFactory.forInterface(MyMXBean.class);
* opts.setMXBeanMappingFactory(defaultFactoryForMyMXBean);
* MyMXBean proxy = JMX.newMBeanProxy(
* mbeanServerConnection, objectName, MyMXBean.class, opts);
* </pre>
*
* @param f the new value. If null, this instance is not for an
* MXBean.
*/
public
void
setMXBeanMappingFactory
(
MXBeanMappingFactory
f
)
{
this
.
mappingFactory
=
f
;
}
/* To maximise object sharing, classes in this package can replace
* a private MBeanOptions with no MXBeanMappingFactory with one
* of these shared instances. But they must be EXTREMELY careful
* never to give out the shared instances to user code, which could
* modify them.
*/
private
static
final
MBeanOptions
[]
CANONICALS
=
{
new
MBeanOptions
(),
MXBEAN
,
};
// Overridden in local subclasses:
MBeanOptions
[]
canonicals
()
{
return
CANONICALS
;
}
// This is only used by the logic for canonical instances.
// Overridden in local subclasses:
boolean
same
(
MBeanOptions
opt
)
{
return
(
opt
.
mappingFactory
==
mappingFactory
);
}
final
MBeanOptions
canonical
()
{
for
(
MBeanOptions
opt
:
canonicals
())
{
if
(
opt
.
getClass
()
==
this
.
getClass
()
&&
same
(
opt
))
return
opt
;
}
return
this
;
}
final
MBeanOptions
uncanonical
()
{
for
(
MBeanOptions
opt
:
canonicals
())
{
if
(
this
==
opt
)
return
clone
();
}
return
this
;
}
private
Map
<
String
,
Object
>
toMap
()
{
Map
<
String
,
Object
>
map
=
new
TreeMap
<
String
,
Object
>();
try
{
BeanInfo
bi
=
java
.
beans
.
Introspector
.
getBeanInfo
(
getClass
());
PropertyDescriptor
[]
pds
=
bi
.
getPropertyDescriptors
();
for
(
PropertyDescriptor
pd
:
pds
)
{
String
name
=
pd
.
getName
();
if
(
name
.
equals
(
"class"
))
continue
;
Method
get
=
pd
.
getReadMethod
();
if
(
get
!=
null
)
map
.
put
(
name
,
get
.
invoke
(
this
));
}
}
catch
(
Exception
e
)
{
Throwable
t
=
e
;
if
(
t
instanceof
InvocationTargetException
)
t
=
t
.
getCause
();
map
.
put
(
"Exception"
,
t
);
}
return
map
;
}
@Override
public
String
toString
()
{
return
getClass
().
getSimpleName
()
+
toMap
();
// For example "MBeanOptions{MXBean=true, <etc>}".
}
/**
* <p>Indicates whether some other object is "equal to" this one. The
* result is true if and only if the other object is also an instance
* of MBeanOptions or a subclass, and has the same properties with
* the same values.</p>
* @return {@inheritDoc}
*/
@Override
public
boolean
equals
(
Object
obj
)
{
if
(
obj
==
this
)
return
true
;
if
(
obj
==
null
||
obj
.
getClass
()
!=
this
.
getClass
())
return
false
;
return
toMap
().
equals
(((
MBeanOptions
)
obj
).
toMap
());
}
@Override
public
int
hashCode
()
{
return
toMap
().
hashCode
();
}
}
/**
* <p>Options to apply to an MBean proxy.</p>
*
* @see #newMBeanProxy
*/
public
static
class
ProxyOptions
extends
MBeanOptions
{
private
static
final
long
serialVersionUID
=
7238804866098386559L
;
private
boolean
notificationEmitter
;
/**
* <p>Construct a {@code ProxyOptions} object where all options have
* their default values.</p>
*/
public
ProxyOptions
()
{}
@Override
public
ProxyOptions
clone
()
{
return
(
ProxyOptions
)
super
.
clone
();
}
/**
* <p>Defines whether the returned proxy should
* implement {@link NotificationEmitter}. The default value is false.</p>
*
* @return true if this proxy will be a NotificationEmitter.
*
* @see JMX#newMBeanProxy(MBeanServerConnection, ObjectName, Class,
* MBeanOptions)
*/
public
boolean
isNotificationEmitter
()
{
return
this
.
notificationEmitter
;
}
/**
* <p>Set the {@link #isNotificationEmitter NotificationEmitter} option to
* the given value.</p>
* @param emitter the new value.
*/
public
void
setNotificationEmitter
(
boolean
emitter
)
{
this
.
notificationEmitter
=
emitter
;
}
// Canonical objects for each of (MXBean,!MXBean) x (Emitter,!Emitter)
private
static
final
ProxyOptions
[]
CANONICALS
=
{
new
ProxyOptions
(),
new
ProxyOptions
(),
new
ProxyOptions
(),
new
ProxyOptions
(),
};
static
{
CANONICALS
[
1
].
setMXBeanMappingFactory
(
MXBeanMappingFactory
.
DEFAULT
);
CANONICALS
[
2
].
setNotificationEmitter
(
true
);
CANONICALS
[
3
].
setMXBeanMappingFactory
(
MXBeanMappingFactory
.
DEFAULT
);
CANONICALS
[
3
].
setNotificationEmitter
(
true
);
}
@Override
MBeanOptions
[]
canonicals
()
{
return
CANONICALS
;
}
@Override
boolean
same
(
MBeanOptions
opt
)
{
return
(
super
.
same
(
opt
)
&&
opt
instanceof
ProxyOptions
&&
((
ProxyOptions
)
opt
).
notificationEmitter
==
notificationEmitter
);
}
}
/**
/**
* <p>Make a proxy for a Standard MBean in a local or remote
* <p>Make a proxy for a Standard MBean in a local or remote
* MBean Server.</p>
* MBean Server.</p>
...
@@ -172,7 +449,7 @@ public class JMX {
...
@@ -172,7 +449,7 @@ public class JMX {
*
*
* <p>This method behaves the same as {@link
* <p>This method behaves the same as {@link
* #newMBeanProxy(MBeanServerConnection, ObjectName, Class)}, but
* #newMBeanProxy(MBeanServerConnection, ObjectName, Class)}, but
* additionally, if {@code notification
Broadcas
ter} is {@code
* additionally, if {@code notification
Emit
ter} is {@code
* true}, then the MBean is assumed to be a {@link
* true}, then the MBean is assumed to be a {@link
* NotificationBroadcaster} or {@link NotificationEmitter} and the
* NotificationBroadcaster} or {@link NotificationEmitter} and the
* returned proxy will implement {@link NotificationEmitter} as
* returned proxy will implement {@link NotificationEmitter} as
...
@@ -189,25 +466,21 @@ public class JMX {
...
@@ -189,25 +466,21 @@ public class JMX {
* {@code connection} to forward to.
* {@code connection} to forward to.
* @param interfaceClass the management interface that the MBean
* @param interfaceClass the management interface that the MBean
* exports, which will also be implemented by the returned proxy.
* exports, which will also be implemented by the returned proxy.
* @param notification
Broadcas
ter make the returned proxy
* @param notification
Emit
ter make the returned proxy
* implement {@link NotificationEmitter} by forwarding its methods
* implement {@link NotificationEmitter} by forwarding its methods
* via {@code connection}.
* via {@code connection}.
*
* @param <T> allows the compiler to know that if the {@code
* @param <T> allows the compiler to know that if the {@code
* interfaceClass} parameter is {@code MyMBean.class}, for
* interfaceClass} parameter is {@code MyMBean.class}, for
* example, then the return type is {@code MyMBean}.
* example, then the return type is {@code MyMBean}.
*
* @return the new proxy instance.
* @return the new proxy instance.
*/
*/
public
static
<
T
>
T
newMBeanProxy
(
MBeanServerConnection
connection
,
public
static
<
T
>
T
newMBeanProxy
(
MBeanServerConnection
connection
,
ObjectName
objectName
,
ObjectName
objectName
,
Class
<
T
>
interfaceClass
,
Class
<
T
>
interfaceClass
,
boolean
notificationBroadcaster
)
{
boolean
notificationEmitter
)
{
return
MBeanServerInvocationHandler
.
newProxyInstance
(
ProxyOptions
opts
=
new
ProxyOptions
();
connection
,
opts
.
setNotificationEmitter
(
notificationEmitter
);
objectName
,
return
newMBeanProxy
(
connection
,
objectName
,
interfaceClass
,
opts
);
interfaceClass
,
notificationBroadcaster
);
}
}
/**
/**
...
@@ -314,7 +587,7 @@ public class JMX {
...
@@ -314,7 +587,7 @@ public class JMX {
*
*
* <p>This method behaves the same as {@link
* <p>This method behaves the same as {@link
* #newMXBeanProxy(MBeanServerConnection, ObjectName, Class)}, but
* #newMXBeanProxy(MBeanServerConnection, ObjectName, Class)}, but
* additionally, if {@code notification
Broadcas
ter} is {@code
* additionally, if {@code notification
Emit
ter} is {@code
* true}, then the MXBean is assumed to be a {@link
* true}, then the MXBean is assumed to be a {@link
* NotificationBroadcaster} or {@link NotificationEmitter} and the
* NotificationBroadcaster} or {@link NotificationEmitter} and the
* returned proxy will implement {@link NotificationEmitter} as
* returned proxy will implement {@link NotificationEmitter} as
...
@@ -331,31 +604,105 @@ public class JMX {
...
@@ -331,31 +604,105 @@ public class JMX {
* {@code connection} to forward to.
* {@code connection} to forward to.
* @param interfaceClass the MXBean interface,
* @param interfaceClass the MXBean interface,
* which will also be implemented by the returned proxy.
* which will also be implemented by the returned proxy.
* @param notification
Broadcas
ter make the returned proxy
* @param notification
Emit
ter make the returned proxy
* implement {@link NotificationEmitter} by forwarding its methods
* implement {@link NotificationEmitter} by forwarding its methods
* via {@code connection}.
* via {@code connection}.
*
* @param <T> allows the compiler to know that if the {@code
* @param <T> allows the compiler to know that if the {@code
* interfaceClass} parameter is {@code MyMXBean.class}, for
* interfaceClass} parameter is {@code MyMXBean.class}, for
* example, then the return type is {@code MyMXBean}.
* example, then the return type is {@code MyMXBean}.
*
* @return the new proxy instance.
* @return the new proxy instance.
*/
*/
public
static
<
T
>
T
newMXBeanProxy
(
MBeanServerConnection
connection
,
public
static
<
T
>
T
newMXBeanProxy
(
MBeanServerConnection
connection
,
ObjectName
objectName
,
ObjectName
objectName
,
Class
<
T
>
interfaceClass
,
Class
<
T
>
interfaceClass
,
boolean
notificationBroadcaster
)
{
boolean
notificationEmitter
)
{
// Check interface for MXBean compliance
ProxyOptions
opts
=
new
ProxyOptions
();
//
MXBeanMappingFactory
f
=
MXBeanMappingFactory
.
forInterface
(
interfaceClass
);
opts
.
setMXBeanMappingFactory
(
f
);
opts
.
setNotificationEmitter
(
notificationEmitter
);
return
newMBeanProxy
(
connection
,
objectName
,
interfaceClass
,
opts
);
}
/**
* <p>Make a proxy for a Standard MBean or MXBean in a local or remote MBean
* Server that may also support the methods of {@link
* NotificationEmitter} and (for an MXBean) that may define custom MXBean
* type mappings.</p>
*
* <p>This method behaves the same as
* {@link #newMBeanProxy(MBeanServerConnection, ObjectName, Class)} or
* {@link #newMXBeanProxy(MBeanServerConnection, ObjectName, Class)},
* according as {@code opts.isMXBean()} is respectively false or true; but
* with the following changes based on {@code opts}.</p>
*
* <ul>
* <li>If {@code opts.isNotificationEmitter()} is {@code
* true}, then the MBean is assumed to be a {@link
* NotificationBroadcaster} or {@link NotificationEmitter} and the
* returned proxy will implement {@link NotificationEmitter} as
* well as {@code interfaceClass}. A call to {@link
* NotificationBroadcaster#addNotificationListener} on the proxy
* will result in a call to {@link
* MBeanServerConnection#addNotificationListener(ObjectName,
* NotificationListener, NotificationFilter, Object)}, and
* likewise for the other methods of {@link
* NotificationBroadcaster} and {@link NotificationEmitter}.</li>
*
* <li>If {@code opts.getMXBeanMappingFactory()} is not null,
* then the mappings it defines will be applied to convert between
* arbitrary Java types and Open Types.</li>
* </ul>
*
* @param connection the MBean server to forward to.
* @param objectName the name of the MBean within
* {@code connection} to forward to.
* @param interfaceClass the Standard MBean or MXBean interface,
* which will also be implemented by the returned proxy.
* @param opts the options to apply for this proxy. Can be null,
* in which case default options are applied.
* @param <T> allows the compiler to know that if the {@code
* interfaceClass} parameter is {@code MyMXBean.class}, for
* example, then the return type is {@code MyMXBean}.
* @return the new proxy instance.
*
* @throws IllegalArgumentException if {@code interfaceClass} is not a
* valid MXBean interface.
*/
public
static
<
T
>
T
newMBeanProxy
(
MBeanServerConnection
connection
,
ObjectName
objectName
,
Class
<
T
>
interfaceClass
,
MBeanOptions
opts
)
{
try
{
try
{
Introspector
.
testComplianceMXBeanInterface
(
interfaceClas
s
);
return
newMBeanProxy2
(
connection
,
objectName
,
interfaceClass
,
opt
s
);
}
catch
(
NotCompliantMBeanException
e
)
{
}
catch
(
NotCompliantMBeanException
e
)
{
throw
new
IllegalArgumentException
(
e
);
throw
new
IllegalArgumentException
(
e
);
}
}
}
private
static
<
T
>
T
newMBeanProxy2
(
MBeanServerConnection
connection
,
ObjectName
objectName
,
Class
<
T
>
interfaceClass
,
MBeanOptions
opts
)
throws
NotCompliantMBeanException
{
if
(
opts
==
null
)
opts
=
new
MBeanOptions
();
boolean
notificationEmitter
=
opts
instanceof
ProxyOptions
&&
((
ProxyOptions
)
opts
).
isNotificationEmitter
();
MXBeanMappingFactory
mappingFactory
=
opts
.
getMXBeanMappingFactory
();
if
(
mappingFactory
!=
null
)
{
// Check interface for MXBean compliance
Introspector
.
testComplianceMXBeanInterface
(
interfaceClass
,
mappingFactory
);
}
InvocationHandler
handler
=
new
MBeanServerInvocationHandler
(
InvocationHandler
handler
=
new
MBeanServerInvocationHandler
(
connection
,
objectName
,
true
);
connection
,
objectName
,
opts
);
final
Class
[]
interfaces
;
final
Class
[]
interfaces
;
if
(
notification
Broadcas
ter
)
{
if
(
notification
Emit
ter
)
{
interfaces
=
interfaces
=
new
Class
<?>[]
{
interfaceClass
,
NotificationEmitter
.
class
};
new
Class
<?>[]
{
interfaceClass
,
NotificationEmitter
.
class
};
}
else
}
else
...
...
src/share/classes/javax/management/MBeanServerInvocationHandler.java
浏览文件 @
3e149c7f
...
@@ -33,6 +33,9 @@ import java.lang.reflect.Method;
...
@@ -33,6 +33,9 @@ import java.lang.reflect.Method;
import
java.lang.reflect.Proxy
;
import
java.lang.reflect.Proxy
;
import
java.util.Arrays
;
import
java.util.Arrays
;
import
java.util.WeakHashMap
;
import
java.util.WeakHashMap
;
import
javax.management.openmbean.MXBeanMappingFactory
;
import
static
javax
.
management
.
JMX
.
MBeanOptions
;
/**
/**
* <p>{@link InvocationHandler} that forwards methods in an MBean's
* <p>{@link InvocationHandler} that forwards methods in an MBean's
...
@@ -111,7 +114,7 @@ public class MBeanServerInvocationHandler implements InvocationHandler {
...
@@ -111,7 +114,7 @@ public class MBeanServerInvocationHandler implements InvocationHandler {
public
MBeanServerInvocationHandler
(
MBeanServerConnection
connection
,
public
MBeanServerInvocationHandler
(
MBeanServerConnection
connection
,
ObjectName
objectName
)
{
ObjectName
objectName
)
{
this
(
connection
,
objectName
,
false
);
this
(
connection
,
objectName
,
null
);
}
}
/**
/**
...
@@ -138,6 +141,14 @@ public class MBeanServerInvocationHandler implements InvocationHandler {
...
@@ -138,6 +141,14 @@ public class MBeanServerInvocationHandler implements InvocationHandler {
public
MBeanServerInvocationHandler
(
MBeanServerConnection
connection
,
public
MBeanServerInvocationHandler
(
MBeanServerConnection
connection
,
ObjectName
objectName
,
ObjectName
objectName
,
boolean
isMXBean
)
{
boolean
isMXBean
)
{
this
(
connection
,
objectName
,
isMXBean
?
MBeanOptions
.
MXBEAN
:
null
);
}
public
MBeanServerInvocationHandler
(
MBeanServerConnection
connection
,
ObjectName
objectName
,
MBeanOptions
options
)
{
if
(
options
==
null
)
options
=
new
MBeanOptions
();
if
(
connection
==
null
)
{
if
(
connection
==
null
)
{
throw
new
IllegalArgumentException
(
"Null connection"
);
throw
new
IllegalArgumentException
(
"Null connection"
);
}
}
...
@@ -146,7 +157,7 @@ public class MBeanServerInvocationHandler implements InvocationHandler {
...
@@ -146,7 +157,7 @@ public class MBeanServerInvocationHandler implements InvocationHandler {
}
}
this
.
connection
=
connection
;
this
.
connection
=
connection
;
this
.
objectName
=
objectName
;
this
.
objectName
=
objectName
;
this
.
isMXBean
=
isMXBean
;
this
.
options
=
options
.
canonical
()
;
}
}
/**
/**
...
@@ -182,7 +193,16 @@ public class MBeanServerInvocationHandler implements InvocationHandler {
...
@@ -182,7 +193,16 @@ public class MBeanServerInvocationHandler implements InvocationHandler {
* @since 1.6
* @since 1.6
*/
*/
public
boolean
isMXBean
()
{
public
boolean
isMXBean
()
{
return
isMXBean
;
return
options
.
isMXBean
();
}
/**
* <p>Return the {@link MBeanOptions} used for this proxy.</p>
*
* @return the MBeanOptions.
*/
public
MBeanOptions
getMBeanOptions
()
{
return
options
.
uncanonical
();
}
}
/**
/**
...
@@ -260,7 +280,7 @@ public class MBeanServerInvocationHandler implements InvocationHandler {
...
@@ -260,7 +280,7 @@ public class MBeanServerInvocationHandler implements InvocationHandler {
return
doLocally
(
proxy
,
method
,
args
);
return
doLocally
(
proxy
,
method
,
args
);
try
{
try
{
if
(
isMXBean
)
{
if
(
isMXBean
()
)
{
MXBeanProxy
p
=
findMXBeanProxy
(
methodClass
);
MXBeanProxy
p
=
findMXBeanProxy
(
methodClass
);
return
p
.
invoke
(
connection
,
objectName
,
method
,
args
);
return
p
.
invoke
(
connection
,
objectName
,
method
,
args
);
}
else
{
}
else
{
...
@@ -326,21 +346,34 @@ public class MBeanServerInvocationHandler implements InvocationHandler {
...
@@ -326,21 +346,34 @@ public class MBeanServerInvocationHandler implements InvocationHandler {
*/
*/
}
}
private
static
MXBeanProxy
findMXBeanProxy
(
Class
<?>
mxbeanInterface
)
{
private
MXBeanProxy
findMXBeanProxy
(
Class
<?>
mxbeanInterface
)
{
MXBeanMappingFactory
mappingFactory
=
options
.
getMXBeanMappingFactory
();
synchronized
(
mxbeanProxies
)
{
synchronized
(
mxbeanProxies
)
{
WeakReference
<
MXBeanProxy
>
proxyRef
=
ClassToProxy
classToProxy
=
mxbeanProxies
.
get
(
mappingFactory
);
mxbeanProxies
.
get
(
mxbeanInterface
);
if
(
classToProxy
==
null
)
{
MXBeanProxy
p
=
(
proxyRef
==
null
)
?
null
:
proxyRef
.
get
();
classToProxy
=
new
ClassToProxy
();
if
(
p
==
null
)
{
mxbeanProxies
.
put
(
mappingFactory
,
classToProxy
);
p
=
new
MXBeanProxy
(
mxbeanInterface
);
mxbeanProxies
.
put
(
mxbeanInterface
,
new
WeakReference
<
MXBeanProxy
>(
p
));
}
}
WeakReference
<
MXBeanProxy
>
wr
=
classToProxy
.
get
(
mxbeanInterface
);
MXBeanProxy
p
;
if
(
wr
!=
null
)
{
p
=
wr
.
get
();
if
(
p
!=
null
)
return
p
;
}
p
=
new
MXBeanProxy
(
mxbeanInterface
,
mappingFactory
);
classToProxy
.
put
(
mxbeanInterface
,
new
WeakReference
<
MXBeanProxy
>(
p
));
return
p
;
return
p
;
}
}
}
}
private
static
final
WeakHashMap
<
Class
<?>,
WeakReference
<
MXBeanProxy
>>
private
static
final
WeakHashMap
<
MXBeanMappingFactory
,
ClassToProxy
>
mxbeanProxies
=
new
WeakHashMap
<
Class
<?>,
WeakReference
<
MXBeanProxy
>>();
mxbeanProxies
=
newWeakHashMap
();
private
static
class
ClassToProxy
extends
WeakHashMap
<
Class
<?>,
WeakReference
<
MXBeanProxy
>>
{}
private
static
<
K
,
V
>
WeakHashMap
<
K
,
V
>
newWeakHashMap
()
{
return
new
WeakHashMap
<
K
,
V
>();
}
private
Object
invokeBroadcasterMethod
(
Object
proxy
,
Method
method
,
private
Object
invokeBroadcasterMethod
(
Object
proxy
,
Method
method
,
Object
[]
args
)
throws
Exception
{
Object
[]
args
)
throws
Exception
{
...
@@ -453,7 +486,7 @@ public class MBeanServerInvocationHandler implements InvocationHandler {
...
@@ -453,7 +486,7 @@ public class MBeanServerInvocationHandler implements InvocationHandler {
objectName
.
equals
(
handler
.
objectName
)
&&
objectName
.
equals
(
handler
.
objectName
)
&&
proxy
.
getClass
().
equals
(
args
[
0
].
getClass
());
proxy
.
getClass
().
equals
(
args
[
0
].
getClass
());
}
else
if
(
methodName
.
equals
(
"toString"
))
{
}
else
if
(
methodName
.
equals
(
"toString"
))
{
return
(
isMXBean
?
"MX"
:
"M"
)
+
"BeanProxy("
+
return
(
isMXBean
()
?
"MX"
:
"M"
)
+
"BeanProxy("
+
connection
+
"["
+
objectName
+
"])"
;
connection
+
"["
+
objectName
+
"])"
;
}
else
if
(
methodName
.
equals
(
"hashCode"
))
{
}
else
if
(
methodName
.
equals
(
"hashCode"
))
{
return
objectName
.
hashCode
()+
connection
.
hashCode
();
return
objectName
.
hashCode
()+
connection
.
hashCode
();
...
@@ -484,5 +517,5 @@ public class MBeanServerInvocationHandler implements InvocationHandler {
...
@@ -484,5 +517,5 @@ public class MBeanServerInvocationHandler implements InvocationHandler {
private
final
MBeanServerConnection
connection
;
private
final
MBeanServerConnection
connection
;
private
final
ObjectName
objectName
;
private
final
ObjectName
objectName
;
private
final
boolean
isMXBean
;
private
final
MBeanOptions
options
;
}
}
src/share/classes/javax/management/MXBean.java
浏览文件 @
3e149c7f
...
@@ -44,6 +44,10 @@ import javax.management.openmbean.CompositeDataInvocationHandler;
...
@@ -44,6 +44,10 @@ import javax.management.openmbean.CompositeDataInvocationHandler;
import
javax.management.openmbean.CompositeDataSupport
;
import
javax.management.openmbean.CompositeDataSupport
;
import
javax.management.openmbean.CompositeDataView
;
import
javax.management.openmbean.CompositeDataView
;
import
javax.management.openmbean.CompositeType
;
import
javax.management.openmbean.CompositeType
;
import
javax.management.openmbean.MXBeanMapping
;
import
javax.management.openmbean.MXBeanMappingClass
;
import
javax.management.openmbean.MXBeanMappingFactory
;
import
javax.management.openmbean.MXBeanMappingFactoryClass
;
import
javax.management.openmbean.OpenDataException
;
import
javax.management.openmbean.OpenDataException
;
import
javax.management.openmbean.OpenMBeanInfo
;
import
javax.management.openmbean.OpenMBeanInfo
;
import
javax.management.openmbean.OpenType
;
import
javax.management.openmbean.OpenType
;
...
@@ -78,7 +82,7 @@ import javax.management.openmbean.TabularType;
...
@@ -78,7 +82,7 @@ import javax.management.openmbean.TabularType;
public interface MisleadingMXBean {}
public interface MisleadingMXBean {}
</pre>
</pre>
<h3
><a name="MXBean-spec">MXBean specification</a>
</h3>
<h3
id="MXBean-spec">MXBean specification
</h3>
<p>The MXBean concept provides a simple way to code an MBean
<p>The MXBean concept provides a simple way to code an MBean
that only references a predefined set of types, the ones defined
that only references a predefined set of types, the ones defined
...
@@ -314,7 +318,7 @@ public class MemoryPool
...
@@ -314,7 +318,7 @@ public class MemoryPool
</table>
</table>
<h2
><a name="mxbean-def">Definition of an MXBean</a>
</h2>
<h2
id="mxbean-def">Definition of an MXBean
</h2>
<p>An MXBean is a kind of MBean. An MXBean object can be
<p>An MXBean is a kind of MBean. An MXBean object can be
registered directly in the MBean Server, or it can be used as an
registered directly in the MBean Server, or it can be used as an
...
@@ -367,7 +371,7 @@ public class MemoryPool
...
@@ -367,7 +371,7 @@ public class MemoryPool
above rules will produce an exception.</p>
above rules will produce an exception.</p>
<h2
><a name="naming-conv">Naming conventions</a>
</h2>
<h2
id="naming-conv">Naming conventions
</h2>
<p>The same naming conventions are applied to the methods in an
<p>The same naming conventions are applied to the methods in an
MXBean as in a Standard MBean:</p>
MXBean as in a Standard MBean:</p>
...
@@ -413,7 +417,7 @@ public class MemoryPool
...
@@ -413,7 +417,7 @@ public class MemoryPool
read-only or write-only respectively.</p>
read-only or write-only respectively.</p>
<h2
><a name="mapping-rules">Type mapping rules</a>
</h2>
<h2
id="mapping-rules">Type mapping rules
</h2>
<p>An MXBean is a kind of Open MBean, as defined by the {@link
<p>An MXBean is a kind of Open MBean, as defined by the {@link
javax.management.openmbean} package. This means that the types of
javax.management.openmbean} package. This means that the types of
...
@@ -475,7 +479,11 @@ public class MemoryPool
...
@@ -475,7 +479,11 @@ public class MemoryPool
from type <em>opendata(J)</em> to type <em>J</em>, a null value is
from type <em>opendata(J)</em> to type <em>J</em>, a null value is
mapped to a null value.</p>
mapped to a null value.</p>
<p>The following table summarizes the type mapping rules.</p>
<p>In addition to the default type mapping rules, you can specify
custom type mappings, as described <a
href="#custom">below</a>.</p>
<p>The following table summarizes the default type mapping rules.</p>
<table border="1" cellpadding="5">
<table border="1" cellpadding="5">
<tr>
<tr>
...
@@ -658,7 +666,7 @@ TabularType tabularType =
...
@@ -658,7 +666,7 @@ TabularType tabularType =
TabularData} that serializes as {@code TabularDataSupport}.</p>
TabularData} that serializes as {@code TabularDataSupport}.</p>
<h3
><a name="mxbean-map">Mappings for MXBean interfaces</a>
</h3>
<h3
id="mxbean-map">Mappings for MXBean interfaces
</h3>
<p>An MXBean interface, or a type referenced within an MXBean
<p>An MXBean interface, or a type referenced within an MXBean
interface, can reference another MXBean interface, <em>J</em>.
interface, can reference another MXBean interface, <em>J</em>.
...
@@ -747,7 +755,7 @@ public interface ModuleMXBean {
...
@@ -747,7 +755,7 @@ public interface ModuleMXBean {
general, notably because it does not work well for MBeans that are
general, notably because it does not work well for MBeans that are
{@link NotificationBroadcaster}s.</p>
{@link NotificationBroadcaster}s.</p>
<h3
><a name="composite-map">Mappings for other types</a>
</h3>
<h3
id="composite-map">Mappings for other types
</h3>
<p>Given a Java class or interface <em>J</em> that does not match the other
<p>Given a Java class or interface <em>J</em> that does not match the other
rules in the table above, the MXBean framework will attempt to map
rules in the table above, the MXBean framework will attempt to map
...
@@ -1035,6 +1043,76 @@ public interface Node {
...
@@ -1035,6 +1043,76 @@ public interface Node {
}
}
</pre>
</pre>
<p>Alternatively, you can define a custom mapping for your recursive
type; see the next section.</p>
<h3 id="custom">Custom MXBean type mappings</h3>
<p>You can augment or replace the default type mappings described
above with custom mappings. An example appears in the
documentation for {@link MXBeanMapping}.</p>
<p>If an MXBean uses custom mappings, then an MXBean proxy for
that MXBean must use the same mappings for correct behavior.
This requires more careful synchronization between client and
server than is necessary with the default mappings. For example
it typically requires the client to have the same implementation
of any {@link MXBeanMapping} subclasses as the server. For this
reason, custom mappings should be avoided if possible.</p>
<p>Every MXBean has an associated {@link MXBeanMappingFactory}.
Call this <code><em>f</em></code>. Then every type that appears
in that MXBean has an associated {@link MXBeanMapping}
determined by <code><em>f</em></code>. If the type is
<code><em>J</em></code>, say, then the mapping is {@link
MXBeanMappingFactory#mappingForType
<em>f</em>.mappingForType}<code>(<em>J</em>,
<em>f</em>)</code>.</p>
<p>The {@code MXBeanMappingFactory} <code><em>f</em></code> for an
MXBean is determined as follows.</p>
<ul>
<li><p>If an {@link JMX.MBeanOptions} argument is supplied to
the {@link StandardMBean} constructor that makes an MXBean,
or to the {@link JMX#newMXBeanProxy JMX.newMXBeanProxy}
method, and the {@code MBeanOptions} object defines a non-null
{@code MXBeanMappingFactory}, then that is the value of
<code><em>f</em></code>.</p></li>
<li><p>Otherwise, if the MXBean interface has an {@link
MXBeanMappingFactoryClass} annotation, then that annotation
must identify a subclass of {@code MXBeanMappingFactory}
with a no-argument constructor. Then
<code><em>f</em></code> is the result of calling this
constructor. If the class does not have a no-argument
constructor, or if calling the constructor produces an
exception, then the MXBean is invalid and an attempt to
register it in the MBean Server will produce a {@link
NotCompliantMBeanException}.</p>
<p>This annotation is not inherited from any parent
interfaces. If an MXBean interface has this annotation,
then usually any MXBean subinterfaces must repeat the same
annotation for correct behavior.</p></li>
<li><p>Otherwise, if the package in which the MXBean interface
appears has an {@code MXBeanMappingFactoryClass} annotation,
then <code><em>f</em></code> is determined as if that
annotation appeared on the MXBean interface.</p></li>
<li><p>Otherwise, <code><em>f</em></code> is the default mapping
factory, {@link MXBeanMappingFactory#DEFAULT}.</p></li>
</ul>
<p>The default mapping factory recognizes the {@link
MXBeanMappingClass} annotation on a class or interface. If
<code><em>J</em></code> is a class or interface that has such an
annotation, then the {@code MXBeanMapping} for
<code><em>J</em></code> produced by the default mapping factory
will be determined by the value of the annotation as described
in its {@linkplain MXBeanMappingClass documentation}.</p>
<h3>MBeanInfo contents for an MXBean</h3>
<h3>MBeanInfo contents for an MXBean</h3>
<p>An MXBean is a type of Open MBean. However, for compatibility
<p>An MXBean is a type of Open MBean. However, for compatibility
...
@@ -1091,7 +1169,7 @@ public interface Node {
...
@@ -1091,7 +1169,7 @@ public interface Node {
{@code mxbean} whose value is the string "{@code true}".</p>
{@code mxbean} whose value is the string "{@code true}".</p>
<h3
><a name="type-names">Type Names</a>
</h3>
<h3
id="type-names">Type Names
</h3>
<p>Sometimes the unmapped type <em>T</em> of a method parameter or
<p>Sometimes the unmapped type <em>T</em> of a method parameter or
return value in an MXBean must be represented as a string. If
return value in an MXBean must be represented as a string. If
...
@@ -1163,6 +1241,8 @@ public interface Node {
...
@@ -1163,6 +1241,8 @@ public interface Node {
appropriate), or <em>C</em> is true of <em>e</em>.{@link
appropriate), or <em>C</em> is true of <em>e</em>.{@link
Throwable#getCause() getCause()}".</p>
Throwable#getCause() getCause()}".</p>
@see MXBeanMapping
@since 1.6
@since 1.6
*/
*/
...
...
src/share/classes/javax/management/MatchQueryExp.java
浏览文件 @
3e149c7f
...
@@ -109,36 +109,7 @@ class MatchQueryExp extends QueryEval implements QueryExp {
...
@@ -109,36 +109,7 @@ class MatchQueryExp extends QueryEval implements QueryExp {
* Returns the string representing the object
* Returns the string representing the object
*/
*/
public
String
toString
()
{
public
String
toString
()
{
return
exp
+
" like "
+
new
StringValueExp
(
likeTranslate
(
pattern
));
return
exp
+
" like "
+
new
StringValueExp
(
pattern
);
}
private
static
String
likeTranslate
(
String
s
)
{
StringBuilder
sb
=
new
StringBuilder
();
int
c
;
for
(
int
i
=
0
;
i
<
s
.
length
();
i
+=
Character
.
charCount
(
c
))
{
c
=
s
.
codePointAt
(
i
);
switch
(
c
)
{
case
'\\'
:
i
+=
Character
.
charCount
(
c
);
sb
.
append
(
'\\'
);
if
(
i
<
s
.
length
())
{
c
=
s
.
codePointAt
(
i
);
sb
.
appendCodePoint
(
c
);
}
break
;
case
'*'
:
sb
.
append
(
'%'
);
break
;
case
'?'
:
sb
.
append
(
'_'
);
break
;
case
'%'
:
sb
.
append
(
"\\%"
);
break
;
case
'_'
:
sb
.
append
(
"\\_"
);
break
;
default
:
sb
.
appendCodePoint
(
c
);
break
;
}
}
return
sb
.
toString
();
}
}
/*
/*
...
...
src/share/classes/javax/management/ObjectName.java
浏览文件 @
3e149c7f
...
@@ -1781,7 +1781,7 @@ public class ObjectName implements Comparable<ObjectName>, QueryExp {
...
@@ -1781,7 +1781,7 @@ public class ObjectName implements Comparable<ObjectName>, QueryExp {
}
}
String
toQueryString
()
{
String
toQueryString
()
{
return
"
LIKE
"
+
Query
.
value
(
toString
());
return
"
like
"
+
Query
.
value
(
toString
());
}
}
/**
/**
...
...
src/share/classes/javax/management/Query.java
浏览文件 @
3e149c7f
...
@@ -108,13 +108,13 @@ package javax.management;
...
@@ -108,13 +108,13 @@ package javax.management;
* <dd>Selects MBeans that have a {@code Status} attribute whose value
* <dd>Selects MBeans that have a {@code Status} attribute whose value
* is one of those three strings.
* is one of those three strings.
*
*
* <dt>{@code Message like 'OK:
%
'}
* <dt>{@code Message like 'OK:
*
'}
* <dd>Selects MBeans that have a {@code Message} attribute whose value
* <dd>Selects MBeans that have a {@code Message} attribute whose value
* is a string beginning with {@code "OK: "}. <b>Notice that the
* is a string beginning with {@code "OK: "}. <b>Notice that the
* wildcard characters are
SQL's ones.</b> In the query language
,
* wildcard characters are
not the ones that SQL uses.</b> In SQL
,
* {@code %} means "any sequence of characters" and {@code _}
* {@code %} means "any sequence of characters" and {@code _}
* means "any single character".
In the rest of the JMX API, these
* means "any single character".
Here, as in the rest of the JMX API,
*
correspond to {@code *} and {@code %
} respectively.
*
those are represented by {@code *} and {@code ?
} respectively.
*
*
* <dt>{@code instanceof 'javax.management.NotificationBroadcaster'}
* <dt>{@code instanceof 'javax.management.NotificationBroadcaster'}
* <dd>Selects MBeans that are instances of
* <dd>Selects MBeans that are instances of
...
@@ -319,11 +319,11 @@ package javax.management;
...
@@ -319,11 +319,11 @@ package javax.management;
*
*
* <tr><td><i>value</i> <b>LIKE</b> <i>stringLiteral</i>
* <tr><td><i>value</i> <b>LIKE</b> <i>stringLiteral</i>
* <td>{@link Query#match Query.match}(<i>q(value)</i>,
* <td>{@link Query#match Query.match}(<i>q(value)</i>,
* <i>
<a href="#translateWildcards">translateWildcards</a>(q(stringLiteral)
)</i>)
* <i>
q(stringLiteral
)</i>)
*
*
* <tr><td><i>value</i> <b>NOT LIKE</b> <i>stringLiteral</i>
* <tr><td><i>value</i> <b>NOT LIKE</b> <i>stringLiteral</i>
* <td>{@link Query#not Query.not}({@link Query#match Query.match}(<i>q(value)</i>,
* <td>{@link Query#not Query.not}({@link Query#match Query.match}(<i>q(value)</i>,
* <i>
<a href="#translateWildcards">translateWildcards</a>(q(stringLiteral)
)</i>))
* <i>
q(stringLiteral
)</i>))
*
*
* <tr><td><i>value1</i> <b>+</b> <i>value2</i>
* <tr><td><i>value1</i> <b>+</b> <i>value2</i>
* <td>{@link Query#plus Query.plus}(<i>q(value1)</i>, <i>q(value2)</i>)
* <td>{@link Query#plus Query.plus}(<i>q(value1)</i>, <i>q(value2)</i>)
...
@@ -360,13 +360,6 @@ package javax.management;
...
@@ -360,13 +360,6 @@ package javax.management;
* --><i>floatingPointLiteral</i>))
* --><i>floatingPointLiteral</i>))
* </table>
* </table>
*
*
* <p id="translateWildcards">Here, <i>translateWildcards</i> is a function
* that translates from the SQL notation for wildcards, using {@code %} and
* {@code _}, to the JMX API notation, using {@code *} and {@code ?}. If the
* <b>LIKE</b> string already contains {@code *} or {@code ?}, these characters
* have their literal meanings, and will be quoted in the call to
* {@link Query#match Query.match}.</p>
*
* @since 1.5
* @since 1.5
*/
*/
public
class
Query
extends
Object
{
public
class
Query
extends
Object
{
...
...
src/share/classes/javax/management/QueryNotificationFilter.java
浏览文件 @
3e149c7f
...
@@ -43,12 +43,6 @@ import java.util.Set;
...
@@ -43,12 +43,6 @@ import java.util.Set;
* on both the client and the server in the remote case, so using this class
* on both the client and the server in the remote case, so using this class
* instead is recommended where possible.</p>
* instead is recommended where possible.</p>
*
*
* <!-- <p>Because this class was introduced in version 2.0 of the JMX API,
* it may not be present on a remote JMX agent that is running an earlier
* version. The method {@link JMX#addListenerWithFilter JMX.addListenerWithFilter}
* can be used when you cannot be sure whether this class is present in the
* agent you are connecting to.</p> -->
*
* <p>This class uses the {@linkplain Query Query API} to specify the
* <p>This class uses the {@linkplain Query Query API} to specify the
* filtering logic. For example, to select only notifications where the
* filtering logic. For example, to select only notifications where the
* {@linkplain Notification#getType() type} is {@code "com.example.mytype"},
* {@linkplain Notification#getType() type} is {@code "com.example.mytype"},
...
...
src/share/classes/javax/management/QueryParser.java
浏览文件 @
3e149c7f
...
@@ -490,8 +490,7 @@ class QueryParser {
...
@@ -490,8 +490,7 @@ class QueryParser {
}
}
AttributeValueExp
alhs
=
(
AttributeValueExp
)
lhs
;
AttributeValueExp
alhs
=
(
AttributeValueExp
)
lhs
;
StringValueExp
sve
=
stringvalue
();
StringValueExp
sve
=
stringvalue
();
String
s
=
sve
.
getValue
();
q
=
Query
.
match
(
alhs
,
sve
);
q
=
Query
.
match
(
alhs
,
patternValueExp
(
s
));
break
;
break
;
}
}
...
@@ -624,40 +623,4 @@ class QueryParser {
...
@@ -624,40 +623,4 @@ class QueryParser {
throw
new
IllegalArgumentException
(
"Expected string: "
+
t
);
throw
new
IllegalArgumentException
(
"Expected string: "
+
t
);
return
Query
.
value
(
t
.
string
);
return
Query
.
value
(
t
.
string
);
}
}
// Convert the SQL pattern syntax, using % and _, to the Query.match
// syntax, using * and ?. The tricky part is recognizing \% and
// \_ as literal values, and also not replacing them inside [].
// But Query.match does not recognize \ inside [], which makes our
// job a tad easier.
private
StringValueExp
patternValueExp
(
String
s
)
{
int
c
;
for
(
int
i
=
0
;
i
<
s
.
length
();
i
+=
Character
.
charCount
(
c
))
{
c
=
s
.
codePointAt
(
i
);
switch
(
c
)
{
case
'\\'
:
i
++;
// i += Character.charCount(c), but we know it's 1!
if
(
i
>=
s
.
length
())
throw
new
IllegalArgumentException
(
"\\ at end of pattern"
);
break
;
case
'['
:
i
=
s
.
indexOf
(
']'
,
i
);
if
(
i
<
0
)
throw
new
IllegalArgumentException
(
"[ without ]"
);
break
;
case
'%'
:
s
=
s
.
substring
(
0
,
i
)
+
"*"
+
s
.
substring
(
i
+
1
);
break
;
case
'_'
:
s
=
s
.
substring
(
0
,
i
)
+
"?"
+
s
.
substring
(
i
+
1
);
break
;
case
'*'
:
case
'?'
:
s
=
s
.
substring
(
0
,
i
)
+
'\\'
+
(
char
)
c
+
s
.
substring
(
i
+
1
);
i
++;
break
;
}
}
return
Query
.
value
(
s
);
}
}
}
src/share/classes/javax/management/StandardMBean.java
浏览文件 @
3e149c7f
...
@@ -25,22 +25,19 @@
...
@@ -25,22 +25,19 @@
package
javax.management
;
package
javax.management
;
import
static
com
.
sun
.
jmx
.
defaults
.
JmxProperties
.
MISC_LOGGER
;
import
com.sun.jmx.mbeanserver.DescriptorCache
;
import
com.sun.jmx.mbeanserver.DescriptorCache
;
import
com.sun.jmx.mbeanserver.Introspector
;
import
com.sun.jmx.mbeanserver.Introspector
;
import
com.sun.jmx.mbeanserver.MBeanSupport
;
import
com.sun.jmx.mbeanserver.MBeanSupport
;
import
com.sun.jmx.mbeanserver.MXBeanSupport
;
import
com.sun.jmx.mbeanserver.MXBeanSupport
;
import
com.sun.jmx.mbeanserver.StandardMBeanSupport
;
import
com.sun.jmx.mbeanserver.StandardMBeanSupport
;
import
com.sun.jmx.mbeanserver.Util
;
import
com.sun.jmx.mbeanserver.Util
;
import
java.io.PrintWriter
;
import
java.io.StringWriter
;
import
java.security.AccessController
;
import
java.security.AccessController
;
import
java.security.PrivilegedAction
;
import
java.security.PrivilegedAction
;
import
java.util.HashMap
;
import
java.util.HashMap
;
import
java.util.Map
;
import
java.util.Map
;
import
java.util.WeakHashMap
;
import
java.util.WeakHashMap
;
import
java.util.logging.Level
;
import
java.util.logging.Level
;
import
javax.management.openmbean.MXBeanMappingFactory
;
import
javax.management.openmbean.OpenMBeanAttributeInfo
;
import
javax.management.openmbean.OpenMBeanAttributeInfo
;
import
javax.management.openmbean.OpenMBeanAttributeInfoSupport
;
import
javax.management.openmbean.OpenMBeanAttributeInfoSupport
;
import
javax.management.openmbean.OpenMBeanConstructorInfo
;
import
javax.management.openmbean.OpenMBeanConstructorInfo
;
...
@@ -50,6 +47,9 @@ import javax.management.openmbean.OpenMBeanOperationInfoSupport;
...
@@ -50,6 +47,9 @@ import javax.management.openmbean.OpenMBeanOperationInfoSupport;
import
javax.management.openmbean.OpenMBeanParameterInfo
;
import
javax.management.openmbean.OpenMBeanParameterInfo
;
import
javax.management.openmbean.OpenMBeanParameterInfoSupport
;
import
javax.management.openmbean.OpenMBeanParameterInfoSupport
;
import
static
com
.
sun
.
jmx
.
defaults
.
JmxProperties
.
MISC_LOGGER
;
import
static
javax
.
management
.
JMX
.
MBeanOptions
;
/**
/**
* <p>An MBean whose management interface is determined by reflection
* <p>An MBean whose management interface is determined by reflection
* on a Java interface.</p>
* on a Java interface.</p>
...
@@ -140,6 +140,11 @@ public class StandardMBean implements DynamicMBean, MBeanRegistration {
...
@@ -140,6 +140,11 @@ public class StandardMBean implements DynamicMBean, MBeanRegistration {
**/
**/
private
volatile
MBeanInfo
cachedMBeanInfo
;
private
volatile
MBeanInfo
cachedMBeanInfo
;
/**
* The MBeanOptions for this StandardMBean.
**/
private
MBeanOptions
options
;
/**
/**
* Make a DynamicMBean out of <var>implementation</var>, using the
* Make a DynamicMBean out of <var>implementation</var>, using the
* specified <var>mbeanInterface</var> class.
* specified <var>mbeanInterface</var> class.
...
@@ -155,12 +160,14 @@ public class StandardMBean implements DynamicMBean, MBeanRegistration {
...
@@ -155,12 +160,14 @@ public class StandardMBean implements DynamicMBean, MBeanRegistration {
* implementation is allowed. If null implementation is allowed,
* implementation is allowed. If null implementation is allowed,
* and a null implementation is passed, then the implementation
* and a null implementation is passed, then the implementation
* is assumed to be <var>this</var>.
* is assumed to be <var>this</var>.
* @param options MBeanOptions to apply to this instance.
* @exception IllegalArgumentException if the given
* @exception IllegalArgumentException if the given
* <var>implementation</var> is null, and null is not allowed.
* <var>implementation</var> is null, and null is not allowed.
**/
**/
@SuppressWarnings
(
"unchecked"
)
// cast to T
private
<
T
>
void
construct
(
T
implementation
,
Class
<
T
>
mbeanInterface
,
private
<
T
>
void
construct
(
T
implementation
,
Class
<
T
>
mbeanInterface
,
boolean
nullImplementationAllowed
,
boolean
nullImplementationAllowed
,
boolean
isMXBean
)
MBeanOptions
options
)
throws
NotCompliantMBeanException
{
throws
NotCompliantMBeanException
{
if
(
implementation
==
null
)
{
if
(
implementation
==
null
)
{
// Have to use (T)this rather than mbeanInterface.cast(this)
// Have to use (T)this rather than mbeanInterface.cast(this)
...
@@ -169,20 +176,23 @@ public class StandardMBean implements DynamicMBean, MBeanRegistration {
...
@@ -169,20 +176,23 @@ public class StandardMBean implements DynamicMBean, MBeanRegistration {
implementation
=
Util
.<
T
>
cast
(
this
);
implementation
=
Util
.<
T
>
cast
(
this
);
else
throw
new
IllegalArgumentException
(
"implementation is null"
);
else
throw
new
IllegalArgumentException
(
"implementation is null"
);
}
}
if
(
isMXBean
)
{
if
(
options
==
null
)
if
(
mbeanInterface
==
null
)
{
options
=
new
MBeanOptions
();
mbeanInterface
=
Util
.
cast
(
Introspector
.
getMXBeanInterface
(
MXBeanMappingFactory
mappingFactory
=
options
.
getMXBeanMappingFactory
();
implementation
.
getClass
()));
boolean
mx
=
(
mappingFactory
!=
null
);
}
if
(
mbeanInterface
==
null
)
{
this
.
mbean
=
new
MXBeanSupport
(
implementation
,
mbeanInterface
);
mbeanInterface
=
Util
.
cast
(
Introspector
.
getStandardOrMXBeanInterface
(
implementation
.
getClass
(),
mx
));
}
if
(
mx
)
{
this
.
mbean
=
new
MXBeanSupport
(
implementation
,
mbeanInterface
,
mappingFactory
);
}
else
{
}
else
{
if
(
mbeanInterface
==
null
)
{
mbeanInterface
=
Util
.
cast
(
Introspector
.
getStandardMBeanInterface
(
implementation
.
getClass
()));
}
this
.
mbean
=
this
.
mbean
=
new
StandardMBeanSupport
(
implementation
,
mbeanInterface
);
new
StandardMBeanSupport
(
implementation
,
mbeanInterface
);
}
}
this
.
options
=
options
.
canonical
();
}
}
/**
/**
...
@@ -211,14 +221,14 @@ public class StandardMBean implements DynamicMBean, MBeanRegistration {
...
@@ -211,14 +221,14 @@ public class StandardMBean implements DynamicMBean, MBeanRegistration {
**/
**/
public
<
T
>
StandardMBean
(
T
implementation
,
Class
<
T
>
mbeanInterface
)
public
<
T
>
StandardMBean
(
T
implementation
,
Class
<
T
>
mbeanInterface
)
throws
NotCompliantMBeanException
{
throws
NotCompliantMBeanException
{
construct
(
implementation
,
mbeanInterface
,
false
,
false
);
construct
(
implementation
,
mbeanInterface
,
false
,
null
);
}
}
/**
/**
* <p>Make a DynamicMBean out of <var>this</var>, using the specified
* <p>Make a DynamicMBean out of <var>this</var>, using the specified
* <var>mbeanInterface</var> class.</p>
* <var>mbeanInterface</var> class.</p>
*
*
* <p>Call {@link #StandardMBean(java.lang.Object, java.lang.Class)
* <p>Call
s
{@link #StandardMBean(java.lang.Object, java.lang.Class)
* this(this,mbeanInterface)}.
* this(this,mbeanInterface)}.
* This constructor is reserved to subclasses.</p>
* This constructor is reserved to subclasses.</p>
*
*
...
@@ -231,13 +241,14 @@ public class StandardMBean implements DynamicMBean, MBeanRegistration {
...
@@ -231,13 +241,14 @@ public class StandardMBean implements DynamicMBean, MBeanRegistration {
**/
**/
protected
StandardMBean
(
Class
<?>
mbeanInterface
)
protected
StandardMBean
(
Class
<?>
mbeanInterface
)
throws
NotCompliantMBeanException
{
throws
NotCompliantMBeanException
{
construct
(
null
,
mbeanInterface
,
true
,
false
);
construct
(
null
,
mbeanInterface
,
true
,
null
);
}
}
/**
/**
* <p>Make a DynamicMBean out of the object
* <p>Make a DynamicMBean out of the object
* <var>implementation</var>, using the specified
* <var>implementation</var>, using the specified
* <var>mbeanInterface</var> class. This constructor can be used
* <var>mbeanInterface</var> class, and choosing whether the
* resultant MBean is an MXBean. This constructor can be used
* to make either Standard MBeans or MXBeans. Unlike the
* to make either Standard MBeans or MXBeans. Unlike the
* constructor {@link #StandardMBean(Object, Class)}, it
* constructor {@link #StandardMBean(Object, Class)}, it
* does not throw NotCompliantMBeanException.</p>
* does not throw NotCompliantMBeanException.</p>
...
@@ -267,7 +278,17 @@ public class StandardMBean implements DynamicMBean, MBeanRegistration {
...
@@ -267,7 +278,17 @@ public class StandardMBean implements DynamicMBean, MBeanRegistration {
public
<
T
>
StandardMBean
(
T
implementation
,
Class
<
T
>
mbeanInterface
,
public
<
T
>
StandardMBean
(
T
implementation
,
Class
<
T
>
mbeanInterface
,
boolean
isMXBean
)
{
boolean
isMXBean
)
{
try
{
try
{
construct
(
implementation
,
mbeanInterface
,
false
,
isMXBean
);
MBeanOptions
opts
=
new
MBeanOptions
();
if
(
mbeanInterface
==
null
)
{
mbeanInterface
=
Util
.
cast
(
Introspector
.
getStandardOrMXBeanInterface
(
implementation
.
getClass
(),
isMXBean
));
}
if
(
isMXBean
)
{
MXBeanMappingFactory
f
=
MXBeanMappingFactory
.
forInterface
(
mbeanInterface
);
opts
.
setMXBeanMappingFactory
(
f
);
}
construct
(
implementation
,
mbeanInterface
,
false
,
opts
);
}
catch
(
NotCompliantMBeanException
e
)
{
}
catch
(
NotCompliantMBeanException
e
)
{
throw
new
IllegalArgumentException
(
e
);
throw
new
IllegalArgumentException
(
e
);
}
}
...
@@ -275,12 +296,13 @@ public class StandardMBean implements DynamicMBean, MBeanRegistration {
...
@@ -275,12 +296,13 @@ public class StandardMBean implements DynamicMBean, MBeanRegistration {
/**
/**
* <p>Make a DynamicMBean out of <var>this</var>, using the specified
* <p>Make a DynamicMBean out of <var>this</var>, using the specified
* <var>mbeanInterface</var> class. This constructor can be used
* <var>mbeanInterface</var> class, and choosing whether the resulting
* MBean is an MXBean. This constructor can be used
* to make either Standard MBeans or MXBeans. Unlike the
* to make either Standard MBeans or MXBeans. Unlike the
* constructor {@link #StandardMBean(Object, Class)}, it
* constructor {@link #StandardMBean(Object, Class)}, it
* does not throw NotCompliantMBeanException.</p>
* does not throw NotCompliantMBeanException.</p>
*
*
* <p>Call {@link #StandardMBean(java.lang.Object, java.lang.Class, boolean)
* <p>Call
s
{@link #StandardMBean(java.lang.Object, java.lang.Class, boolean)
* this(this, mbeanInterface, isMXBean)}.
* this(this, mbeanInterface, isMXBean)}.
* This constructor is reserved to subclasses.</p>
* This constructor is reserved to subclasses.</p>
*
*
...
@@ -297,7 +319,77 @@ public class StandardMBean implements DynamicMBean, MBeanRegistration {
...
@@ -297,7 +319,77 @@ public class StandardMBean implements DynamicMBean, MBeanRegistration {
**/
**/
protected
StandardMBean
(
Class
<?>
mbeanInterface
,
boolean
isMXBean
)
{
protected
StandardMBean
(
Class
<?>
mbeanInterface
,
boolean
isMXBean
)
{
try
{
try
{
construct
(
null
,
mbeanInterface
,
true
,
isMXBean
);
MBeanOptions
opts
=
new
MBeanOptions
();
if
(
mbeanInterface
==
null
)
{
mbeanInterface
=
Introspector
.
getStandardOrMXBeanInterface
(
getClass
(),
isMXBean
);
}
if
(
isMXBean
)
{
MXBeanMappingFactory
f
=
MXBeanMappingFactory
.
forInterface
(
mbeanInterface
);
opts
.
setMXBeanMappingFactory
(
f
);
}
construct
(
null
,
mbeanInterface
,
true
,
opts
);
}
catch
(
NotCompliantMBeanException
e
)
{
throw
new
IllegalArgumentException
(
e
);
}
}
/**
* <p>Make a DynamicMBean out of the object
* <var>implementation</var>, using the specified
* <var>mbeanInterface</var> class and the specified options.</p>
*
* @param implementation The implementation of this MBean.
* @param mbeanInterface The Management Interface exported by this
* MBean's implementation. If <code>null</code>, then this
* object will use standard JMX design pattern to determine
* the management interface associated with the given
* implementation.
* @param options MBeanOptions that control the operation of the resulting
* MBean, as documented in the {@link MBeanOptions} class.
* @param <T> Allows the compiler to check
* that {@code implementation} does indeed implement the class
* described by {@code mbeanInterface}. The compiler can only
* check this if {@code mbeanInterface} is a class literal such
* as {@code MyMBean.class}.
*
* @exception IllegalArgumentException if the given
* <var>implementation</var> is null, or if the <var>mbeanInterface</var>
* does not follow JMX design patterns for Management Interfaces, or
* if the given <var>implementation</var> does not implement the
* specified interface.
**/
public
<
T
>
StandardMBean
(
T
implementation
,
Class
<
T
>
mbeanInterface
,
MBeanOptions
options
)
{
try
{
construct
(
implementation
,
mbeanInterface
,
false
,
options
);
}
catch
(
NotCompliantMBeanException
e
)
{
throw
new
IllegalArgumentException
(
e
);
}
}
/**
* <p>Make a DynamicMBean out of <var>this</var>, using the specified
* <var>mbeanInterface</var> class and the specified options.</p>
*
* <p>Calls {@link #StandardMBean(Object, Class, JMX.MBeanOptions)
* this(this,mbeanInterface,options)}.
* This constructor is reserved to subclasses.</p>
*
* @param mbeanInterface The Management Interface exported by this
* MBean.
* @param options MBeanOptions that control the operation of the resulting
* MBean, as documented in the {@link MBeanOptions} class.
*
* @exception IllegalArgumentException if the <var>mbeanInterface</var>
* does not follow JMX design patterns for Management Interfaces, or
* if <var>this</var> does not implement the specified interface.
**/
protected
StandardMBean
(
Class
<?>
mbeanInterface
,
MBeanOptions
options
)
{
try
{
construct
(
null
,
mbeanInterface
,
true
,
options
);
}
catch
(
NotCompliantMBeanException
e
)
{
}
catch
(
NotCompliantMBeanException
e
)
{
throw
new
IllegalArgumentException
(
e
);
throw
new
IllegalArgumentException
(
e
);
}
}
...
@@ -326,13 +418,19 @@ public class StandardMBean implements DynamicMBean, MBeanRegistration {
...
@@ -326,13 +418,19 @@ public class StandardMBean implements DynamicMBean, MBeanRegistration {
if
(
implementation
==
null
)
if
(
implementation
==
null
)
throw
new
IllegalArgumentException
(
"implementation is null"
);
throw
new
IllegalArgumentException
(
"implementation is null"
);
setImplementation2
(
implementation
);
}
if
(
isMXBean
())
{
private
<
T
>
void
setImplementation2
(
T
implementation
)
throws
NotCompliantMBeanException
{
Class
<?
super
T
>
intf
=
Util
.
cast
(
getMBeanInterface
());
if
(
this
.
mbean
.
isMXBean
())
{
this
.
mbean
=
new
MXBeanSupport
(
implementation
,
this
.
mbean
=
new
MXBeanSupport
(
implementation
,
Util
.<
Class
<
Object
>>
cast
(
getMBeanInterface
()));
intf
,
options
.
getMXBeanMappingFactory
());
}
else
{
}
else
{
this
.
mbean
=
new
StandardMBeanSupport
(
implementation
,
this
.
mbean
=
new
StandardMBeanSupport
(
implementation
,
intf
);
Util
.<
Class
<
Object
>>
cast
(
getMBeanInterface
()));
}
}
}
}
...
@@ -362,6 +460,19 @@ public class StandardMBean implements DynamicMBean, MBeanRegistration {
...
@@ -362,6 +460,19 @@ public class StandardMBean implements DynamicMBean, MBeanRegistration {
return
mbean
.
getResource
().
getClass
();
return
mbean
.
getResource
().
getClass
();
}
}
/**
* Return the MBeanOptions that were specified or implied for this StandardMBean
* instance. If an MBeanOptions object was supplied when this StandardMBean
* instance was constructed, and if that object has not been modified in the
* meantime, then the returned object will be equal to that object, although
* it might not be the same object.
* @return The MBeanOptions that were specified or implied for this StandardMBean
* instance.
*/
public
MBeanOptions
getOptions
()
{
return
options
.
uncanonical
();
}
// ------------------------------------------------------------------
// ------------------------------------------------------------------
// From the DynamicMBean interface.
// From the DynamicMBean interface.
// ------------------------------------------------------------------
// ------------------------------------------------------------------
...
@@ -726,7 +837,7 @@ public class StandardMBean implements DynamicMBean, MBeanRegistration {
...
@@ -726,7 +837,7 @@ public class StandardMBean implements DynamicMBean, MBeanRegistration {
* @return the MBeanNotificationInfo[] for the new MBeanInfo.
* @return the MBeanNotificationInfo[] for the new MBeanInfo.
**/
**/
MBeanNotificationInfo
[]
getNotifications
(
MBeanInfo
info
)
{
MBeanNotificationInfo
[]
getNotifications
(
MBeanInfo
info
)
{
return
null
;
return
info
.
getNotifications
()
;
}
}
/**
/**
...
@@ -1234,5 +1345,4 @@ public class StandardMBean implements DynamicMBean, MBeanRegistration {
...
@@ -1234,5 +1345,4 @@ public class StandardMBean implements DynamicMBean, MBeanRegistration {
return
true
;
return
true
;
}
}
}
}
}
}
src/share/classes/javax/management/openmbean/CompositeDataInvocationHandler.java
浏览文件 @
3e149c7f
...
@@ -26,7 +26,7 @@
...
@@ -26,7 +26,7 @@
package
javax.management.openmbean
;
package
javax.management.openmbean
;
import
com.sun.jmx.mbeanserver.MXBeanLookup
;
import
com.sun.jmx.mbeanserver.MXBeanLookup
;
import
com.sun.jmx.mbeanserver.
OpenConverter
;
import
com.sun.jmx.mbeanserver.
DefaultMXBeanMappingFactory
;
import
java.lang.reflect.InvocationHandler
;
import
java.lang.reflect.InvocationHandler
;
import
java.lang.reflect.Method
;
import
java.lang.reflect.Method
;
import
java.lang.reflect.Proxy
;
import
java.lang.reflect.Proxy
;
...
@@ -115,7 +115,12 @@ public class CompositeDataInvocationHandler implements InvocationHandler {
...
@@ -115,7 +115,12 @@ public class CompositeDataInvocationHandler implements InvocationHandler {
is null.
is null.
*/
*/
public
CompositeDataInvocationHandler
(
CompositeData
compositeData
)
{
public
CompositeDataInvocationHandler
(
CompositeData
compositeData
)
{
this
(
compositeData
,
null
);
this
(
compositeData
,
MXBeanMappingFactory
.
DEFAULT
);
}
public
CompositeDataInvocationHandler
(
CompositeData
compositeData
,
MXBeanMappingFactory
mappingFactory
)
{
this
(
compositeData
,
mappingFactory
,
null
);
}
}
/**
/**
...
@@ -134,11 +139,13 @@ public class CompositeDataInvocationHandler implements InvocationHandler {
...
@@ -134,11 +139,13 @@ public class CompositeDataInvocationHandler implements InvocationHandler {
is null.
is null.
*/
*/
CompositeDataInvocationHandler
(
CompositeData
compositeData
,
CompositeDataInvocationHandler
(
CompositeData
compositeData
,
MXBeanMappingFactory
mappingFactory
,
MXBeanLookup
lookup
)
{
MXBeanLookup
lookup
)
{
if
(
compositeData
==
null
)
if
(
compositeData
==
null
)
throw
new
IllegalArgumentException
(
"compositeData"
);
throw
new
IllegalArgumentException
(
"compositeData"
);
this
.
compositeData
=
compositeData
;
this
.
compositeData
=
compositeData
;
this
.
lookup
=
lookup
;
this
.
lookup
=
lookup
;
this
.
mappingFactory
=
mappingFactory
;
}
}
/**
/**
...
@@ -176,7 +183,7 @@ public class CompositeDataInvocationHandler implements InvocationHandler {
...
@@ -176,7 +183,7 @@ public class CompositeDataInvocationHandler implements InvocationHandler {
}
}
}
}
String
propertyName
=
OpenConverter
.
propertyName
(
method
);
String
propertyName
=
DefaultMXBeanMappingFactory
.
propertyName
(
method
);
if
(
propertyName
==
null
)
{
if
(
propertyName
==
null
)
{
throw
new
IllegalArgumentException
(
"Method is not getter: "
+
throw
new
IllegalArgumentException
(
"Method is not getter: "
+
method
.
getName
());
method
.
getName
());
...
@@ -185,7 +192,7 @@ public class CompositeDataInvocationHandler implements InvocationHandler {
...
@@ -185,7 +192,7 @@ public class CompositeDataInvocationHandler implements InvocationHandler {
if
(
compositeData
.
containsKey
(
propertyName
))
if
(
compositeData
.
containsKey
(
propertyName
))
openValue
=
compositeData
.
get
(
propertyName
);
openValue
=
compositeData
.
get
(
propertyName
);
else
{
else
{
String
decap
=
OpenConverter
.
decapitalize
(
propertyName
);
String
decap
=
DefaultMXBeanMappingFactory
.
decapitalize
(
propertyName
);
if
(
compositeData
.
containsKey
(
decap
))
if
(
compositeData
.
containsKey
(
decap
))
openValue
=
compositeData
.
get
(
decap
);
openValue
=
compositeData
.
get
(
decap
);
else
{
else
{
...
@@ -196,9 +203,10 @@ public class CompositeDataInvocationHandler implements InvocationHandler {
...
@@ -196,9 +203,10 @@ public class CompositeDataInvocationHandler implements InvocationHandler {
throw
new
IllegalArgumentException
(
msg
);
throw
new
IllegalArgumentException
(
msg
);
}
}
}
}
OpenConverter
converter
=
MXBeanMapping
mapping
=
OpenConverter
.
toConverter
(
method
.
getGenericReturnType
());
mappingFactory
.
mappingForType
(
method
.
getGenericReturnType
(),
return
converter
.
fromOpenValue
(
lookup
,
openValue
);
MXBeanMappingFactory
.
DEFAULT
);
return
mapping
.
fromOpenValue
(
openValue
);
}
}
/* This method is called when equals(Object) is
/* This method is called when equals(Object) is
...
@@ -242,4 +250,5 @@ public class CompositeDataInvocationHandler implements InvocationHandler {
...
@@ -242,4 +250,5 @@ public class CompositeDataInvocationHandler implements InvocationHandler {
private
final
CompositeData
compositeData
;
private
final
CompositeData
compositeData
;
private
final
MXBeanLookup
lookup
;
private
final
MXBeanLookup
lookup
;
private
final
MXBeanMappingFactory
mappingFactory
;
}
}
src/share/classes/javax/management/openmbean/CompositeType.java
浏览文件 @
3e149c7f
...
@@ -159,8 +159,8 @@ public class CompositeType extends OpenType<CompositeData> {
...
@@ -159,8 +159,8 @@ public class CompositeType extends OpenType<CompositeData> {
}
}
private
static
void
checkForNullElement
(
Object
[]
arg
,
String
argName
)
{
private
static
void
checkForNullElement
(
Object
[]
arg
,
String
argName
)
{
if
(
(
arg
==
null
)
||
(
arg
.
length
==
0
)
)
{
if
(
arg
==
null
)
{
throw
new
IllegalArgumentException
(
"Argument "
+
argName
+
"[] cannot be null
or empty
."
);
throw
new
IllegalArgumentException
(
"Argument "
+
argName
+
"[] cannot be null."
);
}
}
for
(
int
i
=
0
;
i
<
arg
.
length
;
i
++)
{
for
(
int
i
=
0
;
i
<
arg
.
length
;
i
++)
{
if
(
arg
[
i
]
==
null
)
{
if
(
arg
[
i
]
==
null
)
{
...
...
src/share/classes/javax/management/openmbean/MXBeanMapping.java
0 → 100644
浏览文件 @
3e149c7f
/*
* Copyright 2007 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package
javax.management.openmbean
;
import
java.io.InvalidObjectException
;
import
java.lang.reflect.Type
;
/**
* <p>A custom mapping between Java types and Open types for use in MXBeans.
* To define such a mapping, subclass this class and define at least the
* {@link #fromOpenValue fromOpenValue} and {@link #toOpenValue toOpenValue}
* methods, and optionally the {@link #checkReconstructible} method.
* Then either use an {@link MXBeanMappingClass} annotation on your custom
* Java types, or include this MXBeanMapping in an
* {@link MXBeanMappingFactory}.</p>
*
* <p>For example, suppose we have a class {@code MyLinkedList}, which looks
* like this:</p>
*
* <pre>
* public class MyLinkedList {
* public MyLinkedList(String name, MyLinkedList next) {...}
* public String getName() {...}
* public MyLinkedList getNext() {...}
* }
* </pre>
*
* <p>This is not a valid type for MXBeans, because it contains a
* self-referential property "next" defined by the {@code getNext()}
* method. MXBeans do not support recursive types. So we would like
* to specify a mapping for {@code MyLinkedList} explicitly. When an
* MXBean interface contains {@code MyLinkedList}, that will be mapped
* into a {@code String[]}, which is a valid Open Type.</p>
*
* <p>To define this mapping, we first subclass {@code MXBeanMapping}:</p>
*
* <pre>
* public class MyLinkedListMapping extends MXBeanMapping {
* public MyLinkedListMapping(Type type) throws OpenDataException {
* super(MyLinkedList.class, ArrayType.getArrayType(SimpleType.STRING));
* if (type != MyLinkedList.class)
* throw new OpenDataException("Mapping only valid for MyLinkedList");
* }
*
* {@literal @Override}
* public Object fromOpenValue(Object openValue) throws InvalidObjectException {
* String[] array = (String[]) openValue;
* MyLinkedList list = null;
* for (int i = array.length - 1; i >= 0; i--)
* list = new MyLinkedList(array[i], list);
* return list;
* }
*
* {@literal @Override}
* public Object toOpenValue(Object javaValue) throws OpenDataException {
* ArrayList<String> array = new ArrayList<String>();
* for (MyLinkedList list = (MyLinkedList) javaValue; list != null;
* list = list.getNext())
* array.add(list.getName());
* return array.toArray(new String[0]);
* }
* }
* </pre>
*
* <p>The call to the superclass constructor specifies what the
* original Java type is ({@code MyLinkedList.class}) and what Open
* Type it is mapped to ({@code
* ArrayType.getArrayType(SimpleType.STRING)}). The {@code
* fromOpenValue} method says how we go from the Open Type ({@code
* String[]}) to the Java type ({@code MyLinkedList}), and the {@code
* toOpenValue} method says how we go from the Java type to the Open
* Type.</p>
*
* <p>With this mapping defined, we can annotate the {@code MyLinkedList}
* class appropriately:</p>
*
* <pre>
* {@literal @MXBeanMappingClass}(MyLinkedListMapping.class)
* public class MyLinkedList {...}
* </pre>
*
* <p>Now we can use {@code MyLinkedList} in an MXBean interface and it
* will work.</p>
*
* <p>If we are unable to modify the {@code MyLinkedList} class,
* we can define an {@link MXBeanMappingFactory}. See the documentation
* of that class for further details.</p>
*/
public
abstract
class
MXBeanMapping
{
private
final
Type
javaType
;
private
final
OpenType
<?>
openType
;
private
final
Class
<?>
openClass
;
/**
* <p>Construct a mapping between the given Java type and the given
* Open Type.</p>
*
* @param javaType the Java type (for example, {@code MyLinkedList}).
* @param openType the Open Type (for example, {@code
* ArrayType.getArrayType(SimpleType.STRING)})
*
* @throws NullPointerException if either argument is null.
*/
protected
MXBeanMapping
(
Type
javaType
,
OpenType
<?>
openType
)
{
if
(
javaType
==
null
||
openType
==
null
)
throw
new
NullPointerException
(
"Null argument"
);
this
.
javaType
=
javaType
;
this
.
openType
=
openType
;
this
.
openClass
=
makeOpenClass
(
javaType
,
openType
);
}
/**
* <p>The Java type that was supplied to the constructor.</p>
* @return the Java type that was supplied to the constructor.
*/
public
final
Type
getJavaType
()
{
return
javaType
;
}
/**
* <p>The Open Type that was supplied to the constructor.</p>
* @return the Open Type that was supplied to the constructor.
*/
public
final
OpenType
<?>
getOpenType
()
{
return
openType
;
}
/**
* <p>The Java class that corresponds to instances of the
* {@linkplain #getOpenType() Open Type} for this mapping.</p>
* @return the Java class that corresponds to instances of the
* Open Type for this mapping.
* @see OpenType#getClassName
*/
public
final
Class
<?>
getOpenClass
()
{
return
openClass
;
}
private
static
Class
<?>
makeOpenClass
(
Type
javaType
,
OpenType
<?>
openType
)
{
if
(
javaType
instanceof
Class
<?>
&&
((
Class
<?>)
javaType
).
isPrimitive
())
return
(
Class
<?>)
javaType
;
try
{
String
className
=
OpenType
.
validClassName
(
openType
.
getClassName
());
return
Class
.
forName
(
className
,
false
,
null
);
}
catch
(
ClassNotFoundException
e
)
{
throw
new
RuntimeException
(
e
);
// should not happen
}
catch
(
OpenDataException
e
)
{
throw
new
IllegalArgumentException
(
"Bad OpenType: "
+
openType
,
e
);
}
}
/**
* <p>Convert an instance of the Open Type into the Java type.
* @param openValue the value to be converted.
* @return the converted value.
* @throws InvalidObjectException if the value cannot be converted.
*/
public
abstract
Object
fromOpenValue
(
Object
openValue
)
throws
InvalidObjectException
;
/**
* <p>Convert an instance of the Java type into the Open Type.
* @param javaValue the value to be converted.
* @return the converted value.
* @throws OpenDataException if the value cannot be converted.
*/
public
abstract
Object
toOpenValue
(
Object
javaValue
)
throws
OpenDataException
;
/**
* <p>Throw an appropriate InvalidObjectException if we will not
* be able to convert back from the open data to the original Java
* object. The {@link #fromOpenValue fromOpenValue} throws an
* exception if a given open data value cannot be converted. This
* method throws an exception if <em>no</em> open data values can
* be converted. The default implementation of this method never
* throws an exception. Subclasses can override it as
* appropriate.</p>
* @throws InvalidObjectException if {@code fromOpenValue} will throw
* an exception no matter what its argument is.
*/
public
void
checkReconstructible
()
throws
InvalidObjectException
{}
}
src/share/classes/javax/management/openmbean/MXBeanMappingClass.java
0 → 100644
浏览文件 @
3e149c7f
/*
* Copyright 2007 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package
javax.management.openmbean
;
import
java.lang.annotation.Documented
;
import
java.lang.annotation.ElementType
;
import
java.lang.annotation.Inherited
;
import
java.lang.annotation.Retention
;
import
java.lang.annotation.RetentionPolicy
;
import
java.lang.annotation.Target
;
import
javax.management.NotCompliantMBeanException
;
/**
* Specifies the MXBean mapping to be used for this Java type.
* @see MXBeanMapping
*/
@Retention
(
RetentionPolicy
.
RUNTIME
)
@Target
(
ElementType
.
TYPE
)
@Documented
@Inherited
public
@interface
MXBeanMappingClass
{
/**
* <p>The {@link MXBeanMapping} class to be used to map the
* annotated type. This class must have a public constructor with
* a single argument of type {@link java.lang.reflect.Type}. The
* constructor will be called with the annotated type as an
* argument. See the {@code MXBeanMapping} documentation
* for an example.</p>
*
* <p>If the {@code MXBeanMapping} cannot in fact handle that
* type, the constructor should throw an {@link
* OpenDataException}. If the constructor throws this or any other
* exception then an MXBean in which the annotated type appears is
* invalid, and registering it in the MBean Server will produce a
* {@link NotCompliantMBeanException}.
*/
public
Class
<?
extends
MXBeanMapping
>
value
();
}
src/share/classes/javax/management/openmbean/MXBeanMappingFactory.java
0 → 100644
浏览文件 @
3e149c7f
/*
* Copyright 2007 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package
javax.management.openmbean
;
import
com.sun.jmx.mbeanserver.DefaultMXBeanMappingFactory
;
import
java.lang.reflect.Type
;
/**
* <p>Defines how types are mapped for a given MXBean or set of MXBeans.
* An {@code MXBeanMappingFactory} can be specified either through the
* {@link MXBeanMappingFactoryClass} annotation, or through the
* {@link javax.management.JMX.MBeanOptions JMX.MBeanOptions} argument to a
* {@link javax.management.StandardMBean StandardMBean} constructor or MXBean
* proxy.</p>
*
* <p>An {@code MXBeanMappingFactory} must return an {@code MXBeanMapping}
* for any Java type that appears in the MXBeans that the factory is being
* used for. Usually it does that by handling any custom types, and
* forwarding everything else to the {@linkplain #DEFAULT default mapping
* factory}.</p>
*
* <p>Consider the {@code MyLinkedList} example from the {@link MXBeanMapping}
* documentation. If we are unable to change the {@code MyLinkedList} class
* to add an {@link MXBeanMappingClass} annotation, we could achieve the same
* effect by defining {@code MyLinkedListMappingFactory} as follows:</p>
*
* <pre>
* public class MyLinkedListMappingFactory implements MXBeanMappingFactory {
* public MyLinkedListMappingFactory() {}
*
* public MXBeanMapping mappingForType(Type t, MXBeanMappingFactory f)
* throws OpenDataException {
* if (t == MyLinkedList.class)
* return new MyLinkedListMapping(t);
* else
* return MXBeanMappingFactory.DEFAULT.mappingForType(t, f);
* }
* }
* </pre>
*
* <p>The mapping factory handles only the {@code MyLinkedList} class.
* Every other type is forwarded to the default mapping factory.
* This includes types such as {@code MyLinkedList[]} and
* {@code List<MyLinkedList>}; the default mapping factory will recursively
* invoke {@code MyLinkedListMappingFactory} to map the contained
* {@code MyLinkedList} type.</p>
*
* <p>Once we have defined {@code MyLinkedListMappingFactory}, we can use
* it in an MXBean interface like this:</p>
*
* <pre>
* {@literal @MXBeanMappingFactoryClass}(MyLinkedListMappingFactory.class)
* public interface SomethingMXBean {
* public MyLinkedList getSomething();
* }
* </pre>
*
* <p>Alternatively we can annotate the package that {@code SomethingMXBean}
* appears in, or we can supply the factory to a {@link
* javax.management.StandardMBean StandardMBean} constructor or MXBean
* proxy.</p>
*/
public
abstract
class
MXBeanMappingFactory
{
/**
* <p>Construct an instance of this class.</p>
*/
protected
MXBeanMappingFactory
()
{}
/**
* <p>Mapping factory that applies the default rules for MXBean
* mappings, as described in the <a
* href="../MXBean.html#MXBean-spec">MXBean specification</a>.</p>
*/
public
static
final
MXBeanMappingFactory
DEFAULT
=
new
DefaultMXBeanMappingFactory
();
/**
* <p>Determine the appropriate MXBeanMappingFactory to use for the given
* MXBean interface, based on its annotations. If the interface has an
* {@link MXBeanMappingFactoryClass @MXBeanMappingFactoryClass} annotation,
* that is used to determine the MXBeanMappingFactory. Otherwise, if the
* package containing the interface has such an annotation, that is used.
* Otherwise the MXBeanMappingFactory is the {@linkplain #DEFAULT default}
* one.</p>
*
* @param intf the MXBean interface for which to determine the
* MXBeanMappingFactory.
*
* @return the MXBeanMappingFactory for the given MXBean interface.
*
* @throws IllegalArgumentException if {@code intf} is null, or if an
* exception occurs while trying constructing an MXBeanMappingFactory
* based on an annotation. In the second case, the exception will appear
* in the {@linkplain Throwable#getCause() cause chain} of the
* {@code IllegalArgumentException}.
*/
public
static
MXBeanMappingFactory
forInterface
(
Class
<?>
intf
)
{
if
(
intf
==
null
)
throw
new
IllegalArgumentException
(
"Null interface"
);
MXBeanMappingFactoryClass
annot
=
intf
.
getAnnotation
(
MXBeanMappingFactoryClass
.
class
);
if
(
annot
==
null
)
{
Package
p
=
intf
.
getPackage
();
if
(
p
!=
null
)
annot
=
p
.
getAnnotation
(
MXBeanMappingFactoryClass
.
class
);
}
if
(
annot
==
null
)
return
MXBeanMappingFactory
.
DEFAULT
;
Class
<?
extends
MXBeanMappingFactory
>
factoryClass
=
annot
.
value
();
try
{
return
annot
.
value
().
newInstance
();
}
catch
(
Exception
e
)
{
throw
new
IllegalArgumentException
(
"Could not instantiate MXBeanMappingFactory "
+
factoryClass
.
getName
()
+
" from @MXBeanMappingFactoryClass"
,
e
);
}
}
/**
* <p>Return the mapping for the given Java type. Typically, a
* mapping factory will return mappings for types it handles, and
* forward other types to another mapping factory, most often
* the {@linkplain #DEFAULT default one}.</p>
* @param t the Java type to be mapped.
* @param f the original mapping factory that was consulted to do
* the mapping. A mapping factory should pass this parameter intact
* if it forwards a type to another mapping factory. In the example,
* this is how {@code MyLinkedListMappingFactory} works for types
* like {@code MyLinkedList[]} and {@code List<MyLinkedList>}.
* @return the mapping for the given type.
* @throws OpenDataException if this type cannot be mapped. This
* exception is appropriate if the factory is supposed to handle
* all types of this sort (for example, all linked lists), but
* cannot handle this particular type.
*/
public
abstract
MXBeanMapping
mappingForType
(
Type
t
,
MXBeanMappingFactory
f
)
throws
OpenDataException
;
}
src/share/classes/javax/management/openmbean/MXBeanMappingFactoryClass.java
0 → 100644
浏览文件 @
3e149c7f
/*
* Copyright 2007 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package
javax.management.openmbean
;
import
java.lang.annotation.Documented
;
import
java.lang.annotation.ElementType
;
import
java.lang.annotation.Inherited
;
import
java.lang.annotation.Retention
;
import
java.lang.annotation.RetentionPolicy
;
import
java.lang.annotation.Target
;
/**
* <p>Specifies the MXBean mapping factory to be used for Java types
* in an MXBean interface, or in all MXBean interfaces in a package.</p>
*
* <p>Applying a mapping factory to all Java types in an MXBean interface
* looks like this:</p>
*
* <pre>
* {@literal @MXBeanMappingFactoryClass}(MyLinkedListMappingFactory.class)
* public interface SomethingMXBean {
* public MyLinkedList getSomething();
* }
* </pre>
*
* <p>Applying a mapping factory to all Java types in all MXBean interfaces
* in a package, say {@code com.example.mxbeans}, looks like this. In the
* package source directory, create a file called {@code package-info.java}
* with these contents:</p>
*
* <pre>
* {@literal @MXBeanMappingFactoryClass}(MyLinkedListMappingFactory.class)
* package com.example.mxbeans;
* </pre>
*
* @see MXBeanMappingFactory
*/
@Retention
(
RetentionPolicy
.
RUNTIME
)
@Target
({
ElementType
.
TYPE
,
ElementType
.
PACKAGE
})
@Documented
@Inherited
public
@interface
MXBeanMappingFactoryClass
{
/**
* <p>The {@link MXBeanMappingFactory} class to be used to map
* types in the annotated interface or package. This class must
* have a public constructor with no arguments. See the {@code
* MXBeanMappingFactory} documentation for an example.</p>
*/
public
Class
<?
extends
MXBeanMappingFactory
>
value
();
}
src/share/classes/javax/management/openmbean/OpenType.java
浏览文件 @
3e149c7f
...
@@ -219,7 +219,7 @@ public abstract class OpenType<T> implements Serializable {
...
@@ -219,7 +219,7 @@ public abstract class OpenType<T> implements Serializable {
});
});
}
}
private
static
String
validClassName
(
String
className
)
throws
OpenDataException
{
static
String
validClassName
(
String
className
)
throws
OpenDataException
{
className
=
valid
(
"className"
,
className
);
className
=
valid
(
"className"
,
className
);
// Check if className describes an array class, and determines its elements' class name.
// Check if className describes an array class, and determines its elements' class name.
...
...
src/share/classes/sun/nio/cs/CharsetMapping.java
浏览文件 @
3e149c7f
...
@@ -37,7 +37,7 @@ import java.security.*;
...
@@ -37,7 +37,7 @@ import java.security.*;
public
class
CharsetMapping
{
public
class
CharsetMapping
{
public
final
static
char
UNMAPPABLE_DECODING
=
'\
uFFFD
'
;
public
final
static
char
UNMAPPABLE_DECODING
=
'\
uFFFD
'
;
public
final
static
int
UNMAPPABLE_ENCODING
=
-
1
;
public
final
static
int
UNMAPPABLE_ENCODING
=
0xFFFD
;
char
[]
b2cSB
;
//singlebyte b->c
char
[]
b2cSB
;
//singlebyte b->c
char
[]
b2cDB1
;
//dobulebyte b->c /db1
char
[]
b2cDB1
;
//dobulebyte b->c /db1
...
@@ -109,9 +109,11 @@ public class CharsetMapping {
...
@@ -109,9 +109,11 @@ public class CharsetMapping {
}
}
public
int
encodeSurrogate
(
char
hi
,
char
lo
)
{
public
int
encodeSurrogate
(
char
hi
,
char
lo
)
{
char
c
=
(
char
)
Character
.
toCodePoint
(
hi
,
lo
);
int
cp
=
Character
.
toCodePoint
(
hi
,
lo
);
if
(
cp
<
0x20000
||
cp
>=
0x30000
)
return
UNMAPPABLE_ENCODING
;
int
end
=
c2bSupp
.
length
/
2
;
int
end
=
c2bSupp
.
length
/
2
;
int
i
=
Arrays
.
binarySearch
(
c2bSupp
,
0
,
end
,
c
);
int
i
=
Arrays
.
binarySearch
(
c2bSupp
,
0
,
end
,
(
char
)
cp
);
if
(
i
>=
0
)
if
(
i
>=
0
)
return
c2bSupp
[
end
+
i
];
return
c2bSupp
[
end
+
i
];
return
UNMAPPABLE_ENCODING
;
return
UNMAPPABLE_ENCODING
;
...
...
src/share/classes/sun/nio/cs/ext/SJIS_0213.java
浏览文件 @
3e149c7f
...
@@ -274,14 +274,14 @@ public class SJIS_0213 extends Charset {
...
@@ -274,14 +274,14 @@ public class SJIS_0213 extends Charset {
leftoverBase
=
c
;
leftoverBase
=
c
;
}
else
{
}
else
{
db
=
encodeChar
(
c
);
db
=
encodeChar
(
c
);
if
(
db
>
MAX_SINGLEBYTE
)
{
// Doub
leByte
if
(
db
<=
MAX_SINGLEBYTE
)
{
// Sing
leByte
if
(
dl
-
dp
<
2
)
if
(
dl
<=
dp
)
return
CoderResult
.
OVERFLOW
;
return
CoderResult
.
OVERFLOW
;
da
[
dp
++]
=
(
byte
)(
db
>>
8
);
da
[
dp
++]
=
(
byte
)
db
;
da
[
dp
++]
=
(
byte
)
db
;
}
else
if
(
db
!=
UNMAPPABLE
)
{
// Sing
leByte
}
else
if
(
db
!=
UNMAPPABLE
)
{
// Doub
leByte
if
(
dl
<=
dp
)
if
(
dl
-
dp
<
2
)
return
CoderResult
.
OVERFLOW
;
return
CoderResult
.
OVERFLOW
;
da
[
dp
++]
=
(
byte
)(
db
>>
8
);
da
[
dp
++]
=
(
byte
)
db
;
da
[
dp
++]
=
(
byte
)
db
;
}
else
if
(
Character
.
isHighSurrogate
(
c
))
{
}
else
if
(
Character
.
isHighSurrogate
(
c
))
{
if
((
sp
+
1
)
==
sl
)
if
((
sp
+
1
)
==
sl
)
...
@@ -297,6 +297,8 @@ public class SJIS_0213 extends Charset {
...
@@ -297,6 +297,8 @@ public class SJIS_0213 extends Charset {
da
[
dp
++]
=
(
byte
)(
db
>>
8
);
da
[
dp
++]
=
(
byte
)(
db
>>
8
);
da
[
dp
++]
=
(
byte
)
db
;
da
[
dp
++]
=
(
byte
)
db
;
sp
++;
sp
++;
}
else
if
(
Character
.
isLowSurrogate
(
c
))
{
return
CoderResult
.
malformedForLength
(
1
);
}
else
{
}
else
{
return
CoderResult
.
unmappableForLength
(
1
);
return
CoderResult
.
unmappableForLength
(
1
);
}
}
...
@@ -337,15 +339,15 @@ public class SJIS_0213 extends Charset {
...
@@ -337,15 +339,15 @@ public class SJIS_0213 extends Charset {
leftoverBase
=
c
;
leftoverBase
=
c
;
}
else
{
}
else
{
db
=
encodeChar
(
c
);
db
=
encodeChar
(
c
);
if
(
db
>
MAX_SINGLEBYTE
)
{
// DoubleByte
if
(
db
<=
MAX_SINGLEBYTE
)
{
// Single-byte
if
(
dst
.
remaining
()
<
1
)
return
CoderResult
.
OVERFLOW
;
dst
.
put
((
byte
)
db
);
}
else
if
(
db
!=
UNMAPPABLE
)
{
// DoubleByte
if
(
dst
.
remaining
()
<
2
)
if
(
dst
.
remaining
()
<
2
)
return
CoderResult
.
OVERFLOW
;
return
CoderResult
.
OVERFLOW
;
dst
.
put
((
byte
)(
db
>>
8
));
dst
.
put
((
byte
)(
db
>>
8
));
dst
.
put
((
byte
)(
db
));
dst
.
put
((
byte
)(
db
));
}
else
if
(
db
!=
UNMAPPABLE
)
{
// Single-byte
if
(
dst
.
remaining
()
<
1
)
return
CoderResult
.
OVERFLOW
;
dst
.
put
((
byte
)
db
);
}
else
if
(
Character
.
isHighSurrogate
(
c
))
{
}
else
if
(
Character
.
isHighSurrogate
(
c
))
{
if
(!
src
.
hasRemaining
())
// Surrogates
if
(!
src
.
hasRemaining
())
// Surrogates
return
CoderResult
.
UNDERFLOW
;
return
CoderResult
.
UNDERFLOW
;
...
@@ -360,6 +362,8 @@ public class SJIS_0213 extends Charset {
...
@@ -360,6 +362,8 @@ public class SJIS_0213 extends Charset {
dst
.
put
((
byte
)(
db
>>
8
));
dst
.
put
((
byte
)(
db
>>
8
));
dst
.
put
((
byte
)(
db
));
dst
.
put
((
byte
)(
db
));
mark
++;
mark
++;
}
else
if
(
Character
.
isLowSurrogate
(
c
))
{
return
CoderResult
.
malformedForLength
(
1
);
}
else
{
}
else
{
return
CoderResult
.
unmappableForLength
(
1
);
return
CoderResult
.
unmappableForLength
(
1
);
}
}
...
...
src/share/native/java/lang/System.c
浏览文件 @
3e149c7f
...
@@ -84,7 +84,7 @@ Java_java_lang_System_identityHashCode(JNIEnv *env, jobject this, jobject x)
...
@@ -84,7 +84,7 @@ Java_java_lang_System_identityHashCode(JNIEnv *env, jobject this, jobject x)
#define VENDOR_URL_BUG "http://java.sun.com/cgi-bin/bugreport.cgi"
#define VENDOR_URL_BUG "http://java.sun.com/cgi-bin/bugreport.cgi"
#endif
#endif
#define JAVA_MAX_SUPPORTED_VERSION 5
0
#define JAVA_MAX_SUPPORTED_VERSION 5
1
#define JAVA_MAX_SUPPORTED_MINOR_VERSION 0
#define JAVA_MAX_SUPPORTED_MINOR_VERSION 0
JNIEXPORT
jobject
JNICALL
JNIEXPORT
jobject
JNICALL
...
...
src/solaris/hpi/src/linker_md.c
浏览文件 @
3e149c7f
...
@@ -50,15 +50,6 @@
...
@@ -50,15 +50,6 @@
*/
*/
sys_mon_t
_dl_lock
;
sys_mon_t
_dl_lock
;
/*
* glibc-2.0 libdl is not MT safe. If you are building with any glibc,
* chances are you might want to run the generated bits against glibc-2.0
* libdl.so, so always use locking for any version of glibc.
*/
#ifdef __GLIBC__
#define NEED_DL_LOCK
#endif
/*
/*
* Solaris green threads needs to lock around libdl.so.
* Solaris green threads needs to lock around libdl.so.
*/
*/
...
...
test/java/lang/System/Versions.java
浏览文件 @
3e149c7f
...
@@ -23,7 +23,7 @@
...
@@ -23,7 +23,7 @@
/**
/**
* @test
* @test
* @bug 4989690 6259855
* @bug 4989690 6259855
6706299
* @summary Check that version-related system property invariants hold.
* @summary Check that version-related system property invariants hold.
* @author Martin Buchholz
* @author Martin Buchholz
*/
*/
...
...
test/javax/management/mxbean/CustomTypeTest.java
0 → 100644
浏览文件 @
3e149c7f
/*
* Copyright 2007 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/* @test %M% %I%
* @bug 6562936
* @run compile customtypes/package-info.java
* @run main CustomTypeTest
*/
import
java.io.InvalidObjectException
;
import
java.lang.management.ManagementFactory
;
import
java.lang.reflect.Array
;
import
java.lang.reflect.InvocationHandler
;
import
java.lang.reflect.Method
;
import
java.lang.reflect.Proxy
;
import
java.lang.reflect.Type
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.Collection
;
import
java.util.Date
;
import
java.util.Iterator
;
import
java.util.List
;
import
javax.management.JMX
;
import
javax.management.MBeanServer
;
import
javax.management.ObjectName
;
import
javax.management.StandardMBean
;
import
javax.management.Descriptor
;
import
javax.management.MBeanServerInvocationHandler
;
import
javax.management.NotCompliantMBeanException
;
import
javax.management.openmbean.ArrayType
;
import
javax.management.openmbean.CompositeData
;
import
javax.management.openmbean.CompositeDataSupport
;
import
javax.management.openmbean.CompositeType
;
import
javax.management.openmbean.MXBeanMapping
;
import
javax.management.openmbean.MXBeanMappingClass
;
import
javax.management.openmbean.MXBeanMappingFactory
;
import
javax.management.openmbean.MXBeanMappingFactoryClass
;
import
javax.management.openmbean.OpenDataException
;
import
javax.management.openmbean.OpenType
;
import
javax.management.openmbean.SimpleType
;
import
javax.management.openmbean.TabularData
;
import
static
javax
.
management
.
JMX
.
MBeanOptions
;
import
customtypes.*
;
public
class
CustomTypeTest
{
@MXBeanMappingClass
(
LinkedListMapping
.
class
)
public
static
class
LinkedList
{
private
final
String
name
;
private
final
LinkedList
next
;
public
LinkedList
(
String
name
,
LinkedList
next
)
{
this
.
name
=
name
;
this
.
next
=
next
;
}
public
String
getName
()
{
return
name
;
}
public
LinkedList
getNext
()
{
return
next
;
}
public
String
toString
()
{
if
(
next
==
null
)
return
"("
+
name
+
")"
;
else
return
"("
+
name
+
" "
+
next
+
")"
;
}
public
boolean
equals
(
Object
x
)
{
if
(!(
x
instanceof
LinkedList
))
return
false
;
LinkedList
other
=
(
LinkedList
)
x
;
return
(
this
.
name
.
equals
(
other
.
name
)
&&
(
this
.
next
==
null
?
other
.
next
==
null
:
this
.
next
.
equals
(
other
.
next
)));
}
}
public
static
class
LinkedListMapping
extends
MXBeanMapping
{
public
LinkedListMapping
(
Type
type
)
throws
OpenDataException
{
super
(
LinkedList
.
class
,
ArrayType
.
getArrayType
(
SimpleType
.
STRING
));
if
(
type
!=
LinkedList
.
class
)
{
throw
new
OpenDataException
(
"Mapping only valid for "
+
LinkedList
.
class
);
}
}
public
Object
fromOpenValue
(
Object
openValue
)
throws
InvalidObjectException
{
String
[]
array
=
(
String
[])
openValue
;
LinkedList
list
=
null
;
for
(
int
i
=
array
.
length
-
1
;
i
>=
0
;
i
--)
list
=
new
LinkedList
(
array
[
i
],
list
);
return
list
;
}
public
Object
toOpenValue
(
Object
javaValue
)
throws
OpenDataException
{
ArrayList
<
String
>
array
=
new
ArrayList
<
String
>();
for
(
LinkedList
list
=
(
LinkedList
)
javaValue
;
list
!=
null
;
list
=
list
.
getNext
())
array
.
add
(
list
.
getName
());
return
array
.
toArray
(
new
String
[
0
]);
}
}
public
static
interface
LinkedListMXBean
{
public
LinkedList
getLinkedList
();
}
public
static
class
LinkedListImpl
implements
LinkedListMXBean
{
public
LinkedList
getLinkedList
()
{
return
new
LinkedList
(
"car"
,
new
LinkedList
(
"cdr"
,
null
));
}
}
public
static
class
ObjectMXBeanMapping
extends
MXBeanMapping
{
private
static
final
CompositeType
wildcardType
;
static
{
try
{
wildcardType
=
new
CompositeType
(
Object
.
class
.
getName
(),
"Wildcard type for Object"
,
new
String
[
0
],
// itemNames
new
String
[
0
],
// itemDescriptions
new
OpenType
<?>[
0
]);
// itemTypes
}
catch
(
OpenDataException
e
)
{
throw
new
RuntimeException
(
e
);
}
}
public
ObjectMXBeanMapping
()
{
super
(
Object
.
class
,
wildcardType
);
}
public
Object
fromOpenValue
(
Object
openValue
)
throws
InvalidObjectException
{
if
(!(
openValue
instanceof
CompositeData
))
{
throw
new
InvalidObjectException
(
"Not a CompositeData: "
+
openValue
.
getClass
());
}
CompositeData
cd
=
(
CompositeData
)
openValue
;
if
(!
cd
.
containsKey
(
"value"
))
{
throw
new
InvalidObjectException
(
"CompositeData does not "
+
"contain a \"value\" item: "
+
cd
);
}
Object
x
=
cd
.
get
(
"value"
);
if
(!(
x
instanceof
CompositeData
||
x
instanceof
TabularData
||
x
instanceof
Object
[]))
return
x
;
String
typeName
=
(
String
)
cd
.
get
(
"type"
);
if
(
typeName
==
null
)
{
throw
new
InvalidObjectException
(
"CompositeData does not "
+
"contain a \"type\" item: "
+
cd
);
}
Class
<?>
c
;
try
{
c
=
Class
.
forName
(
typeName
);
}
catch
(
ClassNotFoundException
e
)
{
InvalidObjectException
ioe
=
new
InvalidObjectException
(
"Could not find type"
);
ioe
.
initCause
(
e
);
throw
ioe
;
}
MXBeanMapping
mapping
;
try
{
mapping
=
objectMappingFactory
.
mappingForType
(
c
,
objectMappingFactory
);
}
catch
(
OpenDataException
e
)
{
InvalidObjectException
ioe
=
new
InvalidObjectException
(
"Could not map object's "
+
"type "
+
c
.
getName
());
ioe
.
initCause
(
e
);
throw
ioe
;
}
return
mapping
.
fromOpenValue
(
x
);
}
public
Object
toOpenValue
(
Object
javaValue
)
throws
OpenDataException
{
OpenType
<?>
openType
;
Object
openValue
;
String
typeName
;
if
(
javaValue
==
null
)
{
openType
=
SimpleType
.
VOID
;
openValue
=
null
;
typeName
=
null
;
}
else
{
Class
<?>
c
=
javaValue
.
getClass
();
if
(
c
.
equals
(
Object
.
class
))
throw
new
OpenDataException
(
"Cannot map Object to an open value"
);
MXBeanMapping
mapping
=
objectMappingFactory
.
mappingForType
(
c
,
objectMappingFactory
);
openType
=
mapping
.
getOpenType
();
openValue
=
mapping
.
toOpenValue
(
javaValue
);
typeName
=
c
.
getName
();
}
CompositeType
ct
=
new
CompositeType
(
(
javaValue
==
null
)
?
"null"
:
openType
.
getClassName
(),
"Open Mapping for Object"
,
new
String
[]
{
"type"
,
"value"
},
new
String
[]
{
"type"
,
"value"
},
new
OpenType
<?>[]
{
SimpleType
.
STRING
,
openType
});
return
new
CompositeDataSupport
(
ct
,
new
String
[]
{
"type"
,
"value"
},
new
Object
[]
{
typeName
,
openValue
});
}
}
public
static
class
ObjectMappingFactory
extends
MXBeanMappingFactory
{
private
static
MXBeanMapping
objectMapping
=
new
ObjectMXBeanMapping
();
@Override
public
MXBeanMapping
mappingForType
(
Type
t
,
MXBeanMappingFactory
f
)
throws
OpenDataException
{
if
(
t
.
equals
(
Object
.
class
))
return
objectMapping
;
else
return
MXBeanMappingFactory
.
DEFAULT
.
mappingForType
(
t
,
f
);
}
}
private
static
MXBeanMappingFactory
objectMappingFactory
=
new
ObjectMappingFactory
();
public
static
interface
ObjectMXBean
{
public
Object
getObject
();
public
Object
[]
getObjects
();
public
List
<
Object
>
getObjectList
();
public
Object
[][]
getMoreObjects
();
}
public
static
class
ObjectImpl
implements
ObjectMXBean
{
public
Object
getObject
()
{
return
123
;
}
private
static
Object
[]
objects
=
{
"foo"
,
3
,
3.14f
,
3.14
,
3L
,
new
Date
(),
ObjectName
.
WILDCARD
,
new
byte
[
3
],
new
char
[
3
],
new
int
[
3
][
3
],
new
LinkedListImpl
().
getLinkedList
(),
};
public
Object
[]
getObjects
()
{
return
objects
;
}
public
List
<
Object
>
getObjectList
()
{
return
Arrays
.
asList
(
getObjects
());
}
public
Object
[][]
getMoreObjects
()
{
return
new
Object
[][]
{{
getObjects
()}};
}
}
@MXBeanMappingFactoryClass
(
ObjectMappingFactory
.
class
)
public
static
interface
AnnotatedObjectMXBean
extends
ObjectMXBean
{}
public
static
class
AnnotatedObjectImpl
extends
ObjectImpl
implements
AnnotatedObjectMXBean
{}
public
static
class
BrokenMappingFactory
extends
MXBeanMappingFactory
{
public
MXBeanMapping
mappingForType
(
Type
t
,
MXBeanMappingFactory
f
)
throws
OpenDataException
{
throw
new
OpenDataException
(
t
.
toString
());
}
}
public
static
class
ReallyBrokenMappingFactory
extends
BrokenMappingFactory
{
public
ReallyBrokenMappingFactory
()
{
throw
new
RuntimeException
(
"Oops"
);
}
}
@MXBeanMappingFactoryClass
(
BrokenMappingFactory
.
class
)
public
static
interface
BrokenMXBean
{
public
int
getX
();
}
public
static
class
BrokenImpl
implements
BrokenMXBean
{
public
int
getX
()
{
return
0
;}
}
@MXBeanMappingFactoryClass
(
ReallyBrokenMappingFactory
.
class
)
public
static
interface
ReallyBrokenMXBean
{
public
int
getX
();
}
public
static
class
ReallyBrokenImpl
implements
ReallyBrokenMXBean
{
public
int
getX
()
{
return
0
;}
}
public
static
class
BrokenMapping
extends
MXBeanMapping
{
public
BrokenMapping
(
Type
t
)
{
super
(
t
,
SimpleType
.
STRING
);
throw
new
RuntimeException
(
"Oops"
);
}
public
Object
fromOpenValue
(
Object
openValue
)
throws
InvalidObjectException
{
throw
new
AssertionError
();
}
public
Object
toOpenValue
(
Object
javaValue
)
throws
OpenDataException
{
throw
new
AssertionError
();
}
}
@MXBeanMappingClass
(
BrokenMapping
.
class
)
public
static
class
BrokenType
{}
public
static
interface
BrokenTypeMXBean
{
BrokenType
getBroken
();
}
public
static
class
BrokenTypeImpl
implements
BrokenTypeMXBean
{
public
BrokenType
getBroken
()
{
throw
new
AssertionError
();
}
}
public
static
void
main
(
String
[]
args
)
throws
Exception
{
MBeanServer
mbs
=
ManagementFactory
.
getPlatformMBeanServer
();
System
.
out
.
println
(
"Test @MXBeanMappingClass"
);
ObjectName
linkedName
=
new
ObjectName
(
"d:type=LinkedList"
);
LinkedListMXBean
linkedListMXBean
=
new
LinkedListImpl
();
LinkedList
list1
=
linkedListMXBean
.
getLinkedList
();
mbs
.
registerMBean
(
linkedListMXBean
,
linkedName
);
LinkedListMXBean
linkedProxy
=
JMX
.
newMXBeanProxy
(
mbs
,
linkedName
,
LinkedListMXBean
.
class
);
MBeanServerInvocationHandler
mbsih
=
(
MBeanServerInvocationHandler
)
Proxy
.
getInvocationHandler
(
linkedProxy
);
if
(!
mbsih
.
isMXBean
())
fail
(
"not MXBean proxy"
);
LinkedList
list2
=
linkedProxy
.
getLinkedList
();
if
(
list1
==
list2
)
fail
(
"lists identical!"
);
// They should have gone through the mapping and back,
// and the mapping doesn't do anything that would allow it
// to restore the identical object.
if
(!
list1
.
equals
(
list2
))
fail
(
"lists different: "
+
list1
+
" vs "
+
list2
);
System
.
out
.
println
(
"...success"
);
System
.
out
.
println
(
"Test StandardMBean with MXBeanMappingFactory"
);
ObjectMXBean
wildcardMBean
=
new
ObjectImpl
();
MBeanOptions
options
=
new
MBeanOptions
();
options
.
setMXBeanMappingFactory
(
objectMappingFactory
);
if
(!
options
.
isMXBean
())
fail
(
"Setting MXBeanMappingFactory should imply MXBean"
);
StandardMBean
wildcardStandardMBean
=
new
StandardMBean
(
wildcardMBean
,
ObjectMXBean
.
class
,
options
);
testWildcardMBean
(
mbs
,
wildcardMBean
,
wildcardStandardMBean
,
options
,
ObjectMXBean
.
class
);
System
.
out
.
println
(
"Test @MXBeanMappingFactoryClass on interface"
);
ObjectMXBean
annotatedWildcardMBean
=
new
AnnotatedObjectImpl
();
testWildcardMBean
(
mbs
,
annotatedWildcardMBean
,
annotatedWildcardMBean
,
null
,
AnnotatedObjectMXBean
.
class
);
System
.
out
.
println
(
"Test @MXBeanMappingFactoryClass on package"
);
CustomMXBean
custom
=
zeroProxy
(
CustomMXBean
.
class
);
ObjectName
customName
=
new
ObjectName
(
"d:type=Custom"
);
mbs
.
registerMBean
(
custom
,
customName
);
Object
x
=
mbs
.
getAttribute
(
customName
,
"X"
);
if
(!(
x
instanceof
String
))
fail
(
"Should be String: "
+
x
+
" (a "
+
x
.
getClass
().
getName
()
+
")"
);
CustomMXBean
customProxy
=
JMX
.
newMXBeanProxy
(
mbs
,
customName
,
CustomMXBean
.
class
);
x
=
customProxy
.
getX
();
if
(!(
x
instanceof
Integer
)
||
(
Integer
)
x
!=
0
)
fail
(
"Wrong return from proxy: "
+
x
+
" (a "
+
x
.
getClass
().
getName
()
+
")"
);
System
.
out
.
println
(
"Test MXBeanMappingFactory exception"
);
try
{
mbs
.
registerMBean
(
new
BrokenImpl
(),
new
ObjectName
(
"d:type=Broken"
));
fail
(
"Register did not throw exception"
);
}
catch
(
NotCompliantMBeanException
e
)
{
System
.
out
.
println
(
"...OK: threw: "
+
e
);
}
System
.
out
.
println
(
"Test MXBeanMappingFactory constructor exception"
);
try
{
mbs
.
registerMBean
(
new
ReallyBrokenImpl
(),
new
ObjectName
(
"d:type=Broken"
));
fail
(
"Register did not throw exception"
);
}
catch
(
IllegalArgumentException
e
)
{
System
.
out
.
println
(
"...OK: threw: "
+
e
);
}
System
.
out
.
println
(
"Test MXBeanMappingFactory exception with StandardMBean"
);
MXBeanMappingFactory
brokenF
=
new
BrokenMappingFactory
();
MBeanOptions
brokenO
=
new
MBeanOptions
();
brokenO
.
setMXBeanMappingFactory
(
brokenF
);
try
{
new
StandardMBean
(
wildcardMBean
,
ObjectMXBean
.
class
,
brokenO
);
fail
(
"StandardMBean with broken factory did not throw exception"
);
}
catch
(
IllegalArgumentException
e
)
{
if
(!(
e
.
getCause
()
instanceof
NotCompliantMBeanException
))
{
fail
(
"StandardMBean with broken factory threw wrong exception: "
+
e
.
getCause
());
}
}
System
.
out
.
println
(
"Test MXBeanMappingClass exception"
);
try
{
mbs
.
registerMBean
(
new
BrokenTypeImpl
(),
new
ObjectName
(
"d:type=Broken"
));
fail
(
"Broken MXBeanMappingClass did not throw exception"
);
}
catch
(
NotCompliantMBeanException
e
)
{
System
.
out
.
println
(
"...OK: threw: "
+
e
);
}
if
(
failure
==
null
)
System
.
out
.
println
(
"TEST PASSED"
);
else
throw
new
Exception
(
"TEST FAILED: "
+
failure
);
}
private
static
void
testWildcardMBean
(
MBeanServer
mbs
,
ObjectMXBean
impl
,
Object
mbean
,
MBeanOptions
proxyOptions
,
Class
<?
extends
ObjectMXBean
>
intf
)
throws
Exception
{
ObjectName
wildcardName
=
new
ObjectName
(
"d:type=Object"
);
mbs
.
registerMBean
(
mbean
,
wildcardName
);
try
{
testWildcardMBean2
(
mbs
,
impl
,
wildcardName
,
proxyOptions
,
intf
);
}
finally
{
mbs
.
unregisterMBean
(
wildcardName
);
}
}
private
static
void
testWildcardMBean2
(
MBeanServer
mbs
,
ObjectMXBean
impl
,
ObjectName
wildcardName
,
MBeanOptions
proxyOptions
,
Class
<?
extends
ObjectMXBean
>
intf
)
throws
Exception
{
if
(
proxyOptions
==
null
)
{
proxyOptions
=
new
MBeanOptions
();
MXBeanMappingFactory
f
=
MXBeanMappingFactory
.
forInterface
(
intf
);
proxyOptions
.
setMXBeanMappingFactory
(
f
);
}
Descriptor
d
=
mbs
.
getMBeanInfo
(
wildcardName
).
getDescriptor
();
String
factoryName
=
(
String
)
d
.
getFieldValue
(
JMX
.
MXBEAN_MAPPING_FACTORY_CLASS_FIELD
);
if
(!
ObjectMappingFactory
.
class
.
getName
().
equals
(
factoryName
))
{
fail
(
"Descriptor has wrong MXBeanMappingFactory: "
+
factoryName
+
" should be "
+
ObjectMappingFactory
.
class
.
getName
());
}
ObjectMXBean
wildcardProxy
=
JMX
.
newMBeanProxy
(
mbs
,
wildcardName
,
intf
,
proxyOptions
);
MBeanServerInvocationHandler
mbsih
=
(
MBeanServerInvocationHandler
)
Proxy
.
getInvocationHandler
(
wildcardProxy
);
MBeanOptions
opts
=
mbsih
.
getMBeanOptions
();
if
(!
opts
.
equals
(
proxyOptions
))
{
fail
(
"Proxy options differ from request: "
+
opts
+
" vs "
+
proxyOptions
);
}
Method
[]
wildcardMethods
=
ObjectMXBean
.
class
.
getMethods
();
for
(
Method
m
:
wildcardMethods
)
{
System
.
out
.
println
(
"..."
+
m
.
getName
());
Object
orig
=
m
.
invoke
(
impl
);
Object
copy
=
m
.
invoke
(
wildcardProxy
);
if
(!
deepEquals
(
orig
,
copy
))
{
fail
(
"objects differ: "
+
deepToString
(
orig
)
+
" vs "
+
deepToString
(
copy
));
}
}
}
private
static
<
T
>
T
zeroProxy
(
Class
<
T
>
intf
)
{
return
intf
.
cast
(
Proxy
.
newProxyInstance
(
intf
.
getClassLoader
(),
new
Class
<?>[]
{
intf
},
new
ZeroInvocationHandler
()));
}
private
static
class
ZeroInvocationHandler
implements
InvocationHandler
{
public
Object
invoke
(
Object
proxy
,
Method
method
,
Object
[]
args
)
throws
Throwable
{
return
0
;
}
}
private
static
boolean
deepEquals
(
Object
x
,
Object
y
)
{
if
(
x
==
y
)
return
true
;
if
(
x
==
null
||
y
==
null
)
return
false
;
if
(
x
instanceof
Collection
<?>)
{
if
(!(
y
instanceof
Collection
<?>))
return
false
;
Collection
<?>
xcoll
=
(
Collection
<?>)
x
;
Collection
<?>
ycoll
=
(
Collection
<?>)
y
;
if
(
xcoll
.
size
()
!=
ycoll
.
size
())
return
false
;
Iterator
<?>
xit
=
xcoll
.
iterator
();
Iterator
<?>
yit
=
ycoll
.
iterator
();
while
(
xit
.
hasNext
())
{
if
(!
deepEquals
(
xit
.
next
(),
yit
.
next
()))
return
false
;
}
return
true
;
}
Class
<?>
xclass
=
x
.
getClass
();
Class
<?>
yclass
=
y
.
getClass
();
if
(
xclass
.
isArray
())
{
if
(!
yclass
.
isArray
())
return
false
;
if
(!
xclass
.
getComponentType
().
equals
(
yclass
.
getComponentType
()))
return
false
;
int
len
=
Array
.
getLength
(
x
);
if
(
Array
.
getLength
(
y
)
!=
len
)
return
false
;
for
(
int
i
=
0
;
i
<
len
;
i
++)
{
if
(!
deepEquals
(
Array
.
get
(
x
,
i
),
Array
.
get
(
y
,
i
)))
return
false
;
}
return
true
;
}
// return x.equals(y);
if
(
x
.
equals
(
y
))
return
true
;
System
.
out
.
println
(
"Not equal: <"
+
x
+
"> and <"
+
y
+
">"
);
return
false
;
}
private
static
String
deepToString
(
Object
x
)
{
if
(
x
==
null
)
return
"null"
;
if
(
x
instanceof
Collection
<?>)
{
Collection
<?>
xcoll
=
(
Collection
<?>)
x
;
StringBuilder
sb
=
new
StringBuilder
(
"["
);
for
(
Object
e
:
xcoll
)
{
if
(
sb
.
length
()
>
1
)
sb
.
append
(
", "
);
sb
.
append
(
deepToString
(
e
));
}
sb
.
append
(
"]"
);
return
sb
.
toString
();
}
if
(
x
instanceof
Object
[])
{
Object
[]
xarr
=
(
Object
[])
x
;
return
deepToString
(
Arrays
.
asList
(
xarr
));
}
if
(
x
.
getClass
().
isArray
())
{
// primitive array
String
s
=
Arrays
.
deepToString
(
new
Object
[]
{
x
});
return
s
.
substring
(
1
,
s
.
length
()
-
1
);
}
return
x
.
toString
();
}
private
static
void
fail
(
String
msg
)
{
System
.
out
.
println
(
"TEST FAILED: "
+
msg
);
if
(
msg
.
length
()
>
100
)
msg
=
msg
.
substring
(
0
,
100
)
+
"..."
;
failure
=
msg
;
}
private
static
String
failure
;
}
test/javax/management/mxbean/customtypes/CustomLongMXBean.java
0 → 100644
浏览文件 @
3e149c7f
/*
* Copyright 2007 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
// CustomLongMXBean.java - see CustomTypeTest
package
customtypes
;
import
javax.management.openmbean.MXBeanMappingFactoryClass
;
@MXBeanMappingFactoryClass
(
IntegerIsLongFactory
.
class
)
public
interface
CustomLongMXBean
extends
CustomMXBean
{}
src/share/classes/javax/management/ToQueryString
.java
→
test/javax/management/mxbean/customtypes/CustomMXBean
.java
浏览文件 @
3e149c7f
/*
/*
* Copyright 200
8
Sun Microsystems, Inc. All Rights Reserved.
* Copyright 200
7
Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* published by the Free Software Foundation.
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
...
@@ -23,16 +21,10 @@
...
@@ -23,16 +21,10 @@
* have any questions.
* have any questions.
*/
*/
package
javax.management
;
// CustomMXBean.java - see CustomTypeTest
/* QueryExp classes can extend this to get non-default treatment for
package
customtypes
;
* Query.toString(q). We're reluctant to change the public toString()
* methods of the classes because people might be parsing them, even
public
interface
CustomMXBean
{
* though that's rather fragile. But Query.toString(q) has no such
public
Integer
getX
();
* constraint so it can use the new toQueryString() method defined here.
*/
class
ToQueryString
{
String
toQueryString
()
{
return
toString
();
}
}
}
test/javax/management/mxbean/customtypes/IntegerIsLongFactory.java
0 → 100644
浏览文件 @
3e149c7f
/*
* Copyright 2007 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
// IntegerIsLongFactory.java - see CustomTypeTest
package
customtypes
;
import
java.io.InvalidObjectException
;
import
java.lang.reflect.Type
;
import
javax.management.openmbean.MXBeanMapping
;
import
javax.management.openmbean.MXBeanMappingFactory
;
import
javax.management.openmbean.OpenDataException
;
import
javax.management.openmbean.SimpleType
;
public
class
IntegerIsLongFactory
implements
MXBeanMappingFactory
{
public
MXBeanMapping
forType
(
Type
t
,
MXBeanMappingFactory
f
)
throws
OpenDataException
{
if
(
t
==
Integer
.
class
)
return
IntegerIsLongMapping
;
else
return
MXBeanMappingFactory
.
DEFAULT
.
forType
(
t
,
f
);
}
private
static
final
MXBeanMapping
IntegerIsLongMapping
=
new
IntegerIsLongMapping
();
private
static
class
IntegerIsLongMapping
extends
MXBeanMapping
{
IntegerIsLongMapping
()
{
super
(
Integer
.
class
,
SimpleType
.
STRING
);
}
public
Object
fromOpenValue
(
Object
openValue
)
throws
InvalidObjectException
{
try
{
return
(
Long
)
openValue
;
}
catch
(
Exception
e
)
{
InvalidObjectException
ioe
=
new
InvalidObjectException
(
"oops"
);
ioe
.
initCause
(
e
);
throw
ioe
;
}
}
public
Object
toOpenValue
(
Object
javaValue
)
throws
OpenDataException
{
try
{
Integer
i
=
(
Integer
)
javaValue
;
return
new
Long
((
int
)
i
);
}
catch
(
Exception
e
)
{
OpenDataException
ode
=
new
OpenDataException
(
"oops"
);
ode
.
initCause
(
e
);
throw
ode
;
}
}
}
}
test/javax/management/mxbean/customtypes/IntegerIsStringFactory.java
0 → 100644
浏览文件 @
3e149c7f
/*
* Copyright 2007 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
// IntegerIsStringFactory.java - see CustomTypeTest
package
customtypes
;
import
java.io.InvalidObjectException
;
import
java.lang.reflect.Type
;
import
javax.management.openmbean.MXBeanMapping
;
import
javax.management.openmbean.MXBeanMappingFactory
;
import
javax.management.openmbean.OpenDataException
;
import
javax.management.openmbean.SimpleType
;
public
class
IntegerIsStringFactory
extends
MXBeanMappingFactory
{
@Override
public
MXBeanMapping
mappingForType
(
Type
t
,
MXBeanMappingFactory
f
)
throws
OpenDataException
{
if
(
t
==
Integer
.
class
)
return
integerIsStringMapping
;
else
return
MXBeanMappingFactory
.
DEFAULT
.
mappingForType
(
t
,
f
);
}
private
static
final
MXBeanMapping
integerIsStringMapping
=
new
IntegerIsStringMapping
();
private
static
class
IntegerIsStringMapping
extends
MXBeanMapping
{
IntegerIsStringMapping
()
{
super
(
Integer
.
class
,
SimpleType
.
STRING
);
}
public
Object
fromOpenValue
(
Object
openValue
)
throws
InvalidObjectException
{
try
{
String
s
=
(
String
)
openValue
;
return
Integer
.
parseInt
(
s
);
}
catch
(
Exception
e
)
{
InvalidObjectException
ioe
=
new
InvalidObjectException
(
"oops"
);
ioe
.
initCause
(
e
);
throw
ioe
;
}
}
public
Object
toOpenValue
(
Object
javaValue
)
throws
OpenDataException
{
try
{
Integer
i
=
(
Integer
)
javaValue
;
return
i
.
toString
();
}
catch
(
Exception
e
)
{
OpenDataException
ode
=
new
OpenDataException
(
"oops"
);
ode
.
initCause
(
e
);
throw
ode
;
}
}
}
}
test/javax/management/mxbean/customtypes/package-info.java
0 → 100644
浏览文件 @
3e149c7f
/*
* Copyright 2007 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
// package-info.java - test package annotations for custom types
@javax
.
management
.
openmbean
.
MXBeanMappingFactoryClass
(
IntegerIsStringFactory
.
class
)
package
customtypes
;
test/javax/management/query/QueryExpStringTest.java
浏览文件 @
3e149c7f
...
@@ -121,14 +121,14 @@ public class QueryExpStringTest {
...
@@ -121,14 +121,14 @@ public class QueryExpStringTest {
eq
,
"(12345678) = (2.5)"
,
eq
,
"(12345678) = (2.5)"
,
between
,
"(12345678) between (2.5) and (2.5)"
,
between
,
"(12345678) between (2.5) and (2.5)"
,
match
,
"attr like 'simpleString'"
,
match
,
"attr like 'simpleString'"
,
initial
,
"attr like 'simpleString
%
'"
,
initial
,
"attr like 'simpleString
*
'"
,
initialStar
,
"attr like '\\*
%
'"
,
initialStar
,
"attr like '\\*
*
'"
,
initialPercent
,
"attr like '
\\%%
'"
,
initialPercent
,
"attr like '
%*
'"
,
any
,
"attr like '
%simpleString%
'"
,
any
,
"attr like '
*simpleString*
'"
,
anyStar
,
"attr like '
%\\*%
'"
,
anyStar
,
"attr like '
*\\**
'"
,
anyPercent
,
"attr like '
%\\%%
'"
,
anyPercent
,
"attr like '
*%*
'"
,
ffinal
,
"attr like '
%
simpleString'"
,
ffinal
,
"attr like '
*
simpleString'"
,
finalMagic
,
"attr like '
%
\\?\\*\\[\\\\'"
,
finalMagic
,
"attr like '
*
\\?\\*\\[\\\\'"
,
in
,
"12345678 in (12345678, 2.5)"
,
in
,
"12345678 in (12345678, 2.5)"
,
and
,
"((12345678) > (2.5)) and ((12345678) < (2.5))"
,
and
,
"((12345678) > (2.5)) and ((12345678) < (2.5))"
,
or
,
"((12345678) > (2.5)) or ((12345678) < (2.5))"
,
or
,
"((12345678) > (2.5)) or ((12345678) < (2.5))"
,
...
@@ -207,7 +207,6 @@ public class QueryExpStringTest {
...
@@ -207,7 +207,6 @@ public class QueryExpStringTest {
exp
+
" like "
+
pat
);
exp
+
" like "
+
pat
);
}
}
StringValueExp
spat
=
(
StringValueExp
)
pat
;
StringValueExp
spat
=
(
StringValueExp
)
pat
;
spat
=
Query
.
value
(
translateMatch
(
spat
.
getValue
()));
return
Query
.
match
((
AttributeValueExp
)
exp
,
spat
);
return
Query
.
match
((
AttributeValueExp
)
exp
,
spat
);
}
}
...
@@ -226,28 +225,6 @@ public class QueryExpStringTest {
...
@@ -226,28 +225,6 @@ public class QueryExpStringTest {
throw
new
Exception
(
"Expected in or like after expression"
);
throw
new
Exception
(
"Expected in or like after expression"
);
}
}
private
static
String
translateMatch
(
String
s
)
{
StringBuilder
sb
=
new
StringBuilder
();
for
(
int
i
=
0
;
i
<
s
.
length
();
i
++)
{
// logic not correct for wide chars
char
c
=
s
.
charAt
(
i
);
switch
(
c
)
{
case
'\\'
:
sb
.
append
(
c
).
append
(
s
.
charAt
(++
i
));
break
;
case
'%'
:
sb
.
append
(
'*'
);
break
;
case
'_'
:
sb
.
append
(
'?'
);
break
;
case
'*'
:
sb
.
append
(
"\\*"
);
break
;
case
'?'
:
sb
.
append
(
"\\?"
);
break
;
default
:
sb
.
append
(
c
);
break
;
}
}
return
sb
.
toString
();
}
private
static
QueryExp
parseQueryAfterParen
(
String
[]
ss
)
private
static
QueryExp
parseQueryAfterParen
(
String
[]
ss
)
throws
Exception
{
throws
Exception
{
/* This is very ugly. We might have "(q1) and (q2)" here, or
/* This is very ugly. We might have "(q1) and (q2)" here, or
...
...
test/javax/management/query/QueryParseTest.java
浏览文件 @
3e149c7f
...
@@ -347,30 +347,30 @@ public class QueryParseTest {
...
@@ -347,30 +347,30 @@ public class QueryParseTest {
// LIKE
// LIKE
"A like 'b
%
m'"
,
"A like 'b
*
m'"
,
expectTrue
(
"blim"
),
expectTrue
(
"bm"
),
expectTrue
(
"blim"
),
expectTrue
(
"bm"
),
expectFalse
(
""
),
expectFalse
(
"blimmo"
),
expectFalse
(
"mmm"
),
expectFalse
(
""
),
expectFalse
(
"blimmo"
),
expectFalse
(
"mmm"
),
"A not like 'b
%
m'"
,
"A not like 'b
*
m'"
,
expectFalse
(
"blim"
),
expectFalse
(
"bm"
),
expectFalse
(
"blim"
),
expectFalse
(
"bm"
),
expectTrue
(
""
),
expectTrue
(
"blimmo"
),
expectTrue
(
"mmm"
),
expectTrue
(
""
),
expectTrue
(
"blimmo"
),
expectTrue
(
"mmm"
),
"A like 'b
_
m'"
,
"A like 'b
?
m'"
,
expectTrue
(
"bim"
),
expectFalse
(
"blim"
),
expectTrue
(
"bim"
),
expectFalse
(
"blim"
),
"A like '
%can''t%
'"
,
"A like '
*can''t*
'"
,
expectTrue
(
"can't"
),
expectTrue
(
"can't"
),
expectTrue
(
"I'm sorry Dave, I'm afraid I can't do that"
),
expectTrue
(
"I'm sorry Dave, I'm afraid I can't do that"
),
expectFalse
(
"cant"
),
expectFalse
(
"can''t"
),
expectFalse
(
"cant"
),
expectFalse
(
"can''t"
),
"A like '\\
%%\\%
'"
,
"A like '\\
**\\*
'"
,
expectTrue
(
"
%blim%"
),
expectTrue
(
"%%
"
),
expectTrue
(
"
*blim*"
),
expectTrue
(
"**
"
),
expectFalse
(
"blim"
),
expectFalse
(
"
%asdf"
),
expectFalse
(
"asdf%
"
),
expectFalse
(
"blim"
),
expectFalse
(
"
*asdf"
),
expectFalse
(
"asdf*
"
),
"A LIKE '
*%?_
'"
,
"A LIKE '
%*_?
'"
,
expectTrue
(
"
*blim?!"
),
expectTrue
(
"*?_
"
),
expectTrue
(
"
%blim_?"
),
expectTrue
(
"%_?"
),
expectTrue
(
"%blim_!
"
),
expectFalse
(
"blim"
),
expectFalse
(
"blim
?
"
),
expectFalse
(
"blim"
),
expectFalse
(
"blim
_
"
),
expectFalse
(
"
?*
"
),
expectFalse
(
"??"
),
expectFalse
(
""
),
expectFalse
(
"?"
),
expectFalse
(
"
_%
"
),
expectFalse
(
"??"
),
expectFalse
(
""
),
expectFalse
(
"?"
),
Query
.
toString
(
Query
.
toString
(
Query
.
initialSubString
(
Query
.
attr
(
"A"
),
Query
.
value
(
"*?%_"
))),
Query
.
initialSubString
(
Query
.
attr
(
"A"
),
Query
.
value
(
"*?%_"
))),
...
@@ -483,7 +483,7 @@ public class QueryParseTest {
...
@@ -483,7 +483,7 @@ public class QueryParseTest {
// note the little {} at the end which means this is a subclass
// note the little {} at the end which means this is a subclass
// and therefore QualifiedAttributeValue should return false.
// and therefore QualifiedAttributeValue should return false.
MBeanServerDelegate
.
class
.
getName
()
+
"#SpecificationName LIKE '
%
'"
,
MBeanServerDelegate
.
class
.
getName
()
+
"#SpecificationName LIKE '
*
'"
,
new
Wrapped
(
new
MBeanServerDelegate
(),
true
),
new
Wrapped
(
new
MBeanServerDelegate
(),
true
),
new
Tester
(
new
String
[]
{
"SpecificationName"
},
new
Object
[]
{
"JMX"
},
false
),
new
Tester
(
new
String
[]
{
"SpecificationName"
},
new
Object
[]
{
"JMX"
},
false
),
...
@@ -497,7 +497,7 @@ public class QueryParseTest {
...
@@ -497,7 +497,7 @@ public class QueryParseTest {
"A.class.name = 'java.lang.String'"
,
"A.class.name = 'java.lang.String'"
,
expectTrue
(
"blim"
),
expectFalse
(
95
),
expectFalse
((
Object
)
null
),
expectTrue
(
"blim"
),
expectFalse
(
95
),
expectFalse
((
Object
)
null
),
"A.canonicalName like 'JMImpl
%:%
'"
,
"A.canonicalName like 'JMImpl
*:*
'"
,
expectTrue
(
MBeanServerDelegate
.
DELEGATE_NAME
),
expectTrue
(
MBeanServerDelegate
.
DELEGATE_NAME
),
expectFalse
(
ObjectName
.
WILDCARD
),
expectFalse
(
ObjectName
.
WILDCARD
),
...
@@ -544,12 +544,15 @@ public class QueryParseTest {
...
@@ -544,12 +544,15 @@ public class QueryParseTest {
"a in b, c"
,
"a in 23"
,
"a in (2, 3"
,
"a in (2, 3x)"
,
"a in b, c"
,
"a in 23"
,
"a in (2, 3"
,
"a in (2, 3x)"
,
"a like \"foo\""
,
"a like b"
,
"a like 23"
,
"a like \"foo\""
,
"a like b"
,
"a like 23"
,
"like \"foo\""
,
"like b"
,
"like 23"
,
"like 'a:b'"
,
"like \"foo\""
,
"like b"
,
"like 23"
,
"like 'a:b'"
,
"5 like 'a'"
,
"'a' like '
%
'"
,
"5 like 'a'"
,
"'a' like '
*
'"
,
"a not= b"
,
"a not = b"
,
"a not b"
,
"a not b c"
,
"a not= b"
,
"a not = b"
,
"a not b"
,
"a not b c"
,
"a = +b"
,
"a = +'b'"
,
"a = +true"
,
"a = -b"
,
"a = -'b'"
,
"a = +b"
,
"a = +'b'"
,
"a = +true"
,
"a = -b"
,
"a = -'b'"
,
"a#5 = b"
,
"a#'b' = c"
,
"a#5 = b"
,
"a#'b' = c"
,
"a instanceof b"
,
"a instanceof 17"
,
"a instanceof"
,
"a instanceof b"
,
"a instanceof 17"
,
"a instanceof"
,
"a like 'oops\\'"
,
"a like '[oops'"
,
// "a like 'oops\\'", "a like '[oops'",
// We don't check the above because Query.match doesn't. If LIKE
// rejected bad patterns then there would be some QueryExp values
// that could not be converted to a string and back.
// Check that -Long.MIN_VALUE is an illegal constant. This is one more
// Check that -Long.MIN_VALUE is an illegal constant. This is one more
// than Long.MAX_VALUE and, like the Java language, we only allow it
// than Long.MAX_VALUE and, like the Java language, we only allow it
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录