src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/SerializedFormBuilder.java

Mon, 09 Mar 2009 23:53:41 -0700

author
tbell
date
Mon, 09 Mar 2009 23:53:41 -0700
changeset 240
8c55d5b0ed71
parent 229
03bcd66bd8e7
parent 233
5240b1120530
child 554
9d9f26857129
permissions
-rw-r--r--

Merge

duke@1 1 /*
xdono@229 2 * Copyright 2003-2009 Sun Microsystems, Inc. All Rights Reserved.
duke@1 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
duke@1 4 *
duke@1 5 * This code is free software; you can redistribute it and/or modify it
duke@1 6 * under the terms of the GNU General Public License version 2 only, as
duke@1 7 * published by the Free Software Foundation. Sun designates this
duke@1 8 * particular file as subject to the "Classpath" exception as provided
duke@1 9 * by Sun in the LICENSE file that accompanied this code.
duke@1 10 *
duke@1 11 * This code is distributed in the hope that it will be useful, but WITHOUT
duke@1 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
duke@1 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
duke@1 14 * version 2 for more details (a copy is included in the LICENSE file that
duke@1 15 * accompanied this code).
duke@1 16 *
duke@1 17 * You should have received a copy of the GNU General Public License version
duke@1 18 * 2 along with this work; if not, write to the Free Software Foundation,
duke@1 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
duke@1 20 *
duke@1 21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
duke@1 22 * CA 95054 USA or visit www.sun.com if you need additional information or
duke@1 23 * have any questions.
duke@1 24 */
duke@1 25
duke@1 26 package com.sun.tools.doclets.internal.toolkit.builders;
duke@1 27
duke@1 28 import java.io.*;
duke@1 29 import java.lang.reflect.*;
duke@1 30 import java.util.*;
duke@1 31
bpatel@233 32 import com.sun.javadoc.*;
bpatel@233 33 import com.sun.tools.doclets.internal.toolkit.util.*;
bpatel@233 34 import com.sun.tools.doclets.internal.toolkit.*;
bpatel@233 35
duke@1 36 /**
duke@1 37 * Builds the serialized form.
duke@1 38 *
duke@1 39 * This code is not part of an API.
duke@1 40 * It is implementation that is subject to change.
duke@1 41 * Do not use it as an API
duke@1 42 *
duke@1 43 * @author Jamie Ho
bpatel@233 44 * @author Bhavesh Patel (Modified)
duke@1 45 * @since 1.5
duke@1 46 */
duke@1 47 public class SerializedFormBuilder extends AbstractBuilder {
duke@1 48
duke@1 49 /**
duke@1 50 * The root element of the serialized form XML is {@value}.
duke@1 51 */
duke@1 52 public static final String NAME = "SerializedForm";
duke@1 53
duke@1 54 /**
duke@1 55 * The writer for this builder.
duke@1 56 */
duke@1 57 private SerializedFormWriter writer;
duke@1 58
duke@1 59 /**
duke@1 60 * The writer for serializable fields.
duke@1 61 */
duke@1 62 private SerializedFormWriter.SerialFieldWriter fieldWriter;
duke@1 63
duke@1 64 /**
duke@1 65 * The writer for serializable method documentation.
duke@1 66 */
duke@1 67 private SerializedFormWriter.SerialMethodWriter methodWriter;
duke@1 68
duke@1 69 /**
duke@1 70 * The header for the serial version UID. Save the string
duke@1 71 * here instead of the properties file because we do not want
duke@1 72 * this string to be localized.
duke@1 73 */
duke@1 74 private static final String SERIAL_VERSION_UID_HEADER = "serialVersionUID:";
duke@1 75
duke@1 76 /**
duke@1 77 * The current package being documented.
duke@1 78 */
duke@1 79 private PackageDoc currentPackage;
duke@1 80
duke@1 81 /**
duke@1 82 * The current class being documented.
duke@1 83 */
duke@1 84 private ClassDoc currentClass;
duke@1 85
duke@1 86 /**
duke@1 87 * The current member being documented.
duke@1 88 */
duke@1 89 protected MemberDoc currentMember;
duke@1 90
duke@1 91 private SerializedFormBuilder(Configuration configuration) {
duke@1 92 super(configuration);
duke@1 93 }
duke@1 94
duke@1 95 /**
duke@1 96 * Construct a new SerializedFormBuilder.
duke@1 97 * @param configuration the current configuration of the doclet.
duke@1 98 */
duke@1 99 public static SerializedFormBuilder getInstance(Configuration configuration) {
duke@1 100 SerializedFormBuilder builder = new SerializedFormBuilder(configuration);
duke@1 101 return builder;
duke@1 102 }
duke@1 103
duke@1 104 /**
duke@1 105 * Build the serialized form.
duke@1 106 */
duke@1 107 public void build() throws IOException {
duke@1 108 if (! serialClassFoundToDocument(configuration.root.classes())) {
duke@1 109 //Nothing to document.
duke@1 110 return;
duke@1 111 }
duke@1 112 try {
duke@1 113 writer = configuration.getWriterFactory().getSerializedFormWriter();
duke@1 114 if (writer == null) {
duke@1 115 //Doclet does not support this output.
duke@1 116 return;
duke@1 117 }
duke@1 118 } catch (Exception e) {
duke@1 119 throw new DocletAbortException();
duke@1 120 }
duke@1 121 build(LayoutParser.getInstance(configuration).parseXML(NAME));
duke@1 122 writer.close();
duke@1 123 }
duke@1 124
duke@1 125 /**
duke@1 126 * {@inheritDoc}
duke@1 127 */
duke@1 128 public String getName() {
duke@1 129 return NAME;
duke@1 130 }
duke@1 131
duke@1 132 /**
duke@1 133 * Build the serialized form.
duke@1 134 */
mcimadamore@184 135 public void buildSerializedForm(List<?> elements) throws Exception {
duke@1 136 build(elements);
duke@1 137 writer.close();
duke@1 138 }
duke@1 139
duke@1 140 /**
duke@1 141 * {@inheritDoc}
duke@1 142 */
mcimadamore@184 143 public void invokeMethod(String methodName, Class<?>[] paramClasses,
duke@1 144 Object[] params)
duke@1 145 throws Exception {
duke@1 146 if (DEBUG) {
duke@1 147 configuration.root.printError("DEBUG: " + this.getClass().getName()
duke@1 148 + "." + methodName);
duke@1 149 }
duke@1 150 Method method = this.getClass().getMethod(methodName, paramClasses);
duke@1 151 method.invoke(this, params);
duke@1 152 }
duke@1 153
duke@1 154 /**
duke@1 155 * Build the header.
duke@1 156 */
duke@1 157 public void buildHeader() {
duke@1 158 writer.writeHeader(configuration.getText("doclet.Serialized_Form"));
duke@1 159 }
duke@1 160
duke@1 161 /**
duke@1 162 * Build the contents.
duke@1 163 */
mcimadamore@184 164 public void buildSerializedFormSummaries(List<?> elements) {
duke@1 165 PackageDoc[] packages = configuration.packages;
duke@1 166 for (int i = 0; i < packages.length; i++) {
duke@1 167 currentPackage = packages[i];
duke@1 168 build(elements);
duke@1 169 }
duke@1 170 }
duke@1 171
duke@1 172 /**
duke@1 173 * Build the package serialized for for the current package being processed.
duke@1 174 */
mcimadamore@184 175 public void buildPackageSerializedForm(List<?> elements) {
duke@1 176 String foo = currentPackage.name();
duke@1 177 ClassDoc[] classes = currentPackage.allClasses(false);
duke@1 178 if (classes == null || classes.length == 0) {
duke@1 179 return;
duke@1 180 }
duke@1 181 if (!serialInclude(currentPackage)) {
duke@1 182 return;
duke@1 183 }
duke@1 184 if (!serialClassFoundToDocument(classes)) {
duke@1 185 return;
duke@1 186 }
duke@1 187 build(elements);
duke@1 188 }
duke@1 189
duke@1 190 public void buildPackageHeader() {
duke@1 191 writer.writePackageHeader(Util.getPackageName(currentPackage));
duke@1 192 }
duke@1 193
mcimadamore@184 194 public void buildClassSerializedForm(List<?> elements) {
duke@1 195 ClassDoc[] classes = currentPackage.allClasses(false);
duke@1 196 Arrays.sort(classes);
duke@1 197 for (int j = 0; j < classes.length; j++) {
duke@1 198 currentClass = classes[j];
duke@1 199 fieldWriter = writer.getSerialFieldWriter(currentClass);
duke@1 200 methodWriter = writer.getSerialMethodWriter(currentClass);
duke@1 201 if(currentClass.isClass() && currentClass.isSerializable()) {
duke@1 202 if(!serialClassInclude(currentClass)) {
duke@1 203 continue;
duke@1 204 }
duke@1 205 build(elements);
duke@1 206 }
duke@1 207 }
duke@1 208 }
duke@1 209
duke@1 210 public void buildClassHeader() {
duke@1 211 writer.writeClassHeader(currentClass);
duke@1 212 }
duke@1 213
duke@1 214 /**
duke@1 215 * Build the serial UID information for the given class.
duke@1 216 */
duke@1 217 public void buildSerialUIDInfo() {
duke@1 218 FieldDoc[] fields = currentClass.fields(false);
duke@1 219 for (int i = 0; i < fields.length; i++) {
duke@1 220 if (fields[i].name().equals("serialVersionUID") &&
duke@1 221 fields[i].constantValueExpression() != null) {
duke@1 222 writer.writeSerialUIDInfo(SERIAL_VERSION_UID_HEADER,
duke@1 223 fields[i].constantValueExpression());
duke@1 224 return;
duke@1 225 }
duke@1 226 }
duke@1 227 }
duke@1 228
duke@1 229 /**
duke@1 230 * Build the footer.
duke@1 231 */
duke@1 232 public void buildFooter() {
duke@1 233 writer.writeFooter();
duke@1 234 }
duke@1 235
duke@1 236 /**
duke@1 237 * Return true if the given Doc should be included
duke@1 238 * in the serialized form.
duke@1 239 *
duke@1 240 * @param doc the Doc object to check for serializability.
duke@1 241 */
duke@1 242 public static boolean serialInclude(Doc doc) {
duke@1 243 if (doc == null) {
duke@1 244 return false;
duke@1 245 }
duke@1 246 return doc.isClass() ?
duke@1 247 serialClassInclude((ClassDoc)doc) :
duke@1 248 serialDocInclude(doc);
duke@1 249 }
duke@1 250
duke@1 251 /**
duke@1 252 * Return true if the given ClassDoc should be included
duke@1 253 * in the serialized form.
duke@1 254 *
duke@1 255 * @param cd the ClassDoc object to check for serializability.
duke@1 256 */
duke@1 257 private static boolean serialClassInclude(ClassDoc cd) {
duke@1 258 if (cd.isEnum()) {
duke@1 259 return false;
duke@1 260 }
duke@1 261 try {
duke@1 262 cd.superclassType();
duke@1 263 } catch (NullPointerException e) {
duke@1 264 //Workaround for null pointer bug in ClassDoc.superclassType().
duke@1 265 return false;
duke@1 266 }
duke@1 267 if (cd.isSerializable()) {
duke@1 268 if (cd.tags("serial").length > 0) {
duke@1 269 return serialDocInclude(cd);
duke@1 270 } else if (cd.isPublic() || cd.isProtected()) {
duke@1 271 return true;
duke@1 272 } else {
duke@1 273 return false;
duke@1 274 }
duke@1 275 }
duke@1 276 return false;
duke@1 277 }
duke@1 278
duke@1 279 /**
duke@1 280 * Return true if the given Doc should be included
duke@1 281 * in the serialized form.
duke@1 282 *
duke@1 283 * @param doc the Doc object to check for serializability.
duke@1 284 */
duke@1 285 private static boolean serialDocInclude(Doc doc) {
duke@1 286 if (doc.isEnum()) {
duke@1 287 return false;
duke@1 288 }
duke@1 289 Tag[] serial = doc.tags("serial");
duke@1 290 if (serial.length > 0) {
duke@1 291 String serialtext = serial[0].text().toLowerCase();
duke@1 292 if (serialtext.indexOf("exclude") >= 0) {
duke@1 293 return false;
duke@1 294 } else if (serialtext.indexOf("include") >= 0) {
duke@1 295 return true;
duke@1 296 }
duke@1 297 }
duke@1 298 return true;
duke@1 299 }
duke@1 300
duke@1 301 /**
duke@1 302 * Return true if any of the given classes have a @serialinclude tag.
duke@1 303 *
duke@1 304 * @param classes the classes to check.
duke@1 305 * @return true if any of the given classes have a @serialinclude tag.
duke@1 306 */
duke@1 307 private boolean serialClassFoundToDocument(ClassDoc[] classes) {
duke@1 308 for (int i = 0; i < classes.length; i++) {
duke@1 309 if (serialClassInclude(classes[i])) {
duke@1 310 return true;
duke@1 311 }
duke@1 312 }
duke@1 313 return false;
duke@1 314 }
duke@1 315
duke@1 316 /**
duke@1 317 * Build the method header.
duke@1 318 */
duke@1 319 public void buildMethodHeader() {
duke@1 320 if (currentClass.serializationMethods().length > 0) {
duke@1 321 methodWriter.writeHeader(
duke@1 322 configuration.getText("doclet.Serialized_Form_methods"));
duke@1 323 if (currentClass.isSerializable() && !currentClass.isExternalizable()) {
duke@1 324 if (currentClass.serializationMethods().length == 0) {
duke@1 325 methodWriter.writeNoCustomizationMsg(
duke@1 326 configuration.getText(
duke@1 327 "doclet.Serializable_no_customization"));
duke@1 328 }
duke@1 329 }
duke@1 330 }
duke@1 331 }
duke@1 332
duke@1 333 /**
duke@1 334 * Build the method sub header.
duke@1 335 */
duke@1 336 public void buildMethodSubHeader() {
duke@1 337 methodWriter.writeMemberHeader((MethodDoc) currentMember);
duke@1 338 }
duke@1 339
duke@1 340 /**
duke@1 341 * Build the deprecated method description.
duke@1 342 */
duke@1 343 public void buildDeprecatedMethodInfo() {
duke@1 344 methodWriter.writeDeprecatedMemberInfo((MethodDoc) currentMember);
duke@1 345 }
duke@1 346
duke@1 347 /**
duke@1 348 * Build method tags.
duke@1 349 */
duke@1 350 public void buildMethodDescription() {
duke@1 351 methodWriter.writeMemberDescription((MethodDoc) currentMember);
duke@1 352 }
duke@1 353
duke@1 354 /**
duke@1 355 * Build the method tags.
duke@1 356 */
duke@1 357 public void buildMethodTags() {
duke@1 358 methodWriter.writeMemberTags((MethodDoc) currentMember);
duke@1 359 MethodDoc method = (MethodDoc)currentMember;
duke@1 360 if (method.name().compareTo("writeExternal") == 0
duke@1 361 && method.tags("serialData").length == 0) {
duke@1 362 if (configuration.serialwarn) {
duke@1 363 configuration.getDocletSpecificMsg().warning(
duke@1 364 currentMember.position(), "doclet.MissingSerialDataTag",
duke@1 365 method.containingClass().qualifiedName(), method.name());
duke@1 366 }
duke@1 367 }
duke@1 368 }
duke@1 369
duke@1 370 /**
duke@1 371 * build the information for the method.
duke@1 372 */
mcimadamore@184 373 public void buildMethodInfo(List<?> elements) {
duke@1 374 if(configuration.nocomment){
duke@1 375 return;
duke@1 376 }
duke@1 377 build(elements);
duke@1 378 }
duke@1 379
duke@1 380 /**
duke@1 381 * Build the method footer.
duke@1 382 */
duke@1 383 public void buildMethodFooter() {
bpatel@233 384 methodWriter.writeMemberFooter();
duke@1 385 }
duke@1 386
duke@1 387 /**
duke@1 388 * Build the field header.
duke@1 389 */
duke@1 390 public void buildFieldHeader() {
duke@1 391 if (currentClass.serializableFields().length > 0) {
duke@1 392 buildFieldSerializationOverview(currentClass);
duke@1 393 fieldWriter.writeHeader(configuration.getText(
duke@1 394 "doclet.Serialized_Form_fields"));
duke@1 395 }
duke@1 396 }
duke@1 397
duke@1 398 /**
duke@1 399 * If possible, build the serialization overview for the given
duke@1 400 * class.
duke@1 401 *
duke@1 402 * @param classDoc the class to print the overview for.
duke@1 403 */
duke@1 404 public void buildFieldSerializationOverview(ClassDoc classDoc) {
duke@1 405 if (classDoc.definesSerializableFields()) {
duke@1 406 FieldDoc serialPersistentField =
jjg@198 407 Util.asList(classDoc.serializableFields()).get(0);
bpatel@222 408 // Check to see if there are inline comments, tags or deprecation
bpatel@222 409 // information to be printed.
bpatel@233 410 if (fieldWriter.shouldPrintOverview(serialPersistentField)) {
duke@1 411 fieldWriter.writeHeader(
bpatel@233 412 configuration.getText("doclet.Serialized_Form_class"));
bpatel@222 413 fieldWriter.writeMemberDeprecatedInfo(serialPersistentField);
duke@1 414 if (!configuration.nocomment) {
duke@1 415 fieldWriter.writeMemberDescription(serialPersistentField);
duke@1 416 fieldWriter.writeMemberTags(serialPersistentField);
duke@1 417 }
bpatel@233 418 // Footer required to close the definition list tag
bpatel@233 419 // for serialization overview.
bpatel@233 420 fieldWriter.writeFooter(
bpatel@233 421 configuration.getText("doclet.Serialized_Form_class"));
duke@1 422 }
duke@1 423 }
duke@1 424 }
duke@1 425
duke@1 426 /**
duke@1 427 * Build the field sub header.
duke@1 428 */
duke@1 429 public void buildFieldSubHeader() {
duke@1 430 if (! currentClass.definesSerializableFields() ){
duke@1 431 FieldDoc field = (FieldDoc) currentMember;
duke@1 432 fieldWriter.writeMemberHeader(field.type().asClassDoc(),
duke@1 433 field.type().typeName(), field.type().dimension(), field.name());
duke@1 434 }
duke@1 435 }
duke@1 436
duke@1 437 /**
bpatel@222 438 * Build the field deprecation information.
bpatel@222 439 */
bpatel@222 440 public void buildFieldDeprecationInfo() {
bpatel@222 441 if (!currentClass.definesSerializableFields()) {
bpatel@222 442 FieldDoc field = (FieldDoc)currentMember;
bpatel@222 443 fieldWriter.writeMemberDeprecatedInfo(field);
bpatel@222 444 }
bpatel@222 445 }
bpatel@222 446
bpatel@222 447 /**
duke@1 448 * Build the field information.
duke@1 449 */
duke@1 450 public void buildFieldInfo() {
duke@1 451 if(configuration.nocomment){
duke@1 452 return;
duke@1 453 }
duke@1 454 FieldDoc field = (FieldDoc)currentMember;
duke@1 455 ClassDoc cd = field.containingClass();
duke@1 456 if (cd.definesSerializableFields()) {
duke@1 457 // Process Serializable Fields specified as array of
duke@1 458 // ObjectStreamFields. Print a member for each serialField tag.
duke@1 459 // (There should be one serialField tag per ObjectStreamField
duke@1 460 // element.)
duke@1 461 SerialFieldTag[] tags = field.serialFieldTags();
duke@1 462 Arrays.sort(tags);
duke@1 463 for (int i = 0; i < tags.length; i++) {
duke@1 464 fieldWriter.writeMemberHeader(tags[i].fieldTypeDoc(),
duke@1 465 tags[i].fieldType(), "", tags[i].fieldName());
duke@1 466 fieldWriter.writeMemberDescription(tags[i]);
duke@1 467
duke@1 468 }
duke@1 469 } else {
duke@1 470
duke@1 471 // Process default Serializable field.
duke@1 472 if ((field.tags("serial").length == 0) && ! field.isSynthetic()
duke@1 473 && configuration.serialwarn) {
duke@1 474 configuration.message.warning(field.position(),
duke@1 475 "doclet.MissingSerialTag", cd.qualifiedName(),
duke@1 476 field.name());
duke@1 477 }
duke@1 478 fieldWriter.writeMemberDescription(field);
duke@1 479 fieldWriter.writeMemberTags(field);
duke@1 480 }
duke@1 481 }
duke@1 482
duke@1 483 /**
bpatel@233 484 * Build the field sub footer.
duke@1 485 */
bpatel@233 486 public void buildFieldSubFooter() {
duke@1 487 if (! currentClass.definesSerializableFields()) {
bpatel@233 488 fieldWriter.writeMemberFooter();
duke@1 489 }
duke@1 490 }
duke@1 491
duke@1 492 /**
duke@1 493 * Build the summaries for the methods that belong to the given
duke@1 494 * class.
duke@1 495 */
mcimadamore@184 496 public void buildSerializableMethods(List<?> elements) {
duke@1 497 MemberDoc[] members = currentClass.serializationMethods();
duke@1 498 if (members.length > 0) {
duke@1 499 for (int i = 0; i < members.length; i++) {
duke@1 500 currentMember = members[i];
duke@1 501 build(elements);
duke@1 502 }
duke@1 503 }
duke@1 504 }
duke@1 505
duke@1 506 /**
duke@1 507 * Build the summaries for the fields that belong to the given
duke@1 508 * class.
duke@1 509 */
mcimadamore@184 510 public void buildSerializableFields(List<?> elements) {
duke@1 511 MemberDoc[] members = currentClass.serializableFields();
duke@1 512 if (members.length > 0) {
duke@1 513 for (int i = 0; i < members.length; i++) {
duke@1 514 currentMember = members[i];
duke@1 515 build(elements);
duke@1 516 }
duke@1 517 }
duke@1 518 }
duke@1 519 }

mercurial