From 263d085885df024dca9250cc03c807912b0a7662 Mon Sep 17 00:00:00 2001
From: Matthew Swift <matthew.swift@forgerock.com>
Date: Tue, 24 Apr 2012 22:33:21 +0000
Subject: [PATCH] Reformat to comply with new Checkstyle rules.
---
opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldif/AbstractLDIFReader.java | 1445 ++++++++++++++++++++++++---------------------------------
1 files changed, 612 insertions(+), 833 deletions(-)
diff --git a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldif/AbstractLDIFReader.java b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldif/AbstractLDIFReader.java
index 36e2270..27c4178 100644
--- a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldif/AbstractLDIFReader.java
+++ b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldif/AbstractLDIFReader.java
@@ -6,17 +6,16 @@
* (the "License"). You may not use this file except in compliance
* with the License.
*
- * You can obtain a copy of the license at
- * trunk/opendj3/legal-notices/CDDLv1_0.txt
+ * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
* or http://forgerock.org/license/CDDLv1.0.html.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at
- * trunk/opendj3/legal-notices/CDDLv1_0.txt. If applicable,
- * add the following below this CDDL HEADER, with the fields enclosed
- * by brackets "[]" replaced with your own identifying information:
+ * file and include the License file at legal-notices/CDDLv1_0.txt.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information:
* Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
@@ -28,8 +27,6 @@
package org.forgerock.opendj.ldif;
-
-
import static com.forgerock.opendj.util.StaticUtils.toLowerCase;
import static org.forgerock.opendj.ldap.CoreMessages.*;
@@ -45,7 +42,14 @@
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.i18n.LocalizableMessageBuilder;
import org.forgerock.i18n.LocalizedIllegalArgumentException;
-import org.forgerock.opendj.ldap.*;
+import org.forgerock.opendj.ldap.Attribute;
+import org.forgerock.opendj.ldap.AttributeDescription;
+import org.forgerock.opendj.ldap.ByteString;
+import org.forgerock.opendj.ldap.ByteStringBuilder;
+import org.forgerock.opendj.ldap.DN;
+import org.forgerock.opendj.ldap.DecodeException;
+import org.forgerock.opendj.ldap.Entry;
+import org.forgerock.opendj.ldap.LinkedAttribute;
import org.forgerock.opendj.ldap.schema.Schema;
import org.forgerock.opendj.ldap.schema.SchemaValidationPolicy;
import org.forgerock.opendj.ldap.schema.Syntax;
@@ -54,893 +58,668 @@
import com.forgerock.opendj.util.Base64;
import com.forgerock.opendj.util.Validator;
-
-
/**
* Common LDIF reader functionality.
*/
-abstract class AbstractLDIFReader extends AbstractLDIFStream
-{
- static final class KeyValuePair
- {
- String key;
+abstract class AbstractLDIFReader extends AbstractLDIFStream {
+ static final class KeyValuePair {
+ String key;
- String value;
- }
-
-
-
- /**
- * LDIF reader implementation interface.
- */
- interface LDIFReaderImpl
- {
-
- /**
- * Closes any resources associated with this LDIF reader implementation.
- *
- * @throws IOException
- * If an error occurs while closing.
- */
- void close() throws IOException;
-
-
-
- /**
- * Reads the next line of LDIF from the underlying LDIF source.
- * Implementations must remove trailing line delimiters.
- *
- * @return The next line of LDIF, or {@code null} if the end of the LDIF
- * source has been reached.
- * @throws IOException
- * If an error occurs while reading from the LDIF source.
- */
- String readLine() throws IOException;
- }
-
-
-
- static final class LDIFRecord
- {
- final Iterator<String> iterator;
-
- final LinkedList<String> ldifLines;
-
- final long lineNumber;
-
-
-
- private LDIFRecord(final long lineNumber, final LinkedList<String> ldifLines)
- {
- this.lineNumber = lineNumber;
- this.ldifLines = ldifLines;
- this.iterator = ldifLines.iterator();
+ String value;
}
- }
-
-
-
- /**
- * LDIF output stream writer implementation.
- */
- private static final class LDIFReaderInputStreamImpl implements
- LDIFReaderImpl
- {
-
- private BufferedReader reader;
-
-
/**
- * Creates a new LDIF input stream reader implementation.
+ * LDIF reader implementation interface.
+ */
+ interface LDIFReaderImpl {
+
+ /**
+ * Closes any resources associated with this LDIF reader implementation.
+ *
+ * @throws IOException
+ * If an error occurs while closing.
+ */
+ void close() throws IOException;
+
+ /**
+ * Reads the next line of LDIF from the underlying LDIF source.
+ * Implementations must remove trailing line delimiters.
+ *
+ * @return The next line of LDIF, or {@code null} if the end of the LDIF
+ * source has been reached.
+ * @throws IOException
+ * If an error occurs while reading from the LDIF source.
+ */
+ String readLine() throws IOException;
+ }
+
+ static final class LDIFRecord {
+ final Iterator<String> iterator;
+
+ final LinkedList<String> ldifLines;
+
+ final long lineNumber;
+
+ private LDIFRecord(final long lineNumber, final LinkedList<String> ldifLines) {
+ this.lineNumber = lineNumber;
+ this.ldifLines = ldifLines;
+ this.iterator = ldifLines.iterator();
+ }
+ }
+
+ /**
+ * LDIF output stream writer implementation.
+ */
+ private static final class LDIFReaderInputStreamImpl implements LDIFReaderImpl {
+
+ private BufferedReader reader;
+
+ /**
+ * Creates a new LDIF input stream reader implementation.
+ *
+ * @param in
+ * The input stream to use.
+ */
+ LDIFReaderInputStreamImpl(final InputStream in) {
+ this.reader = new BufferedReader(new InputStreamReader(in));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void close() throws IOException {
+ if (reader != null) {
+ reader.close();
+ reader = null;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String readLine() throws IOException {
+ String line = null;
+ if (reader != null) {
+ line = reader.readLine();
+ if (line == null) {
+ // Automatically close.
+ close();
+ }
+ }
+ return line;
+ }
+ }
+
+ /**
+ * LDIF output stream writer implementation.
+ */
+ private static final class LDIFReaderListImpl implements LDIFReaderImpl {
+
+ private final Iterator<String> iterator;
+
+ /**
+ * Creates a new LDIF list reader.
+ *
+ * @param ldifLines
+ * The string list.
+ */
+ LDIFReaderListImpl(final List<String> ldifLines) {
+ this.iterator = ldifLines.iterator();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void close() throws IOException {
+ // Nothing to do.
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String readLine() throws IOException {
+ if (iterator.hasNext()) {
+ return iterator.next();
+ } else {
+ return null;
+ }
+ }
+ }
+
+ RejectedLDIFListener rejectedRecordListener = RejectedLDIFListener.FAIL_FAST;
+
+ Schema schema = Schema.getDefaultSchema().asNonStrictSchema();
+
+ SchemaValidationPolicy schemaValidationPolicy = SchemaValidationPolicy.ignoreAll();
+
+ private final LDIFReaderImpl impl;
+
+ private long lineNumber = 0;
+
+ /**
+ * Creates a new LDIF entry reader whose source is the provided input
+ * stream.
*
* @param in
- * The input stream to use.
+ * The input stream to use.
*/
- LDIFReaderInputStreamImpl(final InputStream in)
- {
- this.reader = new BufferedReader(new InputStreamReader(in));
+ AbstractLDIFReader(final InputStream in) {
+ Validator.ensureNotNull(in);
+ this.impl = new LDIFReaderInputStreamImpl(in);
}
-
-
/**
- * {@inheritDoc}
- */
- public void close() throws IOException
- {
- if (reader != null)
- {
- reader.close();
- reader = null;
- }
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- public String readLine() throws IOException
- {
- String line = null;
- if (reader != null)
- {
- line = reader.readLine();
- if (line == null)
- {
- // Automatically close.
- close();
- }
- }
- return line;
- }
- }
-
-
-
- /**
- * LDIF output stream writer implementation.
- */
- private static final class LDIFReaderListImpl implements LDIFReaderImpl
- {
-
- private final Iterator<String> iterator;
-
-
-
- /**
- * Creates a new LDIF list reader.
+ * Creates a new LDIF entry reader which will read lines of LDIF from the
+ * provided list.
*
* @param ldifLines
- * The string list.
+ * The list from which lines of LDIF should be read.
*/
- LDIFReaderListImpl(final List<String> ldifLines)
- {
- this.iterator = ldifLines.iterator();
+ AbstractLDIFReader(final List<String> ldifLines) {
+ Validator.ensureNotNull(ldifLines);
+ this.impl = new LDIFReaderListImpl(ldifLines);
}
-
-
- /**
- * {@inheritDoc}
- */
- public void close() throws IOException
- {
- // Nothing to do.
+ final void close0() throws IOException {
+ impl.close();
}
-
-
- /**
- * {@inheritDoc}
- */
- public String readLine() throws IOException
- {
- if (iterator.hasNext())
- {
- return iterator.next();
- }
- else
- {
- return null;
- }
+ final int parseColonPosition(final LDIFRecord record, final String ldifLine)
+ throws DecodeException {
+ final int colonPos = ldifLine.indexOf(":");
+ if (colonPos <= 0) {
+ final LocalizableMessage message =
+ ERR_LDIF_NO_ATTR_NAME.get(record.lineNumber, ldifLine);
+ throw DecodeException.error(message);
+ }
+ return colonPos;
}
- }
+ final ByteString parseSingleValue(final LDIFRecord record, final String ldifLine,
+ final DN entryDN, final int colonPos, final String attrName) throws DecodeException {
+ // Look at the character immediately after the colon. If there is
+ // none, then assume an attribute with an empty value. If it is
+ // another colon, then the value must be base64-encoded. If it is a
+ // less-than sign, then assume that it is a URL. Otherwise, it is a
+ // regular value.
+ final int length = ldifLine.length();
+ ByteString value;
+ if (colonPos == length - 1) {
+ value = ByteString.empty();
+ } else {
+ final char c = ldifLine.charAt(colonPos + 1);
+ if (c == ':') {
+ // The value is base64-encoded. Find the first non-blank
+ // character, take the rest of the line, and base64-decode it.
+ int pos = colonPos + 2;
+ while (pos < length && ldifLine.charAt(pos) == ' ') {
+ pos++;
+ }
- RejectedLDIFListener rejectedRecordListener = RejectedLDIFListener.FAIL_FAST;
+ try {
+ value = Base64.decode(ldifLine.substring(pos));
+ } catch (final LocalizedIllegalArgumentException e) {
+ // The value did not have a valid base64-encoding.
+ final LocalizableMessage message =
+ ERR_LDIF_COULD_NOT_BASE64_DECODE_ATTR.get(entryDN.toString(),
+ record.lineNumber, ldifLine, e.getMessageObject());
+ throw DecodeException.error(message);
+ }
+ } else if (c == '<') {
+ // Find the first non-blank character, decode the rest of the
+ // line as a URL, and read its contents.
+ int pos = colonPos + 2;
+ while (pos < length && ldifLine.charAt(pos) == ' ') {
+ pos++;
+ }
- Schema schema = Schema.getDefaultSchema().asNonStrictSchema();
+ URL contentURL;
+ try {
+ contentURL = new URL(ldifLine.substring(pos));
+ } catch (final Exception e) {
+ // The URL was malformed or had an invalid protocol.
+ final LocalizableMessage message =
+ ERR_LDIF_INVALID_URL.get(entryDN.toString(), record.lineNumber,
+ attrName, String.valueOf(e));
+ throw DecodeException.error(message);
+ }
- SchemaValidationPolicy schemaValidationPolicy = SchemaValidationPolicy.ignoreAll();
+ InputStream inputStream = null;
+ ByteStringBuilder builder = null;
+ try {
+ builder = new ByteStringBuilder();
+ inputStream = contentURL.openConnection().getInputStream();
- private final LDIFReaderImpl impl;
+ int bytesRead;
+ final byte[] buffer = new byte[4096];
+ while ((bytesRead = inputStream.read(buffer)) > 0) {
+ builder.append(buffer, 0, bytesRead);
+ }
- private long lineNumber = 0;
+ value = builder.toByteString();
+ } catch (final Exception e) {
+ // We were unable to read the contents of that URL for some
+ // reason.
+ final LocalizableMessage message =
+ ERR_LDIF_URL_IO_ERROR.get(entryDN.toString(), record.lineNumber,
+ attrName, String.valueOf(contentURL), String.valueOf(e));
+ throw DecodeException.error(message);
+ } finally {
+ if (inputStream != null) {
+ try {
+ inputStream.close();
+ } catch (final Exception e) {
+ // Ignore.
+ }
+ }
+ }
+ } else {
+ // The rest of the line should be the value. Skip over any
+ // spaces and take the rest of the line as the value.
+ int pos = colonPos + 1;
+ while (pos < length && ldifLine.charAt(pos) == ' ') {
+ pos++;
+ }
-
-
- /**
- * Creates a new LDIF entry reader whose source is the provided input stream.
- *
- * @param in
- * The input stream to use.
- */
- AbstractLDIFReader(final InputStream in)
- {
- Validator.ensureNotNull(in);
- this.impl = new LDIFReaderInputStreamImpl(in);
- }
-
-
-
- /**
- * Creates a new LDIF entry reader which will read lines of LDIF from the
- * provided list.
- *
- * @param ldifLines
- * The list from which lines of LDIF should be read.
- */
- AbstractLDIFReader(final List<String> ldifLines)
- {
- Validator.ensureNotNull(ldifLines);
- this.impl = new LDIFReaderListImpl(ldifLines);
- }
-
-
-
- final void close0() throws IOException
- {
- impl.close();
- }
-
-
-
- final int parseColonPosition(final LDIFRecord record, final String ldifLine)
- throws DecodeException
- {
- final int colonPos = ldifLine.indexOf(":");
- if (colonPos <= 0)
- {
- final LocalizableMessage message = ERR_LDIF_NO_ATTR_NAME.get(
- record.lineNumber, ldifLine);
- throw DecodeException.error(message);
- }
- return colonPos;
- }
-
-
-
- final ByteString parseSingleValue(final LDIFRecord record,
- final String ldifLine, final DN entryDN, final int colonPos,
- final String attrName) throws DecodeException
- {
-
- // Look at the character immediately after the colon. If there is
- // none, then assume an attribute with an empty value. If it is
- // another colon, then the value must be base64-encoded. If it is a
- // less-than sign, then assume that it is a URL. Otherwise, it is a
- // regular value.
- final int length = ldifLine.length();
- ByteString value;
- if (colonPos == length - 1)
- {
- value = ByteString.empty();
- }
- else
- {
- final char c = ldifLine.charAt(colonPos + 1);
- if (c == ':')
- {
- // The value is base64-encoded. Find the first non-blank
- // character, take the rest of the line, and base64-decode it.
- int pos = colonPos + 2;
- while (pos < length && ldifLine.charAt(pos) == ' ')
- {
- pos++;
- }
-
- try
- {
- value = Base64.decode(ldifLine.substring(pos));
- }
- catch (final LocalizedIllegalArgumentException e)
- {
- // The value did not have a valid base64-encoding.
- final LocalizableMessage message = ERR_LDIF_COULD_NOT_BASE64_DECODE_ATTR
- .get(entryDN.toString(), record.lineNumber, ldifLine,
- e.getMessageObject());
- throw DecodeException.error(message);
- }
- }
- else if (c == '<')
- {
- // Find the first non-blank character, decode the rest of the
- // line as a URL, and read its contents.
- int pos = colonPos + 2;
- while (pos < length && ldifLine.charAt(pos) == ' ')
- {
- pos++;
- }
-
- URL contentURL;
- try
- {
- contentURL = new URL(ldifLine.substring(pos));
- }
- catch (final Exception e)
- {
- // The URL was malformed or had an invalid protocol.
- final LocalizableMessage message = ERR_LDIF_INVALID_URL.get(
- entryDN.toString(), record.lineNumber, attrName,
- String.valueOf(e));
- throw DecodeException.error(message);
- }
-
- InputStream inputStream = null;
- ByteStringBuilder builder = null;
- try
- {
- builder = new ByteStringBuilder();
- inputStream = contentURL.openConnection().getInputStream();
-
- int bytesRead;
- final byte[] buffer = new byte[4096];
- while ((bytesRead = inputStream.read(buffer)) > 0)
- {
- builder.append(buffer, 0, bytesRead);
- }
-
- value = builder.toByteString();
- }
- catch (final Exception e)
- {
- // We were unable to read the contents of that URL for some
- // reason.
- final LocalizableMessage message = ERR_LDIF_URL_IO_ERROR.get(
- entryDN.toString(), record.lineNumber, attrName,
- String.valueOf(contentURL), String.valueOf(e));
- throw DecodeException.error(message);
- }
- finally
- {
- if (inputStream != null)
- {
- try
- {
- inputStream.close();
+ value = ByteString.valueOf(ldifLine.substring(pos));
}
- catch (final Exception e)
- {
- // Ignore.
+ }
+ return value;
+ }
+
+ final LDIFRecord readLDIFRecord() throws IOException {
+ // Read the entry lines into a buffer.
+ final StringBuilder lastLineBuilder = new StringBuilder();
+ final LinkedList<String> ldifLines = new LinkedList<String>();
+ long recordLineNumber = 0;
+
+ final int stateStart = 0;
+ final int stateStartCommentLine = 1;
+ final int stateGotLDIFLine = 2;
+ final int stateGotCommentLine = 3;
+ final int appendingLDIFLine = 4;
+
+ int state = stateStart;
+
+ while (true) {
+ final String line = readLine();
+
+ switch (state) {
+ case stateStart:
+ if (line == null) {
+ // We have reached the end of the LDIF source.
+ return null;
+ } else if (line.length() == 0) {
+ // Skip leading blank lines.
+ } else if (line.charAt(0) == '#') {
+ // This is a comment at the start of the LDIF record.
+ state = stateStartCommentLine;
+ } else if (isContinuationLine(line)) {
+ // Fatal: got a continuation line at the start of the
+ // record.
+ final LocalizableMessage message =
+ ERR_LDIF_INVALID_LEADING_SPACE.get(lineNumber, line);
+ throw DecodeException.fatalError(message);
+ } else {
+ // Got the first line of LDIF.
+ ldifLines.add(line);
+ recordLineNumber = lineNumber;
+ state = stateGotLDIFLine;
+ }
+ break;
+ case stateStartCommentLine:
+ if (line == null) {
+ // We have reached the end of the LDIF source.
+ return null;
+ } else if (line.length() == 0) {
+ // Skip leading blank lines and comments.
+ state = stateStart;
+ } else if (line.charAt(0) == '#') {
+ // This is another comment at the start of the LDIF record.
+ } else if (isContinuationLine(line)) {
+ // Skip comment continuation lines.
+ } else {
+ // Got the first line of LDIF.
+ ldifLines.add(line);
+ recordLineNumber = lineNumber;
+ state = stateGotLDIFLine;
+ }
+ break;
+ case stateGotLDIFLine:
+ if (line == null) {
+ // We have reached the end of the LDIF source.
+ return new LDIFRecord(recordLineNumber, ldifLines);
+ } else if (line.length() == 0) {
+ // We have reached the end of the LDIF record.
+ return new LDIFRecord(recordLineNumber, ldifLines);
+ } else if (line.charAt(0) == '#') {
+ // This is a comment.
+ state = stateGotCommentLine;
+ } else if (isContinuationLine(line)) {
+ // Got a continuation line for the previous line.
+ lastLineBuilder.setLength(0);
+ lastLineBuilder.append(ldifLines.removeLast());
+ lastLineBuilder.append(line.substring(1));
+ state = appendingLDIFLine;
+ } else {
+ // Got the next line of LDIF.
+ ldifLines.add(line);
+ state = stateGotLDIFLine;
+ }
+ break;
+ case stateGotCommentLine:
+ if (line == null) {
+ // We have reached the end of the LDIF source.
+ return new LDIFRecord(recordLineNumber, ldifLines);
+ } else if (line.length() == 0) {
+ // We have reached the end of the LDIF record.
+ return new LDIFRecord(recordLineNumber, ldifLines);
+ } else if (line.charAt(0) == '#') {
+ // This is another comment.
+ state = stateGotCommentLine;
+ } else if (isContinuationLine(line)) {
+ // Skip comment continuation lines.
+ } else {
+ // Got the next line of LDIF.
+ ldifLines.add(line);
+ state = stateGotLDIFLine;
+ }
+ break;
+ case appendingLDIFLine:
+ if (line == null) {
+ // We have reached the end of the LDIF source.
+ ldifLines.add(lastLineBuilder.toString());
+ return new LDIFRecord(recordLineNumber, ldifLines);
+ } else if (line.length() == 0) {
+ // We have reached the end of the LDIF record.
+ ldifLines.add(lastLineBuilder.toString());
+ return new LDIFRecord(recordLineNumber, ldifLines);
+ } else if (line.charAt(0) == '#') {
+ // This is a comment.
+ ldifLines.add(lastLineBuilder.toString());
+ state = stateGotCommentLine;
+ } else if (isContinuationLine(line)) {
+ // Got another continuation line for the previous line.
+ lastLineBuilder.append(line.substring(1));
+ } else {
+ // Got the next line of LDIF.
+ ldifLines.add(lastLineBuilder.toString());
+ ldifLines.add(line);
+ state = stateGotLDIFLine;
+ }
+ break;
}
- }
}
- }
- else
- {
- // The rest of the line should be the value. Skip over any
- // spaces and take the rest of the line as the value.
- int pos = colonPos + 1;
- while (pos < length && ldifLine.charAt(pos) == ' ')
- {
- pos++;
- }
-
- value = ByteString.valueOf(ldifLine.substring(pos));
- }
}
- return value;
- }
+ final boolean readLDIFRecordAttributeValue(final LDIFRecord record, final String ldifLine,
+ final Entry entry, final List<LocalizableMessage> schemaErrors) throws DecodeException {
+ // Parse the attribute description.
+ final int colonPos = parseColonPosition(record, ldifLine);
+ final String attrDescr = ldifLine.substring(0, colonPos);
+ AttributeDescription attributeDescription;
+ try {
+ attributeDescription = AttributeDescription.valueOf(attrDescr, schema);
+ } catch (final UnknownSchemaElementException e) {
+ final LocalizableMessage message =
+ ERR_LDIF_UNKNOWN_ATTRIBUTE_TYPE.get(record.lineNumber, entry.getName()
+ .toString(), attrDescr);
+ switch (schemaValidationPolicy.checkAttributesAndObjectClasses()) {
+ case REJECT:
+ schemaErrors.add(message);
+ return false;
+ case WARN:
+ schemaErrors.add(message);
+ return true;
+ default: // Ignore
+ // This should not happen: we should be using a non-strict
+ // schema for
+ // this policy.
+ throw new IllegalStateException("Schema is not consistent with policy", e);
+ }
+ } catch (final LocalizedIllegalArgumentException e) {
+ final LocalizableMessage message =
+ ERR_LDIF_MALFORMED_ATTRIBUTE_NAME.get(record.lineNumber, entry.getName()
+ .toString(), attrDescr);
+ throw DecodeException.error(message);
+ }
- final LDIFRecord readLDIFRecord() throws IOException
- {
- // Read the entry lines into a buffer.
- final StringBuilder lastLineBuilder = new StringBuilder();
- final LinkedList<String> ldifLines = new LinkedList<String>();
- long recordLineNumber = 0;
+ // Now parse the attribute value.
+ final ByteString value =
+ parseSingleValue(record, ldifLine, entry.getName(), colonPos, attrDescr);
- final int stateStart = 0;
- final int stateStartCommentLine = 1;
- final int stateGotLDIFLine = 2;
- final int stateGotCommentLine = 3;
- final int appendingLDIFLine = 4;
+ // Skip the attribute if requested before performing any schema
+ // checking: the attribute may have been excluded because it is
+ // known to violate the schema.
+ if (isAttributeExcluded(attributeDescription)) {
+ return true;
+ }
- int state = stateStart;
+ final Syntax syntax = attributeDescription.getAttributeType().getSyntax();
- while (true)
- {
- final String line = readLine();
+ // Ensure that the binary option is present if required.
+ if (!syntax.isBEREncodingRequired()) {
+ if (schemaValidationPolicy.checkAttributeValues().needsChecking()
+ && attributeDescription.containsOption("binary")) {
+ final LocalizableMessage message =
+ ERR_LDIF_UNEXPECTED_BINARY_OPTION.get(record.lineNumber, entry.getName()
+ .toString(), attrDescr);
+ schemaErrors.add(message);
+ return !schemaValidationPolicy.checkAttributeValues().isReject();
+ }
+ } else {
+ attributeDescription = attributeDescription.withOption("binary");
+ }
- switch (state)
- {
- case stateStart:
- if (line == null)
- {
- // We have reached the end of the LDIF source.
- return null;
+ final boolean checkAttributeValues =
+ schemaValidationPolicy.checkAttributeValues().needsChecking();
+ if (checkAttributeValues) {
+ LocalizableMessageBuilder builder = new LocalizableMessageBuilder();
+ if (!syntax.valueIsAcceptable(value, builder)) {
+ schemaErrors.add(builder.toMessage());
+ if (schemaValidationPolicy.checkAttributeValues().isReject()) {
+ return false;
+ }
+ }
}
- else if (line.length() == 0)
- {
- // Skip leading blank lines.
- }
- else if (line.charAt(0) == '#')
- {
- // This is a comment at the start of the LDIF record.
- state = stateStartCommentLine;
- }
- else if (isContinuationLine(line))
- {
- // Fatal: got a continuation line at the start of the record.
- final LocalizableMessage message = ERR_LDIF_INVALID_LEADING_SPACE
- .get(lineNumber, line);
- throw DecodeException.fatalError(message);
- }
- else
- {
- // Got the first line of LDIF.
- ldifLines.add(line);
- recordLineNumber = lineNumber;
- state = stateGotLDIFLine;
- }
- break;
- case stateStartCommentLine:
- if (line == null)
- {
- // We have reached the end of the LDIF source.
- return null;
- }
- else if (line.length() == 0)
- {
- // Skip leading blank lines and comments.
- state = stateStart;
- }
- else if (line.charAt(0) == '#')
- {
- // This is another comment at the start of the LDIF record.
- }
- else if (isContinuationLine(line))
- {
- // Skip comment continuation lines.
- }
- else
- {
- // Got the first line of LDIF.
- ldifLines.add(line);
- recordLineNumber = lineNumber;
- state = stateGotLDIFLine;
- }
- break;
- case stateGotLDIFLine:
- if (line == null)
- {
- // We have reached the end of the LDIF source.
- return new LDIFRecord(recordLineNumber, ldifLines);
- }
- else if (line.length() == 0)
- {
- // We have reached the end of the LDIF record.
- return new LDIFRecord(recordLineNumber, ldifLines);
- }
- else if (line.charAt(0) == '#')
- {
- // This is a comment.
- state = stateGotCommentLine;
- }
- else if (isContinuationLine(line))
- {
- // Got a continuation line for the previous line.
- lastLineBuilder.setLength(0);
- lastLineBuilder.append(ldifLines.removeLast());
- lastLineBuilder.append(line.substring(1));
- state = appendingLDIFLine;
- }
- else
- {
- // Got the next line of LDIF.
- ldifLines.add(line);
- state = stateGotLDIFLine;
- }
- break;
- case stateGotCommentLine:
- if (line == null)
- {
- // We have reached the end of the LDIF source.
- return new LDIFRecord(recordLineNumber, ldifLines);
- }
- else if (line.length() == 0)
- {
- // We have reached the end of the LDIF record.
- return new LDIFRecord(recordLineNumber, ldifLines);
- }
- else if (line.charAt(0) == '#')
- {
- // This is another comment.
- state = stateGotCommentLine;
- }
- else if (isContinuationLine(line))
- {
- // Skip comment continuation lines.
- }
- else
- {
- // Got the next line of LDIF.
- ldifLines.add(line);
- state = stateGotLDIFLine;
- }
- break;
- case appendingLDIFLine:
- if (line == null)
- {
- // We have reached the end of the LDIF source.
- ldifLines.add(lastLineBuilder.toString());
- return new LDIFRecord(recordLineNumber, ldifLines);
- }
- else if (line.length() == 0)
- {
- // We have reached the end of the LDIF record.
- ldifLines.add(lastLineBuilder.toString());
- return new LDIFRecord(recordLineNumber, ldifLines);
- }
- else if (line.charAt(0) == '#')
- {
- // This is a comment.
- ldifLines.add(lastLineBuilder.toString());
- state = stateGotCommentLine;
- }
- else if (isContinuationLine(line))
- {
- // Got another continuation line for the previous line.
- lastLineBuilder.append(line.substring(1));
- }
- else
- {
- // Got the next line of LDIF.
- ldifLines.add(lastLineBuilder.toString());
- ldifLines.add(line);
- state = stateGotLDIFLine;
- }
- break;
- }
- }
- }
+ Attribute attribute = entry.getAttribute(attributeDescription);
+ if (attribute == null) {
+ attribute = new LinkedAttribute(attributeDescription, value);
+ entry.addAttribute(attribute);
+ } else if (checkAttributeValues) {
+ if (!attribute.add(value)) {
+ final LocalizableMessage message =
+ WARN_LDIF_DUPLICATE_ATTRIBUTE_VALUE.get(record.lineNumber, entry.getName()
+ .toString(), attrDescr, value.toString());
+ schemaErrors.add(message);
+ if (schemaValidationPolicy.checkAttributeValues().isReject()) {
+ return false;
+ }
+ } else if (attributeDescription.getAttributeType().isSingleValue()) {
+ final LocalizableMessage message =
+ ERR_LDIF_MULTI_VALUED_SINGLE_VALUED_ATTRIBUTE.get(record.lineNumber, entry
+ .getName().toString(), attrDescr);
+ schemaErrors.add(message);
+ if (schemaValidationPolicy.checkAttributeValues().isReject()) {
+ return false;
+ }
+ }
+ } else {
+ attribute.add(value);
+ }
-
- final boolean readLDIFRecordAttributeValue(final LDIFRecord record,
- final String ldifLine, final Entry entry,
- final List<LocalizableMessage> schemaErrors) throws DecodeException
- {
- // Parse the attribute description.
- final int colonPos = parseColonPosition(record, ldifLine);
- final String attrDescr = ldifLine.substring(0, colonPos);
-
- AttributeDescription attributeDescription;
- try
- {
- attributeDescription = AttributeDescription.valueOf(attrDescr, schema);
- }
- catch (final UnknownSchemaElementException e)
- {
- final LocalizableMessage message = ERR_LDIF_UNKNOWN_ATTRIBUTE_TYPE.get(
- record.lineNumber, entry.getName().toString(), attrDescr);
- switch (schemaValidationPolicy.checkAttributesAndObjectClasses())
- {
- case REJECT:
- schemaErrors.add(message);
- return false;
- case WARN:
- schemaErrors.add(message);
return true;
- default: // Ignore
- // This should not happen: we should be using a non-strict schema for
- // this policy.
- throw new IllegalStateException("Schema is not consistent with policy",
- e);
- }
- }
- catch (final LocalizedIllegalArgumentException e)
- {
- final LocalizableMessage message = ERR_LDIF_MALFORMED_ATTRIBUTE_NAME.get(
- record.lineNumber, entry.getName().toString(), attrDescr);
- throw DecodeException.error(message);
}
- // Now parse the attribute value.
- final ByteString value = parseSingleValue(record, ldifLine,
- entry.getName(), colonPos, attrDescr);
-
- // Skip the attribute if requested before performing any schema
- // checking: the attribute may have been excluded because it is
- // known to violate the schema.
- if (isAttributeExcluded(attributeDescription))
- {
- return true;
- }
-
- final Syntax syntax = attributeDescription.getAttributeType().getSyntax();
-
- // Ensure that the binary option is present if required.
- if (!syntax.isBEREncodingRequired())
- {
- if (schemaValidationPolicy.checkAttributeValues().needsChecking()
- && attributeDescription.containsOption("binary"))
- {
- final LocalizableMessage message = ERR_LDIF_UNEXPECTED_BINARY_OPTION
- .get(record.lineNumber, entry.getName().toString(), attrDescr);
- schemaErrors.add(message);
- if (schemaValidationPolicy.checkAttributeValues().isReject())
- {
- return false;
+ final DN readLDIFRecordDN(final LDIFRecord record) throws DecodeException {
+ String ldifLine = record.iterator.next();
+ int colonPos = ldifLine.indexOf(":");
+ if (colonPos <= 0) {
+ final LocalizableMessage message =
+ ERR_LDIF_NO_ATTR_NAME.get(record.lineNumber, ldifLine.toString());
+ throw DecodeException.error(message);
}
- else
- {
- // Skip to next attribute value.
- return true;
+
+ String attrName = toLowerCase(ldifLine.substring(0, colonPos));
+ if (attrName.equals("version")) {
+ // This is the version line, try the next line if there is one.
+ if (!record.iterator.hasNext()) {
+ return null;
+ }
+
+ ldifLine = record.iterator.next();
+ colonPos = ldifLine.indexOf(":");
+ if (colonPos <= 0) {
+ final LocalizableMessage message =
+ ERR_LDIF_NO_ATTR_NAME.get(record.lineNumber, ldifLine.toString());
+ throw DecodeException.error(message);
+ }
+
+ attrName = toLowerCase(ldifLine.substring(0, colonPos));
}
- }
- }
- else
- {
- attributeDescription = attributeDescription.withOption("binary");
- }
- final boolean checkAttributeValues = schemaValidationPolicy
- .checkAttributeValues().needsChecking();
- if (checkAttributeValues)
- {
- LocalizableMessageBuilder builder = new LocalizableMessageBuilder();
- if (!syntax.valueIsAcceptable(value, builder))
- {
- schemaErrors.add(builder.toMessage());
- if (schemaValidationPolicy.checkAttributeValues().isReject())
- {
- return false;
+ if (!attrName.equals("dn")) {
+ final LocalizableMessage message =
+ ERR_LDIF_NO_DN.get(record.lineNumber, ldifLine.toString());
+ throw DecodeException.error(message);
}
- }
- }
- Attribute attribute = entry.getAttribute(attributeDescription);
- if (attribute == null)
- {
- attribute = new LinkedAttribute(attributeDescription, value);
- entry.addAttribute(attribute);
- }
- else if (checkAttributeValues)
- {
- if (!attribute.add(value))
- {
- final LocalizableMessage message = WARN_LDIF_DUPLICATE_ATTRIBUTE_VALUE
- .get(record.lineNumber, entry.getName().toString(), attrDescr,
- value.toString());
- schemaErrors.add(message);
- if (schemaValidationPolicy.checkAttributeValues().isReject())
- {
- return false;
+ // Look at the character immediately after the colon. If there is
+ // none, then assume the null DN. If it is another colon, then the
+ // DN must be base64-encoded. Otherwise, it may be one or more
+ // spaces.
+ final int length = ldifLine.length();
+ if (colonPos == length - 1) {
+ return DN.rootDN();
}
- }
- else if (attributeDescription.getAttributeType().isSingleValue())
- {
- final LocalizableMessage message = ERR_LDIF_MULTI_VALUED_SINGLE_VALUED_ATTRIBUTE
- .get(record.lineNumber, entry.getName().toString(), attrDescr);
- schemaErrors.add(message);
- if (schemaValidationPolicy.checkAttributeValues().isReject())
- {
- return false;
+
+ String dnString = null;
+
+ if (ldifLine.charAt(colonPos + 1) == ':') {
+ // The DN is base64-encoded. Find the first non-blank character
+ // and take the rest of the line and base64-decode it.
+ int pos = colonPos + 2;
+ while (pos < length && ldifLine.charAt(pos) == ' ') {
+ pos++;
+ }
+
+ final String base64DN = ldifLine.substring(pos);
+ try {
+ dnString = Base64.decode(base64DN).toString();
+ } catch (final LocalizedIllegalArgumentException e) {
+ // The value did not have a valid base64-encoding.
+ final LocalizableMessage message =
+ ERR_LDIF_COULD_NOT_BASE64_DECODE_DN.get(record.lineNumber, ldifLine, e
+ .getMessageObject());
+ throw DecodeException.error(message);
+ }
+ } else {
+ // The rest of the value should be the DN. Skip over any spaces
+ // and attempt to decode the rest of the line as the DN.
+ int pos = colonPos + 1;
+ while (pos < length && ldifLine.charAt(pos) == ' ') {
+ pos++;
+ }
+
+ dnString = ldifLine.substring(pos);
}
- }
- }
- else
- {
- attribute.add(value);
+
+ try {
+ return DN.valueOf(dnString, schema);
+ } catch (final LocalizedIllegalArgumentException e) {
+ final LocalizableMessage message =
+ ERR_LDIF_INVALID_DN.get(record.lineNumber, ldifLine, e.getMessageObject());
+ throw DecodeException.error(message);
+ }
}
- return true;
- }
+ final String readLDIFRecordKeyValuePair(final LDIFRecord record, final KeyValuePair pair,
+ final boolean allowBase64) {
+ final String ldifLine = record.iterator.next();
+ final int colonPos = ldifLine.indexOf(":");
+ if (colonPos <= 0) {
+ pair.key = null;
+ return ldifLine;
+ }
+ pair.key = ldifLine.substring(0, colonPos);
+ // Look at the character immediately after the colon. If there is
+ // none, then no value was specified. Throw an exception
+ final int length = ldifLine.length();
+ if (colonPos == length - 1) {
+ pair.key = null;
+ return ldifLine;
+ }
+ if (allowBase64 && ldifLine.charAt(colonPos + 1) == ':') {
+ // The value is base64-encoded. Find the first non-blank
+ // character, take the rest of the line, and base64-decode it.
+ int pos = colonPos + 2;
+ while (pos < length && ldifLine.charAt(pos) == ' ') {
+ pos++;
+ }
- final DN readLDIFRecordDN(final LDIFRecord record) throws DecodeException
- {
- String ldifLine = record.iterator.next();
- int colonPos = ldifLine.indexOf(":");
- if (colonPos <= 0)
- {
- final LocalizableMessage message = ERR_LDIF_NO_ATTR_NAME.get(
- record.lineNumber, ldifLine.toString());
- throw DecodeException.error(message);
- }
+ try {
+ pair.value = Base64.decode(ldifLine.substring(pos)).toString();
+ } catch (final LocalizedIllegalArgumentException e) {
+ pair.key = null;
+ return ldifLine;
+ }
+ } else {
+ // The rest of the value should be the changetype. Skip over any
+ // spaces and attempt to decode the rest of the line as the
+ // changetype string.
+ int pos = colonPos + 1;
+ while (pos < length && ldifLine.charAt(pos) == ' ') {
+ pos++;
+ }
- String attrName = toLowerCase(ldifLine.substring(0, colonPos));
- if (attrName.equals("version"))
- {
- // This is the version line, try the next line if there is one.
- if (!record.iterator.hasNext())
- {
- return null;
- }
+ pair.value = ldifLine.substring(pos);
+ }
- ldifLine = record.iterator.next();
- colonPos = ldifLine.indexOf(":");
- if (colonPos <= 0)
- {
- final LocalizableMessage message = ERR_LDIF_NO_ATTR_NAME.get(
- record.lineNumber, ldifLine.toString());
- throw DecodeException.error(message);
- }
-
- attrName = toLowerCase(ldifLine.substring(0, colonPos));
- }
-
- if (!attrName.equals("dn"))
- {
- final LocalizableMessage message = ERR_LDIF_NO_DN.get(record.lineNumber,
- ldifLine.toString());
- throw DecodeException.error(message);
- }
-
- // Look at the character immediately after the colon. If there is
- // none, then assume the null DN. If it is another colon, then the
- // DN must be base64-encoded. Otherwise, it may be one or more
- // spaces.
- final int length = ldifLine.length();
- if (colonPos == length - 1)
- {
- return DN.rootDN();
- }
-
- String dnString = null;
-
- if (ldifLine.charAt(colonPos + 1) == ':')
- {
- // The DN is base64-encoded. Find the first non-blank character
- // and take the rest of the line and base64-decode it.
- int pos = colonPos + 2;
- while (pos < length && ldifLine.charAt(pos) == ' ')
- {
- pos++;
- }
-
- final String base64DN = ldifLine.substring(pos);
- try
- {
- dnString = Base64.decode(base64DN).toString();
- }
- catch (final LocalizedIllegalArgumentException e)
- {
- // The value did not have a valid base64-encoding.
- final LocalizableMessage message = ERR_LDIF_COULD_NOT_BASE64_DECODE_DN
- .get(record.lineNumber, ldifLine, e.getMessageObject());
- throw DecodeException.error(message);
- }
- }
- else
- {
- // The rest of the value should be the DN. Skip over any spaces
- // and attempt to decode the rest of the line as the DN.
- int pos = colonPos + 1;
- while (pos < length && ldifLine.charAt(pos) == ' ')
- {
- pos++;
- }
-
- dnString = ldifLine.substring(pos);
- }
-
- try
- {
- return DN.valueOf(dnString, schema);
- }
- catch (final LocalizedIllegalArgumentException e)
- {
- final LocalizableMessage message = ERR_LDIF_INVALID_DN.get(
- record.lineNumber, ldifLine, e.getMessageObject());
- throw DecodeException.error(message);
- }
- }
-
-
-
- final String readLDIFRecordKeyValuePair(final LDIFRecord record,
- final KeyValuePair pair, final boolean allowBase64)
- {
- final String ldifLine = record.iterator.next();
- final int colonPos = ldifLine.indexOf(":");
- if (colonPos <= 0)
- {
- pair.key = null;
- return ldifLine;
- }
- pair.key = ldifLine.substring(0, colonPos);
-
- // Look at the character immediately after the colon. If there is
- // none, then no value was specified. Throw an exception
- final int length = ldifLine.length();
- if (colonPos == length - 1)
- {
- pair.key = null;
- return ldifLine;
- }
-
- if (allowBase64 && ldifLine.charAt(colonPos + 1) == ':')
- {
- // The value is base64-encoded. Find the first non-blank
- // character, take the rest of the line, and base64-decode it.
- int pos = colonPos + 2;
- while (pos < length && ldifLine.charAt(pos) == ' ')
- {
- pos++;
- }
-
- try
- {
- pair.value = Base64.decode(ldifLine.substring(pos)).toString();
- }
- catch (final LocalizedIllegalArgumentException e)
- {
- pair.key = null;
return ldifLine;
- }
- }
- else
- {
- // The rest of the value should be the changetype. Skip over any
- // spaces and attempt to decode the rest of the line as the
- // changetype string.
- int pos = colonPos + 1;
- while (pos < length && ldifLine.charAt(pos) == ' ')
- {
- pos++;
- }
-
- pair.value = ldifLine.substring(pos);
}
- return ldifLine;
- }
-
-
-
- final void handleMalformedRecord(final LDIFRecord record,
- final LocalizableMessage message) throws DecodeException
- {
- rejectedRecordListener.handleMalformedRecord(record.lineNumber,
- record.ldifLines, message);
- }
-
-
-
- final void handleSchemaValidationFailure(final LDIFRecord record,
- final List<LocalizableMessage> messages) throws DecodeException
- {
- rejectedRecordListener.handleSchemaValidationFailure(record.lineNumber,
- record.ldifLines, messages);
- }
-
-
-
- final void handleSchemaValidationWarning(final LDIFRecord record,
- final List<LocalizableMessage> messages) throws DecodeException
- {
- rejectedRecordListener.handleSchemaValidationWarning(record.lineNumber,
- record.ldifLines, messages);
- }
-
-
-
- final void handleSkippedRecord(final LDIFRecord record,
- final LocalizableMessage message) throws DecodeException
- {
- rejectedRecordListener.handleSkippedRecord(record.lineNumber,
- record.ldifLines, message);
- }
-
-
-
- // Determine whether the provided line is a continuation line. Note
- // that while RFC 2849 technically only allows a space in this
- // position, both OpenLDAP and the Sun Java System Directory Server
- // allow a tab as well, so we will too for compatibility reasons. See
- // issue #852 for details.
- private boolean isContinuationLine(final String line)
- {
- return line.charAt(0) == ' ' || line.charAt(0) == '\t';
- }
-
-
-
- private String readLine() throws IOException
- {
- final String line = impl.readLine();
- if (line != null)
- {
- lineNumber++;
+ final void handleMalformedRecord(final LDIFRecord record, final LocalizableMessage message)
+ throws DecodeException {
+ rejectedRecordListener.handleMalformedRecord(record.lineNumber, record.ldifLines, message);
}
- return line;
- }
+
+ final void handleSchemaValidationFailure(final LDIFRecord record,
+ final List<LocalizableMessage> messages) throws DecodeException {
+ rejectedRecordListener.handleSchemaValidationFailure(record.lineNumber, record.ldifLines,
+ messages);
+ }
+
+ final void handleSchemaValidationWarning(final LDIFRecord record,
+ final List<LocalizableMessage> messages) throws DecodeException {
+ rejectedRecordListener.handleSchemaValidationWarning(record.lineNumber, record.ldifLines,
+ messages);
+ }
+
+ final void handleSkippedRecord(final LDIFRecord record, final LocalizableMessage message)
+ throws DecodeException {
+ rejectedRecordListener.handleSkippedRecord(record.lineNumber, record.ldifLines, message);
+ }
+
+ // Determine whether the provided line is a continuation line. Note
+ // that while RFC 2849 technically only allows a space in this
+ // position, both OpenLDAP and the Sun Java System Directory Server
+ // allow a tab as well, so we will too for compatibility reasons. See
+ // issue #852 for details.
+ private boolean isContinuationLine(final String line) {
+ return line.charAt(0) == ' ' || line.charAt(0) == '\t';
+ }
+
+ private String readLine() throws IOException {
+ final String line = impl.readLine();
+ if (line != null) {
+ lineNumber++;
+ }
+ return line;
+ }
}
--
Gitblit v1.10.0