All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.speedment.tool.config.internal.component.DocumentPropertyComponentImpl Maven / Gradle / Ivy

Go to download

A Speedment bundle that shades all dependencies into one jar. This is useful when deploying an application on a server.

The newest version!
/*
 *
 * Copyright (c) 2006-2019, Speedment, Inc. All Rights Reserved.
 *
 * 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.speedment.tool.config.internal.component;

import com.speedment.runtime.config.*;
import com.speedment.runtime.core.internal.util.ImmutableListUtil;
import com.speedment.tool.config.*;
import com.speedment.tool.config.component.DocumentPropertyComponent;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import static java.util.Collections.emptyList;
import static java.util.Objects.requireNonNull;

/**
 *
 * @author Emil Forslund
 */
public final class DocumentPropertyComponentImpl implements DocumentPropertyComponent {

    private final Branch root;

    private final static Constructor DEFAULT_CONSTRUCTOR = parent -> {
        final AbstractDocumentProperty castedParent
            = (AbstractDocumentProperty) parent;
        return new DefaultDocumentProperty(castedParent, null);
    };

    public DocumentPropertyComponentImpl() {
        root = new Branch(DEFAULT_CONSTRUCTOR);

        root.find(emptyList()).set(parent -> new ProjectProperty());
        root.find(DBMSES).set(parent -> new DbmsProperty((Project) parent));
        root.find(SCHEMAS).set(parent -> new SchemaProperty((Dbms) parent));
        root.find(TABLES).set(parent -> new TableProperty((Schema) parent));
        root.find(COLUMNS).set(parent -> new ColumnProperty((Table) parent));
        root.find(PRIMARY_KEY_COLUMNS).set(parent -> new PrimaryKeyColumnProperty((Table) parent));
        root.find(INDEXES).set(parent -> new IndexProperty((Table) parent));
        root.find(INDEX_COLUMNS).set(parent -> new IndexColumnProperty((Index) parent));
        root.find(FOREIGN_KEYS).set(parent -> new ForeignKeyProperty((Table) parent));
        root.find(FOREIGN_KEY_COLUMNS).set(parent -> new ForeignKeyColumnProperty((ForeignKey) parent));
    }
    
    @Override
    public  void setConstructor(Constructor constructor, List keyPath) {
        root.find(keyPath).set(constructor);
    }

    @Override
    @SuppressWarnings("unchecked")
    public  Constructor getConstructor(List keyPath) {
        return (Constructor) root.find(keyPath).get();
    }

    private final static class Branch {

        private final ConstructorHolder holder;
        private final Map children;

        private Branch(Constructor constructor) {
            this.holder = new ConstructorHolder(constructor);
            this.children = new ConcurrentHashMap<>();
        }

        public ConstructorHolder find(List keyPath) {
            return find(0, keyPath);
        }

        private ConstructorHolder find(int i, List keyPath) {
            // If we are at the last key, return our constructor.
            if (i == keyPath.size()) {
                return holder;

                // If there are still keys in the path, find the one mentioned in
                // the i:th key and recurse into that branch
            } else if (i < keyPath.size()) {
                return children.computeIfAbsent(
                    keyPath.get(i), k -> new Branch(parent -> {
                    final AbstractDocumentProperty castedParent
                        = (AbstractDocumentProperty) parent;
                    return new DefaultDocumentProperty(castedParent, k);
                })
                ).find(i + 1, keyPath);

                // If we are out of keys, something is terrible wrong...
            } else {
                throw new UnsupportedOperationException(
                    "iterator is outside the specified keyPath."
                );
            }
        }

        @Override
        public String toString() {
            return children.toString();
        }
    }

    private final static class ConstructorHolder {

        private Constructor constructor;

        private ConstructorHolder(Constructor constructor) {
            this.constructor = requireNonNull(constructor);
        }

        public  void set(Constructor constructor) {
            this.constructor = requireNonNull(constructor);
        }

        public Constructor get() {
            return constructor;
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy