Skip to content

Antora #783

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Jul 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions .github/workflows/deploy-docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: Deploy Docs
on:
push:
branches-ignore: [ gh-pages ]
tags: '**'
repository_dispatch:
types: request-build-reference # legacy
#schedule:
#- cron: '0 10 * * *' # Once per day at 10am UTC
workflow_dispatch:
permissions:
actions: write
jobs:
build:
runs-on: ubuntu-latest
# FIXME enable when pushed to spring-projects
# if: github.repository_owner == 'spring-projects'
steps:
- name: Checkout
uses: actions/checkout@v3
with:
ref: docs-build
fetch-depth: 1
- name: Dispatch (partial build)
if: github.ref_type == 'branch'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: gh workflow run deploy-docs.yml -r $(git rev-parse --abbrev-ref HEAD) -f build-refname=${{ github.ref_name }}
- name: Dispatch (full build)
if: github.ref_type == 'tag'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: gh workflow run deploy-docs.yml -r $(git rev-parse --abbrev-ref HEAD)
19 changes: 19 additions & 0 deletions antora.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
name: ldap
version: true
title: Spring LDAP
nav:
- modules/ROOT/nav.adoc
ext:
collector:
run:
command: gradlew -q -PbuildSrc.skipTests=true "-Dorg.gradle.jvmargs=-Xmx3g -XX:+HeapDumpOnOutOfMemoryError" generateAntoraYml
local: true
scan:
dir: ./build/generated-antora-resources

asciidoc:
attributes:
attribute-missing: 'warn'
# FIXME: the copyright is not removed
# FIXME: The package is not renamed
chomp: 'all'
44 changes: 25 additions & 19 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ buildscript {
}
}

plugins {
id 'io.spring.antora.generate-antora-yml' version '0.0.1'
id 'org.antora' version '1.0.0'
}

apply plugin: 'io.spring.convention.root'
apply plugin: 'io.spring.convention.docs'
apply plugin: 'io.spring.javaformat'
Expand All @@ -32,26 +37,27 @@ nohttp {
source.exclude "buildSrc/build/**"
}

asciidoctor {
outputDir = new File("$buildDir/docs")
attributes([
copycss : '',
icons : 'font',
'source-highlighter': 'prettify',
sectanchors : '',
toc2: '',
idprefix: '',
idseparator: '-',
doctype: 'book',
numbered: '',
'spring-ldap-version' : project.version,
revnumber : project.version
])
options = [
eruby: 'erubis'
]

antora {
playbook = 'cached-antora-playbook.yml'
playbookProvider {
repository = 'spring-projects/spring-ldap'
branch = 'docs-build'
path = 'lib/antora/templates/per-branch-antora-playbook.yml'
checkLocalBranch = true
}
options = [clean: true, fetch: !project.gradle.startParameter.offline, stacktrace: true]
}



tasks.named("generateAntoraYml") {
asciidocAttributes = project.provider( {
return ['project-version': project.version]
} )
}


s101 {
configurationDirectory = project.file("etc/s101")
}
Expand All @@ -60,7 +66,7 @@ allprojects {
if (!['spring-ldap-bom', 'spring-security-docs'].contains(project.name)) {
apply plugin: 'io.spring.javaformat'
apply plugin: 'checkstyle'

pluginManager.withPlugin("io.spring.convention.checkstyle", { plugin ->
configure(plugin) {
dependencies {
Expand Down
39 changes: 39 additions & 0 deletions cached-antora-playbook.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# PACKAGES [email protected] @antora/atlas-extension:1.0.0-alpha.1 @antora/[email protected] @springio/[email protected] @asciidoctor/[email protected] @springio/asciidoctor-extensions @opendevise/[email protected]
#
# The purpose of this Antora playbook is to build the docs in the current branch.
antora:
extensions:
- '@antora/collector-extension'
- id: '@antora/atlas-extension'
require: '@antora/atlas-extension'
enabled: false
- '@springio/antora-extensions/latest-version-extension'
- require: '@springio/antora-extensions/root-component-extension'
root_component_name: 'ldap'
site:
title: Spring LDAP Reference
content:
sources:
- url: .
branches: HEAD
worktrees: true
asciidoc:
attributes:
hide-uri-scheme: '@'
page-pagination: ''
primary-site-url: https://docs.spring.io/spring-ldap/reference
tabs-sync-option: '@'
extensions:
- '@asciidoctor/tabs'
- '@springio/asciidoctor-extensions'
- '@springio/asciidoctor-extensions/include-code-extension'
sourcemap: true
urls:
latest_version_segment: ''
runtime:
log:
failure_level: warn
ui:
bundle:
url: https://github.com/spring-io/antora-ui-spring/releases/download/latest/ui-bundle.zip
snapshot: true
18 changes: 18 additions & 0 deletions modules/ROOT/nav.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
* xref:index.adoc[]
* xref:preface.adoc[]
* xref:introduction.adoc[]
* xref:spring-ldap-basic-usage.adoc[]
* xref:dirobjectfactory.adoc[]
* xref:odm.adoc[]
* xref:query-builder-advanced.adoc[]
* xref:configuration.adoc[]
* xref:repositories.adoc[]
* xref:pooling.adoc[]
* xref:adding-missing-overloaded-api-methods.adoc[]
* xref:processing-the-dircontext.adoc[]
* xref:transaction-support.adoc[]
* xref:user-authentication.adoc[]
* xref:ldif-parsing.adoc[]
* xref:utilities.adoc[]
* xref:testing.adoc[]
* xref:faq.adoc[]
144 changes: 144 additions & 0 deletions modules/ROOT/pages/adding-missing-overloaded-api-methods.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
[[adding-missing-overloaded-api-methods]]
= Adding Missing Overloaded API Methods

This section covers how to add your own overloaded API methods to implement new functionality.

[[implementing-custom-search-methods]]
== Implementing Custom Search Methods

`LdapTemplate` contains several overloaded versions of the most common operations in `DirContext`. However, we have not provided an alternative for each and every method signature, mostly because there are so many of them. We have, however, provided a means to call whichever `DirContext` method you want and still get the benefits that `LdapTemplate` provides.

Suppose you want to call the following `DirContext` method:

====
[source,java]
[subs="verbatim,quotes"]
----
NamingEnumeration search(Name name, String filterExpr, Object[] filterArgs, SearchControls ctls)
----
====

There is no corresponding overloaded method in `LdapTemplate`. The way to solve this is to use a custom `SearchExecutor` implementation, as follows:

====
[source,java]
[subs="verbatim,quotes"]
----
public interface SearchExecutor {
public NamingEnumeration executeSearch(DirContext ctx) throws NamingException;
}
----
====

In your custom executor, you have access to a `DirContext` object, which you can use to call the method you want. You can then provide a handler that is responsible for mapping attributes and collecting the results. You can, for example, use one of the available implementations of `CollectingNameClassPairCallbackHandler`, which collects the mapped results in an internal list. In order to actually perform the search, you need to call the `search` method in `LdapTemplate` that takes an executor and a handler as arguments. Finally, you need to return whatever your handler has collected. The following example shows how to do all of that:

.A custom search method using `SearchExecutor` and `AttributesMapper`
====
[source,java]
[subs="verbatim,quotes"]
----
package com.example.repo;

public class PersonRepoImpl implements PersonRepo {
...
public List search(final Name base, final String filter, final String[] params,
final SearchControls ctls) {
**SearchExecutor executor = new SearchExecutor() {
public NamingEnumeration executeSearch(DirContext ctx) {
return ctx.search(base, filter, params, ctls);
}
};**

CollectingNameClassPairCallbackHandler handler =
new AttributesMapperCallbackHandler(new PersonAttributesMapper());

ldapTemplate.search(**executor**, handler);
return handler.getList();
}
}
----
====

If you prefer the `ContextMapper` to the `AttributesMapper`, the following example shows what it would look like:

.A custom search method using `SearchExecutor` and `ContextMapper`
====
[source,java]
[subs="verbatim,quotes"]
----
package com.example.repo;

public class PersonRepoImpl implements PersonRepo {
...
public List search(final Name base, final String filter, final String[] params,
final SearchControls ctls) {
SearchExecutor executor = new SearchExecutor() {
public NamingEnumeration executeSearch(DirContext ctx) {
return ctx.search(base, filter, params, ctls);
}
};

CollectingNameClassPairCallbackHandler handler =
**new ContextMapperCallbackHandler(new PersonContextMapper()**);

ldapTemplate.search(executor, handler);
return handler.getList();
}
}
----
====

NOTE: When you use the `ContextMapperCallbackHandler`, you must make sure that you have called `setReturningObjFlag(true)` on your `SearchControls` instance.

[[implementing-other-custom-context-methods]]
== Implementing Other Custom Context Methods

In the same manner as for custom `search` methods, you can actually call any method in `DirContext` by using a `ContextExecutor`, as follows:

====
[source,java]
[subs="verbatim,quotes"]
----
public interface ContextExecutor {
public Object executeWithContext(DirContext ctx) throws NamingException;
}
----
====

When implementing a custom `ContextExecutor`, you can choose between using the `executeReadOnly()` or the `executeReadWrite()` method. Suppose you want to call the following method:

====
[source,java]
[subs="verbatim,quotes"]
----
Object lookupLink(Name name)
----
====

The method is available in `DirContext`, but there is no matching method in `LdapTemplate`. It is a lookup method, so it should be read-only. We can implement it as follows:

.A custom `DirContext` method using `ContextExecutor`
====
[source,java]
[subs="verbatim,quotes"]
----
package com.example.repo;

public class PersonRepoImpl implements PersonRepo {
...
public Object lookupLink(final Name name) {
ContextExecutor executor = new ContextExecutor() {
public Object executeWithContext(DirContext ctx) {
return ctx.lookupLink(name);
}
};

return ldapTemplate.executeReadOnly(executor);
}
}
----
====

In the same manner, you can perform a read-write operation by using the `executeReadWrite()` method.


Loading