001/* 002 * Copyright 2016-2017 UnboundID Corp. 003 * All Rights Reserved. 004 */ 005/* 006 * Copyright (C) 2016-2017 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 */ 021package com.unboundid.util; 022 023 024 025import java.io.BufferedReader; 026import java.io.Closeable; 027import java.io.File; 028import java.io.FileReader; 029import java.io.IOException; 030import java.util.concurrent.atomic.AtomicLong; 031 032import com.unboundid.ldap.sdk.Filter; 033import com.unboundid.ldap.sdk.LDAPException; 034import com.unboundid.ldap.sdk.ResultCode; 035 036import 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) 046public 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}