com.castlemock.web.basis.model.ServiceFacadeImpl.java Source code

Java tutorial

Introduction

Here is the source code for com.castlemock.web.basis.model.ServiceFacadeImpl.java

Source

/*
 * Copyright 2015 Karl Dahlgren
 *
 * 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.castlemock.web.basis.model;

import com.castlemock.core.basis.model.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;

import java.io.Serializable;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

/**
 * The facade class is responsible for gather all services for a specific type and collaborate with all services
 * in order to provide unified functionality. This enables the using classes to operate all service of a specific type
 * from one single point.
 * @author Karl Dahlgren
 * @since 1.0
 * @see Service
 */
@org.springframework.stereotype.Service
public abstract class ServiceFacadeImpl<D extends TypeIdentifiable, I extends Serializable, SA extends ServiceAdapter<D, D, I>>
        implements ServiceFacade<D, I> {

    @Autowired
    private ApplicationContext applicationContext;
    protected final Map<String, SA> services = new HashMap<String, SA>();

    /**
     * The initialize method is responsible for for locating all the service instances for a specific module
     * and organizing them depending on the type.
     * @param clazz The class of the {@link ServiceAdapter} that the facade is managing
     * @see Service
     * @see TypeIdentifier
     * @see TypeIdentifiable
     */
    protected void initiate(final Class<?> clazz) {
        final Map<String, Object> foundServices = applicationContext
                .getBeansWithAnnotation(org.springframework.stereotype.Service.class);

        for (Map.Entry<String, Object> entry : foundServices.entrySet()) {
            final Object value = entry.getValue();
            if (clazz.isInstance(value)) {
                final SA serviceAdapter = (SA) value;
                final String type = serviceAdapter.getTypeIdentifier().getType().toUpperCase();
                services.put(type, serviceAdapter);
            }
        }
    }

    /**
     * The method provides the functionality to create and store a DTO instance to a specific service.
     * The service is identified with the provided type value.
     * @param type The type of the instance that will be created
     * @param dto The instance that will be created
     * @return The saved instance
     */
    @Override
    public D save(final String type, final D dto) {
        final SA serviceAdapter = findByType(type);
        final D convertedDto = serviceAdapter.convertType(dto);
        return serviceAdapter.create(convertedDto);
    }

    /**
     * The method provides the functionality to delete a specific instance. The type is
     * identified with the provided typeUrl value. When the type has been identified, the instance
     * itself has to be identified. This is done with the provided id. The instance with the matching type
     * and id will be deleted.
     * @param typeUrl The url for the specific type that the instance belongs to
     * @param id The id of the instance that will be deleted
     */
    @Override
    public void delete(final String typeUrl, final I id) {
        final ServiceAdapter serviceAdapter = findByTypeUrl(typeUrl);
        serviceAdapter.delete(id);
    }

    /**
     * The method is used to update an already existing instance. The instance type is
     * identified with the provided typeUrl value. When the instance type has been identified, the instance
     * itself has to be identified. This is done with the provided id. The instance with the matching id will be
     * replaced with the provided dto instance. Please note that not all values will be updated. It depends on the instance
     * type.
     * @param typeUrl The url for the specific type that the instance belongs to
     * @param id The id of the instance that will be updated
     * @param dto The instance with the new updated values
     * @return The updated instance
     */
    @Override
    public D update(final String typeUrl, final I id, final D dto) {
        final SA serviceAdapter = findByTypeUrl(typeUrl);
        final D convertedDto = serviceAdapter.convertType(dto);
        return serviceAdapter.update(id, convertedDto);
    }

    /**
     * The method is responsible for retrieving all instances from all the various service types.
     * @return A list containing all the instance independent from type
     */
    @Override
    public List<D> findAll() {
        final List<D> dtoList = new LinkedList<D>();
        for (Map.Entry<String, SA> entry : services.entrySet()) {
            SA serviceAdapter = entry.getValue();

            for (D dto : serviceAdapter.readAll()) {
                dto.setTypeIdentifier(serviceAdapter.getTypeIdentifier());
                dtoList.add(dto);
            }
        }
        return dtoList;
    }

    /**
     * The method is used to retrieve a instance with a specific type. The type is
     * identified with the provided typeUrl value. When the instance type has been identified, the instance
     * itself has to be identified.
     * @param typeUrl The url for the specific type that the instance belongs to
     * @param id The id of the instance that will be retrieved
     * @return A instance that matches the instance type and the provided id. If no instance matches the provided
     *         values, null will be returned.
     */
    @Override
    public D findOne(String typeUrl, final I id) {
        final SA serviceAdapter = findByTypeUrl(typeUrl);
        final D dto = serviceAdapter.read(id);
        final TypeIdentifier typeIdentifier = serviceAdapter.getTypeIdentifier();
        dto.setTypeIdentifier(typeIdentifier);
        return dto;
    }

    /**
     * The method retrieves all service types
     * @return A list with all the service types
     */
    @Override
    public List<String> getTypes() {
        return new LinkedList<String>(services.keySet());
    }

    /**
     * The method is responsible for finding a service class that has the same type url as the
     * one provided.
     * @param typeUrl The type url which the service class must match
     * @return A service that has the same type url as the one provided
     * @throws IllegalArgumentException A IllegalArgumentException will be thrown
     * if no service matches the provided type
     */
    protected SA findByTypeUrl(final String typeUrl) {
        SA serviceAdapter = null;
        for (SA tmpService : services.values()) {
            if (tmpService.getTypeIdentifier().getTypeUrl().equals(typeUrl)) {
                serviceAdapter = tmpService;
                break;
            }
        }

        if (serviceAdapter == null) {
            throw new IllegalArgumentException("Invalid type");
        }

        return serviceAdapter;
    }

    /**
     * The method provides the functionality to find a service class that has the same type
     * as the one provided.
     * @param type The type that the service has to match
     * @return A service that has the same type as the one provided
     * @throws IllegalArgumentException A IllegalArgumentException will be thrown
     * If no service matches the provided type
     */
    protected SA findByType(final String type) {
        final SA serviceAdapter = services.get(type.toUpperCase());

        if (serviceAdapter == null) {
            throw new IllegalArgumentException("Invalid type");
        }

        return serviceAdapter;
    }

    /**
     * Returns the type URL for a specific type
     * @param type The type that will be used to retrieve the type URL
     * @return The matching type URL
     * @throws IllegalArgumentException A IllegalArgumentException will be thrown
     * If no service matches the provided type
     */
    @Override
    public String getTypeUrl(final String type) {
        final SA serviceAdapter = findByType(type);
        return serviceAdapter.getTypeIdentifier().getTypeUrl();
    }
}