001    /*
002     * Copyright 2009-2013 UnboundID Corp.
003     * All Rights Reserved.
004     */
005    /*
006     * Copyright (C) 2009-2013 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     *   try
050     *   {
051     *     while (true)
052     *     {
053     *       try
054     *       {
055     *         Entry entry = entrySource.nextEntry();
056     *         if (entry == null)
057     *         {
058     *           // There are no more entries to be read.
059     *           break;
060     *         }
061     *         else
062     *           {
063     *           // Do something with the entry here.
064     *         }
065     *       }
066     *       catch (EntrySourceException e)
067     *       {
068     *         // Some kind of problem was encountered (e.g., a malformed entry
069     *         // found in the LDIF file, or an I/O error when trying to read).  See
070     *         // if we can continue reading entries.
071     *         if (! e.mayContinueReading())
072     *         {
073     *           break;
074     *         }
075     *       }
076     *     }
077     *   }
078     *   finally
079     *   {
080     *     entrySource.close();
081     *   }
082     * </PRE>
083     */
084    @ThreadSafety(level=ThreadSafetyLevel.NOT_THREADSAFE)
085    public final class LDIFEntrySource
086           extends EntrySource
087    {
088      // Indicates whether this entry source has been closed.
089      private final AtomicBoolean closed;
090    
091      // The LDIF reader from which entries will be read.
092      private final LDIFReader ldifReader;
093    
094    
095    
096      /**
097       * Creates a new LDAP entry source that will obtain entries from the provided
098       * LDIF reader.
099       *
100       * @param  ldifReader  The LDIF reader from which to read entries.  It must
101       *                     not be {@code null}.
102       */
103      public LDIFEntrySource(final LDIFReader ldifReader)
104      {
105        ensureNotNull(ldifReader);
106    
107        this.ldifReader = ldifReader;
108    
109        closed = new AtomicBoolean(false);
110      }
111    
112    
113    
114      /**
115       * {@inheritDoc}
116       */
117      @Override()
118      public Entry nextEntry()
119             throws EntrySourceException
120      {
121        if (closed.get())
122        {
123          return null;
124        }
125    
126        try
127        {
128          final Entry e = ldifReader.readEntry();
129          if (e == null)
130          {
131            close();
132          }
133    
134          return e;
135        }
136        catch (LDIFException le)
137        {
138          debugException(le);
139          if (le.mayContinueReading())
140          {
141            throw new EntrySourceException(true, le);
142          }
143          else
144          {
145            close();
146            throw new EntrySourceException(false, le);
147          }
148        }
149        catch (Exception e)
150        {
151          debugException(e);
152          close();
153          throw new EntrySourceException(false, e);
154        }
155      }
156    
157    
158    
159      /**
160       * {@inheritDoc}
161       */
162      @Override()
163      public void close()
164      {
165        if (closed.compareAndSet(false, true))
166        {
167          try
168          {
169            ldifReader.close();
170          }
171          catch (Exception e)
172          {
173            debugException(e);
174          }
175        }
176      }
177    }