io.fabric8.profiles.Profiles.java Source code

Java tutorial

Introduction

Here is the source code for io.fabric8.profiles.Profiles.java

Source

/**
 *  Copyright 2005-2016 Red Hat, Inc.
 *
 *  Red Hat licenses this file to you 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 io.fabric8.profiles;

import com.fasterxml.jackson.databind.JsonNode;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Properties;

import static io.fabric8.profiles.ProfilesHelpers.readJsonFile;
import static io.fabric8.profiles.ProfilesHelpers.readPropertiesFile;
import static io.fabric8.profiles.ProfilesHelpers.readYamlFile;
import static io.fabric8.profiles.ProfilesHelpers.recusivelyCollectFileListing;
import static io.fabric8.profiles.ProfilesHelpers.toBytes;
import static io.fabric8.profiles.ProfilesHelpers.toJsonBytes;
import static io.fabric8.profiles.ProfilesHelpers.toYamlBytes;

public class Profiles {

    private final Path repository;

    /**
     * @param repository directory should be a repository containing profile configurations.
     */
    public Profiles(Path repository) {
        this.repository = repository;
    }

    /**
     * @param target       is the directory where resulting materialized profile configuration will be written to.
     * @param profileNames a list of profile names that will be combined to create the materialized profile.
     */
    public void materialize(Path target, String... profileNames) throws IOException {
        ArrayList<String> profileSearchOrder = new ArrayList<>();
        for (String profileName : profileNames) {
            collectProfileNames(profileSearchOrder, profileName);
        }

        HashSet<String> files = new HashSet<>();
        for (String profileName : profileSearchOrder) {
            files.addAll(listFiles(profileName));
        }

        System.out.println("profile search order" + profileSearchOrder);
        System.out.println("files: " + files);
        for (String file : files) {
            try (InputStream is = materializeFile(file, profileSearchOrder)) {
                Files.copy(is, target.resolve(file), StandardCopyOption.REPLACE_EXISTING);
            }
        }

    }

    private InputStream materializeFile(String fileName, ArrayList<String> profileSearchOrder) throws IOException {
        if (fileName.endsWith(".properties")) {

            // later property files in the profile overwrite values
            // in previous properties.
            Properties properties = new Properties();
            for (String profile : profileSearchOrder) {
                Path path = getProfilePath(profile).resolve(fileName);
                if (Files.exists(path)) {
                    ProfilesHelpers.merge(properties, readPropertiesFile(path));
                }
            }
            return new ByteArrayInputStream(toBytes(properties));
        } else if (fileName.endsWith(".json")) {
            JsonNode node = null;
            for (String profile : profileSearchOrder) {
                Path path = getProfilePath(profile).resolve(fileName);
                if (Files.exists(path)) {
                    node = ProfilesHelpers.merge(node, readJsonFile(path));
                }
            }
            return new ByteArrayInputStream(toJsonBytes(node));
        } else if (fileName.endsWith(".yml")) {
            JsonNode node = null;
            for (String profile : profileSearchOrder) {
                Path path = getProfilePath(profile).resolve(fileName);
                if (Files.exists(path)) {
                    node = ProfilesHelpers.merge(node, readYamlFile(path));
                }
            }
            return new ByteArrayInputStream(toYamlBytes(node));
        } else {
            // Last profile in list wins, since we cant merge these types of files.
            Path last = null;
            for (String profile : profileSearchOrder) {
                Path path = getProfilePath(profile).resolve(fileName);
                if (Files.exists(path)) {
                    last = path;
                }
            }
            return Files.newInputStream(last);
        }
    }

    private ArrayList<String> listFiles(String profileName) throws IOException {
        ArrayList<String> rc = new ArrayList<>();
        Path dir = getProfilePath(profileName);
        recusivelyCollectFileListing(rc, dir, dir);
        return rc;
    }

    private void collectProfileNames(ArrayList<String> target, String profileName) throws IOException {
        if (target.contains(profileName)) {
            return;
        }

        Path path = getProfilePath(profileName);
        if (!Files.exists(path)) {
            throw new IOException("Profile directory does not exists: " + path);
        }
        Properties props = new Properties();
        Path agentProperties = path.resolve("io.fabric8.agent.properties");
        if (Files.exists(agentProperties)) {
            props = readPropertiesFile(agentProperties);
        }

        String parents = props.getProperty("attribute.parents", "default".equals(profileName) ? "" : "default");
        for (String parent : parents.split(",")) {
            parent = parent.trim();
            if (!parent.isEmpty()) {
                collectProfileNames(target, parent);
            }
        }

        target.add(profileName);
    }

    private Path getProfilePath(String profileName) {
        return repository.resolve(profileName.replaceAll("-", "/") + ".profile");
    }

}