Skip to content

Commit 13e0f99

Browse files
committed
8351413: Remove XML interchange in java.management/javax/management/modelmbean/DescriptorSupport
Reviewed-by: dfuchs, sspitsyn
1 parent bf3cfbe commit 13e0f99

File tree

6 files changed

+5
-649
lines changed

6 files changed

+5
-649
lines changed

src/java.management/share/classes/javax/management/modelmbean/DescriptorSupport.java

Lines changed: 0 additions & 356 deletions
Original file line numberDiff line numberDiff line change
@@ -174,137 +174,6 @@ public DescriptorSupport(DescriptorSupport inDescr) {
174174
init(inDescr.descriptorMap);
175175
}
176176

177-
178-
/**
179-
* <p>Descriptor constructor taking an XML String.</p>
180-
*
181-
* <p>The format of the XML string is not defined, but an
182-
* implementation must ensure that the string returned by
183-
* {@link #toXMLString() toXMLString()} on an existing
184-
* descriptor can be used to instantiate an equivalent
185-
* descriptor using this constructor.</p>
186-
*
187-
* <p>In this implementation, all field values will be created
188-
* as Strings. If the field values are not Strings, the
189-
* programmer will have to reset or convert these fields
190-
* correctly.</p>
191-
*
192-
* @param inStr An XML-formatted string used to populate this
193-
* Descriptor. The format is not defined, but any
194-
* implementation must ensure that the string returned by
195-
* method {@link #toXMLString toXMLString} on an existing
196-
* descriptor can be used to instantiate an equivalent
197-
* descriptor when instantiated using this constructor.
198-
*
199-
* @exception RuntimeOperationsException If the String inStr
200-
* passed in parameter is null
201-
* @exception XMLParseException XML parsing problem while parsing
202-
* the input String
203-
* @exception MBeanException Wraps a distributed communication Exception.
204-
* @deprecated This constructor exists for historical reasons. If
205-
* reading from XML is required, it should be implemented externally.
206-
*/
207-
/* At some stage we should rewrite this code to be cleverer. Using
208-
a StringTokenizer as we do means, first, that we accept a lot of
209-
bogus strings without noticing they are bogus, and second, that we
210-
split the string being parsed at characters like > even if they
211-
occur in the middle of a field value. */
212-
@Deprecated(since="25", forRemoval=true)
213-
@SuppressWarnings("removal")
214-
public DescriptorSupport(String inStr)
215-
throws MBeanException, RuntimeOperationsException,
216-
XMLParseException {
217-
/* parse an XML-formatted string and populate internal
218-
* structure with it */
219-
if (MODELMBEAN_LOGGER.isLoggable(Level.TRACE)) {
220-
MODELMBEAN_LOGGER.log(Level.TRACE,
221-
"Descriptor(String = '" + inStr + "') Constructor");
222-
}
223-
if (inStr == null) {
224-
if (MODELMBEAN_LOGGER.isLoggable(Level.TRACE)) {
225-
MODELMBEAN_LOGGER.log(Level.TRACE,
226-
"Descriptor(String = null) Illegal arguments");
227-
}
228-
final String msg = "String in parameter is null";
229-
final RuntimeException iae = new IllegalArgumentException(msg);
230-
throw new RuntimeOperationsException(iae, msg);
231-
}
232-
233-
final String lowerInStr = inStr.toLowerCase(Locale.ENGLISH);
234-
if (!lowerInStr.startsWith("<descriptor>")
235-
|| !lowerInStr.endsWith("</descriptor>")) {
236-
throw new XMLParseException("No <descriptor>, </descriptor> pair");
237-
// XMLParseException is deprecated for removal.
238-
}
239-
240-
// parse xmlstring into structures
241-
init(null);
242-
// create dummy descriptor: should have same size
243-
// as number of fields in xmlstring
244-
// loop through structures and put them in descriptor
245-
246-
StringTokenizer st = new StringTokenizer(inStr, "<> \t\n\r\f");
247-
248-
boolean inFld = false;
249-
boolean inDesc = false;
250-
String fieldName = null;
251-
String fieldValue = null;
252-
253-
254-
while (st.hasMoreTokens()) { // loop through tokens
255-
String tok = st.nextToken();
256-
257-
if (tok.equalsIgnoreCase("FIELD")) {
258-
inFld = true;
259-
} else if (tok.equalsIgnoreCase("/FIELD")) {
260-
if ((fieldName != null) && (fieldValue != null)) {
261-
fieldName =
262-
fieldName.substring(fieldName.indexOf('"') + 1,
263-
fieldName.lastIndexOf('"'));
264-
final Object fieldValueObject =
265-
parseQuotedFieldValue(fieldValue);
266-
setField(fieldName, fieldValueObject);
267-
}
268-
fieldName = null;
269-
fieldValue = null;
270-
inFld = false;
271-
} else if (tok.equalsIgnoreCase("DESCRIPTOR")) {
272-
inDesc = true;
273-
} else if (tok.equalsIgnoreCase("/DESCRIPTOR")) {
274-
inDesc = false;
275-
fieldName = null;
276-
fieldValue = null;
277-
inFld = false;
278-
} else if (inFld && inDesc) {
279-
// want kw=value, eg, name="myname" value="myvalue"
280-
int eq_separator = tok.indexOf('=');
281-
if (eq_separator > 0) {
282-
String kwPart = tok.substring(0,eq_separator);
283-
String valPart = tok.substring(eq_separator+1);
284-
if (kwPart.equalsIgnoreCase("NAME"))
285-
fieldName = valPart;
286-
else if (kwPart.equalsIgnoreCase("VALUE"))
287-
fieldValue = valPart;
288-
else { // xml parse exception
289-
final String msg =
290-
"Expected `name' or `value', got `" + tok + "'";
291-
throw new XMLParseException(msg);
292-
// XMLParseException is deprecated for removal.
293-
}
294-
} else { // xml parse exception
295-
final String msg =
296-
"Expected `keyword=value', got `" + tok + "'";
297-
throw new XMLParseException(msg);
298-
// XMLParseException is deprecated for removal.
299-
}
300-
}
301-
} // while tokens
302-
if (MODELMBEAN_LOGGER.isLoggable(Level.TRACE)) {
303-
MODELMBEAN_LOGGER.log(Level.TRACE,
304-
"Descriptor(XMLString) Exit");
305-
}
306-
}
307-
308177
/**
309178
* Constructor taking field names and field values. Neither array
310179
* can be null.
@@ -899,231 +768,6 @@ private boolean validateField(String fldName, Object fldValue) {
899768
return true;
900769
}
901770

902-
903-
904-
/**
905-
* <p>Returns an XML String representing the descriptor.</p>
906-
*
907-
* <p>The format is not defined, but an implementation must
908-
* ensure that the string returned by this method can be
909-
* used to build an equivalent descriptor when instantiated
910-
* using the constructor {@link #DescriptorSupport(String)
911-
* DescriptorSupport(String inStr)}.</p>
912-
*
913-
* <p>Fields which are not String objects will have toString()
914-
* called on them to create the value. The value will be
915-
* enclosed in parentheses. It is not guaranteed that you can
916-
* reconstruct these objects unless they have been
917-
* specifically set up to support toString() in a meaningful
918-
* format and have a matching constructor that accepts a
919-
* String in the same format.</p>
920-
*
921-
* <p>If the descriptor is empty the following String is
922-
* returned: &lt;Descriptor&gt;&lt;/Descriptor&gt;</p>
923-
*
924-
* @return the XML string.
925-
*
926-
* @exception RuntimeOperationsException for illegal value for
927-
* field Names or field Values. If the XML formatted string
928-
* construction fails for any reason, this exception will be
929-
* thrown.
930-
* @deprecated This method exists for historical reasons. If
931-
* writing to XML is required, it should be implemented externally.
932-
*/
933-
@Deprecated(since="25", forRemoval=true)
934-
public synchronized String toXMLString() {
935-
final StringBuilder buf = new StringBuilder("<Descriptor>");
936-
Set<Map.Entry<String, Object>> returnedSet = descriptorMap.entrySet();
937-
for (Map.Entry<String, Object> currElement : returnedSet) {
938-
final String name = currElement.getKey();
939-
Object value = currElement.getValue();
940-
String valueString = null;
941-
/* Set valueString to non-null if and only if this is a string that
942-
cannot be confused with the encoding of an object. If it
943-
could be so confused (surrounded by parentheses) then we
944-
call makeFieldValue as for any non-String object and end
945-
up with an encoding like "(java.lang.String/(thing))". */
946-
if (value instanceof String) {
947-
final String svalue = (String) value;
948-
if (!svalue.startsWith("(") || !svalue.endsWith(")"))
949-
valueString = quote(svalue);
950-
}
951-
if (valueString == null)
952-
valueString = makeFieldValue(value);
953-
buf.append("<field name=\"").append(name).append("\" value=\"")
954-
.append(valueString).append("\"></field>");
955-
}
956-
buf.append("</Descriptor>");
957-
return buf.toString();
958-
}
959-
960-
private static final String[] entities = {
961-
" &#32;",
962-
"\"&quot;",
963-
"<&lt;",
964-
">&gt;",
965-
"&&amp;",
966-
"\r&#13;",
967-
"\t&#9;",
968-
"\n&#10;",
969-
"\f&#12;",
970-
};
971-
private static final Map<String,Character> entityToCharMap =
972-
new HashMap<>();
973-
private static final String[] charToEntityMap;
974-
975-
static {
976-
char maxChar = 0;
977-
for (int i = 0; i < entities.length; i++) {
978-
final char c = entities[i].charAt(0);
979-
if (c > maxChar)
980-
maxChar = c;
981-
}
982-
charToEntityMap = new String[maxChar + 1];
983-
for (int i = 0; i < entities.length; i++) {
984-
final char c = entities[i].charAt(0);
985-
final String entity = entities[i].substring(1);
986-
charToEntityMap[c] = entity;
987-
entityToCharMap.put(entity, c);
988-
}
989-
}
990-
991-
private static boolean isMagic(char c) {
992-
return (c < charToEntityMap.length && charToEntityMap[c] != null);
993-
}
994-
995-
/*
996-
* Quote the string so that it will be acceptable to the (String)
997-
* constructor. Since the parsing code in that constructor is fairly
998-
* stupid, we're obliged to quote apparently innocuous characters like
999-
* space, <, and >. In a future version, we should rewrite the parser
1000-
* and only quote " plus either \ or & (depending on the quote syntax).
1001-
*/
1002-
private static String quote(String s) {
1003-
boolean found = false;
1004-
for (int i = 0; i < s.length(); i++) {
1005-
if (isMagic(s.charAt(i))) {
1006-
found = true;
1007-
break;
1008-
}
1009-
}
1010-
if (!found)
1011-
return s;
1012-
final StringBuilder buf = new StringBuilder();
1013-
for (int i = 0; i < s.length(); i++) {
1014-
char c = s.charAt(i);
1015-
if (isMagic(c))
1016-
buf.append(charToEntityMap[c]);
1017-
else
1018-
buf.append(c);
1019-
}
1020-
return buf.toString();
1021-
}
1022-
1023-
@SuppressWarnings("removal")
1024-
private static String unquote(String s) throws XMLParseException {
1025-
if (!s.startsWith("\"") || !s.endsWith("\"")) {
1026-
throw new XMLParseException("Value must be quoted: <" + s + ">");
1027-
// XMLParseException is deprecated for removal.
1028-
}
1029-
final StringBuilder buf = new StringBuilder();
1030-
final int len = s.length() - 1;
1031-
for (int i = 1; i < len; i++) {
1032-
final char c = s.charAt(i);
1033-
final int semi;
1034-
final Character quoted;
1035-
if (c == '&'
1036-
&& (semi = s.indexOf(';', i + 1)) >= 0
1037-
&& ((quoted = entityToCharMap.get(s.substring(i, semi+1)))
1038-
!= null)) {
1039-
buf.append(quoted);
1040-
i = semi;
1041-
} else
1042-
buf.append(c);
1043-
}
1044-
return buf.toString();
1045-
}
1046-
1047-
/**
1048-
* Make the string that will go inside "..." for a value that is not
1049-
* a plain String.
1050-
* @throws RuntimeOperationsException if the value cannot be encoded.
1051-
*/
1052-
private static String makeFieldValue(Object value) {
1053-
if (value == null)
1054-
return "(null)";
1055-
1056-
Class<?> valueClass = value.getClass();
1057-
try {
1058-
valueClass.getConstructor(String.class);
1059-
} catch (NoSuchMethodException e) {
1060-
final String msg =
1061-
"Class " + valueClass + " does not have a public " +
1062-
"constructor with a single string arg";
1063-
final RuntimeException iae = new IllegalArgumentException(msg);
1064-
throw new RuntimeOperationsException(iae,
1065-
"Cannot make XML descriptor");
1066-
} catch (SecurityException e) {
1067-
// OK: we'll pretend the constructor is there
1068-
// too bad if it's not: we'll find out when we try to
1069-
// reconstruct the DescriptorSupport
1070-
}
1071-
1072-
final String quotedValueString = quote(value.toString());
1073-
1074-
return "(" + valueClass.getName() + "/" + quotedValueString + ")";
1075-
}
1076-
1077-
/*
1078-
* Parse a field value from the XML produced by toXMLString().
1079-
* Given a descriptor XML containing <field name="nnn" value="vvv">,
1080-
* the argument to this method will be "vvv" (a string including the
1081-
* containing quote characters). If vvv begins and ends with parentheses,
1082-
* then it may contain:
1083-
* - the characters "null", in which case the result is null;
1084-
* - a value of the form "some.class.name/xxx", in which case the
1085-
* result is equivalent to `new some.class.name("xxx")';
1086-
* - some other string, in which case the result is that string,
1087-
* without the parentheses.
1088-
*/
1089-
@SuppressWarnings("removal")
1090-
private static Object parseQuotedFieldValue(String s)
1091-
throws XMLParseException {
1092-
s = unquote(s);
1093-
if (s.equalsIgnoreCase("(null)"))
1094-
return null;
1095-
if (!s.startsWith("(") || !s.endsWith(")"))
1096-
return s;
1097-
final int slash = s.indexOf('/');
1098-
if (slash < 0) {
1099-
// compatibility: old code didn't include class name
1100-
return s.substring(1, s.length() - 1);
1101-
}
1102-
final String className = s.substring(1, slash);
1103-
1104-
final Constructor<?> constr;
1105-
try {
1106-
final ClassLoader contextClassLoader =
1107-
Thread.currentThread().getContextClassLoader();
1108-
final Class<?> c =
1109-
Class.forName(className, false, contextClassLoader);
1110-
constr = c.getConstructor(new Class<?>[] {String.class});
1111-
} catch (Exception e) {
1112-
throw new XMLParseException(e, "Cannot parse value: <" + s + ">");
1113-
// XMLParseException is deprecated for removal.
1114-
}
1115-
final String arg = s.substring(slash + 1, s.length() - 1);
1116-
try {
1117-
return constr.newInstance(new Object[] {arg});
1118-
} catch (Exception e) {
1119-
final String msg =
1120-
"Cannot construct instance of " + className +
1121-
" with arg: <" + s + ">";
1122-
throw new XMLParseException(e, msg);
1123-
// XMLParseException is deprecated for removal.
1124-
}
1125-
}
1126-
1127771
/**
1128772
* Returns a human readable string representing the
1129773
* descriptor. The string will be in the format of

0 commit comments

Comments
 (0)