Performed deletes according to Jasper's instructions.
This commit is contained in:
@@ -4,7 +4,6 @@
|
||||
<configExtension>xml</configExtension>
|
||||
</configExtensions>
|
||||
<configs>
|
||||
<config>src/itest/java/conf/beans.xml</config>
|
||||
</configs>
|
||||
<configSets>
|
||||
<configSet>
|
||||
@@ -12,7 +11,6 @@
|
||||
<allowBeanDefinitionOverriding>true</allowBeanDefinitionOverriding>
|
||||
<incomplete>false</incomplete>
|
||||
<configs>
|
||||
<config>src/itest/java/conf/beans.xml</config>
|
||||
</configs>
|
||||
</configSet>
|
||||
</configSets>
|
||||
|
||||
@@ -1,84 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!--
|
||||
This context automatically starts the Apache Directory Server
|
||||
and sets up the test data
|
||||
-->
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
|
||||
<!-- JNDI environment variable -->
|
||||
<bean id="environment"
|
||||
class="org.springframework.beans.factory.config.PropertiesFactoryBean">
|
||||
<property name="properties">
|
||||
<props>
|
||||
<prop key="java.naming.security.authentication">
|
||||
simple
|
||||
</prop>
|
||||
<prop key="java.naming.security.principal">
|
||||
${userDn}
|
||||
</prop>
|
||||
<prop key="java.naming.security.credentials">
|
||||
${password}
|
||||
</prop>
|
||||
</props>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<!--
|
||||
Note the non-standard port, in order to leave 389 unused, thus
|
||||
making it easier for the integration tests requiring OpenLDAP.
|
||||
-->
|
||||
<bean id="configuration" class="org.apache.directory.server.configuration.MutableServerStartupConfiguration">
|
||||
<property name="ldapPort" value="3900" />
|
||||
<property name="contextPartitionConfigurations">
|
||||
<set>
|
||||
<ref bean="jaywayPartitionConfiguration"/>
|
||||
</set>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="jaywayPartitionConfiguration"
|
||||
class="org.apache.directory.server.core.partition.impl.btree.MutableBTreePartitionConfiguration">
|
||||
<property name="name" value="example" />
|
||||
<property name="suffix" value="dc=example,dc=com" />
|
||||
<property name="contextEntry">
|
||||
<value>
|
||||
objectClass: top
|
||||
objectClass: domain
|
||||
objectClass: extensibleObject
|
||||
dc: example
|
||||
</value>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="configEnvHelper" class="org.springframework.ldap.ConfigEnvHelper">
|
||||
<constructor-arg ref="environment" />
|
||||
<constructor-arg ref="configuration" />
|
||||
</bean>
|
||||
|
||||
<bean name="serverContext" class="javax.naming.InitialContext">
|
||||
<constructor-arg>
|
||||
<bean class="org.springframework.beans.factory.config.PropertyPathFactoryBean">
|
||||
<property name="targetObject" ref="configEnvHelper" />
|
||||
<property name="propertyPath" value="env" />
|
||||
</bean>
|
||||
</constructor-arg>
|
||||
</bean>
|
||||
|
||||
<bean name="ldapServerManager" class="org.springframework.ldap.LdapServerManager">
|
||||
<property name="contextSource" ref="contextSource" />
|
||||
</bean>
|
||||
|
||||
<!-- Custom editors required to launch ApacheDS -->
|
||||
<bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
|
||||
<property name="customEditors">
|
||||
<map>
|
||||
<entry key="javax.naming.directory.Attributes">
|
||||
<bean class="org.apache.directory.server.core.configuration.AttributesPropertyEditor"/>
|
||||
</entry>
|
||||
</map>
|
||||
</property>
|
||||
</bean>
|
||||
</beans>
|
||||
@@ -1,43 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
|
||||
<beans>
|
||||
|
||||
<import resource="classpath:/conf/apacheDsContext.xml"/>
|
||||
|
||||
<bean id="placeholderConfig"
|
||||
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
|
||||
<property name="location" value="classpath:/conf/ldap.properties" />
|
||||
</bean>
|
||||
|
||||
<bean id="contextSource" class="org.springframework.ldap.core.support.LdapContextSource" >
|
||||
<property name="urls" value="${urls}" />
|
||||
<property name="userDn" value="${userDn}" />
|
||||
<property name="password" value="${password}" />
|
||||
<property name="base" value="${base}" />
|
||||
<property name="dirObjectFactory" value="org.springframework.ldap.core.support.DefaultDirObjectFactory" />
|
||||
</bean>
|
||||
|
||||
<bean id="ldapTemplate" singleton="true" class="org.springframework.ldap.core.LdapTemplate">
|
||||
<constructor-arg ref="contextSource"/>
|
||||
</bean>
|
||||
|
||||
<bean id="typeConverter" singleton="true" class="org.springframework.ldap.odm.attributetypes.LdapTypeConverter"/>
|
||||
|
||||
<bean id="referencedEntryEditorFactory" singleton="true"
|
||||
class="org.springframework.ldap.odm.attributetypes.ReferencedEntryEditorFactory">
|
||||
<constructor-arg value="${base}" />
|
||||
<constructor-arg ref="ldapTemplate"/>
|
||||
</bean>
|
||||
|
||||
<bean id="ctxMapperFactory" singleton="true"
|
||||
class="org.springframework.ldap.odm.mapping.ObjectDirectoryMapperFactory">
|
||||
<constructor-arg ref="typeConverter"/>
|
||||
<constructor-arg ref="referencedEntryEditorFactory"/>
|
||||
</bean>
|
||||
|
||||
<bean id="ldapDao" singleton="true" class="org.springframework.ldap.odm.dao.LdapDaoImpl">
|
||||
<constructor-arg ref="ldapTemplate"/>
|
||||
<constructor-arg ref="ctxMapperFactory"/>
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
@@ -1,4 +0,0 @@
|
||||
urls=ldap://127.0.0.1:3900
|
||||
userDn=uid=admin,ou=system
|
||||
password=secret
|
||||
base=dc=example,dc=com
|
||||
@@ -1,50 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE log4j:configuration SYSTEM "http://logging.apache.org/log4j/docs/api/org/apache/log4j/xml/log4j.dtd">
|
||||
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
|
||||
|
||||
<appender name="console" class="org.apache.log4j.ConsoleAppender">
|
||||
<layout class="org.apache.log4j.PatternLayout">
|
||||
<!-- <param name="ConversionPattern" value="[%d{dd/MMM/yyy:HH:mm:ss:SS}] [%t] [%x] %-5p %c{1} - %m %n"/> -->
|
||||
<param name="ConversionPattern" value="[%t] [%x] %-5p %c{1} - %m %n"/>
|
||||
</layout>
|
||||
</appender>
|
||||
|
||||
<appender name="file" class="org.apache.log4j.FileAppender">
|
||||
<param name="file" value="odm.log"/>
|
||||
<layout class="org.apache.log4j.PatternLayout">
|
||||
<param name="ConversionPattern" value="[%d{dd/MMM/yyy:HH:mm:ss:SS}] [%t] [%x] %-5p %c{1} - %m %n"/>
|
||||
</layout>
|
||||
</appender>
|
||||
|
||||
<logger name="org.springframework.beans">
|
||||
<level value="warn"/>
|
||||
<appender-ref ref="console"/>
|
||||
</logger>
|
||||
|
||||
<logger name="org.springframework.context">
|
||||
<level value="warn"/>
|
||||
<appender-ref ref="console"/>
|
||||
</logger>
|
||||
|
||||
<logger name="org.apache.directory">
|
||||
<level value="error"/>
|
||||
<appender-ref ref="console"/>
|
||||
</logger>
|
||||
|
||||
<logger name="org.springframework.core">
|
||||
<level value="warn"/>
|
||||
<appender-ref ref="console"/>
|
||||
</logger>
|
||||
|
||||
<logger name="org.springframework.ldap.core">
|
||||
<level value="info"/>
|
||||
<appender-ref ref="console"/>
|
||||
</logger>
|
||||
|
||||
<logger name="org.springframework.ldap.odm">
|
||||
<level value="debug"/>
|
||||
<appender-ref ref="console"/>
|
||||
</logger>
|
||||
|
||||
|
||||
</log4j:configuration>
|
||||
@@ -1,19 +0,0 @@
|
||||
dn: ou=people,dc=example,dc=com
|
||||
objectclass: top
|
||||
objectclass: organizationalUnit
|
||||
ou: people
|
||||
|
||||
dn: ou=roles,dc=example,dc=com
|
||||
objectclass: top
|
||||
objectclass: organizationalUnit
|
||||
ou: roles
|
||||
|
||||
dn: cn=webUser,ou=roles,dc=example,dc=com
|
||||
objectclass: top
|
||||
objectclass: organizationalRole
|
||||
cn: webUser
|
||||
description: Everyday site visitor
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
dn: ou=people,dc=example,dc=com
|
||||
objectclass: top
|
||||
objectclass: organizationalUnit
|
||||
ou: people
|
||||
|
||||
dn: ou=roles,dc=example,dc=com
|
||||
objectclass: top
|
||||
objectclass: organizationalUnit
|
||||
ou: roles
|
||||
@@ -1,349 +0,0 @@
|
||||
/*
|
||||
* Copyright 2006 by Majitek. All Rights Reserved.
|
||||
*
|
||||
* This software is the proprietary information of Majitek. Use is subject to license terms.
|
||||
*/
|
||||
package org.springframework.ldap.odm.contextmapping;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.naming.Name;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.ldap.core.DirContextAdapter;
|
||||
import org.springframework.ldap.core.DistinguishedName;
|
||||
import org.springframework.ldap.odm.annotations.DirAttribute;
|
||||
import org.springframework.ldap.odm.annotations.NamingAttribute;
|
||||
import org.springframework.ldap.odm.annotations.NamingSuffix;
|
||||
import org.springframework.ldap.odm.annotations.ObjectClasses;
|
||||
import org.springframework.ldap.odm.attributetypes.LdapTypeConverter;
|
||||
import org.springframework.ldap.odm.attributetypes.ReferencedEntryEditorFactory;
|
||||
import org.springframework.ldap.odm.contextmapping.exception.ContextMapperException;
|
||||
import org.springframework.ldap.odm.entity.MockEntity;
|
||||
import org.springframework.test.AbstractDependencyInjectionSpringContextTests;
|
||||
import org.testng.Assert;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
public class AnnotatedClassContextMapperTest extends
|
||||
AbstractDependencyInjectionSpringContextTests {
|
||||
private static final Log LOGGER = LogFactory
|
||||
.getLog(AnnotatedClassContextMapperTest.class);
|
||||
|
||||
private LdapTypeConverter typeConverter;
|
||||
|
||||
private ReferencedEntryEditorFactory refEditorFactory;
|
||||
|
||||
public void setRefEditorFactory(
|
||||
ReferencedEntryEditorFactory refEditorFactory) {
|
||||
this.refEditorFactory = refEditorFactory;
|
||||
}
|
||||
|
||||
public void setTypeConverter(LdapTypeConverter typeConverter) {
|
||||
this.typeConverter = typeConverter;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String[] getConfigLocations() {
|
||||
return new String[] { "conf/beans.xml" };
|
||||
}
|
||||
|
||||
public void testMapsDirectoryAttributesToBeanProperties() {
|
||||
try {
|
||||
AnnotatedClassContextMapper contextMapper = new AnnotatedClassContextMapper(
|
||||
MockEntity.class, typeConverter, refEditorFactory);
|
||||
ContextMap contextMap = contextMapper.getContextMap();
|
||||
Assert.assertEquals("cn", contextMap.attributeNameFor("Name"),
|
||||
"Name mapping not as expected");
|
||||
Assert.assertEquals("mail", contextMap.attributeNameFor("Mail"),
|
||||
"Mail mapping not as expected");
|
||||
Assert.assertEquals("addr", contextMap.attributeNameFor("Address"),
|
||||
"Address mapping not as expected");
|
||||
Assert.assertEquals("userpassword", contextMap
|
||||
.attributeNameFor("Password"),
|
||||
"Password mapping not as expected");
|
||||
Assert.assertEquals("desc", contextMap
|
||||
.attributeNameFor("Description"),
|
||||
"Description mapping not as expected");
|
||||
} catch (ContextMapperException e) {
|
||||
LOGGER.debug(e.getMessage());
|
||||
Assert.fail(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
public void testReturnsCorrectNamingAttribute() {
|
||||
try {
|
||||
AnnotatedClassContextMapper contextMapper = new AnnotatedClassContextMapper(
|
||||
MockEntity.class, typeConverter, refEditorFactory);
|
||||
Assert.assertEquals("cn", contextMapper.getNamingAttribute(),
|
||||
"Context mapper naming attribute not as expected");
|
||||
|
||||
} catch (ContextMapperException e) {
|
||||
LOGGER.debug(e.getMessage());
|
||||
Assert.fail(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
public void testReturnsCorrectObjectClasses() {
|
||||
try {
|
||||
AnnotatedClassContextMapper contextMapper = new AnnotatedClassContextMapper(
|
||||
MockEntity.class, typeConverter, refEditorFactory);
|
||||
Assert.assertEquals(new String[] { "top", "person",
|
||||
"organizationalPerson", "inetorgperson" }, contextMapper
|
||||
.getObjectClasses(),
|
||||
"Context mapper naming attribute not as expected");
|
||||
|
||||
} catch (ContextMapperException e) {
|
||||
LOGGER.debug(e.getMessage());
|
||||
Assert.fail(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void testBuildDn() {
|
||||
try {
|
||||
AnnotatedClassContextMapper contextMapper = new AnnotatedClassContextMapper(
|
||||
MockEntity.class, typeConverter, refEditorFactory);
|
||||
MockEntity entity = new MockEntity();
|
||||
entity.setName("Mr Bean");
|
||||
entity.setAddress("Somewhere in england");
|
||||
entity.setDescription(new String[] { "The quick brown fox jumped",
|
||||
"over the lazy dog" });
|
||||
Name dn = contextMapper.buildDn(entity);
|
||||
Assert.assertEquals("cn=Mr Bean, ou=people, dc=example, dc=com", dn
|
||||
.toString(), "dn not as expected");
|
||||
|
||||
} catch (ContextMapperException e) {
|
||||
LOGGER.debug(e.getMessage());
|
||||
Assert.fail(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void testMapToContext() {
|
||||
try {
|
||||
AnnotatedClassContextMapper contextMapper = new AnnotatedClassContextMapper(
|
||||
MockEntity.class, typeConverter, refEditorFactory);
|
||||
MockEntity entity = new MockEntity();
|
||||
entity.setName("Mr Bean");
|
||||
entity.setMail("bean@bean.com");
|
||||
entity.setAddress("Somewhere in england");
|
||||
entity.setPassword("fred".getBytes());
|
||||
entity.setDescription(new String[] { "The quick brown fox jumped",
|
||||
"over the lazy dog" });
|
||||
entity.setAcceptEmails(false);
|
||||
entity.setResetLogin(new Date(1L));
|
||||
entity.setCreator(new DistinguishedName(
|
||||
"uid=amAdmin,ou=people,dc=myretsu,dc=com"));
|
||||
entity.setFailedLogins(3);
|
||||
DirContextAdapter ctxAdapter = new DirContextAdapter();
|
||||
contextMapper.mapToContext(entity, ctxAdapter);
|
||||
|
||||
Assert.assertEquals("Mr Bean", ctxAdapter.getStringAttribute("cn"),
|
||||
"Name mapping not as expected");
|
||||
Assert
|
||||
.assertEquals("bean@bean.com", ctxAdapter
|
||||
.getStringAttribute("mail"),
|
||||
"Mail mapping not as expected");
|
||||
Assert.assertEquals("Somewhere in england", ctxAdapter
|
||||
.getObjectAttribute("addr"),
|
||||
"Address mapping not as expected");
|
||||
Assert.assertEquals("fred", new String((byte[]) ctxAdapter
|
||||
.getObjectAttribute("userpassword")),
|
||||
"Password mapping not as expected");
|
||||
Assert.assertEquals("The quick brown fox jumped", ctxAdapter
|
||||
.getStringAttributes("desc")[0],
|
||||
"Description mapping not as expected");
|
||||
Assert.assertEquals("false", ctxAdapter
|
||||
.getStringAttribute("acceptemails"),
|
||||
"AcceptEmails mapping not as expected");
|
||||
Assert.assertEquals("19700101100000.1", ctxAdapter
|
||||
.getStringAttribute("loginresettime"),
|
||||
"ResetLogin mapping not as expected");
|
||||
Assert.assertEquals("3", ctxAdapter
|
||||
.getStringAttribute("failedlogins"),
|
||||
"FailedLogins mapping not as expected");
|
||||
Assert.assertEquals("uid=amAdmin, ou=people, dc=myretsu, dc=com",
|
||||
ctxAdapter.getStringAttribute("creatorname"),
|
||||
"Creator mapping not as expected");
|
||||
} catch (ContextMapperException e) {
|
||||
LOGGER.debug(e.getMessage());
|
||||
Assert.fail(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
public void testMapFromContext() throws ContextMapperException {
|
||||
AnnotatedClassContextMapper contextMapper = new AnnotatedClassContextMapper(
|
||||
MockEntity.class, typeConverter, refEditorFactory);
|
||||
DirContextAdapter ctxAdapter = new DirContextAdapter();
|
||||
ctxAdapter.setAttributeValue("cn", "Mr Bean");
|
||||
ctxAdapter.setAttributeValue("mail", "bean@bean.com");
|
||||
ctxAdapter.setAttributeValue("addr", "Somewhere in england");
|
||||
ctxAdapter.setAttributeValue("userpassword", "fred".getBytes());
|
||||
ctxAdapter
|
||||
.setAttributeValues("desc", new String[] { "elem1", "elem2" });
|
||||
ctxAdapter.setAttributeValue("userpassword", "fred".getBytes());
|
||||
ctxAdapter.setAttributeValue("acceptemails", "true");
|
||||
ctxAdapter.setAttributeValue("loginresettime", "19700101100000.1");
|
||||
ctxAdapter.setAttributeValue("failedlogins", "3");
|
||||
ctxAdapter.setAttributeValue("creatorname",
|
||||
"uid=amAdmin,ou=people,dc=myretsu,dc=com");
|
||||
|
||||
MockEntity entity = (MockEntity) contextMapper
|
||||
.mapFromContext(ctxAdapter);
|
||||
Assert.assertEquals(entity.getMail(), "bean@bean.com",
|
||||
"The mocked entity should match what has been mapped");
|
||||
Assert.assertEquals("Mr Bean", entity.getName(),
|
||||
"Name mapping not as expected");
|
||||
Assert.assertEquals(entity.getMail(), "bean@bean.com",
|
||||
"Mail mapping not as expected");
|
||||
Assert.assertEquals(entity.getAddress(), "Somewhere in england",
|
||||
"Address mapping not as expected");
|
||||
Assert.assertEquals("fred", new String(entity.getPassword()),
|
||||
"Password mapping not as expected");
|
||||
Assert.assertEquals("elem1", entity.getDescription()[0],
|
||||
"Description mapping not as expected");
|
||||
Assert.assertEquals(Boolean.TRUE, entity.getAcceptEmails(),
|
||||
"AcceptEmails mapping not as expected");
|
||||
Assert.assertEquals(new Date(1L), entity.getResetLogin(),
|
||||
"ResetLogin mapping not as expected");
|
||||
Assert.assertEquals(new Integer(3), entity.getFailedLogins(),
|
||||
"FailedLogin mapping not as expected");
|
||||
Assert.assertEquals(new DistinguishedName(
|
||||
"uid=amAdmin,ou=people,dc=myretsu,dc=com"),
|
||||
entity.getCreator(), "Creator mapping not as expected");
|
||||
|
||||
}
|
||||
|
||||
@Test(groups = { "AnnotatedClassContextMapper" }, expectedExceptions = ContextMapperException.class)
|
||||
public void throwsExceptionWhenNamingSuffixHasSyntaxError()
|
||||
throws ContextMapperException {
|
||||
AnnotatedClassContextMapper contextMapper = new AnnotatedClassContextMapper(
|
||||
MockModelNamingSuffixSyntaxError.class, typeConverter,
|
||||
refEditorFactory);
|
||||
Assert
|
||||
.fail("AnnotatedClassContextMapper should throw an exception when naming path annotation syntax is "
|
||||
+ "incorrect.");
|
||||
}
|
||||
|
||||
@Test(groups = { "AnnotatedClassContextMapper" }, expectedExceptions = ContextMapperException.class)
|
||||
public void throwsExceptionWhenNamingSuffixNotInSeparateElements()
|
||||
throws ContextMapperException {
|
||||
AnnotatedClassContextMapper contextMapper = new AnnotatedClassContextMapper(
|
||||
MockModelNamingSuffixNotInSeparateElements.class,
|
||||
typeConverter, refEditorFactory);
|
||||
Assert
|
||||
.fail("AnnotatedClassContextMapper should throw an exception when naming path annotation syntax is "
|
||||
+ "incorrect.");
|
||||
}
|
||||
|
||||
@Test(groups = { "AnnotatedClassContextMapper" }, expectedExceptions = ContextMapperException.class)
|
||||
public void throwsExceptionWhenModelObjectMissingGetterOrSetter()
|
||||
throws ContextMapperException {
|
||||
AnnotatedClassContextMapper contextMapper = new AnnotatedClassContextMapper(
|
||||
MockModelMissingSetter.class, typeConverter, refEditorFactory);
|
||||
Assert.fail("Should've thrown exception due to missing getter/setter");
|
||||
}
|
||||
|
||||
@Test(groups = { "AnnotatedClassContextMapper" })
|
||||
public void throwsExceptionWhenBeanPropertyNotAValidTranslationType() {
|
||||
try {
|
||||
AnnotatedClassContextMapper contextMapper = new AnnotatedClassContextMapper(
|
||||
MockModelInvalidTranslationType.class, typeConverter,
|
||||
refEditorFactory);
|
||||
Assert
|
||||
.fail("Should've thrown exception due to missing getter/setter");
|
||||
} catch (ContextMapperException e) {
|
||||
Assert
|
||||
.assertTrue(e
|
||||
.getMessage()
|
||||
.contains(
|
||||
"MockModelInvalidTranslationType.getMap() has invalid return type"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@NamingAttribute("cn")
|
||||
@NamingSuffix( { "ou=people", "dc=example", "dc=com" })
|
||||
@ObjectClasses( { "top", "person", "organizationalPerson", "inetorgperson" })
|
||||
public class MockModelMissingSetter {
|
||||
@DirAttribute("cn")
|
||||
private String name;
|
||||
|
||||
@DirAttribute("addr")
|
||||
private String address;
|
||||
|
||||
@DirAttribute("mail")
|
||||
private String mail;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
public String getMail() {
|
||||
return mail;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public void setAddress(String address) {
|
||||
this.address = address;
|
||||
}
|
||||
}
|
||||
|
||||
@NamingAttribute("cn")
|
||||
@NamingSuffix( { "ou=people", "dc=example", "dc=com" })
|
||||
@ObjectClasses( { "top", "person", "organizationalPerson", "inetorgperson" })
|
||||
public class MockModelBadMethodName {
|
||||
|
||||
@DirAttribute("cn")
|
||||
private String name;
|
||||
|
||||
@DirAttribute("addr")
|
||||
private String address;
|
||||
|
||||
public String zzzName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getAddress() {
|
||||
return address;
|
||||
}
|
||||
}
|
||||
|
||||
@NamingAttribute("cn")
|
||||
@NamingSuffix( { "ou=people,dc=example ,dc=com" })
|
||||
@ObjectClasses( { "top", "person", "organizationalPerson", "inetorgperson" })
|
||||
public class MockModelNamingSuffixNotInSeparateElements {
|
||||
}
|
||||
|
||||
@NamingAttribute("cn")
|
||||
@NamingSuffix( { "ou=people", "dc<example", "dc=com" })
|
||||
@ObjectClasses( { "top", "person", "organizationalPerson", "inetorgperson" })
|
||||
public class MockModelNamingSuffixSyntaxError {
|
||||
|
||||
}
|
||||
|
||||
@NamingAttribute("cn")
|
||||
@NamingSuffix( { "ou=people", "dc=example", "dc=com" })
|
||||
@ObjectClasses( { "top", "person", "organizationalPerson", "inetorgperson" })
|
||||
public class MockModelInvalidTranslationType {
|
||||
@DirAttribute("fred")
|
||||
private Map map;
|
||||
|
||||
public Map getMap() {
|
||||
return map;
|
||||
}
|
||||
|
||||
public void setMap(Map map) {
|
||||
this.map = map;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,408 +0,0 @@
|
||||
/*
|
||||
* Copyright 2006 by Majitek. All Rights Reserved.
|
||||
*
|
||||
* This software is the proprietary information of Majitek. Use is subject to license terms.
|
||||
*/
|
||||
package org.springframework.ldap.odm.contextmapping;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.ldap.core.DirContextAdapter;
|
||||
import org.springframework.ldap.core.DistinguishedName;
|
||||
import org.springframework.ldap.odm.annotations.DirAttribute;
|
||||
import org.springframework.ldap.odm.annotations.NamingAttribute;
|
||||
import org.springframework.ldap.odm.annotations.NamingSuffix;
|
||||
import org.springframework.ldap.odm.annotations.ObjectClasses;
|
||||
import org.springframework.ldap.odm.attributetypes.LdapTypeConverter;
|
||||
import org.springframework.ldap.odm.attributetypes.ReferencedEntryEditorFactory;
|
||||
import org.springframework.ldap.odm.contextmapping.exception.ContextMapperException;
|
||||
import org.springframework.ldap.odm.entity.MockEntity;
|
||||
import org.springframework.test.AbstractDependencyInjectionSpringContextTests;
|
||||
import org.testng.Assert;
|
||||
|
||||
import javax.naming.Name;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
public class AnnotationObjectDirectoryMapperTest extends
|
||||
AbstractDependencyInjectionSpringContextTests
|
||||
{
|
||||
private static final Log LOGGER = LogFactory
|
||||
.getLog(AnnotationObjectDirectoryMapperTest.class);
|
||||
|
||||
private LdapTypeConverter typeConverter;
|
||||
|
||||
private ReferencedEntryEditorFactory refEditorFactory;
|
||||
|
||||
public void setRefEditorFactory(
|
||||
ReferencedEntryEditorFactory refEditorFactory)
|
||||
{
|
||||
this.refEditorFactory = refEditorFactory;
|
||||
}
|
||||
|
||||
public void setTypeConverter(LdapTypeConverter typeConverter)
|
||||
{
|
||||
this.typeConverter = typeConverter;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String[] getConfigLocations()
|
||||
{
|
||||
return new String[]{"conf/beans.xml"};
|
||||
}
|
||||
|
||||
public void testMapsDirectoryAttributesToBeanProperties()
|
||||
{
|
||||
try
|
||||
{
|
||||
AnnotationObjectDirectoryMapper contextMapper = new AnnotationObjectDirectoryMapper(
|
||||
MockEntity.class, typeConverter, refEditorFactory);
|
||||
ContextMap contextMap = contextMapper.getContextMap();
|
||||
Assert.assertEquals("cn", contextMap.attributeNameFor("Name"),
|
||||
"Name mapping not as expected");
|
||||
Assert.assertEquals("mail", contextMap.attributeNameFor("Mail"),
|
||||
"Mail mapping not as expected");
|
||||
Assert.assertEquals("addr", contextMap.attributeNameFor("Address"),
|
||||
"Address mapping not as expected");
|
||||
Assert.assertEquals("userpassword", contextMap
|
||||
.attributeNameFor("Password"),
|
||||
"Password mapping not as expected");
|
||||
Assert.assertEquals("desc", contextMap
|
||||
.attributeNameFor("Description"),
|
||||
"Description mapping not as expected");
|
||||
}
|
||||
catch (ContextMapperException e)
|
||||
{
|
||||
LOGGER.debug(e.getMessage());
|
||||
Assert.fail(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
public void testReturnsCorrectNamingAttribute()
|
||||
{
|
||||
try
|
||||
{
|
||||
AnnotationObjectDirectoryMapper contextMapper = new AnnotationObjectDirectoryMapper(
|
||||
MockEntity.class, typeConverter, refEditorFactory);
|
||||
Assert.assertEquals("cn", contextMapper.getNamingAttribute(),
|
||||
"Context mapper naming attribute not as expected");
|
||||
|
||||
}
|
||||
catch (ContextMapperException e)
|
||||
{
|
||||
LOGGER.debug(e.getMessage());
|
||||
Assert.fail(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
public void testReturnsCorrectObjectClasses()
|
||||
{
|
||||
try
|
||||
{
|
||||
AnnotationObjectDirectoryMapper contextMapper = new AnnotationObjectDirectoryMapper(
|
||||
MockEntity.class, typeConverter, refEditorFactory);
|
||||
Assert.assertEquals(new String[]{"top", "person",
|
||||
"organizationalPerson", "inetorgperson"}, contextMapper
|
||||
.getObjectClasses(),
|
||||
"Context mapper naming attribute not as expected");
|
||||
|
||||
}
|
||||
catch (ContextMapperException e)
|
||||
{
|
||||
LOGGER.debug(e.getMessage());
|
||||
Assert.fail(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void testBuildDn()
|
||||
{
|
||||
try
|
||||
{
|
||||
AnnotationObjectDirectoryMapper contextMapper = new AnnotationObjectDirectoryMapper(
|
||||
MockEntity.class, typeConverter, refEditorFactory);
|
||||
MockEntity entity = new MockEntity();
|
||||
entity.setName("Mr Bean");
|
||||
entity.setAddress("Somewhere in england");
|
||||
entity.setDescription(new String[]{"The quick brown fox jumped",
|
||||
"over the lazy dog"});
|
||||
Name dn = contextMapper.buildDn(entity);
|
||||
Assert.assertEquals("cn=Mr Bean, ou=people, dc=example, dc=com", dn
|
||||
.toString(), "dn not as expected");
|
||||
|
||||
}
|
||||
catch (ContextMapperException e)
|
||||
{
|
||||
LOGGER.debug(e.getMessage());
|
||||
Assert.fail(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void testMapToContext()
|
||||
{
|
||||
try
|
||||
{
|
||||
AnnotationObjectDirectoryMapper contextMapper = new AnnotationObjectDirectoryMapper(
|
||||
MockEntity.class, typeConverter, refEditorFactory);
|
||||
MockEntity entity = new MockEntity();
|
||||
entity.setName("Mr Bean");
|
||||
entity.setMail("bean@bean.com");
|
||||
entity.setAddress("Somewhere in england");
|
||||
entity.setPassword("fred".getBytes());
|
||||
entity.setDescription(new String[]{"The quick brown fox jumped",
|
||||
"over the lazy dog"});
|
||||
entity.setAcceptEmails(false);
|
||||
entity.setResetLogin(new Date(1L));
|
||||
entity.setCreator(new DistinguishedName(
|
||||
"uid=amAdmin,ou=people,dc=myretsu,dc=com"));
|
||||
entity.setFailedLogins(3);
|
||||
DirContextAdapter ctxAdapter = new DirContextAdapter();
|
||||
contextMapper.mapToContext(entity, ctxAdapter);
|
||||
|
||||
Assert.assertEquals("Mr Bean", ctxAdapter.getStringAttribute("cn"),
|
||||
"Name mapping not as expected");
|
||||
Assert
|
||||
.assertEquals("bean@bean.com", ctxAdapter
|
||||
.getStringAttribute("mail"),
|
||||
"Mail mapping not as expected");
|
||||
Assert.assertEquals("Somewhere in england", ctxAdapter
|
||||
.getObjectAttribute("addr"),
|
||||
"Address mapping not as expected");
|
||||
Assert.assertEquals("fred", new String((byte[]) ctxAdapter
|
||||
.getObjectAttribute("userpassword")),
|
||||
"Password mapping not as expected");
|
||||
Assert.assertEquals("The quick brown fox jumped", ctxAdapter
|
||||
.getStringAttributes("desc")[0],
|
||||
"Description mapping not as expected");
|
||||
Assert.assertEquals("false", ctxAdapter
|
||||
.getStringAttribute("acceptemails"),
|
||||
"AcceptEmails mapping not as expected");
|
||||
Assert.assertEquals("19700101100000.1", ctxAdapter
|
||||
.getStringAttribute("loginresettime"),
|
||||
"ResetLogin mapping not as expected");
|
||||
Assert.assertEquals("3", ctxAdapter
|
||||
.getStringAttribute("failedlogins"),
|
||||
"FailedLogins mapping not as expected");
|
||||
Assert.assertEquals("uid=amAdmin, ou=people, dc=myretsu, dc=com",
|
||||
ctxAdapter.getStringAttribute("creatorname"),
|
||||
"Creator mapping not as expected");
|
||||
}
|
||||
catch (ContextMapperException e)
|
||||
{
|
||||
LOGGER.debug(e.getMessage());
|
||||
Assert.fail(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
public void testMapFromContext() throws ContextMapperException
|
||||
{
|
||||
AnnotationObjectDirectoryMapper contextMapper = new AnnotationObjectDirectoryMapper(
|
||||
MockEntity.class, typeConverter, refEditorFactory);
|
||||
DirContextAdapter ctxAdapter = new DirContextAdapter();
|
||||
ctxAdapter.setAttributeValue("cn", "Mr Bean");
|
||||
ctxAdapter.setAttributeValue("mail", "bean@bean.com");
|
||||
ctxAdapter.setAttributeValue("addr", "Somewhere in england");
|
||||
ctxAdapter.setAttributeValue("userpassword", "fred".getBytes());
|
||||
ctxAdapter
|
||||
.setAttributeValues("desc", new String[]{"elem1", "elem2"});
|
||||
ctxAdapter.setAttributeValue("userpassword", "fred".getBytes());
|
||||
ctxAdapter.setAttributeValue("acceptemails", "true");
|
||||
ctxAdapter.setAttributeValue("loginresettime", "19700101100000.1");
|
||||
ctxAdapter.setAttributeValue("failedlogins", "3");
|
||||
ctxAdapter.setAttributeValue("creatorname",
|
||||
"uid=amAdmin,ou=people,dc=myretsu,dc=com");
|
||||
|
||||
MockEntity entity = (MockEntity) contextMapper
|
||||
.mapFromContext(ctxAdapter);
|
||||
Assert.assertEquals(entity.getMail(), "bean@bean.com",
|
||||
"The mocked entity should match what has been mapped");
|
||||
Assert.assertEquals("Mr Bean", entity.getName(),
|
||||
"Name mapping not as expected");
|
||||
Assert.assertEquals(entity.getMail(), "bean@bean.com",
|
||||
"Mail mapping not as expected");
|
||||
Assert.assertEquals(entity.getAddress(), "Somewhere in england",
|
||||
"Address mapping not as expected");
|
||||
Assert.assertEquals("fred", new String(entity.getPassword()),
|
||||
"Password mapping not as expected");
|
||||
Assert.assertEquals("elem1", entity.getDescription()[0],
|
||||
"Description mapping not as expected");
|
||||
Assert.assertEquals(Boolean.TRUE, entity.getAcceptEmails(),
|
||||
"AcceptEmails mapping not as expected");
|
||||
Assert.assertEquals(new Date(1L), entity.getResetLogin(),
|
||||
"ResetLogin mapping not as expected");
|
||||
Assert.assertEquals(new Integer(3), entity.getFailedLogins(),
|
||||
"FailedLogin mapping not as expected");
|
||||
Assert.assertEquals(new DistinguishedName(
|
||||
"uid=amAdmin,ou=people,dc=myretsu,dc=com"),
|
||||
entity.getCreator(), "Creator mapping not as expected");
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void testThrowsExceptionWhenNamingSuffixHasSyntaxError()
|
||||
{
|
||||
try
|
||||
{
|
||||
AnnotationObjectDirectoryMapper contextMapper = new AnnotationObjectDirectoryMapper(
|
||||
MockModelNamingSuffixSyntaxError.class, typeConverter,
|
||||
refEditorFactory);
|
||||
Assert.fail(
|
||||
"AnnotationObjectDirectoryMapper should throw an exception when naming " +
|
||||
"path annotation syntax is incorrect.");
|
||||
}
|
||||
catch (ContextMapperException e)
|
||||
{
|
||||
//pass
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void testThrowsExceptionWhenNamingSuffixNotInSeparateElements()
|
||||
{
|
||||
try
|
||||
{
|
||||
AnnotationObjectDirectoryMapper contextMapper = new AnnotationObjectDirectoryMapper(
|
||||
MockModelNamingSuffixNotInSeparateElements.class,
|
||||
typeConverter, refEditorFactory);
|
||||
Assert.fail("AnnotationObjectDirectoryMapper should throw an exception when naming" +
|
||||
" path annotation syntax is incorrect.");
|
||||
}
|
||||
catch (ContextMapperException e)
|
||||
{
|
||||
//pass
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void testThrowsExceptionWhenModelObjectMissingGetterOrSetter()
|
||||
{
|
||||
try
|
||||
{
|
||||
AnnotationObjectDirectoryMapper contextMapper = new AnnotationObjectDirectoryMapper(
|
||||
MockModelMissingSetter.class, typeConverter, refEditorFactory);
|
||||
Assert.fail("Should've thrown exception due to missing getter/setter");
|
||||
}
|
||||
catch (ContextMapperException e)
|
||||
{
|
||||
//pass
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void testThrowsExceptionWhenBeanPropertyNotAValidTranslationType()
|
||||
{
|
||||
try
|
||||
{
|
||||
AnnotationObjectDirectoryMapper contextMapper = new AnnotationObjectDirectoryMapper(
|
||||
MockModelInvalidTranslationType.class, typeConverter,
|
||||
refEditorFactory);
|
||||
Assert.fail("Should've thrown exception due to missing getter/setter");
|
||||
}
|
||||
catch (ContextMapperException e)
|
||||
{
|
||||
Assert.assertTrue(e.getMessage().contains(
|
||||
"MockModelInvalidTranslationType.getMap() has invalid return type"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@NamingAttribute("cn")
|
||||
@NamingSuffix({"ou=people", "dc=example", "dc=com"})
|
||||
@ObjectClasses({"top", "person", "organizationalPerson", "inetorgperson"})
|
||||
public class MockModelMissingSetter
|
||||
{
|
||||
@DirAttribute("cn")
|
||||
private String name;
|
||||
|
||||
@DirAttribute("addr")
|
||||
private String address;
|
||||
|
||||
@DirAttribute("mail")
|
||||
private String mail;
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getAddress()
|
||||
{
|
||||
return address;
|
||||
}
|
||||
|
||||
public String getMail()
|
||||
{
|
||||
return mail;
|
||||
}
|
||||
|
||||
public void setName(String name)
|
||||
{
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public void setAddress(String address)
|
||||
{
|
||||
this.address = address;
|
||||
}
|
||||
}
|
||||
|
||||
@NamingAttribute("cn")
|
||||
@NamingSuffix({"ou=people", "dc=example", "dc=com"})
|
||||
@ObjectClasses({"top", "person", "organizationalPerson", "inetorgperson"})
|
||||
public class MockModelBadMethodName
|
||||
{
|
||||
|
||||
@DirAttribute("cn")
|
||||
private String name;
|
||||
|
||||
@DirAttribute("addr")
|
||||
private String address;
|
||||
|
||||
public String zzzName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getAddress()
|
||||
{
|
||||
return address;
|
||||
}
|
||||
}
|
||||
|
||||
@NamingAttribute("cn")
|
||||
@NamingSuffix({"ou=people,dc=example ,dc=com"})
|
||||
@ObjectClasses({"top", "person", "organizationalPerson", "inetorgperson"})
|
||||
public class MockModelNamingSuffixNotInSeparateElements
|
||||
{
|
||||
}
|
||||
|
||||
@NamingAttribute("cn")
|
||||
@NamingSuffix({"ou=people", "dc<example", "dc=com"})
|
||||
@ObjectClasses({"top", "person", "organizationalPerson", "inetorgperson"})
|
||||
public class MockModelNamingSuffixSyntaxError
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@NamingAttribute("cn")
|
||||
@NamingSuffix({"ou=people", "dc=example", "dc=com"})
|
||||
@ObjectClasses({"top", "person", "organizationalPerson", "inetorgperson"})
|
||||
public class MockModelInvalidTranslationType
|
||||
{
|
||||
@DirAttribute("fred")
|
||||
private Map map;
|
||||
|
||||
public Map getMap()
|
||||
{
|
||||
return map;
|
||||
}
|
||||
|
||||
public void setMap(Map map)
|
||||
{
|
||||
this.map = map;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,138 +0,0 @@
|
||||
/*
|
||||
* Copyright 2006 by Majitek. All Rights Reserved.
|
||||
*
|
||||
* This software is the proprietary information of Majitek. Use is subject to license terms.
|
||||
*/
|
||||
package org.springframework.ldap.odm.entity;
|
||||
|
||||
import org.springframework.ldap.core.DistinguishedName;
|
||||
import org.springframework.ldap.odm.annotations.DirAttribute;
|
||||
import org.springframework.ldap.odm.annotations.NamingAttribute;
|
||||
import org.springframework.ldap.odm.annotations.NamingSuffix;
|
||||
import org.springframework.ldap.odm.annotations.ObjectClasses;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@NamingAttribute("cn")
|
||||
@NamingSuffix({"ou = people", "dc = example", "dc=com"})
|
||||
@ObjectClasses({"top", "person", "organizationalPerson", "inetorgperson"})
|
||||
public class MockEntity
|
||||
{
|
||||
|
||||
@DirAttribute("cn")
|
||||
private String name;
|
||||
|
||||
@DirAttribute("addr")
|
||||
private String address;
|
||||
|
||||
@DirAttribute("mail")
|
||||
private String mail;
|
||||
|
||||
@DirAttribute("userpassword")
|
||||
private byte[] password;
|
||||
|
||||
@DirAttribute("desc")
|
||||
private String[] description;
|
||||
|
||||
@DirAttribute("acceptemails")
|
||||
private Boolean acceptEmails;
|
||||
|
||||
@DirAttribute("loginresettime")
|
||||
private Date resetLogin;
|
||||
|
||||
@DirAttribute("failedlogins")
|
||||
private Integer failedLogins;
|
||||
|
||||
@DirAttribute("creatorname")
|
||||
private DistinguishedName creator;
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name)
|
||||
{
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getAddress()
|
||||
{
|
||||
return address;
|
||||
}
|
||||
|
||||
public void setAddress(String address)
|
||||
{
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
public String getMail()
|
||||
{
|
||||
return mail;
|
||||
}
|
||||
|
||||
public void setMail(String mail)
|
||||
{
|
||||
this.mail = mail;
|
||||
}
|
||||
|
||||
public byte[] getPassword()
|
||||
{
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(byte[] password)
|
||||
{
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public String[] getDescription()
|
||||
{
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String[] description)
|
||||
{
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public Boolean getAcceptEmails()
|
||||
{
|
||||
return acceptEmails;
|
||||
}
|
||||
|
||||
public void setAcceptEmails(Boolean acceptEmails)
|
||||
{
|
||||
this.acceptEmails = acceptEmails;
|
||||
}
|
||||
|
||||
public Date getResetLogin()
|
||||
{
|
||||
return resetLogin;
|
||||
}
|
||||
|
||||
public void setResetLogin(Date resetLogin)
|
||||
{
|
||||
this.resetLogin = resetLogin;
|
||||
}
|
||||
|
||||
public Integer getFailedLogins()
|
||||
{
|
||||
return failedLogins;
|
||||
}
|
||||
|
||||
public void setFailedLogins(Integer failedLogins)
|
||||
{
|
||||
this.failedLogins = failedLogins;
|
||||
}
|
||||
|
||||
public DistinguishedName getCreator()
|
||||
{
|
||||
return creator;
|
||||
}
|
||||
|
||||
public void setCreator(DistinguishedName creator)
|
||||
{
|
||||
this.creator = creator;
|
||||
}
|
||||
}
|
||||
@@ -1,116 +0,0 @@
|
||||
/*
|
||||
* Copyright 2006 by Majitek. All Rights Reserved.
|
||||
*
|
||||
* This software is the proprietary information of Majitek. Use is subject to license terms.
|
||||
*/
|
||||
package org.springframework.ldap.odm.entity;
|
||||
|
||||
import org.springframework.ldap.odm.annotations.DirAttribute;
|
||||
import org.springframework.ldap.odm.annotations.NamingAttribute;
|
||||
import org.springframework.ldap.odm.annotations.NamingSuffix;
|
||||
import org.springframework.ldap.odm.annotations.ObjectClasses;
|
||||
import org.apache.commons.lang.builder.EqualsBuilder;
|
||||
|
||||
import com.thoughtworks.xstream.XStream;
|
||||
|
||||
|
||||
@NamingAttribute("uid")
|
||||
@NamingSuffix({"ou=people"})
|
||||
@ObjectClasses({"person", "organizationalPerson", "inetorgperson"})
|
||||
public class TestPerson
|
||||
{
|
||||
/*********************************** Directory mapped fields ************************************/
|
||||
@DirAttribute("uid")
|
||||
private String identifier;
|
||||
|
||||
@DirAttribute("sn")
|
||||
private String lastName;
|
||||
|
||||
@DirAttribute("givenName")
|
||||
private String givenName;
|
||||
|
||||
@DirAttribute("cn")
|
||||
private String fullName;
|
||||
|
||||
@DirAttribute("mail")
|
||||
private String emailAddress;
|
||||
|
||||
@DirAttribute("userpassword")
|
||||
private byte[] password;
|
||||
|
||||
/************************************************************************************************/
|
||||
|
||||
public String getIdentifier()
|
||||
{
|
||||
return identifier;
|
||||
}
|
||||
|
||||
public void setIdentifier(String identifier)
|
||||
{
|
||||
this.identifier = identifier;
|
||||
}
|
||||
|
||||
public String getLastName()
|
||||
{
|
||||
return lastName;
|
||||
}
|
||||
|
||||
public void setLastName(String lastName)
|
||||
{
|
||||
this.lastName = lastName;
|
||||
}
|
||||
|
||||
public String getGivenName()
|
||||
{
|
||||
return givenName;
|
||||
}
|
||||
|
||||
public void setGivenName(String givenName)
|
||||
{
|
||||
this.givenName = givenName;
|
||||
}
|
||||
|
||||
public String getFullName()
|
||||
{
|
||||
return fullName;
|
||||
}
|
||||
|
||||
public void setFullName(String fullName)
|
||||
{
|
||||
this.fullName = fullName;
|
||||
}
|
||||
|
||||
public String getEmailAddress()
|
||||
{
|
||||
return emailAddress;
|
||||
}
|
||||
|
||||
public void setEmailAddress(String emailAddress)
|
||||
{
|
||||
this.emailAddress = emailAddress;
|
||||
}
|
||||
|
||||
public byte[] getPassword()
|
||||
{
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(byte[] password)
|
||||
{
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
XStream xStream = new XStream();
|
||||
xStream.alias("TestPerson", TestPerson.class);
|
||||
return "\n" + xStream.toXML(this);
|
||||
}
|
||||
|
||||
public boolean equals(Object o)
|
||||
{
|
||||
return EqualsBuilder.reflectionEquals(this, o);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
/*
|
||||
* Copyright 2006 by Majitek. All Rights Reserved.
|
||||
*
|
||||
* This software is the proprietary information of Majitek. Use is subject to license terms.
|
||||
*/
|
||||
package org.springframework.ldap.odm.entity;
|
||||
|
||||
import org.springframework.ldap.odm.annotations.DirAttribute;
|
||||
import org.springframework.ldap.odm.annotations.NamingAttribute;
|
||||
import org.springframework.ldap.odm.annotations.NamingSuffix;
|
||||
import org.springframework.ldap.odm.annotations.ObjectClasses;
|
||||
|
||||
import com.thoughtworks.xstream.XStream;
|
||||
|
||||
@NamingAttribute("cn")
|
||||
@NamingSuffix({"ou=roles"})
|
||||
@ObjectClasses({"top", "organizationalRole"})
|
||||
|
||||
public class TestRole
|
||||
{
|
||||
/*********************************** Directory mapped fields ************************************/
|
||||
@DirAttribute("cn")
|
||||
private String roleName;
|
||||
|
||||
@DirAttribute
|
||||
private String description;
|
||||
|
||||
@DirAttribute("roleOccupant")
|
||||
private TestPerson[] members;
|
||||
|
||||
/************************************************************************************************/
|
||||
|
||||
public String getRoleName()
|
||||
{
|
||||
return roleName;
|
||||
}
|
||||
|
||||
public void setRoleName(String roleName)
|
||||
{
|
||||
this.roleName = roleName;
|
||||
}
|
||||
|
||||
public String getDescription()
|
||||
{
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description)
|
||||
{
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public TestPerson[] getMembers()
|
||||
{
|
||||
return members;
|
||||
}
|
||||
|
||||
public void setMembers(TestPerson[] members)
|
||||
{
|
||||
this.members = members;
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
XStream xStream = new XStream();
|
||||
xStream.alias("TestRole", TestRole.class);
|
||||
xStream.alias("TestPerson", TestPerson.class);
|
||||
return "\n" + xStream.toXML(this);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
/*
|
||||
* Copyright 2006 by Majitek. All Rights Reserved.
|
||||
*
|
||||
* This software is the proprietary information of Majitek. Use is subject to license terms.
|
||||
*/
|
||||
package org.springframework.ldap.odm.attributetypes.exception;
|
||||
|
||||
public class ReferencedEntryEditorCreationException extends Exception
|
||||
{
|
||||
public ReferencedEntryEditorCreationException(String message, Throwable cause)
|
||||
{
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
||||
@@ -1,335 +0,0 @@
|
||||
/*
|
||||
* Copyright 2006 by Majitek. All Rights Reserved.
|
||||
*
|
||||
* This software is the proprietary information of Majitek. Use is subject to license terms.
|
||||
*/
|
||||
package org.springframework.ldap.odm.contextmapping;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.naming.Name;
|
||||
import javax.naming.directory.Attribute;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.TypeMismatchException;
|
||||
import org.springframework.ldap.core.ContextAssembler;
|
||||
import org.springframework.ldap.core.ContextMapper;
|
||||
import org.springframework.ldap.core.DirContextAdapter;
|
||||
import org.springframework.ldap.core.DistinguishedName;
|
||||
import org.springframework.ldap.odm.annotations.DirAttribute;
|
||||
import org.springframework.ldap.odm.annotations.NamingAttribute;
|
||||
import org.springframework.ldap.odm.annotations.NamingSuffix;
|
||||
import org.springframework.ldap.odm.annotations.ObjectClasses;
|
||||
import org.springframework.ldap.odm.attributetypes.LdapTypeConverter;
|
||||
import org.springframework.ldap.odm.attributetypes.ReferencedEntryEditorFactory;
|
||||
import org.springframework.ldap.odm.attributetypes.ValidConversionType;
|
||||
import org.springframework.ldap.odm.attributetypes.exception.ReferencedEntryEditorCreationException;
|
||||
import org.springframework.ldap.odm.contextmapping.exception.ContextMapperException;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
public class AnnotatedClassContextMapper implements ContextMapper, ContextAssembler
|
||||
{
|
||||
private static final Log LOGGER = LogFactory.getLog(AnnotatedClassContextMapper.class);
|
||||
|
||||
private LdapTypeConverter typeConverter;
|
||||
private ReferencedEntryEditorFactory refEditorFactory;
|
||||
|
||||
private Class<?> clazz;
|
||||
private String namingAttribute;
|
||||
private String[] objectClasses;
|
||||
private String[] namingSuffixElements;
|
||||
private DistinguishedName namingSuffix;
|
||||
|
||||
private ContextMap contextMap;
|
||||
private Map<String, Method> propertyGetters;
|
||||
private Map<String, Method> propertySetters;
|
||||
|
||||
|
||||
public AnnotatedClassContextMapper(Class<?> clazz, LdapTypeConverter typeConverter,
|
||||
ReferencedEntryEditorFactory refEditorFactory) throws ContextMapperException
|
||||
{
|
||||
this.clazz = clazz;
|
||||
this.typeConverter = typeConverter;
|
||||
this.refEditorFactory = refEditorFactory;
|
||||
checkConfigured();
|
||||
checkRequiredMetaData();
|
||||
buildNamingSuffix();
|
||||
mapAttributesToBeanProperties();
|
||||
cacheGettersAndSetters();
|
||||
registerReferencedEntries();
|
||||
}
|
||||
|
||||
private void checkConfigured() throws ContextMapperException
|
||||
{
|
||||
if (clazz == null)
|
||||
{
|
||||
throw new ContextMapperException("Error creating context mapper."
|
||||
+ ". Class<?> arugment is null");
|
||||
}
|
||||
|
||||
if (this.typeConverter == null)
|
||||
{
|
||||
throw new ContextMapperException("Error creating context mapper for class: "
|
||||
+ clazz.getSimpleName()
|
||||
+ ". AttributeTypeTranslator arugment is null");
|
||||
}
|
||||
|
||||
if (this.refEditorFactory == null)
|
||||
{
|
||||
throw new ContextMapperException("Error creating context mapper for class: "
|
||||
+ clazz.getSimpleName()
|
||||
+ ". ReferencedEntryEditorFactory arugment is null");
|
||||
}
|
||||
}
|
||||
|
||||
private void checkRequiredMetaData() throws ContextMapperException
|
||||
{
|
||||
NamingAttribute attnNamingAttr = clazz.getAnnotation(NamingAttribute.class);
|
||||
ObjectClasses attnObjectClasses = clazz.getAnnotation(ObjectClasses.class);
|
||||
NamingSuffix attnNamingSuffix = clazz.getAnnotation(NamingSuffix.class);
|
||||
this.namingAttribute = attnNamingAttr != null ? attnNamingAttr.value() : null;
|
||||
this.objectClasses = attnObjectClasses != null ? attnObjectClasses.value() : null;
|
||||
this.namingSuffixElements = attnNamingSuffix != null ? attnNamingSuffix.value() : null;
|
||||
|
||||
if (this.namingAttribute == null)
|
||||
{
|
||||
throw new ContextMapperException("Error creating context mapper for class: "
|
||||
+ clazz.getSimpleName()
|
||||
+ ". The @NamingAttribute annotation is required.");
|
||||
}
|
||||
|
||||
if (this.objectClasses == null)
|
||||
{
|
||||
throw new ContextMapperException("Error creating context mapper for class: "
|
||||
+ clazz.getSimpleName()
|
||||
+ ". The @ObjectClasses annotation is required.");
|
||||
}
|
||||
|
||||
if (namingSuffixElements == null || namingSuffixElements.length == 0)
|
||||
{
|
||||
throw new ContextMapperException("Error creating context mapper for class: "
|
||||
+ clazz.getSimpleName()
|
||||
+ ". The @NamingSuffix annotation is required.");
|
||||
}
|
||||
|
||||
if (namingSuffixElements[0].contains(","))
|
||||
{
|
||||
throw new ContextMapperException("Error creating context mapper for class: "
|
||||
+ clazz.getSimpleName()
|
||||
+ ". Naming path nodes must be defined as separate elements, "
|
||||
+ "for example: @NamingSuffix({\"ou=people\", \"dc=example\", \"dc=com\"}), and not: "
|
||||
+ "@NamingSuffix({\"ou=people,dc=example,dc=com\"})");
|
||||
}
|
||||
}
|
||||
|
||||
private void buildNamingSuffix() throws ContextMapperException
|
||||
{
|
||||
namingSuffix = new DistinguishedName();
|
||||
for (int i = namingSuffixElements.length - 1; i >= 0; i--)
|
||||
{
|
||||
String[] nameValue = namingSuffixElements[i].split("=");
|
||||
if (nameValue.length != 2)
|
||||
{
|
||||
throw new ContextMapperException("Error creating context mapper for class: " + clazz.getSimpleName()
|
||||
+ ". Syntax error in naming suffix element: " + namingSuffixElements[i]);
|
||||
}
|
||||
namingSuffix.add(nameValue[0].trim(), nameValue[1].trim());
|
||||
}
|
||||
}
|
||||
|
||||
private void mapAttributesToBeanProperties()
|
||||
{
|
||||
contextMap = new ContextMap();
|
||||
for (Field field : clazz.getDeclaredFields())
|
||||
{
|
||||
DirAttribute dirAttribute = field.getAnnotation(DirAttribute.class);
|
||||
if (dirAttribute != null)
|
||||
{
|
||||
String beanPropertyName = StringUtils.capitalize(field.getName());
|
||||
String attributeName = dirAttribute.value().equals("") ? field.getName() : dirAttribute.value();
|
||||
contextMap.map(beanPropertyName, attributeName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void cacheGettersAndSetters() throws ContextMapperException
|
||||
{
|
||||
propertyGetters = new HashMap<String, Method>();
|
||||
propertySetters = new HashMap<String, Method>();
|
||||
|
||||
for (String beanPropertyName : contextMap.beanPropertyNames())
|
||||
{
|
||||
try
|
||||
{
|
||||
Method getter = clazz.getMethod("get" + beanPropertyName);
|
||||
propertyGetters.put(beanPropertyName, getter);
|
||||
Method setter = clazz.getMethod("set" + beanPropertyName, getter.getReturnType());
|
||||
propertySetters.put(beanPropertyName, setter);
|
||||
}
|
||||
catch (NoSuchMethodException e)
|
||||
{
|
||||
throw new ContextMapperException("Error creating context mapper for class: "
|
||||
+ clazz.getSimpleName()
|
||||
+ ". " + clazz.getSimpleName() + " is missing a getter/setter for property: "
|
||||
+ beanPropertyName, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void registerReferencedEntries() throws ContextMapperException
|
||||
{
|
||||
for (Method getter : propertyGetters.values())
|
||||
{
|
||||
Class<?> returnType = getter.getReturnType();
|
||||
if (!ValidConversionType.isValidConversionType(returnType))
|
||||
{
|
||||
try
|
||||
{
|
||||
Class componentType = returnType.isArray() ? returnType.getComponentType() : returnType;
|
||||
typeConverter.registerCustomEditor(componentType,
|
||||
refEditorFactory.referencedEntryEditorForClass(componentType));
|
||||
}
|
||||
catch (ReferencedEntryEditorCreationException e)
|
||||
{
|
||||
throw new ContextMapperException(clazz.getSimpleName() + "."
|
||||
+ getter.getName()
|
||||
+ "() has invalid return type. Return type must be a context mapped "
|
||||
+ "directory object, or one of the following: "
|
||||
+ ValidConversionType.listTypes(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Object mapFromContext(Object ctx)
|
||||
{
|
||||
DirContextAdapter ctxAdapter = (DirContextAdapter) ctx;
|
||||
Object instance;
|
||||
try
|
||||
{
|
||||
instance = clazz.newInstance();
|
||||
for (String beanPropertyName : contextMap.beanPropertyNames())
|
||||
{
|
||||
Class attributeType = propertyGetters.get(beanPropertyName).getReturnType();
|
||||
Attribute attribute =
|
||||
ctxAdapter.getAttributes().get(contextMap.attributeNameFor(beanPropertyName));
|
||||
if (attribute != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
Object beanPropertyValue = typeConverter.convertIfNecessary(
|
||||
new AttributeDecorator(attribute).getAllAsObject(), attributeType);
|
||||
propertySetters.get(beanPropertyName).invoke(instance, beanPropertyValue);
|
||||
}
|
||||
catch (TypeMismatchException e)
|
||||
{
|
||||
throw new ContextMapperException("Cannot set bean property '" + beanPropertyName
|
||||
+ "' in class " + clazz.getSimpleName() + ", " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new RuntimeException(e.getMessage(), e);
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
// TODO: Simplify this method: When bug with DirContextAdapter.setAttribute() (LDAP-15) is fixed,
|
||||
// TODO: register a type converter to convert to type Attribute
|
||||
public void mapToContext(Object beanInstance, Object ctx)
|
||||
{
|
||||
DirContextAdapter ctxAdapter = (DirContextAdapter) ctx;
|
||||
ctxAdapter.setAttributeValues("objectclass", objectClasses);
|
||||
for (String attributeName : contextMap.attributeNames())
|
||||
{
|
||||
try
|
||||
{
|
||||
Object beanPropertyValue = propertyGetters.get(
|
||||
contextMap.beanPropertyNameFor(attributeName)).invoke(beanInstance);
|
||||
LOGGER.trace("mapToContext() attribute:" + attributeName + ", value: " + beanPropertyValue);
|
||||
|
||||
if (beanPropertyValue != null)
|
||||
{
|
||||
if (beanPropertyValue instanceof byte[])
|
||||
{
|
||||
ctxAdapter.setAttributeValue(attributeName, beanPropertyValue);
|
||||
}
|
||||
else if (beanPropertyValue instanceof Object[])
|
||||
{
|
||||
ctxAdapter.setAttributeValues(attributeName,
|
||||
typeConverter.getAllAsText((Object[]) beanPropertyValue));
|
||||
}
|
||||
else
|
||||
{
|
||||
ctxAdapter.setAttributeValue(attributeName,
|
||||
typeConverter.getAsText(beanPropertyValue));
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new RuntimeException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Name buildDn(Object beanInstance) throws ContextMapperException
|
||||
{
|
||||
if (beanInstance == null)
|
||||
{
|
||||
throw new ContextMapperException("Can't build Dn from beanInstance, beanInstance is null");
|
||||
}
|
||||
return buildDn(namingAttributeValue(beanInstance));
|
||||
}
|
||||
|
||||
public Name buildDn(String namingAttributeValue) throws ContextMapperException
|
||||
{
|
||||
if (namingAttributeValue == null)
|
||||
{
|
||||
throw new ContextMapperException("Can't build Dn from namingAttributeValue, namingAttributeValue is null");
|
||||
}
|
||||
DistinguishedName dn = (DistinguishedName) namingSuffix.clone();
|
||||
dn.add(namingAttribute, namingAttributeValue);
|
||||
LOGGER.trace("buildDn(): " + dn);
|
||||
return dn;
|
||||
}
|
||||
|
||||
public String namingAttributeValue(Object beanInstance)
|
||||
{
|
||||
Method method = propertyGetters.get(contextMap.beanPropertyNameFor(namingAttribute));
|
||||
try
|
||||
{
|
||||
return (String) method.invoke(clazz.cast(beanInstance));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new RuntimeException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
public ContextMap getContextMap()
|
||||
{
|
||||
return contextMap;
|
||||
}
|
||||
|
||||
public String[] getObjectClasses()
|
||||
{
|
||||
return objectClasses;
|
||||
}
|
||||
|
||||
public String getNamingAttribute()
|
||||
{
|
||||
return namingAttribute;
|
||||
}
|
||||
|
||||
public DistinguishedName getNamingSuffix()
|
||||
{
|
||||
return namingSuffix;
|
||||
}
|
||||
}
|
||||
@@ -1,332 +0,0 @@
|
||||
/*
|
||||
* Copyright 2006 by Majitek. All Rights Reserved.
|
||||
*
|
||||
* This software is the proprietary information of Majitek. Use is subject to license terms.
|
||||
*/
|
||||
package org.springframework.ldap.odm.contextmapping;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.TypeMismatchException;
|
||||
import org.springframework.ldap.core.DirContextAdapter;
|
||||
import org.springframework.ldap.core.DistinguishedName;
|
||||
import org.springframework.ldap.odm.annotations.DirAttribute;
|
||||
import org.springframework.ldap.odm.annotations.NamingAttribute;
|
||||
import org.springframework.ldap.odm.annotations.NamingSuffix;
|
||||
import org.springframework.ldap.odm.annotations.ObjectClasses;
|
||||
import org.springframework.ldap.odm.attributetypes.LdapTypeConverter;
|
||||
import org.springframework.ldap.odm.attributetypes.ValidConversionType;
|
||||
import org.springframework.ldap.odm.attributetypes.ReferencedEntryEditorFactory;
|
||||
import org.springframework.ldap.odm.attributetypes.exception.ReferencedEntryEditorCreationException;
|
||||
import org.springframework.ldap.odm.contextmapping.exception.ContextMapperException;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import javax.naming.Name;
|
||||
import javax.naming.directory.Attribute;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class AnnotationObjectDirectoryMapper implements ObjectDirectoryMapper
|
||||
{
|
||||
private static final Log LOGGER = LogFactory.getLog(AnnotationObjectDirectoryMapper.class);
|
||||
|
||||
private LdapTypeConverter typeConverter;
|
||||
private ReferencedEntryEditorFactory refEditorFactory;
|
||||
|
||||
private Class<?> clazz;
|
||||
private String namingAttribute;
|
||||
private String[] objectClasses;
|
||||
private String[] namingSuffixElements;
|
||||
private DistinguishedName namingSuffix;
|
||||
|
||||
private ContextMap contextMap;
|
||||
private Map<String, Method> propertyGetters;
|
||||
private Map<String, Method> propertySetters;
|
||||
|
||||
|
||||
public AnnotationObjectDirectoryMapper(Class<?> clazz, LdapTypeConverter typeConverter,
|
||||
ReferencedEntryEditorFactory refEditorFactory) throws ContextMapperException
|
||||
{
|
||||
this.clazz = clazz;
|
||||
this.typeConverter = typeConverter;
|
||||
this.refEditorFactory = refEditorFactory;
|
||||
checkConfigured();
|
||||
checkRequiredMetaData();
|
||||
buildNamingSuffix();
|
||||
mapAttributesToBeanProperties();
|
||||
cacheGettersAndSetters();
|
||||
registerReferencedEntries();
|
||||
}
|
||||
|
||||
private void checkConfigured() throws ContextMapperException
|
||||
{
|
||||
if (clazz == null)
|
||||
{
|
||||
throw new ContextMapperException("Error creating context mapper."
|
||||
+ ". Class<?> arugment is null");
|
||||
}
|
||||
|
||||
if (this.typeConverter == null)
|
||||
{
|
||||
throw new ContextMapperException("Error creating context mapper for class: "
|
||||
+ clazz.getSimpleName()
|
||||
+ ". AttributeTypeTranslator arugment is null");
|
||||
}
|
||||
|
||||
if (this.refEditorFactory == null)
|
||||
{
|
||||
throw new ContextMapperException("Error creating context mapper for class: "
|
||||
+ clazz.getSimpleName()
|
||||
+ ". ReferencedEntryEditorFactory arugment is null");
|
||||
}
|
||||
}
|
||||
|
||||
private void checkRequiredMetaData() throws ContextMapperException
|
||||
{
|
||||
NamingAttribute attnNamingAttr = clazz.getAnnotation(NamingAttribute.class);
|
||||
ObjectClasses attnObjectClasses = clazz.getAnnotation(ObjectClasses.class);
|
||||
NamingSuffix attnNamingSuffix = clazz.getAnnotation(NamingSuffix.class);
|
||||
this.namingAttribute = attnNamingAttr != null ? attnNamingAttr.value() : null;
|
||||
this.objectClasses = attnObjectClasses != null ? attnObjectClasses.value() : null;
|
||||
this.namingSuffixElements = attnNamingSuffix != null ? attnNamingSuffix.value() : null;
|
||||
|
||||
if (this.namingAttribute == null)
|
||||
{
|
||||
throw new ContextMapperException("Error creating context mapper for class: "
|
||||
+ clazz.getSimpleName()
|
||||
+ ". The @NamingAttribute annotation is required.");
|
||||
}
|
||||
|
||||
if (this.objectClasses == null)
|
||||
{
|
||||
throw new ContextMapperException("Error creating context mapper for class: "
|
||||
+ clazz.getSimpleName()
|
||||
+ ". The @ObjectClasses annotation is required.");
|
||||
}
|
||||
|
||||
if (namingSuffixElements == null || namingSuffixElements.length == 0)
|
||||
{
|
||||
throw new ContextMapperException("Error creating context mapper for class: "
|
||||
+ clazz.getSimpleName()
|
||||
+ ". The @NamingSuffix annotation is required.");
|
||||
}
|
||||
|
||||
if (namingSuffixElements[0].contains(","))
|
||||
{
|
||||
throw new ContextMapperException("Error creating context mapper for class: "
|
||||
+ clazz.getSimpleName()
|
||||
+ ". Naming path nodes must be defined as separate elements, "
|
||||
+ "for example: @NamingSuffix({\"ou=people\", \"dc=example\", \"dc=com\"}), and not: "
|
||||
+ "@NamingSuffix({\"ou=people,dc=example,dc=com\"})");
|
||||
}
|
||||
}
|
||||
|
||||
private void buildNamingSuffix() throws ContextMapperException
|
||||
{
|
||||
namingSuffix = new DistinguishedName();
|
||||
for (int i = namingSuffixElements.length - 1; i >= 0; i--)
|
||||
{
|
||||
String[] nameValue = namingSuffixElements[i].split("=");
|
||||
if (nameValue.length != 2)
|
||||
{
|
||||
throw new ContextMapperException("Error creating context mapper for class: " + clazz.getSimpleName()
|
||||
+ ". Syntax error in naming suffix element: " + namingSuffixElements[i]);
|
||||
}
|
||||
namingSuffix.add(nameValue[0].trim(), nameValue[1].trim());
|
||||
}
|
||||
}
|
||||
|
||||
private void mapAttributesToBeanProperties()
|
||||
{
|
||||
contextMap = new ContextMap();
|
||||
for (Field field : clazz.getDeclaredFields())
|
||||
{
|
||||
DirAttribute dirAttribute = field.getAnnotation(DirAttribute.class);
|
||||
if (dirAttribute != null)
|
||||
{
|
||||
String beanPropertyName = StringUtils.capitalize(field.getName());
|
||||
String attributeName = dirAttribute.value().equals("") ? field.getName() : dirAttribute.value();
|
||||
contextMap.map(beanPropertyName, attributeName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void cacheGettersAndSetters() throws ContextMapperException
|
||||
{
|
||||
propertyGetters = new HashMap<String, Method>();
|
||||
propertySetters = new HashMap<String, Method>();
|
||||
|
||||
for (String beanPropertyName : contextMap.beanPropertyNames())
|
||||
{
|
||||
try
|
||||
{
|
||||
Method getter = clazz.getMethod("get" + beanPropertyName);
|
||||
propertyGetters.put(beanPropertyName, getter);
|
||||
Method setter = clazz.getMethod("set" + beanPropertyName, getter.getReturnType());
|
||||
propertySetters.put(beanPropertyName, setter);
|
||||
}
|
||||
catch (NoSuchMethodException e)
|
||||
{
|
||||
throw new ContextMapperException("Error creating context mapper for class: "
|
||||
+ clazz.getSimpleName()
|
||||
+ ". " + clazz.getSimpleName() + " is missing a getter/setter for property: "
|
||||
+ beanPropertyName, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void registerReferencedEntries() throws ContextMapperException
|
||||
{
|
||||
for (Method getter : propertyGetters.values())
|
||||
{
|
||||
Class<?> returnType = getter.getReturnType();
|
||||
if (!ValidConversionType.isValidConversionType(returnType))
|
||||
{
|
||||
try
|
||||
{
|
||||
Class componentType = returnType.isArray() ? returnType.getComponentType() : returnType;
|
||||
typeConverter.registerCustomEditor(componentType,
|
||||
refEditorFactory.referencedEntryEditorForClass(componentType));
|
||||
}
|
||||
catch (ReferencedEntryEditorCreationException e)
|
||||
{
|
||||
throw new ContextMapperException(clazz.getSimpleName() + "."
|
||||
+ getter.getName()
|
||||
+ "() has invalid return type. Return type must be a context mapped "
|
||||
+ "directory object, or one of the following: "
|
||||
+ ValidConversionType.listTypes(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Object mapFromContext(Object ctx)
|
||||
{
|
||||
DirContextAdapter ctxAdapter = (DirContextAdapter) ctx;
|
||||
Object instance;
|
||||
try
|
||||
{
|
||||
instance = clazz.newInstance();
|
||||
for (String beanPropertyName : contextMap.beanPropertyNames())
|
||||
{
|
||||
Class attributeType = propertyGetters.get(beanPropertyName).getReturnType();
|
||||
Attribute attribute =
|
||||
ctxAdapter.getAttributes().get(contextMap.attributeNameFor(beanPropertyName));
|
||||
if (attribute != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
Object beanPropertyValue = typeConverter.convertIfNecessary(
|
||||
new AttributeDecorator(attribute).getAllAsObject(), attributeType);
|
||||
propertySetters.get(beanPropertyName).invoke(instance, beanPropertyValue);
|
||||
}
|
||||
catch (TypeMismatchException e)
|
||||
{
|
||||
throw new ContextMapperException("Cannot set bean property '" + beanPropertyName
|
||||
+ "' in class " + clazz.getSimpleName() + ", " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new RuntimeException(e.getMessage(), e);
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
// TODO: Simplify this method: When bug with DirContextAdapter.setAttribute() (LDAP-15) is fixed,
|
||||
// TODO: register a type converter to convert to type Attribute
|
||||
public void mapToContext(Object beanInstance, Object ctx)
|
||||
{
|
||||
DirContextAdapter ctxAdapter = (DirContextAdapter) ctx;
|
||||
ctxAdapter.setAttributeValues("objectclass", objectClasses);
|
||||
for (String attributeName : contextMap.attributeNames())
|
||||
{
|
||||
try
|
||||
{
|
||||
Object beanPropertyValue = propertyGetters.get(
|
||||
contextMap.beanPropertyNameFor(attributeName)).invoke(beanInstance);
|
||||
LOGGER.trace("mapToContext() attribute:" + attributeName + ", value: " + beanPropertyValue);
|
||||
|
||||
if (beanPropertyValue != null)
|
||||
{
|
||||
if (beanPropertyValue instanceof byte[])
|
||||
{
|
||||
ctxAdapter.setAttributeValue(attributeName, beanPropertyValue);
|
||||
}
|
||||
else if (beanPropertyValue instanceof Object[])
|
||||
{
|
||||
ctxAdapter.setAttributeValues(attributeName,
|
||||
typeConverter.getAllAsText((Object[]) beanPropertyValue));
|
||||
}
|
||||
else
|
||||
{
|
||||
ctxAdapter.setAttributeValue(attributeName,
|
||||
typeConverter.getAsText(beanPropertyValue));
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new RuntimeException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Name buildDn(Object beanInstance) throws ContextMapperException
|
||||
{
|
||||
if (beanInstance == null)
|
||||
{
|
||||
throw new ContextMapperException("Can't build Dn from beanInstance, beanInstance is null");
|
||||
}
|
||||
return buildDn(namingAttributeValue(beanInstance));
|
||||
}
|
||||
|
||||
public Name buildDn(String namingAttributeValue) throws ContextMapperException
|
||||
{
|
||||
if (namingAttributeValue == null)
|
||||
{
|
||||
throw new ContextMapperException("Can't build Dn from namingAttributeValue, namingAttributeValue is null");
|
||||
}
|
||||
DistinguishedName dn = (DistinguishedName) namingSuffix.clone();
|
||||
dn.add(namingAttribute, namingAttributeValue);
|
||||
LOGGER.trace("buildDn(): " + dn);
|
||||
return dn;
|
||||
}
|
||||
|
||||
public String namingAttributeValue(Object beanInstance)
|
||||
{
|
||||
Method method = propertyGetters.get(contextMap.beanPropertyNameFor(namingAttribute));
|
||||
try
|
||||
{
|
||||
return (String) method.invoke(clazz.cast(beanInstance));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new RuntimeException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
public ContextMap getContextMap()
|
||||
{
|
||||
return contextMap;
|
||||
}
|
||||
|
||||
public String[] getObjectClasses()
|
||||
{
|
||||
return objectClasses;
|
||||
}
|
||||
|
||||
public String getNamingAttribute()
|
||||
{
|
||||
return namingAttribute;
|
||||
}
|
||||
|
||||
public DistinguishedName getNamingSuffix()
|
||||
{
|
||||
return namingSuffix;
|
||||
}
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
* Copyright 2006 by Majitek. All Rights Reserved.
|
||||
*
|
||||
* This software is the proprietary information of Majitek. Use is subject to license terms.
|
||||
*/
|
||||
package org.springframework.ldap.odm.contextmapping;
|
||||
|
||||
import javax.naming.NamingException;
|
||||
import javax.naming.directory.Attribute;
|
||||
|
||||
public class AttributeDecorator
|
||||
{
|
||||
private Attribute attribute;
|
||||
|
||||
public AttributeDecorator(Attribute attribute)
|
||||
{
|
||||
this.attribute = attribute;
|
||||
}
|
||||
|
||||
public Object getAllAsObject() throws NamingException
|
||||
{
|
||||
if (attribute != null)
|
||||
{
|
||||
if (attribute.size() == 1)
|
||||
{
|
||||
return attribute.get(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
Object[] o = new Object[attribute.size()];
|
||||
for (int i = 0; i < attribute.size(); i++)
|
||||
{
|
||||
o[i] = attribute.get(i);
|
||||
}
|
||||
return o;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
/*
|
||||
* Copyright 2006 by Majitek. All Rights Reserved.
|
||||
*
|
||||
* This software is the proprietary information of Majitek. Use is subject to license terms.
|
||||
*/
|
||||
package org.springframework.ldap.odm.contextmapping;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/** A bi-directional map of bean property names to attribute names */
|
||||
public class ContextMap
|
||||
{
|
||||
private static final Log LOGGER = LogFactory.getLog(ContextMap.class);
|
||||
private Map<String, String> beanPropertyNameKeys;
|
||||
private Map<String, String> attributeNameKeys;
|
||||
|
||||
public ContextMap()
|
||||
{
|
||||
beanPropertyNameKeys = new HashMap();
|
||||
attributeNameKeys = new HashMap();
|
||||
}
|
||||
|
||||
public void map(String beanPropertyName, String toAttributeName)
|
||||
{
|
||||
LOGGER.info("Bean property '" + beanPropertyName + "' maps to ldap attribute '" + toAttributeName + "'");
|
||||
beanPropertyNameKeys.put(beanPropertyName, toAttributeName);
|
||||
attributeNameKeys.put(toAttributeName, beanPropertyName);
|
||||
}
|
||||
|
||||
public String beanPropertyNameFor(String attributeName)
|
||||
{
|
||||
return attributeNameKeys.get(attributeName);
|
||||
}
|
||||
|
||||
public String attributeNameFor(String beanPropertyName)
|
||||
{
|
||||
return beanPropertyNameKeys.get(beanPropertyName);
|
||||
}
|
||||
|
||||
public Set<String> beanPropertyNames()
|
||||
{
|
||||
return beanPropertyNameKeys.keySet();
|
||||
}
|
||||
|
||||
public Set<String> attributeNames()
|
||||
{
|
||||
return attributeNameKeys.keySet();
|
||||
}
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
/*
|
||||
* Copyright 2006 by Majitek. All Rights Reserved.
|
||||
*
|
||||
* This software is the proprietary information of Majitek. Use is subject to license terms.
|
||||
*/
|
||||
package org.springframework.ldap.odm.contextmapping;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.ldap.odm.attributetypes.LdapTypeConverter;
|
||||
import org.springframework.ldap.odm.attributetypes.ReferencedEntryEditorFactory;
|
||||
import org.springframework.ldap.odm.contextmapping.exception.ContextMapperException;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class ContextMapperFactory
|
||||
{
|
||||
private static final Log LOGGER = LogFactory.getLog(ContextMapperFactory.class);
|
||||
private Map<Class, AnnotationObjectDirectoryMapper> contextMappers;
|
||||
private LdapTypeConverter typeConverter;
|
||||
private ReferencedEntryEditorFactory referencedEntryEditorFactory;
|
||||
|
||||
public ContextMapperFactory(LdapTypeConverter typeConverter,
|
||||
ReferencedEntryEditorFactory referencedEntryEditorFactory)
|
||||
{
|
||||
contextMappers = new HashMap<Class, AnnotationObjectDirectoryMapper>();
|
||||
this.typeConverter = typeConverter;
|
||||
this.referencedEntryEditorFactory = referencedEntryEditorFactory;
|
||||
this.referencedEntryEditorFactory.setContextMapperFactory(this);
|
||||
}
|
||||
|
||||
public ObjectDirectoryMapper contextMapperForClass(Class clazz)
|
||||
throws ContextMapperException
|
||||
{
|
||||
if (contextMappers.containsKey(clazz))
|
||||
{
|
||||
LOGGER.debug("Returning cached context mapper for class: " + clazz.getSimpleName());
|
||||
return contextMappers.get(clazz);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGGER.debug("Attempting to create a context mapper for class: " + clazz.getSimpleName());
|
||||
AnnotationObjectDirectoryMapper contextMapper =
|
||||
new AnnotationObjectDirectoryMapper(clazz, typeConverter, referencedEntryEditorFactory);
|
||||
contextMappers.put(clazz, contextMapper);
|
||||
return contextMapper;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
/*
|
||||
* Copyright 2005 by Majitek. All Rights Reserved.
|
||||
*
|
||||
* This software is the proprietary information of Majitek. Use is subject to license terms.
|
||||
*/
|
||||
|
||||
package org.springframework.ldap.odm.contextmapping;
|
||||
|
||||
import org.springframework.ldap.core.ContextMapper;
|
||||
import org.springframework.ldap.core.ContextAssembler;
|
||||
import org.springframework.ldap.core.DistinguishedName;
|
||||
import org.springframework.ldap.odm.contextmapping.exception.ContextMapperException;
|
||||
|
||||
import javax.naming.Name;
|
||||
|
||||
public interface ObjectDirectoryMapper extends ContextMapper, ContextAssembler
|
||||
{
|
||||
Object mapFromContext(Object ctx);
|
||||
|
||||
void mapToContext(Object beanInstance, Object ctx);
|
||||
|
||||
Name buildDn(Object beanInstance) throws ContextMapperException;
|
||||
|
||||
Name buildDn(String namingAttributeValue) throws ContextMapperException;
|
||||
|
||||
String namingAttributeValue(Object beanInstance);
|
||||
|
||||
ContextMap getContextMap();
|
||||
|
||||
String[] getObjectClasses();
|
||||
|
||||
String getNamingAttribute();
|
||||
|
||||
DistinguishedName getNamingSuffix();
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
/*
|
||||
* Copyright 2006 by Majitek. All Rights Reserved.
|
||||
*
|
||||
* This software is the proprietary information of Majitek. Use is subject to license terms.
|
||||
*/
|
||||
package org.springframework.ldap.odm.contextmapping.exception;
|
||||
|
||||
public class ContextMapperException extends Exception
|
||||
{
|
||||
|
||||
|
||||
public ContextMapperException(String message)
|
||||
{
|
||||
super(message);
|
||||
}
|
||||
|
||||
public ContextMapperException(String message, Throwable cause)
|
||||
{
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
/*
|
||||
* Copyright 2006 by Majitek. All Rights Reserved.
|
||||
*
|
||||
* This software is the proprietary information of Majitek. Use is subject to license terms.
|
||||
*/
|
||||
package org.springframework.ldap.odm.dao.exception;
|
||||
|
||||
public class DaoException extends RuntimeException
|
||||
{
|
||||
public DaoException(String message)
|
||||
{
|
||||
super(message);
|
||||
}
|
||||
|
||||
public DaoException(String message, Throwable cause)
|
||||
{
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
/*
|
||||
* Copyright 2006 by Majitek. All Rights Reserved.
|
||||
*
|
||||
* This software is the proprietary information of Majitek. Use is subject to license terms.
|
||||
*/
|
||||
package org.springframework.ldap.odm.dao.exception;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A Serializable version of org.springframework.dao.DataIntegrityViolationException
|
||||
*/
|
||||
public class DataIntegrityViolationException extends DaoException
|
||||
{
|
||||
|
||||
private List<String> nonUniqueAttributes;
|
||||
|
||||
public DataIntegrityViolationException(String message)
|
||||
{
|
||||
super(message);
|
||||
}
|
||||
|
||||
public DataIntegrityViolationException(String message, Throwable cause)
|
||||
{
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
/*
|
||||
* Copyright 2006 by Majitek. All Rights Reserved.
|
||||
*
|
||||
* This software is the proprietary information of Majitek. Use is subject to license terms.
|
||||
*/
|
||||
package org.springframework.ldap.odm.dao.exception;
|
||||
|
||||
/**
|
||||
* A Serializable version of org.springframework.dao.EntryNotFoundException
|
||||
*/
|
||||
public class EntryNotFoundException extends DaoException
|
||||
{
|
||||
|
||||
public EntryNotFoundException(String message)
|
||||
{
|
||||
super(message);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user