/*
* ====================
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2008-2009 Sun Microsystems, Inc. All rights reserved.
*
* The contents of this file are subject to the terms of the Common Development
* and Distribution License("CDDL") (the "License"). You may not use this file
* except in compliance with the License.
*
* You can obtain a copy of the License at
* http://IdentityConnectors.dev.java.net/legal/license.txt
* See the License for the specific language governing permissions and limitations
* under the License.
*
* When distributing the Covered Code, include this CDDL Header Notice in each file
* and include the License file at identityconnectors/legal/license.txt.
* If applicable, add the following below this CDDL Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyrighted [year] [name of copyright owner]"
* ====================
*/
package org.identityconnectors.ldap.sync.sunds;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
public class LdifParser implements Iterable<LdifParser.Line> {
private final String ldif;
public LdifParser(String ldif) {
this.ldif = ldif;
}
public Iterator<Line> iterator() {
return new LineIterator(getUnfoldedLines());
}
private List<String> getUnfoldedLines() {
String[] lines = ldif.split("\n", -1);
ArrayList<String> result = new ArrayList<String>(lines.length);
StringBuilder builder = null;
for (String line : lines) {
if (line.startsWith(" ")) {
String content = line.substring(1);
if (builder == null) {
builder = new StringBuilder(content);
} else {
builder.append(content);
}
} else {
if (builder != null) {
result.add(builder.toString());
}
builder = new StringBuilder(line);
}
}
if (builder != null) {
result.add(builder.toString());
}
return result;
}
private static final class LineIterator implements Iterator<Line> {
private final Iterator<String> rawLines;
private Line lastLine;
private Line next;
public LineIterator(List<String> rawLines) {
this.rawLines = rawLines.iterator();
}
public boolean hasNext() {
if (next == null) {
next = getNext();
}
return next != null;
}
public Line next() {
if (next == null) {
next = getNext();
}
if (next == null) {
throw new NoSuchElementException();
}
Line result = next;
next = null;
return result;
}
private Line getNext() {
Line result = null;
while (result == null && rawLines.hasNext()) {
String rawLine = rawLines.next();
if (rawLine.trim().length() == 0 && lastLine != ChangeSeparator.INSTANCE) {
result = ChangeSeparator.INSTANCE;
} else if (rawLine.startsWith("-") && lastLine != Separator.INSTANCE) {
result = Separator.INSTANCE;
} else {
int sepIndex = rawLine.indexOf(':');
if (sepIndex > 0) {
String name = rawLine.substring(0, sepIndex).trim();
String value = rawLine.substring(sepIndex + 1).trim();
result = new NameValue(name, value);
}
}
}
// Always send a change separator as the last thing.
if (result == null && lastLine != ChangeSeparator.INSTANCE) {
result = ChangeSeparator.INSTANCE;
}
lastLine = result;
return result;
}
public void remove() {
throw new UnsupportedOperationException();
}
}
public abstract static class Line {
}
public final static class NameValue extends Line {
private final String name;
private final String value;
public NameValue(String name, String value) {
super();
this.name = name;
this.value = value;
}
public String getName() {
return name;
}
public String getValue() {
return value;
}
@Override
public String toString() {
return "LdifParser$NameValue[name: " + name + "; value: " + value + "]";
}
}
public static final class Separator extends Line {
final static Separator INSTANCE = new Separator();
private Separator() {
}
@Override
public String toString() {
return "LdifParser$Separator";
}
}
public static final class ChangeSeparator extends Line {
final static ChangeSeparator INSTANCE = new ChangeSeparator();
private ChangeSeparator() {
}
@Override
public String toString() {
return "LdifParser$ChangeSeparator";
}
}
}