com.asakusafw.runtime.flow.RuntimeResourceManager.java Source code

Java tutorial

Introduction

Here is the source code for com.asakusafw.runtime.flow.RuntimeResourceManager.java

Source

/**
 * Copyright 2011-2017 Asakusa Framework Team.
 *
 * 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.asakusafw.runtime.flow;

import java.io.IOException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.ServiceLoader;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.conf.Configurable;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.conf.Configured;

import com.asakusafw.runtime.core.HadoopConfiguration;
import com.asakusafw.runtime.core.legacy.RuntimeResource;

/**
 * Manages lifecycle of {@link RuntimeResource} objects.
 * @since 0.1.0
 * @version 0.7.3
 */
public class RuntimeResourceManager extends Configured {

    static final Log LOG = LogFactory.getLog(RuntimeResourceManager.class);

    /**
     * The standard name of the framework configuration file.
     */
    public static final String CONFIGURATION_FILE_NAME = "asakusa-resources.xml"; //$NON-NLS-1$

    /**
     * The path to configuration file (relative from $ASAKUSA_HOME).
     * @since 0.2.5
     */
    public static final String CONFIGURATION_FILE_PATH = "core/conf/" + CONFIGURATION_FILE_NAME; //$NON-NLS-1$

    private final HadoopConfiguration configuration;

    private List<RuntimeResource> resources;

    /**
     * Creates a new instance.
     * @param configuration the current configuration
     * @throws IllegalArgumentException if the parameter is {@code null}
     */
    public RuntimeResourceManager(Configuration configuration) {
        super(configuration);
        if (configuration == null) {
            throw new IllegalArgumentException("configuration must not be null"); //$NON-NLS-1$
        }
        this.configuration = new HadoopConfiguration(configuration);
        this.resources = Collections.emptyList();
    }

    /**
     * Initializes the managed resources.
     * @throws IOException if failed to initialize resources
     * @throws InterruptedException if interrupted while initializing resources
     * @throws IllegalArgumentException if the configuration is something wrong
     * @throws IllegalStateException if the current lifecycle is something wrong
     */
    public void setup() throws IOException, InterruptedException {
        if (LOG.isDebugEnabled()) {
            LOG.debug("Loading runtime plugins"); //$NON-NLS-1$
        }
        List<? extends RuntimeResource> loaded = load();
        this.resources = new ArrayList<>();
        for (RuntimeResource resource : loaded) {
            if (LOG.isDebugEnabled()) {
                LOG.debug(MessageFormat.format("Activating runtime plugin: {0}", //$NON-NLS-1$
                        resource.getClass().getName()));
            }
            resource.setup(configuration);
            resources.add(resource);
        }
        if (LOG.isDebugEnabled()) {
            LOG.debug(MessageFormat.format("Loaded {0} runtime plugins", //$NON-NLS-1$
                    resources.size()));
        }
    }

    /**
     * Finalizes and releases the managed resources.
     * @throws IOException if failed to finalize resources
     * @throws InterruptedException if interrupted while initializing resources
     * @throws IllegalArgumentException if the configuration is something wrong
     * @throws IllegalStateException if the current lifecycle is something wrong
     */
    public void cleanup() throws IOException, InterruptedException {
        int count = resources.size();
        if (LOG.isDebugEnabled()) {
            LOG.debug(MessageFormat.format("Unloading {0} runtime plugins", //$NON-NLS-1$
                    count));
        }
        try {
            for (RuntimeResource resource : resources) {
                if (LOG.isDebugEnabled()) {
                    LOG.debug(MessageFormat.format("Deactivating runtime plugin: {0}", //$NON-NLS-1$
                            resource.getClass().getName()));
                }
                resource.cleanup(configuration);
            }
        } finally {
            this.resources = Collections.emptyList();
        }
        if (LOG.isDebugEnabled()) {
            LOG.debug(MessageFormat.format("Unloaded {0} runtime plugins", //$NON-NLS-1$
                    count));
        }
    }

    /**
     * Loads the available resources.
     * In this implementation, the method collects service information from
     * {@code META-INF/services/com.asakusafw.runtime.core.RuntimeResource}
     * and creates {@link RuntimeResource} implementations on them via SPI.
     * @return the loaded resources
     * @throws IOException if failed to load the resources
     */
    protected List<RuntimeResource> load() throws IOException {
        List<RuntimeResource> results = new ArrayList<>();
        ClassLoader loader = configuration.getClassLoader();
        try {
            for (RuntimeResource resource : ServiceLoader.load(RuntimeResource.class, loader)) {
                if (resource instanceof Configurable) {
                    ((Configurable) resource).setConf(configuration.getConf());
                }
                results.add(resource);
            }
        } catch (RuntimeException e) {
            throw new IOException(
                    MessageFormat.format("Failed to load resources ({0})", RuntimeResource.class.getName()), e);
        }
        return results;
    }
}