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