Frames | No Frames |
1: /** 2: * Copyright 2004 The Apache Software Foundation 3: * Copyright 2005 Stephen McConnell 4: * 5: * Licensed under the Apache License, Version 2.0 (the "License"); 6: * you may not use this file except in compliance with the License. 7: * You may obtain a copy of the License at 8: * 9: * http://www.apache.org/licenses/LICENSE-2.0 10: * 11: * Unless required by applicable law or agreed to in writing, software 12: * distributed under the License is distributed on an "AS IS" BASIS, 13: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14: * See the License for the specific language governing permissions and 15: * limitations under the License. 16: */ 17: package net.dpml.cli.commandline; 18: 19: import java.util.ArrayList; 20: import java.util.Arrays; 21: import java.util.Collections; 22: import java.util.HashSet; 23: import java.util.Iterator; 24: import java.util.List; 25: import java.util.Set; 26: import java.util.StringTokenizer; 27: import java.util.prefs.BackingStoreException; 28: import java.util.prefs.Preferences; 29: 30: import net.dpml.cli.Option; 31: 32: /** 33: * A CommandLine implementation using the Preferences API, useful when 34: * constructing a complex DefaultingCommandLine 35: * 36: * This implementation uses the children of a single preference node to populate 37: * the CommandLine. Options are keyed from their preferred name and presence in 38: * the Preferences object is taken as presence in the CommandLine. Argument 39: * values are taken from the Preference value and are optionally separated using 40: * the separator char defined, at construction time. Switch values can be 41: * specified using a simple value of <code>true</code> or <code>false</code>; 42: * obviously this means that Switches with Arguments are not supported by this 43: * implementation. 44: * 45: * @author <a href="@PUBLISHER-URL@">@PUBLISHER-NAME@</a> 46: * @version @PROJECT-VERSION@ 47: * @see java.util.prefs.Preferences 48: * @see net.dpml.cli.commandline.DefaultingCommandLine 49: * @see net.dpml.cli.Option#getPreferredName() 50: */ 51: public class PreferencesCommandLine extends CommandLineImpl 52: { 53: private static final char NUL = '\0'; 54: private final Preferences m_preferences; 55: private final Option m_root; 56: private final char m_separator; 57: 58: /** 59: * Creates a new PreferencesCommandLine using the specified root Option and 60: * Preferences node. Argument values will be separated using the char 0. 61: * 62: * @param root the CommandLine's root Option 63: * @param preferences the Preferences node to get values from 64: */ 65: public PreferencesCommandLine( final Option root, final Preferences preferences ) 66: { 67: this( root, preferences, NUL ); 68: } 69: 70: /** 71: * Creates a new PreferencesCommandLine using the specified root Option, 72: * Preferences node and value separator. 73: * 74: * @param root the CommandLine's root Option 75: * @param preferences the Preferences node to get values from 76: * @param separator the character to split argument values 77: */ 78: public PreferencesCommandLine( 79: final Option root, final Preferences preferences, final char separator ) 80: { 81: m_root = root; 82: m_preferences = preferences; 83: m_separator = separator; 84: } 85: 86: /** 87: * Detects the presence of an option in this CommandLine. 88: * 89: * @param option the Option to search for 90: * @return true iff the option is present 91: */ 92: public boolean hasOption( Option option ) 93: { 94: if( option==null ) 95: { 96: return false; 97: } 98: else 99: { 100: try 101: { 102: return Arrays.asList( m_preferences.keys() ).contains( option.getPreferredName() ); 103: } 104: catch( BackingStoreException e ) 105: { 106: return false; 107: } 108: } 109: } 110: 111: /** 112: * Finds the Option with the specified trigger 113: * 114: * @param trigger the name of the option to retrieve 115: * @return the Option matching the trigger or null if none exists 116: */ 117: public Option getOption( String trigger ) 118: { 119: return m_root.findOption( trigger ); 120: } 121: 122: /** 123: * Retrieves the Argument values associated with the specified Option 124: * 125: * @param option the Option associated with the values 126: * @param defaultValues the result to return if no values are found 127: * @return a list of values or defaultValues if none are found 128: */ 129: public List getValues( final Option option, final List defaultValues ) 130: { 131: final String value = m_preferences.get( option.getPreferredName(), null ); 132: if( value==null ) 133: { 134: return defaultValues; 135: } 136: else if( m_separator>NUL ) 137: { 138: final List values = new ArrayList(); 139: final StringTokenizer tokens = new StringTokenizer( value, String.valueOf( m_separator ) ); 140: 141: while( tokens.hasMoreTokens() ) 142: { 143: values.add( tokens.nextToken() ); 144: } 145: 146: return values; 147: } 148: else 149: { 150: return Collections.singletonList( value ); 151: } 152: } 153: 154: /** 155: * Retrieves the Boolean value associated with the specified Switch 156: * 157: * @param option the Option associated with the value 158: * @param defaultValue the Boolean to use if none match 159: * @return the Boolean associated with option or defaultValue if none exists 160: */ 161: public Boolean getSwitch( final Option option, final Boolean defaultValue ) 162: { 163: final String value = m_preferences.get( option.getPreferredName(), null ); 164: if( "true".equals( value ) ) 165: { 166: return Boolean.TRUE; 167: } 168: else if( "false".equals( value ) ) 169: { 170: return Boolean.FALSE; 171: } 172: else 173: { 174: return defaultValue; 175: } 176: } 177: 178: /** 179: * Retrieves the value associated with the specified property 180: * 181: * @param property the property name to lookup 182: * @param defaultValue the value to use if no other is found 183: * @return the value of the property or defaultValue 184: */ 185: public String getProperty( final String property, final String defaultValue ) 186: { 187: return m_preferences.get( property, defaultValue ); 188: } 189: 190: /** 191: * Retrieves the set of all property names associated with this CommandLine 192: * 193: * @return a none null set of property names 194: */ 195: public Set getProperties() 196: { 197: try 198: { 199: return new HashSet( Arrays.asList( m_preferences.keys() ) ); 200: } 201: catch( BackingStoreException e ) 202: { 203: return Collections.EMPTY_SET; 204: } 205: } 206: 207: /** 208: * Retrieves a list of all Options found in this CommandLine 209: * 210: * @return a none null list of Options 211: */ 212: public List getOptions() 213: { 214: try 215: { 216: final List options = new ArrayList(); 217: final Iterator keys = Arrays.asList( m_preferences.keys() ).iterator(); 218: while( keys.hasNext() ) 219: { 220: final String trigger = (String) keys.next(); 221: final Option option = m_root.findOption( trigger ); 222: if( option != null ) 223: { 224: options.add( option ); 225: } 226: } 227: return Collections.unmodifiableList( options ); 228: } 229: catch( BackingStoreException e ) 230: { 231: return Collections.EMPTY_LIST; 232: } 233: } 234: 235: /** 236: * Retrieves a list of all Option triggers found in this CommandLine 237: * 238: * @return a none null list of Option triggers 239: */ 240: public Set getOptionTriggers() 241: { 242: final Set triggers = new HashSet(); 243: final Iterator options = getOptions().iterator(); 244: while( options.hasNext() ) 245: { 246: final Option option = (Option) options.next(); 247: triggers.addAll( option.getTriggers() ); 248: } 249: return Collections.unmodifiableSet( triggers ); 250: } 251: }