001package org.unix4j.unix.sed; 002 003import java.util.Collections; 004import java.util.Iterator; 005 006import org.unix4j.convert.OptionSetConverters.OptionSetConverter; 007import org.unix4j.convert.ValueConverter; 008import org.unix4j.option.DefaultOptionSet; 009import org.unix4j.option.Option; 010import org.unix4j.option.OptionSet; 011 012import org.unix4j.unix.Sed; 013import org.unix4j.unix.sed.SedOption; 014 015/** 016 * Interface implemented by all option sets for the {@link Sed sed} command. 017 * It is recommended to use {@link Sed#Options} to specify a valid 018 * combination of options. 019 * <p> 020 * The options for the sed command are: 021 * <p> 022 * <table> 023 * <tr valign="top"><td width="10px"></td><td nowrap="nowrap">{@code -n}</td><td> </td><td nowrap="nowrap">{@code --quiet}</td><td> </td><td>Suppress the default output (in which each line, after it is 024 examined for editing, is written to standard output). Only lines 025 explicitly selected for output are written.</td></tr> 026 * <tr valign="top"><td width="10px"></td><td nowrap="nowrap">{@code -g}</td><td> </td><td nowrap="nowrap">{@code --global}</td><td> </td><td>Globally substitute for all non-overlapping instances of the regexp 027 rather than just the first one. 028 <p> 029 (This option is ignored if the occurrence operand is specified).</td></tr> 030 * <tr valign="top"><td width="10px"></td><td nowrap="nowrap">{@code -p}</td><td> </td><td nowrap="nowrap">{@code --print}</td><td> </td><td>Write the matched line to standard output.</td></tr> 031 * <tr valign="top"><td width="10px"></td><td nowrap="nowrap">{@code -l}</td><td> </td><td nowrap="nowrap">{@code --lineNumber}</td><td> </td><td>Writes the current line number on a separate line to the standard 032 output.</td></tr> 033 * <tr valign="top"><td width="10px"></td><td nowrap="nowrap">{@code -I}</td><td> </td><td nowrap="nowrap">{@code --ignoreCase}</td><td> </td><td>Use case insensitive pattern matching.</td></tr> 034 * <tr valign="top"><td width="10px"></td><td nowrap="nowrap">{@code -s}</td><td> </td><td nowrap="nowrap">{@code --substitute}</td><td> </td><td>Substitutes the replacement string for instances of the regexp in 035 the matched line. 036<p> 037 The characters "$0" appearing in the replacement are replaced 038 by the line matching the regexp. The characters "$n", where n is a 039 digit other than zero, are replaced by the text matched by the 040 corresponding backreference expression (aka group). The special 041 meaning of "$n" in this context can be suppressed by preceding it 042 by a backslash. 043<p> 044 A line can be split by substituting a newline ('\n') into it. 045 <p> 046 A substitution is considered to have been performed even if the 047 replacement string is identical to the string that it replaces.</td></tr> 048 * <tr valign="top"><td width="10px"></td><td nowrap="nowrap">{@code -a}</td><td> </td><td nowrap="nowrap">{@code --append}</td><td> </td><td>Append string2 as a separate line after the matched line.</td></tr> 049 * <tr valign="top"><td width="10px"></td><td nowrap="nowrap">{@code -i}</td><td> </td><td nowrap="nowrap">{@code --insert}</td><td> </td><td>Insert string2 as a separate line before the matched line.</td></tr> 050 * <tr valign="top"><td width="10px"></td><td nowrap="nowrap">{@code -c}</td><td> </td><td nowrap="nowrap">{@code --change}</td><td> </td><td>Write string2 as a separate line instead of the matched line.</td></tr> 051 * <tr valign="top"><td width="10px"></td><td nowrap="nowrap">{@code -d}</td><td> </td><td nowrap="nowrap">{@code --delete}</td><td> </td><td>Delete the matched line.</td></tr> 052 * <tr valign="top"><td width="10px"></td><td nowrap="nowrap">{@code -y}</td><td> </td><td nowrap="nowrap">{@code --translate}</td><td> </td><td>Replace all occurrences of characters in string1 with the 053 corresponding characters in string2. If the number of characters in 054 the two strings are not equal, or if any of the characters in 055 string1 appear more than once, the results are undefined.</td></tr> 056 * </table> 057 * <p> 058 * This interface serves as an alias for the extended interface to simplify the 059 * command signature methods by avoiding generic parameters. 060 */ 061public interface SedOptions extends OptionSet<SedOption> { 062 /** 063 * Constant for an empty option set. 064 */ 065 SedOptions EMPTY = new SedOptions() { 066 @Override 067 public Class<SedOption> optionType() { 068 return SedOption.class; 069 } 070 @Override 071 public boolean isSet(SedOption option) { 072 return false; 073 } 074 /** 075 * Returns 0 as this is a set with no active options. 076 * 077 * @return zero 078 */ 079 @Override 080 public int size() { 081 return 0; 082 } 083 /** 084 * Returns an immutable empty set. 085 * 086 * @return an immutable empty set. 087 */ 088 @Override 089 public java.util.Set<SedOption> asSet() { 090 return Collections.emptySet(); 091 } 092 093 /** 094 * Returns an iterator returning no elements. 095 * 096 * @return an immutable iterator with no elements. 097 */ 098 @Override 099 public Iterator<SedOption> iterator() { 100 return asSet().iterator(); 101 } 102 103 /** 104 * Returns true if the {@link Option#acronym() acronym} should be used 105 * for the specified {@code option} in string representations. 106 * <p> 107 * This method returns always true; 108 * 109 * @param option 110 * the option of interest 111 * @return always true 112 */ 113 @Override 114 public boolean useAcronymFor(SedOption option) { 115 return true; 116 } 117 }; 118 /** 119 * Default implementation for a modifiable option set. 120 */ 121 class Default extends DefaultOptionSet<SedOption> implements SedOptions { 122 /** 123 * Default constructor for an empty option set with no active options. 124 */ 125 public Default() { 126 super(SedOption.class); 127 } 128 /** 129 * Constructor for an option set with a single active option. 130 * @param option the option to be set 131 */ 132 public Default(SedOption option) { 133 super(option); 134 } 135 /** 136 * Constructor for an option set with the given active options. 137 * @param options the options to be set 138 */ 139 public Default(SedOption... options) { 140 this(); 141 setAll(options); 142 } 143 /** 144 * Constructor for an option set initialized with the options given by 145 * another option set. 146 * 147 * @param optionSet set with the options to be active 148 */ 149 public Default(OptionSet<SedOption> optionSet) { 150 this(); 151 setAll(optionSet); 152 } 153 } 154 155 /** 156 * Value converter for {@link SedOptions} based on an {@link OptionSetConverter}. 157 */ 158 ValueConverter<SedOptions> CONVERTER = new ValueConverter<SedOptions>() { 159 private final OptionSetConverter<SedOption> converter = new OptionSetConverter<SedOption>(SedOption.class); 160 @Override 161 public SedOptions convert(Object value) { 162 final OptionSet<SedOption> set = converter.convert(value); 163 return set == null ? null : new Default(set); 164 } 165 }; 166}