Return-Path: Delivered-To: apmail-commons-commits-archive@locus.apache.org Received: (qmail 21451 invoked from network); 22 Mar 2008 03:09:49 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 22 Mar 2008 03:09:49 -0000 Received: (qmail 68406 invoked by uid 500); 22 Mar 2008 03:09:37 -0000 Delivered-To: apmail-commons-commits-archive@commons.apache.org Received: (qmail 68302 invoked by uid 500); 22 Mar 2008 03:09:37 -0000 Mailing-List: contact commits-help@commons.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@commons.apache.org Delivered-To: mailing list commits@commons.apache.org Received: (qmail 68217 invoked by uid 99); 22 Mar 2008 03:09:36 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 21 Mar 2008 20:09:36 -0700 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.3] (HELO eris.apache.org) (140.211.11.3) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 22 Mar 2008 03:08:50 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id C5B141A9850; Fri, 21 Mar 2008 20:08:45 -0700 (PDT) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r639943 [6/17] - in /commons/proper/cli/trunk/src: java/org/apache/commons/cli2/ java/org/apache/commons/cli2/builder/ java/org/apache/commons/cli2/commandline/ java/org/apache/commons/cli2/option/ java/org/apache/commons/cli2/resource/ jav... Date: Sat, 22 Mar 2008 03:08:35 -0000 To: commits@commons.apache.org From: bayard@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20080322030845.C5B141A9850@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Modified: commons/proper/cli/trunk/src/java/org/apache/commons/cli2/util/Comparators.java URL: http://svn.apache.org/viewvc/commons/proper/cli/trunk/src/java/org/apache/commons/cli2/util/Comparators.java?rev=639943&r1=639942&r2=639943&view=diff ============================================================================== --- commons/proper/cli/trunk/src/java/org/apache/commons/cli2/util/Comparators.java (original) +++ commons/proper/cli/trunk/src/java/org/apache/commons/cli2/util/Comparators.java Fri Mar 21 20:08:23 2008 @@ -1 +1,456 @@ -/** * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package org.apache.commons.cli2.util;import java.util.Comparator;import java.util.List;import org.apache.commons.cli2.Group;import org.apache.commons.cli2.Option;import org.apache.commons.cli2.option.Co mmand;import org.apache.commons.cli2.option.DefaultOption;import org.apache.commons.cli2.option.Switch;/** * A collection of Comparators suitable for use with Option instances. */public class Comparators { private Comparators(){ // constructor hiden from potential users } /** * Chains comparators together. * * @see #chain(Comparator[]) * @param c0 * a comparator * @param c1 * a comparator * @return a chained comparator */ public static Comparator chain(final Comparator c0, final Comparator c1) { return chain(new Comparator[] { c0, c1 }); } /** * Chains comparators together. * * @see #chain(Comparator[]) * @param c0 * a comparator * @param c1 * a comparator * @param c2 * a comparator * @return a chained comparator */ public static Comparator chain( final Comparator c0, final Comparator c1, final Comp arator c2) { return chain(new Comparator[] { c0, c1, c2 }); } /** * Chains comparators together. * * @see #chain(Comparator[]) * @param c0 * a comparator * @param c1 * a comparator * @param c2 * a comparator * @param c3 * a comparator * @return a chained comparator */ public static Comparator chain( final Comparator c0, final Comparator c1, final Comparator c2, final Comparator c3) { return chain(new Comparator[] { c0, c1, c2, c3 }); } /** * Chains comparators together. * * @see #chain(Comparator[]) * @param c0 * a comparator * @param c1 * a comparator * @param c2 * a comparator * @param c3 * a comparator * @param c4 * a comparator * @return a chained comparator */ public static Comparator chain( final Comparator c0, final Comparator c1, final Comparator c2, final Comparator c3, final Comparator c4) { return chain(new Comparator[] { c0, c1, c2, c3, c4 }); } /** * Chains comparators together. * * @see #chain(Comparator[]) * @param comparators * a List of comparators to chain together * @return a chained comparator */ public static Comparator chain(final List comparators) { return new Chain( (Comparator[])comparators.toArray( new Comparator[comparators.size()])); } /** * Chains an array of comparators together. Each Comparator will be called * in turn until one of them return a non-zero value, this value will be * returned. * * @param comparators * the array of comparators * @return a chained comparator */ public static Comparator chain(final Comparator[] comparators) { return new Chain(comparators); } /** * Chains a series of Comparators together. */ private static class Chain implements Comparator { final Comparator[] chain; /** * Creates a Comparator chain using the specified array of Comparators * @param chain the Comparators in the chain */ public Chain(final Comparator[] chain) { this.chain = new Comparator[chain.length]; System.arraycopy(chain, 0, this.chain, 0, chain.length); } public int compare(final Object left, final Object right) { int result = 0; for (int i = 0; result == 0 && i < chain.length; ++i) { result = chain[i].compare(left, right); } return result; } } /** * Reverses a comparator's logic. * * @param wrapped * the Comparator to reverse the logic of * @return a comparator with reverse logic */ private static Comparator reverse(final Comparator wra pped) { return new Reverse(wrapped); } private static class Reverse implements Comparator { private final Comparator wrapped; /** * Creates a Comparator with reverse logic * @param wrapped the original logic */ public Reverse(final Comparator wrapped) { this.wrapped = wrapped; } public int compare(final Object left, final Object right) { return -wrapped.compare(left, right); } } /** * Forces Group instances to appear at the beginning of lists * * @see Group * @return a new comparator */ public static Comparator groupFirst() { return new GroupFirst(); } /** * Forces Group instances to appear at the end of lists * * @see Group * @return a new comparator */ public static Comparator groupLast() { return reverse(groupFirst()); } private static class GroupFirst implements Comparator { public int co mpare(final Object left, final Object right) { final boolean l = left instanceof Group; final boolean r = right instanceof Group; if (l ^ r) { if (l) { return -1; } return 1; } return 0; } } /** * Forces Switch instances to appear at the beginning of lists * * @see Switch * @return a new comparator */ public static Comparator switchFirst() { return new SwitchFirst(); } /** * Forces Switch instances to appear at the end of lists * * @see Switch * @return a new comparator */ public static Comparator switchLast() { return reverse(switchFirst()); } private static class SwitchFirst implements Comparator { public int compare(final Object left, final Object right) { final boolean l = left instanceof Switch; final boolean r = right instanceof Switch; if (l ^ r) { if (l) { return -1; } return 1; } return 0; } } /** * Forces Command instances to appear at the beginning of lists * * @see Command * @return a new comparator */ public static Comparator commandFirst() { return new CommandFirst(); } /** * Forces Command instances to appear at the end of lists * * @see Command * @return a new comparator */ public static Comparator commandLast() { return reverse(commandFirst()); } private static class CommandFirst implements Comparator { public int compare(final Object left, final Object right) { final boolean l = left instanceof Command; final boolean r = right instanceof Command; if (l ^ r) { if (l) { return -1; } return 1; } ret urn 0; } } /** * Forces DefaultOption instances to appear at the beginning of lists * * @see DefaultOption * @return a new comparator */ public static Comparator defaultOptionFirst() { return new DefaultOptionFirst(); } /** * Forces DefaultOption instances to appear at the end of lists * * @see DefaultOption * @return a new comparator */ public static Comparator defaultOptionLast() { return reverse(defaultOptionFirst()); } private static class DefaultOptionFirst implements Comparator { public int compare(final Object left, final Object right) { final boolean l = left instanceof DefaultOption; final boolean r = right instanceof DefaultOption; if (l ^ r) { if (l) { return -1; } return 1; } return 0; } } /** * Forces Comparators with a particular trigger to appear at the beginning * of lists * * @param name * the trigger name to select * @see Option#getTriggers() * @return a new comparator */ public static Comparator namedFirst(final String name) { return new Named(name); } /** * Forces Comparators with a particular trigger to appear at the end of * lists * * @param name * the trigger name to select * @see Option#getTriggers() * @return a new comparator */ public static Comparator namedLast(final String name) { return reverse(new Named(name)); } private static class Named implements Comparator { private final String name; /** * Creates a Comparator that sorts a particular name high in order * @param name the trigger name to select */ public Named(final String name) { this.name = name; } public int compare(final Object oleft, final Object origh t) { final Option left = (Option)oleft; final Option right = (Option)oright; final boolean l = left.getTriggers().contains(name); final boolean r = right.getTriggers().contains(name); if (l ^ r) { if (l) { return -1; } return 1; } return 0; } } /** * Orders Options by preferredName * * @see Option#getPreferredName() * @return a new comparator */ public static Comparator preferredNameFirst() { return new PreferredName(); } /** * Orders Options by preferredName, reversed * * @see Option#getPreferredName() * @return a new comparator */ public static Comparator preferredNameLast() { return reverse(preferredNameFirst()); } private static class PreferredName implements Comparator { public int compare(final Object oleft, final Object oright) { final Option left = (Option)oleft; final Option right = (Option)oright; return left.getPreferredName().compareTo(right.getPreferredName()); } } /** * Orders Options grouping required Options first * * @see Option#isRequired() * @return a new comparator */ public static Comparator requiredFirst() { return new Required(); } /** * Orders Options grouping required Options last * * @see Option#isRequired() * @return a new comparator */ public static Comparator requiredLast() { return reverse(requiredFirst()); } private static class Required implements Comparator { public int compare(final Object oleft, final Object oright) { final Option left = (Option)oleft; final Option right = (Option)oright; final boolean l = left.isRequired(); final boolean r = right.isRequired(); if (l ^ r) { if (l) { return -1; } return 1; } return 0; } }} \ No newline at end of file +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.cli2.util; + +import java.util.Comparator; +import java.util.List; + +import org.apache.commons.cli2.Group; +import org.apache.commons.cli2.Option; +import org.apache.commons.cli2.option.Command; +import org.apache.commons.cli2.option.DefaultOption; +import org.apache.commons.cli2.option.Switch; + +/** + * A collection of Comparators suitable for use with Option instances. + */ +public class Comparators { + + private Comparators(){ + // constructor hiden from potential users + } + + + /** + * Chains comparators together. + * + * @see #chain(Comparator[]) + * @param c0 + * a comparator + * @param c1 + * a comparator + * @return a chained comparator + */ + public static Comparator chain(final Comparator c0, final Comparator c1) { + return chain(new Comparator[] { c0, c1 }); + } + + /** + * Chains comparators together. + * + * @see #chain(Comparator[]) + * @param c0 + * a comparator + * @param c1 + * a comparator + * @param c2 + * a comparator + * @return a chained comparator + */ + public static Comparator chain( + final Comparator c0, + final Comparator c1, + final Comparator c2) { + return chain(new Comparator[] { c0, c1, c2 }); + } + + /** + * Chains comparators together. + * + * @see #chain(Comparator[]) + * @param c0 + * a comparator + * @param c1 + * a comparator + * @param c2 + * a comparator + * @param c3 + * a comparator + * @return a chained comparator + */ + public static Comparator chain( + final Comparator c0, + final Comparator c1, + final Comparator c2, + final Comparator c3) { + return chain(new Comparator[] { c0, c1, c2, c3 }); + } + + /** + * Chains comparators together. + * + * @see #chain(Comparator[]) + * @param c0 + * a comparator + * @param c1 + * a comparator + * @param c2 + * a comparator + * @param c3 + * a comparator + * @param c4 + * a comparator + * @return a chained comparator + */ + public static Comparator chain( + final Comparator c0, + final Comparator c1, + final Comparator c2, + final Comparator c3, + final Comparator c4) { + return chain(new Comparator[] { c0, c1, c2, c3, c4 }); + } + + /** + * Chains comparators together. + * + * @see #chain(Comparator[]) + * @param comparators + * a List of comparators to chain together + * @return a chained comparator + */ + public static Comparator chain(final List comparators) { + return new Chain( + (Comparator[])comparators.toArray( + new Comparator[comparators.size()])); + } + + /** + * Chains an array of comparators together. Each Comparator will be called + * in turn until one of them return a non-zero value, this value will be + * returned. + * + * @param comparators + * the array of comparators + * @return a chained comparator + */ + public static Comparator chain(final Comparator[] comparators) { + return new Chain(comparators); + } + + /** + * Chains a series of Comparators together. + */ + private static class Chain implements Comparator { + + final Comparator[] chain; + + /** + * Creates a Comparator chain using the specified array of Comparators + * @param chain the Comparators in the chain + */ + public Chain(final Comparator[] chain) { + this.chain = new Comparator[chain.length]; + System.arraycopy(chain, 0, this.chain, 0, chain.length); + } + + public int compare(final Object left, final Object right) { + int result = 0; + for (int i = 0; result == 0 && i < chain.length; ++i) { + result = chain[i].compare(left, right); + } + return result; + } + } + + /** + * Reverses a comparator's logic. + * + * @param wrapped + * the Comparator to reverse the logic of + * @return a comparator with reverse logic + */ + private static Comparator reverse(final Comparator wrapped) { + return new Reverse(wrapped); + } + + private static class Reverse implements Comparator { + private final Comparator wrapped; + + /** + * Creates a Comparator with reverse logic + * @param wrapped the original logic + */ + public Reverse(final Comparator wrapped) { + this.wrapped = wrapped; + } + + public int compare(final Object left, final Object right) { + return -wrapped.compare(left, right); + } + } + + /** + * Forces Group instances to appear at the beginning of lists + * + * @see Group + * @return a new comparator + */ + public static Comparator groupFirst() { + return new GroupFirst(); + } + + /** + * Forces Group instances to appear at the end of lists + * + * @see Group + * @return a new comparator + */ + public static Comparator groupLast() { + return reverse(groupFirst()); + } + + private static class GroupFirst implements Comparator { + public int compare(final Object left, final Object right) { + final boolean l = left instanceof Group; + final boolean r = right instanceof Group; + + if (l ^ r) { + if (l) { + return -1; + } + return 1; + } + return 0; + } + } + + /** + * Forces Switch instances to appear at the beginning of lists + * + * @see Switch + * @return a new comparator + */ + public static Comparator switchFirst() { + return new SwitchFirst(); + } + + /** + * Forces Switch instances to appear at the end of lists + * + * @see Switch + * @return a new comparator + */ + public static Comparator switchLast() { + return reverse(switchFirst()); + } + + private static class SwitchFirst implements Comparator { + public int compare(final Object left, final Object right) { + final boolean l = left instanceof Switch; + final boolean r = right instanceof Switch; + + if (l ^ r) { + if (l) { + return -1; + } + return 1; + } + return 0; + } + } + + /** + * Forces Command instances to appear at the beginning of lists + * + * @see Command + * @return a new comparator + */ + public static Comparator commandFirst() { + return new CommandFirst(); + } + + /** + * Forces Command instances to appear at the end of lists + * + * @see Command + * @return a new comparator + */ + public static Comparator commandLast() { + return reverse(commandFirst()); + } + + private static class CommandFirst implements Comparator { + public int compare(final Object left, final Object right) { + final boolean l = left instanceof Command; + final boolean r = right instanceof Command; + + if (l ^ r) { + if (l) { + return -1; + } + return 1; + } + return 0; + } + } + + /** + * Forces DefaultOption instances to appear at the beginning of lists + * + * @see DefaultOption + * @return a new comparator + */ + public static Comparator defaultOptionFirst() { + return new DefaultOptionFirst(); + } + + /** + * Forces DefaultOption instances to appear at the end of lists + * + * @see DefaultOption + * @return a new comparator + */ + public static Comparator defaultOptionLast() { + return reverse(defaultOptionFirst()); + } + + private static class DefaultOptionFirst implements Comparator { + public int compare(final Object left, final Object right) { + final boolean l = left instanceof DefaultOption; + final boolean r = right instanceof DefaultOption; + + if (l ^ r) { + if (l) { + return -1; + } + return 1; + } + return 0; + } + } + + /** + * Forces Comparators with a particular trigger to appear at the beginning + * of lists + * + * @param name + * the trigger name to select + * @see Option#getTriggers() + * @return a new comparator + */ + public static Comparator namedFirst(final String name) { + return new Named(name); + } + + /** + * Forces Comparators with a particular trigger to appear at the end of + * lists + * + * @param name + * the trigger name to select + * @see Option#getTriggers() + * @return a new comparator + */ + public static Comparator namedLast(final String name) { + return reverse(new Named(name)); + } + + private static class Named implements Comparator { + private final String name; + + /** + * Creates a Comparator that sorts a particular name high in order + * @param name the trigger name to select + */ + public Named(final String name) { + this.name = name; + } + public int compare(final Object oleft, final Object oright) { + final Option left = (Option)oleft; + final Option right = (Option)oright; + + final boolean l = left.getTriggers().contains(name); + final boolean r = right.getTriggers().contains(name); + + if (l ^ r) { + if (l) { + return -1; + } + return 1; + } + return 0; + } + } + + /** + * Orders Options by preferredName + * + * @see Option#getPreferredName() + * @return a new comparator + */ + public static Comparator preferredNameFirst() { + return new PreferredName(); + } + + /** + * Orders Options by preferredName, reversed + * + * @see Option#getPreferredName() + * @return a new comparator + */ + public static Comparator preferredNameLast() { + return reverse(preferredNameFirst()); + } + + private static class PreferredName implements Comparator { + public int compare(final Object oleft, final Object oright) { + final Option left = (Option)oleft; + final Option right = (Option)oright; + + return left.getPreferredName().compareTo(right.getPreferredName()); + } + } + + /** + * Orders Options grouping required Options first + * + * @see Option#isRequired() + * @return a new comparator + */ + public static Comparator requiredFirst() { + return new Required(); + } + + /** + * Orders Options grouping required Options last + * + * @see Option#isRequired() + * @return a new comparator + */ + public static Comparator requiredLast() { + return reverse(requiredFirst()); + } + + private static class Required implements Comparator { + public int compare(final Object oleft, final Object oright) { + final Option left = (Option)oleft; + final Option right = (Option)oright; + + final boolean l = left.isRequired(); + final boolean r = right.isRequired(); + + if (l ^ r) { + if (l) { + return -1; + } + return 1; + } + return 0; + } + } +} Modified: commons/proper/cli/trunk/src/java/org/apache/commons/cli2/util/HelpFormatter.java URL: http://svn.apache.org/viewvc/commons/proper/cli/trunk/src/java/org/apache/commons/cli2/util/HelpFormatter.java?rev=639943&r1=639942&r2=639943&view=diff ============================================================================== --- commons/proper/cli/trunk/src/java/org/apache/commons/cli2/util/HelpFormatter.java (original) +++ commons/proper/cli/trunk/src/java/org/apache/commons/cli2/util/HelpFormatter.java Fri Mar 21 20:08:23 2008 @@ -1 +1,638 @@ -/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package org.apache.commons.cli2.util;import java.io.PrintWriter;import java.util.ArrayList;import java.util.Collections;import java.util.Comparator;import java.util.HashSet;import java.util.Iterator;impo rt java.util.List;import java.util.Set;import org.apache.commons.cli2.DisplaySetting;import org.apache.commons.cli2.Group;import org.apache.commons.cli2.HelpLine;import org.apache.commons.cli2.Option;import org.apache.commons.cli2.OptionException;import org.apache.commons.cli2.resource.ResourceConstants;import org.apache.commons.cli2.resource.ResourceHelper;/** * Presents on screen help based on the application's Options */public class HelpFormatter { /** * The default screen width */ public static final int DEFAULT_FULL_WIDTH = 80; /** * The default screen furniture left of screen */ public static final String DEFAULT_GUTTER_LEFT = ""; /** * The default screen furniture right of screen */ public static final String DEFAULT_GUTTER_CENTER = " "; /** * The default screen furniture between columns */ public static final String DEFAULT_GUTTER_RIGHT = ""; /** * The default DisplaySettings used to select the element s to display in the * displayed line of full usage information. * * @see DisplaySetting */ public static final Set DEFAULT_FULL_USAGE_SETTINGS; /** * The default DisplaySettings used to select the elements of usage per help * line in the main body of help * * @see DisplaySetting */ public static final Set DEFAULT_LINE_USAGE_SETTINGS; /** * The default DisplaySettings used to select the help lines in the main * body of help */ public static final Set DEFAULT_DISPLAY_USAGE_SETTINGS; static { final Set fullUsage = new HashSet(DisplaySetting.ALL); fullUsage.remove(DisplaySetting.DISPLAY_ALIASES); fullUsage.remove(DisplaySetting.DISPLAY_GROUP_NAME); DEFAULT_FULL_USAGE_SETTINGS = Collections.unmodifiableSet(fullUsage); final Set lineUsage = new HashSet(); lineUsage.add(DisplaySetting.DISPLAY_ALIASES); lineUsage.add(DisplaySetting.DISPLAY_GROUP_NAME); lineUsage. add(DisplaySetting.DISPLAY_PARENT_ARGUMENT); DEFAULT_LINE_USAGE_SETTINGS = Collections.unmodifiableSet(lineUsage); final Set displayUsage = new HashSet(DisplaySetting.ALL); displayUsage.remove(DisplaySetting.DISPLAY_PARENT_ARGUMENT); DEFAULT_DISPLAY_USAGE_SETTINGS = Collections.unmodifiableSet(displayUsage); } private Set fullUsageSettings = new HashSet(DEFAULT_FULL_USAGE_SETTINGS); private Set lineUsageSettings = new HashSet(DEFAULT_LINE_USAGE_SETTINGS); private Set displaySettings = new HashSet(DEFAULT_DISPLAY_USAGE_SETTINGS); private OptionException exception = null; private Group group; private Comparator comparator = null; private String divider = null; private String header = null; private String footer = null; private String shellCommand = ""; private PrintWriter out = new PrintWriter(System.out); //or should this default to .err? private final String gutterLeft; private final String gutterCenter ; private final String gutterRight; private final int pageWidth; /** * Creates a new HelpFormatter using the defaults */ public HelpFormatter() { this(DEFAULT_GUTTER_LEFT, DEFAULT_GUTTER_CENTER, DEFAULT_GUTTER_RIGHT, DEFAULT_FULL_WIDTH); } /** * Creates a new HelpFormatter using the specified parameters * @param gutterLeft the string marking left of screen * @param gutterCenter the string marking center of screen * @param gutterRight the string marking right of screen * @param fullWidth the width of the screen */ public HelpFormatter(final String gutterLeft, final String gutterCenter, final String gutterRight, final int fullWidth) { // default the left gutter to empty string this.gutterLeft = (gutterLeft == null) ? DEFAULT_GUTTER_LEFT : gutterLeft; // default the center gutter to a single space this.gutterCenter = (gu tterCenter == null) ? DEFAULT_GUTTER_CENTER : gutterCenter; // default the right gutter to empty string this.gutterRight = (gutterRight == null) ? DEFAULT_GUTTER_RIGHT : gutterRight; // calculate the available page width this.pageWidth = fullWidth - this.gutterLeft.length() - this.gutterRight.length(); // check available page width is valid int availableWidth = fullWidth - pageWidth + this.gutterCenter.length(); if (availableWidth < 2) { throw new IllegalArgumentException(ResourceHelper.getResourceHelper().getMessage(ResourceConstants.HELPFORMATTER_GUTTER_TOO_LONG)); } } /** * Prints the Option help. */ public void print() { printHeader(); printException(); printUsage(); printHelp(); printFooter(); out.flush(); } /** * Prints any error message. */ public void printException() { if (exception != null) { printDivider() ; printWrapped(exception.getMessage()); } } /** * Prints detailed help per option. */ public void printHelp() { printDivider(); final Option option; if ((exception != null) && (exception.getOption() != null)) { option = exception.getOption(); } else { option = group; } // grab the HelpLines to display final List helpLines = option.helpLines(0, displaySettings, comparator); // calculate the maximum width of the usage strings int usageWidth = 0; for (final Iterator i = helpLines.iterator(); i.hasNext();) { final HelpLine helpLine = (HelpLine) i.next(); final String usage = helpLine.usage(lineUsageSettings, comparator); usageWidth = Math.max(usageWidth, usage.length()); } // build a blank string to pad wrapped descriptions final StringBuffer blankBuffer = new StringBuffer(); for (int i = 0; i < usageWidth; i++) { blankBuffer.append(' '); } // determine the width available for descriptions final int descriptionWidth = Math.max(1, pageWidth - gutterCenter.length() - usageWidth); // display each HelpLine for (final Iterator i = helpLines.iterator(); i.hasNext();) { // grab the HelpLine final HelpLine helpLine = (HelpLine) i.next(); // wrap the description final List descList = wrap(helpLine.getDescription(), descriptionWidth); final Iterator descriptionIterator = descList.iterator(); // display usage + first line of description printGutterLeft(); pad(helpLine.usage(lineUsageSettings, comparator), usageWidth, out); out.print(gutterCenter); pad((String) descriptionIterator.next(), descriptionWidth, out); printGutterRight(); out.println(); // display padding + remaining lines of desc ription while (descriptionIterator.hasNext()) { printGutterLeft(); //pad(helpLine.getUsage(),usageWidth,out); out.print(blankBuffer); out.print(gutterCenter); pad((String) descriptionIterator.next(), descriptionWidth, out); printGutterRight(); out.println(); } } printDivider(); } /** * Prints a single line of usage information (wrapping if necessary) */ public void printUsage() { printDivider(); final StringBuffer buffer = new StringBuffer("Usage:\n"); buffer.append(shellCommand).append(' '); group.appendUsage(buffer, fullUsageSettings, comparator, " "); printWrapped(buffer.toString()); } /** * Prints a header string if necessary */ public void printHeader() { if (header != null) { printDivider(); printWrapped(header); } } /** * Prints a footer string if necessary */ public void printFooter() { if (footer != null) { printWrapped(footer); printDivider(); } } /** * Prints a string wrapped if necessary * @param text the string to wrap */ public void printWrapped(final String text) { for (final Iterator i = wrap(text, pageWidth).iterator(); i.hasNext();) { printGutterLeft(); pad((String) i.next(), pageWidth, out); printGutterRight(); out.println(); } out.flush(); } /** * Prints the left gutter string */ public void printGutterLeft() { if (gutterLeft != null) { out.print(gutterLeft); } } /** * Prints the right gutter string */ public void printGutterRight() { if (gutterRight != null) { out.print(gutterRight); } } /** * Prints the divider text */ public void printDivider() { if (divider != null) { out.println(divider); } } protected static void pad(final String text, final int width, final PrintWriter writer) { final int left; // write the text and record how many characters written if (text == null) { left = 0; } else { writer.write(text); left = text.length(); } // pad remainder with spaces for (int i = left; i < width; ++i) { writer.write(' '); } } protected static List wrap(final String text, final int width) { // check for valid width if (width < 1) { throw new IllegalArgumentException(ResourceHelper.getResourceHelper().getMessage(ResourceConstants.HELPFORMATTER_WIDTH_TOO_NARROW, new Object[] { new Integer(width) })); } // handle degenerate case if (text == null) { return Collections.singletonList(""); } final List lines = new ArrayList(); final char[] chars = text.toCharArray(); int left = 0; // for each character in the string while (left < chars.length) { // sync left and right indeces int right = left; // move right until we run out of characters, width or find a newline while ((right < chars.length) && (chars[right] != '\n') && (right < (left + width + 1))) { right++; } // if a newline was found if ((right < chars.length) && (chars[right] == '\n')) { // record the substring final String line = new String(chars, left, right - left); lines.add(line); // move to the end of the substring left = right + 1; if (left == chars.length) { lines.add(""); } // restart the loop continue; } // move to the next ideal wrap point right = (left + width) - 1; // if we have run out of characters if (chars.length <= right) { // record the substring final String line = new String(chars, left, chars.length - left); lines.add(line); // abort the loop break; } // back track the substring end until a space is found while ((right >= left) && (chars[right] != ' ')) { right--; } // if a space was found if (right >= left) { / / record the substring to space final String line = new String(chars, left, right - left); lines.add(line); // absorb all the spaces before next substring while ((right < chars.length) && (chars[right] == ' ')) { right++; } left = right; // restart the loop continue; } // move to the wrap position irrespective of spaces right = Math.min(left + width, chars.length); // record the substring final String line = new String(chars, left, right - left); lines.add(line); // absorb any the spaces before next substring while ((right < chars.length) && (chars[right] == ' ')) { right++; } left = right; } return lines; } /** * The Comparator to use when sorting Options * @param comparator Comparator t o use when sorting Options */ public void setComparator(Comparator comparator) { this.comparator = comparator; } /** * The DisplaySettings used to select the help lines in the main body of * help * * @param displaySettings the settings to use * @see DisplaySetting */ public void setDisplaySettings(Set displaySettings) { this.displaySettings = displaySettings; } /** * Sets the string to use as a divider between sections of help * @param divider the dividing string */ public void setDivider(String divider) { this.divider = divider; } /** * Sets the exception to document * @param exception the exception that occured */ public void setException(OptionException exception) { this.exception = exception; } /** * Sets the footer text of the help screen * @param footer the footer text */ public void setFooter(String footer) { this.footer = footer; } /** * The DisplaySettings used to select the elements to display in the * displayed line of full usage information. * @see DisplaySetting * @param fullUsageSettings */ public void setFullUsageSettings(Set fullUsageSettings) { this.fullUsageSettings = fullUsageSettings; } /** * Sets the Group of Options to document * @param group the options to document */ public void setGroup(Group group) { this.group = group; } /** * Sets the footer text of the help screen * @param header the footer text */ public void setHeader(String header) { this.header = header; } /** * Sets the DisplaySettings used to select elements in the per helpline * usage strings. * @see DisplaySetting * @param lineUsageSettings the DisplaySettings to use */ public void setLineUsageSettings(Set lineUsageSettings) { this.lineUsageSettings = lineUsageSettings; } /** * Sets the command string used to invoke the application * @param shellCommand the invokation command */ public void setShellCommand(String shellCommand) { this.shellCommand = shellCommand; } /** * @return the Comparator used to sort the Group */ public Comparator getComparator() { return comparator; } /** * @return the DisplaySettings used to select HelpLines */ public Set getDisplaySettings() { return displaySettings; } /** * @return the String used as a horizontal section divider */ public String getDivider() { return divider; } /** * @return the Exception being documented by this HelpFormatter */ public OptionException getException() { return exception; } /** * @return the help screen footer text */ public String getFooter() { return footer; } /** * @return the DisplaySettings used in the full usage string */ public Set getFullUs ageSettings() { return fullUsageSettings; } /** * @return the group documented by this HelpFormatter */ public Group getGroup() { return group; } /** * @return the String used as the central gutter */ public String getGutterCenter() { return gutterCenter; } /** * @return the String used as the left gutter */ public String getGutterLeft() { return gutterLeft; } /** * @return the String used as the right gutter */ public String getGutterRight() { return gutterRight; } /** * @return the help screen header text */ public String getHeader() { return header; } /** * @return the DisplaySettings used in the per help line usage strings */ public Set getLineUsageSettings() { return lineUsageSettings; } /** * @return the width of the screen in characters */ public int getPageWidth() { return pageWidth; } /** * @return the command used to execute the application */ public String getShellCommand() { return shellCommand; } /** * @param out the PrintWriter to write to */ public void setPrintWriter(PrintWriter out) { this.out = out; } /** * @return the PrintWriter that will be written to */ public PrintWriter getPrintWriter() { return out; }} \ No newline at end of file +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.cli2.util; + +import java.io.PrintWriter; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import org.apache.commons.cli2.DisplaySetting; +import org.apache.commons.cli2.Group; +import org.apache.commons.cli2.HelpLine; +import org.apache.commons.cli2.Option; +import org.apache.commons.cli2.OptionException; +import org.apache.commons.cli2.resource.ResourceConstants; +import org.apache.commons.cli2.resource.ResourceHelper; + +/** + * Presents on screen help based on the application's Options + */ +public class HelpFormatter { + /** + * The default screen width + */ + public static final int DEFAULT_FULL_WIDTH = 80; + + /** + * The default screen furniture left of screen + */ + public static final String DEFAULT_GUTTER_LEFT = ""; + + /** + * The default screen furniture right of screen + */ + public static final String DEFAULT_GUTTER_CENTER = " "; + + /** + * The default screen furniture between columns + */ + public static final String DEFAULT_GUTTER_RIGHT = ""; + + /** + * The default DisplaySettings used to select the elements to display in the + * displayed line of full usage information. + * + * @see DisplaySetting + */ + public static final Set DEFAULT_FULL_USAGE_SETTINGS; + + /** + * The default DisplaySettings used to select the elements of usage per help + * line in the main body of help + * + * @see DisplaySetting + */ + public static final Set DEFAULT_LINE_USAGE_SETTINGS; + + /** + * The default DisplaySettings used to select the help lines in the main + * body of help + */ + public static final Set DEFAULT_DISPLAY_USAGE_SETTINGS; + + static { + final Set fullUsage = new HashSet(DisplaySetting.ALL); + fullUsage.remove(DisplaySetting.DISPLAY_ALIASES); + fullUsage.remove(DisplaySetting.DISPLAY_GROUP_NAME); + DEFAULT_FULL_USAGE_SETTINGS = Collections.unmodifiableSet(fullUsage); + + final Set lineUsage = new HashSet(); + lineUsage.add(DisplaySetting.DISPLAY_ALIASES); + lineUsage.add(DisplaySetting.DISPLAY_GROUP_NAME); + lineUsage.add(DisplaySetting.DISPLAY_PARENT_ARGUMENT); + DEFAULT_LINE_USAGE_SETTINGS = Collections.unmodifiableSet(lineUsage); + + final Set displayUsage = new HashSet(DisplaySetting.ALL); + displayUsage.remove(DisplaySetting.DISPLAY_PARENT_ARGUMENT); + DEFAULT_DISPLAY_USAGE_SETTINGS = Collections.unmodifiableSet(displayUsage); + } + + private Set fullUsageSettings = new HashSet(DEFAULT_FULL_USAGE_SETTINGS); + private Set lineUsageSettings = new HashSet(DEFAULT_LINE_USAGE_SETTINGS); + private Set displaySettings = new HashSet(DEFAULT_DISPLAY_USAGE_SETTINGS); + private OptionException exception = null; + private Group group; + private Comparator comparator = null; + private String divider = null; + private String header = null; + private String footer = null; + private String shellCommand = ""; + private PrintWriter out = new PrintWriter(System.out); + + //or should this default to .err? + private final String gutterLeft; + private final String gutterCenter; + private final String gutterRight; + private final int pageWidth; + + /** + * Creates a new HelpFormatter using the defaults + */ + public HelpFormatter() { + this(DEFAULT_GUTTER_LEFT, DEFAULT_GUTTER_CENTER, DEFAULT_GUTTER_RIGHT, DEFAULT_FULL_WIDTH); + } + + /** + * Creates a new HelpFormatter using the specified parameters + * @param gutterLeft the string marking left of screen + * @param gutterCenter the string marking center of screen + * @param gutterRight the string marking right of screen + * @param fullWidth the width of the screen + */ + public HelpFormatter(final String gutterLeft, + final String gutterCenter, + final String gutterRight, + final int fullWidth) { + // default the left gutter to empty string + this.gutterLeft = (gutterLeft == null) ? DEFAULT_GUTTER_LEFT : gutterLeft; + + // default the center gutter to a single space + this.gutterCenter = (gutterCenter == null) ? DEFAULT_GUTTER_CENTER : gutterCenter; + + // default the right gutter to empty string + this.gutterRight = (gutterRight == null) ? DEFAULT_GUTTER_RIGHT : gutterRight; + + // calculate the available page width + this.pageWidth = fullWidth - this.gutterLeft.length() - this.gutterRight.length(); + + // check available page width is valid + int availableWidth = fullWidth - pageWidth + this.gutterCenter.length(); + + if (availableWidth < 2) { + throw new IllegalArgumentException(ResourceHelper.getResourceHelper().getMessage(ResourceConstants.HELPFORMATTER_GUTTER_TOO_LONG)); + } + } + + /** + * Prints the Option help. + */ + public void print() { + printHeader(); + printException(); + printUsage(); + printHelp(); + printFooter(); + out.flush(); + } + + /** + * Prints any error message. + */ + public void printException() { + if (exception != null) { + printDivider(); + printWrapped(exception.getMessage()); + } + } + + /** + * Prints detailed help per option. + */ + public void printHelp() { + printDivider(); + + final Option option; + + if ((exception != null) && (exception.getOption() != null)) { + option = exception.getOption(); + } else { + option = group; + } + + // grab the HelpLines to display + final List helpLines = option.helpLines(0, displaySettings, comparator); + + // calculate the maximum width of the usage strings + int usageWidth = 0; + + for (final Iterator i = helpLines.iterator(); i.hasNext();) { + final HelpLine helpLine = (HelpLine) i.next(); + final String usage = helpLine.usage(lineUsageSettings, comparator); + usageWidth = Math.max(usageWidth, usage.length()); + } + + // build a blank string to pad wrapped descriptions + final StringBuffer blankBuffer = new StringBuffer(); + + for (int i = 0; i < usageWidth; i++) { + blankBuffer.append(' '); + } + + // determine the width available for descriptions + final int descriptionWidth = Math.max(1, pageWidth - gutterCenter.length() - usageWidth); + + // display each HelpLine + for (final Iterator i = helpLines.iterator(); i.hasNext();) { + // grab the HelpLine + final HelpLine helpLine = (HelpLine) i.next(); + + // wrap the description + final List descList = wrap(helpLine.getDescription(), descriptionWidth); + final Iterator descriptionIterator = descList.iterator(); + + // display usage + first line of description + printGutterLeft(); + pad(helpLine.usage(lineUsageSettings, comparator), usageWidth, out); + out.print(gutterCenter); + pad((String) descriptionIterator.next(), descriptionWidth, out); + printGutterRight(); + out.println(); + + // display padding + remaining lines of description + while (descriptionIterator.hasNext()) { + printGutterLeft(); + + //pad(helpLine.getUsage(),usageWidth,out); + out.print(blankBuffer); + out.print(gutterCenter); + pad((String) descriptionIterator.next(), descriptionWidth, out); + printGutterRight(); + out.println(); + } + } + + printDivider(); + } + + /** + * Prints a single line of usage information (wrapping if necessary) + */ + public void printUsage() { + printDivider(); + + final StringBuffer buffer = new StringBuffer("Usage:\n"); + buffer.append(shellCommand).append(' '); + group.appendUsage(buffer, fullUsageSettings, comparator, " "); + printWrapped(buffer.toString()); + } + + /** + * Prints a header string if necessary + */ + public void printHeader() { + if (header != null) { + printDivider(); + printWrapped(header); + } + } + + /** + * Prints a footer string if necessary + */ + public void printFooter() { + if (footer != null) { + printWrapped(footer); + printDivider(); + } + } + + /** + * Prints a string wrapped if necessary + * @param text the string to wrap + */ + public void printWrapped(final String text) { + for (final Iterator i = wrap(text, pageWidth).iterator(); i.hasNext();) { + printGutterLeft(); + pad((String) i.next(), pageWidth, out); + printGutterRight(); + out.println(); + } + + out.flush(); + } + + /** + * Prints the left gutter string + */ + public void printGutterLeft() { + if (gutterLeft != null) { + out.print(gutterLeft); + } + } + + /** + * Prints the right gutter string + */ + public void printGutterRight() { + if (gutterRight != null) { + out.print(gutterRight); + } + } + + /** + * Prints the divider text + */ + public void printDivider() { + if (divider != null) { + out.println(divider); + } + } + + protected static void pad(final String text, + final int width, + final PrintWriter writer) { + final int left; + + // write the text and record how many characters written + if (text == null) { + left = 0; + } else { + writer.write(text); + left = text.length(); + } + + // pad remainder with spaces + for (int i = left; i < width; ++i) { + writer.write(' '); + } + } + + protected static List wrap(final String text, + final int width) { + // check for valid width + if (width < 1) { + throw new IllegalArgumentException(ResourceHelper.getResourceHelper().getMessage(ResourceConstants.HELPFORMATTER_WIDTH_TOO_NARROW, + new Object[] { + new Integer(width) + })); + } + + // handle degenerate case + if (text == null) { + return Collections.singletonList(""); + } + + final List lines = new ArrayList(); + final char[] chars = text.toCharArray(); + int left = 0; + + // for each character in the string + while (left < chars.length) { + // sync left and right indeces + int right = left; + + // move right until we run out of characters, width or find a newline + while ((right < chars.length) && (chars[right] != '\n') && + (right < (left + width + 1))) { + right++; + } + + // if a newline was found + if ((right < chars.length) && (chars[right] == '\n')) { + // record the substring + final String line = new String(chars, left, right - left); + lines.add(line); + + // move to the end of the substring + left = right + 1; + + if (left == chars.length) { + lines.add(""); + } + + // restart the loop + continue; + } + + // move to the next ideal wrap point + right = (left + width) - 1; + + // if we have run out of characters + if (chars.length <= right) { + // record the substring + final String line = new String(chars, left, chars.length - left); + lines.add(line); + + // abort the loop + break; + } + + // back track the substring end until a space is found + while ((right >= left) && (chars[right] != ' ')) { + right--; + } + + // if a space was found + if (right >= left) { + // record the substring to space + final String line = new String(chars, left, right - left); + lines.add(line); + + // absorb all the spaces before next substring + while ((right < chars.length) && (chars[right] == ' ')) { + right++; + } + + left = right; + + // restart the loop + continue; + } + + // move to the wrap position irrespective of spaces + right = Math.min(left + width, chars.length); + + // record the substring + final String line = new String(chars, left, right - left); + lines.add(line); + + // absorb any the spaces before next substring + while ((right < chars.length) && (chars[right] == ' ')) { + right++; + } + + left = right; + } + + return lines; + } + + /** + * The Comparator to use when sorting Options + * @param comparator Comparator to use when sorting Options + */ + public void setComparator(Comparator comparator) { + this.comparator = comparator; + } + + /** + * The DisplaySettings used to select the help lines in the main body of + * help + * + * @param displaySettings the settings to use + * @see DisplaySetting + */ + public void setDisplaySettings(Set displaySettings) { + this.displaySettings = displaySettings; + } + + /** + * Sets the string to use as a divider between sections of help + * @param divider the dividing string + */ + public void setDivider(String divider) { + this.divider = divider; + } + + /** + * Sets the exception to document + * @param exception the exception that occured + */ + public void setException(OptionException exception) { + this.exception = exception; + } + + /** + * Sets the footer text of the help screen + * @param footer the footer text + */ + public void setFooter(String footer) { + this.footer = footer; + } + + /** + * The DisplaySettings used to select the elements to display in the + * displayed line of full usage information. + * @see DisplaySetting + * @param fullUsageSettings + */ + public void setFullUsageSettings(Set fullUsageSettings) { + this.fullUsageSettings = fullUsageSettings; + } + + /** + * Sets the Group of Options to document + * @param group the options to document + */ + public void setGroup(Group group) { + this.group = group; + } + + /** + * Sets the footer text of the help screen + * @param header the footer text + */ + public void setHeader(String header) { + this.header = header; + } + + /** + * Sets the DisplaySettings used to select elements in the per helpline + * usage strings. + * @see DisplaySetting + * @param lineUsageSettings the DisplaySettings to use + */ + public void setLineUsageSettings(Set lineUsageSettings) { + this.lineUsageSettings = lineUsageSettings; + } + + /** + * Sets the command string used to invoke the application + * @param shellCommand the invokation command + */ + public void setShellCommand(String shellCommand) { + this.shellCommand = shellCommand; + } + + /** + * @return the Comparator used to sort the Group + */ + public Comparator getComparator() { + return comparator; + } + + /** + * @return the DisplaySettings used to select HelpLines + */ + public Set getDisplaySettings() { + return displaySettings; + } + + /** + * @return the String used as a horizontal section divider + */ + public String getDivider() { + return divider; + } + + /** + * @return the Exception being documented by this HelpFormatter + */ + public OptionException getException() { + return exception; + } + + /** + * @return the help screen footer text + */ + public String getFooter() { + return footer; + } + + /** + * @return the DisplaySettings used in the full usage string + */ + public Set getFullUsageSettings() { + return fullUsageSettings; + } + + /** + * @return the group documented by this HelpFormatter + */ + public Group getGroup() { + return group; + } + + /** + * @return the String used as the central gutter + */ + public String getGutterCenter() { + return gutterCenter; + } + + /** + * @return the String used as the left gutter + */ + public String getGutterLeft() { + return gutterLeft; + } + + /** + * @return the String used as the right gutter + */ + public String getGutterRight() { + return gutterRight; + } + + /** + * @return the help screen header text + */ + public String getHeader() { + return header; + } + + /** + * @return the DisplaySettings used in the per help line usage strings + */ + public Set getLineUsageSettings() { + return lineUsageSettings; + } + + /** + * @return the width of the screen in characters + */ + public int getPageWidth() { + return pageWidth; + } + + /** + * @return the command used to execute the application + */ + public String getShellCommand() { + return shellCommand; + } + + /** + * @param out the PrintWriter to write to + */ + public void setPrintWriter(PrintWriter out) { + this.out = out; + } + + /** + * @return the PrintWriter that will be written to + */ + public PrintWriter getPrintWriter() { + return out; + } +} Modified: commons/proper/cli/trunk/src/java/org/apache/commons/cli2/validation/ClassValidator.java URL: http://svn.apache.org/viewvc/commons/proper/cli/trunk/src/java/org/apache/commons/cli2/validation/ClassValidator.java?rev=639943&r1=639942&r2=639943&view=diff ============================================================================== --- commons/proper/cli/trunk/src/java/org/apache/commons/cli2/validation/ClassValidator.java (original) +++ commons/proper/cli/trunk/src/java/org/apache/commons/cli2/validation/ClassValidator.java Fri Mar 21 20:08:23 2008 @@ -1 +1,201 @@ -/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package org.apache.commons.cli2.validation;import java.util.List;import java.util.ListIterator;import org.apache.commons.cli2.resource.ResourceConstants;import org.apache.commons.cli2.resource.ResourceHe lper;/** * The ClassValidator validates the string argument * values are class names. * * The following example shows how to validate the 'logger' * argument value is a class name, that can be instantiated. * *
 * ... * ClassValidator validator = new ClassValidator(); * validator.setInstance(true); * * ArgumentBuilder builder = new ArgumentBuilder(); * Argument logger = *     builder.withName("logger"); *            .withValidator(validator); * 
* * @author John Keyes */public class ClassValidator implements Validator { /** i18n */ private static final ResourceHelper resources = ResourceHelper.getResourceHelper(); /** whether the class argument is loadable */ private boolean loadable; /** whether to create an instance of the class */ private boolean instance; /** the classloader to load classes from */ private ClassLoader loader; /** * Validate each argument value in the specified List against this instances * permit ted attributes. * * If a value is valid then it's String value in the list is * replaced with it's Class value or instance. * * @see org.apache.commons.cli2.validation.Validator#validate(java.util.List) */ public void validate(final List values) throws InvalidArgumentException { for (final ListIterator i = values.listIterator(); i.hasNext();) { final String name = (String) i.next(); if (!isPotentialClassName(name)) { throw new InvalidArgumentException(resources.getMessage(ResourceConstants.CLASSVALIDATOR_BAD_CLASSNAME, name)); } if (loadable || instance) { final ClassLoader theLoader = getClassLoader(); try { final Class clazz = theLoader.loadClass(name); if (instance) { i.set(clazz.newInstan ce()); } else { i.set(clazz); } } catch (final ClassNotFoundException exp) { throw new InvalidArgumentException(resources.getMessage(ResourceConstants.CLASSVALIDATOR_CLASS_NOTFOUND, name)); } catch (final IllegalAccessException exp) { throw new InvalidArgumentException(resources.getMessage(ResourceConstants.CLASSVALIDATOR_CLASS_ACCESS, name, exp.getMessage())); } catch (final InstantiationException exp) { throw new InvalidArgumentException(resources.getMessage(ResourceConstants.CLASSVALIDATOR_CLASS_CREATE, name)); } } } } /** * Returns whether the argu ment value must represent a * class that is loadable. * * @return whether the argument value must represent a * class that is loadable. */ public boolean isLoadable() { return loadable; } /** * Specifies whether the argument value must represent a * class that is loadable. * * @param loadable whether the argument value must * represent a class that is loadable. */ public void setLoadable(boolean loadable) { this.loadable = loadable; } /** * Returns the {@link ClassLoader} used to resolve and load * the classes specified by the argument values. * * @return the {@link ClassLoader} used to resolve and load * the classes specified by the argument values. */ public ClassLoader getClassLoader() { if (loader == null) { loader = getClass().getClassLoader(); } return loader; } /** * Specifies the {@link ClassLoader} used to resolve and load * the classes specified by the argument values. * * @param loader the {@link ClassLoader} used to resolve and load * the classes specified by the argument values. */ public void setClassLoader(ClassLoader loader) { this.loader = loader; } /** * Returns whether the argument value must represent a * class that can be instantiated. * * @return whether the argument value must represent a * class that can be instantiated. */ public boolean isInstance() { return instance; } /** * Specifies whether the argument value must represent a * class that can be instantiated. * * @param instance whether the argument value must * represent a class that can be instantiated. */ public void setInstance(boolean instance) { this.instance = instance; } /** * Returns whether the specified name is allowed as * a Java class name. */ protected boolean isPotentialClassName( final String name) { final char[] chars = name.toCharArray(); boolean expectingStart = true; for (int i = 0; i < chars.length; ++i) { final char c = chars[i]; if (expectingStart) { if (!Character.isJavaIdentifierStart(c)) { return false; } expectingStart = false; } else { if (c == '.') { expectingStart = true; } else if (!Character.isJavaIdentifierPart(c)) { return false; } } } return !expectingStart; }} \ No newline at end of file +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.cli2.validation; + +import java.util.List; +import java.util.ListIterator; + +import org.apache.commons.cli2.resource.ResourceConstants; +import org.apache.commons.cli2.resource.ResourceHelper; + +/** + * The ClassValidator validates the string argument + * values are class names. + * + * The following example shows how to validate the 'logger' + * argument value is a class name, that can be instantiated. + * + *
+ * ...
+ * ClassValidator validator = new ClassValidator();
+ * validator.setInstance(true);
+ *
+ * ArgumentBuilder builder = new ArgumentBuilder();
+ * Argument logger =
+ *     builder.withName("logger");
+ *            .withValidator(validator);
+ * 
+ * + * @author John Keyes + */ +public class ClassValidator implements Validator { + /** i18n */ + private static final ResourceHelper resources = ResourceHelper.getResourceHelper(); + + /** whether the class argument is loadable */ + private boolean loadable; + + /** whether to create an instance of the class */ + private boolean instance; + + /** the classloader to load classes from */ + private ClassLoader loader; + + /** + * Validate each argument value in the specified List against this instances + * permitted attributes. + * + * If a value is valid then it's String value in the list is + * replaced with it's Class value or instance. + * + * @see org.apache.commons.cli2.validation.Validator#validate(java.util.List) + */ + public void validate(final List values) + throws InvalidArgumentException { + for (final ListIterator i = values.listIterator(); i.hasNext();) { + final String name = (String) i.next(); + + if (!isPotentialClassName(name)) { + throw new InvalidArgumentException(resources.getMessage(ResourceConstants.CLASSVALIDATOR_BAD_CLASSNAME, + name)); + } + + if (loadable || instance) { + final ClassLoader theLoader = getClassLoader(); + + try { + final Class clazz = theLoader.loadClass(name); + + if (instance) { + i.set(clazz.newInstance()); + } else { + i.set(clazz); + } + } catch (final ClassNotFoundException exp) { + throw new InvalidArgumentException(resources.getMessage(ResourceConstants.CLASSVALIDATOR_CLASS_NOTFOUND, + name)); + } catch (final IllegalAccessException exp) { + throw new InvalidArgumentException(resources.getMessage(ResourceConstants.CLASSVALIDATOR_CLASS_ACCESS, + name, exp.getMessage())); + } catch (final InstantiationException exp) { + throw new InvalidArgumentException(resources.getMessage(ResourceConstants.CLASSVALIDATOR_CLASS_CREATE, + name)); + } + } + } + } + + /** + * Returns whether the argument value must represent a + * class that is loadable. + * + * @return whether the argument value must represent a + * class that is loadable. + */ + public boolean isLoadable() { + return loadable; + } + + /** + * Specifies whether the argument value must represent a + * class that is loadable. + * + * @param loadable whether the argument value must + * represent a class that is loadable. + */ + public void setLoadable(boolean loadable) { + this.loadable = loadable; + } + + /** + * Returns the {@link ClassLoader} used to resolve and load + * the classes specified by the argument values. + * + * @return the {@link ClassLoader} used to resolve and load + * the classes specified by the argument values. + */ + public ClassLoader getClassLoader() { + if (loader == null) { + loader = getClass().getClassLoader(); + } + + return loader; + } + + /** + * Specifies the {@link ClassLoader} used to resolve and load + * the classes specified by the argument values. + * + * @param loader the {@link ClassLoader} used to resolve and load + * the classes specified by the argument values. + */ + public void setClassLoader(ClassLoader loader) { + this.loader = loader; + } + + /** + * Returns whether the argument value must represent a + * class that can be instantiated. + * + * @return whether the argument value must represent a + * class that can be instantiated. + */ + public boolean isInstance() { + return instance; + } + + /** + * Specifies whether the argument value must represent a + * class that can be instantiated. + * + * @param instance whether the argument value must + * represent a class that can be instantiated. + */ + public void setInstance(boolean instance) { + this.instance = instance; + } + + /** + * Returns whether the specified name is allowed as + * a Java class name. + */ + protected boolean isPotentialClassName(final String name) { + final char[] chars = name.toCharArray(); + + boolean expectingStart = true; + + for (int i = 0; i < chars.length; ++i) { + final char c = chars[i]; + + if (expectingStart) { + if (!Character.isJavaIdentifierStart(c)) { + return false; + } + + expectingStart = false; + } else { + if (c == '.') { + expectingStart = true; + } else if (!Character.isJavaIdentifierPart(c)) { + return false; + } + } + } + + return !expectingStart; + } +}