com.uber.hoodie.common.util.DFSPropertiesConfiguration.java Source code

Java tutorial

Introduction

Here is the source code for com.uber.hoodie.common.util.DFSPropertiesConfiguration.java

Source

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF 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 com.uber.hoodie.common.util;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashSet;
import java.util.Set;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;

/**
 * A simplified versions of Apache commons - PropertiesConfiguration, that supports limited field types and hierarchical
 * configurations within the same folder as the root file.
 *
 * Includes denoted by the same include=filename.properties syntax, with relative path from root file's folder. Lines
 * beginning with '#' are ignored as comments. Final values for properties are resolved by the order in which they are
 * specified in the files, with included files treated as if they are inline.
 *
 * Note: Not reusing commons-configuration since it has too many conflicting runtime deps.
 */
public class DFSPropertiesConfiguration {

    private static volatile Logger log = LogManager.getLogger(DFSPropertiesConfiguration.class);

    private final FileSystem fs;

    private final Path rootFile;

    private final TypedProperties props;

    // Keep track of files visited, to detect loops
    private final Set<String> visitedFiles;

    public DFSPropertiesConfiguration(FileSystem fs, Path rootFile, TypedProperties defaults) {
        this.fs = fs;
        this.rootFile = rootFile;
        this.props = defaults;
        this.visitedFiles = new HashSet<>();
        visitFile(rootFile);
    }

    private String[] splitProperty(String line) {
        int ind = line.indexOf('=');
        String k = line.substring(0, ind).trim();
        String v = line.substring(ind + 1).trim();
        return new String[] { k, v };
    }

    private void visitFile(Path file) {
        try {
            if (visitedFiles.contains(file.getName())) {
                throw new IllegalStateException("Loop detected; file " + file + " already referenced");
            }
            visitedFiles.add(file.getName());
            BufferedReader reader = new BufferedReader(new InputStreamReader(fs.open(file)));
            addProperties(reader);
        } catch (IOException ioe) {
            log.error("Error reading in properies from dfs", ioe);
            throw new IllegalArgumentException("Cannot read properties from dfs", ioe);
        }
    }

    /**
     * Add properties from input stream
     * @param reader Buffered Reader
     * @throws IOException
     */
    public void addProperties(BufferedReader reader) throws IOException {
        try {
            String line;
            while ((line = reader.readLine()) != null) {
                if (line.startsWith("#") || line.equals("") || !line.contains("=")) {
                    continue;
                }
                String[] split = splitProperty(line);
                if (line.startsWith("include=") || line.startsWith("include =")) {
                    visitFile(new Path(rootFile.getParent(), split[1]));
                } else {
                    props.setProperty(split[0], split[1]);
                }
            }
        } finally {
            reader.close();
        }
    }

    public DFSPropertiesConfiguration(FileSystem fs, Path rootFile) {
        this(fs, rootFile, new TypedProperties());
    }

    public TypedProperties getConfig() {
        return props;
    }
}