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