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.core;
019
020 import javax.annotation.Nonnull;
021 import javax.annotation.Nullable;
022
023 import static griffon.util.GriffonNameUtils.requireNonBlank;
024 import static java.util.Objects.requireNonNull;
025
026 /**
027 * @author Andres Almiray
028 * @since 2.5.0
029 */
030 public interface ObservableContext extends Context {
031 void addContextEventListener(@Nonnull ContextEventListener listener);
032
033 void removeContextEventListener(@Nonnull ContextEventListener listener);
034
035 @Nonnull
036 ContextEventListener[] getContextEventListeners();
037
038 interface ContextEventListener {
039 void contextChanged(@Nonnull ContextEvent contextEvent);
040 }
041
042 class ContextEvent {
043 private final Type type;
044 private final String key;
045 private final Object oldValue;
046 private final Object newValue;
047
048 public ContextEvent(@Nonnull Type type, @Nonnull String key, @Nullable Object oldValue, @Nullable Object newValue) {
049 this.type = requireNonNull(type, "Argument 'type' must not be null");
050 this.key = requireNonBlank(key, "Argument 'key' must not be null");
051 this.oldValue = oldValue;
052 this.newValue = newValue;
053 }
054
055 @Nonnull
056 public Type getType() {
057 return type;
058 }
059
060 @Nonnull
061 public String getKey() {
062 return key;
063 }
064
065 @Nullable
066 public Object getOldValue() {
067 return oldValue;
068 }
069
070 @Nullable
071 public Object getNewValue() {
072 return newValue;
073 }
074
075 @Override
076 public boolean equals(Object o) {
077 if (this == o) return true;
078 if (o == null || getClass() != o.getClass()) return false;
079
080 ContextEvent that = (ContextEvent) o;
081
082 if (!key.equals(that.key)) return false;
083 if (newValue != null ? !newValue.equals(that.newValue) : that.newValue != null) return false;
084 if (oldValue != null ? !oldValue.equals(that.oldValue) : that.oldValue != null) return false;
085 if (type != that.type) return false;
086
087 return true;
088 }
089
090 @Override
091 public int hashCode() {
092 int result = type.hashCode();
093 result = 31 * result + key.hashCode();
094 result = 31 * result + (oldValue != null ? oldValue.hashCode() : 0);
095 result = 31 * result + (newValue != null ? newValue.hashCode() : 0);
096 return result;
097 }
098
099 @Override
100 public String toString() {
101 final StringBuilder sb = new StringBuilder("ContextEvent{");
102 sb.append("type=").append(type);
103 sb.append(", key='").append(key).append('\'');
104 sb.append(", oldValue=").append(oldValue);
105 sb.append(", newValue=").append(newValue);
106 sb.append('}');
107 return sb.toString();
108 }
109
110 public enum Type {
111 ADD, REMOVE, UPDATE
112 }
113 }
114 }
|