Package org.netbeans.gradle.project.validate

Source Code of org.netbeans.gradle.project.validate.BackgroundValidator$MostSevereValidator

package org.netbeans.gradle.project.validate;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import org.jtrim.collections.Equality;
import org.jtrim.collections.RefLinkedList;
import org.jtrim.collections.RefList;
import org.jtrim.concurrent.GenericUpdateTaskExecutor;
import org.jtrim.concurrent.MonitorableTaskExecutorService;
import org.jtrim.concurrent.TaskExecutor;
import org.jtrim.concurrent.UpdateTaskExecutor;
import org.jtrim.event.EventDispatcher;
import org.jtrim.event.ListenerRef;
import org.jtrim.event.ListenerRegistries;
import org.jtrim.property.MutableProperty;
import org.jtrim.property.PropertyFactory;
import org.jtrim.property.PropertySource;
import org.jtrim.property.ValueConverter;
import org.jtrim.property.swing.SwingProperties;
import org.jtrim.property.swing.SwingPropertySource;
import org.jtrim.swing.concurrent.SwingTaskExecutor;
import org.jtrim.utils.ExceptionHelper;
import org.netbeans.gradle.project.NbTaskExecutors;

import static org.jtrim.property.PropertyFactory.*;

public final class BackgroundValidator {
    private static final MonitorableTaskExecutorService VALIDATOR_PROCESSOR
            = NbTaskExecutors.newExecutor("Gradle-NewProject-Validator-Processor", 1);

    private final UpdateTaskExecutor validationExecutor;

    private final MutableProperty<Problem> currentProblem;
    private final SwingPropertySource<Problem, ChangeListener> currentProblemForSwing;
    private final PropertySource<Boolean> valid;

    private final MostSevereValidator validator;

    public BackgroundValidator() {
        this.validationExecutor = new GenericUpdateTaskExecutor(VALIDATOR_PROCESSOR);
        this.validator = new MostSevereValidator();

        this.currentProblem = lazilySetProperty(memProperty((Problem)null, true), Equality.<Problem>referenceEquality());
        this.currentProblemForSwing = SwingProperties.toSwingSource(currentProblem, new EventDispatcher<ChangeListener, Void>() {
            @Override
            public void onEvent(ChangeListener eventListener, Void arg) {
                eventListener.stateChanged(new ChangeEvent(BackgroundValidator.this));
            }
        });
        this.valid = PropertyFactory.convert(currentProblem, new ValueConverter<Problem, Boolean>() {
            @Override
            public Boolean convert(Problem input) {
                return input == null || input.getLevel() != Problem.Level.SEVERE;
            }
        });
    }

    public <InputType> ListenerRef addValidator(
            Validator<InputType> validator,
            PropertySource<? extends InputType> input) {

        return addValidator(validator, input, SwingTaskExecutor.getStrictExecutor(true));
    }

    public <InputType> ListenerRef addValidator(
            final Validator<InputType> validator,
            final PropertySource<? extends InputType> input,
            final TaskExecutor inputReaderExecutor) {

        ExceptionHelper.checkNotNullArgument(validator, "validator");
        ExceptionHelper.checkNotNullArgument(input, "input");
        ExceptionHelper.checkNotNullArgument(inputReaderExecutor, "inputReaderExecutor");

        final UpdateTaskExecutor updateReader = new GenericUpdateTaskExecutor(inputReaderExecutor);

        final AtomicReference<InputType> valueRef = new AtomicReference<>(input.getValue());
        final Runnable updateValueTask = new Runnable() {
            @Override
            public void run() {
                valueRef.set(input.getValue());
                performValidation();
            }
        };

        ListenerRef ref1 = input.addChangeListener(new Runnable() {
            @Override
            public void run() {
                updateReader.execute(updateValueTask);
            }
        });
        ListenerRef ref2 = this.validator.addValidator(new Validator<Void>() {
            @Override
            public Problem validateInput(Void inputType) {
                return validator.validateInput(valueRef.get());
            }
        });

        performValidation();

        final ListenerRef result = ListenerRegistries.combineListenerRefs(ref1, ref2);
        return new ListenerRef() {
            @Override
            public boolean isRegistered() {
                return result.isRegistered();
            }

            @Override
            public void unregister() {
                result.unregister();
                performValidation();
            }
        };
    }

    public PropertySource<Problem> currentProblem() {
        return currentProblem;
    }

    public SwingPropertySource<Problem, ChangeListener> currentProblemForSwing() {
        return currentProblemForSwing;
    }

    private void performValidation() {
        validationExecutor.execute(new Runnable() {
            @Override
            public void run() {
                Problem problem = validator.validateInput(null);
                currentProblem.setValue(problem);
            }
        });
    }

    public PropertySource<Boolean> valid() {
        return valid;
    }

    public boolean isValid() {
        return valid.getValue();
    }

    private static class MostSevereValidator implements Validator<Void> {
        private final Lock validatorsLock;
        private final RefList<Validator<Void>> validators;

        public MostSevereValidator() {
            this.validatorsLock = new ReentrantLock();
            this.validators = new RefLinkedList<>();
        }

        public ListenerRef addValidator(Validator<Void> validator) {
            final RefList.ElementRef<Validator<Void>> elementRef;

            validatorsLock.lock();
            try {
                elementRef = validators.addLastGetReference(validator);
            } finally {
                validatorsLock.unlock();
            }

            return new ListenerRef() {
                @Override
                public boolean isRegistered() {
                    validatorsLock.lock();
                    try {
                        return !elementRef.isRemoved();
                    } finally {
                        validatorsLock.unlock();
                    }
                }

                @Override
                public void unregister() {
                    validatorsLock.lock();
                    try {
                        elementRef.remove();
                    } finally {
                        validatorsLock.unlock();
                    }
                }
            };
        }

        public List<Validator<Void>> getValidators() {
            validatorsLock.lock();
            try {
                return new ArrayList<>(validators);
            } finally {
                validatorsLock.unlock();
            }
        }

        @Override
        public Problem validateInput(Void inputType) {
            Problem mostSevere = null;
            for (Validator<Void> current: getValidators()) {
                Problem currentProblem = current.validateInput(null);
                if (currentProblem != null) {
                    if (currentProblem.getLevel() == Problem.Level.SEVERE) {
                        return currentProblem;
                    }

                    if (mostSevere == null) {
                        mostSevere = currentProblem;
                    }
                    else if (mostSevere.getLevel().getIntValue() < currentProblem.getLevel().getIntValue()) {
                        mostSevere = currentProblem;
                    }
                }
            }
            return mostSevere;
        }
    }
}
TOP

Related Classes of org.netbeans.gradle.project.validate.BackgroundValidator$MostSevereValidator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.