diff --git a/repository/net.sf/chainedoptions-src/0.9.0/chainedoptions-src-0.9.0.zip b/repository/net.sf/chainedoptions-src/0.9.0/chainedoptions-src-0.9.0.zip new file mode 100644 index 00000000..ab2e19b1 Binary files /dev/null and b/repository/net.sf/chainedoptions-src/0.9.0/chainedoptions-src-0.9.0.zip differ diff --git a/repository/net.sf/chainedoptions-src/ivy-0.9.0.xml b/repository/net.sf/chainedoptions-src/ivy-0.9.0.xml new file mode 100644 index 00000000..b4440e67 --- /dev/null +++ b/repository/net.sf/chainedoptions-src/ivy-0.9.0.xml @@ -0,0 +1,16 @@ + + + + + + + + + + diff --git a/repository/net.sf/chainedoptions/0.9.0/chainedoptions-0.9.0.jar b/repository/net.sf/chainedoptions/0.9.0/chainedoptions-0.9.0.jar new file mode 100644 index 00000000..b4cb820b Binary files /dev/null and b/repository/net.sf/chainedoptions/0.9.0/chainedoptions-0.9.0.jar differ diff --git a/spring-ldap-person/.classpath b/spring-ldap-person/.classpath index cd5ecaa7..04443d8f 100644 --- a/spring-ldap-person/.classpath +++ b/spring-ldap-person/.classpath @@ -16,6 +16,7 @@ + diff --git a/spring-ldap-person/.settings/org.springframework.ide.eclipse.core.prefs b/spring-ldap-person/.settings/org.springframework.ide.eclipse.core.prefs new file mode 100644 index 00000000..70b0cd2d --- /dev/null +++ b/spring-ldap-person/.settings/org.springframework.ide.eclipse.core.prefs @@ -0,0 +1,5 @@ +#Tue Jul 17 23:38:33 CEST 2007 +eclipse.preferences.version=1 +org.springframework.ide.eclipse.core.builders.enable.aopreferencemodelbuilder=true +org.springframework.ide.eclipse.core.builders.enable.beansvalidator=true +org.springframework.ide.eclipse.core.builders.enable.webflowvalidator=true diff --git a/spring-ldap-person/.springBeans b/spring-ldap-person/.springBeans index 4857f5db..32e7378d 100644 --- a/spring-ldap-person/.springBeans +++ b/spring-ldap-person/.springBeans @@ -6,13 +6,11 @@ src/main/webapp/WEB-INF/flows/detail-group-flow-beans.xml src/main/webapp/WEB-INF/flows/search-group-flow-beans.xml - src/webapp/WEB-INF/apacheDsContext.xml src/main/webapp/WEB-INF/flows/search-flow-beans.xml - src/webapp/WEB-INF/applicationContext.xml - src/webapp/WEB-INF/applicationContext-acegi-security.xml - src/webapp/WEB-INF/ldaptemplate-servlet.xml src/main/webapp/WEB-INF/flows/detail-flow-beans.xml src/main/webapp/WEB-INF/ldaptemplate-webflow-config.xml + src/main/webapp/WEB-INF/optionsContext.xml + src/main/webapp/WEB-INF/applicationContext.xml @@ -20,15 +18,13 @@ false false - src/webapp/WEB-INF/apacheDsContext.xml - src/webapp/WEB-INF/applicationContext.xml - src/webapp/WEB-INF/applicationContext-acegi-security.xml - src/webapp/WEB-INF/ldaptemplate-servlet.xml src/main/webapp/WEB-INF/flows/detail-flow-beans.xml src/main/webapp/WEB-INF/flows/detail-group-flow-beans.xml src/main/webapp/WEB-INF/flows/search-flow-beans.xml src/main/webapp/WEB-INF/flows/search-group-flow-beans.xml src/main/webapp/WEB-INF/ldaptemplate-webflow-config.xml + src/main/webapp/WEB-INF/applicationContext.xml + src/main/webapp/WEB-INF/optionsContext.xml diff --git a/spring-ldap-person/ivy.xml b/spring-ldap-person/ivy.xml index 0f3f66aa..53ddb709 100644 --- a/spring-ldap-person/ivy.xml +++ b/spring-ldap-person/ivy.xml @@ -1,9 +1,9 @@ - - @@ -16,105 +16,110 @@ - - - + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/spring-ldap-person/src/main/java/org/springframework/ldap/samples/person/dao/CompanyContextMapper.java b/spring-ldap-person/src/main/java/org/springframework/ldap/samples/person/dao/CompanyContextMapper.java new file mode 100644 index 00000000..3dc2b43c --- /dev/null +++ b/spring-ldap-person/src/main/java/org/springframework/ldap/samples/person/dao/CompanyContextMapper.java @@ -0,0 +1,39 @@ +/* + * Copyright 2005-2007 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.ldap.samples.person.dao; + +import org.springframework.ldap.core.ContextMapper; +import org.springframework.ldap.core.DirContextOperations; +import org.springframework.ldap.samples.person.domain.Company; + +/** + * Maps from DirContextOperations (DirContextAdapters, really) to Company + * objects. A DN for a company will be of the form ou=[name],c=country + * + * @author Ulrik Sandberg + */ +public class CompanyContextMapper implements ContextMapper { + + /* + * @see org.springframework.ldap.core.ContextMapper#mapFromContext(java.lang.Object) + */ + public Object mapFromContext(Object ctx) { + DirContextOperations dirContext = (DirContextOperations) ctx; + Company company = new Company(); + company.setName(dirContext.getStringAttribute("ou")); + return company; + } +} diff --git a/spring-ldap-person/src/main/java/org/springframework/ldap/samples/person/dao/CompanyDao.java b/spring-ldap-person/src/main/java/org/springframework/ldap/samples/person/dao/CompanyDao.java new file mode 100644 index 00000000..dbab51a8 --- /dev/null +++ b/spring-ldap-person/src/main/java/org/springframework/ldap/samples/person/dao/CompanyDao.java @@ -0,0 +1,27 @@ +/* + * Copyright 2005-2007 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.ldap.samples.person.dao; + +import java.util.List; + +/** + * Data Access Object interface for the Company entity. + * + * @author Ulrik Sandberg + */ +public interface CompanyDao { + public List findByCountry(String country); +} diff --git a/spring-ldap-person/src/main/java/org/springframework/ldap/samples/person/dao/CompanyDaoImpl.java b/spring-ldap-person/src/main/java/org/springframework/ldap/samples/person/dao/CompanyDaoImpl.java new file mode 100644 index 00000000..be22cbff --- /dev/null +++ b/spring-ldap-person/src/main/java/org/springframework/ldap/samples/person/dao/CompanyDaoImpl.java @@ -0,0 +1,57 @@ +/* + * Copyright 2005-2007 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.ldap.samples.person.dao; + +import java.util.List; + +import org.springframework.ldap.core.ContextMapper; +import org.springframework.ldap.core.DistinguishedName; +import org.springframework.ldap.core.LdapOperations; +import org.springframework.ldap.filter.EqualsFilter; + +/** + * Default implementation of CompanyDao. This implementation uses + * DirContextOperations (DirContextAdapter really, but for mock testing purposes + * we use the interface) for managing attribute values. It has been specified in + * the Spring Context that the DirObjectFactory should be used when creating + * objects from contexts, which defaults to creating DirContextAdapter objects. + * This means that we can use a ContextMapper to map from the found contexts to + * our domain objects. + * + * @author Ulrik Sandberg + */ +public class CompanyDaoImpl implements CompanyDao { + /** + * The template object that performs all data access work. + */ + LdapOperations ldapOperations; + + public List findByCountry(String country) { + EqualsFilter filter = new EqualsFilter("objectclass", "organizationalUnit"); + DistinguishedName base = new DistinguishedName(); + base.add("c", country); + return ldapOperations.search(base, filter.toString(), + getContextMapper()); + } + + ContextMapper getContextMapper() { + return new CompanyContextMapper(); + } + + public void setLdapOperations(LdapOperations ldapOperations) { + this.ldapOperations = ldapOperations; + } +} diff --git a/spring-ldap-person/src/main/java/org/springframework/ldap/samples/person/dao/CountryContextMapper.java b/spring-ldap-person/src/main/java/org/springframework/ldap/samples/person/dao/CountryContextMapper.java new file mode 100644 index 00000000..425f6902 --- /dev/null +++ b/spring-ldap-person/src/main/java/org/springframework/ldap/samples/person/dao/CountryContextMapper.java @@ -0,0 +1,41 @@ +/* + * Copyright 2005-2007 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.ldap.samples.person.dao; + +import org.springframework.ldap.core.ContextMapper; +import org.springframework.ldap.core.DirContextOperations; +import org.springframework.ldap.samples.person.domain.Country; + +/** + * Maps from DirContextOperations (DirContextAdapters, really) to Country + * objects. A DN for a country will be of the form c=[name] + * + * @author Ulrik Sandberg + */ +public class CountryContextMapper implements ContextMapper { + + /* + * @see org.springframework.ldap.core.ContextMapper#mapFromContext(java.lang.Object) + */ + public Object mapFromContext(Object ctx) { + DirContextOperations dirContext = (DirContextOperations) ctx; + Country country = new Country(); + country.setName(dirContext.getStringAttribute("c")); + // we don't use country codes, so just use the country name as code + country.setCode(country.getName()); + return country; + } +} diff --git a/spring-ldap-person/src/main/java/org/springframework/ldap/samples/person/dao/CountryDao.java b/spring-ldap-person/src/main/java/org/springframework/ldap/samples/person/dao/CountryDao.java new file mode 100644 index 00000000..77d7b0d3 --- /dev/null +++ b/spring-ldap-person/src/main/java/org/springframework/ldap/samples/person/dao/CountryDao.java @@ -0,0 +1,27 @@ +/* + * Copyright 2005-2007 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.ldap.samples.person.dao; + +import java.util.List; + +/** + * Data Access Object interface for the Country entity. + * + * @author Ulrik Sandberg + */ +public interface CountryDao { + public List findAll(); +} diff --git a/spring-ldap-person/src/main/java/org/springframework/ldap/samples/person/dao/CountryDaoImpl.java b/spring-ldap-person/src/main/java/org/springframework/ldap/samples/person/dao/CountryDaoImpl.java new file mode 100644 index 00000000..9cbc56df --- /dev/null +++ b/spring-ldap-person/src/main/java/org/springframework/ldap/samples/person/dao/CountryDaoImpl.java @@ -0,0 +1,58 @@ +/* + * Copyright 2005-2007 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.ldap.samples.person.dao; + +import java.util.List; + +import org.springframework.ldap.core.ContextMapper; +import org.springframework.ldap.core.DistinguishedName; +import org.springframework.ldap.core.LdapOperations; +import org.springframework.ldap.filter.EqualsFilter; + +/** + * Default implementation of CountryDao. This implementation uses + * DirContextOperations (DirContextAdapter really, but for mock testing purposes + * we use the interface) for managing attribute values. It has been specified in + * the Spring Context that the DirObjectFactory should be used when creating + * objects from contexts, which defaults to creating DirContextAdapter objects. + * This means that we can use a ContextMapper to map from the found contexts to + * our domain objects. + * + * @author Ulrik Sandberg + */ +public class CountryDaoImpl implements CountryDao { + /** + * The template object that performs all data access work. + */ + LdapOperations ldapOperations; + + /* + * @see org.springframework.ldap.samples.person.dao.CountryDao#findAll() + */ + public List findAll() { + EqualsFilter filter = new EqualsFilter("objectclass", "country"); + return ldapOperations.search(DistinguishedName.EMPTY_PATH, filter + .encode(), getContextMapper()); + } + + ContextMapper getContextMapper() { + return new CountryContextMapper(); + } + + public void setLdapOperations(LdapOperations ldapOperations) { + this.ldapOperations = ldapOperations; + } +} diff --git a/spring-ldap-person/src/main/java/org/springframework/ldap/samples/person/domain/Company.java b/spring-ldap-person/src/main/java/org/springframework/ldap/samples/person/domain/Company.java new file mode 100644 index 00000000..dc3e3f31 --- /dev/null +++ b/spring-ldap-person/src/main/java/org/springframework/ldap/samples/person/domain/Company.java @@ -0,0 +1,53 @@ +/* + * Copyright 2005-2007 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.ldap.samples.person.domain; + +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; +import org.springframework.core.style.ToStringCreator; + +/** + * Simple class representing a company. + * + * @author Ulrik Sandberg + */ +public class Company { + + private String name; + + public boolean equals(Object obj) { + if (obj == null || getClass() != obj.getClass()) { + return false; + } + return EqualsBuilder.reflectionEquals(this, obj); + } + + public int hashCode() { + return HashCodeBuilder.reflectionHashCode(this); + } + + public String toString() { + return new ToStringCreator(this).toString(); + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/spring-ldap-person/src/main/java/org/springframework/ldap/samples/person/domain/Country.java b/spring-ldap-person/src/main/java/org/springframework/ldap/samples/person/domain/Country.java new file mode 100644 index 00000000..80edeccd --- /dev/null +++ b/spring-ldap-person/src/main/java/org/springframework/ldap/samples/person/domain/Country.java @@ -0,0 +1,63 @@ +/* + * Copyright 2005-2007 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.ldap.samples.person.domain; + +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; +import org.springframework.core.style.ToStringCreator; + +/** + * Simple class representing a country. + * + * @author Ulrik Sandberg + */ +public class Country { + + private String code; + + private String name; + + public boolean equals(Object obj) { + if (obj == null || getClass() != obj.getClass()) { + return false; + } + return EqualsBuilder.reflectionEquals(this, obj); + } + + public int hashCode() { + return HashCodeBuilder.reflectionHashCode(this); + } + + public String toString() { + return new ToStringCreator(this).toString(); + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/spring-ldap-person/src/main/java/org/springframework/ldap/samples/person/options/CompanyConverter.java b/spring-ldap-person/src/main/java/org/springframework/ldap/samples/person/options/CompanyConverter.java new file mode 100644 index 00000000..914068f4 --- /dev/null +++ b/spring-ldap-person/src/main/java/org/springframework/ldap/samples/person/options/CompanyConverter.java @@ -0,0 +1,38 @@ +/* + * Copyright 2005-2007 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.ldap.samples.person.options; + +import net.sf.chainedoptions.AbstractBeanConverter; +import net.sf.chainedoptions.LabelValueBean; + +import org.springframework.ldap.samples.person.domain.Company; + +/** + * Responsible for converting the properties of a Company domain object into a + * LabelValueBean. + * + * @author Ulrik Sandberg + */ +public class CompanyConverter extends AbstractBeanConverter { + + /* + * @see net.sf.chainedoptions.AbstractBeanConverter#convertBean(java.lang.Object) + */ + protected LabelValueBean convertBean(Object bean) { + Company company = (Company) bean; + return new LabelValueBean(company.getName(), company.getName()); + } +} diff --git a/spring-ldap-person/src/main/java/org/springframework/ldap/samples/person/options/CompanyOption.java b/spring-ldap-person/src/main/java/org/springframework/ldap/samples/person/options/CompanyOption.java new file mode 100644 index 00000000..a62fa49e --- /dev/null +++ b/spring-ldap-person/src/main/java/org/springframework/ldap/samples/person/options/CompanyOption.java @@ -0,0 +1,68 @@ +/* + * Copyright 2005-2007 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.ldap.samples.person.options; + +import java.util.List; + +import net.sf.chainedoptions.AbstractChainedOption; +import net.sf.chainedoptions.BeanConverter; +import net.sf.chainedoptions.ChainedOptionStrategy; + +import org.springframework.ldap.samples.person.dao.CompanyDao; +import org.springframework.util.Assert; + +/** + * Responsible for retrieving available companies for a given country, sorting + * them, and adjusting the command object if necessary. Collaborates with + * {@link ChainedOptionStrategy}, {@link BeanConverter}, {@link CompanyDao}. + * + * @author Ulrik Sandberg + */ +public class CompanyOption extends AbstractChainedOption { + + private String countryProperty; + + private CompanyDao companyDao; + + /* + * @see net.sf.chainedoptions.AbstractChainedOption#retrieveOptions(java.lang.Object, + * java.lang.Object) + */ + public List retrieveOptions(Object command, Object context) { + String country = (String) getProperty(command, countryProperty); + List companyBeans = companyDao.findByCountry(country); + List companies = getConverter().convert(companyBeans); + return getStrategy(command).adjustAndSort(companies, context); + } + + /* + * @see net.sf.chainedoptions.AbstractChainedOption#initChainedOption() + */ + protected void initChainedOption() { + super.initChainedOption(); + Assert.notNull(companyDao, "Property ÕcompanyDaoÕ must be set"); + Assert.notNull(countryProperty, "Property ÕcountryPropertyÕ must be set"); + Assert.notNull(getConverter(), "Property ÕconverterÕ must be set"); + } + + public void setCompanyDao(CompanyDao companyDao) { + this.companyDao = companyDao; + } + + public void setCountryProperty(String countryProperty) { + this.countryProperty = countryProperty; + } +} diff --git a/spring-ldap-person/src/main/java/org/springframework/ldap/samples/person/options/CountryConverter.java b/spring-ldap-person/src/main/java/org/springframework/ldap/samples/person/options/CountryConverter.java new file mode 100644 index 00000000..abd7ea05 --- /dev/null +++ b/spring-ldap-person/src/main/java/org/springframework/ldap/samples/person/options/CountryConverter.java @@ -0,0 +1,38 @@ +/* + * Copyright 2005-2007 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.ldap.samples.person.options; + +import org.springframework.ldap.samples.person.domain.Country; + +import net.sf.chainedoptions.AbstractBeanConverter; +import net.sf.chainedoptions.LabelValueBean; + +/** + * Responsible for converting the properties of a Country domain object into a + * LabelValueBean. + * + * @author Ulrik Sandberg + */ +public class CountryConverter extends AbstractBeanConverter { + + /* + * @see net.sf.chainedoptions.AbstractBeanConverter#convertBean(java.lang.Object) + */ + protected LabelValueBean convertBean(Object bean) { + Country country = (Country) bean; + return new LabelValueBean(country.getName(), country.getCode()); + } +} diff --git a/spring-ldap-person/src/main/java/org/springframework/ldap/samples/person/options/CountryOption.java b/spring-ldap-person/src/main/java/org/springframework/ldap/samples/person/options/CountryOption.java new file mode 100644 index 00000000..350c017b --- /dev/null +++ b/spring-ldap-person/src/main/java/org/springframework/ldap/samples/person/options/CountryOption.java @@ -0,0 +1,60 @@ +/* + * Copyright 2005-2007 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.ldap.samples.person.options; + +import java.util.List; + +import net.sf.chainedoptions.AbstractChainedOption; +import net.sf.chainedoptions.BeanConverter; +import net.sf.chainedoptions.ChainedOptionStrategy; + +import org.springframework.ldap.samples.person.dao.CountryDao; +import org.springframework.util.Assert; + +/** + * Responsible for retrieving available countries, sorting them, and adjusting + * the command object if necessary. Collaborates with + * {@link ChainedOptionStrategy}, {@link BeanConverter}, {@link CountryDao}. + * + * @author Ulrik Sandberg + */ +public class CountryOption extends AbstractChainedOption { + + private CountryDao countryDao; + + /* + * @see net.sf.chainedoptions.AbstractChainedOption#retrieveOptions(java.lang.Object, + * java.lang.Object) + */ + public List retrieveOptions(Object command, Object context) { + List countryBeans = countryDao.findAll(); + List countries = getConverter().convert(countryBeans); + return getStrategy(command).adjustAndSort(countries, context); + } + + /* + * @see net.sf.chainedoptions.AbstractChainedOption#initChainedOption() + */ + protected void initChainedOption() { + super.initChainedOption(); + Assert.notNull(countryDao, "Property ÕcountryDaoÕ must be set"); + Assert.notNull(getConverter(), "Property ÕconverterÕ must be set"); + } + + public void setCountryDao(CountryDao countryDao) { + this.countryDao = countryDao; + } +} diff --git a/spring-ldap-person/src/main/java/org/springframework/ldap/samples/person/web/EditPersonFormAction.java b/spring-ldap-person/src/main/java/org/springframework/ldap/samples/person/web/EditPersonFormAction.java index c7797d0a..99f9bdfc 100644 --- a/spring-ldap-person/src/main/java/org/springframework/ldap/samples/person/web/EditPersonFormAction.java +++ b/spring-ldap-person/src/main/java/org/springframework/ldap/samples/person/web/EditPersonFormAction.java @@ -16,23 +16,28 @@ package org.springframework.ldap.samples.person.web; +import net.sf.chainedoptions.ChainedOptionManager; + import org.springframework.beans.PropertyEditorRegistry; import org.springframework.beans.propertyeditors.StringArrayPropertyEditor; +import org.springframework.util.Assert; import org.springframework.webflow.action.FormAction; +import org.springframework.webflow.execution.Event; import org.springframework.webflow.execution.RequestContext; /** * Action implementation that handles edit of a person. Registers appropriate - * property editors. + * property editors, and provides an action method for setting up reference + * data. * * @author Mattias Arthursson - * + * @author Ulrik Sandberg */ public class EditPersonFormAction extends FormAction { + private ChainedOptionManager chainedOptionManager; + /* - * (non-Javadoc) - * * @see org.springframework.webflow.action.FormAction#registerPropertyEditors(org.springframework.webflow.execution.RequestContext, * org.springframework.beans.PropertyEditorRegistry) */ @@ -41,4 +46,25 @@ public class EditPersonFormAction extends FormAction { registry.registerCustomEditor(String[].class, new StringArrayPropertyEditor()); } + + public Event referenceData(RequestContext context) throws Exception { + if (logger.isDebugEnabled()) { + logger.debug("Executing referenceData"); + } + + Object formObject = getFormObject(context); + chainedOptionManager.referenceData(context.getRequestScope().asMap(), + formObject, null); + return success(); + } + + protected void initAction() { + Assert.notNull(chainedOptionManager, + "The property 'chainedOptionManager' must not be null"); + } + + public void setChainedOptionManager( + ChainedOptionManager chainedOptionManager) { + this.chainedOptionManager = chainedOptionManager; + } } diff --git a/spring-ldap-person/src/main/webapp/WEB-INF/applicationContext.xml b/spring-ldap-person/src/main/webapp/WEB-INF/applicationContext.xml index 92d006d6..429e288e 100644 --- a/spring-ldap-person/src/main/webapp/WEB-INF/applicationContext.xml +++ b/spring-ldap-person/src/main/webapp/WEB-INF/applicationContext.xml @@ -73,11 +73,21 @@ - - - - + + + + + + + + + + + + diff --git a/spring-ldap-person/src/main/webapp/WEB-INF/flows/detail-flow-beans.xml b/spring-ldap-person/src/main/webapp/WEB-INF/flows/detail-flow-beans.xml index e10ecb70..ed8022db 100644 --- a/spring-ldap-person/src/main/webapp/WEB-INF/flows/detail-flow-beans.xml +++ b/spring-ldap-person/src/main/webapp/WEB-INF/flows/detail-flow-beans.xml @@ -9,7 +9,8 @@ - + + \ No newline at end of file diff --git a/spring-ldap-person/src/main/webapp/WEB-INF/flows/detail-flow.xml b/spring-ldap-person/src/main/webapp/WEB-INF/flows/detail-flow.xml index 1d8c5c1c..9ec184cb 100644 --- a/spring-ldap-person/src/main/webapp/WEB-INF/flows/detail-flow.xml +++ b/spring-ldap-person/src/main/webapp/WEB-INF/flows/detail-flow.xml @@ -28,28 +28,36 @@ - + - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/spring-ldap-person/src/main/webapp/WEB-INF/jsp/editDetails.jsp b/spring-ldap-person/src/main/webapp/WEB-INF/jsp/editDetails.jsp index 2da82db7..5d7850bc 100644 --- a/spring-ldap-person/src/main/webapp/WEB-INF/jsp/editDetails.jsp +++ b/spring-ldap-person/src/main/webapp/WEB-INF/jsp/editDetails.jsp @@ -24,26 +24,23 @@ - Company - + Country + - Country - + Company + Phone - - Description - - - - + + + diff --git a/spring-ldap-person/src/main/webapp/WEB-INF/jsp/showAddCandidates.jsp b/spring-ldap-person/src/main/webapp/WEB-INF/jsp/showAddCandidates.jsp index 58f6f3f3..79790f56 100644 --- a/spring-ldap-person/src/main/webapp/WEB-INF/jsp/showAddCandidates.jsp +++ b/spring-ldap-person/src/main/webapp/WEB-INF/jsp/showAddCandidates.jsp @@ -37,8 +37,8 @@ ${person.fullName} - ${person.company} ${person.country} + ${person.company} ${person.phone} diff --git a/spring-ldap-person/src/main/webapp/WEB-INF/jsp/showDetails.jsp b/spring-ldap-person/src/main/webapp/WEB-INF/jsp/showDetails.jsp index 91a772ad..7d6641ce 100644 --- a/spring-ldap-person/src/main/webapp/WEB-INF/jsp/showDetails.jsp +++ b/spring-ldap-person/src/main/webapp/WEB-INF/jsp/showDetails.jsp @@ -10,31 +10,23 @@ Person Details -
+
Name ${person.fullName} - - Company - ${person.company} - Country ${person.country} - Phone - ${person.phone} + Company + ${person.company} - Description - - - ${description}
-
- + Phone + ${person.phone} diff --git a/spring-ldap-person/src/main/webapp/WEB-INF/optionsContext.xml b/spring-ldap-person/src/main/webapp/WEB-INF/optionsContext.xml new file mode 100644 index 00000000..34ca51ce --- /dev/null +++ b/spring-ldap-person/src/main/webapp/WEB-INF/optionsContext.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + country + + + countries + + + + + + + + + + + + + + + company + + + companies + + + country + + + + + + + + + diff --git a/spring-ldap-person/src/main/webapp/WEB-INF/web.xml b/spring-ldap-person/src/main/webapp/WEB-INF/web.xml index 3c3ccb4d..fd27f77c 100644 --- a/spring-ldap-person/src/main/webapp/WEB-INF/web.xml +++ b/spring-ldap-person/src/main/webapp/WEB-INF/web.xml @@ -8,7 +8,7 @@ version="2.4"> LdapTemplate Example contextConfigLocation - /WEB-INF/applicationContext.xml /WEB-INF/applicationContext-acegi-security.xml + /WEB-INF/applicationContext.xml /WEB-INF/applicationContext-acegi-security.xml /WEB-INF/optionsContext.xml diff --git a/spring-ldap-person/src/test/java/org/springframework/ldap/samples/person/dao/CompanyDaoImplTest.java b/spring-ldap-person/src/test/java/org/springframework/ldap/samples/person/dao/CompanyDaoImplTest.java new file mode 100644 index 00000000..83d0dc36 --- /dev/null +++ b/spring-ldap-person/src/test/java/org/springframework/ldap/samples/person/dao/CompanyDaoImplTest.java @@ -0,0 +1,97 @@ +/* + * Copyright 2005-2007 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.ldap.samples.person.dao; + +import java.util.Collections; +import java.util.List; + +import junit.framework.TestCase; + +import org.easymock.MockControl; +import org.springframework.ldap.core.ContextMapper; +import org.springframework.ldap.core.DistinguishedName; +import org.springframework.ldap.core.LdapOperations; + +/** + * Unit tests for the CompanyDaoImpl class. + * + * @author Ulrik Sandberg + */ +public class CompanyDaoImplTest extends TestCase { + + private MockControl ldapOperationsControl; + + private LdapOperations ldapOperationsMock; + + private MockControl contextMapperControl; + + private ContextMapper contextMapperMock; + + private CompanyDaoImpl tested; + + protected void setUp() throws Exception { + super.setUp(); + ldapOperationsControl = MockControl.createControl(LdapOperations.class); + ldapOperationsMock = (LdapOperations) ldapOperationsControl.getMock(); + + contextMapperControl = MockControl.createControl(ContextMapper.class); + contextMapperMock = (ContextMapper) contextMapperControl.getMock(); + + tested = new CompanyDaoImpl() { + ContextMapper getContextMapper() { + return contextMapperMock; + } + }; + tested.setLdapOperations(ldapOperationsMock); + } + + protected void tearDown() throws Exception { + super.tearDown(); + + ldapOperationsControl = null; + ldapOperationsMock = null; + + contextMapperControl = null; + contextMapperMock = null; + + tested = null; + } + + protected void replay() { + ldapOperationsControl.replay(); + contextMapperControl.replay(); + } + + protected void verify() { + ldapOperationsControl.verify(); + contextMapperControl.verify(); + } + + public void testFindByCountry() { + List expectedList = Collections.singletonList(null); + ldapOperationsControl.expectAndReturn(ldapOperationsMock.search( + new DistinguishedName("c=Sweden"), "(objectclass=organizationalUnit)", + contextMapperMock), expectedList); + + replay(); + + List result = tested.findByCountry("Sweden"); + + verify(); + + assertSame(expectedList, result); + } +} diff --git a/spring-ldap-person/src/test/java/org/springframework/ldap/samples/person/dao/CountryDaoImplTest.java b/spring-ldap-person/src/test/java/org/springframework/ldap/samples/person/dao/CountryDaoImplTest.java new file mode 100644 index 00000000..49d9f2bd --- /dev/null +++ b/spring-ldap-person/src/test/java/org/springframework/ldap/samples/person/dao/CountryDaoImplTest.java @@ -0,0 +1,97 @@ +/* + * Copyright 2005-2007 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.ldap.samples.person.dao; + +import java.util.Collections; +import java.util.List; + +import junit.framework.TestCase; + +import org.easymock.MockControl; +import org.springframework.ldap.core.ContextMapper; +import org.springframework.ldap.core.DistinguishedName; +import org.springframework.ldap.core.LdapOperations; + +/** + * Unit tests for the CountryDaoImpl class. + * + * @author Ulrik Sandberg + */ +public class CountryDaoImplTest extends TestCase { + + private MockControl ldapOperationsControl; + + private LdapOperations ldapOperationsMock; + + private MockControl contextMapperControl; + + private ContextMapper contextMapperMock; + + private CountryDaoImpl tested; + + protected void setUp() throws Exception { + super.setUp(); + ldapOperationsControl = MockControl.createControl(LdapOperations.class); + ldapOperationsMock = (LdapOperations) ldapOperationsControl.getMock(); + + contextMapperControl = MockControl.createControl(ContextMapper.class); + contextMapperMock = (ContextMapper) contextMapperControl.getMock(); + + tested = new CountryDaoImpl() { + ContextMapper getContextMapper() { + return contextMapperMock; + } + }; + tested.setLdapOperations(ldapOperationsMock); + } + + protected void tearDown() throws Exception { + super.tearDown(); + + ldapOperationsControl = null; + ldapOperationsMock = null; + + contextMapperControl = null; + contextMapperMock = null; + + tested = null; + } + + protected void replay() { + ldapOperationsControl.replay(); + contextMapperControl.replay(); + } + + protected void verify() { + ldapOperationsControl.verify(); + contextMapperControl.verify(); + } + + public void testFindAll() { + List expectedList = Collections.singletonList(null); + ldapOperationsControl.expectAndReturn(ldapOperationsMock.search( + DistinguishedName.EMPTY_PATH, "(objectclass=country)", + contextMapperMock), expectedList); + + replay(); + + List result = tested.findAll(); + + verify(); + + assertSame(expectedList, result); + } +} diff --git a/spring-ldap-person/src/test/java/org/springframework/ldap/samples/person/web/DetailFlowExecutionTest.java b/spring-ldap-person/src/test/java/org/springframework/ldap/samples/person/web/DetailFlowExecutionTest.java index fc1ad40b..9ad6e7a2 100644 --- a/spring-ldap-person/src/test/java/org/springframework/ldap/samples/person/web/DetailFlowExecutionTest.java +++ b/spring-ldap-person/src/test/java/org/springframework/ldap/samples/person/web/DetailFlowExecutionTest.java @@ -15,6 +15,10 @@ */ package org.springframework.ldap.samples.person.web; +import java.util.HashMap; + +import net.sf.chainedoptions.ChainedOptionManager; + import org.easymock.MockControl; import org.springframework.ldap.samples.person.domain.Person; import org.springframework.ldap.samples.person.service.PersonService; @@ -31,6 +35,10 @@ public class DetailFlowExecutionTest extends AbstractXmlFlowExecutionTests { private PersonService personServiceMock; + private MockControl chainedOptionManagerControl; + + private ChainedOptionManager chainedOptionManagerMock; + private MutableAttributeMap attributeMap; protected void setUp() throws Exception { @@ -39,6 +47,9 @@ public class DetailFlowExecutionTest extends AbstractXmlFlowExecutionTests { personServiceControl = MockControl.createControl(PersonService.class); personServiceMock = (PersonService) personServiceControl.getMock(); + chainedOptionManagerControl = MockControl.createControl(ChainedOptionManager.class); + chainedOptionManagerMock = (ChainedOptionManager) chainedOptionManagerControl.getMock(); + attributeMap = new LocalAttributeMap(); attributeMap.put("country", "Sweden"); attributeMap.put("company", "company1"); @@ -49,14 +60,18 @@ public class DetailFlowExecutionTest extends AbstractXmlFlowExecutionTests { super.tearDown(); personServiceControl = null; personServiceMock = null; + chainedOptionManagerControl = null; + chainedOptionManagerMock = null; } protected void replay() { personServiceControl.replay(); + chainedOptionManagerControl.replay(); } protected void verify() { personServiceControl.verify(); + chainedOptionManagerControl.verify(); } public void testStartFlow() { @@ -84,6 +99,7 @@ public class DetailFlowExecutionTest extends AbstractXmlFlowExecutionTests { public void testEdit() { expectFindByPrimaryKey(); + expectReferenceData(); replay(); startFlow(attributeMap); @@ -97,6 +113,7 @@ public class DetailFlowExecutionTest extends AbstractXmlFlowExecutionTests { public void testCancel() { expectFindByPrimaryKey(); + expectReferenceData(); replay(); startFlow(attributeMap); @@ -111,6 +128,7 @@ public class DetailFlowExecutionTest extends AbstractXmlFlowExecutionTests { public void testSubmit() { expectFindByPrimaryKey(); + expectReferenceData(); expectUpdate(); replay(); @@ -124,6 +142,12 @@ public class DetailFlowExecutionTest extends AbstractXmlFlowExecutionTests { assertModelAttributeNotNull("person", view); } + private void expectReferenceData() { + Person person = setupPerson(); + HashMap map = new HashMap(); + chainedOptionManagerMock.referenceData(map, person, null); + } + private void expectFindByPrimaryKey() { expectFindByPrimaryKey(1); } @@ -163,5 +187,6 @@ public class DetailFlowExecutionTest extends AbstractXmlFlowExecutionTests { */ protected void registerMockServices(MockFlowServiceLocator serviceRegistry) { serviceRegistry.registerBean("personService", personServiceMock); + serviceRegistry.registerBean("editPersonChainedOptionManager", chainedOptionManagerMock); } } \ No newline at end of file