mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

Nicolas Capponi
02.47.2013 2fef5aa0046548cb88034553f522d907195a19f7
opendj-admin/src/main/java/org/opends/server/admin/PropertyDefinitionUsageBuilder.java
@@ -25,354 +25,319 @@
 *      Copyright 2008-2009 Sun Microsystems, Inc.
 */
package org.opends.server.admin;
import org.opends.messages.Message;
import org.opends.messages.MessageBuilder;
import java.text.NumberFormat;
import java.util.EnumSet;
import java.util.Set;
import java.util.TreeSet;
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.i18n.LocalizableMessageBuilder;
/**
 * A property definition visitor which can be used to generate syntax
 * usage information.
 * A property definition visitor which can be used to generate syntax usage
 * information.
 */
public final class PropertyDefinitionUsageBuilder {
  /**
   * Underlying implementation.
   */
  private class MyPropertyDefinitionVisitor extends
      PropertyDefinitionVisitor<Message, Void> {
    // Flag indicating whether detailed syntax information will be
    // generated.
    private final boolean isDetailed;
    // The formatter to use for numeric values.
    private final NumberFormat numberFormat;
    // Private constructor.
    private MyPropertyDefinitionVisitor(boolean isDetailed) {
      this.isDetailed = isDetailed;
      this.numberFormat = NumberFormat.getNumberInstance();
      this.numberFormat.setGroupingUsed(true);
      this.numberFormat.setMaximumFractionDigits(2);
    }
    /**
     * {@inheritDoc}
     * Underlying implementation.
     */
    @Override
    public <C extends ConfigurationClient, S extends Configuration>
    Message visitAggregation(AggregationPropertyDefinition<C, S> d, Void p) {
      return Message.raw("NAME");
    }
    private class MyPropertyDefinitionVisitor extends PropertyDefinitionVisitor<LocalizableMessage, Void> {
        // Flag indicating whether detailed syntax information will be
        // generated.
        private final boolean isDetailed;
        // The formatter to use for numeric values.
        private final NumberFormat numberFormat;
    /**
     * {@inheritDoc}
     */
    @Override
    public Message visitAttributeType(AttributeTypePropertyDefinition d,
        Void p) {
      return Message.raw("OID");
    }
        // Private constructor.
        private MyPropertyDefinitionVisitor(boolean isDetailed) {
            this.isDetailed = isDetailed;
    /**
     * {@inheritDoc}
     */
    @Override
    public Message visitACI(ACIPropertyDefinition d,
        Void p) {
      return Message.raw("ACI");
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public Message visitBoolean(BooleanPropertyDefinition d, Void p) {
      if (isDetailed) {
        return Message.raw("false | true");
      } else {
        return Message.raw("BOOLEAN");
      }
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public Message visitClass(ClassPropertyDefinition d, Void p) {
      if (isDetailed && !d.getInstanceOfInterface().isEmpty()) {
        return Message.raw("CLASS <= " + d.getInstanceOfInterface().get(0));
      } else {
        return Message.raw("CLASS");
      }
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public Message visitDN(DNPropertyDefinition d, Void p) {
      if (isDetailed && d.getBaseDN() != null) {
        return Message.raw("DN <= " + d.getBaseDN());
      } else {
        return Message.raw("DN");
      }
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public Message visitDuration(DurationPropertyDefinition d, Void p) {
      MessageBuilder builder = new MessageBuilder();
      DurationUnit unit = d.getBaseUnit();
      if (isDetailed && d.getLowerLimit() > 0) {
        builder.append(DurationUnit.toString(d.getLowerLimit()));
        builder.append(" <= ");
      }
      builder.append("DURATION (");
      builder.append(unit.getShortName());
      builder.append(")");
      if (isDetailed) {
        if (d.getUpperLimit() != null) {
          builder.append(" <= ");
          builder.append(DurationUnit.toString(d.getUpperLimit()));
            this.numberFormat = NumberFormat.getNumberInstance();
            this.numberFormat.setGroupingUsed(true);
            this.numberFormat.setMaximumFractionDigits(2);
        }
        if (d.isAllowUnlimited()) {
          builder.append(" | unlimited");
        }
      }
      return builder.toMessage();
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public <E extends Enum<E>> Message visitEnum(EnumPropertyDefinition<E> d,
        Void p) {
      if (!isDetailed) {
        // Use the last word in the property name.
        String name = d.getName();
        int i = name.lastIndexOf('-');
        if (i == -1 || i == (name.length() - 1)) {
          return Message.raw(name.toUpperCase());
        } else {
          return Message.raw(name.substring(i + 1).toUpperCase());
        }
      } else {
        Set<String> values = new TreeSet<String>();
        for (Object value : EnumSet.allOf(d.getEnumClass())) {
          values.add(value.toString().trim().toLowerCase());
        /**
         * {@inheritDoc}
         */
        @Override
        public <C extends ConfigurationClient, S extends Configuration> LocalizableMessage visitAggregation(
                AggregationPropertyDefinition<C, S> d, Void p) {
            return LocalizableMessage.raw("NAME");
        }
        boolean isFirst = true;
        MessageBuilder builder = new MessageBuilder();
        for (String s : values) {
          if (!isFirst) {
            builder.append(" | ");
          }
          builder.append(s);
          isFirst = false;
        /**
         * {@inheritDoc}
         */
        @Override
        public LocalizableMessage visitAttributeType(AttributeTypePropertyDefinition d, Void p) {
            return LocalizableMessage.raw("OID");
        }
        return builder.toMessage();
      }
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public Message visitInteger(IntegerPropertyDefinition d, Void p) {
      MessageBuilder builder = new MessageBuilder();
      if (isDetailed) {
        builder.append(String.valueOf(d.getLowerLimit()));
        builder.append(" <= ");
      }
      builder.append("INTEGER");
      if (isDetailed) {
        if (d.getUpperLimit() != null) {
          builder.append(" <= ");
          builder.append(String.valueOf(d.getUpperLimit()));
        } else if (d.isAllowUnlimited()) {
          builder.append(" | unlimited");
        /**
         * {@inheritDoc}
         */
        @Override
        public LocalizableMessage visitACI(ACIPropertyDefinition d, Void p) {
            return LocalizableMessage.raw("ACI");
        }
      }
      return builder.toMessage();
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public Message visitIPAddress(IPAddressPropertyDefinition d, Void p) {
      return Message.raw("HOST_NAME");
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public Message visitIPAddressMask(IPAddressMaskPropertyDefinition d,
        Void p) {
      return Message.raw("IP_ADDRESS_MASK");
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public Message visitSize(SizePropertyDefinition d, Void p) {
      MessageBuilder builder = new MessageBuilder();
      if (isDetailed && d.getLowerLimit() > 0) {
        SizeUnit unit = SizeUnit.getBestFitUnitExact(d.getLowerLimit());
        builder.append(numberFormat.format(unit.fromBytes(d.getLowerLimit())));
        builder.append(' ');
        builder.append(unit.getShortName());
        builder.append(" <= ");
      }
      builder.append("SIZE");
      if (isDetailed) {
        if (d.getUpperLimit() != null) {
          long upperLimit = d.getUpperLimit();
          SizeUnit unit = SizeUnit.getBestFitUnitExact(upperLimit);
          // Quite often an upper limit is some power of 2 minus 1. In those
          // cases lets use a "less than" relation rather than a "less than
          // or equal to" relation. This will result in a much more readable
          // quantity.
          if (unit == SizeUnit.BYTES && upperLimit < Long.MAX_VALUE) {
            unit = SizeUnit.getBestFitUnitExact(upperLimit + 1);
            if (unit != SizeUnit.BYTES) {
              upperLimit += 1;
              builder.append(" < ");
        /**
         * {@inheritDoc}
         */
        @Override
        public LocalizableMessage visitBoolean(BooleanPropertyDefinition d, Void p) {
            if (isDetailed) {
                return LocalizableMessage.raw("false | true");
            } else {
              builder.append(" <= ");
                return LocalizableMessage.raw("BOOLEAN");
            }
          } else {
            builder.append(" <= ");
          }
          builder.append(numberFormat.format(unit.fromBytes(upperLimit)));
          builder.append(' ');
          builder.append(unit.getShortName());
        }
        if (d.isAllowUnlimited()) {
          builder.append(" | unlimited");
        /**
         * {@inheritDoc}
         */
        @Override
        public LocalizableMessage visitClass(ClassPropertyDefinition d, Void p) {
            if (isDetailed && !d.getInstanceOfInterface().isEmpty()) {
                return LocalizableMessage.raw("CLASS <= " + d.getInstanceOfInterface().get(0));
            } else {
                return LocalizableMessage.raw("CLASS");
            }
        }
      }
      return builder.toMessage();
        /**
         * {@inheritDoc}
         */
        @Override
        public LocalizableMessage visitDN(DNPropertyDefinition d, Void p) {
            if (isDetailed && d.getBaseDN() != null) {
                return LocalizableMessage.raw("DN <= " + d.getBaseDN());
            } else {
                return LocalizableMessage.raw("DN");
            }
        }
        /**
         * {@inheritDoc}
         */
        @Override
        public LocalizableMessage visitDuration(DurationPropertyDefinition d, Void p) {
            LocalizableMessageBuilder builder = new LocalizableMessageBuilder();
            DurationUnit unit = d.getBaseUnit();
            if (isDetailed && d.getLowerLimit() > 0) {
                builder.append(DurationUnit.toString(d.getLowerLimit()));
                builder.append(" <= ");
            }
            builder.append("DURATION (");
            builder.append(unit.getShortName());
            builder.append(")");
            if (isDetailed) {
                if (d.getUpperLimit() != null) {
                    builder.append(" <= ");
                    builder.append(DurationUnit.toString(d.getUpperLimit()));
                }
                if (d.isAllowUnlimited()) {
                    builder.append(" | unlimited");
                }
            }
            return builder.toMessage();
        }
        /**
         * {@inheritDoc}
         */
        @Override
        public <E extends Enum<E>> LocalizableMessage visitEnum(EnumPropertyDefinition<E> d, Void p) {
            if (!isDetailed) {
                // Use the last word in the property name.
                String name = d.getName();
                int i = name.lastIndexOf('-');
                if (i == -1 || i == (name.length() - 1)) {
                    return LocalizableMessage.raw(name.toUpperCase());
                } else {
                    return LocalizableMessage.raw(name.substring(i + 1).toUpperCase());
                }
            } else {
                Set<String> values = new TreeSet<String>();
                for (Object value : EnumSet.allOf(d.getEnumClass())) {
                    values.add(value.toString().trim().toLowerCase());
                }
                boolean isFirst = true;
                LocalizableMessageBuilder builder = new LocalizableMessageBuilder();
                for (String s : values) {
                    if (!isFirst) {
                        builder.append(" | ");
                    }
                    builder.append(s);
                    isFirst = false;
                }
                return builder.toMessage();
            }
        }
        /**
         * {@inheritDoc}
         */
        @Override
        public LocalizableMessage visitInteger(IntegerPropertyDefinition d, Void p) {
            LocalizableMessageBuilder builder = new LocalizableMessageBuilder();
            if (isDetailed) {
                builder.append(String.valueOf(d.getLowerLimit()));
                builder.append(" <= ");
            }
            builder.append("INTEGER");
            if (isDetailed) {
                if (d.getUpperLimit() != null) {
                    builder.append(" <= ");
                    builder.append(String.valueOf(d.getUpperLimit()));
                } else if (d.isAllowUnlimited()) {
                    builder.append(" | unlimited");
                }
            }
            return builder.toMessage();
        }
        /**
         * {@inheritDoc}
         */
        @Override
        public LocalizableMessage visitIPAddress(IPAddressPropertyDefinition d, Void p) {
            return LocalizableMessage.raw("HOST_NAME");
        }
        /**
         * {@inheritDoc}
         */
        @Override
        public LocalizableMessage visitIPAddressMask(IPAddressMaskPropertyDefinition d, Void p) {
            return LocalizableMessage.raw("IP_ADDRESS_MASK");
        }
        /**
         * {@inheritDoc}
         */
        @Override
        public LocalizableMessage visitSize(SizePropertyDefinition d, Void p) {
            LocalizableMessageBuilder builder = new LocalizableMessageBuilder();
            if (isDetailed && d.getLowerLimit() > 0) {
                SizeUnit unit = SizeUnit.getBestFitUnitExact(d.getLowerLimit());
                builder.append(numberFormat.format(unit.fromBytes(d.getLowerLimit())));
                builder.append(' ');
                builder.append(unit.getShortName());
                builder.append(" <= ");
            }
            builder.append("SIZE");
            if (isDetailed) {
                if (d.getUpperLimit() != null) {
                    long upperLimit = d.getUpperLimit();
                    SizeUnit unit = SizeUnit.getBestFitUnitExact(upperLimit);
                    // Quite often an upper limit is some power of 2 minus 1. In
                    // those
                    // cases lets use a "less than" relation rather than a "less
                    // than
                    // or equal to" relation. This will result in a much more
                    // readable
                    // quantity.
                    if (unit == SizeUnit.BYTES && upperLimit < Long.MAX_VALUE) {
                        unit = SizeUnit.getBestFitUnitExact(upperLimit + 1);
                        if (unit != SizeUnit.BYTES) {
                            upperLimit += 1;
                            builder.append(" < ");
                        } else {
                            builder.append(" <= ");
                        }
                    } else {
                        builder.append(" <= ");
                    }
                    builder.append(numberFormat.format(unit.fromBytes(upperLimit)));
                    builder.append(' ');
                    builder.append(unit.getShortName());
                }
                if (d.isAllowUnlimited()) {
                    builder.append(" | unlimited");
                }
            }
            return builder.toMessage();
        }
        /**
         * {@inheritDoc}
         */
        @Override
        public LocalizableMessage visitString(StringPropertyDefinition d, Void p) {
            if (d.getPattern() != null) {
                if (isDetailed) {
                    LocalizableMessageBuilder builder = new LocalizableMessageBuilder();
                    builder.append(d.getPatternUsage());
                    builder.append(" - ");
                    builder.append(d.getPatternSynopsis());
                    return builder.toMessage();
                } else {
                    return LocalizableMessage.raw(d.getPatternUsage());
                }
            } else {
                return LocalizableMessage.raw("STRING");
            }
        }
        /**
         * {@inheritDoc}
         */
        @Override
        public <T> LocalizableMessage visitUnknown(PropertyDefinition<T> d, Void p)
                throws UnknownPropertyDefinitionException {
            return LocalizableMessage.raw("?");
        }
    }
    // Underlying implementation.
    private final MyPropertyDefinitionVisitor pimpl;
    /**
     * {@inheritDoc}
     * Creates a new property usage builder.
     *
     * @param isDetailed
     *            Indicates whether or not the generated usage should contain
     *            detailed information such as constraints.
     */
    @Override
    public Message visitString(StringPropertyDefinition d, Void p) {
      if (d.getPattern() != null) {
        if (isDetailed) {
          MessageBuilder builder = new MessageBuilder();
          builder.append(d.getPatternUsage());
          builder.append(" - ");
          builder.append(d.getPatternSynopsis());
          return builder.toMessage();
        } else {
          return Message.raw(d.getPatternUsage());
        }
      } else {
        return Message.raw("STRING");
      }
    public PropertyDefinitionUsageBuilder(boolean isDetailed) {
        this.pimpl = new MyPropertyDefinitionVisitor(isDetailed);
    }
    /**
     * {@inheritDoc}
     * Generates the usage information for the provided property definition.
     *
     * @param pd
     *            The property definitions.
     * @return Returns the usage information for the provided property
     *         definition.
     */
    @Override
    public <T> Message visitUnknown(PropertyDefinition<T> d, Void p)
        throws UnknownPropertyDefinitionException {
      return Message.raw("?");
    }
  }
  // Underlying implementation.
  private final MyPropertyDefinitionVisitor pimpl;
  /**
   * Creates a new property usage builder.
   *
   * @param isDetailed
   *          Indicates whether or not the generated usage should
   *          contain detailed information such as constraints.
   */
  public PropertyDefinitionUsageBuilder(boolean isDetailed) {
    this.pimpl = new MyPropertyDefinitionVisitor(isDetailed);
  }
  /**
   * Generates the usage information for the provided property
   * definition.
   *
   * @param pd
   *          The property definitions.
   * @return Returns the usage information for the provided property
   *         definition.
   */
  public Message getUsage(PropertyDefinition<?> pd) {
    return pd.accept(pimpl, null);
  };
    public LocalizableMessage getUsage(PropertyDefinition<?> pd) {
        return pd.accept(pimpl, null);
    };
}