Updated according to Keiths second delivery, plus some minor cleanup.

This commit is contained in:
Ulrik Sandberg
2009-08-02 19:31:38 +00:00
parent 721fe2d73c
commit e17523daf3
13 changed files with 69 additions and 97 deletions

View File

@@ -1,7 +1,4 @@
/**
* Extends BasicAttribute adding support for options.
*/
package org.springframework.ldap.ldif;
package org.springframework.ldap.core;
import java.util.Collection;
import java.util.HashSet;
@@ -18,7 +15,6 @@ import javax.naming.directory.BasicAttribute;
* {@link java.lang.String}.
*
* @author Keith Barlow
*
*/
public class LdapAttribute extends BasicAttribute {

View File

@@ -1,7 +1,4 @@
/**
* Extends BasicAttributes adding support for DNs.
*/
package org.springframework.ldap.ldif;
package org.springframework.ldap.core;
import java.net.URI;

View File

@@ -1,6 +1,3 @@
/**
*
*/
package org.springframework.ldap.ldif;
import org.springframework.ldap.NamingException;
@@ -9,7 +6,6 @@ import org.springframework.ldap.NamingException;
* Thrown whenever a parsed attribute does not conform to LDAP specifications.
*
* @author Keith Barlow
*
*/
public class InvalidAttributeFormatException extends NamingException {

View File

@@ -1,6 +1,3 @@
/**
*
*/
package org.springframework.ldap.ldif;
import org.springframework.ldap.NamingException;
@@ -9,7 +6,6 @@ import org.springframework.ldap.NamingException;
* Thrown whenever a parsed record does not conform to LDAP specifications.
*
* @author Keith Barlow
*
*/
public class InvalidRecordFormatException extends NamingException {

View File

@@ -12,12 +12,13 @@ import javax.naming.directory.Attribute;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.ldap.core.DistinguishedName;
import org.springframework.ldap.core.LdapAttributes;
import org.springframework.ldap.ldif.InvalidAttributeFormatException;
import org.springframework.ldap.ldif.InvalidRecordFormatException;
import org.springframework.ldap.ldif.LdapAttributes;
import org.springframework.ldap.ldif.support.AttributeValidationPolicy;
import org.springframework.ldap.ldif.support.DefaultAttributeValidationPolicy;
import org.springframework.ldap.ldif.support.LineIdentifier;
@@ -27,13 +28,13 @@ import org.springframework.ldap.schema.Specification;
import org.springframework.util.Assert;
/**
* The {@link LDIFParser LDIFParser} is the main class of the {@link org.springframework.ldap.ldif} package.
* The {@link LdifParser LdifParser} is the main class of the {@link org.springframework.ldap.ldif} package.
* This class reads lines from a resource and assembles them into an {@link LdapAttributes LdapAttributes} object.
* The {@link LDIFParser LDIFParser} does ignores <i>changetype</i> LDIF entries as their usefulness in the
* The {@link LdifParser LdifParser} does ignores <i>changetype</i> LDIF entries as their usefulness in the
* context of an application has yet to be determined.
* <p>
* <b>Design</b><br/>
* {@link LDIFPaser LDIFParser} provides the main interface for operation but requires three supporting classes to
* {@link LdifParser LdifParser} provides the main interface for operation but requires three supporting classes to
* enable operation:
* <ul>
* <li>{@link SeparatorPolicy SeparatorPolicy} - establishes the mechanism by which lines are assembled into attributes.</li>
@@ -48,7 +49,7 @@ import org.springframework.util.Assert;
* lines and appends them to the buffer until it encounters the start of a new attribute or an end of record
* delimiter. When the new attribute or end of record is encountered, the buffer is passed to the
* {@link AttributeValidationPolicy AttributeValidationPolicy} which ensures the buffer conforms to a valid
* attribute definition as defined in RFC2849 and returns an {@link org.springframework.ldap.ldif.LdapAttribute LdapAttribute} object
* attribute definition as defined in RFC2849 and returns an {@link org.springframework.ldap.core.LdapAttribute LdapAttribute} object
* which is then added to the record, an {@link LdapAttributes LdapAttributes} object. Upon encountering the
* end of record, the record is validated by the {@link Specification Specification} policy and,
* if valid, returned to the requester.
@@ -60,9 +61,9 @@ import org.springframework.util.Assert;
* @author Keith Barlow
*
*/
public class LDIFParser implements Parser {
public class LdifParser implements Parser, InitializingBean {
private static final Log log = LogFactory.getLog(LDIFParser.class);
private static final Log log = LogFactory.getLog(LdifParser.class);
/**
* The resource to parse.
@@ -87,12 +88,12 @@ public class LDIFParser implements Parser {
/**
* The RecordSpecification for validating records produced.
*/
private Specification<LdapAttributes> recordSpecification = new DefaultSchemaSpecification();
private Specification<LdapAttributes> specification = new DefaultSchemaSpecification();
/**
* Default constructor.
*/
public LDIFParser() {
public LdifParser() {
}
@@ -101,7 +102,7 @@ public class LDIFParser implements Parser {
*
* @param resource The resource to parse.
*/
public LDIFParser(Resource resource) {
public LdifParser(Resource resource) {
this.resource = resource;
}
@@ -110,7 +111,7 @@ public class LDIFParser implements Parser {
*
* @param file The file to parse.
*/
public LDIFParser(File file) {
public LdifParser(File file) {
this.resource = new FileSystemResource(file);
}
@@ -141,28 +142,19 @@ public class LDIFParser implements Parser {
* @param specification
*/
public void setRecordSpecification(Specification<LdapAttributes> specification) {
this.recordSpecification = specification;
this.specification = specification;
}
public void setResource(Resource resource) {
this.resource = resource;
}
public void afterPropertiesSet() throws Exception {
}
public void open() throws IOException {
Assert.notNull(resource, "Resource must be set.");
Assert.isTrue(resource.exists(), resource.getDescription() + ": resource does not exist!");
Assert.isTrue(resource.isReadable(), "Resource is not readable.");
reader = new BufferedReader(new InputStreamReader(resource.getInputStream()));
reader = new BufferedReader(new InputStreamReader(resource.getInputStream()));
}
public void close() throws IOException {
public void close() throws IOException {
if (resource.isOpen())
reader.close();
}
@@ -245,9 +237,9 @@ public class LDIFParser implements Parser {
//flush buffer.
addAttributeToRecord(builder.toString(), record);
log.debug("satisfied: " + recordSpecification.isSatisfiedBy(record));
log.debug("satisfied: " + specification.isSatisfiedBy(record));
if (recordSpecification.isSatisfiedBy(record)) {
if (specification.isSatisfiedBy(record)) {
log.trace("Returning record.");
return record;
@@ -316,5 +308,10 @@ public class LDIFParser implements Parser {
record = null;
}
}
public void afterPropertiesSet() throws Exception {
Assert.notNull(resource, "A resource to parse is required.");
Assert.isTrue(resource.exists(), resource.getDescription() + ": resource does not exist!");
Assert.isTrue(resource.isReadable(), "Resource is not readable.");
}
}

View File

@@ -4,44 +4,43 @@ import java.io.IOException;
import javax.naming.directory.Attributes;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.core.io.Resource;
/**
* The Parser interface represents the required methods to be implemented by parser utilities.
* These methods are the base set of methods needed to provide parsing ability.
* @author Keith Barlow
*
* @author Keith Barlow
*/
public interface Parser extends InitializingBean {
public interface Parser {
/**
* Sets the resource to parse.
*
* @param resource The resource to parse.
*/
public void setResource(Resource resource);
void setResource(Resource resource);
/**
* Opens the resource: the resource must be opened prior to parsing.
*
* @throws IOException if a problem is encountered while trying to open the resource.
*/
public void open() throws IOException;
void open() throws IOException;
/**
* Closes the resource after parsing.
*
* @throws IOException if a problem is encountered while trying to close the resource.
*/
public void close() throws IOException;
void close() throws IOException;
/**
* Resets the line read parser.
*
* @throws Exception if a problem is encountered while trying to reset the resource.
*/
public void reset() throws IOException;
void reset() throws IOException;
/**
* True if the resource contains more records; false otherwise.
@@ -49,7 +48,7 @@ public interface Parser extends InitializingBean {
* @return boolean indicating whether or not the end of record has been reached.
* @throws IOException if a problem is encountered while trying to validate the resource is ready.
*/
public boolean hasMoreRecords() throws IOException;
boolean hasMoreRecords() throws IOException;
/**
* Parses the next record from the resource.
@@ -57,6 +56,6 @@ public interface Parser extends InitializingBean {
* @return LdapAttributes object representing the record parsed.
* @throws IOException if a problem is encountered while trying to read from the resource.
*/
public Attributes getRecord() throws IOException;
Attributes getRecord() throws IOException;
}

View File

@@ -4,8 +4,8 @@ import javax.naming.directory.Attribute;
/**
* Interface defining the required methods for AttributeValidationPolicies.
* @author Keith Barlow
*
* @author Keith Barlow
*/
public interface AttributeValidationPolicy {
@@ -15,6 +15,6 @@ public interface AttributeValidationPolicy {
* @param buffer
* @return LdapAttribute representing the attribute parsed.
*/
public Attribute parse(String buffer);
Attribute parse(String buffer);
}

View File

@@ -1,15 +1,3 @@
/**
* Attribute validation policy
*
* Meets the standards imposed by RFC 2849 for the "LDAP Data Interchange Format (LDIF)
* - Technical Specification".
*
* Special attention is called to URL support: RFC 2849 requires that
* LDIFs support URLs as defined in 1738; however, RFC 1738 has been updated by several RFCs including
* RFC 1808, RFC 2396, and RFC 3986 (which obsoleted the formers). Unsupported features of this
* implementation of URL identification include query strings and fragments in HTTP URLs.
*
*/
package org.springframework.ldap.ldif.support;
import java.io.IOException;
@@ -24,16 +12,23 @@ import javax.naming.directory.Attribute;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.ldap.core.LdapAttribute;
import org.springframework.ldap.ldif.InvalidAttributeFormatException;
import org.springframework.ldap.ldif.LdapAttribute;
import sun.misc.BASE64Decoder;
/**
* Ensures the buffer represents a valid attribute as defined by RFC2849.
*
* Meets the standards imposed by RFC 2849 for the "LDAP Data Interchange Format (LDIF)
* - Technical Specification".
*
* Special attention is called to URL support: RFC 2849 requires that
* LDIFs support URLs as defined in 1738; however, RFC 1738 has been updated by several RFCs including
* RFC 1808, RFC 2396, and RFC 3986 (which obsoleted the formers). Unsupported features of this
* implementation of URL identification include query strings and fragments in HTTP URLs.
*
* @author Keith Barlow
*
*/
@SuppressWarnings("unused")
public class DefaultAttributeValidationPolicy implements AttributeValidationPolicy {

View File

@@ -1,6 +1,3 @@
/**
* Policy object for enforcing LDIF record separation rules. Designed explicitly for use in LDIFParser.
*/
package org.springframework.ldap.ldif.support;
import org.apache.commons.lang.StringUtils;
@@ -8,14 +5,14 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* This default separator policy should really not be required to be
* replaced but it is modular just in case.
* Policy object for enforcing LDIF record separation rules. Designed explicitly
* for use in LdifParser. This default separator policy should really not be
* required to be replaced but it is modular just in case.
* <p>
* This class applies the separation policy prescribed in RFC2849
* for LDIF files and identifies the line type from the input.
* This class applies the separation policy prescribed in RFC2849 for LDIF files
* and identifies the line type from the input.
*
* @author Keith Barlow
*
*/
public class SeparatorPolicy {

View File

@@ -3,8 +3,8 @@ package org.springframework.ldap.schema;
import javax.naming.NamingException;
import org.springframework.ldap.core.DistinguishedName;
import org.springframework.ldap.core.LdapAttributes;
import org.springframework.ldap.core.LdapRdn;
import org.springframework.ldap.ldif.LdapAttributes;
import sun.misc.BASE64Encoder;
@@ -20,7 +20,6 @@ import sun.misc.BASE64Encoder;
* </ul>
*
* @author Keith Barlow
*
*/
public class DefaultSchemaSpecification implements Specification<LdapAttributes> {

View File

@@ -4,7 +4,7 @@ import javax.naming.NamingException;
/**
* The specification interface is implemented to declare rules that
* a record must conform to. The motiviation behind this class was
* a record must conform to. The motivation behind this class was
* to provide a mechanism to enable schema validations.
*
* @author Keith Barlow

View File

@@ -12,7 +12,7 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized.Parameters;
import org.junit.runners.Parameterized;
import org.springframework.ldap.ldif.LdapAttribute;
import org.springframework.ldap.core.LdapAttribute;
import org.springframework.ldap.ldif.support.DefaultAttributeValidationPolicy;
import sun.misc.BASE64Decoder;
@@ -23,7 +23,6 @@ import sun.misc.BASE64Decoder;
* the requirements for attribute values prescribed in RFC2849.
*
* @author Keith Barlow
*
*/
@RunWith(Parameterized.class)
public class DefaultAttributeValidationPolicyTest {

View File

@@ -10,39 +10,40 @@ import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.core.io.ClassPathResource;
import org.springframework.ldap.ldif.LdapAttributes;
import org.springframework.ldap.ldif.parser.LDIFParser;
import org.springframework.ldap.core.LdapAttributes;
import org.springframework.ldap.ldif.parser.LdifParser;
/**
* Unit test for LDIFParser.
* Unit test for LdifParser.
*
* Test results in complete end to end test of all LDIFParser functionality:
* 1.) Open a file
* 2.) Read lines and compose an attribute.
* 3.) Parse the attribute and create a LdapAttribute object.
* 4.) Repeat until end of record (Identify end of record).
* 5.) Return a valid LdapAttributes object.
* 6.) Close file upon completion.
* Test results in complete end to end test of all LdifParser functionality:
* <ol>
* <li>Open a file
* <li>Read lines and compose an attribute.
* <li>Parse the attribute and create a LdapAttribute object.
* <li>Repeat until end of record (Identify end of record).
* <li>Return a valid LdapAttributes object.
* <li>Close file upon completion.
* </ol>
*
* Provided test file is comprised of sample LDIFs from RFC2849 and exhausts the full range of
* the functionality prescribed by RFC2849 for the LDAP Data Interchange Format (LDIF).
*
* @author Keith Barlow
*
*/
public class LDIFParserTest {
public class LdifParserTest {
private static Log log = LogFactory.getLog(LDIFParserTest.class);
private static Log log = LogFactory.getLog(LdifParserTest.class);
private LDIFParser parser;
private LdifParser parser;
/**
* Default constructor: loads a preselected resource with sample LDIF entries.
* Each entry is parsed and checked for a DN and objectclass. Output is printed for visual verification
* of LDIF correctness.
*/
public LDIFParserTest() {
parser = new LDIFParser(new ClassPathResource("test.ldif"));
public LdifParserTest() {
parser = new LdifParser(new ClassPathResource("test.ldif"));
}
/**