AbstractResetableProperty.java
001 /*
002  * SPDX-License-Identifier: Apache-2.0
003  *
004  * Copyright 2008-2017 the original author or authors.
005  *
006  * Licensed under the Apache License, Version 2.0 (the "License");
007  * you may not use this file except in compliance with the License.
008  * You may obtain a copy of the License at
009  *
010  *     http://www.apache.org/licenses/LICENSE-2.0
011  *
012  * Unless required by applicable law or agreed to in writing, software
013  * distributed under the License is distributed on an "AS IS" BASIS,
014  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015  * See the License for the specific language governing permissions and
016  * limitations under the License.
017  */
018 package griffon.javafx.beans.property;
019 
020 import javafx.beans.binding.Bindings;
021 import javafx.beans.binding.BooleanBinding;
022 import javafx.beans.property.Property;
023 
024 import javax.annotation.Nonnull;
025 import javax.annotation.Nullable;
026 import java.util.Objects;
027 
028 import static griffon.util.GriffonNameUtils.isBlank;
029 
030 /**
031  @author Andres Almiray
032  @since 2.10.0
033  */
034 public abstract class AbstractResetableProperty<T> implements ResetableProperty<T> {
035     private static final Object DEFAULT_BEAN = null;
036     private static final String DEFAULT_NAME = "";
037 
038     private final Object bean;
039     private final String name;
040     protected final BooleanBinding dirty;
041 
042     /**
043      * The constructor of {@code AbstractResetableProperty}
044      */
045     public AbstractResetableProperty() {
046         this(DEFAULT_BEAN, DEFAULT_NAME, null);
047     }
048 
049     /**
050      * The constructor of {@code AbstractResetableProperty}
051      *
052      @param baseValue the base value  of this {@code AbstractResetableProperty}
053      */
054     public AbstractResetableProperty(@Nullable T baseValue) {
055         this(DEFAULT_BEAN, DEFAULT_NAME, baseValue);
056     }
057 
058     /**
059      * The constructor of {@code AbstractResetableProperty}
060      *
061      @param bean the bean of this {@code AbstractResetableProperty}
062      @param name the name of this {@code AbstractResetableProperty}
063      */
064     public AbstractResetableProperty(@Nullable Object bean, @Nonnull String name) {
065         this(bean, name, null);
066     }
067 
068     /**
069      * The constructor of {@code AbstractResetableProperty}
070      *
071      @param bean      the bean of this {@code AbstractResetableProperty}
072      @param name      the name of this {@code AbstractResetableProperty}
073      @param baseValue the base value  of this {@code AbstractResetableProperty}
074      */
075     public AbstractResetableProperty(@Nullable Object bean, @Nonnull String name, @Nullable T baseValue) {
076         this.bean = bean;
077         this.name = isBlank(name? DEFAULT_NAME : name;
078 
079         writableBaseValueProperty().setValue(baseValue);
080         setValue(baseValue);
081 
082         dirty = createDirtyBinding();
083     }
084 
085     @Nonnull
086     protected BooleanBinding createDirtyBinding() {
087         return Bindings.createBooleanBinding(this::checkValuesAreNotEqual, baseValueProperty(), valueProperty());
088     }
089 
090     protected boolean checkValuesAreNotEqual() {
091         return !Objects.equals(getBaseValue(), getValue());
092     }
093 
094     @Nonnull
095     protected abstract Property<T> writableBaseValueProperty();
096 
097     @Nonnull
098     @Override
099     public BooleanBinding dirtyProperty() {
100         return dirty;
101     }
102 
103     @Override
104     @Nullable
105     public T getBaseValue() {
106         return baseValueProperty().getValue();
107     }
108 
109     @Override
110     @Nullable
111     public T getValue() {
112         return valueProperty().getValue();
113     }
114 
115     @Nonnull
116     @Override
117     public ResetableProperty<T> setValue(@Nullable T value) {
118         valueProperty().setValue(value);
119         return this;
120     }
121 
122     @Override
123     public boolean isDirty() {
124         return dirty.get();
125     }
126 
127     @Nonnull
128     @Override
129     public ResetableProperty<T> rebase() {
130         writableBaseValueProperty().setValue(getValue());
131         return this;
132     }
133 
134     @Nonnull
135     @Override
136     public ResetableProperty<T> reset() {
137         setValue(getBaseValue());
138         return this;
139     }
140 
141     @Nullable
142     @Override
143     public Object getBean() {
144         return bean;
145     }
146 
147     @Nonnull
148     @Override
149     public String getName() {
150         return name;
151     }
152 }