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

org.neo4j.configuration.SettingImpl Maven / Gradle / Ivy

There is a newer version: 5.23.0
Show newest version
/*
 * Copyright (c) "Neo4j"
 * Neo4j Sweden AB [http://neo4j.com]
 *
 * This file is part of Neo4j.
 *
 * Neo4j is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see .
 */
package org.neo4j.configuration;

import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

import org.neo4j.annotations.api.IgnoreApiCheck;
import org.neo4j.graphdb.config.Configuration;
import org.neo4j.graphdb.config.Setting;
import org.neo4j.internal.helpers.Exceptions;

import static java.lang.String.format;

@IgnoreApiCheck
public final class SettingImpl implements Setting
{
    private final String name;
    private final String suffix;
    private final SettingImpl dependency;
    private final SettingValueParser parser;
    private final T defaultValue;
    private final List> constraints;
    private final boolean dynamic;
    private final boolean immutable;
    private boolean internal;
    private String description;
    private boolean deprecated;
    private String documentedDefaultValue;

    private SettingImpl( String name,
            SettingValueParser parser,
            T defaultValue,
            List> constraints,
            boolean dynamic,
            boolean immutable,
            SettingImpl dependency )
    {
        this.name = name;
        this.parser = parser;
        this.dependency = dependency;
        this.constraints = constraints;
        this.defaultValue = defaultValue;
        this.dynamic = dynamic;
        this.immutable = immutable;
        this.internal = name != null && name.contains( "unsupported." );
        this.suffix = StringUtils.isNotEmpty( name ) ? name.substring( name.lastIndexOf( '.' ) + 1 ) : name;
    }

    public static  Builder newBuilder( String name, SettingValueParser parser, T defaultValue )
    {
        return new Builder<>( name, parser, defaultValue );
    }

    @Override
    public T defaultValue()
    {
        return defaultValue;
    }

    public T parse( String value )
    {
        if ( value == null )
        {
           return null;
        }

        return parser.parse( value );
    }

    public String valueToString( T value )
    {
        if ( value != null )
        {
            return parser.valueToString( value );
        }
        return "No Value";
    }

    T solveDefault( T value, T defaultValue )
    {
        return parser.solveDefault(value, defaultValue);
    }

    T solveDependency( T value, T dependencyValue )
    {
        return parser.solveDependency( value, dependencyValue );
    }

    public void validate( T value, Configuration config )
    {
        if ( value != null )
        {
            if ( !parser.getType().isAssignableFrom( value.getClass() ) ) //Does only check outer class if generic types.
            {
                throw new IllegalArgumentException( format( "Setting '%s' can not have value '%s'. Should be of type '%s', but is '%s'",
                                name, value, parser.getType().getSimpleName(), value.getClass().getSimpleName() ) );
            }
            try
            {
                parser.validate( value );
                for ( SettingConstraint constraint : constraints )
                {
                    constraint.validate( value, config );
                }
            }
            catch ( IllegalArgumentException e )
            {
                throw Exceptions.withMessage( e, format( "Failed to validate '%s' for '%s': %s", value, name(), e.getMessage() ) );
            }

        }
    }

    @Override
    public String toString()
    {
        String desc = format( "%s, %s", name, parser.getDescription() );

        if ( !constraints.isEmpty() )
        {
            String constraintDesc = constraints.stream().map( SettingConstraint::getDescription ).collect( Collectors.joining( " and " ) );
            desc = format( "%s which %s", desc, constraintDesc );
        }

        if ( dependency != null )
        {
            desc = format( "%s. %s from %s", desc, parser.getSolverDescription(), dependency.name() );
        }

        return desc;
    }

    SettingImpl dependency()
    {
        return dependency;
    }

    @Override
    public String description()
    {
        return description != null ? description : toString();
    }

    @Override
    public boolean equals( Object o )
    {
        if ( this == o )
        {
            return true;
        }
        if ( o == null || getClass() != o.getClass() )
        {
            return false;
        }
        SettingImpl setting = (SettingImpl) o;
        return name.equals( setting.name );
    }

    @Override
    public int hashCode()
    {
        return Objects.hash( name );
    }

    @Override
    public String name()
    {
        return name;
    }

    public String suffix()
    {
        return suffix;
    }

    @Override
    public boolean dynamic()
    {
        return dynamic;
    }

    public boolean immutable()
    {
        return immutable;
    }

    @Override
    public boolean internal()
    {
        return internal;
    }

    public boolean deprecated()
    {
        return deprecated;
    }

    public String documentedDefaultValue()
    {
        return documentedDefaultValue;
    }

    void setDescription( String description )
    {
        this.description = description;
    }

    void setInternal()
    {
        internal = true;
    }

    void setDeprecated()
    {
        deprecated = true;
    }

    void setDocumentedDefaultValue( String documentedDefaultValue )
    {
        this.documentedDefaultValue = documentedDefaultValue;
    }

    SettingValueParser parser()
    {
        return parser;
    }

    public static class Builder
    {
        private final String name;
        private final SettingValueParser parser;
        private final List> constraints = new ArrayList<>();
        private final T defaultValue;
        private boolean dynamic;
        private boolean immutable;
        private SettingImpl dependency;

        private Builder( String name, SettingValueParser parser, T defaultValue )
        {
            this.name = name;
            this.parser = parser;
            this.defaultValue = defaultValue;
        }

        public Builder dynamic()
        {
            this.dynamic = true;
            return this;
        }

        public Builder immutable()
        {
            this.immutable = true;
            return this;
        }

        public Builder addConstraint( SettingConstraint constraint )
        {
            constraint.setParser( parser );
            constraints.add( constraint );
            return this;
        }

        public Builder setDependency( Setting setting )
        {
            dependency = (SettingImpl) setting;
            return this;
        }

        public Setting build()
        {
            if ( immutable && dynamic )
            {
                throw new IllegalArgumentException( "Setting can not be both dynamic and immutable" );
            }
            if ( dependency != null && !dependency.immutable() )
            {
                throw new IllegalArgumentException( "Setting can only have immutable dependency" );
            }

            return new SettingImpl<>( name, parser, defaultValue, constraints, dynamic, immutable, dependency );
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy