001 /*
002 * Copyright 2016 UnboundID Corp.
003 * All Rights Reserved.
004 */
005 /*
006 * Copyright (C) 2016 UnboundID Corp.
007 *
008 * This program is free software; you can redistribute it and/or modify
009 * it under the terms of the GNU General Public License (GPLv2 only)
010 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only)
011 * as published by the Free Software Foundation.
012 *
013 * This program is distributed in the hope that it will be useful,
014 * but WITHOUT ANY WARRANTY; without even the implied warranty of
015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
016 * GNU General Public License for more details.
017 *
018 * You should have received a copy of the GNU General Public License
019 * along with this program; if not, see <http://www.gnu.org/licenses>.
020 */
021 package com.unboundid.util;
022
023
024
025 import java.io.BufferedReader;
026 import java.io.Closeable;
027 import java.io.File;
028 import java.io.FileReader;
029 import java.io.IOException;
030 import java.util.concurrent.atomic.AtomicLong;
031
032 import com.unboundid.ldap.sdk.Filter;
033 import com.unboundid.ldap.sdk.LDAPException;
034 import com.unboundid.ldap.sdk.ResultCode;
035
036 import static com.unboundid.util.UtilityMessages.*;
037
038
039
040 /**
041 * This class provides a mechanism for reading LDAP search filters from a file.
042 * The file is expected to have one filter per line. Blank lines and lines
043 * beginning with the octothorpe (#) character will be ignored.
044 */
045 @ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
046 public final class FilterFileReader
047 implements Closeable
048 {
049 // A counter used to keep track of the line number for information read from
050 // the file.
051 private final AtomicLong lineNumberCounter;
052
053 // The reader to use to read the filters.
054 private final BufferedReader reader;
055
056 // The file from which the filters are being read.
057 private final File filterFile;
058
059
060
061 /**
062 * Creates a new filter file reader that will read from the file with the
063 * specified path.
064 *
065 * @param path The path to the file to be read. It must not be {@code null}
066 * and the file must exist.
067 *
068 * @throws IOException If a problem is encountered while opening the file
069 * for reading.
070 */
071 public FilterFileReader(final String path)
072 throws IOException
073 {
074 this(new File(path));
075 }
076
077
078
079 /**
080 * Creates a new filter file reader that will read from the specified file.
081 *
082 * @param filterFile The file to be read. It must not be {@code null} and
083 * the file must exist.
084 *
085 * @throws IOException If a problem is encountered while opening the file
086 * for reading.
087 */
088 public FilterFileReader(final File filterFile)
089 throws IOException
090 {
091 this.filterFile = filterFile;
092
093 reader = new BufferedReader(new FileReader(filterFile));
094 lineNumberCounter = new AtomicLong(0L);
095 }
096
097
098
099 /**
100 * Reads the next filter from the file.
101 *
102 * @return The filter read from the file, or {@code null} if there are no
103 * more filters to be read.
104 *
105 * @throws IOException If a problem is encountered while trying to read from
106 * the file.
107 *
108 * @throws LDAPException If data read from the file can't be parsed as an
109 * LDAP search filter.
110 */
111 public Filter readFilter()
112 throws IOException, LDAPException
113 {
114 while (true)
115 {
116 final long lineNumber;
117 final String line;
118 synchronized (this)
119 {
120 line = reader.readLine();
121 lineNumber = lineNumberCounter.incrementAndGet();
122 }
123
124 if (line == null)
125 {
126 return null;
127 }
128
129 final String filterString = line.trim();
130 if ((filterString.length() == 0) || filterString.startsWith("#"))
131 {
132 continue;
133 }
134
135 try
136 {
137 return Filter.create(filterString);
138 }
139 catch (final LDAPException le)
140 {
141 Debug.debugException(le);
142 throw new LDAPException(ResultCode.FILTER_ERROR,
143 ERR_FILTER_FILE_READER_CANNOT_PARSE_FILTER.get(filterString,
144 lineNumber, filterFile.getAbsolutePath(), le.getMessage()),
145 le);
146 }
147 }
148 }
149
150
151
152 /**
153 * Closes this filter file reader.
154 *
155 * @throws IOException If a problem is encountered while closing the reader.
156 */
157 public void close()
158 throws IOException
159 {
160 reader.close();
161 }
162 }