| New file |
| | |
| | | /* |
| | | * CDDL HEADER START |
| | | * |
| | | * The contents of this file are subject to the terms of the |
| | | * Common Development and Distribution License, Version 1.0 only |
| | | * (the "License"). You may not use this file except in compliance |
| | | * with the License. |
| | | * |
| | | * You can obtain a copy of the license at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE |
| | | * or https://OpenDS.dev.java.net/OpenDS.LICENSE. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, |
| | | * add the following below this CDDL HEADER, with the fields enclosed |
| | | * by brackets "[]" replaced with your own identifying information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Portions Copyright 2007-2008 Sun Microsystems, Inc. |
| | | */ |
| | | package org.opends.server.admin.doc; |
| | | |
| | | import java.io.File; |
| | | import java.io.PrintWriter; |
| | | import java.util.Collection; |
| | | import java.util.Iterator; |
| | | import java.util.TreeMap; |
| | | import java.util.TreeSet; |
| | | import org.opends.messages.Message; |
| | | import org.opends.server.admin.ACIPropertyDefinition; |
| | | import org.opends.server.admin.AbsoluteInheritedDefaultBehaviorProvider; |
| | | import org.opends.server.admin.AbstractManagedObjectDefinition; |
| | | import org.opends.server.admin.AdministratorAction.Type; |
| | | import org.opends.server.admin.AggregationPropertyDefinition; |
| | | import org.opends.server.admin.AliasDefaultBehaviorProvider; |
| | | import org.opends.server.admin.AttributeTypePropertyDefinition; |
| | | import org.opends.server.admin.BooleanPropertyDefinition; |
| | | import org.opends.server.admin.ClassLoaderProvider; |
| | | import org.opends.server.admin.ClassPropertyDefinition; |
| | | import org.opends.server.admin.DNPropertyDefinition; |
| | | import org.opends.server.admin.DefaultBehaviorProvider; |
| | | import org.opends.server.admin.DefinedDefaultBehaviorProvider; |
| | | import org.opends.server.admin.DurationPropertyDefinition; |
| | | import org.opends.server.admin.EnumPropertyDefinition; |
| | | import org.opends.server.admin.IPAddressMaskPropertyDefinition; |
| | | import org.opends.server.admin.IPAddressPropertyDefinition; |
| | | import org.opends.server.admin.IntegerPropertyDefinition; |
| | | import org.opends.server.admin.LDAPProfile; |
| | | import org.opends.server.admin.PropertyDefinition; |
| | | import org.opends.server.admin.PropertyDefinitionVisitor; |
| | | import org.opends.server.admin.PropertyOption; |
| | | import org.opends.server.admin.RelationDefinition; |
| | | import org.opends.server.admin.RelativeInheritedDefaultBehaviorProvider; |
| | | import org.opends.server.admin.SizePropertyDefinition; |
| | | import org.opends.server.admin.StringPropertyDefinition; |
| | | import org.opends.server.admin.TopCfgDefn; |
| | | import org.opends.server.admin.UndefinedDefaultBehaviorProvider; |
| | | import org.opends.server.admin.std.meta.RootCfgDefn; |
| | | import org.opends.server.types.InitializationException; |
| | | import org.opends.server.util.EmbeddedUtils; |
| | | |
| | | /** |
| | | * This class allow Configuration Guide documentation generation (html format). |
| | | * It is based on the Admin Framework Introspection API |
| | | * |
| | | */ |
| | | public class ConfigGuideGeneration { |
| | | |
| | | // Note : still to be done : |
| | | // I18n support. Today all the strings are hardcoded in this file |
| | | |
| | | private final String OPENDS_WIKI = "https://www.opends.org/wiki"; |
| | | private final String ACI_SYNTAX_PAGE = OPENDS_WIKI + "/page/ACISyntax"; |
| | | private final String CSS_FILE = "opends-config.css"; |
| | | |
| | | /** |
| | | * Entry point for documentation generation. |
| | | * |
| | | * @param args The output generation directory (optional) |
| | | */ |
| | | public static void main(String[] args) { |
| | | if (args.length == 0) { |
| | | // Default dir is prefixed by the system-dependent default temporary dir |
| | | generationDir = System.getProperty("java.io.tmpdir") + File.separator + |
| | | "opends_config_guide"; |
| | | } else if ((args.length != 1) || !(new File(args[0])).isDirectory()) { |
| | | usage(); |
| | | } else { |
| | | generationDir = args[0]; |
| | | } |
| | | // Create new dir if necessary |
| | | try { |
| | | (new File(generationDir)).mkdir(); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | System.exit(1); |
| | | } |
| | | System.out.println("Generation directory is : " + generationDir); |
| | | ConfigGuideGeneration myGen = new ConfigGuideGeneration(); |
| | | myGen.generate(); |
| | | } |
| | | |
| | | private void generate() { |
| | | init(); |
| | | |
| | | // Generate the inheritance tree of all the managed objects |
| | | genManagedObjectInheritanceTree(topMoList); |
| | | |
| | | // Generate the relation tree of all the managed objects |
| | | genManagedObjectRelationTree(topRelList); |
| | | |
| | | // Generate all the managed objects and their children |
| | | genAllManagedObject(topMoList); |
| | | |
| | | // Generate a list of managed objects |
| | | genManagedObjectList(moList); |
| | | |
| | | // Generate an index of properties |
| | | genPropertiesIndex(); |
| | | } |
| | | |
| | | private void init() { |
| | | |
| | | // Build a list of top relations |
| | | RootCfgDefn rootCfg = RootCfgDefn.getInstance(); |
| | | for (RelationDefinition rel : rootCfg.getAllRelationDefinitions()) { |
| | | topRelList.put(rel.getChildDefinition().getName(), rel); |
| | | } |
| | | |
| | | // Enable the client-side class loader to explicitly load classes |
| | | // which are not directly reachable from the root configuration |
| | | EmbeddedUtils.initializeForClientUse(); |
| | | // Bootstrap definition classes. |
| | | try { |
| | | ClassLoaderProvider.getInstance().enable(); |
| | | } catch (InitializationException e) { |
| | | System.err.println("ERROR : Cannot enable the client-side class loader."); |
| | | e.printStackTrace(); |
| | | System.exit(1); |
| | | } |
| | | // Switch off class name validation in client. |
| | | ClassPropertyDefinition.setAllowClassValidation(false); |
| | | // Switch off attribute type name validation in client. |
| | | AttributeTypePropertyDefinition.setCheckSchema(false); |
| | | |
| | | // Build a sorted list of top managed objects |
| | | TopCfgDefn topCfg = TopCfgDefn.getInstance(); |
| | | Collection<AbstractManagedObjectDefinition<?, ?>> topObjects = |
| | | topCfg.getChildren(); |
| | | for (AbstractManagedObjectDefinition topObject : topObjects) { |
| | | if (topObject.getName().equals("")) { |
| | | // root |
| | | continue; |
| | | } |
| | | topMoList.put(topObject.getName(), topObject); |
| | | } |
| | | |
| | | } |
| | | |
| | | /** |
| | | * Generate the inheritance tree of all the managed objects. |
| | | */ |
| | | private void genManagedObjectInheritanceTree( |
| | | TreeMap<String, AbstractManagedObjectDefinition> list) { |
| | | |
| | | htmlHeader("OpenDS - Configuring Specific Server Components - " + |
| | | "Inheritance tree"); |
| | | heading2("Configuring Specific Server Components - Inheritance tree"); |
| | | genMoInheritanceTree(list); |
| | | generateFile("ManagedObjectInheritanceTree.html"); |
| | | } |
| | | |
| | | @SuppressWarnings("unchecked") |
| | | private void genMoInheritanceTree( |
| | | TreeMap<String, AbstractManagedObjectDefinition> list) { |
| | | |
| | | beginList(); |
| | | for (AbstractManagedObjectDefinition mo : list.values()) { |
| | | if (listLevel == 1) { |
| | | paragraph( |
| | | getLink(mo.getUserFriendlyPluralName().toString(), |
| | | mo.getName() + ".html")); |
| | | } else { |
| | | link(mo.getUserFriendlyName().toString(), mo.getName() + ".html"); |
| | | } |
| | | if (mo.hasChildren()) { |
| | | genMoInheritanceTree(makeMOTreeMap(mo.getChildren())); |
| | | } |
| | | } |
| | | endList(); |
| | | if (listLevel == 1) { |
| | | newline(); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Generate the relation tree of all the managed objects. |
| | | */ |
| | | private void genManagedObjectRelationTree( |
| | | TreeMap<String, RelationDefinition> list) { |
| | | |
| | | htmlHeader("OpenDS - Configuring Specific Server Components - " + |
| | | "Containment tree"); |
| | | heading2("Configuring Specific Server Components - Containment tree"); |
| | | paragraph( |
| | | "This tree represents the composition relation between components. " + |
| | | "This means that a child component is deleted " + |
| | | "when its parent is deleted."); |
| | | genMORelationTree(list); |
| | | generateFile("ManagedObjectRelationTree.html"); |
| | | } |
| | | |
| | | @SuppressWarnings("unchecked") |
| | | private void genMORelationTree(TreeMap<String, RelationDefinition> subList) { |
| | | if (!subList.values().isEmpty()) { |
| | | beginList(); |
| | | for (RelationDefinition rel : subList.values()) { |
| | | AbstractManagedObjectDefinition childMo = rel.getChildDefinition(); |
| | | AbstractManagedObjectDefinition parentMo = rel.getParentDefinition(); |
| | | relList.put(childMo.getName(), rel); |
| | | String linkStr = getLink(childMo.getUserFriendlyName().toString(), |
| | | childMo.getName() + ".html"); |
| | | String fromStr = ""; |
| | | if (!parentMo.getName().equals("")) { |
| | | fromStr = " (from " + |
| | | getLink(parentMo.getUserFriendlyName().toString(), |
| | | parentMo.getName() + ".html") + ")"; |
| | | } |
| | | bullet(linkStr + fromStr); |
| | | genMORelationTree(makeRelTreeMap(childMo.getAllRelationDefinitions())); |
| | | if (childMo.hasChildren()) { |
| | | for (Iterator<AbstractManagedObjectDefinition> it = |
| | | childMo.getChildren().iterator(); it.hasNext();) { |
| | | |
| | | AbstractManagedObjectDefinition mo = it.next(); |
| | | genMORelationTree(makeRelTreeMap(mo.getAllRelationDefinitions())); |
| | | } |
| | | } |
| | | if (listLevel == 1) { |
| | | newline(); |
| | | } |
| | | } |
| | | endList(); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Generate all the managed objects HTML pages. |
| | | */ |
| | | @SuppressWarnings("unchecked") |
| | | private void genAllManagedObject( |
| | | TreeMap<String, AbstractManagedObjectDefinition> list) { |
| | | |
| | | for (AbstractManagedObjectDefinition mo : list.values()) { |
| | | moList.put(mo.getName(), mo); |
| | | genManagedObject(mo); |
| | | if (mo.hasChildren()) { |
| | | genAllManagedObject(makeMOTreeMap(mo.getChildren())); |
| | | } |
| | | } |
| | | } |
| | | |
| | | private void genManagedObject(AbstractManagedObjectDefinition mo) { |
| | | //------------------------------------------------------------------------ |
| | | // Header |
| | | //------------------------------------------------------------------------ |
| | | |
| | | String title = "The " + mo.getUserFriendlyName() + " Configuration"; |
| | | htmlHeader("OpenDS - " + title); |
| | | |
| | | // title |
| | | heading2(title); |
| | | |
| | | // description |
| | | paragraph(mo.getSynopsis()); |
| | | paragraph(mo.getDescription()); |
| | | |
| | | newline(); |
| | | horizontalLine(); |
| | | |
| | | // sub-components |
| | | if (mo.hasChildren()) { |
| | | heading4("Direct Subcomponents"); |
| | | paragraph("The following " + mo.getUserFriendlyPluralName() + |
| | | " are available in the server :"); |
| | | beginList(); |
| | | @SuppressWarnings("unchecked") |
| | | TreeMap<String, AbstractManagedObjectDefinition> children = |
| | | makeMOTreeMap(mo.getChildren()); |
| | | for ( AbstractManagedObjectDefinition child : children.values()) { |
| | | link(child.getUserFriendlyName().toString(), child.getName() + ".html"); |
| | | } |
| | | endList(); |
| | | |
| | | paragraph("All the " + mo.getUserFriendlyPluralName() + |
| | | " inherit from the properties described below."); |
| | | } |
| | | |
| | | // Parent |
| | | if (!mo.getParent().isTop()) { |
| | | heading4("Parent Component"); |
| | | paragraph("The " + mo.getUserFriendlyName() + " component inherits from " |
| | | + getLink(mo.getParent().getUserFriendlyName().toString(), |
| | | mo.getParent().getName() + ".html")); |
| | | } |
| | | |
| | | // Relations |
| | | if (!mo.getRelationDefinitions().isEmpty()) { |
| | | heading4("Relations From this Component"); |
| | | paragraph( |
| | | "The following components have a direct composition relation FROM " + |
| | | mo.getUserFriendlyPluralName() + " :"); |
| | | @SuppressWarnings("unchecked") |
| | | Collection<RelationDefinition> rels = mo.getRelationDefinitions(); |
| | | for ( RelationDefinition rel : rels) { |
| | | beginList(); |
| | | AbstractManagedObjectDefinition childRel = rel.getChildDefinition(); |
| | | link(childRel.getUserFriendlyName().toString(), childRel.getName() + |
| | | ".html"); |
| | | endList(); |
| | | } |
| | | } |
| | | if (!mo.getReverseRelationDefinitions().isEmpty()) { |
| | | boolean isRoot = false; |
| | | @SuppressWarnings("unchecked") |
| | | Collection<RelationDefinition> rels = mo.getReverseRelationDefinitions(); |
| | | for ( RelationDefinition rel : rels) { |
| | | // only check if it is not root |
| | | if (rel.getParentDefinition().getName().equals("")) { |
| | | isRoot = true; |
| | | } |
| | | } |
| | | if (!isRoot) { |
| | | heading4("Relations To this Component"); |
| | | paragraph( |
| | | "The following components have a direct composition relation TO " + |
| | | mo.getUserFriendlyPluralName() + " :"); |
| | | for ( RelationDefinition rel : rels) { |
| | | beginList(); |
| | | AbstractManagedObjectDefinition childRel = rel.getParentDefinition(); |
| | | link(childRel.getUserFriendlyName().toString(), childRel.getName() + |
| | | ".html"); |
| | | endList(); |
| | | } |
| | | } |
| | | } |
| | | |
| | | newline(); |
| | | horizontalLine(); |
| | | newline(); |
| | | |
| | | // Page links |
| | | paragraph("This page describes the " + mo.getUserFriendlyName() + ":"); |
| | | beginList(); |
| | | link("Properties", "#Properties"); |
| | | link("LDAP Mapping", "#LDAP Mapping"); |
| | | endList(); |
| | | newline(); |
| | | |
| | | |
| | | //------------------------------------------------------------------------ |
| | | // Properties |
| | | //------------------------------------------------------------------------ |
| | | |
| | | heading3("Properties"); |
| | | |
| | | paragraph(mo.getUserFriendlyPluralName() + |
| | | " contain the following properties:"); |
| | | newline(); |
| | | |
| | | // Properties actually defined in this managed object |
| | | @SuppressWarnings("unchecked") |
| | | Collection<PropertyDefinition> props = mo.getAllPropertyDefinitions(); |
| | | TreeMap<String, PropertyDefinition> propList = makePropTreeMap(props); |
| | | for ( PropertyDefinition prop : propList.values()) { |
| | | generateProperty(mo, prop); |
| | | newline(); |
| | | } |
| | | |
| | | newline(); |
| | | |
| | | //------------------------------------------------------------------------ |
| | | // LDAP mapping |
| | | //------------------------------------------------------------------------ |
| | | |
| | | heading3("LDAP Mapping"); |
| | | paragraph( |
| | | "Each dscfg configuration property can be mapped to a specific " + |
| | | "LDAP attribute under the \"cn=config\" entry. " + |
| | | "The mappings that follow are provided for information only. " + |
| | | "In general, you should avoid changing the server configuration " + |
| | | "by manipulating the LDAP attributes directly."); |
| | | |
| | | // Managed object table |
| | | startTable(); |
| | | |
| | | LDAPProfile ldapProfile = LDAPProfile.getInstance(); |
| | | tableRow("Base DN", getBaseDN(mo, ldapProfile)); |
| | | |
| | | tableRow("objectclass name", ldapProfile.getObjectClass(mo)); |
| | | if (mo.getParent().getName() != null) { |
| | | String superior = ""; |
| | | if (mo.getParent().getName().equals("top")) { |
| | | superior = "top"; |
| | | } else { |
| | | if (moList.get(mo.getParent().getName()) != null) { |
| | | superior = |
| | | ldapProfile.getObjectClass(moList.get(mo.getParent().getName())); |
| | | } else { |
| | | System.err.println( |
| | | "Error: managed object " + mo.getName() + " not found."); |
| | | } |
| | | } |
| | | tableRow("objectclass superior", superior); |
| | | } else { |
| | | System.err.println( |
| | | "Error: objectclass superior not found for " + mo.getName()); |
| | | } |
| | | endTable(); |
| | | |
| | | newline(); |
| | | // Properties table |
| | | startTable(); |
| | | tableRow("Property", "LDAP attribute"); |
| | | for ( PropertyDefinition prop : propList.values()) { |
| | | tableRow(prop.getName(), ldapProfile.getAttributeName(mo, prop)); |
| | | } |
| | | |
| | | endTable(); |
| | | |
| | | htmlFooter(); |
| | | |
| | | generateFile(mo.getName() + ".html"); |
| | | } |
| | | |
| | | private void generateProperty( |
| | | AbstractManagedObjectDefinition mo, PropertyDefinition prop) { |
| | | |
| | | // Property name |
| | | paragraph(getAnchor(prop.getName()) + prop.getName(), TextStyle.BOLD); |
| | | |
| | | // Property table |
| | | startTable(); |
| | | tableRow("Description", |
| | | ((prop.getSynopsis() != null) ? prop.getSynopsis().toString() : "") + |
| | | ((prop.getDescription() != null) ? |
| | | prop.getDescription().toString() : "")); |
| | | |
| | | // Default value |
| | | String defValueStr = getDefaultBehaviorString(prop); |
| | | tableRow("Default Value", defValueStr); |
| | | |
| | | tableRow("Allowed Values", getSyntaxStr(prop)); |
| | | |
| | | tableRow("Multi-valued", |
| | | (prop.hasOption(PropertyOption.MULTI_VALUED) ? "Yes" : "No")); |
| | | |
| | | if (prop.hasOption(PropertyOption.MANDATORY)) { |
| | | tableRow("Required", "Yes"); |
| | | } |
| | | |
| | | if (prop.getAdministratorAction() != null) { |
| | | Message synopsis = prop.getAdministratorAction().getSynopsis(); |
| | | Type actionType = prop.getAdministratorAction().getType(); |
| | | String actionStr = ""; |
| | | if (actionType == actionType.COMPONENT_RESTART) { |
| | | actionStr = "The " + mo.getUserFriendlyName() + |
| | | " must be disabled and re-enabled for changes to this setting " + |
| | | "to take effect"; |
| | | } else if (actionType == actionType.SERVER_RESTART) { |
| | | actionStr = "Restart the server"; |
| | | } else if (actionType == actionType.NONE) { |
| | | actionStr = "None"; |
| | | } |
| | | String action = actionStr + |
| | | ((synopsis != null) ? ". " + synopsis : ""); |
| | | tableRow("Admin Action Required", action); |
| | | } |
| | | |
| | | |
| | | if (prop.hasOption(PropertyOption.ADVANCED)) { |
| | | tableRow("Advanced Property", "Yes"); |
| | | } |
| | | |
| | | endTable(); |
| | | |
| | | } |
| | | |
| | | private void genManagedObjectList( |
| | | TreeMap<String, AbstractManagedObjectDefinition> list) { |
| | | |
| | | htmlHeader("Component List"); |
| | | for (AbstractManagedObjectDefinition mo : list.values()) { |
| | | link(mo.getUserFriendlyName().toString(), mo.getName() + ".html"); |
| | | } |
| | | htmlFooter(); |
| | | generateFile("ManagedObjectList.html"); |
| | | } |
| | | |
| | | private void genPropertiesIndex() { |
| | | |
| | | // Build a sorted list of (property name + its managed object name) |
| | | TreeSet<String> propMoList = new TreeSet<String>(); |
| | | for (AbstractManagedObjectDefinition<?, ?> mo : moList.values()) { |
| | | for (PropertyDefinition<?> prop : mo.getPropertyDefinitions()) { |
| | | propMoList.add( |
| | | prop.getName() + "," + prop.getManagedObjectDefinition().getName()); |
| | | } |
| | | } |
| | | |
| | | String lettersPointers = ""; |
| | | String firstChar = "."; |
| | | for (String propMoStr : propMoList) { |
| | | String[] propMoArray = propMoStr.split(","); |
| | | String propName = propMoArray[0]; |
| | | AbstractManagedObjectDefinition mo = moList.get(propMoArray[1]); |
| | | if (!propName.startsWith(firstChar)) { |
| | | firstChar = propName.substring(0, 1); |
| | | String letter = firstChar.toUpperCase(); |
| | | htmlBuff.append(getAnchor(letter) + getHeading2(letter)); |
| | | lettersPointers += getLink(letter, "#" + letter) + " "; |
| | | } |
| | | String propLink = getLink(propName, |
| | | mo.getName() + ".html" + "#" + propName); |
| | | String moLink = |
| | | getLink(mo.getUserFriendlyName().toString(), mo.getName() + ".html"); |
| | | paragraph(propLink + " (" + moLink + ")"); |
| | | } |
| | | |
| | | String indexBody = htmlBuff.toString(); |
| | | htmlBuff = new StringBuffer(); |
| | | htmlHeader("Properties Index"); |
| | | paragraph(lettersPointers); |
| | | htmlBuff.append(indexBody); |
| | | htmlFooter(); |
| | | generateFile("PropertiesIndex.html"); |
| | | } |
| | | |
| | | private String getBaseDN( |
| | | AbstractManagedObjectDefinition mo, LDAPProfile ldapProfile) { |
| | | |
| | | if (relList.get(mo.getName()) != null) { |
| | | return ldapProfile.getRelationRDNSequence(relList.get(mo.getName())); |
| | | } else if (moList.get(mo.getParent().getName()) != null) { |
| | | // check its superior |
| | | return getBaseDN(moList.get(mo.getParent().getName()), ldapProfile); |
| | | } else { |
| | | System.err.println("Error: Base DN not found for " + mo.getName()); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | @SuppressWarnings("unchecked") |
| | | private String getSyntaxStr(PropertyDefinition prop) { |
| | | // Create a visitor for performing syntax specific processing. |
| | | PropertyDefinitionVisitor<String, Void> visitor = |
| | | new PropertyDefinitionVisitor<String, Void>() { |
| | | |
| | | @Override |
| | | public String visitACI(ACIPropertyDefinition prop, Void p) { |
| | | return getLink("An ACI Syntax", ACI_SYNTAX_PAGE); |
| | | } |
| | | |
| | | @Override |
| | | public String visitAggregation( |
| | | AggregationPropertyDefinition prop, Void p) { |
| | | |
| | | RelationDefinition rel = prop.getRelationDefinition(); |
| | | String linkStr = getLink(rel.getUserFriendlyName().toString(), |
| | | rel.getName() + ".html"); |
| | | return "The DN of any " + linkStr + ". " + |
| | | ((prop.getSourceConstraintSynopsis() != null) ? |
| | | prop.getSourceConstraintSynopsis().toString() : ""); |
| | | } |
| | | |
| | | @Override |
| | | public String visitAttributeType( |
| | | AttributeTypePropertyDefinition prop, Void p) { |
| | | |
| | | return "The name of an attribute type defined in the server schema."; |
| | | } |
| | | |
| | | @Override |
| | | public String visitBoolean(BooleanPropertyDefinition prop, Void p) { |
| | | return "true" + getNewLine() + "false"; |
| | | } |
| | | |
| | | @Override |
| | | public String visitClass(ClassPropertyDefinition prop, Void p) { |
| | | String classStr = |
| | | "A java class that implements or extends the class(es) :"; |
| | | for (String clazz : prop.getInstanceOfInterface()) { |
| | | classStr += getNewLine() + clazz; |
| | | } |
| | | return classStr; |
| | | } |
| | | |
| | | @Override |
| | | public String visitDN(DNPropertyDefinition prop, Void p) { |
| | | String retStr = "A valid DN."; |
| | | if (prop.getBaseDN() != null) { |
| | | retStr += prop.getBaseDN().toString(); |
| | | } |
| | | return retStr; |
| | | } |
| | | |
| | | @Override |
| | | public String visitDuration(DurationPropertyDefinition prop, Void p) { |
| | | String durationStr = ""; |
| | | |
| | | if (prop.isAllowUnlimited()) { |
| | | durationStr += "A value of \"-1\" or \"unlimited\" for no limit. "; |
| | | } |
| | | if (prop.getMaximumUnit() != null) { |
| | | durationStr += "Maximum unit is \"" + |
| | | prop.getMaximumUnit().getLongName() + "\". "; |
| | | } |
| | | long lowerLimitStr = new Double(prop.getBaseUnit(). |
| | | fromMilliSeconds(prop.getLowerLimit())).longValue(); |
| | | durationStr += "Lower limit is " + lowerLimitStr + |
| | | " " + prop.getBaseUnit().getLongName() + ". "; |
| | | if (prop.getUpperLimit() != null) { |
| | | long upperLimitStr = new Double(prop.getBaseUnit(). |
| | | fromMilliSeconds(prop.getUpperLimit())).longValue(); |
| | | durationStr += "Upper limit is " + upperLimitStr + |
| | | " " + prop.getBaseUnit().getLongName() + ". "; |
| | | } |
| | | |
| | | return durationStr; |
| | | } |
| | | |
| | | @Override |
| | | public String visitEnum(EnumPropertyDefinition prop, Void p) { |
| | | String enumStr = ""; |
| | | Class en = prop.getEnumClass(); |
| | | for (Object cst : en.getEnumConstants()) { |
| | | enumStr += cst.toString(); |
| | | if (prop.getValueSynopsis((Enum) cst) != null) { |
| | | enumStr += " - " + prop.getValueSynopsis((Enum) cst).toString(); |
| | | } |
| | | enumStr += getNewLine() + getNewLine(); |
| | | } |
| | | return enumStr; |
| | | } |
| | | |
| | | @Override |
| | | public String visitInteger(IntegerPropertyDefinition prop, Void p) { |
| | | String intStr = "An integer value."; |
| | | intStr += " Lower value is " + prop.getLowerLimit() + "."; |
| | | if (prop.getUpperLimit() != null) { |
| | | intStr += " Upper value is " + prop.getUpperLimit() + " ."; |
| | | } |
| | | if (prop.isAllowUnlimited()) { |
| | | intStr += " A value of \"-1\" or \"unlimited\" for no limit."; |
| | | } |
| | | if (prop.getUnitSynopsis() != null) { |
| | | intStr += " Unit is " + prop.getUnitSynopsis() + "."; |
| | | } |
| | | return intStr; |
| | | } |
| | | |
| | | @Override |
| | | public String visitIPAddress(IPAddressPropertyDefinition prop, Void p) { |
| | | return "An IP address"; |
| | | } |
| | | |
| | | @Override |
| | | public String visitIPAddressMask( |
| | | IPAddressMaskPropertyDefinition prop, Void p) { |
| | | |
| | | return "An IP address mask"; |
| | | } |
| | | |
| | | @Override |
| | | public String visitSize(SizePropertyDefinition prop, Void p) { |
| | | String sizeStr = "A positive integer representing a size."; |
| | | if (prop.getLowerLimit() != 0) { |
| | | sizeStr += " Lower value is " + prop.getLowerLimit() + "."; |
| | | } |
| | | if (prop.getUpperLimit() != null) { |
| | | sizeStr += " Upper value is " + prop.getUpperLimit() + " ."; |
| | | } |
| | | if (prop.isAllowUnlimited()) { |
| | | sizeStr += " A value of \"-1\" or \"unlimited\" for no limit."; |
| | | } |
| | | return sizeStr; |
| | | } |
| | | |
| | | @Override |
| | | public String visitString(StringPropertyDefinition prop, Void p) { |
| | | return "A String"; |
| | | } |
| | | |
| | | @Override |
| | | public String visitUnknown(PropertyDefinition prop, Void p) { |
| | | return "Unknown"; |
| | | } |
| | | }; |
| | | |
| | | // Invoke the visitor against the property definition. |
| | | return (String) prop.accept(visitor, null); |
| | | |
| | | } |
| | | |
| | | @SuppressWarnings("unchecked") |
| | | private String getDefaultBehaviorString(PropertyDefinition prop) { |
| | | DefaultBehaviorProvider defaultBehav = prop.getDefaultBehaviorProvider(); |
| | | String defValueStr = ""; |
| | | if (defaultBehav instanceof UndefinedDefaultBehaviorProvider) { |
| | | defValueStr = "None"; |
| | | } else if (defaultBehav instanceof DefinedDefaultBehaviorProvider) { |
| | | DefinedDefaultBehaviorProvider defBehav = |
| | | (DefinedDefaultBehaviorProvider) defaultBehav; |
| | | for (Iterator<String> it = defBehav.getDefaultValues().iterator(); |
| | | it.hasNext();) { |
| | | |
| | | String str = it.next(); |
| | | defValueStr += str + (it.hasNext() ? "\n" : ""); |
| | | } |
| | | } else if (defaultBehav instanceof AliasDefaultBehaviorProvider) { |
| | | AliasDefaultBehaviorProvider aliasBehav = ( |
| | | AliasDefaultBehaviorProvider) defaultBehav; |
| | | defValueStr = aliasBehav.getSynopsis().toString(); |
| | | } else if |
| | | (defaultBehav instanceof RelativeInheritedDefaultBehaviorProvider) { |
| | | RelativeInheritedDefaultBehaviorProvider relativBehav = |
| | | (RelativeInheritedDefaultBehaviorProvider) defaultBehav; |
| | | defValueStr = getDefaultBehaviorString( |
| | | relativBehav.getManagedObjectDefinition(). |
| | | getPropertyDefinition(relativBehav.getPropertyName())); |
| | | } else if |
| | | (defaultBehav instanceof AbsoluteInheritedDefaultBehaviorProvider) { |
| | | AbsoluteInheritedDefaultBehaviorProvider absoluteBehav = |
| | | (AbsoluteInheritedDefaultBehaviorProvider) defaultBehav; |
| | | defValueStr = getDefaultBehaviorString( |
| | | absoluteBehav.getManagedObjectDefinition(). |
| | | getPropertyDefinition(absoluteBehav.getPropertyName())); |
| | | } |
| | | return defValueStr; |
| | | } |
| | | |
| | | private TreeMap<String, AbstractManagedObjectDefinition> makeMOTreeMap( |
| | | Collection<AbstractManagedObjectDefinition> coll) { |
| | | |
| | | if (coll == null) { |
| | | return null; |
| | | } |
| | | TreeMap<String, AbstractManagedObjectDefinition> map = |
| | | new TreeMap<String, AbstractManagedObjectDefinition>(); |
| | | for (AbstractManagedObjectDefinition mo : coll) { |
| | | map.put(mo.getName(), mo); |
| | | } |
| | | return map; |
| | | } |
| | | |
| | | private TreeMap<String, RelationDefinition> makeRelTreeMap( |
| | | Collection<RelationDefinition> coll) { |
| | | |
| | | if (coll == null) { |
| | | return null; |
| | | } |
| | | TreeMap<String, RelationDefinition> map = |
| | | new TreeMap<String, RelationDefinition>(); |
| | | for (RelationDefinition rel : coll) { |
| | | map.put(rel.getChildDefinition().getName(), rel); |
| | | } |
| | | return map; |
| | | } |
| | | |
| | | private TreeMap<String, PropertyDefinition> makePropTreeMap( |
| | | Collection<PropertyDefinition> coll) { |
| | | |
| | | if (coll == null) { |
| | | return null; |
| | | } |
| | | TreeMap<String, PropertyDefinition> map = |
| | | new TreeMap<String, PropertyDefinition>(); |
| | | for (PropertyDefinition prop : coll) { |
| | | map.put(prop.getName(), prop); |
| | | } |
| | | return map; |
| | | } |
| | | |
| | | private void horizontalLine() { |
| | | htmlBuff.append("<hr style=\"width: 100%; height: 2px;\">"); |
| | | } |
| | | |
| | | private void endTable() { |
| | | htmlBuff.append("</tbody>\n"); |
| | | htmlBuff.append("</table>\n"); |
| | | } |
| | | |
| | | private void bullet(String str) { |
| | | htmlBuff.append( |
| | | "<li>" + |
| | | str + |
| | | "</li>\n"); |
| | | } |
| | | |
| | | private void heading2(String string) { |
| | | heading(string, 2); |
| | | } |
| | | |
| | | private void heading3(String string) { |
| | | heading(string, 3); |
| | | } |
| | | |
| | | private void heading4(String string) { |
| | | heading(string, 4); |
| | | } |
| | | |
| | | private void heading(String str, int level) { |
| | | htmlBuff.append(getHeading(str, level)); |
| | | } |
| | | |
| | | private String getHeading(String str, int level) { |
| | | String strLevel = (new Integer(level)).toString(); |
| | | return "<h" + strLevel + ">" + |
| | | "<a name=\"" + str + "\"></a>" + |
| | | str + |
| | | "</h" + strLevel + ">\n"; |
| | | } |
| | | |
| | | private String getHeading2(String str) { |
| | | return getHeading(str, 2); |
| | | } |
| | | |
| | | private String getAnchor(String str) { |
| | | return "<a name=\"" + str + "\"></a>"; |
| | | } |
| | | |
| | | private void htmlHeader(String pageTitle) { |
| | | htmlBuff.append(getHtmlHeader(pageTitle) + |
| | | "<body style=\"color: rgb(0, 0, 0); " + |
| | | "background-color: rgb(255, 255, 255);\">\n"); |
| | | |
| | | } |
| | | |
| | | // private void htmlHeaderForFrames(String pageTitle) { |
| | | // htmlBuff.append(getHtmlHeader(pageTitle)); |
| | | // } |
| | | private String getHtmlHeader(String pageTitle) { |
| | | return ("<html>\n" + |
| | | "<head>\n" + |
| | | "<meta http-equiv=\"content-type\"\n" + |
| | | "content=\"text/html; charset=ISO-8859-1\">\n" + |
| | | "<title>" + pageTitle + "</title>\n" + |
| | | "<link rel=\"stylesheet\" type=\"text/css\"\n" + |
| | | "href=\"" + CSS_FILE + "\">\n" + |
| | | "</head>\n"); |
| | | } |
| | | |
| | | private String getLink(String str, String link) { |
| | | return "<a href=\"" + link + "\">" + str + "</a>"; |
| | | } |
| | | |
| | | private void link(String str, String link) { |
| | | String htmlStr = ""; |
| | | if (!inList && getIndentPixels() > 0) { |
| | | htmlStr += "<div style=\"margin-left: " + getIndentPixels() + "px;\">"; |
| | | } else if (inList) { |
| | | htmlStr += "<li>"; |
| | | } |
| | | htmlStr += getLink(str, link); |
| | | if (!inList && getIndentPixels() > 0) { |
| | | htmlStr += "</div>"; |
| | | } else if (inList) { |
| | | htmlStr += "</li>"; |
| | | } |
| | | if (!inList) { |
| | | htmlStr += "<br>"; |
| | | } |
| | | htmlBuff.append(htmlStr + "\n"); |
| | | } |
| | | |
| | | private void newline() { |
| | | htmlBuff.append( |
| | | getNewLine()); |
| | | } |
| | | |
| | | private String getNewLine() { |
| | | return "<br>\n"; |
| | | } |
| | | |
| | | private void paragraph(Message description) { |
| | | if (description != null) { |
| | | paragraph(description.toString()); |
| | | } |
| | | } |
| | | |
| | | private void paragraph(Message description, TextStyle style) { |
| | | if (description != null) { |
| | | paragraph(description.toString(), style); |
| | | } |
| | | } |
| | | |
| | | private void paragraph(String description) { |
| | | paragraph(description, TextStyle.STANDARD); |
| | | } |
| | | |
| | | private void paragraph(String description, TextStyle style) { |
| | | String firstTag; |
| | | if (getIndentPixels() > 0) { |
| | | firstTag = "<p style=\"margin-left: " + getIndentPixels() + "px;\">"; |
| | | } else if (style == style.BOLD) { |
| | | firstTag = "<p style=\"font-weight: bold;\">"; |
| | | } else { |
| | | firstTag = "<p>"; |
| | | } |
| | | htmlBuff.append( |
| | | firstTag + |
| | | description + |
| | | "</p>\n"); |
| | | } |
| | | |
| | | private int getIndentPixels() { |
| | | return (ind * 40); |
| | | } |
| | | |
| | | private void startTable() { |
| | | htmlBuff.append( |
| | | "<table " + |
| | | "style=\"width: 100%; text-align: left;\"" + |
| | | "border=\"1\"" + |
| | | "cellpadding=\"1\"" + |
| | | "cellspacing=\"0\"" + |
| | | ">\n"); |
| | | |
| | | htmlBuff.append("<tbody>\n"); |
| | | } |
| | | |
| | | private void tableRow(String... strings) { |
| | | htmlBuff.append( |
| | | "<tr>\n"); |
| | | for (int ii = 0; ii < strings.length; ii++) { |
| | | String string = strings[ii]; |
| | | htmlBuff.append( |
| | | "<td style=\"" + |
| | | "vertical-align: top; " + |
| | | ((ii == 0) ? "width: 20%;" : "") + |
| | | "\">" + |
| | | string + |
| | | "<br></td>"); |
| | | } |
| | | htmlBuff.append( |
| | | "</tr>\n"); |
| | | } |
| | | |
| | | /** |
| | | * Text style. |
| | | */ |
| | | private enum TextStyle { |
| | | |
| | | STANDARD, BOLD, ITALIC, UNDERLINE, FIXED_WIDTH |
| | | } |
| | | |
| | | /** |
| | | * List style. |
| | | */ |
| | | private enum ListStyle { |
| | | |
| | | STANDARD, BULLET, NUMBER |
| | | } |
| | | |
| | | private void indent() { |
| | | ind++; |
| | | } |
| | | |
| | | private void outdent() { |
| | | ind--; |
| | | } |
| | | |
| | | private void beginList() { |
| | | inList = true; |
| | | listLevel++; |
| | | htmlBuff.append( |
| | | "<ul>\n"); |
| | | } |
| | | |
| | | private void endList() { |
| | | listLevel--; |
| | | if (listLevel == 0) { |
| | | inList = false; |
| | | } |
| | | htmlBuff.append( |
| | | "</ul>\n"); |
| | | } |
| | | |
| | | private void htmlFooter() { |
| | | htmlBuff.append( |
| | | "</body>\n" + |
| | | "</html>\n"); |
| | | } |
| | | |
| | | private static void usage() { |
| | | System.err.println( |
| | | "Usage : Provide the argument : output generation directory."); |
| | | System.exit(1); |
| | | } |
| | | |
| | | private void generateFile(String fileName) { |
| | | // Write the html buffer in a file |
| | | try { |
| | | PrintWriter file = new java.io.PrintWriter( |
| | | new java.io.FileWriter(generationDir + File.separator + fileName)); |
| | | file.write(htmlBuff.toString()); |
| | | file.close(); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | System.exit(1); |
| | | } |
| | | // re-init html buffer |
| | | htmlBuff = new StringBuffer(); |
| | | } |
| | | |
| | | // Relation List from RootConfiguration |
| | | private TreeMap<String, RelationDefinition> topRelList = |
| | | new TreeMap<String, RelationDefinition>(); |
| | | private TreeMap<String, RelationDefinition> relList = |
| | | new TreeMap<String, RelationDefinition>(); |
| | | // managed object list |
| | | private TreeMap<String, AbstractManagedObjectDefinition> moList = |
| | | new TreeMap<String, AbstractManagedObjectDefinition>(); |
| | | private TreeMap<String, AbstractManagedObjectDefinition> topMoList = |
| | | new TreeMap<String, AbstractManagedObjectDefinition>(); |
| | | private int ind = 0; |
| | | private StringBuffer htmlBuff = new StringBuffer(); |
| | | private static String generationDir; |
| | | private boolean inList = false; |
| | | private int listLevel = 0; |
| | | } |