001    /*
002     * Copyright 2007-2016 UnboundID Corp.
003     * All Rights Reserved.
004     */
005    /*
006     * Copyright (C) 2008-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.ArrayList;
026    import java.util.Arrays;
027    import java.util.Collections;
028    import java.util.List;
029    
030    import com.unboundid.util.LDAPSDKException;
031    import com.unboundid.util.StaticUtils;
032    
033    import static com.unboundid.util.Validator.*;
034    
035    
036    
037    /**
038     * This class defines an exception that may be thrown if a problem occurs while
039     * attempting to decode data read from an LDIF source.  It has a flag to
040     * indicate whether it is possible to try to continue reading additional
041     * information from the LDIF source, and also the approximate line number on
042     * which the problem was encountered.
043     */
044    public final class LDIFException
045           extends LDAPSDKException
046    {
047      /**
048       * The serial version UID for this serializable class.
049       */
050      private static final long serialVersionUID = 1665883395956836732L;
051    
052    
053    
054      // Indicates whether it is possible to continue attempting to read from the
055      // LDIF source.
056      private final boolean mayContinueReading;
057    
058      // The line number in the LDIF source on which the problem occurred.
059      private final long lineNumber;
060    
061      // A list of the lines comprising the LDIF data being parsed, if available.
062      private final List<String> dataLines;
063    
064    
065    
066      /**
067       * Creates a new LDIF exception with the provided information.
068       *
069       * @param  message             A message explaining the problem that occurred.
070       *                             It must not be {@code null}.
071       * @param  lineNumber          The line number in the LDIF source on which the
072       *                             problem occurred.
073       * @param  mayContinueReading  Indicates whether it is possible to continue
074       *                             attempting to read from the LDIF source.
075       */
076      public LDIFException(final String message, final long lineNumber,
077                           final boolean mayContinueReading)
078      {
079        this(message, lineNumber, mayContinueReading, (List<CharSequence>) null,
080             null);
081      }
082    
083    
084    
085      /**
086       * Creates a new LDIF exception with the provided information.
087       *
088       * @param  message             A message explaining the problem that occurred.
089       *                             It must not be {@code null}.
090       * @param  lineNumber          The line number in the LDIF source on which the
091       *                             problem occurred.
092       * @param  mayContinueReading  Indicates whether it is possible to continue
093       *                             attempting to read from the LDIF source.
094       * @param  cause               The underlying exception that triggered this
095       *                             exception.
096       */
097      public LDIFException(final String message, final long lineNumber,
098                           final boolean mayContinueReading, final Throwable cause)
099      {
100        this(message, lineNumber, mayContinueReading, (List<CharSequence>) null,
101             cause);
102      }
103    
104    
105    
106      /**
107       * Creates a new LDIF exception with the provided information.
108       *
109       * @param  message             A message explaining the problem that occurred.
110       *                             It must not be {@code null}.
111       * @param  lineNumber          The line number in the LDIF source on which the
112       *                             problem occurred.
113       * @param  mayContinueReading  Indicates whether it is possible to continue
114       *                             attempting to read from the LDIF source.
115       * @param  dataLines           The lines that comprise the data that could not
116       *                             be parsed as valid LDIF.  It may be
117       *                             {@code null} if this is not available.
118       * @param  cause               The underlying exception that triggered this
119       *                             exception.
120       */
121      public LDIFException(final String message, final long lineNumber,
122                           final boolean mayContinueReading,
123                           final CharSequence[] dataLines, final Throwable cause)
124      {
125        this(message, lineNumber, mayContinueReading,
126             (dataLines == null) ? null : Arrays.asList(dataLines),
127             cause);
128      }
129    
130    
131    
132      /**
133       * Creates a new LDIF exception with the provided information.
134       *
135       * @param  message             A message explaining the problem that occurred.
136       *                             It must not be {@code null}.
137       * @param  lineNumber          The line number in the LDIF source on which the
138       *                             problem occurred.
139       * @param  mayContinueReading  Indicates whether it is possible to continue
140       *                             attempting to read from the LDIF source.
141       * @param  dataLines           The lines that comprise the data that could not
142       *                             be parsed as valid LDIF.  It may be
143       *                             {@code null} if this is not available.
144       * @param  cause               The underlying exception that triggered this
145       *                             exception.
146       */
147      public LDIFException(final String message, final long lineNumber,
148                           final boolean mayContinueReading,
149                           final List<? extends CharSequence> dataLines,
150                           final Throwable cause)
151      {
152        super(message, cause);
153    
154        ensureNotNull(message);
155    
156        this.lineNumber         = lineNumber;
157        this.mayContinueReading = mayContinueReading;
158    
159        if (dataLines == null)
160        {
161          this.dataLines = null;
162        }
163        else
164        {
165          final ArrayList<String> lineList =
166               new ArrayList<String>(dataLines.size());
167          for (final CharSequence s : dataLines)
168          {
169            lineList.add(s.toString());
170          }
171    
172          this.dataLines = Collections.unmodifiableList(lineList);
173        }
174      }
175    
176    
177    
178      /**
179       * Retrieves the line number on which the problem occurred.
180       *
181       * @return  The line number on which the problem occurred.
182       */
183      public long getLineNumber()
184      {
185        return lineNumber;
186      }
187    
188    
189    
190      /**
191       * Indicates whether it is possible to continue attempting to read from the
192       * LDIF source.
193       *
194       * @return  {@code true} if it is possible to continue attempting to read from
195       *          the LDIF source, or {@code false} if it is not possible to
196       *          continue.
197       */
198      public boolean mayContinueReading()
199      {
200        return mayContinueReading;
201      }
202    
203    
204    
205      /**
206       * Retrieves the lines comprising the data that could not be parsed as valid
207       * LDIF, if available.
208       *
209       * @return  An unmodifiable list of the lines comprising the data that could
210       *          not be parsed as valid LDIF, or {@code null} if that is not
211       *          available.
212       */
213      public List<String> getDataLines()
214      {
215        return dataLines;
216      }
217    
218    
219    
220      /**
221       * {@inheritDoc}
222       */
223      @Override()
224      public void toString(final StringBuilder buffer)
225      {
226        buffer.append("LDIFException(lineNumber=");
227        buffer.append(lineNumber);
228        buffer.append(", mayContinueReading=");
229        buffer.append(mayContinueReading);
230        buffer.append(", message='");
231        buffer.append(getMessage());
232    
233        if (dataLines != null)
234        {
235          buffer.append("', dataLines='");
236          for (final CharSequence s : dataLines)
237          {
238            buffer.append(s);
239            buffer.append("{end-of-line}");
240          }
241        }
242    
243        final Throwable cause = getCause();
244        if (cause == null)
245        {
246          buffer.append("')");
247        }
248        else
249        {
250          buffer.append("', cause=");
251          StaticUtils.getStackTrace(cause, buffer);
252          buffer.append(')');
253        }
254      }
255    
256    
257    
258      /**
259       * {@inheritDoc}
260       */
261      @Override()
262      public String getExceptionMessage()
263      {
264        return toString();
265      }
266    }