001    /*
002     * Copyright 2009-2015 UnboundID Corp.
003     * All Rights Reserved.
004     */
005    /*
006     * Copyright (C) 2015 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.ldap.sdk.unboundidds.logs;
022    
023    
024    
025    import java.io.BufferedReader;
026    import java.io.File;
027    import java.io.FileReader;
028    import java.io.IOException;
029    import java.io.Reader;
030    
031    import com.unboundid.util.NotMutable;
032    import com.unboundid.util.ThreadSafety;
033    import com.unboundid.util.ThreadSafetyLevel;
034    
035    import static com.unboundid.ldap.sdk.unboundidds.logs.LogMessages.*;
036    
037    
038    
039    /**
040     * <BLOCKQUOTE>
041     *   <B>NOTE:</B>  This class is part of the Commercial Edition of the UnboundID
042     *   LDAP SDK for Java.  It is not available for use in applications that
043     *   include only the Standard Edition of the LDAP SDK, and is not supported for
044     *   use in conjunction with non-UnboundID products.
045     * </BLOCKQUOTE>
046     * This class provides a mechanism for reading message from a Directory Server
047     * access log.
048     */
049    @NotMutable()
050    @ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
051    public final class AccessLogReader
052    {
053      // The reader used to read the contents of the log file.
054      private final BufferedReader reader;
055    
056    
057    
058      /**
059       * Creates a new access log reader that will read messages from the specified
060       * log file.
061       *
062       * @param  path  The path of the log file to read.
063       *
064       * @throws  IOException  If a problem occurs while opening the file for
065       *                       reading.
066       */
067      public AccessLogReader(final String path)
068             throws IOException
069      {
070        reader = new BufferedReader(new FileReader(path));
071      }
072    
073    
074    
075      /**
076       * Creates a new access log reader that will read messages from the specified
077       * log file.
078       *
079       * @param  file  The log file to read.
080       *
081       * @throws  IOException  If a problem occurs while opening the file for
082       *                       reading.
083       */
084      public AccessLogReader(final File file)
085             throws IOException
086      {
087        reader = new BufferedReader(new FileReader(file));
088      }
089    
090    
091    
092      /**
093       * Creates a new access log reader that will read messages using the provided
094       * {@code Reader} object.
095       *
096       * @param  reader  The reader to use to read log messages.
097       */
098      public AccessLogReader(final Reader reader)
099      {
100        if (reader instanceof BufferedReader)
101        {
102          this.reader = (BufferedReader) reader;
103        }
104        else
105        {
106          this.reader = new BufferedReader(reader);
107        }
108      }
109    
110    
111    
112      /**
113       * Reads the next access log message from the log file.
114       *
115       * @return  The access log message read from the log file, or {@code null} if
116       *          there are no more messages to be read.
117       *
118       * @throws  IOException  If an error occurs while trying to read from the
119       *                       file.
120       *
121       * @throws  LogException  If an error occurs while trying to parse the log
122       *                        message.
123       */
124      public AccessLogMessage read()
125             throws IOException, LogException
126      {
127        while (true)
128        {
129          final String line = reader.readLine();
130          if (line == null)
131          {
132            return null;
133          }
134    
135          if ((line.length() == 0) || (line.charAt(0) == '#'))
136          {
137            continue;
138          }
139    
140          return parse(line);
141        }
142      }
143    
144    
145    
146      /**
147       * Parses the provided string as an access log message.
148       *
149       * @param  s  The string to parse as an access log message.
150       *
151       * @return  The parsed access log message.
152       *
153       * @throws  LogException  If an error occurs while trying to parse the log
154       *                        message.
155       */
156      public static AccessLogMessage parse(final String s)
157             throws LogException
158      {
159        final LogMessage m = new LogMessage(s);
160        if (m.hasUnnamedValue(AccessLogMessageType.CONNECT.getLogIdentifier()))
161        {
162          return new ConnectAccessLogMessage(m);
163        }
164        else if (m.hasUnnamedValue(AccessLogMessageType.DISCONNECT.
165                      getLogIdentifier()))
166        {
167          return new DisconnectAccessLogMessage(m);
168        }
169        else if (m.hasUnnamedValue(AccessLogMessageType.CLIENT_CERTIFICATE.
170                      getLogIdentifier()))
171        {
172          return new ClientCertificateAccessLogMessage(m);
173        }
174        else if (m.hasUnnamedValue(AccessLogMessageType.SECURITY_NEGOTIATION.
175                      getLogIdentifier()))
176        {
177          return new SecurityNegotiationAccessLogMessage(m);
178        }
179        else if (m.hasUnnamedValue(AccessLogMessageType.ENTRY_REBALANCING_REQUEST.
180                      getLogIdentifier()))
181        {
182          return new EntryRebalancingRequestAccessLogMessage(m);
183        }
184        else if (m.hasUnnamedValue(AccessLogMessageType.ENTRY_REBALANCING_RESULT.
185                      getLogIdentifier()))
186        {
187          return new EntryRebalancingResultAccessLogMessage(m);
188        }
189        else if (m.hasUnnamedValue(AccessLogMessageType.REQUEST.
190                      getLogIdentifier()))
191        {
192          if (m.hasUnnamedValue(AccessLogOperationType.ABANDON.
193                   getLogIdentifier()))
194          {
195            return new AbandonRequestAccessLogMessage(m);
196          }
197          else if (m.hasUnnamedValue(AccessLogOperationType.ADD.
198                        getLogIdentifier()))
199          {
200            return new AddRequestAccessLogMessage(m);
201          }
202          else if (m.hasUnnamedValue(AccessLogOperationType.BIND.
203                        getLogIdentifier()))
204          {
205            return new BindRequestAccessLogMessage(m);
206          }
207          else if (m.hasUnnamedValue(AccessLogOperationType.COMPARE.
208                        getLogIdentifier()))
209          {
210            return new CompareRequestAccessLogMessage(m);
211          }
212          else if (m.hasUnnamedValue(AccessLogOperationType.DELETE.
213                        getLogIdentifier()))
214          {
215            return new DeleteRequestAccessLogMessage(m);
216          }
217          else if (m.hasUnnamedValue(AccessLogOperationType.EXTENDED.
218                        getLogIdentifier()))
219          {
220            return new ExtendedRequestAccessLogMessage(m);
221          }
222          else if (m.hasUnnamedValue(AccessLogOperationType.MODIFY.
223                        getLogIdentifier()))
224          {
225            return new ModifyRequestAccessLogMessage(m);
226          }
227          else if (m.hasUnnamedValue(AccessLogOperationType.MODDN.
228                        getLogIdentifier()))
229          {
230            return new ModifyDNRequestAccessLogMessage(m);
231          }
232          else if (m.hasUnnamedValue(AccessLogOperationType.SEARCH.
233                        getLogIdentifier()))
234          {
235            return new SearchRequestAccessLogMessage(m);
236          }
237          else if (m.hasUnnamedValue(AccessLogOperationType.UNBIND.
238                        getLogIdentifier()))
239          {
240            return new UnbindRequestAccessLogMessage(m);
241          }
242          else
243          {
244            throw new LogException(s,
245                 ERR_LOG_MESSAGE_INVALID_REQUEST_OPERATION_TYPE.get());
246          }
247        }
248        else if (m.hasUnnamedValue(AccessLogMessageType.RESULT.
249                      getLogIdentifier()))
250        {
251          if (m.hasUnnamedValue(AccessLogOperationType.ABANDON.
252                   getLogIdentifier()))
253          {
254            return new AbandonResultAccessLogMessage(m);
255          }
256          else if (m.hasUnnamedValue(AccessLogOperationType.ADD.
257                        getLogIdentifier()))
258          {
259            return new AddResultAccessLogMessage(m);
260          }
261          else if (m.hasUnnamedValue(AccessLogOperationType.BIND.
262                        getLogIdentifier()))
263          {
264            return new BindResultAccessLogMessage(m);
265          }
266          else if (m.hasUnnamedValue(AccessLogOperationType.COMPARE.
267                        getLogIdentifier()))
268          {
269            return new CompareResultAccessLogMessage(m);
270          }
271          else if (m.hasUnnamedValue(AccessLogOperationType.DELETE.
272                        getLogIdentifier()))
273          {
274            return new DeleteResultAccessLogMessage(m);
275          }
276          else if (m.hasUnnamedValue(AccessLogOperationType.EXTENDED.
277                        getLogIdentifier()))
278          {
279            return new ExtendedResultAccessLogMessage(m);
280          }
281          else if (m.hasUnnamedValue(AccessLogOperationType.MODIFY.
282                        getLogIdentifier()))
283          {
284            return new ModifyResultAccessLogMessage(m);
285          }
286          else if (m.hasUnnamedValue(AccessLogOperationType.MODDN.
287                        getLogIdentifier()))
288          {
289            return new ModifyDNResultAccessLogMessage(m);
290          }
291          else if (m.hasUnnamedValue(AccessLogOperationType.SEARCH.
292                        getLogIdentifier()))
293          {
294            return new SearchResultAccessLogMessage(m);
295          }
296          else
297          {
298            throw new LogException(s,
299                 ERR_LOG_MESSAGE_INVALID_RESULT_OPERATION_TYPE.get());
300          }
301        }
302        else if (m.hasUnnamedValue(AccessLogMessageType.FORWARD.
303                      getLogIdentifier()))
304        {
305          if (m.hasUnnamedValue(AccessLogOperationType.ABANDON.
306                   getLogIdentifier()))
307          {
308            return new AbandonForwardAccessLogMessage(m);
309          }
310          else if (m.hasUnnamedValue(AccessLogOperationType.ADD.
311                        getLogIdentifier()))
312          {
313            return new AddForwardAccessLogMessage(m);
314          }
315          else if (m.hasUnnamedValue(AccessLogOperationType.BIND.
316                        getLogIdentifier()))
317          {
318            return new BindForwardAccessLogMessage(m);
319          }
320          else if (m.hasUnnamedValue(AccessLogOperationType.COMPARE.
321                        getLogIdentifier()))
322          {
323            return new CompareForwardAccessLogMessage(m);
324          }
325          else if (m.hasUnnamedValue(AccessLogOperationType.DELETE.
326                        getLogIdentifier()))
327          {
328            return new DeleteForwardAccessLogMessage(m);
329          }
330          else if (m.hasUnnamedValue(AccessLogOperationType.EXTENDED.
331                        getLogIdentifier()))
332          {
333            return new ExtendedForwardAccessLogMessage(m);
334          }
335          else if (m.hasUnnamedValue(AccessLogOperationType.MODIFY.
336                        getLogIdentifier()))
337          {
338            return new ModifyForwardAccessLogMessage(m);
339          }
340          else if (m.hasUnnamedValue(AccessLogOperationType.MODDN.
341                        getLogIdentifier()))
342          {
343            return new ModifyDNForwardAccessLogMessage(m);
344          }
345          else if (m.hasUnnamedValue(AccessLogOperationType.SEARCH.
346                        getLogIdentifier()))
347          {
348            return new SearchForwardAccessLogMessage(m);
349          }
350          else
351          {
352            throw new LogException(s,
353                 ERR_LOG_MESSAGE_INVALID_FORWARD_OPERATION_TYPE.get());
354          }
355        }
356        else if (m.hasUnnamedValue(AccessLogMessageType.FORWARD_FAILED.
357                      getLogIdentifier()))
358        {
359          if (m.hasUnnamedValue(AccessLogOperationType.ADD.getLogIdentifier()))
360          {
361            return new AddForwardFailedAccessLogMessage(m);
362          }
363          else if (m.hasUnnamedValue(AccessLogOperationType.BIND.
364                        getLogIdentifier()))
365          {
366            return new BindForwardFailedAccessLogMessage(m);
367          }
368          else if (m.hasUnnamedValue(AccessLogOperationType.COMPARE.
369                        getLogIdentifier()))
370          {
371            return new CompareForwardFailedAccessLogMessage(m);
372          }
373          else if (m.hasUnnamedValue(AccessLogOperationType.DELETE.
374                        getLogIdentifier()))
375          {
376            return new DeleteForwardFailedAccessLogMessage(m);
377          }
378          else if (m.hasUnnamedValue(AccessLogOperationType.EXTENDED.
379                        getLogIdentifier()))
380          {
381            return new ExtendedForwardFailedAccessLogMessage(m);
382          }
383          else if (m.hasUnnamedValue(AccessLogOperationType.MODIFY.
384                        getLogIdentifier()))
385          {
386            return new ModifyForwardFailedAccessLogMessage(m);
387          }
388          else if (m.hasUnnamedValue(AccessLogOperationType.MODDN.
389                        getLogIdentifier()))
390          {
391            return new ModifyDNForwardFailedAccessLogMessage(m);
392          }
393          else if (m.hasUnnamedValue(AccessLogOperationType.SEARCH.
394                        getLogIdentifier()))
395          {
396            return new SearchForwardFailedAccessLogMessage(m);
397          }
398          else
399          {
400            throw new LogException(s,
401                 ERR_LOG_MESSAGE_INVALID_FORWARD_FAILED_OPERATION_TYPE.get());
402          }
403        }
404        else if (m.hasUnnamedValue(AccessLogMessageType.ASSURANCE_COMPLETE.
405                      getLogIdentifier()))
406        {
407          if (m.hasUnnamedValue(AccessLogOperationType.ADD.getLogIdentifier()))
408          {
409            return new AddAssuranceCompletedAccessLogMessage(m);
410          }
411          else if (m.hasUnnamedValue(AccessLogOperationType.DELETE.
412                        getLogIdentifier()))
413          {
414            return new DeleteAssuranceCompletedAccessLogMessage(m);
415          }
416          else if (m.hasUnnamedValue(AccessLogOperationType.MODIFY.
417                        getLogIdentifier()))
418          {
419            return new ModifyAssuranceCompletedAccessLogMessage(m);
420          }
421          else if (m.hasUnnamedValue(AccessLogOperationType.MODDN.
422                        getLogIdentifier()))
423          {
424            return new ModifyDNAssuranceCompletedAccessLogMessage(m);
425          }
426          else
427          {
428            throw new LogException(s,
429                 ERR_LOG_MESSAGE_INVALID_ASSURANCE_COMPLETE_OPERATION_TYPE.get());
430          }
431        }
432        else if (m.hasUnnamedValue(AccessLogMessageType.ENTRY.getLogIdentifier()))
433        {
434          return new SearchEntryAccessLogMessage(m);
435        }
436        else if (m.hasUnnamedValue(AccessLogMessageType.REFERENCE.
437                      getLogIdentifier()))
438        {
439          return new SearchReferenceAccessLogMessage(m);
440        }
441        else if (m.hasUnnamedValue(AccessLogMessageType.INTERMEDIATE_RESPONSE.
442                      getLogIdentifier()))
443        {
444          return new IntermediateResponseAccessLogMessage(m);
445        }
446        else
447        {
448          throw new LogException(s,
449               ERR_LOG_MESSAGE_INVALID_ACCESS_MESSAGE_TYPE.get());
450        }
451      }
452    
453    
454    
455      /**
456       * Closes this error log reader.
457       *
458       * @throws  IOException  If a problem occurs while closing the reader.
459       */
460      public void close()
461             throws IOException
462      {
463        reader.close();
464      }
465    }