001    /*
002     * Copyright 2009-2016 UnboundID Corp.
003     * All Rights Reserved.
004     */
005    /*
006     * Copyright (C) 2009-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.ldif;
022    
023    
024    
025    import java.util.concurrent.atomic.AtomicBoolean;
026    
027    import com.unboundid.ldap.sdk.Entry;
028    import com.unboundid.ldap.sdk.EntrySource;
029    import com.unboundid.ldap.sdk.EntrySourceException;
030    import com.unboundid.util.ThreadSafety;
031    import com.unboundid.util.ThreadSafetyLevel;
032    
033    import static com.unboundid.util.Debug.*;
034    import static com.unboundid.util.Validator.*;
035    
036    
037    
038    /**
039     * This class provides an {@link EntrySource} that will read entries from an
040     * LDIF file.
041     * <BR><BR>
042     * <H2>Example</H2>
043     * The following example demonstrates the process that may be used for iterating
044     * through all entries in an LDIF file using the entry source API:
045     * <PRE>
046     * LDIFEntrySource entrySource =
047     *      new LDIFEntrySource(new LDIFReader(pathToLDIFFile));
048     *
049     * int entriesRead = 0;
050     * int errorsEncountered = 0;
051     * try
052     * {
053     *   while (true)
054     *   {
055     *     try
056     *     {
057     *       Entry entry = entrySource.nextEntry();
058     *       if (entry == null)
059     *       {
060     *         // There are no more entries to be read.
061     *         break;
062     *       }
063     *       else
064     *       {
065     *         // Do something with the entry here.
066     *         entriesRead++;
067     *       }
068     *     }
069     *     catch (EntrySourceException e)
070     *     {
071     *       // Some kind of problem was encountered (e.g., a malformed entry
072     *       // found in the LDIF file, or an I/O error when trying to read).  See
073     *       // if we can continue reading entries.
074     *       errorsEncountered++;
075     *       if (! e.mayContinueReading())
076     *       {
077     *         break;
078     *       }
079     *     }
080     *   }
081     * }
082     * finally
083     * {
084     *   entrySource.close();
085     * }
086     * </PRE>
087     */
088    @ThreadSafety(level=ThreadSafetyLevel.NOT_THREADSAFE)
089    public final class LDIFEntrySource
090           extends EntrySource
091    {
092      // Indicates whether this entry source has been closed.
093      private final AtomicBoolean closed;
094    
095      // The LDIF reader from which entries will be read.
096      private final LDIFReader ldifReader;
097    
098    
099    
100      /**
101       * Creates a new LDAP entry source that will obtain entries from the provided
102       * LDIF reader.
103       *
104       * @param  ldifReader  The LDIF reader from which to read entries.  It must
105       *                     not be {@code null}.
106       */
107      public LDIFEntrySource(final LDIFReader ldifReader)
108      {
109        ensureNotNull(ldifReader);
110    
111        this.ldifReader = ldifReader;
112    
113        closed = new AtomicBoolean(false);
114      }
115    
116    
117    
118      /**
119       * {@inheritDoc}
120       */
121      @Override()
122      public Entry nextEntry()
123             throws EntrySourceException
124      {
125        if (closed.get())
126        {
127          return null;
128        }
129    
130        try
131        {
132          final Entry e = ldifReader.readEntry();
133          if (e == null)
134          {
135            close();
136          }
137    
138          return e;
139        }
140        catch (LDIFException le)
141        {
142          debugException(le);
143          if (le.mayContinueReading())
144          {
145            throw new EntrySourceException(true, le);
146          }
147          else
148          {
149            close();
150            throw new EntrySourceException(false, le);
151          }
152        }
153        catch (Exception e)
154        {
155          debugException(e);
156          close();
157          throw new EntrySourceException(false, e);
158        }
159      }
160    
161    
162    
163      /**
164       * {@inheritDoc}
165       */
166      @Override()
167      public void close()
168      {
169        if (closed.compareAndSet(false, true))
170        {
171          try
172          {
173            ldifReader.close();
174          }
175          catch (Exception e)
176          {
177            debugException(e);
178          }
179        }
180      }
181    }