001 /* 002 * CDDL HEADER START 003 * 004 * The contents of this file are subject to the terms of the 005 * Common Development and Distribution License, Version 1.0 only 006 * (the "License"). You may not use this file except in compliance 007 * with the License. 008 * 009 * You can obtain a copy of the license at 010 * trunk/opends/resource/legal-notices/OpenDS.LICENSE 011 * or https://OpenDS.dev.java.net/OpenDS.LICENSE. 012 * See the License for the specific language governing permissions 013 * and limitations under the License. 014 * 015 * When distributing Covered Code, include this CDDL HEADER in each 016 * file and include the License file at 017 * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, 018 * add the following below this CDDL HEADER, with the fields enclosed 019 * by brackets "[]" replaced with your own identifying information: 020 * Portions Copyright [yyyy] [name of copyright owner] 021 * 022 * CDDL HEADER END 023 * 024 * 025 * Copyright 2007-2008 Sun Microsystems, Inc. 026 */ 027 package org.opends.server.admin.doc; 028 029 import java.io.File; 030 import java.io.PrintWriter; 031 import java.util.Collection; 032 import java.util.Iterator; 033 import java.util.Properties; 034 import java.util.TreeMap; 035 import java.util.TreeSet; 036 import org.opends.messages.Message; 037 import org.opends.server.admin.ACIPropertyDefinition; 038 import org.opends.server.admin.AbsoluteInheritedDefaultBehaviorProvider; 039 import org.opends.server.admin.AbstractManagedObjectDefinition; 040 import org.opends.server.admin.AdministratorAction.Type; 041 import org.opends.server.admin.AggregationPropertyDefinition; 042 import org.opends.server.admin.AliasDefaultBehaviorProvider; 043 import org.opends.server.admin.AttributeTypePropertyDefinition; 044 import org.opends.server.admin.BooleanPropertyDefinition; 045 import org.opends.server.admin.ClassLoaderProvider; 046 import org.opends.server.admin.ClassPropertyDefinition; 047 import org.opends.server.admin.DNPropertyDefinition; 048 import org.opends.server.admin.DefaultBehaviorProvider; 049 import org.opends.server.admin.DefinedDefaultBehaviorProvider; 050 import org.opends.server.admin.DurationPropertyDefinition; 051 import org.opends.server.admin.EnumPropertyDefinition; 052 import org.opends.server.admin.IPAddressMaskPropertyDefinition; 053 import org.opends.server.admin.IPAddressPropertyDefinition; 054 import org.opends.server.admin.IntegerPropertyDefinition; 055 import org.opends.server.admin.LDAPProfile; 056 import org.opends.server.admin.PropertyDefinition; 057 import org.opends.server.admin.PropertyDefinitionVisitor; 058 import org.opends.server.admin.PropertyOption; 059 import org.opends.server.admin.RelationDefinition; 060 import org.opends.server.admin.RelationOption; 061 import org.opends.server.admin.RelativeInheritedDefaultBehaviorProvider; 062 import org.opends.server.admin.SizePropertyDefinition; 063 import org.opends.server.admin.StringPropertyDefinition; 064 import org.opends.server.admin.Tag; 065 import org.opends.server.admin.TopCfgDefn; 066 import org.opends.server.admin.UndefinedDefaultBehaviorProvider; 067 import org.opends.server.admin.std.meta.RootCfgDefn; 068 import org.opends.server.types.InitializationException; 069 import org.opends.server.util.EmbeddedUtils; 070 071 /** 072 * This class allow Configuration Guide documentation generation (html format). 073 * It is based on the Admin Framework Introspection API 074 * 075 */ 076 public class ConfigGuideGeneration { 077 078 // Note : still to be done : 079 // I18n support. Today all the strings are hardcoded in this file 080 081 private final static String ACI_SYNTAX_REL_URL = "/page/ACISyntax"; 082 private final static String DURATION_SYNTAX_REL_URL = 083 "/page/DefinitionDuration"; 084 private final String CSS_FILE = "opends-config.css"; 085 086 private final String MAIN_FILE = "index.html"; 087 private final String INHERITANCE_TREE_FILE = 088 "ManagedObjectInheritanceTree.html"; 089 private final String RELATION_TREE_FILE = "ManagedObjectRelationTree.html"; 090 private final String MO_LIST_FILE = "ManagedObjectList.html"; 091 private final String PROPERTIES_INDEX_FILE = "PropertiesIndex.html"; 092 private final String WELCOME_FILE = "welcome.html"; 093 private final String MAINTOP_FILE = "maintop.html"; 094 private final String INDEX_FILE = "index.html"; 095 096 private static final String CONFIG_GUIDE_DIR = "opends_config_guide"; 097 private final String MAIN_FRAME = "mainFrame"; 098 099 /** 100 * Entry point for documentation generation. 101 * 102 * Properties: 103 * GenerationDir - The directory where the doc is generated 104 * (default is /var/tmp/[CONFIG_GUIDE_DIR>]) 105 * LdapMapping - Presence means that the LDAP mapping section is to be 106 * generated (default is no) 107 * OpendsWiki - The URL of the OpenDS Wiki 108 * (default is "https://www.opends.org/wiki") 109 * OpendsHome - The URL of the OpenDS project Home page 110 * (default is "http://www.opends.org") 111 * 112 * @param args none. 113 */ 114 public static void main(String[] args) { 115 Properties properties = System.getProperties(); 116 generationDir = properties.getProperty("GenerationDir"); 117 if (generationDir == null) { 118 // Default dir is prefixed by the system-dependent default temporary dir 119 generationDir = System.getProperty("java.io.tmpdir") + File.separator + 120 CONFIG_GUIDE_DIR; 121 } 122 // Create new dir if necessary 123 try { 124 (new File(generationDir)).mkdir(); 125 } catch (Exception e) { 126 e.printStackTrace(); 127 System.exit(1); 128 } 129 System.out.println("Generation directory is : " + generationDir); 130 131 if (properties.getProperty("LdapMapping") != null) { 132 ldapMapping = true; 133 } 134 135 opendsWiki = properties.getProperty("OpendsWiki"); 136 if (opendsWiki == null) { 137 // Default is current wiki 138 opendsWiki = "https://www.opends.org/wiki"; 139 } 140 aciSyntaxPage = opendsWiki + ACI_SYNTAX_REL_URL; 141 durationSyntaxPage = opendsWiki + DURATION_SYNTAX_REL_URL; 142 143 opendsHome = properties.getProperty("OpendsHome"); 144 if (opendsHome == null) { 145 // Default is current OpenDS project home 146 opendsHome = "http://www.opends.org"; 147 } 148 149 ConfigGuideGeneration myGen = new ConfigGuideGeneration(); 150 myGen.generate(); 151 } 152 153 private void generate() { 154 init(); 155 156 // Generate the relation tree of all the managed objects 157 genManagedObjectRelationTree(catTopRelList); 158 159 // Generate the inheritance tree of all the managed objects 160 genManagedObjectInheritanceTree(catTopMoList); 161 162 // Generate all the managed objects and their children 163 genAllManagedObject(topMoList); 164 165 // Generate a list of managed objects 166 genManagedObjectList(moList); 167 168 // Generate an index of properties 169 genPropertiesIndex(); 170 171 // Generate the Index page 172 genIndexPage(); 173 174 // Generate the Main Top page 175 genMainTopPage(); 176 177 // Generate the Welcome page 178 genWelcomePage(); 179 } 180 181 private void init() { 182 183 // Build a list of top relations 184 RootCfgDefn rootCfg = RootCfgDefn.getInstance(); 185 for (RelationDefinition rel : rootCfg.getAllRelationDefinitions()) { 186 topRelList.put(rel.getChildDefinition().getName(), rel); 187 } 188 189 // Enable the client-side class loader to explicitly load classes 190 // which are not directly reachable from the root configuration 191 EmbeddedUtils.initializeForClientUse(); 192 // Bootstrap definition classes. 193 try { 194 ClassLoaderProvider.getInstance().enable(); 195 } catch (InitializationException e) { 196 System.err.println("ERROR : Cannot enable the client-side class loader."); 197 e.printStackTrace(); 198 System.exit(1); 199 } 200 // Switch off class name validation in client. 201 ClassPropertyDefinition.setAllowClassValidation(false); 202 // Switch off attribute type name validation in client. 203 AttributeTypePropertyDefinition.setCheckSchema(false); 204 205 // Build a sorted list of top managed objects 206 TopCfgDefn topCfg = TopCfgDefn.getInstance(); 207 Collection<AbstractManagedObjectDefinition<?, ?>> topObjects = 208 topCfg.getChildren(); 209 for (AbstractManagedObjectDefinition topObject : topObjects) { 210 if (topObject.getName().equals("")) { 211 // root 212 continue; 213 } 214 topMoList.put(topObject.getName(), topObject); 215 } 216 217 218 // Build a list of top relations by category (core, database, ...) 219 for (RelationDefinition rel : topRelList.values()) { 220 AbstractManagedObjectDefinition<?, ?> mo = rel.getChildDefinition(); 221 Collection<Tag> tags = mo.getAllTags(); 222 for (Tag tag : tags) { 223 TreeMap<String, RelationDefinition> catMap = 224 catTopRelList.get(tag.getName()); 225 if (catMap == null) { 226 catMap = new TreeMap<String, RelationDefinition>(); 227 catTopRelList.put(tag.getName(), catMap); 228 } 229 catMap.put(mo.getName(), rel); 230 } 231 } 232 233 // Build a list of top managed objects by category (core, database, ...) 234 for (AbstractManagedObjectDefinition<?, ?> topObject : topMoList.values()) { 235 Collection<Tag> tags = topObject.getAllTags(); 236 for (Tag tag : tags) { 237 TreeMap<String, AbstractManagedObjectDefinition> catMap = 238 catTopMoList.get(tag.getName()); 239 if (catMap == null) { 240 catMap = new TreeMap<String, AbstractManagedObjectDefinition>(); 241 catTopMoList.put(tag.getName(), catMap); 242 } 243 catMap.put(topObject.getName(), topObject); 244 } 245 } 246 247 } 248 249 /** 250 * Generate the inheritance tree of all the managed objects. 251 */ 252 @SuppressWarnings("unchecked") 253 private void genManagedObjectInheritanceTree( 254 TreeMap<String, TreeMap<String, AbstractManagedObjectDefinition>> list) { 255 256 htmlHeader("OpenDS Configuration Reference - Inheritance View"); 257 tabMenu(INHERITANCE_TREE_FILE); 258 viewHelp("This view represents the inheritance relationships between " + 259 "configuration components."); 260 jumpSection(); 261 262 for (String catName : list.keySet()) { 263 heading3(getFriendlyName(catName)); 264 // Get the list of the category 265 TreeMap<String, AbstractManagedObjectDefinition> catList = 266 list.get(catName); 267 for (AbstractManagedObjectDefinition mo : catList.values()) { 268 if ((relList.get(mo.getName()) != null) && 269 (relList.get(mo.getName()).hasOption(RelationOption.HIDDEN))) { 270 continue; 271 } 272 paragraph( 273 getLink(mo.getUserFriendlyName().toString(), 274 mo.getName() + ".html", MAIN_FRAME)); 275 if (mo.hasChildren()) { 276 genMoInheritanceTree(makeMOTreeMap(mo.getChildren())); 277 } 278 } 279 } 280 281 htmlFooter(); 282 generateFile(INHERITANCE_TREE_FILE); 283 } 284 285 @SuppressWarnings("unchecked") 286 private void genMoInheritanceTree( 287 TreeMap<String, AbstractManagedObjectDefinition> catList) { 288 289 beginList(); 290 for (AbstractManagedObjectDefinition mo : catList.values()) { 291 link(mo.getUserFriendlyName().toString(), mo.getName() + ".html", 292 MAIN_FRAME); 293 if (mo.hasChildren()) { 294 genMoInheritanceTree(makeMOTreeMap(mo.getChildren())); 295 } 296 } 297 endList(); 298 } 299 300 private void jumpSection() { 301 htmlBuff.append("<p class=\"category-index\">" + 302 "<strong>Jump To:</strong><br>\n"); 303 304 String[] catNames = catTopMoList.keySet().toArray(new String[0]); 305 for (int ii=0; ii < catNames.length; ii++) { 306 if (ii != 0) { 307 htmlBuff.append(", "); 308 } 309 String catFriendlyName = getFriendlyName(catNames[ii]); 310 htmlBuff.append(getLink(catFriendlyName, "#" + catFriendlyName)); 311 } 312 htmlBuff.append("</p>\n"); 313 } 314 315 316 /** 317 * Generate the relation tree of all the managed objects. 318 */ 319 private void genManagedObjectRelationTree( 320 TreeMap <String, TreeMap<String, RelationDefinition>> list) { 321 322 htmlHeader("OpenDS Configuration Reference - Structure View"); 323 tabMenu(RELATION_TREE_FILE); 324 viewHelp("This view represents the structural relationships between " + 325 "components and indicates how certain components can exist only within " + 326 "container components."); 327 jumpSection(); 328 329 for (String catName : list.keySet()) { 330 heading3(getFriendlyName(catName)); 331 // Get the list of the category 332 TreeMap<String, RelationDefinition> catList = list.get(catName); 333 genMORelationTree(catList); 334 } 335 336 htmlFooter(); 337 generateFile(RELATION_TREE_FILE); 338 } 339 340 341 @SuppressWarnings("unchecked") 342 private void genMORelationTree(TreeMap<String, RelationDefinition> list) { 343 for (RelationDefinition rel : list.values()) { 344 AbstractManagedObjectDefinition childMo = rel.getChildDefinition(); 345 AbstractManagedObjectDefinition parentMo = rel.getParentDefinition(); 346 relList.put(childMo.getName(), rel); 347 if (rel.hasOption(RelationOption.HIDDEN)) { 348 continue; 349 } 350 String linkStr = getLink(childMo.getUserFriendlyName().toString(), 351 childMo.getName() + ".html", MAIN_FRAME); 352 String fromStr = ""; 353 if (!parentMo.getName().equals("")) { 354 fromStr = " (from " + 355 getLink(parentMo.getUserFriendlyName().toString(), 356 parentMo.getName() + ".html", MAIN_FRAME) + ")"; 357 } 358 if (!inList) { 359 paragraph(linkStr + fromStr); 360 } else { 361 bullet(linkStr + fromStr); 362 } 363 genMORelationSubTree(makeRelTreeMap(childMo.getAllRelationDefinitions())); 364 if (childMo.hasChildren()) { 365 for (Iterator<AbstractManagedObjectDefinition> it = 366 childMo.getChildren().iterator(); it.hasNext();) { 367 368 AbstractManagedObjectDefinition mo = it.next(); 369 genMORelationSubTree(makeRelTreeMap(mo.getAllRelationDefinitions())); 370 } 371 } 372 } 373 } 374 375 376 private void genMORelationSubTree(TreeMap<String, RelationDefinition> list) { 377 if (!list.values().isEmpty()) { 378 beginList(); 379 genMORelationTree(list); 380 endList(); 381 } 382 } 383 384 385 /** 386 * Generate all the managed objects HTML pages. 387 */ 388 @SuppressWarnings("unchecked") 389 private void genAllManagedObject( 390 TreeMap<String, AbstractManagedObjectDefinition> list) { 391 392 for (AbstractManagedObjectDefinition mo : list.values()) { 393 if ((relList.get(mo.getName()) != null) && 394 (relList.get(mo.getName()).hasOption(RelationOption.HIDDEN))) { 395 continue; 396 } 397 moList.put(mo.getName(), mo); 398 genManagedObject(mo); 399 if (mo.hasChildren()) { 400 genAllManagedObject(makeMOTreeMap(mo.getChildren())); 401 } 402 } 403 } 404 405 private void genManagedObject(AbstractManagedObjectDefinition mo) { 406 //------------------------------------------------------------------------ 407 // Header 408 //------------------------------------------------------------------------ 409 410 homeLink(); 411 String title = mo.getUserFriendlyName().toString(); 412 htmlHeader("OpenDS - " + title); 413 414 // title 415 heading2(title); 416 417 // Abstract notice 418 if (mo.hasChildren()) { 419 paragraph( 420 "Note: this is an abstract component, that cannot be instantiated.", 421 TextStyle.ITALIC); 422 } 423 424 // description 425 paragraph(mo.getSynopsis()); 426 paragraph(mo.getDescription()); 427 428 // sub-components 429 if (mo.hasChildren()) { 430 heading3("Direct Subcomponents"); 431 paragraph("The following " + mo.getUserFriendlyPluralName() + 432 " are available in the server :"); 433 beginList(); 434 @SuppressWarnings("unchecked") 435 TreeMap<String, AbstractManagedObjectDefinition> children = 436 makeMOTreeMap(mo.getChildren()); 437 for ( AbstractManagedObjectDefinition child : children.values()) { 438 link(child.getUserFriendlyName().toString(), child.getName() + ".html"); 439 } 440 endList(); 441 442 paragraph("These " + mo.getUserFriendlyPluralName() + 443 " inherit from the properties described below."); 444 } 445 446 // Parent 447 if (!mo.getParent().isTop()) { 448 heading3("Parent Component"); 449 paragraph("The " + mo.getUserFriendlyName() + 450 " component inherits from the " + 451 getLink(mo.getParent().getUserFriendlyName().toString(), 452 mo.getParent().getName() + ".html")); 453 } 454 455 // Relations 456 generateRelationsSection(mo); 457 458 // Page links in case of LDAP mapping 459 if (ldapMapping) { 460 newline(); 461 horizontalLine(); 462 newline(); 463 paragraph("This page describes the " + mo.getUserFriendlyName() + ":"); 464 beginList(); 465 link("Properties", "#Properties"); 466 link("LDAP Mapping", "#LDAP Mapping"); 467 endList(); 468 newline(); 469 } 470 471 472 //------------------------------------------------------------------------ 473 // Properties 474 //------------------------------------------------------------------------ 475 476 heading3("Properties"); 477 478 paragraph("A description of each property follows."); 479 newline(); 480 481 TreeMap<String, PropertyDefinition> basicProps = 482 new TreeMap<String, PropertyDefinition>(); 483 TreeMap<String, PropertyDefinition> advancedProps = 484 new TreeMap<String, PropertyDefinition>(); 485 // Properties actually defined in this managed object 486 @SuppressWarnings("unchecked") 487 Collection<PropertyDefinition> props = mo.getAllPropertyDefinitions(); 488 for ( PropertyDefinition prop : props) { 489 if (prop.hasOption(PropertyOption.ADVANCED)) { 490 advancedProps.put(prop.getName(), prop); 491 } else { 492 basicProps.put(prop.getName(), prop); 493 } 494 } 495 496 propertiesLinkTable(basicProps, advancedProps); 497 498 // basic properties 499 if (basicProps.size() > 0) { 500 heading4("Basic Properties"); 501 for ( PropertyDefinition prop : basicProps.values()) { 502 generateProperty(mo, prop); 503 newline(); 504 } 505 newline(); 506 } 507 508 // advanced properties 509 if (advancedProps.size() > 0) { 510 heading4("Advanced Properties"); 511 for ( PropertyDefinition prop : advancedProps.values()) { 512 generateProperty(mo, prop); 513 newline(); 514 } 515 newline(); 516 } 517 518 if (ldapMapping) { 519 genLdapMapping(mo); 520 } 521 522 htmlFooter(); 523 524 generateFile(mo.getName() + ".html"); 525 } 526 527 528 private TreeMap<String, PropertyDefinition> 529 getPropertyList(AbstractManagedObjectDefinition mo) { 530 531 @SuppressWarnings("unchecked") 532 Collection<PropertyDefinition> props = mo.getAllPropertyDefinitions(); 533 return makePropTreeMap(props); 534 } 535 536 private void homeLink() { 537 htmlBuff.append("<div style=\"font-size:11px;margin-top:-10px;" + 538 "margin-bottom:-10px; text-align:right\"><a href=\"" + 539 MAIN_FILE + 540 "\" target=\"_top\">Configuration Reference Home</a></div>"); 541 } 542 543 544 private void generateRelationsSection(AbstractManagedObjectDefinition mo) { 545 // Composition relations 546 @SuppressWarnings("unchecked") 547 Collection<RelationDefinition> compRels = mo.getRelationDefinitions(); 548 @SuppressWarnings("unchecked") 549 Collection<RelationDefinition> reverseCompRels = 550 mo.getReverseRelationDefinitions(); 551 // Aggregation properties 552 @SuppressWarnings("unchecked") 553 Collection<AggregationPropertyDefinition> aggregProps = 554 mo.getAggregationPropertyDefinitions(); 555 @SuppressWarnings("unchecked") 556 Collection<AggregationPropertyDefinition> reverseAggregProps = 557 mo.getReverseAggregationPropertyDefinitions(); 558 559 560 // Check if something to print in composition relations 561 // (even if the list not empty, it may contain only hidden relations) 562 boolean isCompRelsEmpty = true; 563 if (!compRels.isEmpty()) { 564 for (RelationDefinition rel : compRels) { 565 if (rel.hasOption(RelationOption.HIDDEN)) { 566 continue; 567 } 568 isCompRelsEmpty = false; 569 } 570 } 571 boolean isReverseCompRelsEmpty = true; 572 if (!reverseCompRels.isEmpty()) { 573 for (RelationDefinition rel : reverseCompRels) { 574 if (rel.hasOption(RelationOption.HIDDEN)) { 575 continue; 576 } 577 // check if it is not root 578 if (rel.getParentDefinition().getName().equals("")) { 579 continue; 580 } 581 isReverseCompRelsEmpty = false; 582 } 583 } 584 585 // 586 // Relations FROM this component 587 // 588 589 if (!isCompRelsEmpty || !aggregProps.isEmpty()) { 590 heading3("Relations From this Component"); 591 } 592 593 if (!isCompRelsEmpty) { 594 paragraph( 595 "The following components have a direct COMPOSITION relation FROM " + 596 mo.getUserFriendlyPluralName() + " :"); 597 for ( RelationDefinition rel : compRels) { 598 if (rel.hasOption(RelationOption.HIDDEN)) { 599 continue; 600 } 601 beginList(); 602 AbstractManagedObjectDefinition childRel = rel.getChildDefinition(); 603 link(childRel.getUserFriendlyName().toString(), childRel.getName() + 604 ".html"); 605 endList(); 606 } 607 } 608 if (!aggregProps.isEmpty()) { 609 paragraph( 610 "The following components have a direct AGGREGATION relation FROM " + 611 mo.getUserFriendlyPluralName() + " :"); 612 TreeMap<String, AbstractManagedObjectDefinition> componentList = 613 new TreeMap<String, AbstractManagedObjectDefinition>(); 614 for ( AggregationPropertyDefinition agg : aggregProps) { 615 RelationDefinition rel = agg.getRelationDefinition(); 616 AbstractManagedObjectDefinition childRel = rel.getChildDefinition(); 617 componentList.put(childRel.getName(), childRel); 618 } 619 for (AbstractManagedObjectDefinition component : componentList.values()) { 620 beginList(); 621 link(component.getUserFriendlyName().toString(), component.getName() + 622 ".html"); 623 endList(); 624 } 625 } 626 627 628 // 629 // Relations TO this component 630 // 631 632 if (!isReverseCompRelsEmpty || !reverseAggregProps.isEmpty()) { 633 heading3("Relations To this Component"); 634 } 635 636 if (!mo.getReverseRelationDefinitions().isEmpty()) { 637 if (!isReverseCompRelsEmpty) { 638 paragraph( 639 "The following components have a direct COMPOSITION relation TO " + 640 mo.getUserFriendlyPluralName() + " :"); 641 for ( RelationDefinition rel : reverseCompRels) { 642 beginList(); 643 AbstractManagedObjectDefinition childRel = rel.getParentDefinition(); 644 link(childRel.getUserFriendlyName().toString(), childRel.getName() + 645 ".html"); 646 endList(); 647 } 648 } 649 } 650 if (!reverseAggregProps.isEmpty()) { 651 paragraph( 652 "The following components have a direct AGGREGATION relation TO " + 653 mo.getUserFriendlyPluralName() + " :"); 654 TreeMap<String, AbstractManagedObjectDefinition> componentList = 655 new TreeMap<String, AbstractManagedObjectDefinition>(); 656 for ( AggregationPropertyDefinition agg : reverseAggregProps) { 657 AbstractManagedObjectDefinition fromMo = 658 agg.getManagedObjectDefinition(); 659 componentList.put(fromMo.getName(), fromMo); 660 } 661 for (AbstractManagedObjectDefinition component : componentList.values()) { 662 beginList(); 663 link(component.getUserFriendlyName().toString(), component.getName() + 664 ".html"); 665 endList(); 666 667 } 668 } 669 670 } 671 672 private void generateProperty( 673 AbstractManagedObjectDefinition mo, PropertyDefinition prop) { 674 675 // Property name 676 paragraph(getAnchor(prop.getName()) + prop.getName(), TextStyle.STANDARD, 677 "propertyname"); 678 679 // Property table 680 startTable(); 681 tableRow("Description", 682 ((prop.getSynopsis() != null) ? prop.getSynopsis().toString()+ " " : "") + 683 ((prop.getDescription() != null) ? 684 prop.getDescription().toString() : "")); 685 686 // Default value 687 String defValueStr = getDefaultBehaviorString(prop); 688 tableRow("Default Value", defValueStr); 689 690 tableRow("Allowed Values", getSyntaxStr(prop)); 691 692 tableRow("Multi-valued", 693 (prop.hasOption(PropertyOption.MULTI_VALUED) ? "Yes" : "No")); 694 695 if (prop.hasOption(PropertyOption.MANDATORY)) { 696 tableRow("Required", "Yes"); 697 } else { 698 tableRow("Required", "No"); 699 } 700 701 String action = "None"; 702 if (prop.getAdministratorAction() != null) { 703 Message synopsis = prop.getAdministratorAction().getSynopsis(); 704 Type actionType = prop.getAdministratorAction().getType(); 705 String actionStr = ""; 706 if (actionType == actionType.COMPONENT_RESTART) { 707 actionStr = "The " + mo.getUserFriendlyName() + 708 " must be disabled and re-enabled for changes to this setting " + 709 "to take effect"; 710 } else if (actionType == actionType.SERVER_RESTART) { 711 actionStr = "Restart the server"; 712 } else if (actionType == actionType.NONE) { 713 actionStr = "None"; 714 } 715 String dot = (actionStr.equals("") ? "" : ". "); 716 action = actionStr + 717 ((synopsis != null) ? dot + synopsis : ""); 718 } 719 tableRow("Admin Action Required", action); 720 721 if (prop.hasOption(PropertyOption.ADVANCED)) { 722 tableRow("Advanced Property", "Yes"); 723 } else { 724 tableRow("Advanced Property", "No"); 725 } 726 727 endTable(); 728 729 } 730 731 732 private void propertiesLinkTable(TreeMap<String, 733 PropertyDefinition> basicProps, 734 TreeMap<String, PropertyDefinition> advancedProps) { 735 htmlBuff.append( 736 "<table border=\"0\" cellspacing=\"0\" class=\"jump-table\">\n" + 737 " <tr>\n" + 738 " <th>Basic Properties:</th>\n" + 739 " <th>Advanced Properties:</th>\n" + 740 " </tr>\n"); 741 742 PropertyDefinition[] basicPropsArray = 743 basicProps.values().toArray(new PropertyDefinition[0]); 744 PropertyDefinition[] advancedPropsArray = 745 advancedProps.values().toArray(new PropertyDefinition[0]); 746 747 for (int ii=0; 748 (ii < basicPropsArray.length) || (ii < advancedPropsArray.length); 749 ii++) { 750 String basicPropName = 751 ii < basicPropsArray.length ? basicPropsArray[ii].getName() : null; 752 String advancedPropName = 753 ii < advancedPropsArray.length ? 754 advancedPropsArray[ii].getName() : null; 755 756 String basicHtmlCell = ""; 757 if (basicPropName != null) { 758 basicHtmlCell = " <td>↓ <a href=\"#" + basicPropName + "\">" 759 + basicPropName + "</a></td>\n"; 760 } else if ((basicPropsArray.length == 0) && (ii == 0)) { 761 basicHtmlCell = " <td> None</td>\n"; 762 } else if (ii >= basicPropsArray.length) { 763 // Case of nb of basic props < nb of advanced props 764 basicHtmlCell = " <td></td>\n"; 765 } 766 767 String advancedHtmlCell = ""; 768 if (advancedPropName != null) { 769 advancedHtmlCell = " <td>↓ <a href=\"#" + advancedPropName + 770 "\">" + advancedPropName + "</a></td>\n"; 771 } else if ((advancedPropsArray.length == 0) && (ii == 0)) { 772 advancedHtmlCell = " <td> None</td>\n"; 773 } 774 775 htmlBuff.append("<tr>\n"); 776 htmlBuff.append(basicHtmlCell + advancedHtmlCell); 777 htmlBuff.append("</tr>\n"); 778 } 779 htmlBuff.append("</table>\n"); 780 } 781 782 783 private void genLdapMapping(AbstractManagedObjectDefinition mo) { 784 //------------------------------------------------------------------------ 785 // LDAP mapping 786 //------------------------------------------------------------------------ 787 788 heading3("LDAP Mapping"); 789 paragraph( 790 "Each configuration property can be mapped to a specific " + 791 "LDAP attribute under the \"cn=config\" entry. " + 792 "The mappings that follow are provided for information only. " + 793 "In general, you should avoid changing the server configuration " + 794 "by manipulating the LDAP attributes directly."); 795 796 // Managed object table 797 startTable(); 798 799 LDAPProfile ldapProfile = LDAPProfile.getInstance(); 800 tableRow("Base DN", getBaseDN(mo, ldapProfile)); 801 802 tableRow("objectclass name", ldapProfile.getObjectClass(mo)); 803 if (mo.getParent().getName() != null) { 804 String superior = ""; 805 if (mo.getParent().getName().equals("top")) { 806 superior = "top"; 807 } else { 808 if (moList.get(mo.getParent().getName()) != null) { 809 superior = 810 ldapProfile.getObjectClass(moList.get(mo.getParent().getName())); 811 } else { 812 System.err.println( 813 "Error: managed object " + mo.getName() + " not found."); 814 } 815 } 816 tableRow("objectclass superior", superior); 817 } else { 818 System.err.println( 819 "Error: objectclass superior not found for " + mo.getName()); 820 } 821 endTable(); 822 823 newline(); 824 // Properties table 825 startTable(); 826 tableRow("Property", "LDAP attribute"); 827 for ( PropertyDefinition prop : getPropertyList(mo).values()) { 828 tableRow(prop.getName(), ldapProfile.getAttributeName(mo, prop)); 829 } 830 831 endTable(); 832 833 } 834 835 private void genManagedObjectList( 836 TreeMap<String, AbstractManagedObjectDefinition> list) { 837 838 htmlHeader("OpenDS Configuration Reference - Components View"); 839 tabMenu(MO_LIST_FILE); 840 viewHelp("This view provides a list of all configuration components, " + 841 "in alphabetical order."); 842 843 newline(); 844 StringBuffer moPointers = new StringBuffer(); 845 String lettersPointers = ""; 846 String firstChar = "."; 847 for (AbstractManagedObjectDefinition mo : list.values()) { 848 if (!mo.getName().startsWith(firstChar)) { 849 firstChar = mo.getName().substring(0, 1); 850 String letter = firstChar.toUpperCase(); 851 moPointers.append(getAnchor(letter) + getHeading2(letter)); 852 lettersPointers += getLink(letter, "#" + letter) + " "; 853 } 854 moPointers.append( 855 "<p> " + 856 getLink(mo.getUserFriendlyName().toString(), mo.getName() + ".html", 857 MAIN_FRAME) + 858 "</p>\n"); 859 } 860 paragraph(lettersPointers); 861 htmlBuff.append(moPointers); 862 htmlFooter(); 863 generateFile(MO_LIST_FILE); 864 } 865 866 private void genPropertiesIndex() { 867 868 // Build a sorted list of (property name + its managed object name) 869 TreeSet<String> propMoList = new TreeSet<String>(); 870 for (AbstractManagedObjectDefinition<?, ?> mo : moList.values()) { 871 for (PropertyDefinition<?> prop : mo.getPropertyDefinitions()) { 872 propMoList.add( 873 prop.getName() + "," + prop.getManagedObjectDefinition().getName()); 874 } 875 } 876 877 String lettersPointers = ""; 878 String firstChar = "."; 879 for (String propMoStr : propMoList) { 880 String[] propMoArray = propMoStr.split(","); 881 String propName = propMoArray[0]; 882 AbstractManagedObjectDefinition mo = moList.get(propMoArray[1]); 883 if (!propName.startsWith(firstChar)) { 884 firstChar = propName.substring(0, 1); 885 String letter = firstChar.toUpperCase(); 886 htmlBuff.append(getAnchor(letter) + getHeading2(letter)); 887 lettersPointers += getLink(letter, "#" + letter) + " "; 888 } 889 String propLink = getLink(propName, 890 mo.getName() + ".html" + "#" + propName, MAIN_FRAME); 891 String moLink = 892 getLink(mo.getUserFriendlyName().toString(), mo.getName() + ".html", 893 MAIN_FRAME, "#666"); 894 paragraph(propLink + " [ " + moLink + " ]"); 895 } 896 897 String indexBody = htmlBuff.toString(); 898 htmlBuff = new StringBuffer(); 899 htmlHeader("OpenDS Configuration Reference - Properties View"); 900 tabMenu(PROPERTIES_INDEX_FILE); 901 viewHelp("This view provides a list of all configuration properties, " + 902 "in alphabetical order, and indicates the configuration component to " + 903 "which each property applies."); 904 905 newline(); 906 paragraph(lettersPointers); 907 htmlBuff.append(indexBody); 908 htmlFooter(); 909 generateFile(PROPERTIES_INDEX_FILE); 910 } 911 912 private void genWelcomePage() { 913 htmlHeader("OpenDS Configuration Reference - Welcome"); 914 heading2("About This Reference"); 915 paragraph("This reference " + 916 "describes the OpenDS configuration properties that can be manipulated " + 917 "with the dsconfig command."); 918 paragraph("Configuration components are grouped according to the area of " + 919 "the server in which they are used, as follows:"); 920 921 beginList(); 922 for (String catName : catTopMoList.keySet()) { 923 bullet(getFriendlyName(catName)); 924 } 925 endList(); 926 927 paragraph( 928 "For ease of reference, the configuration is described on multiple " + 929 "tabs. These tabs provide alternative views of the configuration " + 930 "components:"); 931 beginList(); 932 bullet("The <strong>Inheritance</strong> view represents the inheritance " + 933 "relationships between configuration components. A sub-component " + 934 "inherits all of the properties of its parent component."); 935 bullet("The <strong>Structure</strong> view represents the structural " + 936 "relationships between components and indicates how certain components " + 937 "can exist only within container components. When a container " + 938 "component is deleted, all of the components within it are also " + 939 "deleted."); 940 bullet( 941 "The <strong>Components</strong> view provides an alphabetical list " + 942 "of all configuration components."); 943 bullet( 944 "The <strong>Properties</strong> view provides an alphabetical list " + 945 "of all configuration properties, and indicates the configuration " + 946 "component to which each property applies."); 947 endList(); 948 949 newline(); 950 paragraph("When you set up OpenDS, certain components are created in the " + 951 "configuration by default. These components are configured with " + 952 "specific values, which are not necessarily the same as the " + 953 "\"default values\" of new components that you create using dsconfig. " + 954 "The \"default values\" listed in this document refer to the values " + 955 "of the new components that you create using dsconfig."); 956 957 htmlFooter(); 958 generateFile(WELCOME_FILE); 959 960 } 961 962 private void genMainTopPage() { 963 htmlHeader("OpenDS Configuration Reference - Main Top"); 964 htmlBuff.append("<div class=\"breadcrumb\"><span class=\"pageactions\">" + 965 "<a href=\"" + opendsWiki + "\" target=\"_parent\">" + 966 "<span style=\"font-size: 12px;\">« </span>" + 967 "Back to OpenDS Wiki</a></span> </div>\n"); 968 htmlBuff.append("<table class=\"titletable\" cellspacing=\"0\" " + 969 "width=\"100%\">\n"); 970 htmlBuff.append("<tbody><tr>\n"); 971 htmlBuff.append(" <td><h2>OpenDS Configuration Reference</h2></td>\n"); 972 htmlBuff.append(" <td valign=\"bottom\" width=\"10%\">" + 973 "<a href=\"" + opendsHome + "\" target=\"_parent\">" + 974 "<img src=\"opends_logo_sm.png\" alt=\"OpenDS Logo\" align=\"bottom\" " + 975 "border=\"0\" height=\"33\" width=\"104\"></a></td>\n"); 976 htmlBuff.append("</tr>\n"); 977 htmlBuff.append("</tbody></table>\n"); 978 979 htmlFooter(); 980 generateFile(MAINTOP_FILE); 981 982 } 983 984 private void genIndexPage() { 985 htmlBuff.append(getHtmlHeader("OpenDS Configuration Reference")); 986 987 htmlBuff.append("<frameset rows=\"80,*\" framespacing=\"1\" " + 988 "frameborder=\"yes\" border=\"1\" bordercolor=\"#333333\">\n"); 989 htmlBuff.append(" <frame src=\"" + MAINTOP_FILE + "\" name=\"topFrame\" " + 990 "id=\"topFrame\" border=\"1\" title=\"topFrame\" scrolling=\"no\">\n"); 991 htmlBuff.append(" <frameset cols=\"375,*\" frameborder=\"yes\" " + 992 "border=\"1\" " + 993 "framespacing=\"1\">\n"); 994 htmlBuff.append(" <frame src=\"" + INHERITANCE_TREE_FILE + "\" " + 995 "name=\"leftFrame\" id=\"leftFrame\" title=\"leftFrame\" " + 996 "scrolling=\"auto\">\n"); 997 htmlBuff.append(" <frame src=\"" + WELCOME_FILE + 998 "\" name=\"mainFrame\" " + 999 "id=\"mainFrame\" title=\"mainFrame\" scrolling=\"auto\">\n"); 1000 htmlBuff.append(" </frameset>\n"); 1001 htmlBuff.append("</frameset>\n"); 1002 htmlBuff.append("<noframes><body>\n"); 1003 htmlBuff.append("</body>\n"); 1004 htmlBuff.append("</noframes>\n"); 1005 htmlBuff.append("</html>\n"); 1006 1007 generateFile(INDEX_FILE); 1008 } 1009 1010 private String getBaseDN( 1011 AbstractManagedObjectDefinition mo, LDAPProfile ldapProfile) { 1012 1013 RelationDefinition rel = relList.get(mo.getName()); 1014 if (rel != null) { 1015 String baseDn = ldapProfile.getRelationRDNSequence(rel); 1016 if (!baseDn.equals("")) { 1017 return baseDn; 1018 } else { 1019 // Check the parent relation 1020 return getBaseDN(rel.getParentDefinition(), ldapProfile); 1021 } 1022 } else if (moList.get(mo.getParent().getName()) != null) { 1023 // check its superior 1024 return getBaseDN(moList.get(mo.getParent().getName()), ldapProfile); 1025 } else { 1026 System.err.println("Error: Base DN not found for " + mo.getName()); 1027 } 1028 return null; 1029 } 1030 1031 @SuppressWarnings("unchecked") 1032 private String getSyntaxStr(PropertyDefinition prop) { 1033 // Create a visitor for performing syntax specific processing. 1034 PropertyDefinitionVisitor<String, Void> visitor = 1035 new PropertyDefinitionVisitor<String, Void>() { 1036 1037 @Override 1038 public String visitACI(ACIPropertyDefinition prop, Void p) { 1039 return getLink("An ACI Syntax", aciSyntaxPage); 1040 } 1041 1042 @Override 1043 public String visitAggregation( 1044 AggregationPropertyDefinition prop, Void p) { 1045 1046 RelationDefinition rel = prop.getRelationDefinition(); 1047 String linkStr = getLink(rel.getUserFriendlyName().toString(), 1048 rel.getName() + ".html"); 1049 return "The DN of any " + linkStr + ". " + 1050 ((prop.getSourceConstraintSynopsis() != null) ? 1051 prop.getSourceConstraintSynopsis().toString() : ""); 1052 } 1053 1054 @Override 1055 public String visitAttributeType( 1056 AttributeTypePropertyDefinition prop, Void p) { 1057 return "The name of an attribute type defined in the server schema."; 1058 } 1059 1060 @Override 1061 public String visitBoolean(BooleanPropertyDefinition prop, Void p) { 1062 return "true" + getNewLine() + "false"; 1063 } 1064 1065 @Override 1066 public String visitClass(ClassPropertyDefinition prop, Void p) { 1067 String classStr = 1068 "A java class that implements or extends the class(es) :"; 1069 for (String clazz : prop.getInstanceOfInterface()) { 1070 classStr += getNewLine() + clazz; 1071 } 1072 return classStr; 1073 } 1074 1075 @Override 1076 public String visitDN(DNPropertyDefinition prop, Void p) { 1077 String retStr = "A valid DN."; 1078 if (prop.getBaseDN() != null) { 1079 retStr += prop.getBaseDN().toString(); 1080 } 1081 return retStr; 1082 } 1083 1084 @Override 1085 public String visitDuration(DurationPropertyDefinition prop, Void p) { 1086 String durationStr = ""; 1087 1088 durationStr += getLink("A duration Syntax", durationSyntaxPage) + 1089 ". "; 1090 if (prop.isAllowUnlimited()) { 1091 durationStr += "A value of \"-1\" or \"unlimited\" for no limit. "; 1092 } 1093 if (prop.getMaximumUnit() != null) { 1094 durationStr += "Maximum unit is \"" + 1095 prop.getMaximumUnit().getLongName() + "\". "; 1096 } 1097 long lowerLimitStr = new Double(prop.getBaseUnit(). 1098 fromMilliSeconds(prop.getLowerLimit())).longValue(); 1099 durationStr += "Lower limit is " + lowerLimitStr + 1100 " " + prop.getBaseUnit().getLongName() + ". "; 1101 if (prop.getUpperLimit() != null) { 1102 long upperLimitStr = new Double(prop.getBaseUnit(). 1103 fromMilliSeconds(prop.getUpperLimit())).longValue(); 1104 durationStr += "Upper limit is " + upperLimitStr + 1105 " " + prop.getBaseUnit().getLongName() + ". "; 1106 } 1107 1108 return durationStr; 1109 } 1110 1111 @Override 1112 public String visitEnum(EnumPropertyDefinition prop, Void p) { 1113 String enumStr = ""; 1114 Class en = prop.getEnumClass(); 1115 for (Object cst : en.getEnumConstants()) { 1116 enumStr += cst.toString(); 1117 if (prop.getValueSynopsis((Enum) cst) != null) { 1118 enumStr += " - " + prop.getValueSynopsis((Enum) cst).toString(); 1119 } 1120 enumStr += getNewLine() + getNewLine(); 1121 } 1122 return enumStr; 1123 } 1124 1125 @Override 1126 public String visitInteger(IntegerPropertyDefinition prop, Void p) { 1127 String intStr = "An integer value."; 1128 intStr += " Lower value is " + prop.getLowerLimit() + "."; 1129 if (prop.getUpperLimit() != null) { 1130 intStr += " Upper value is " + prop.getUpperLimit() + " ."; 1131 } 1132 if (prop.isAllowUnlimited()) { 1133 intStr += " A value of \"-1\" or \"unlimited\" for no limit."; 1134 } 1135 if (prop.getUnitSynopsis() != null) { 1136 intStr += " Unit is " + prop.getUnitSynopsis() + "."; 1137 } 1138 return intStr; 1139 } 1140 1141 @Override 1142 public String visitIPAddress(IPAddressPropertyDefinition prop, Void p) { 1143 return "An IP address"; 1144 } 1145 1146 @Override 1147 public String visitIPAddressMask( 1148 IPAddressMaskPropertyDefinition prop, Void p) { 1149 1150 return "An IP address mask"; 1151 } 1152 1153 @Override 1154 public String visitSize(SizePropertyDefinition prop, Void p) { 1155 String sizeStr = "A positive integer representing a size."; 1156 if (prop.getLowerLimit() != 0) { 1157 sizeStr += " Lower value is " + prop.getLowerLimit() + "."; 1158 } 1159 if (prop.getUpperLimit() != null) { 1160 sizeStr += " Upper value is " + prop.getUpperLimit() + " ."; 1161 } 1162 if (prop.isAllowUnlimited()) { 1163 sizeStr += " A value of \"-1\" or \"unlimited\" for no limit."; 1164 } 1165 return sizeStr; 1166 } 1167 1168 @Override 1169 public String visitString(StringPropertyDefinition prop, Void p) { 1170 String retStr = "A String"; 1171 if (prop.getPatternSynopsis() != null) { 1172 retStr = prop.getPatternSynopsis().toString(); 1173 } 1174 return retStr; 1175 } 1176 1177 @Override 1178 public String visitUnknown(PropertyDefinition prop, Void p) { 1179 return "Unknown"; 1180 } 1181 }; 1182 1183 // Invoke the visitor against the property definition. 1184 return (String) prop.accept(visitor, null); 1185 1186 } 1187 1188 @SuppressWarnings("unchecked") 1189 private String getDefaultBehaviorString(PropertyDefinition prop) { 1190 DefaultBehaviorProvider defaultBehav = prop.getDefaultBehaviorProvider(); 1191 String defValueStr = ""; 1192 if (defaultBehav instanceof UndefinedDefaultBehaviorProvider) { 1193 defValueStr = "None"; 1194 } else if (defaultBehav instanceof DefinedDefaultBehaviorProvider) { 1195 DefinedDefaultBehaviorProvider defBehav = 1196 (DefinedDefaultBehaviorProvider) defaultBehav; 1197 for (Iterator<String> it = defBehav.getDefaultValues().iterator(); 1198 it.hasNext();) { 1199 1200 String str = it.next(); 1201 defValueStr += str + (it.hasNext() ? "\n" : ""); 1202 } 1203 } else if (defaultBehav instanceof AliasDefaultBehaviorProvider) { 1204 AliasDefaultBehaviorProvider aliasBehav = ( 1205 AliasDefaultBehaviorProvider) defaultBehav; 1206 defValueStr = aliasBehav.getSynopsis().toString(); 1207 } else if 1208 (defaultBehav instanceof RelativeInheritedDefaultBehaviorProvider) { 1209 RelativeInheritedDefaultBehaviorProvider relativBehav = 1210 (RelativeInheritedDefaultBehaviorProvider) defaultBehav; 1211 defValueStr = getDefaultBehaviorString( 1212 relativBehav.getManagedObjectDefinition(). 1213 getPropertyDefinition(relativBehav.getPropertyName())); 1214 } else if 1215 (defaultBehav instanceof AbsoluteInheritedDefaultBehaviorProvider) { 1216 AbsoluteInheritedDefaultBehaviorProvider absoluteBehav = 1217 (AbsoluteInheritedDefaultBehaviorProvider) defaultBehav; 1218 defValueStr = getDefaultBehaviorString( 1219 absoluteBehav.getManagedObjectDefinition(). 1220 getPropertyDefinition(absoluteBehav.getPropertyName())); 1221 } 1222 return defValueStr; 1223 } 1224 1225 private TreeMap<String, AbstractManagedObjectDefinition> makeMOTreeMap( 1226 Collection<AbstractManagedObjectDefinition> coll) { 1227 1228 if (coll == null) { 1229 return null; 1230 } 1231 TreeMap<String, AbstractManagedObjectDefinition> map = 1232 new TreeMap<String, AbstractManagedObjectDefinition>(); 1233 for (AbstractManagedObjectDefinition mo : coll) { 1234 map.put(mo.getName(), mo); 1235 } 1236 return map; 1237 } 1238 1239 private TreeMap<String, RelationDefinition> makeRelTreeMap( 1240 Collection<RelationDefinition> coll) { 1241 1242 if (coll == null) { 1243 return null; 1244 } 1245 TreeMap<String, RelationDefinition> map = 1246 new TreeMap<String, RelationDefinition>(); 1247 for (RelationDefinition rel : coll) { 1248 map.put(rel.getChildDefinition().getName(), rel); 1249 } 1250 return map; 1251 } 1252 1253 private TreeMap<String, PropertyDefinition> makePropTreeMap( 1254 Collection<PropertyDefinition> coll) { 1255 1256 if (coll == null) { 1257 return null; 1258 } 1259 TreeMap<String, PropertyDefinition> map = 1260 new TreeMap<String, PropertyDefinition>(); 1261 for (PropertyDefinition prop : coll) { 1262 map.put(prop.getName(), prop); 1263 } 1264 return map; 1265 } 1266 1267 private void horizontalLine() { 1268 htmlBuff.append("<hr style=\"width: 100%; height: 2px;\">"); 1269 } 1270 1271 private void endTable() { 1272 htmlBuff.append("</tbody>\n"); 1273 htmlBuff.append("</table>\n"); 1274 } 1275 1276 private void bullet(String str) { 1277 htmlBuff.append( 1278 "<li>" + 1279 str + 1280 "</li>\n"); 1281 } 1282 1283 private void heading2(String string) { 1284 heading(string, 2); 1285 } 1286 1287 private void heading3(String string) { 1288 heading(string, 3); 1289 } 1290 1291 private void heading4(String string) { 1292 heading(string, 4); 1293 } 1294 1295 private void heading(String str, int level) { 1296 htmlBuff.append(getHeading(str, level)); 1297 } 1298 1299 private String getHeading(String str, int level) { 1300 String strLevel = (new Integer(level)).toString(); 1301 return "<h" + strLevel + ">" + 1302 "<a name=\"" + str + "\"></a>" + 1303 str + 1304 "</h" + strLevel + ">\n"; 1305 } 1306 1307 private String getHeading2(String str) { 1308 return getHeading(str, 2); 1309 } 1310 1311 private String getAnchor(String str) { 1312 return "<a name=\"" + str + "\"></a>"; 1313 } 1314 1315 private void htmlHeader(String pageTitle) { 1316 htmlBuff.append(getHtmlHeader(pageTitle) + 1317 "<body>\n"); 1318 1319 } 1320 1321 private String getHtmlHeader(String pageTitle) { 1322 return ("<html>\n" + 1323 "<head>\n" + 1324 "<meta http-equiv=\"content-type\"\n" + 1325 "content=\"text/html; charset=ISO-8859-1\">\n" + 1326 "<title>" + pageTitle + "</title>\n" + 1327 "<link rel=\"stylesheet\" type=\"text/css\"\n" + 1328 "href=\"" + CSS_FILE + "\">\n" + 1329 "</head>\n"); 1330 } 1331 1332 // Add a Tab Menu, the active tab is the one given as parameter 1333 private void tabMenu(String activeTab) { 1334 htmlBuff.append( 1335 "<div class=\"tabmenu\"> " + 1336 1337 "<span><a " + 1338 (activeTab.equals(INHERITANCE_TREE_FILE) ? "class=\"activetab\" " : "") + 1339 "href=\"" + INHERITANCE_TREE_FILE + "\"" + 1340 " title=\"Inheritance View of Components\">Inheritance</a></span> " + 1341 1342 "<span><a " + 1343 (activeTab.equals(RELATION_TREE_FILE) ? "class=\"activetab\" " : "") + 1344 "href=\"" + RELATION_TREE_FILE + "\"" + 1345 " title=\"Relational View of Components\">Structure</a></span> " + 1346 1347 "<span><a " + 1348 (activeTab.equals(MO_LIST_FILE) ? "class=\"activetab\" " : "") + 1349 "href=\"" + MO_LIST_FILE + "\"" + 1350 " title=\"Alphabetical Index of Components\">Components</a></span> " + 1351 1352 "<span><a " + 1353 (activeTab.equals(PROPERTIES_INDEX_FILE) ? "class=\"activetab\" " : "") + 1354 "href=\"" + PROPERTIES_INDEX_FILE + "\"" + 1355 " title=\"Alphabetical Index of Properties\" >Properties</a></span>" + 1356 1357 "</div>" + 1358 "\n" 1359 ); 1360 } 1361 1362 private String getLink(String str, String link) { 1363 return getLink(str, link, null, null); 1364 } 1365 1366 private String getLink(String str, String link, String target) { 1367 return getLink(str, link, target, null); 1368 } 1369 1370 private String getLink(String str, String link, String target, String color) { 1371 return "<a " + 1372 (color != null ? "style=\"color:" + color + "\" " : "") + 1373 "href=\"" + link + "\"" + 1374 (target == null ? "" : " target=\"" + target + "\"") + 1375 ">" 1376 + str + "</a>"; 1377 } 1378 1379 private void link(String str, String link) { 1380 link(str, link, null, null); 1381 } 1382 1383 private void link(String str, String link, String target) { 1384 link(str, link, target, null); 1385 } 1386 1387 private void link(String str, String link, String target, String color) { 1388 String htmlStr = ""; 1389 if (!inList && getIndentPixels() > 0) { 1390 htmlStr += "<div style=\"margin-left: " + getIndentPixels() + "px;\">"; 1391 } else if (inList) { 1392 htmlStr += "<li>"; 1393 } 1394 htmlStr += getLink(str, link, target, color); 1395 if (!inList && getIndentPixels() > 0) { 1396 htmlStr += "</div>"; 1397 } else if (inList) { 1398 htmlStr += "</li>"; 1399 } 1400 if (!inList) { 1401 htmlStr += "<br>"; 1402 } 1403 htmlBuff.append(htmlStr + "\n"); 1404 } 1405 1406 private void newline() { 1407 htmlBuff.append( 1408 getNewLine()); 1409 } 1410 1411 private String getNewLine() { 1412 return "<br>\n"; 1413 } 1414 1415 private void paragraph(Message description) { 1416 if (description != null) { 1417 paragraph(description.toString()); 1418 } 1419 } 1420 1421 private void paragraph(Message description, TextStyle style) { 1422 if (description != null) { 1423 paragraph(description.toString(), style, null); 1424 } 1425 } 1426 1427 private void paragraph(String description) { 1428 paragraph(description, TextStyle.STANDARD, null); 1429 } 1430 1431 private void paragraph(String description, TextStyle style) { 1432 paragraph(description, style, null); 1433 } 1434 1435 private void paragraph(String description, TextStyle style, String pClass) { 1436 String indentStr = ""; 1437 String styleStr = ""; 1438 String classStr = ""; 1439 if (getIndentPixels() > 0) { 1440 indentStr = "style=\"margin-left: " + getIndentPixels() + "px;\""; 1441 } 1442 if (style == style.BOLD) { 1443 styleStr = "style=\"font-weight: bold;\""; 1444 } else if (style == style.ITALIC) { 1445 styleStr = "style=\"font-style: italic;\""; 1446 } 1447 if (pClass != null) { 1448 classStr = "class=" + pClass; 1449 } 1450 1451 htmlBuff.append( 1452 "<p " + 1453 indentStr + " " + 1454 styleStr + " " + 1455 classStr + 1456 ">" + 1457 description + 1458 "</p>\n"); 1459 } 1460 1461 private int getIndentPixels() { 1462 return (ind * 40); 1463 } 1464 1465 private void startTable() { 1466 htmlBuff.append( 1467 "<table " + 1468 "style=\"width: 100%; text-align: left;\"" + 1469 "border=\"1\"" + 1470 "cellpadding=\"1\"" + 1471 "cellspacing=\"0\"" + 1472 ">\n"); 1473 1474 htmlBuff.append("<tbody>\n"); 1475 } 1476 1477 /* 1478 * Generate a "friendly" name from a string : 1479 * '-' and '_' replaced by space 1480 * first letter of a word in uppercase 1481 */ 1482 private String getFriendlyName(String str) { 1483 String retStr = ""; 1484 String[] words = str.split("\\p{Punct}"); 1485 for (int ii = 0; ii < words.length; ii++) { 1486 if (ii>0) { 1487 retStr += " "; 1488 } 1489 String word = words[ii]; 1490 String firstChar = word.substring(0, 1).toUpperCase(); 1491 retStr += firstChar + word.substring(1, word.length()); 1492 } 1493 return retStr; 1494 } 1495 1496 private void tableRow(String... strings) { 1497 htmlBuff.append( 1498 "<tr>\n"); 1499 for (int ii = 0; ii < strings.length; ii++) { 1500 String string = strings[ii]; 1501 htmlBuff.append( 1502 "<td style=\"" + 1503 "vertical-align: top; " + 1504 ((ii == 0) ? "width: 20%;" : "") + 1505 "\">" + 1506 string + 1507 "<br></td>"); 1508 } 1509 htmlBuff.append( 1510 "</tr>\n"); 1511 } 1512 1513 /** 1514 * Text style. 1515 */ 1516 private enum TextStyle { 1517 1518 STANDARD, BOLD, ITALIC, UNDERLINE, FIXED_WIDTH 1519 } 1520 1521 /** 1522 * List style. 1523 */ 1524 private enum ListStyle { 1525 1526 STANDARD, BULLET, NUMBER 1527 } 1528 1529 private void indent() { 1530 ind++; 1531 } 1532 1533 private void outdent() { 1534 ind--; 1535 } 1536 1537 private void beginList() { 1538 inList = true; 1539 listLevel++; 1540 htmlBuff.append( 1541 "<ul>\n"); 1542 } 1543 1544 private void endList() { 1545 listLevel--; 1546 if (listLevel == 0) { 1547 inList = false; 1548 } 1549 htmlBuff.append( 1550 "</ul>\n"); 1551 } 1552 1553 private void htmlFooter() { 1554 htmlBuff.append( 1555 "</body>\n" + 1556 "</html>\n"); 1557 } 1558 1559 private static void usage() { 1560 System.err.println( 1561 "Usage : Provide the argument : output generation directory."); 1562 System.exit(1); 1563 } 1564 1565 private void viewHelp(String helpStr) { 1566 htmlBuff.append( 1567 "<p class=\"view-help\" >" + 1568 helpStr + 1569 "</p>" + 1570 "\n" 1571 ); 1572 } 1573 1574 private void generateFile(String fileName) { 1575 // Write the html buffer in a file 1576 try { 1577 PrintWriter file = new java.io.PrintWriter( 1578 new java.io.FileWriter(generationDir + File.separator + fileName)); 1579 file.write(htmlBuff.toString()); 1580 file.close(); 1581 } catch (Exception e) { 1582 e.printStackTrace(); 1583 System.exit(1); 1584 } 1585 // re-init html buffer 1586 htmlBuff = new StringBuffer(); 1587 } 1588 1589 // Relation List from RootConfiguration 1590 private TreeMap<String, RelationDefinition> topRelList = 1591 new TreeMap<String, RelationDefinition>(); 1592 private TreeMap<String, RelationDefinition> relList = 1593 new TreeMap<String, RelationDefinition>(); 1594 private TreeMap<String, TreeMap<String, RelationDefinition>> catTopRelList = 1595 new TreeMap<String, TreeMap<String, RelationDefinition>>(); 1596 // managed object list 1597 private TreeMap<String, AbstractManagedObjectDefinition> moList = 1598 new TreeMap<String, AbstractManagedObjectDefinition>(); 1599 private TreeMap<String, AbstractManagedObjectDefinition> topMoList = 1600 new TreeMap<String, AbstractManagedObjectDefinition>(); 1601 private TreeMap<String, TreeMap<String, AbstractManagedObjectDefinition>> 1602 catTopMoList = 1603 new TreeMap<String, TreeMap<String, AbstractManagedObjectDefinition>>(); 1604 private int ind = 0; 1605 private StringBuffer htmlBuff = new StringBuffer(); 1606 private static String generationDir; 1607 private static boolean ldapMapping = false; 1608 private static String opendsWiki; 1609 private static String opendsHome; 1610 private static String aciSyntaxPage; 1611 private static String durationSyntaxPage; 1612 private boolean inList = false; 1613 private int listLevel = 0; 1614 }