@@ -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: <Descriptor></Descriptor></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- "  " ,
962- "\" "" ,
963- "<<" ,
964- ">>" ,
965- "&&" ,
966- "\r " ,
967- "\t 	" ,
968- "\n " ,
969- "\f " ,
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