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