001/*
002 * The contents of this file are subject to the terms of the Common Development and
003 * Distribution License (the License). You may not use this file except in compliance with the
004 * License.
005 *
006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
007 * specific language governing permission and limitations under the License.
008 *
009 * When distributing Covered Software, include this CDDL Header Notice in each file and include
010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
011 * Header, with the fields enclosed by brackets [] replaced by your own identifying
012 * information: "Portions copyright [year] [name of copyright owner]".
013 *
014 * Copyright 2015-2016 ForgeRock AS.
015 */
016package org.forgerock.selfservice.json;
017
018import java.util.HashMap;
019import java.util.Map;
020
021import org.forgerock.json.JsonValue;
022import org.forgerock.selfservice.core.AnonymousProcessService;
023import org.forgerock.selfservice.core.ProcessStore;
024import org.forgerock.selfservice.core.ProgressStageProvider;
025import org.forgerock.selfservice.core.config.ProcessInstanceConfig;
026import org.forgerock.selfservice.core.config.StageConfig;
027import org.forgerock.selfservice.core.snapshot.SnapshotTokenHandlerFactory;
028import org.forgerock.util.Reject;
029
030/**
031 * Builder for {@link AnonymousProcessService} from JSON config and AnonymousProcessService requirements.
032 *
033 * @since 20.0.0
034 */
035public final class JsonAnonymousProcessServiceBuilder {
036
037    private ClassLoader classLoader = getClass().getClassLoader(); // assume this ClassLoader if not supplied
038    private Map<String, Class<? extends StageConfig>> stageConfigMappings = new HashMap<>();
039    private JsonValue jsonConfig;
040    private ProgressStageProvider progressStageProvider;
041    private SnapshotTokenHandlerFactory tokenHandlerFactory;
042    private ProcessStore processStore;
043
044    private JsonAnonymousProcessServiceBuilder() {
045        // prevent direct instantiation
046    }
047
048    /**
049     * Construct a new JsonAnonymousProcessServiceBuilder.
050     *
051     * @return the JsonAnonymousProcesssServiceBuilder.
052     */
053    public static JsonAnonymousProcessServiceBuilder newBuilder() {
054        return new JsonAnonymousProcessServiceBuilder();
055    }
056
057    /**
058     * Set the ClassLoader.
059     *
060     * @param classLoader the ClassLoader
061     * @return this builder instance
062     */
063    public JsonAnonymousProcessServiceBuilder withClassLoader(ClassLoader classLoader) {
064        this.classLoader = classLoader;
065        return this;
066    }
067
068    /**
069     * Provide additional named type-mapping, if desired.
070     *
071     * @param name the {@code name} attribute value to associate with the new stage config type
072     * @param type the {@link StageConfig} type to associate
073     * @return this builder instance
074     */
075    public JsonAnonymousProcessServiceBuilder withStageConfigMapping(String name, Class<? extends StageConfig> type) {
076        this.stageConfigMappings.put(name, type);
077        return this;
078    }
079
080    /**
081     * Set the JSON config from which to build the {@link ProcessInstanceConfig}.
082     *
083     * @param jsonConfig the JSON config for a {@link ProcessInstanceConfig}.
084     * @return this builder instance
085     */
086    public JsonAnonymousProcessServiceBuilder withJsonConfig(JsonValue jsonConfig) {
087        this.jsonConfig = jsonConfig;
088        return this;
089    }
090
091    /**
092     * Sets the {@link ProgressStageProvider}.
093     *
094     * @param progressStageProvider the {@link ProgressStageProvider}.
095     * @return this builder instance
096     */
097    public JsonAnonymousProcessServiceBuilder withProgressStageProvider(ProgressStageProvider progressStageProvider) {
098        this.progressStageProvider = progressStageProvider;
099        return this;
100    }
101
102    /**
103     * Sets the {@link SnapshotTokenHandlerFactory}.
104     *
105     * @param tokenHandlerFactory the {@link SnapshotTokenHandlerFactory}.
106     * @return this builder instance
107     */
108    public JsonAnonymousProcessServiceBuilder withTokenHandlerFactory(SnapshotTokenHandlerFactory tokenHandlerFactory) {
109        this.tokenHandlerFactory = tokenHandlerFactory;
110        return this;
111    }
112
113    /**
114     * Sets the {@link ProcessStore}.
115     *
116     * @param processStore the {@link ProcessStore}.
117     * @return this builder instance
118     */
119    public JsonAnonymousProcessServiceBuilder withProcessStore(ProcessStore processStore) {
120        this.processStore = processStore;
121        return this;
122    }
123
124    /**
125     * Build an {@link AnonymousProcessService} from the JSON config and the other elements.
126     *
127     * @return the {@link AnonymousProcessService}
128     */
129    public AnonymousProcessService build() {
130        Reject.ifNull(classLoader, jsonConfig, progressStageProvider, tokenHandlerFactory, processStore);
131        ProcessInstanceConfig config = new JsonConfig(classLoader, stageConfigMappings)
132                .buildProcessInstanceConfig(jsonConfig);
133        Reject.ifNull(config.getStageConfigs(), config.getSnapshotTokenConfig(), config.getStorageType());
134        Reject.ifTrue(config.getStageConfigs().isEmpty());
135        return new AnonymousProcessService(config, progressStageProvider, tokenHandlerFactory, processStore,
136                classLoader);
137    }
138}