Initial import.

This commit is contained in:
Mark Paluch
2016-11-21 15:53:45 +01:00
commit 9bbf0389e2
47 changed files with 3624 additions and 0 deletions

17
.gitignore vendored Normal file
View File

@@ -0,0 +1,17 @@
.DS_Store
*.iml
*.ipr
*.iws
*.orig
target
.springBeans
.sonar4clipse
*.sonar4clipseExternals
.ant-targets-build.xml
.settings/
.project
.classpath
src/ant/.ant-targets-upload-dist.xml
atlassian-ide-plugin.xml
/.gradle/
/.idea/

18
.travis.yml Normal file
View File

@@ -0,0 +1,18 @@
language: java
jdk:
- oraclejdk8
env:
matrix:
- PROFILE=ci
sudo: false
cache:
directories:
- $HOME/.m2
install: true
script: "mvn clean dependency:list test -P${PROFILE} -Dsort"

27
CODE_OF_CONDUCT.adoc Normal file
View File

@@ -0,0 +1,27 @@
= Contributor Code of Conduct
As contributors and maintainers of this project, and in the interest of fostering an open and welcoming community, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.
We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, religion, or nationality.
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery
* Personal attacks
* Trolling or insulting/derogatory comments
* Public or private harassment
* Publishing other's private information, such as physical or electronic addresses,
without explicit permission
* Other unethical or unprofessional conduct
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
By adopting this Code of Conduct, project maintainers commit themselves to fairly and consistently applying these principles to every aspect of managing this project. Project maintainers who do not follow or enforce the Code of Conduct may be permanently removed from the project team.
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community.
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting a project maintainer at spring-code-of-conduct@pivotal.io.
All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances.
Maintainers are obligated to maintain confidentiality with regard to the reporter of an incident.
This Code of Conduct is adapted from the http://contributor-covenant.org[Contributor Covenant], version 1.3.0, available at http://contributor-covenant.org/version/1/3/0/[contributor-covenant.org/version/1/3/0/].

3
CONTRIBUTING.adoc Normal file
View File

@@ -0,0 +1,3 @@
= Spring Data contribution guidelines
You find the contribution guidelines for Spring Data projects https://github.com/spring-projects/spring-data-build/blob/master/CONTRIBUTING.adoc[here].

116
README.md Normal file
View File

@@ -0,0 +1,116 @@
[![Spring Data LDAP](https://spring.io/badges/spring-data-ldap/ga.svg)](http://projects.spring.io/spring-data-ldap#quick-start)
[![Spring Data LDAP](https://spring.io/badges/spring-data-ldap/snapshot.svg)](http://projects.spring.io/spring-data-ldap#quick-start)
# Spring Data LDAP
The primary goal of the [Spring Data](http://projects.spring.io/spring-data) project is to make it easier to build Spring-powered applications that use new data access technologies such as non-relational databases, map-reduce frameworks, and cloud based data services.
The Spring Data LDAP project aims to provide familiar and consistent repository abstractions for [Spring LDAP](https://github.com/spring-projects/spring-ldap).
## Getting Help
For a comprehensive treatment of all the Spring Data LDAP features, please refer to:
* the [User Guide](http://docs.spring.io/spring-data/ldap/docs/current/reference/html/)
* the [JavaDocs](http://docs.spring.io/spring-data/ldap/docs/current/api/) have extensive comments in them as well.
* the home page of [Spring Data LDAP](http://projects.spring.io/spring-data-ldap) contains links to articles and other resources.
* for more detailed questions, use [Spring Data LDAP on Stackoverflow](http://stackoverflow.com/questions/tagged/spring-data-ldap).
If you are new to Spring as well as to Spring Data, look for information about [Spring projects](http://projects.spring.io/).
## Quick Start
### Maven configuration
Add the Maven dependency:
```xml
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-ldap</artifactId>
<version>${version}.RELEASE</version>
</dependency>
```
If you'd rather like the latest snapshots of the upcoming major version, use our Maven snapshot repository and declare the appropriate dependency version.
```xml
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-ldap</artifactId>
<version>${version}.BUILD-SNAPSHOT</version>
</dependency>
<repository>
<id>spring-libs-snapshot</id>
<name>Spring Snapshot Repository</name>
<url>http://repo.spring.io/libs-snapshot</url>
</repository>
```
### Spring Data repositories
To simplify the creation of data repositories Spring Data LDAP provides a generic repository programming model. It will automatically create a repository proxy for you that adds implementations of finder methods you specify on an interface.
For example, given a `Person` class with first and last name properties, a `PersonRepository` interface that can query for `Person` by last name and when the first name matches a like expression is shown below:
```java
public interface PersonRepository extends CrudRepository<Person, Name> {
List<Person> findByLastname(String lastname);
List<Person> findByFirstnameLike(String firstname);
}
```
The queries issued on execution will be derived from the method name. Extending `CrudRepository` causes CRUD methods being pulled into the interface so that you can easily save and find single entities and collections of them.
You can have Spring automatically create a proxy for the interface by using the following JavaConfig:
```java
@Configuration
@EnableLdapRepositories
class ApplicationConfig {
}
```
This will find the repository interface and register a proxy object in the container. You can use it as shown below:
```java
@Service
public class MyService {
private final PersonRepository repository;
@Autowired
public MyService(PersonRepository repository) {
this.repository = repository;
}
public void doWork() {
repository.deleteAll();
Person person = new Person();
person.setFirstname("Rob");
person.setLastname("Winch");
person = repository.save(person);
List<Person> lastNameResults = repository.findByLastname("Winch");
List<Person> firstNameResults = repository.findByFirstnameLike("Ro*");
}
}
```
## Contributing to Spring Data
Here are some ways for you to get involved in the community:
* Get involved with the Spring community on Stackoverflow and help out on the [spring-data-ldap](http://stackoverflow.com/questions/tagged/spring-data-ldap) tag by responding to questions and joining the debate.
* Create [JIRA](https://jira.springframework.org/browse/DATALDAP) tickets for bugs and new features and comment and vote on the ones that you are interested in.
* Github is for social coding: if you want to write code, we encourage contributions through pull requests from [forks of this repository](http://help.github.com/forking/). If you want to contribute code this way, please reference a JIRA ticket as well covering the specific issue you are addressing.
* Watch for upcoming articles on Spring by [subscribing](http://spring.io/blog) to spring.io.
Before we accept a non-trivial patch or pull request we will need you to sign the [contributor's agreement](https://support.springsource.com/spring_committer_signup). Signing the contributor's agreement does not grant anyone commit rights to the main repository, but it does mean that we can accept your contributions, and you will get an author credit if we do. Active contributors might be asked to join the core team, and given the ability to merge pull requests.

291
etc/formatting.xml Normal file
View File

@@ -0,0 +1,291 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<profiles version="12">
<profile kind="CodeFormatterProfile" name="Spring Data" version="12">
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.disabling_tag" value="@formatter:off"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_field" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.use_on_off_tags" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_ellipsis" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_multiple_fields" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression" value="80"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_binary_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_array_initializer" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_package" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation" value="2"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_binary_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_package" value="0"/>
<setting id="org.eclipse.jdt.core.compiler.source" value="1.7"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_line_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.join_wrapped_lines" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_member_type" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.align_type_members_on_columns" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_unary_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.indent_parameter_description" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.lineSplit" value="120"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.indentation.size" value="2"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.enabling_tag" value="@formatter:on"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_assignment" value="0"/>
<setting id="org.eclipse.jdt.core.compiler.problem.assertIdentifier" value="error"/>
<setting id="org.eclipse.jdt.core.formatter.tabulation.char" value="tab"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_body" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_method" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_method_declaration" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_switch" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.compiler.problem.enumIdentifier" value="error"/>
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_ellipsis" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_method_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.compact_else_if" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.indent_root_tags" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_constant" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.tabulation.size" value="2"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_empty_lines" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block_in_case" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter" value="insert"/>
<setting id="org.eclipse.jdt.core.compiler.compliance" value="1.7"/>
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer" value="2"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_unary_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_binary_expression" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while" value="do not insert"/>
<setting id="org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode" value="enabled"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_label" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_javadoc_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.comment.line_length" value="120"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_import_groups" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_binary_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_block" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.join_lines_in_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_compact_if" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_imports" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_html" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_source_code" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer" value="insert"/>
<setting id="org.eclipse.jdt.core.compiler.codegen.targetPlatform" value="1.7"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_resources_in_try" value="80"/>
<setting id="org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_header" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_block_comments" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_enum_constants" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_type_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_imports" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line" value="false"/>
</profile>
</profiles>

168
pom.xml Normal file
View File

@@ -0,0 +1,168 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-ldap</artifactId>
<version>1.0.0.BUILD-SNAPSHOT</version>
<name>Spring Data LDAP</name>
<description>Spring Data integration for LDAP</description>
<url>https://github.com/spring-projects/spring-data-ldap</url>
<parent>
<groupId>org.springframework.data.build</groupId>
<artifactId>spring-data-parent</artifactId>
<version>1.9.0.BUILD-SNAPSHOT</version>
</parent>
<properties>
<spring-ldap>2.2.0.BUILD-SNAPSHOT</spring-ldap>
<springdata.commons>1.13.0.BUILD-SNAPSHOT</springdata.commons>
<assertj>3.5.2</assertj>
<bundlor.enabled>false</bundlor.enabled>
</properties>
<developers>
<developer>
<id>rwinch</id>
<name>Rob Winch</name>
<email>rwinch at pivotal.io</email>
<organization>Pivotal</organization>
<organizationUrl>http://www.pivotal.io</organizationUrl>
<roles>
<role>Project Lead</role>
</roles>
<timezone>-6</timezone>
</developer>
<developer>
<id>mpaluch</id>
<name>Mark Paluch</name>
<email>mpaluch at pivotal.io</email>
<organization>Pivotal</organization>
<organizationUrl>http://www.pivotal.io</organizationUrl>
<roles>
<role>Developer</role>
</roles>
<timezone>+1</timezone>
</developer>
</developers>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.ldap</groupId>
<artifactId>spring-ldap-core</artifactId>
<version>${spring-ldap}</version>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>spring-data-commons</artifactId>
<version>${springdata.commons}</version>
</dependency>
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-mongodb</artifactId>
<version>${querydsl}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-apt</artifactId>
<version>${querydsl}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>${assertj}</version>
<scope>test</scope>
</dependency>
</dependencies>
<repositories>
<repository>
<id>spring-libs-snapshot</id>
<url>https://repo.spring.io/libs-snapshot</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-plugins-release</id>
<url>https://repo.spring.io/plugins-release</url>
</pluginRepository>
</pluginRepositories>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>wagon-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.asciidoctor</groupId>
<artifactId>asciidoctor-maven-plugin</artifactId>
<configuration>
<attributes>
<version>${project.version}</version>
<projectName>${project.name}</projectName>
<projectVersion>${project.version}</projectVersion>
<aspectjVersion>${aspectj}</aspectjVersion>
<querydslVersion>${querydsl}</querydslVersion>
<springVersion>${spring}</springVersion>
<releasetrainVersion>${releasetrain}</releasetrainVersion>
<springLdapVersion>${spring-ldap}</springLdapVersion>
<allow-uri-read>true</allow-uri-read>
<toclevels>3</toclevels>
<numbered>true</numbered>
</attributes>
</configuration>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>release</id>
<build>
<plugins>
<plugin>
<groupId>org.jfrog.buildinfo</groupId>
<artifactId>artifactory-maven-plugin</artifactId>
<inherited>false</inherited>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>

View File

@@ -0,0 +1,40 @@
= Spring Data LDAP - Reference Documentation
Mattias Hellborg Arthursson; Ulrik Sandberg; Eric Dalquist; Keith Barlow; Rob Winch; Mark Paluch
:revnumber: {version}
:revdate: {localdate}
:toc:
:toc-placement!:
:spring-data-commons-docs: ../../../../spring-data-commons/src/main/asciidoc
(C) 2008-2016 The original authors.
NOTE: _Copies of this document may be made for your own use and for distribution to others, provided that you do not charge any fee for such copies and further provided that each copy contains this Copyright Notice, whether distributed in print or electronically._
toc::[]
include::preface.adoc[]
:leveloffset: +1
include::new-features.adoc[]
include::{spring-data-commons-docs}/dependencies.adoc[]
include::{spring-data-commons-docs}/repositories.adoc[]
:leveloffset: -1
[[reference]]
= Reference Documentation
:leveloffset: +1
include::reference/introduction.adoc[]
include::reference/ldap-repositories.adoc[]
:leveloffset: -1
[[appendix]]
= Appendix
:numbered!:
:leveloffset: +1
include::{spring-data-commons-docs}/repository-namespace-reference.adoc[]
include::{spring-data-commons-docs}/repository-populator-namespace-reference.adoc[]
include::{spring-data-commons-docs}/repository-query-keywords-reference.adoc[]
include::{spring-data-commons-docs}/repository-query-return-types-reference.adoc[]
:leveloffset: -1

View File

@@ -0,0 +1,6 @@
[[new-features]]
= New & Noteworthy
[[new-features.1.0]]
== What's new in Spring Data LDAP 1.0
* Migration of Spring LDAP's repository suport into Spring Data LDAP.

View File

@@ -0,0 +1,43 @@
[[preface]]
= Preface
Spring Data LDAP makes it easier to build Spring-based applications that use the Lightweight Directory Access Protocol with Spring LDAP.
This document is the reference guide for Spring Data - Document Support. It explains Document module concepts and semantics and the syntax for various store namespaces.
[[get-started:first-steps:spring]]
== Knowing Spring
Spring Data uses Spring framework's http://docs.spring.io/spring/docs/4.2.x/spring-framework-reference/html/spring-core.html[core] functionality, such as the http://docs.spring.io/spring/docs/{springVersion}/spring-framework-reference/html/beans.html[IoC] container, http://docs.spring.io/spring/docs/{springVersion}/spring-framework-reference/html/validation.html#core-convert[type conversion system], http://docs.spring.io/spring/docs/{springVersion}/spring-framework-reference/html/expressions.html[expression language], http://docs.spring.io/spring/docs/{springVersion}/spring-framework-reference/html/jmx.html[JMX integration], and portable http://docs.spring.io/spring/docs/{springVersion}/spring-framework-reference/html/dao.html#dao-exceptions[DAO exception hierarchy]. While it is not important to know the Spring APIs, understanding the concepts behind them is. At a minimum, the idea behind IoC should be familiar for whatever IoC container you choose to use.
To learn more about Spring, you can refer to the comprehensive (and sometimes disarming) documentation that explains in detail the Spring Framework. There are a lot of articles, blog entries and books on the matter - take a look at the Spring framework http://spring.io/docs[home page ] for more information.
[[requirements]]
== Requirements
Spring Data LDAP 1.x binaries requires JDK level 6.0 and above, http://spring.io/docs[Spring Framework] {springVersion} and above, and http://projects.spring.io/spring-ldap[Spring LDAP] {springLdapVersion} and above.
== Additional Help Resources
Learning a new framework is not always straight forward. In this section, we try to provide what we think is an easy to follow guide for starting with Spring Data LDAP module. However, if you encounter issues or you are just looking for an advice, feel free to use one of the links below:
[[get-started:help]]
=== Support
There are a few support options available:
[[get-started:help:community]]
==== Community Forum
Spring Data on Stackoverflow http://stackoverflow.com/questions/tagged/spring-data[Stackoverflow] is a tag for all Spring Data (not just Document) users to share information and help each other. Note that registration is needed *only* for posting.
[[get-started:help:professional]]
==== Professional Support
Professional, from-the-source support, with guaranteed response time, is available from http://pivotal.io/[Pivotal Sofware, Inc.], the company behind Spring Data and Spring.
[[get-started:up-to-date]]
=== Following Development
For information on the Spring Data LDAP source code repository, nightly builds and snapshot artifacts please see the http://projects.spring.io/spring-data-ldap/[Spring Data LDAP homepage]. You can help make Spring Data best serve the needs of the Spring community by interacting with developers through the Community on http://stackoverflow.com/questions/tagged/spring-data[Stackoverflow]. To follow developer activity look for the mailing list information on the Spring Data LDAP homepage. If you encounter a bug or want to suggest an improvement, please create a ticket on the Spring Data issue https://jira.spring.io/browse/DATALDAP[tracker]. To stay up to date with the latest news and announcements in the Spring eco system, subscribe to the Spring Community http://spring.io[Portal]. Lastly, you can follow the Spring http://spring.io/blog[blog ]or the project team on Twitter (http://twitter.com/SpringData[SpringData]).

View File

@@ -0,0 +1,9 @@
[[introduction]]
= Introduction
== Document Structure
This part of the reference documentation explains the core functionality offered by Spring Data LDAP.
<<ldap.repositories>> introduces the repository support for LDAP.

View File

@@ -0,0 +1,200 @@
[[ldap.repositories]]
= LDAP repositories
[[ldap.repo-intro]]
== Introduction
This chapter will point out the specialties for repository support for MongoDB. This builds on the core repository support explained in <<repositories>>. So make sure you've got a sound understanding of the basic concepts explained there.
* Spring LDAP repositories can be enabled using an `<ldap:repositories>` tag in your XML configuration or using an `@EnableLdapRepositories` annotation on a configuration class.
* To include support for `LdapQuery` parameters in automatically generated repositories, have your interface extend `LdapRepository` rather than `CrudRepository`.
* All Spring LDAP repositories must work with entities annotated with the ODM annotations, as described in http://docs.spring.io/spring-ldap/docs/{springLdapVersion}.RELEASE/reference/#odm[Object-Directory Mapping].
* Since all ODM managed classes must have a Distinguished Name as ID, all Spring LDAP repositories must have the ID type parameter set to `javax.naming.Name`.
Indeed, the built-in `LdapRepository` only takes one type parameter; the managed entity class, defaulting ID to `javax.naming.Name`.
* Due to specifics of the LDAP protocol, paging and sorting is not supported for Spring LDAP repositories.
NOTE: Make sure to use ODM annotations like `org.springframework.ldap.odm.annotations.Id`. Using Spring Data's annotation does not work as Spring LDAP uses its own mapping layer.
[[ldap.repo-usage]]
== Usage
To access domain entities stored in a LDAP-compliant directory you can leverage our sophisticated repository support that eases implementing those quite significantly. To do so, simply create an interface for your repository:
.Sample Person entity
====
[source,java]
----
@Entry(objectClasses = { "person", "top" }, base="ou=someOu")
public class Person {
@Id
private Name dn;
@Attribute(name="cn")
@DnAttribute(value="cn", index=1)
private String fullName;
@Attribute(name="firstName")
private String firstName;
// No @Attribute annotation means this will be bound to the LDAP attribute
// with the same value
private String firstName;
@DnAttribute(value="ou", index=0)
@Transient
private String company;
@Transient
private String someUnmappedField;
// ...more attributes below
}
----
====
We have a quite simple domain object here. Note that it has a property named `dn` of type `Name`.
.Basic repository interface to persist Person entities
====
[source]
----
public interface PersonRepository extends CrudRepository<Person, Long> {
// additional custom finder methods go here
}
----
====
Right now this interface simply serves typing purposes but we will add additional methods to it later. In your Spring configuration simply add
.JavaConfig for repositories
====
[source,java]
----
@Configuration
@EnableLdapRepositories
class ApplicationConfig {
@Bean
ContextSource contextSource() {
LdapContextSource ldapContextSource = new LdapContextSource();
ldapContextSource.setUrl("ldap://127.0.0.1:389");
return ldapContextSource;
}
@Bean
LdapTemplate ldapTemplate(ContextSource contextSource) {
return new LdapTemplate(contextSource);
}
}
----
====
As our domain repository extends `CrudRepository` it provides you with CRUD operations as well as methods for access to the entities. Working with the repository instance is just a matter of dependency injecting it into a client.
.Paging access to Person entities
====
[source,java]
----
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class PersonRepositoryTests {
@Autowired PersonRepository repository;
@Test
public void readAll() {
List<Person> persons = repository.findAll();
assertThat(persons.isEmpty(), is(false));
}
}
----
====
The sample creates an application context with Spring's unit test support which will perform annotation based dependency injection into test cases. Inside the test method we simply use the repository to query the datastore.
[[ldap.repositories.queries]]
== Query methods
Most of the data access operations you usually trigger on a repository result a query being executed against the MongoDB databases. Defining such a query is just a matter of declaring a method on the repository interface
.PersonRepository with query methods
====
[source,java]
----
public interface PersonRepository extends PagingAndSortingRepository<Person, String> {
List<Person> findByLastname(String lastname); <1>
List<Person> findByLastnameFirstname(String lastname, String firstname); <2>
}
----
<1> The method shows a query for all people with the given lastname. The query will be derived parsing the method name for constraints which can be concatenated with `And` and `Or`. Thus the method name will result in a query expression of `(&(objectclass=person)(lastname=lastname))`.
<1> The method shows a query for all people with the given lastname and firstname. The query will be derived parsing the method name.Thus the method name will result in a query expression of `(&(objectclass=person)(lastname=lastname)(firstname=firstname))`.
====
[cols="1,2,3", options="header"]
.Supported keywords for query methods
|===
| Keyword
| Sample
| Logical result
| `LessThanEqual`
| `findByAgeLessThanEqual(int age)`
| `(attribute<=age)`
| `GreaterThanEqual`
| `findByAgeGreaterThanEqual(int age)`
| `(attribute>=age)`
| `IsNotNull`, `NotNull`
| `findByFirstnameNotNull()`
| `(firstname=*)`
| `IsNull`, `Null`
| `findByFirstnameNull()`
| `(!(firstname=*))`
| `Like`
| `findByFirstnameLike(String name)`
| `(firstname=name)`
| `NotLike`, `IsNotLike`
| `findByFirstnameNotLike(String name)`
| `(!(firstname=name*))`
| `StartingWith`
| `findByStartingWith(String name)`
| `(firstname=name*)`
| `EndingWith`
| `findByFirstnameLike(String name)`
| `(firstname=*name)`
| `Containing`
| `findByFirstnameLike(String name)`
| `(firstname=\*name*)`
| `(No keyword)`
| `findByFirstname(String name)`
| `(Firstname=name)`
| `Not`
| `findByFirstnameNot(String name)`
| `(!(Firstname=name))`
|===
=== QueryDSL support
Basic QueryDSL support is included in Spring LDAP. This support includes the following:
* An Annotation Processor, `LdapAnnotationProcessor`, for generating QueryDSL classes based on Spring LDAP ODM annotations. See http://docs.spring.io/spring-ldap/docs/{springLdapVersion}.RELEASE/reference/#odm[Object-Directory Mapping] for more information on the ODM annotations.
* A Query implementation, `QueryDslLdapQuery`, for building and executing QueryDSL queries in code.
* Spring Data repository support for QueryDSL predicates. `QueryDslPredicateExecutor` includes a number of additional methods with appropriate parameters; extend this interface along with `LdapRepository` to include this support in your repository.

View File

@@ -0,0 +1,47 @@
/*
* Copyright 2016 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.data.ldap.repository;
import javax.naming.Name;
import org.springframework.data.repository.CrudRepository;
import org.springframework.ldap.query.LdapQuery;
/**
* Ldap specific extensions to CrudRepository.
*
* @author Mattias Hellborg Arthursson
* @since 2.0
*/
public interface LdapRepository<T> extends CrudRepository<T, Name> {
/**
* Find one entry matching the specified query.
*
* @param ldapQuery the query specification.
* @return the found entry or <code>null</code> if no matching entry was found.
* @throws org.springframework.dao.IncorrectResultSizeDataAccessException if more than one entry matches the query.
*/
T findOne(LdapQuery ldapQuery);
/**
* Find all entries matching the specified query.
*
* @param ldapQuery the query specification.
* @return the entries matching the query.
*/
Iterable<T> findAll(LdapQuery ldapQuery);
}

View File

@@ -0,0 +1,75 @@
/*
* Copyright 2016 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.data.ldap.repository;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.ldap.query.SearchScope;
/**
* Annotation for use in {@link org.springframework.data.ldap.repository.LdapRepository} declarations to create
* automatic query methods based on statically defined queries.
*
* @author Mattias Hellborg Arthursson
* @since 2.0
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Query {
/**
* Search base, to be used as input to
* {@link org.springframework.ldap.query.LdapQueryBuilder#base(javax.naming.Name)}.
*
* @return the search base, default is {@link org.springframework.ldap.support.LdapUtils#emptyLdapName()}
*/
String base() default "";
/**
* The filter format string, to be used as input to
* {@link org.springframework.ldap.query.LdapQueryBuilder#filter(String, Object...)}.
*
* @return search filter, must be specified.
*/
String value() default "";
/**
* Search scope, to be used as input to
* {@link org.springframework.ldap.query.LdapQueryBuilder#searchScope(org.springframework.ldap.query.SearchScope)}.
*
* @return the search scope.
*/
SearchScope searchScope() default SearchScope.SUBTREE;
/**
* Time limit, to be used as input to {@link org.springframework.ldap.query.LdapQueryBuilder#timeLimit(int)}.
*
* @return the time limit.
*/
int timeLimit() default 0;
/**
* Count limit, to be used as input to {@link org.springframework.ldap.query.LdapQueryBuilder#countLimit(int)}.
*
* @return the count limit.
*/
int countLimit() default 0;
}

View File

@@ -0,0 +1,113 @@
/*
* Copyright 2016 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.data.ldap.repository.config;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.Import;
import org.springframework.data.repository.query.QueryLookupStrategy.Key;
import org.springframework.data.ldap.repository.support.LdapRepositoryFactoryBean;
/**
* Annotation to activate Ldap repositories. If no base package is configured through either {@link #value()},
* {@link #basePackages()} or {@link #basePackageClasses()} it will trigger scanning of the package of annotated class.
*
* @author Mattias Hellborg Arthursson
* @since 2.0
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import(LdapRepositoriesRegistrar.class)
public @interface EnableLdapRepositories {
/**
* Alias for the {@link #basePackages()} attribute. Allows for more concise annotation declarations e.g.:
* {@code @EnableLdapRepositories("org.my.pkg")} instead of {@code @EnableLdapRepositories(basePackages="org.my.pkg")}.
*/
String[] value() default {};
/**
* Base packages to scan for annotated components. {@link #value()} is an alias for (and mutually exclusive with) this
* attribute. Use {@link #basePackageClasses()} for a type-safe alternative to String-based package names.
*/
String[] basePackages() default {};
/**
* Type-safe alternative to {@link #basePackages()} for specifying the packages to scan for annotated components. The
* package of each class specified will be scanned. Consider creating a special no-op marker class or interface in
* each package that serves no purpose other than being referenced by this attribute.
*/
Class<?>[] basePackageClasses() default {};
/**
* Specifies which types are eligible for component scanning. Further narrows the set of candidate components from
* everything in {@link #basePackages()} to everything in the base packages that matches the given filter or filters.
*/
Filter[] includeFilters() default {};
/**
* Specifies which types are not eligible for component scanning.
*/
Filter[] excludeFilters() default {};
/**
* Returns the postfix to be used when looking up custom repository implementations. Defaults to {@literal Impl}. So
* for a repository named {@code PersonRepository} the corresponding implementation class will be looked up scanning
* for {@code PersonRepositoryImpl}.
*
* @return
*/
String repositoryImplementationPostfix() default "";
/**
* Configures the location of where to find the Spring Data named queries properties file. Will default to
* {@code META-INFO/mongo-named-queries.properties}.
*
* @return
*/
String namedQueriesLocation() default "";
/**
* Returns the key of the {@link org.springframework.data.repository.query.QueryLookupStrategy} to be used for lookup queries for query methods. Defaults to
* {@link org.springframework.data.repository.query.QueryLookupStrategy.Key#CREATE_IF_NOT_FOUND}.
*
* @return
*/
Key queryLookupStrategy() default Key.CREATE_IF_NOT_FOUND;
/**
* Returns the {@link org.springframework.beans.factory.FactoryBean} class to be used for each repository instance. Defaults to
* {@link org.springframework.data.ldap.repository.support.LdapRepositoryFactoryBean}.
*
* @return
*/
Class<?> repositoryFactoryBeanClass() default LdapRepositoryFactoryBean.class;
/**
* Configures the name of the {@link org.springframework.ldap.core.LdapTemplate} bean to be used with the repositories detected.
*
* @return
*/
String ldapTemplateRef() default "ldapTemplate";
}

View File

@@ -0,0 +1,40 @@
/*
* Copyright 2016 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.data.ldap.repository.config;
import java.lang.annotation.Annotation;
import org.springframework.data.repository.config.RepositoryBeanDefinitionRegistrarSupport;
import org.springframework.data.repository.config.RepositoryConfigurationExtension;
/**
* LDAP-specific {@link org.springframework.context.annotation.ImportBeanDefinitionRegistrar}.
*
* @author Mattias Hellborg Arthursson
* @since 2.0
*/
class LdapRepositoriesRegistrar extends RepositoryBeanDefinitionRegistrarSupport {
@Override
protected Class<? extends Annotation> getAnnotation() {
return EnableLdapRepositories.class;
}
@Override
protected RepositoryConfigurationExtension getExtension() {
return new LdapRepositoryConfigurationExtension();
}
}

View File

@@ -0,0 +1,108 @@
/*
* Copyright 2016 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.data.ldap.repository.config;
import java.lang.annotation.Annotation;
import java.util.Collection;
import java.util.Collections;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.data.ldap.repository.LdapRepository;
import org.springframework.data.repository.config.AnnotationRepositoryConfigurationSource;
import org.springframework.data.repository.config.RepositoryConfigurationExtension;
import org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport;
import org.springframework.data.repository.config.XmlRepositoryConfigurationSource;
import org.springframework.ldap.odm.annotations.Entry;
import org.springframework.data.ldap.repository.support.LdapRepositoryFactoryBean;
import org.springframework.util.StringUtils;
import org.w3c.dom.Element;
/**
* {@link RepositoryConfigurationExtension} for LDAP.
*
* @author Mattias Hellborg Arthursson
* @author Mark Paluch
* @since 2.0
*/
public class LdapRepositoryConfigurationExtension extends RepositoryConfigurationExtensionSupport {
private static final String ATT_LDAP_TEMPLATE_REF = "ldap-template-ref";
/*
* (non-Javadoc)
* @see org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport#getModuleName()
*/
@Override
public String getModuleName() {
return "LDAP";
}
/*
* (non-Javadoc)
* @see org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport#getModulePrefix()
*/
@Override
protected String getModulePrefix() {
return "ldap";
}
/*
* (non-Javadoc)
* @see org.springframework.data.repository.config.RepositoryConfigurationExtension#getRepositoryFactoryClassName()
*/
public String getRepositoryFactoryClassName() {
return LdapRepositoryFactoryBean.class.getName();
}
/*
* (non-Javadoc)
* @see org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport#getIdentifyingAnnotations()
*/
@Override
protected Collection<Class<? extends Annotation>> getIdentifyingAnnotations() {
return Collections.<Class<? extends Annotation>> singleton(Entry.class);
}
/*
* (non-Javadoc)
* @see org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport#getIdentifyingTypes()
*/
@Override
protected Collection<Class<?>> getIdentifyingTypes() {
return Collections.<Class<?>> singleton(LdapRepository.class);
}
@Override
public void postProcess(BeanDefinitionBuilder builder, XmlRepositoryConfigurationSource config) {
Element element = config.getElement();
String ldapTemplateRef = element.getAttribute(ATT_LDAP_TEMPLATE_REF);
if (!StringUtils.hasText(ldapTemplateRef)) {
ldapTemplateRef = "ldapTemplate";
}
builder.addPropertyReference("ldapOperations", ldapTemplateRef);
}
@Override
public void postProcess(BeanDefinitionBuilder builder, AnnotationRepositoryConfigurationSource config) {
AnnotationAttributes attributes = config.getAttributes();
builder.addPropertyReference("ldapOperations", attributes.getString("ldapTemplateRef"));
}
}

View File

@@ -0,0 +1,66 @@
/*
* Copyright 2016 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.data.ldap.repository.query;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.data.repository.query.QueryMethod;
import org.springframework.data.repository.query.RepositoryQuery;
import org.springframework.ldap.core.LdapOperations;
import org.springframework.ldap.query.LdapQuery;
/**
* @author Mattias Hellborg Arthursson
* @since 2.0
*/
abstract class AbstractLdapRepositoryQuery implements RepositoryQuery {
private final LdapQueryMethod queryMethod;
private final Class<?> clazz;
private final LdapOperations ldapOperations;
public AbstractLdapRepositoryQuery(LdapQueryMethod queryMethod, Class<?> clazz, LdapOperations ldapOperations) {
this.queryMethod = queryMethod;
this.clazz = clazz;
this.ldapOperations = ldapOperations;
}
@Override
public final Object execute(Object[] parameters) {
LdapQuery query = createQuery(parameters);
if (queryMethod.isCollectionQuery()) {
return ldapOperations.find(query, clazz);
} else {
try {
return ldapOperations.findOne(query, clazz);
} catch (EmptyResultDataAccessException e) {
return null;
}
}
}
protected abstract LdapQuery createQuery(Object[] parameters);
Class<?> getClazz() {
return clazz;
}
@Override
public final QueryMethod getQueryMethod() {
return queryMethod;
}
}

View File

@@ -0,0 +1,61 @@
/*
* Copyright 2016 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.data.ldap.repository.query;
import static org.springframework.ldap.query.LdapQueryBuilder.*;
import org.springframework.ldap.core.LdapOperations;
import org.springframework.ldap.query.LdapQuery;
import org.springframework.data.ldap.repository.Query;
import org.springframework.util.Assert;
/**
* Handles queries for repository methods annotated with {@link org.springframework.data.ldap.repository.Query}.
*
* @author Mattias Hellborg Arthursson
* @since 2.0
*/
public class AnnotatedLdapRepositoryQuery extends AbstractLdapRepositoryQuery {
private final Query queryAnnotation;
/**
* Construct a new instance.
*
* @param queryMethod the QueryMethod.
* @param clazz the managed class.
* @param ldapOperations the LdapOperations instance to use.
*/
public AnnotatedLdapRepositoryQuery(LdapQueryMethod queryMethod, Class<?> clazz, LdapOperations ldapOperations) {
super(queryMethod, clazz, ldapOperations);
queryAnnotation = queryMethod.getQueryAnnotation();
Assert.notNull(queryMethod, "Annotation must be present");
Assert.hasLength(queryAnnotation.value(), "Query filter must be specified");
}
@Override
protected LdapQuery createQuery(Object[] parameters) {
return query().base(queryAnnotation.base()) //
.searchScope(queryAnnotation.searchScope()) //
.countLimit(queryAnnotation.countLimit()) //
.timeLimit(queryAnnotation.timeLimit()) //
.filter(queryAnnotation.value(), parameters);
}
}

View File

@@ -0,0 +1,128 @@
/*
* Copyright 2016 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.data.ldap.repository.query;
import static org.springframework.ldap.query.LdapQueryBuilder.*;
import java.util.Iterator;
import org.springframework.data.domain.Sort;
import org.springframework.data.mapping.PropertyPath;
import org.springframework.data.repository.query.Parameters;
import org.springframework.data.repository.query.ParametersParameterAccessor;
import org.springframework.data.repository.query.parser.AbstractQueryCreator;
import org.springframework.data.repository.query.parser.Part;
import org.springframework.data.repository.query.parser.PartTree;
import org.springframework.ldap.odm.annotations.Entry;
import org.springframework.ldap.odm.core.ObjectDirectoryMapper;
import org.springframework.ldap.query.ConditionCriteria;
import org.springframework.ldap.query.ContainerCriteria;
import org.springframework.ldap.query.LdapQuery;
/**
* Creator of dynamic queries based on method names.
*
* @author Mattias Hellborg Arthursson
* @since 2.0
*/
public class LdapQueryCreator extends AbstractQueryCreator<LdapQuery, ContainerCriteria> {
private final Class<?> clazz;
private final ObjectDirectoryMapper mapper;
/**
* Construct a new instance.
*/
public LdapQueryCreator(PartTree tree, Parameters<?, ?> parameters, Class<?> clazz, ObjectDirectoryMapper mapper,
Object[] values) {
super(tree, new ParametersParameterAccessor(parameters, values));
this.clazz = clazz;
this.mapper = mapper;
}
@Override
protected ContainerCriteria create(Part part, Iterator<Object> iterator) {
String base = clazz.getAnnotation(Entry.class).base();
ConditionCriteria criteria = query().base(base).where(getAttribute(part));
return appendCondition(part, iterator, criteria);
}
private ContainerCriteria appendCondition(Part part, Iterator<Object> iterator, ConditionCriteria criteria) {
Part.Type type = part.getType();
String value = null;
if (iterator.hasNext()) {
value = iterator.next().toString();
}
switch (type) {
case NEGATING_SIMPLE_PROPERTY:
return criteria.not().is(value);
case SIMPLE_PROPERTY:
return criteria.is(value);
case STARTING_WITH:
return criteria.like(value + "*");
case ENDING_WITH:
return criteria.like("*" + value);
case CONTAINING:
return criteria.like("*" + value + "*");
case LIKE:
return criteria.like(value);
case NOT_LIKE:
return criteria.not().like(value);
case GREATER_THAN_EQUAL:
return criteria.gte(value);
case LESS_THAN_EQUAL:
return criteria.lte(value);
case IS_NOT_NULL:
return criteria.isPresent();
case IS_NULL:
return criteria.not().isPresent();
}
throw new IllegalArgumentException(String.format("%s queries are not supported for LDAP repositories", type));
}
private String getAttribute(Part part) {
PropertyPath path = part.getProperty();
if (path.hasNext()) {
throw new IllegalArgumentException("Nested properties are not supported");
}
return mapper.attributeFor(clazz, path.getSegment());
}
@Override
protected ContainerCriteria and(Part part, ContainerCriteria base, Iterator<Object> iterator) {
ConditionCriteria criteria = base.and(getAttribute(part));
return appendCondition(part, iterator, criteria);
}
@Override
protected ContainerCriteria or(ContainerCriteria base, ContainerCriteria criteria) {
return base.or(criteria);
}
@Override
protected LdapQuery complete(ContainerCriteria criteria, Sort sort) {
return criteria;
}
}

View File

@@ -0,0 +1,69 @@
/*
* Copyright 2016 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.data.ldap.repository.query;
import java.lang.reflect.Method;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.data.projection.ProjectionFactory;
import org.springframework.data.repository.core.RepositoryMetadata;
import org.springframework.data.repository.query.QueryMethod;
import org.springframework.data.ldap.repository.Query;
/**
* QueryMethod for Ldap Queries.
*
* @author Mattias Hellborg Arthursson
* @author Eddu Melendez
* @since 2.0
*/
public class LdapQueryMethod extends QueryMethod {
private final Method method;
/**
* Creates a new LdapQueryMethod from the given parameters.
*
* @param method must not be {@literal null}
* @param metadata must not be {@literal null}
*/
public LdapQueryMethod(Method method, RepositoryMetadata metadata, ProjectionFactory factory) {
super(method, metadata, factory);
this.method = method;
}
/**
* Check whether the target method is annotated with {@link org.springframework.data.ldap.repository.Query}.
*
* @return <code>true</code> if the target method is annotated with {@link org.springframework.data.ldap.repository.Query},
* <code>false</code> otherwise.
*/
public boolean hasQueryAnnotation() {
return getQueryAnnotation() != null;
}
/**
* Get the {@link org.springframework.data.ldap.repository.Query} annotation of the target method (if any).
*
* @return the {@link org.springframework.data.ldap.repository.Query} annotation of the target method if present, or
* <code>null</code> otherwise.
*/
Query getQueryAnnotation() {
return AnnotationUtils.getAnnotation(method, Query.class);
}
}

View File

@@ -0,0 +1,49 @@
/*
* Copyright 2016 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.data.ldap.repository.query;
import org.springframework.data.repository.query.Parameters;
import org.springframework.data.repository.query.parser.PartTree;
import org.springframework.ldap.core.LdapOperations;
import org.springframework.ldap.odm.core.ObjectDirectoryMapper;
import org.springframework.ldap.query.LdapQuery;
/**
* @author Mattias Hellborg Arthursson
*/
public class PartTreeLdapRepositoryQuery extends AbstractLdapRepositoryQuery {
private final PartTree partTree;
private final Parameters<?, ?> parameters;
private final ObjectDirectoryMapper objectDirectoryMapper;
public PartTreeLdapRepositoryQuery(LdapQueryMethod queryMethod, Class<?> clazz, LdapOperations ldapOperations) {
super(queryMethod, clazz, ldapOperations);
partTree = new PartTree(queryMethod.getName(), clazz);
parameters = queryMethod.getParameters();
objectDirectoryMapper = ldapOperations.getObjectDirectoryMapper();
}
@Override
protected LdapQuery createQuery(Object[] actualParameters) {
org.springframework.data.ldap.repository.query.LdapQueryCreator queryCreator = new LdapQueryCreator(partTree,
this.parameters, getClazz(), objectDirectoryMapper, actualParameters);
return queryCreator.createQuery();
}
}

View File

@@ -0,0 +1,59 @@
/*
* Copyright 2016 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.data.ldap.repository.support;
import java.lang.annotation.Annotation;
import java.util.Collection;
import java.util.Map;
import javax.annotation.processing.RoundEnvironment;
import javax.lang.model.element.VariableElement;
import org.springframework.ldap.odm.annotations.Id;
import com.querydsl.apt.DefaultConfiguration;
/**
* @author Mattias Hellborg Arthursson
* @author Eddu Melendez
* @since 2.0
*/
class DefaultLdapAnnotationProcessorConfiguration extends DefaultConfiguration {
public DefaultLdapAnnotationProcessorConfiguration(
RoundEnvironment roundEnv,
Map<String, String> options,
Collection<String> keywords,
Class<? extends Annotation> entitiesAnn,
Class<? extends Annotation> entityAnn,
Class<? extends Annotation> superTypeAnn,
Class<? extends Annotation> embeddableAnn,
Class<? extends Annotation> embeddedAnn,
Class<? extends Annotation> skipAnn) {
super(roundEnv, options, keywords, entitiesAnn, entityAnn, superTypeAnn, embeddableAnn, embeddedAnn, skipAnn);
}
@Override
public boolean isBlockedField(VariableElement field) {
return super.isBlockedField(field) || field.getAnnotation(Id.class) != null;
}
@Override
public boolean isValidField(VariableElement field) {
return super.isValidField(field) && field.getAnnotation(Id.class) == null;
}
}

View File

@@ -0,0 +1,57 @@
/*
* Copyright 2016 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.data.ldap.repository.support;
import java.util.Collections;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.annotation.processing.SupportedSourceVersion;
import javax.lang.model.SourceVersion;
import javax.tools.Diagnostic;
import org.springframework.ldap.odm.annotations.Entry;
import org.springframework.ldap.odm.annotations.Transient;
import com.querydsl.apt.AbstractQuerydslProcessor;
import com.querydsl.apt.Configuration;
import com.querydsl.apt.DefaultConfiguration;
import com.querydsl.core.annotations.QueryEntities;
/**
* QueryDSL Annotation Processor to generate QueryDSL classes for entity classes annotated with {@link Entry}.
*
* @author Mattias Hellborg Arthursson
* @author Eddu Melendez
* @since 2.0
*/
@SupportedAnnotationTypes("org.springframework.ldap.odm.annotations.*")
@SupportedSourceVersion(SourceVersion.RELEASE_6)
public class LdapAnnotationProcessor extends AbstractQuerydslProcessor {
@Override
protected Configuration createConfiguration(RoundEnvironment roundEnv) {
processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, "Running " + getClass().getSimpleName());
DefaultConfiguration configuration = new DefaultLdapAnnotationProcessorConfiguration(roundEnv,
processingEnv.getOptions(), Collections.<String> emptySet(), QueryEntities.class, Entry.class, null, null, null,
Transient.class);
configuration.setUseFields(true);
configuration.setUseGetters(false);
return configuration;
}
}

View File

@@ -0,0 +1,114 @@
/*
* Copyright 2016 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.data.ldap.repository.support;
import static org.springframework.data.querydsl.QueryDslUtils.*;
import java.io.Serializable;
import java.lang.reflect.Method;
import org.springframework.data.projection.ProjectionFactory;
import org.springframework.data.querydsl.QueryDslPredicateExecutor;
import org.springframework.data.repository.core.EntityInformation;
import org.springframework.data.repository.core.NamedQueries;
import org.springframework.data.repository.core.RepositoryInformation;
import org.springframework.data.repository.core.RepositoryMetadata;
import org.springframework.data.repository.core.support.RepositoryFactorySupport;
import org.springframework.data.repository.query.EvaluationContextProvider;
import org.springframework.data.repository.query.QueryLookupStrategy;
import org.springframework.data.repository.query.QueryLookupStrategy.Key;
import org.springframework.data.repository.query.RepositoryQuery;
import org.springframework.ldap.core.LdapOperations;
import org.springframework.data.ldap.repository.query.AnnotatedLdapRepositoryQuery;
import org.springframework.data.ldap.repository.query.LdapQueryMethod;
import org.springframework.data.ldap.repository.query.PartTreeLdapRepositoryQuery;
import org.springframework.data.ldap.repository.support.SimpleLdapRepository;
/**
* Factory to create {@link org.springframework.data.ldap.repository.LdapRepository} instances.
*
* @author Mattias Hellborg Arthursson
* @author Eddu Melendez
* @since 2.0
*/
public class LdapRepositoryFactory extends RepositoryFactorySupport {
private final LdapOperations ldapOperations;
public LdapRepositoryFactory(LdapOperations ldapOperations) {
this.ldapOperations = ldapOperations;
}
@Override
public <T, ID extends Serializable> EntityInformation<T, ID> getEntityInformation(Class<T> domainClass) {
return null;
}
@SuppressWarnings({ "unchecked", "rawtypes" })
protected Object getTargetRepository(RepositoryMetadata metadata) {
if (!isQueryDslRepository(metadata.getRepositoryInterface())) {
return new org.springframework.data.ldap.repository.support.SimpleLdapRepository(ldapOperations,
ldapOperations.getObjectDirectoryMapper(), metadata.getDomainType());
}
return new QueryDslLdapRepository(ldapOperations, ldapOperations.getObjectDirectoryMapper(),
metadata.getDomainType());
}
protected Object getTargetRepository(RepositoryInformation metadata) {
return getTargetRepository((RepositoryMetadata) metadata);
}
private static boolean isQueryDslRepository(Class<?> repositoryInterface) {
return QUERY_DSL_PRESENT && QueryDslPredicateExecutor.class.isAssignableFrom(repositoryInterface);
}
@Override
protected Class<?> getRepositoryBaseClass(RepositoryMetadata metadata) {
if (!isQueryDslRepository(metadata.getRepositoryInterface())) {
return SimpleLdapRepository.class;
} else {
return QueryDslLdapRepository.class;
}
}
@Override
protected QueryLookupStrategy getQueryLookupStrategy(QueryLookupStrategy.Key key) {
return new LdapQueryLookupStrategy();
}
@Override
protected QueryLookupStrategy getQueryLookupStrategy(Key key, EvaluationContextProvider evaluationContextProvider) {
return new LdapQueryLookupStrategy();
}
private final class LdapQueryLookupStrategy implements QueryLookupStrategy {
@Override
public RepositoryQuery resolveQuery(Method method, RepositoryMetadata metadata, ProjectionFactory factory,
NamedQueries namedQueries) {
LdapQueryMethod queryMethod = new LdapQueryMethod(method, metadata, factory);
Class<?> domainType = metadata.getDomainType();
if (queryMethod.hasQueryAnnotation()) {
return new AnnotatedLdapRepositoryQuery(queryMethod, domainType, ldapOperations);
} else {
return new PartTreeLdapRepositoryQuery(queryMethod, domainType, ldapOperations);
}
}
}
}

View File

@@ -0,0 +1,53 @@
/*
* Copyright 2016 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.data.ldap.repository.support;
import javax.naming.Name;
import org.springframework.data.repository.Repository;
import org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport;
import org.springframework.data.repository.core.support.RepositoryFactorySupport;
import org.springframework.ldap.core.LdapOperations;
import org.springframework.data.ldap.repository.support.LdapRepositoryFactory;
import org.springframework.util.Assert;
/**
* {@link org.springframework.beans.factory.FactoryBean} to create
* {@link org.springframework.data.ldap.repository.LdapRepository} instances.
*
* @author Mattias Hellborg Arthursson
* @since 2.0
*/
public class LdapRepositoryFactoryBean<T extends Repository<S, Name>, S>
extends RepositoryFactoryBeanSupport<T, S, Name> {
private LdapOperations ldapOperations;
public void setLdapOperations(LdapOperations ldapOperations) {
this.ldapOperations = ldapOperations;
}
@Override
protected RepositoryFactorySupport createRepositoryFactory() {
return new LdapRepositoryFactory(ldapOperations);
}
@Override
public void afterPropertiesSet() {
super.afterPropertiesSet();
Assert.notNull(ldapOperations, "LdapOperations must be set");
}
}

View File

@@ -0,0 +1,124 @@
/*
* Copyright 2016 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.data.ldap.repository.support;
import org.springframework.ldap.filter.AndFilter;
import org.springframework.ldap.filter.EqualsFilter;
import org.springframework.ldap.filter.Filter;
import org.springframework.ldap.filter.GreaterThanOrEqualsFilter;
import org.springframework.ldap.filter.LessThanOrEqualsFilter;
import org.springframework.ldap.filter.LikeFilter;
import org.springframework.ldap.filter.NotFilter;
import org.springframework.ldap.filter.OrFilter;
import org.springframework.ldap.filter.PresentFilter;
import org.springframework.ldap.odm.core.ObjectDirectoryMapper;
import com.querydsl.core.types.*;
/**
* Helper class for generating LDAP filters from QueryDSL Expressions.
*
* @author Mattias Hellborg Arthursson
* @author Eddu Melendez
* @since 2.0
*/
class LdapSerializer implements Visitor<Object, Void> {
private final ObjectDirectoryMapper odm;
private final Class<?> clazz;
public LdapSerializer(ObjectDirectoryMapper odm, Class<?> clazz) {
this.odm = odm;
this.clazz = clazz;
}
public Filter handle(Expression<?> expression) {
return (Filter) expression.accept(this, null);
}
@Override
public Object visit(Constant<?> expr, Void context) {
return expr.getConstant().toString();
}
@Override
public Object visit(FactoryExpression<?> expr, Void context) {
throw new UnsupportedOperationException();
}
@Override
public Object visit(Operation<?> expr, Void context) {
Operator operator = expr.getOperator();
if (operator == Ops.EQ) {
return new EqualsFilter(attribute(expr), value(expr));
} else if (operator == Ops.AND) {
return new AndFilter().and(handle(expr.getArg(0))).and(handle(expr.getArg(1)));
} else if (operator == Ops.OR) {
return new OrFilter().or(handle(expr.getArg(0))).or(handle(expr.getArg(1)));
} else if (operator == Ops.NOT) {
return new NotFilter(handle(expr.getArg(0)));
} else if (operator == Ops.LIKE) {
return new LikeFilter(attribute(expr), value(expr));
} else if (operator == Ops.STARTS_WITH || operator == Ops.STARTS_WITH_IC) {
return new LikeFilter(attribute(expr), value(expr) + "*");
} else if (operator == Ops.ENDS_WITH || operator == Ops.ENDS_WITH_IC) {
return new LikeFilter(attribute(expr), "*" + value(expr));
} else if (operator == Ops.STRING_CONTAINS || operator == Ops.STRING_CONTAINS_IC) {
return new LikeFilter(attribute(expr), "*" + value(expr) + "*");
} else if (operator == Ops.IS_NOT_NULL) {
return new PresentFilter(attribute(expr));
} else if (operator == Ops.IS_NULL) {
return new NotFilter(new PresentFilter(attribute(expr)));
} else if (operator == Ops.GOE) {
return new GreaterThanOrEqualsFilter(attribute(expr), value(expr));
} else if (operator == Ops.LOE) {
return new LessThanOrEqualsFilter(attribute(expr), value(expr));
}
throw new UnsupportedOperationException("Unsupported operator " + operator.toString());
}
private String value(Operation<?> expr) {
return (String) expr.getArg(1).accept(this, null);
}
private String attribute(Operation<?> expr) {
return odm.attributeFor(clazz, (String) expr.getArg(0).accept(this, null));
}
@Override
public Object visit(ParamExpression<?> expr, Void context) {
throw new UnsupportedOperationException();
}
@Override
public Object visit(Path<?> expr, Void context) {
return expr.getMetadata().getName();
}
@Override
public Object visit(SubQueryExpression<?> expr, Void context) {
throw new UnsupportedOperationException();
}
@Override
public Object visit(TemplateExpression<?> expr, Void context) {
throw new UnsupportedOperationException();
}
}

View File

@@ -0,0 +1,78 @@
/*
* Copyright 2016 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.data.ldap.repository.support;
import static org.springframework.ldap.query.LdapQueryBuilder.*;
import java.util.List;
import org.springframework.ldap.core.LdapOperations;
import org.springframework.ldap.query.LdapQuery;
import com.querydsl.core.DefaultQueryMetadata;
import com.querydsl.core.FilteredClause;
import com.querydsl.core.support.QueryMixin;
import com.querydsl.core.types.EntityPath;
import com.querydsl.core.types.Predicate;
/**
* Spring LDAP specific {@link FilteredClause} implementation.
*
* @author Mattias Hellborg Arthursson
* @author Eddu Melendez
* @since 2.0
*/
public class QueryDslLdapQuery<K> implements FilteredClause<QueryDslLdapQuery<K>> {
private final LdapOperations ldapOperations;
private final Class<? extends K> clazz;
private QueryMixin<QueryDslLdapQuery<K>> queryMixin = new QueryMixin<QueryDslLdapQuery<K>>(this,
new DefaultQueryMetadata().noValidate());
private final LdapSerializer filterGenerator;
@SuppressWarnings("unchecked")
public QueryDslLdapQuery(LdapOperations ldapOperations, EntityPath<K> entityPath) {
this(ldapOperations, (Class<K>) entityPath.getType());
}
public QueryDslLdapQuery(LdapOperations ldapOperations, Class<K> clazz) {
this.ldapOperations = ldapOperations;
this.clazz = clazz;
this.filterGenerator = new LdapSerializer(ldapOperations.getObjectDirectoryMapper(), clazz);
}
@Override
public QueryDslLdapQuery<K> where(Predicate... o) {
return queryMixin.where(o);
}
@SuppressWarnings("unchecked")
public List<K> list() {
return (List<K>) ldapOperations.find(buildQuery(), clazz);
}
public K uniqueResult() {
return ldapOperations.findOne(buildQuery(), clazz);
}
LdapQuery buildQuery() {
return query().filter(filterGenerator.handle(queryMixin.getMetadata().getWhere()));
}
}

View File

@@ -0,0 +1,85 @@
/*
* Copyright 2016 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.data.ldap.repository.support;
import java.util.List;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.querydsl.QueryDslPredicateExecutor;
import org.springframework.ldap.core.LdapOperations;
import org.springframework.ldap.odm.core.ObjectDirectoryMapper;
import org.springframework.data.ldap.repository.support.QueryDslLdapQuery;
import org.springframework.data.ldap.repository.support.SimpleLdapRepository;
import com.querydsl.core.types.OrderSpecifier;
import com.querydsl.core.types.Predicate;
/**
* Base repository implementation for QueryDSL support.
*
* @author Mattias Hellborg Arthursson
* @author Eddu Melendez
* @since 2.0
*/
public class QueryDslLdapRepository<T> extends SimpleLdapRepository<T> implements QueryDslPredicateExecutor<T> {
public QueryDslLdapRepository(LdapOperations ldapOperations, ObjectDirectoryMapper odm, Class<T> clazz) {
super(ldapOperations, odm, clazz);
}
@Override
public T findOne(Predicate predicate) {
return queryFor(predicate).uniqueResult();
}
@Override
public List<T> findAll(Predicate predicate) {
return queryFor(predicate).list();
}
@Override
public long count(Predicate predicate) {
return findAll(predicate).size();
}
public boolean exists(Predicate predicate) {
return count(predicate) > 0;
}
public Iterable<T> findAll(Predicate predicate, Sort sort) {
throw new UnsupportedOperationException();
}
private QueryDslLdapQuery<T> queryFor(Predicate predicate) {
return new QueryDslLdapQuery<T>(getLdapOperations(), getClazz()).where(predicate);
}
public Iterable<T> findAll(OrderSpecifier<?>... orders) {
throw new UnsupportedOperationException();
}
@Override
public Iterable<T> findAll(Predicate predicate, OrderSpecifier<?>... orders) {
throw new UnsupportedOperationException();
}
@Override
public Page<T> findAll(Predicate predicate, Pageable pageable) {
throw new UnsupportedOperationException();
}
}

View File

@@ -0,0 +1,242 @@
/*
* Copyright 2016 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.data.ldap.repository.support;
import static org.springframework.ldap.query.LdapQueryBuilder.*;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import javax.naming.Name;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.data.domain.Persistable;
import org.springframework.ldap.NameNotFoundException;
import org.springframework.ldap.core.LdapOperations;
import org.springframework.ldap.core.support.CountNameClassPairCallbackHandler;
import org.springframework.ldap.filter.Filter;
import org.springframework.ldap.odm.core.ObjectDirectoryMapper;
import org.springframework.ldap.query.LdapQuery;
import org.springframework.data.ldap.repository.LdapRepository;
import org.springframework.util.Assert;
/**
* Base repository implementation for LDAP.
*
* @author Mattias Hellborg Arthursson
* @since 2.0
*/
public class SimpleLdapRepository<T> implements LdapRepository<T> {
private static final String OBJECTCLASS_ATTRIBUTE = "objectclass";
private final LdapOperations ldapOperations;
private final ObjectDirectoryMapper odm;
private final Class<T> clazz;
public SimpleLdapRepository(LdapOperations ldapOperations, ObjectDirectoryMapper odm, Class<T> clazz) {
this.ldapOperations = ldapOperations;
this.odm = odm;
this.clazz = clazz;
}
protected LdapOperations getLdapOperations() {
return ldapOperations;
}
protected Class<T> getClazz() {
return clazz;
}
@Override
public long count() {
Filter filter = odm.filterFor(clazz, null);
CountNameClassPairCallbackHandler callback = new CountNameClassPairCallbackHandler();
LdapQuery query = query().attributes(OBJECTCLASS_ATTRIBUTE).filter(filter);
ldapOperations.search(query, callback);
return callback.getNoOfRows();
}
private <S extends T> boolean isNew(S entity, Name id) {
if (entity instanceof Persistable) {
Persistable<?> persistable = (Persistable<?>) entity;
return persistable.isNew();
} else {
return id == null;
}
}
@Override
public <S extends T> S save(S entity) {
Assert.notNull(entity, "Entity must not be null");
Name declaredId = odm.getId(entity);
if (isNew(entity, declaredId)) {
ldapOperations.create(entity);
} else {
ldapOperations.update(entity);
}
return entity;
}
@Override
public <S extends T> Iterable<S> save(Iterable<S> entities) {
return new TransformingIterable<S, S>(entities, new Function<S, S>() {
@Override
public S transform(S entry) {
return save(entry);
}
});
}
@Override
public T findOne(Name name) {
Assert.notNull(name, "Id must not be null");
try {
return ldapOperations.findByDn(name, clazz);
} catch (NameNotFoundException e) {
return null;
}
}
@Override
public List<T> findAll(LdapQuery ldapQuery) {
Assert.notNull(ldapQuery, "LdapQuery must not be null");
return ldapOperations.find(ldapQuery, clazz);
}
@Override
public T findOne(LdapQuery ldapQuery) {
Assert.notNull(ldapQuery, "LdapQuery must not be null");
try {
return ldapOperations.findOne(ldapQuery, clazz);
} catch (EmptyResultDataAccessException e) {
return null;
}
}
@Override
public boolean exists(Name name) {
Assert.notNull(name, "Id must not be null");
return findOne(name) != null;
}
@Override
public List<T> findAll() {
return ldapOperations.findAll(clazz);
}
@Override
public List<T> findAll(final Iterable<Name> names) {
Iterable<T> found = new TransformingIterable<Name, T>(names, new Function<Name, T>() {
@Override
public T transform(Name name) {
return findOne(name);
}
});
LinkedList<T> list = new LinkedList<T>();
for (T entry : found) {
if (entry != null) {
list.add(entry);
}
}
return list;
}
@Override
public void delete(Name name) {
Assert.notNull(name, "Id must not be null");
ldapOperations.unbind(name);
}
@Override
public void delete(T entity) {
Assert.notNull(entity, "Entity must not be null");
ldapOperations.delete(entity);
}
@Override
public void delete(Iterable<? extends T> entities) {
for (T entity : entities) {
delete(entity);
}
}
@Override
public void deleteAll() {
delete(findAll());
}
private static final class TransformingIterable<F, T> implements Iterable<T> {
private final Iterable<F> target;
private final Function<F, T> function;
private TransformingIterable(Iterable<F> target, Function<F, T> function) {
this.target = target;
this.function = function;
}
@Override
public Iterator<T> iterator() {
final Iterator<F> targetIterator = target.iterator();
return new Iterator<T>() {
@Override
public boolean hasNext() {
return targetIterator.hasNext();
}
@Override
public T next() {
return function.transform(targetIterator.next());
}
@Override
public void remove() {
throw new UnsupportedOperationException("Remove is not supported for this iterator");
}
};
}
}
private interface Function<F, T> {
T transform(F entry);
}
}

View File

@@ -0,0 +1,10 @@
Spring Data LDAP Changelog
=============================
Changes in version 1.0.0.M1 LDAP (2016-11-11)
------------------------------------------------
Repository
* Introducing generic repository implementation for LDAP
* Automatic implementation of interface query method names on repositories.

View File

@@ -0,0 +1,216 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
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.
=======================================================================
To the extent any open source subcomponents are licensed under the EPL and/or other
similar licenses that require the source code and/or modifications to
source code to be made available (as would be noted above), you may obtain a
copy of the source code corresponding to the binaries for such open source
components and modifications thereto, if any, (the "Source Files"), by
downloading the Source Files from http://www.springsource.org/download,
or by sending a request, with your name and address to: VMware, Inc., 3401 Hillview
Avenue, Palo Alto, CA 94304, United States of America or email info@vmware.com. All
such requests should clearly specify: OPEN SOURCE FILES REQUEST, Attention General
Counsel. VMware shall mail a copy of the Source Files to you on a CD or equivalent
physical medium. This offer to obtain a copy of the Source Files is valid for three
years from the date you acquired this Software product.

View File

@@ -0,0 +1,10 @@
Spring Data LDAP 1.0 M1
Copyright (c) [2010-2015] Pivotal Software, Inc.
This product is licensed to you under the Apache License, Version 2.0 (the "License").
You may not use this product except in compliance with the License.
This product may include a number of subcomponents with
separate copyright notices and license terms. Your use of the source
code for the these subcomponents is subject to the terms and
conditions of the subcomponent's license, as noted in the LICENSE file.

View File

@@ -0,0 +1,22 @@
/*
* Copyright 2016 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.data.ldap.config;
/**
* @author Mattias Hellborg Arthursson
*/
public class DummyEntity {
}

View File

@@ -0,0 +1,27 @@
/*
* Copyright 2016 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.data.ldap.config;
import javax.naming.Name;
import org.springframework.data.repository.CrudRepository;
/**
* @author Mattias Hellborg Arthursson
*/
public interface DummyLdapRepository extends CrudRepository<DummyEntity, Name> {
}

View File

@@ -0,0 +1,212 @@
/*
* Copyright 2016 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.data.ldap.repository;
import static org.assertj.core.api.Assertions.*;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.*;
import java.util.Arrays;
import java.util.Iterator;
import javax.naming.Name;
import javax.naming.ldap.LdapName;
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.springframework.data.domain.Persistable;
import org.springframework.ldap.NameNotFoundException;
import org.springframework.ldap.core.LdapOperations;
import org.springframework.ldap.core.support.CountNameClassPairCallbackHandler;
import org.springframework.ldap.filter.Filter;
import org.springframework.ldap.odm.core.ObjectDirectoryMapper;
import org.springframework.ldap.query.LdapQuery;
import org.springframework.data.ldap.repository.support.SimpleLdapRepository;
import org.springframework.ldap.support.LdapUtils;
/**
* @author Mattias Hellborg Arthursson
*/
public class SimpleLdapRepositoryTest {
private LdapOperations ldapOperationsMock;
private ObjectDirectoryMapper odmMock;
private SimpleLdapRepository<Object> tested;
@Before
public void prepareTestedInstance() {
ldapOperationsMock = mock(LdapOperations.class);
odmMock = mock(ObjectDirectoryMapper.class);
tested = new SimpleLdapRepository<Object>(ldapOperationsMock, odmMock, Object.class);
}
@Test
public void testCount() {
Filter filterMock = mock(Filter.class);
when(odmMock.filterFor(Object.class, null)).thenReturn(filterMock);
ArgumentCaptor<LdapQuery> ldapQuery = ArgumentCaptor.forClass(LdapQuery.class);
doNothing().when(ldapOperationsMock).search(ldapQuery.capture(), any(CountNameClassPairCallbackHandler.class));
long count = tested.count();
assertThat(count).isEqualTo(0);
LdapQuery query = ldapQuery.getValue();
assertThat(query.filter()).isEqualTo(filterMock);
assertThat(query.attributes()).isEqualTo(new String[]{"objectclass"});
}
@Test
public void testSaveNonPersistableWithIdSet() {
Object expectedEntity = new Object();
when(odmMock.getId(expectedEntity)).thenReturn(LdapUtils.emptyLdapName());
when(odmMock.getCalculatedId(expectedEntity)).thenReturn(null);
tested.save(expectedEntity);
verify(ldapOperationsMock).update(expectedEntity);
}
@Test
public void testSaveNonPersistableWithIdChanged() {
Object expectedEntity = new Object();
LdapName expectedName = LdapUtils.newLdapName("ou=newlocation");
when(odmMock.getId(expectedEntity)).thenReturn(LdapUtils.emptyLdapName());
when(odmMock.getCalculatedId(expectedEntity)).thenReturn(expectedName);
tested.save(expectedEntity);
verify(ldapOperationsMock).update(expectedEntity);
}
@Test
public void testSaveNonPersistableWithNoIdCalculatedId() {
Object expectedEntity = new Object();
LdapName expectedName = LdapUtils.emptyLdapName();
when(odmMock.getId(expectedEntity)).thenReturn(null);
when(odmMock.getCalculatedId(expectedEntity)).thenReturn(expectedName);
tested.save(expectedEntity);
verify(ldapOperationsMock).create(expectedEntity);
}
@Test
public void testSavePersistableNewWithDeclaredId() {
Persistable expectedEntity = mock(Persistable.class);
when(expectedEntity.isNew()).thenReturn(true);
when(odmMock.getId(expectedEntity)).thenReturn(LdapUtils.emptyLdapName());
when(odmMock.getCalculatedId(expectedEntity)).thenReturn(null);
tested.save(expectedEntity);
verify(ldapOperationsMock).create(expectedEntity);
}
@Test
public void testSavePersistableNewWithCalculatedId() {
Persistable expectedEntity = mock(Persistable.class);
LdapName expectedName = LdapUtils.emptyLdapName();
when(expectedEntity.isNew()).thenReturn(true);
when(odmMock.getId(expectedEntity)).thenReturn(null);
when(odmMock.getCalculatedId(expectedEntity)).thenReturn(expectedName);
tested.save(expectedEntity);
verify(ldapOperationsMock).create(expectedEntity);
}
@Test
public void testSavePersistableNotNew() {
Persistable expectedEntity = mock(Persistable.class);
when(expectedEntity.isNew()).thenReturn(false);
when(odmMock.getId(expectedEntity)).thenReturn(LdapUtils.emptyLdapName());
when(odmMock.getCalculatedId(expectedEntity)).thenReturn(null);
tested.save(expectedEntity);
verify(ldapOperationsMock).update(expectedEntity);
}
@Test
public void testFindOneWithName() {
LdapName expectedName = LdapUtils.emptyLdapName();
Object expectedResult = new Object();
when(ldapOperationsMock.findByDn(expectedName, Object.class)).thenReturn(expectedResult);
Object actualResult = tested.findOne(expectedName);
assertThat(actualResult).isSameAs(expectedResult);
}
@Test
public void verifyThatNameNotFoundInFindOneWithNameReturnsNull() {
LdapName expectedName = LdapUtils.emptyLdapName();
when(ldapOperationsMock.findByDn(expectedName, Object.class)).thenThrow(new NameNotFoundException(""));
Object actualResult = tested.findOne(expectedName);
assertThat(actualResult).isNull();
}
@Test
public void testFindAll() {
Name expectedName1 = LdapUtils.newLdapName("ou=aa");
Name expectedName2 = LdapUtils.newLdapName("ou=bb");
Object expectedResult1 = new Object();
Object expectedResult2 = new Object();
when(ldapOperationsMock.findByDn(expectedName1, Object.class)).thenReturn(expectedResult1);
when(ldapOperationsMock.findByDn(expectedName2, Object.class)).thenReturn(expectedResult2);
Iterable<Object> actualResult = tested.findAll(Arrays.asList(expectedName1, expectedName2));
Iterator<Object> iterator = actualResult.iterator();
assertThat(iterator.next()).isSameAs(expectedResult1);
assertThat(iterator.next()).isSameAs(expectedResult2);
assertThat(iterator.hasNext()).isFalse();
}
@Test
public void testFindAllWhereOneEntryIsNotFound() {
Name expectedName1 = LdapUtils.newLdapName("ou=aa");
Name expectedName2 = LdapUtils.newLdapName("ou=bb");
Object expectedResult2 = new Object();
when(ldapOperationsMock.findByDn(expectedName1, Object.class)).thenReturn(null);
when(ldapOperationsMock.findByDn(expectedName2, Object.class)).thenReturn(expectedResult2);
Iterable<Object> actualResult = tested.findAll(Arrays.asList(expectedName1, expectedName2));
Iterator<Object> iterator = actualResult.iterator();
assertThat(iterator.next()).isSameAs(expectedResult2);
assertThat(iterator.hasNext()).isFalse();
}
}

View File

@@ -0,0 +1,52 @@
/*
* Copyright 2016 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.data.ldap.repository.config;
import static org.assertj.core.api.Assertions.*;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;
import org.springframework.data.ldap.config.DummyLdapRepository;
import org.springframework.data.ldap.repository.config.AnnotationConfigTests.Config;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
/**
* @author Mattias Hellborg Arthursson
* @author Mark Paluch
*/
@RunWith(SpringRunner.class)
@ContextConfiguration(classes = Config.class)
public class AnnotationConfigTests {
@Autowired ApplicationContext context;
@Test
public void testAnnotationConfig() {
DummyLdapRepository repository = context.getBean(DummyLdapRepository.class);
assertThat(repository).isNotNull();
}
@Configuration
@ImportResource("classpath:/ldap-annotation-config.xml")
@EnableLdapRepositories(basePackageClasses = DummyLdapRepository.class)
static class Config {}
}

View File

@@ -0,0 +1,25 @@
/*
* Copyright 2016 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.data.ldap.repository.config;
import org.springframework.context.annotation.Configuration;
/**
* @author Mattias Hellborg Arthursson
*/
@Configuration
@EnableLdapRepositories(basePackages = "org.springframework.ldap.config")
public class SpringLdapConfiguration {}

View File

@@ -0,0 +1,30 @@
/*
* Copyright 2016 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.data.ldap.repository.query;
import java.util.List;
import org.springframework.data.ldap.repository.LdapRepository;
import org.springframework.data.ldap.repository.support.BaseUnitTestPerson;
import org.springframework.data.ldap.repository.support.UnitTestPerson;
/**
* @author Rob Winch
*/
public interface BaseTestPersonRepository extends LdapRepository<UnitTestPerson> {
List<BaseUnitTestPerson> findByFullName(String name);
}

View File

@@ -0,0 +1,147 @@
/*
* Copyright 2016 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.data.ldap.repository.query;
import static org.assertj.core.api.Assertions.*;
import java.lang.reflect.Method;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.ldap.repository.support.BaseUnitTestPerson;
import org.springframework.data.ldap.repository.support.UnitTestPerson;
import org.springframework.data.projection.ProjectionFactory;
import org.springframework.data.projection.SpelAwareProxyProjectionFactory;
import org.springframework.data.repository.core.support.DefaultRepositoryMetadata;
import org.springframework.ldap.core.LdapTemplate;
import org.springframework.ldap.query.LdapQuery;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;
/**
* @author Mattias Hellborg Arthursson
* @author Eddu Melendez
*/
@ContextConfiguration("classpath:/query-test.xml")
public class PartTreeLdapRepositoryQueryTest extends AbstractJUnit4SpringContextTests {
@Autowired private LdapTemplate ldapTemplate;
private Class<?> targetClass;
private Class<?> entityClass;
private DefaultRepositoryMetadata repositoryMetadata;
private ProjectionFactory factory;
@Before
public void prepareTest() {
entityClass = UnitTestPerson.class;
targetClass = UnitTestPersonRepository.class;
repositoryMetadata = new DefaultRepositoryMetadata(targetClass);
factory = new SpelAwareProxyProjectionFactory();
}
@Test
public void testFindByFullName() throws NoSuchMethodException {
assertFilterForMethod(targetClass.getMethod("findByFullName", String.class), "(cn=John Doe)", "John Doe");
}
// LDAP-314
@Test
public void testFindByFullNameWithBase() throws NoSuchMethodException {
entityClass = BaseUnitTestPerson.class;
targetClass = BaseTestPersonRepository.class;
repositoryMetadata = new DefaultRepositoryMetadata(targetClass);
assertFilterAndBaseForMethod(targetClass.getMethod("findByFullName", String.class), "(cn=John Doe)", "ou=someOu",
"John Doe");
}
@Test
public void testFindByFullNameLike() throws NoSuchMethodException {
assertFilterForMethod(targetClass.getMethod("findByFullNameLike", String.class), "(cn=*John*)", "*John*");
}
@Test
public void testFindByFullNameStartsWith() throws NoSuchMethodException {
assertFilterForMethod(targetClass.getMethod("findByFullNameStartsWith", String.class), "(cn=John*)", "John");
}
@Test
public void testFindByFullNameEndsWith() throws NoSuchMethodException {
assertFilterForMethod(targetClass.getMethod("findByFullNameEndsWith", String.class), "(cn=*John)", "John");
}
@Test
public void testFindByFullNameContains() throws NoSuchMethodException {
assertFilterForMethod(targetClass.getMethod("findByFullNameContains", String.class), "(cn=*John*)", "John");
}
@Test
public void testFindByFullNameGreaterThanEqual() throws NoSuchMethodException {
assertFilterForMethod(targetClass.getMethod("findByFullNameGreaterThanEqual", String.class), "(cn>=John)", "John");
}
@Test
public void testFindByFullNameLessThanEqual() throws NoSuchMethodException {
assertFilterForMethod(targetClass.getMethod("findByFullNameLessThanEqual", String.class), "(cn<=John)", "John");
}
@Test
public void testFindByFullNameIsNotNull() throws NoSuchMethodException {
assertFilterForMethod(targetClass.getMethod("findByFullNameIsNotNull"), "(cn=*)");
}
@Test
public void testFindByFullNameIsNull() throws NoSuchMethodException {
assertFilterForMethod(targetClass.getMethod("findByFullNameIsNull"), "(!(cn=*))");
}
@Test
public void testFindByFullNameNot() throws NoSuchMethodException {
assertFilterForMethod(targetClass.getMethod("findByFullNameNot", String.class), "(!(cn=John Doe))", "John Doe");
}
@Test
public void testFindByFullNameNotLike() throws NoSuchMethodException {
assertFilterForMethod(targetClass.getMethod("findByFullNameNotLike", String.class), "(!(cn=*John*))", "*John*");
}
@Test
public void testFindByFullNameAndLastName() throws NoSuchMethodException {
assertFilterForMethod(targetClass.getMethod("findByFullNameAndLastName", String.class, String.class),
"(&(cn=John Doe)(sn=Doe))", "John Doe", "Doe");
}
@Test
public void testFindByFullNameAndLastNameNot() throws NoSuchMethodException {
assertFilterForMethod(targetClass.getMethod("findByFullNameAndLastNameNot", String.class, String.class),
"(&(cn=John Doe)(!(sn=Doe)))", "John Doe", "Doe");
}
private void assertFilterForMethod(Method targetMethod, String expectedFilter, Object... expectedParams) {
assertFilterAndBaseForMethod(targetMethod, expectedFilter, "", expectedParams);
}
private void assertFilterAndBaseForMethod(Method targetMethod, String expectedFilter, String expectedBase,
Object... expectedParams) {
LdapQueryMethod queryMethod = new LdapQueryMethod(targetMethod, repositoryMetadata, factory);
PartTreeLdapRepositoryQuery tested = new PartTreeLdapRepositoryQuery(queryMethod, entityClass, ldapTemplate);
LdapQuery query = tested.createQuery(expectedParams);
String base = query.base().toString();
assertThat(base).isEqualTo(expectedBase);
assertThat(query.filter().encode()).isEqualTo(expectedFilter);
}
}

View File

@@ -0,0 +1,54 @@
/*
* Copyright 2016 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.data.ldap.repository.query;
import java.util.List;
import org.springframework.data.ldap.repository.LdapRepository;
import org.springframework.data.ldap.repository.support.UnitTestPerson;
/**
* @author Mattias Hellborg Arthursson
*/
public interface UnitTestPersonRepository extends LdapRepository<UnitTestPerson> {
List<UnitTestPerson> findByFullName(String name);
List<UnitTestPerson> findByFullNameNot(String name);
List<UnitTestPerson> findByFullNameLike(String name);
List<UnitTestPerson> findByFullNameNotLike(String name);
List<UnitTestPerson> findByFullNameStartsWith(String name);
List<UnitTestPerson> findByFullNameEndsWith(String name);
List<UnitTestPerson> findByFullNameContains(String name);
List<UnitTestPerson> findByFullNameGreaterThanEqual(String name);
List<UnitTestPerson> findByFullNameLessThanEqual(String name);
List<UnitTestPerson> findByFullNameIsNotNull();
List<UnitTestPerson> findByFullNameIsNull();
List<UnitTestPerson> findByFullNameAndLastName(String fullName, String lastName);
List<UnitTestPerson> findByFullNameAndLastNameNot(String fullName, String lastName);
}

View File

@@ -0,0 +1,49 @@
/*
* Copyright 2016 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.data.ldap.repository.support;
import java.util.List;
import javax.naming.Name;
import org.springframework.ldap.odm.annotations.Attribute;
import org.springframework.ldap.odm.annotations.DnAttribute;
import org.springframework.ldap.odm.annotations.Entry;
import org.springframework.ldap.odm.annotations.Id;
import org.springframework.ldap.odm.annotations.Transient;
/**
* @author Rob Winch
*/
@Entry(base = "ou=someOu", objectClasses = { "inetOrgPerson", "organizationalPerson", "person", "top" })
public class BaseUnitTestPerson {
@Id private Name dn;
@Attribute(name = "cn") @DnAttribute("cn") private String fullName;
@Attribute(name = "sn") private String lastName;
@Attribute(name = "description") private List<String> description;
@Transient @DnAttribute("c") private String country;
@Transient @DnAttribute("ou") private String company;
// This should be automatically found
private String telephoneNumber;
}

View File

@@ -0,0 +1,58 @@
/*
* Copyright 2016 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.data.ldap.repository.support;
import static com.querydsl.core.types.PathMetadataFactory.*;
import javax.annotation.Generated;
import com.querydsl.core.types.Path;
import com.querydsl.core.types.PathMetadata;
import com.querydsl.core.types.dsl.EntityPathBase;
import com.querydsl.core.types.dsl.ListPath;
import com.querydsl.core.types.dsl.PathInits;
import com.querydsl.core.types.dsl.StringPath;
/**
* QPerson is a Querydsl query type for Person
*/
@Generated("com.mysema.query.codegen.EntitySerializer")
public class QPerson extends EntityPathBase<UnitTestPerson> {
private static final long serialVersionUID = -1526737794;
public static final QPerson person = new QPerson("person");
public final StringPath fullName = createString("fullName");
public final ListPath<String, StringPath> description = this.<String, StringPath> createList("description",
String.class, StringPath.class, PathInits.DIRECT2);
public final StringPath lastName = createString("lastName");
public QPerson(String variable) {
super(UnitTestPerson.class, forVariable(variable));
}
public QPerson(Path<? extends UnitTestPerson> path) {
super(path.getType(), path.getMetadata());
}
public QPerson(PathMetadata metadata) {
super(UnitTestPerson.class, metadata);
}
}

View File

@@ -0,0 +1,122 @@
/*
* Copyright 2016 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.data.ldap.repository.support;
import static org.assertj.core.api.Assertions.*;
import org.junit.Before;
import org.junit.Test;
import org.springframework.ldap.filter.Filter;
import org.springframework.ldap.odm.core.ObjectDirectoryMapper;
import org.springframework.ldap.odm.core.impl.DefaultObjectDirectoryMapper;
import com.querydsl.core.types.Expression;
/**
* @author Mattias Hellborg Arthursson
* @author Eddu Melendez
*/
public class QueryDslFilterGeneratorTest {
private LdapSerializer tested;
private QPerson person;
@Before
public void prepareTestedInstance() {
ObjectDirectoryMapper odm = new DefaultObjectDirectoryMapper();
tested = new LdapSerializer(odm, UnitTestPerson.class);
person = QPerson.person;
}
@Test
public void testEqualsFilter() {
Expression<?> expression = person.fullName.eq("John Doe");
Filter result = tested.handle(expression);
assertThat(result.toString()).isEqualTo("(cn=John Doe)");
}
@Test
public void testAndFilter() {
Expression<?> expression = person.fullName.eq("John Doe").and(person.lastName.eq("Doe"));
Filter result = tested.handle(expression);
assertThat(result.toString()).isEqualTo("(&(cn=John Doe)(sn=Doe))");
}
@Test
public void testOrFilter() {
Expression<?> expression = person.fullName.eq("John Doe").or(person.lastName.eq("Doe"));
Filter result = tested.handle(expression);
assertThat(result.toString()).isEqualTo("(|(cn=John Doe)(sn=Doe))");
}
@Test
public void testOr() {
Expression<?> expression = person.fullName.eq("John Doe")
.and(person.lastName.eq("Doe").or(person.lastName.eq("Die")));
Filter result = tested.handle(expression);
assertThat(result.toString()).isEqualTo("(&(cn=John Doe)(|(sn=Doe)(sn=Die)))");
}
@Test
public void testNot() {
Expression<?> expression = person.fullName.eq("John Doe").not();
Filter result = tested.handle(expression);
assertThat(result.toString()).isEqualTo("(!(cn=John Doe))");
}
@Test
public void testIsLike() {
Expression<?> expression = person.fullName.like("kalle*");
Filter result = tested.handle(expression);
assertThat(result.toString()).isEqualTo("(cn=kalle*)");
}
@Test
public void testStartsWith() {
Expression<?> expression = person.fullName.startsWith("kalle");
Filter result = tested.handle(expression);
assertThat(result.toString()).isEqualTo("(cn=kalle*)");
}
@Test
public void testEndsWith() {
Expression<?> expression = person.fullName.endsWith("kalle");
Filter result = tested.handle(expression);
assertThat(result.toString()).isEqualTo("(cn=*kalle)");
}
@Test
public void testContains() {
Expression<?> expression = person.fullName.contains("kalle");
Filter result = tested.handle(expression);
assertThat(result.toString()).isEqualTo("(cn=*kalle*)");
}
@Test
public void testNotNull() {
Expression<?> expression = person.fullName.isNotNull();
Filter result = tested.handle(expression);
assertThat(result.toString()).isEqualTo("(cn=*)");
}
@Test
public void testNull() {
Expression<?> expression = person.fullName.isNull();
Filter result = tested.handle(expression);
assertThat(result.toString()).isEqualTo("(!(cn=*))");
}
}

View File

@@ -0,0 +1,58 @@
/*
* Copyright 2016 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.data.ldap.repository.support;
import java.util.List;
import javax.naming.Name;
import org.springframework.ldap.odm.annotations.Attribute;
import org.springframework.ldap.odm.annotations.DnAttribute;
import org.springframework.ldap.odm.annotations.Entry;
import org.springframework.ldap.odm.annotations.Id;
import org.springframework.ldap.odm.annotations.Transient;
/**
* @author Mattias Hellborg Arthursson
*/
@Entry(objectClasses = {"inetOrgPerson", "organizationalPerson", "person", "top"})
public class UnitTestPerson {
@Id
private Name dn;
@Attribute(name = "cn")
@DnAttribute("cn")
private String fullName;
@Attribute(name = "sn")
private String lastName;
@Attribute(name = "description")
private List<String> description;
@Transient
@DnAttribute("c")
private String country;
@Transient
@DnAttribute("ou")
private String company;
// This should be automatically found
private String telephoneNumber;
}

View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ldap="http://www.springframework.org/schema/ldap"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/ldap http://www.springframework.org/schema/ldap/spring-ldap.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<ldap:context-source password="apassword" url="ldap://localhost:389" username="uid=admin"/>
<ldap:ldap-template/>
<context:component-scan base-package="org.springframework.data.ldap.repository.config"/>
</beans>

View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ldap="http://www.springframework.org/schema/ldap"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/ldap http://www.springframework.org/schema/ldap/spring-ldap.xsd">
<ldap:context-source url="ldap://localhost:389"
username="cn=Admin"
password="secret" />
<ldap:ldap-template />
<ldap:repositories base-package="org.springframework.ldap.repository.query" />
</beans>