1 /* 2 * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.sun.tools.javadoc.main; 27 28 import com.sun.javadoc.*; 29 30 /** 31 * Documents a Serializable field defined by an ObjectStreamField. 32 * <pre> 33 * The class parses and stores the three serialField tag parameters: 34 * 35 * - field name 36 * - field type name 37 * (fully-qualified or visible from the current import context) 38 * - description of the valid values for the field 39 40 * </pre> 41 * This tag is only allowed in the javadoc for the special member 42 * serialPersistentFields. 43 * 44 * <p><b>This is NOT part of any supported API. 45 * If you write code that depends on this, you do so at your own risk. 46 * This code and its internal interfaces are subject to change or 47 * deletion without notice.</b> 48 * 49 * @author Joe Fialli 50 * @author Neal Gafter 51 * 52 * @see java.io.ObjectStreamField 53 */ 54 @Deprecated(since="9", forRemoval=true) 55 @SuppressWarnings("removal") 56 class SerialFieldTagImpl 57 extends TagImpl 58 implements SerialFieldTag, Comparable<Object> 59 { 60 //### These could be final, except that the constructor 61 //### does not set them directly. 62 63 private String fieldName; // Required Argument 1 of serialField 64 private String fieldType; // Required Argument 2 of serialField 65 private String description; // Optional Remaining Arguments of serialField 66 67 private ClassDoc containingClass; // Class containing serialPersistentField member 68 private ClassDoc fieldTypeDoc; // ClassDocImpl of fieldType 69 private FieldDocImpl matchingField; // FieldDocImpl with same name as fieldName 70 71 /* Constructor. */ SerialFieldTagImpl(DocImpl holder, String name, String text)72 SerialFieldTagImpl(DocImpl holder, String name, String text) { 73 super(holder, name, text); 74 parseSerialFieldString(); 75 if (holder instanceof MemberDoc) { 76 containingClass = ((MemberDocImpl)holder).containingClass(); 77 } 78 } 79 80 /* 81 * The serialField tag is composed of three entities. 82 * 83 * serialField serializableFieldName serisliableFieldType 84 * description of field. 85 * 86 * The fieldName and fieldType must be legal Java Identifiers. 87 */ parseSerialFieldString()88 private void parseSerialFieldString() { 89 int len = text.length(); 90 if (len == 0) { 91 return; 92 } 93 94 // if no white space found 95 /* Skip white space. */ 96 int inx = 0; 97 int cp; 98 for (; inx < len; inx += Character.charCount(cp)) { 99 cp = text.codePointAt(inx); 100 if (!Character.isWhitespace(cp)) { 101 break; 102 } 103 } 104 105 /* find first word. */ 106 int first = inx; 107 int last = inx; 108 cp = text.codePointAt(inx); 109 if (! Character.isJavaIdentifierStart(cp)) { 110 docenv().warning(holder, 111 "tag.serialField.illegal_character", 112 new String(Character.toChars(cp)), text); 113 return; 114 } 115 116 for (inx += Character.charCount(cp); inx < len; inx += Character.charCount(cp)) { 117 cp = text.codePointAt(inx); 118 if (!Character.isJavaIdentifierPart(cp)) { 119 break; 120 } 121 } 122 123 if (inx < len && ! Character.isWhitespace(cp = text.codePointAt(inx))) { 124 docenv().warning(holder, 125 "tag.serialField.illegal_character", 126 new String(Character.toChars(cp)), text); 127 return; 128 } 129 130 last = inx; 131 fieldName = text.substring(first, last); 132 133 /* Skip white space. */ 134 for (; inx < len; inx += Character.charCount(cp)) { 135 cp = text.codePointAt(inx); 136 if (!Character.isWhitespace(cp)) { 137 break; 138 } 139 } 140 141 /* find second word. */ 142 first = inx; 143 last = inx; 144 145 for (; inx < len; inx += Character.charCount(cp)) { 146 cp = text.codePointAt(inx); 147 if (Character.isWhitespace(cp)) { 148 break; 149 } 150 } 151 if (inx < len && ! Character.isWhitespace(cp = text.codePointAt(inx))) { 152 docenv().warning(holder, 153 "tag.serialField.illegal_character", 154 new String(Character.toChars(cp)), text); 155 return; 156 } 157 last = inx; 158 fieldType = text.substring(first, last); 159 160 /* Skip leading white space. Rest of string is description for serialField.*/ 161 for (; inx < len; inx += Character.charCount(cp)) { 162 cp = text.codePointAt(inx); 163 if (!Character.isWhitespace(cp)) { 164 break; 165 } 166 } 167 description = text.substring(inx); 168 } 169 170 /** 171 * return a key for sorting. 172 */ key()173 String key() { 174 return fieldName; 175 } 176 177 /* 178 * Optional. Link this serialField tag to its corrsponding 179 * field in the class. Note: there is no requirement that 180 * there be a field in the class that matches serialField tag. 181 */ mapToFieldDocImpl(FieldDocImpl fd)182 void mapToFieldDocImpl(FieldDocImpl fd) { 183 matchingField = fd; 184 } 185 186 /** 187 * Return the serialziable field name. 188 */ fieldName()189 public String fieldName() { 190 return fieldName; 191 } 192 193 /** 194 * Return the field type string. 195 */ fieldType()196 public String fieldType() { 197 return fieldType; 198 } 199 200 /** 201 * Return the ClassDocImpl for field type. 202 * 203 * @returns null if no ClassDocImpl for field type is visible from 204 * containingClass context. 205 */ fieldTypeDoc()206 public ClassDoc fieldTypeDoc() { 207 if (fieldTypeDoc == null && containingClass != null) { 208 fieldTypeDoc = containingClass.findClass(fieldType); 209 } 210 return fieldTypeDoc; 211 } 212 213 /** 214 * Return the corresponding FieldDocImpl for this SerialFieldTagImpl. 215 * 216 * @returns null if no matching FieldDocImpl. 217 */ getMatchingField()218 FieldDocImpl getMatchingField() { 219 return matchingField; 220 } 221 222 /** 223 * Return the field comment. If there is no serialField comment, return 224 * javadoc comment of corresponding FieldDocImpl. 225 */ description()226 public String description() { 227 if (description.length() == 0 && matchingField != null) { 228 229 //check for javadoc comment of corresponding field. 230 Comment comment = matchingField.comment(); 231 if (comment != null) { 232 return comment.commentText(); 233 } 234 } 235 return description; 236 } 237 238 /** 239 * Return the kind of this tag. 240 */ kind()241 public String kind() { 242 return "@serialField"; 243 } 244 245 /** 246 * Convert this object to a string. 247 */ toString()248 public String toString() { 249 return name + ":" + text; 250 } 251 252 /** 253 * Compares this Object with the specified Object for order. Returns a 254 * negative integer, zero, or a positive integer as this Object is less 255 * than, equal to, or greater than the given Object. 256 * <p> 257 * Included to make SerialFieldTagImpl items java.lang.Comparable. 258 * 259 * @param obj the <code>Object</code> to be compared. 260 * @return a negative integer, zero, or a positive integer as this Object 261 * is less than, equal to, or greater than the given Object. 262 * @exception ClassCastException the specified Object's type prevents it 263 * from being compared to this Object. 264 * @since 1.2 265 */ compareTo(Object obj)266 public int compareTo(Object obj) { 267 return key().compareTo(((SerialFieldTagImpl)obj).key()); 268 } 269 } 270