Package com.saasovation.agilepm.application.product

Source Code of com.saasovation.agilepm.application.product.ProductApplicationService

//   Copyright 2012,2013 Vaughn Vernon
//
//   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 com.saasovation.agilepm.application.product;

import java.util.Date;

import com.saasovation.agilepm.application.ApplicationServiceLifeCycle;
import com.saasovation.agilepm.domain.model.discussion.DiscussionAvailability;
import com.saasovation.agilepm.domain.model.discussion.DiscussionDescriptor;
import com.saasovation.agilepm.domain.model.product.Product;
import com.saasovation.agilepm.domain.model.product.ProductDiscussionRequestTimedOut;
import com.saasovation.agilepm.domain.model.product.ProductId;
import com.saasovation.agilepm.domain.model.product.ProductRepository;
import com.saasovation.agilepm.domain.model.team.ProductOwner;
import com.saasovation.agilepm.domain.model.team.ProductOwnerRepository;
import com.saasovation.agilepm.domain.model.tenant.TenantId;
import com.saasovation.common.domain.model.process.ProcessId;
import com.saasovation.common.domain.model.process.TimeConstrainedProcessTracker;
import com.saasovation.common.domain.model.process.TimeConstrainedProcessTrackerRepository;

public class ProductApplicationService {

    private TimeConstrainedProcessTrackerRepository processTrackerRepository;
    private ProductOwnerRepository productOwnerRepository;
    private ProductRepository productRepository;

    public ProductApplicationService(
            ProductRepository aProductRepository,
            ProductOwnerRepository aProductOwnerRepository,
            TimeConstrainedProcessTrackerRepository aProcessTrackerRepository) {

        super();

        this.processTrackerRepository = aProcessTrackerRepository;
        this.productOwnerRepository = aProductOwnerRepository;
        this.productRepository = aProductRepository;
    }

    // TODO: additional APIs / student assignment

    public void initiateDiscussion(InitiateDiscussionCommand aCommand) {
        ApplicationServiceLifeCycle.begin();

        try {
            Product product =
                    this.productRepository()
                        .productOfId(
                                new TenantId(aCommand.getTenantId()),
                                new ProductId(aCommand.getProductId()));

            if (product == null) {
                throw new IllegalStateException(
                        "Unknown product of tenant id: "
                        + aCommand.getTenantId()
                        + " and product id: "
                        + aCommand.getProductId());
            }

            product.initiateDiscussion(new DiscussionDescriptor(aCommand.getDiscussionId()));

            this.productRepository().save(product);

            ProcessId processId = ProcessId.existingProcessId(product.discussionInitiationId());

            TimeConstrainedProcessTracker tracker =
                    this.processTrackerRepository()
                        .trackerOfProcessId(aCommand.getTenantId(), processId);

            tracker.completed();

            this.processTrackerRepository().save(tracker);

            ApplicationServiceLifeCycle.success();

        } catch (RuntimeException e) {
            ApplicationServiceLifeCycle.fail(e);
        }
    }

    public String newProduct(NewProductCommand aCommand) {

        return this.newProductWith(
                aCommand.getTenantId(),
                aCommand.getProductOwnerId(),
                aCommand.getName(),
                aCommand.getDescription(),
                DiscussionAvailability.NOT_REQUESTED);
    }

    public String newProductWithDiscussion(NewProductCommand aCommand) {

        return this.newProductWith(
                aCommand.getTenantId(),
                aCommand.getProductOwnerId(),
                aCommand.getName(),
                aCommand.getDescription(),
                this.requestDiscussionIfAvailable());
    }

    public void requestProductDiscussion(RequestProductDiscussionCommand aCommand) {
        Product product =
                this.productRepository()
                    .productOfId(
                            new TenantId(aCommand.getTenantId()),
                            new ProductId(aCommand.getProductId()));

        if (product == null) {
            throw new IllegalStateException(
                    "Unknown product of tenant id: "
                    + aCommand.getTenantId()
                    + " and product id: "
                    + aCommand.getProductId());
        }

        this.requestProductDiscussionFor(product);
    }

    public void retryProductDiscussionRequest(RetryProductDiscussionRequestCommand aCommand) {

        ProcessId processId = ProcessId.existingProcessId(aCommand.getProcessId());

        TenantId tenantId = new TenantId(aCommand.getTenantId());

        Product product =
                this.productRepository()
                    .productOfDiscussionInitiationId(
                            tenantId,
                            processId.id());

        if (product == null) {
            throw new IllegalStateException(
                    "Unknown product of tenant id: "
                    + aCommand.getTenantId()
                    + " and discussion initiation id: "
                    + processId.id());
        }

        this.requestProductDiscussionFor(product);
    }

    public void startDiscussionInitiation(StartDiscussionInitiationCommand aCommand) {

        ApplicationServiceLifeCycle.begin();

        try {
            Product product =
                    this.productRepository()
                        .productOfId(
                                new TenantId(aCommand.getTenantId()),
                                new ProductId(aCommand.getProductId()));

            if (product == null) {
                throw new IllegalStateException(
                        "Unknown product of tenant id: "
                        + aCommand.getTenantId()
                        + " and product id: "
                        + aCommand.getProductId());
            }

            String timedOutEventName =
                    ProductDiscussionRequestTimedOut.class.getName();

            TimeConstrainedProcessTracker tracker =
                    new TimeConstrainedProcessTracker(
                            product.tenantId().id(),
                            ProcessId.newProcessId(),
                            "Create discussion for product: "
                                + product.name(),
                            new Date(),
                            5L * 60L * 1000L, // retries every 5 minutes
                            3, // 3 total retries
                            timedOutEventName);

            this.processTrackerRepository().save(tracker);

            product.startDiscussionInitiation(tracker.processId().id());

            this.productRepository().save(product);

            ApplicationServiceLifeCycle.success();

        } catch (RuntimeException e) {
            ApplicationServiceLifeCycle.fail(e);
        }
    }

    public void timeOutProductDiscussionRequest(TimeOutProductDiscussionRequestCommand aCommand) {

        ApplicationServiceLifeCycle.begin();

        try {
            ProcessId processId = ProcessId.existingProcessId(aCommand.getProcessId());

            TenantId tenantId = new TenantId(aCommand.getTenantId());

            Product product =
                    this.productRepository()
                        .productOfDiscussionInitiationId(
                                tenantId,
                                processId.id());

            this.sendEmailForTimedOutProcess(product);

            product.failDiscussionInitiation();

            this.productRepository().save(product);

            ApplicationServiceLifeCycle.success();

        } catch (RuntimeException e) {
            ApplicationServiceLifeCycle.fail(e);
        }
    }

    private void sendEmailForTimedOutProcess(Product aProduct) {

        // TODO: Implement

    }

    private String newProductWith(
            String aTenantId,
            String aProductOwnerId,
            String aName,
            String aDescription,
            DiscussionAvailability aDiscussionAvailability) {

        TenantId tenantId = new TenantId(aTenantId);
        ProductId productId = null;

        ApplicationServiceLifeCycle.begin();

        try {
            productId = this.productRepository().nextIdentity();

            ProductOwner productOwner =
                    this.productOwnerRepository()
                        .productOwnerOfIdentity(
                                tenantId,
                                aProductOwnerId);

            Product product =
                    new Product(
                            tenantId,
                            productId,
                            productOwner.productOwnerId(),
                            aName,
                            aDescription,
                            aDiscussionAvailability);

            this.productRepository().save(product);

            ApplicationServiceLifeCycle.success();

        } catch (RuntimeException e) {
            ApplicationServiceLifeCycle.fail(e);
        }

        return productId.id();
    }

    private DiscussionAvailability requestDiscussionIfAvailable() {
        DiscussionAvailability availability = DiscussionAvailability.ADD_ON_NOT_ENABLED;

        boolean enabled = true; // TODO: determine add-on enabled

        if (enabled) {
            availability = DiscussionAvailability.REQUESTED;
        }

        return availability;
    }

    private TimeConstrainedProcessTrackerRepository processTrackerRepository() {
        return this.processTrackerRepository;
    }

    private ProductOwnerRepository productOwnerRepository() {
        return this.productOwnerRepository;
    }

    private ProductRepository productRepository() {
        return this.productRepository;
    }

    private void requestProductDiscussionFor(Product aProduct) {

        ApplicationServiceLifeCycle.begin();

        try {
            aProduct.requestDiscussion(this.requestDiscussionIfAvailable());

            this.productRepository().save(aProduct);

            ApplicationServiceLifeCycle.success();

        } catch (RuntimeException e) {
            ApplicationServiceLifeCycle.fail(e);
        }
    }
}
TOP

Related Classes of com.saasovation.agilepm.application.product.ProductApplicationService

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.