001/** 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.commons.cli2.commandline; 018 019import java.util.ArrayList; 020import java.util.Arrays; 021import java.util.Collections; 022import java.util.HashSet; 023import java.util.Iterator; 024import java.util.List; 025import java.util.Set; 026import java.util.StringTokenizer; 027import java.util.prefs.BackingStoreException; 028import java.util.prefs.Preferences; 029 030import org.apache.commons.cli2.Option; 031import org.apache.commons.cli2.option.PropertyOption; 032 033/** 034 * A CommandLine implementation using the Preferences API, useful when 035 * constructing a complex DefaultingCommandLine 036 * 037 * This implementation uses the children of a single preference node to populate 038 * the CommandLine. Options are keyed from their preferred name and presence in 039 * the Preferences object is taken as presence in the CommandLine. Argument 040 * values are taken from the Preference value and are optionally separated using 041 * the separator char defined, at construction time. Switch values can be 042 * specified using a simple value of <code>true</code> or <code>false</code>; 043 * obviously this means that Switches with Arguments are not supported by this 044 * implementation. 045 * 046 * @see java.util.prefs.Preferences 047 * @see org.apache.commons.cli2.commandline.DefaultingCommandLine 048 * @see org.apache.commons.cli2.Option#getPreferredName() 049 */ 050public class PreferencesCommandLine extends CommandLineImpl { 051 052 private static final char NUL = '\0'; 053 private final Preferences preferences; 054 private final Option root; 055 private final char separator; 056 057 /** 058 * Creates a new PreferencesCommandLine using the specified root Option and 059 * Preferences node. Argument values will be separated using the char 0. 060 * 061 * @param root the CommandLine's root Option 062 * @param preferences the Preferences node to get values from 063 */ 064 public PreferencesCommandLine(final Option root, final Preferences preferences){ 065 this(root,preferences,NUL); 066 } 067 068 /** 069 * Creates a new PreferencesCommandLine using the specified root Option, 070 * Preferences node and value separator. 071 * 072 * @param root the CommandLine's root Option 073 * @param preferences the Preferences node to get values from 074 * @param separator the character to split argument values 075 */ 076 public PreferencesCommandLine(final Option root, final Preferences preferences, final char separator){ 077 this.root = root; 078 this.preferences = preferences; 079 this.separator = separator; 080 } 081 082 public boolean hasOption(Option option) { 083 if(option==null){ 084 return false; 085 } 086 else{ 087 try { 088 return Arrays.asList(preferences.keys()).contains(option.getPreferredName()); 089 } catch (BackingStoreException e) { 090 return false; 091 } 092 } 093 } 094 095 public Option getOption(String trigger) { 096 return root.findOption(trigger); 097 } 098 099 public List getValues(final Option option, final List defaultValues) { 100 final String value = preferences.get(option.getPreferredName(),null); 101 102 if(value==null){ 103 return defaultValues; 104 } 105 else if(separator>NUL){ 106 final List values = new ArrayList(); 107 final StringTokenizer tokens = new StringTokenizer(value,String.valueOf(separator)); 108 109 while(tokens.hasMoreTokens()){ 110 values.add(tokens.nextToken()); 111 } 112 113 return values; 114 } 115 else{ 116 return Collections.singletonList(value); 117 } 118 } 119 120 public Boolean getSwitch(final Option option, final Boolean defaultValue) { 121 final String value = preferences.get(option.getPreferredName(),null); 122 if("true".equals(value)){ 123 return Boolean.TRUE; 124 } 125 else if("false".equals(value)){ 126 return Boolean.FALSE; 127 } 128 else{ 129 return defaultValue; 130 } 131 } 132 133 public String getProperty(final String property) { 134 return getProperty(new PropertyOption(), property); 135 } 136 137 public String getProperty(final Option option, final String property, final String defaultValue) { 138 return preferences.get(property, defaultValue); 139 } 140 141 public Set getProperties(final Option option) { 142 try { 143 return new HashSet(Arrays.asList(preferences.keys())); 144 } catch (BackingStoreException e) { 145 return Collections.EMPTY_SET; 146 } 147 } 148 149 public Set getProperties() { 150 return getProperties(new PropertyOption()); 151 } 152 153 public List getOptions() { 154 try { 155 final List options = new ArrayList(); 156 final Iterator keys = Arrays.asList(preferences.keys()).iterator(); 157 while (keys.hasNext()) { 158 final String trigger = (String) keys.next(); 159 final Option option = root.findOption(trigger); 160 if (option != null) { 161 options.add(option); 162 } 163 } 164 return Collections.unmodifiableList(options); 165 } catch (BackingStoreException e) { 166 return Collections.EMPTY_LIST; 167 } 168 } 169 170 public Set getOptionTriggers() { 171 final Set triggers = new HashSet(); 172 final Iterator options = getOptions().iterator(); 173 while(options.hasNext()){ 174 final Option option = (Option)options.next(); 175 triggers.addAll(option.getTriggers()); 176 } 177 return Collections.unmodifiableSet(triggers); 178 } 179}