001package org.unix4j.unix.find;
002
003import java.util.Collections;
004import java.util.EnumSet;
005import java.util.Iterator;
006
007import org.unix4j.option.Option;
008import org.unix4j.unix.Find;
009
010/**
011 * Options for the {@link Find find} command.
012 * <p>
013 * For most applications, it may be more convenient to use {@link Find#Options} 
014 * instead of the option constants defined here.
015 * <p>
016 * <table>
017 * <tr valign="top"><td width="10px"></td><td nowrap="nowrap">{@code -d}</td><td>&nbsp;&nbsp;</td><td nowrap="nowrap">{@code --typeDirectory}</td><td>&nbsp;</td><td>Consider only directories</td></tr>
018 * <tr valign="top"><td width="10px"></td><td nowrap="nowrap">{@code -f}</td><td>&nbsp;&nbsp;</td><td nowrap="nowrap">{@code --typeFile}</td><td>&nbsp;</td><td>Consider only regular files</td></tr>
019 * <tr valign="top"><td width="10px"></td><td nowrap="nowrap">{@code -l}</td><td>&nbsp;&nbsp;</td><td nowrap="nowrap">{@code --typeSymlink}</td><td>&nbsp;</td><td>Consider only symbolic links</td></tr>
020 * <tr valign="top"><td width="10px"></td><td nowrap="nowrap">{@code -x}</td><td>&nbsp;&nbsp;</td><td nowrap="nowrap">{@code --typeOther}</td><td>&nbsp;</td><td>Consider only files that are neither of directory (d), 
021                        regular file (f) or symlink (l).</td></tr>
022 * <tr valign="top"><td width="10px"></td><td nowrap="nowrap">{@code -r}</td><td>&nbsp;&nbsp;</td><td nowrap="nowrap">{@code --regex}</td><td>&nbsp;</td><td>Use full regular expression syntax for the patterns specified by the
023                        name operand
024<p>
025                        (This option is ignored if no name operand is specified).</td></tr>
026 * <tr valign="top"><td width="10px"></td><td nowrap="nowrap">{@code -i}</td><td>&nbsp;&nbsp;</td><td nowrap="nowrap">{@code --ignoreCase}</td><td>&nbsp;</td><td>Use case insensitive matching when applying the file name pattern
027                        specified by the name operand
028<p>
029                        (This option is ignored if no name operand is specified).</td></tr>
030 * <tr valign="top"><td width="10px"></td><td nowrap="nowrap">{@code -n}</td><td>&nbsp;&nbsp;</td><td nowrap="nowrap">{@code --timeNewer}</td><td>&nbsp;</td><td>Consider only files that have been created, modified or accessed
031                        after or at the time specified by the time operand (the default)
032                        <p>
033                        (This option is ignored if no time operand is specified).</td></tr>
034 * <tr valign="top"><td width="10px"></td><td nowrap="nowrap">{@code -o}</td><td>&nbsp;&nbsp;</td><td nowrap="nowrap">{@code --timeOlder}</td><td>&nbsp;</td><td>Consider only files that have been created, modified or accessed
035                        before or at the time specified by the time operand
036                        <p>
037                        (This option is ignored if no time operand is specified).</td></tr>
038 * <tr valign="top"><td width="10px"></td><td nowrap="nowrap">{@code -c}</td><td>&nbsp;&nbsp;</td><td nowrap="nowrap">{@code --timeCreate}</td><td>&nbsp;</td><td>The time operand refers to the creation time of the file
039                        <p>
040                        (This option is ignored if no time operand is specified).</td></tr>
041 * <tr valign="top"><td width="10px"></td><td nowrap="nowrap">{@code -a}</td><td>&nbsp;&nbsp;</td><td nowrap="nowrap">{@code --timeAccess}</td><td>&nbsp;</td><td>The time operand refers to the last access time of the file
042                        <p>
043                        (This option is ignored if no time operand is specified).</td></tr>
044 * <tr valign="top"><td width="10px"></td><td nowrap="nowrap">{@code -m}</td><td>&nbsp;&nbsp;</td><td nowrap="nowrap">{@code --timeModified}</td><td>&nbsp;</td><td>The time operand refers to the last modification time of the file
045                        (the default)
046                        <p>
047                        (This option is ignored if no time operand is specified).</td></tr>
048 * <tr valign="top"><td width="10px"></td><td nowrap="nowrap">{@code -z}</td><td>&nbsp;&nbsp;</td><td nowrap="nowrap">{@code --print0}</td><td>&nbsp;</td><td>Print the full file name on the standard output, followed by a null 
049                        character (instead of the newline character used by default). This
050                        allows file names that contain newlines or other types of white 
051                        space to be correctly interpreted by programs that process the find 
052                        output. This option corresponds to the --delimiter0 option of xargs.</td></tr>
053 * </table>
054 */
055public enum FindOption implements Option, FindOptions {
056        /**
057         * Option <b>{@code --typeDirectory}</b>, <b>{@code -d}</b>: 
058         * Consider only directories
059         */
060        typeDirectory('d'),
061        /**
062         * Option <b>{@code --typeFile}</b>, <b>{@code -f}</b>: 
063         * Consider only regular files
064         */
065        typeFile('f'),
066        /**
067         * Option <b>{@code --typeSymlink}</b>, <b>{@code -l}</b>: 
068         * Consider only symbolic links
069         */
070        typeSymlink('l'),
071        /**
072         * Option <b>{@code --typeOther}</b>, <b>{@code -x}</b>: 
073         * Consider only files that are neither of directory (d), 
074                        regular file (f) or symlink (l).
075         */
076        typeOther('x'),
077        /**
078         * Option <b>{@code --regex}</b>, <b>{@code -r}</b>: 
079         * Use full regular expression syntax for the patterns specified by the
080                        name operand
081<p>
082                        (This option is ignored if no name operand is specified).
083         */
084        regex('r'),
085        /**
086         * Option <b>{@code --ignoreCase}</b>, <b>{@code -i}</b>: 
087         * Use case insensitive matching when applying the file name pattern
088                        specified by the name operand
089<p>
090                        (This option is ignored if no name operand is specified).
091         */
092        ignoreCase('i'),
093        /**
094         * Option <b>{@code --timeNewer}</b>, <b>{@code -n}</b>: 
095         * Consider only files that have been created, modified or accessed
096                        after or at the time specified by the time operand (the default)
097                        <p>
098                        (This option is ignored if no time operand is specified).
099         */
100        timeNewer('n'),
101        /**
102         * Option <b>{@code --timeOlder}</b>, <b>{@code -o}</b>: 
103         * Consider only files that have been created, modified or accessed
104                        before or at the time specified by the time operand
105                        <p>
106                        (This option is ignored if no time operand is specified).
107         */
108        timeOlder('o'),
109        /**
110         * Option <b>{@code --timeCreate}</b>, <b>{@code -c}</b>: 
111         * The time operand refers to the creation time of the file
112                        <p>
113                        (This option is ignored if no time operand is specified).
114         */
115        timeCreate('c'),
116        /**
117         * Option <b>{@code --timeAccess}</b>, <b>{@code -a}</b>: 
118         * The time operand refers to the last access time of the file
119                        <p>
120                        (This option is ignored if no time operand is specified).
121         */
122        timeAccess('a'),
123        /**
124         * Option <b>{@code --timeModified}</b>, <b>{@code -m}</b>: 
125         * The time operand refers to the last modification time of the file
126                        (the default)
127                        <p>
128                        (This option is ignored if no time operand is specified).
129         */
130        timeModified('m'),
131        /**
132         * Option <b>{@code --print0}</b>, <b>{@code -z}</b>: 
133         * Print the full file name on the standard output, followed by a null 
134                        character (instead of the newline character used by default). This
135                        allows file names that contain newlines or other types of white 
136                        space to be correctly interpreted by programs that process the find 
137                        output. This option corresponds to the --delimiter0 option of xargs.
138         */
139        print0('z');
140        
141        private final char acronym;
142        private FindOption(char acronym) {
143                this.acronym = acronym;
144        }
145        @Override
146        public Class<FindOption> optionType() {
147                return FindOption.class;
148        }
149        /**
150         * Returns the option with the given {@code acronym}, or {@code null} if no
151         * such option is found.
152         * 
153         * @param acronym the option {@link #acronym() acronym}
154         * @return      the option with the given {@code acronym} or {@code null} if it
155         *                      is not found
156         */
157        public static FindOption findByAcronym(char acronym) {
158                for (final FindOption opt : values()) {
159                        if (opt.acronym() == acronym) return opt;
160                }
161                return null;
162        }
163        @Override
164        public char acronym() {
165                return acronym;
166        }
167        @Override
168        public boolean isSet(FindOption option) {
169                return equals(option);
170        }
171        /**
172         * Returns a new set with {@code this} active option.
173         * 
174         * @return a new set containing this option
175         */
176        @Override
177        public EnumSet<FindOption> asSet() {
178                return EnumSet.of(this);
179        }
180        
181        /**
182         * Returns an immutable iterator returning o single element: {@code this} 
183         * option.
184         * 
185         * @return an immutable iterator with {@code this} active option.
186         */
187        @Override
188        public Iterator<FindOption> iterator() {
189                return Collections.singleton(this).iterator();
190        }
191        
192        /**
193         * Returns 1 as this is a set with a single element: {@code this} option
194         * 
195         * @return one
196         */
197        @Override
198        public int size() {
199                return 1;
200        }
201
202        /**
203         * Returns true if the {@link Option#acronym() acronym} should be used for
204         * the specified {@code option} in string representations. 
205         * <p>
206         * This method returns always true for all options.
207         *  
208         * @param option
209         *            the option of interest
210         * @return always true indicating that option acronyms should be used in
211         *                      string representations for all options
212         */
213        @Override
214        public boolean useAcronymFor(FindOption option) {
215                return true;
216        }
217}