@@ -0,0 +1,2931 @@
+/*%0A * Copyright 2017-present Open Networking Foundation%0A *%0A * Licensed under the Apache License, Version 2.0 (the %22License%22);%0A * you may not use this file except in compliance with the License.%0A * You may obtain a copy of the License at%0A *%0A *     http://www.apache.org/licenses/LICENSE-2.0%0A *%0A * Unless required by applicable law or agreed to in writing, software%0A * distributed under the License is distributed on an %22AS IS%22 BASIS,%0A * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.%0A * See the License for the specific language governing permissions and%0A * limitations under the License.%0A */%0Apackage io.atomix.primitives.impl;%0A%0Aimport com.google.common.collect.ImmutableSet;%0Aimport com.google.common.collect.Sets;%0Aimport io.atomix.primitives.DistributedPrimitive;%0Aimport io.atomix.protocols.raft.proxy.RaftProxy;%0A%0Aimport java.util.Collection;%0Aimport java.util.Set;%0Aimport java.util.function.Consumer;%0Aimport java.util.function.Function;%0A%0Aimport static com.google.common.base.MoreObjects.toStringHelper;%0Aimport static com.google.common.base.Preconditions.checkNotNull;%0A%0A/**%0A * Abstract base class for primitives that interact with Raft replicated state machines via proxy.%0A */%0Apublic abstract class AbstractRaftPrimitive implements DistributedPrimitive %7B%0A    private final Function%3CRaftProxy.State, Status%3E mapper = state -%3E %7B%0A        switch (state) %7B%0A            case CONNECTED:%0A                return Status.ACTIVE;%0A            case SUSPENDED:%0A                return Status.SUSPENDED;%0A            case CLOSED:%0A                return Status.INACTIVE;%0A            default:%0A                throw new IllegalStateException(%22Unknown state %22 + state);%0A        %7D%0A    %7D;%0A%0A    protected final RaftProxy proxy;%0A    private final Set%3CConsumer%3CStatus%3E%3E statusChangeListeners = Sets.newCopyOnWriteArraySet();%0A%0A    public AbstractRaftPrimitive(RaftProxy proxy) %7B%0A        this.proxy = checkNotNull(proxy, %22proxy cannot be null%22);%0A        proxy.addStateChangeListener(this::onStateChange);%0A    %7D%0A%0A    @Override%0A    public String name() %7B%0A        return proxy.name();%0A    %7D%0A%0A    /**%0A     * Handles a Raft session state change.%0A     *%0A     * @param state the updated Raft session state%0A     */%0A    private void onStateChange(RaftProxy.State state) %7B%0A        statusChangeListeners.forEach(listener -%3E listener.accept(mapper.apply(state)));%0A    %7D%0A%0A    @Override%0A    public void addStatusChangeListener(Consumer%3CStatus%3E listener) %7B%0A        statusChangeListeners.add(listener);%0A    %7D%0A%0A    @Override%0A    public void removeStatusChangeListener(Consumer%3CStatus%3E listener) %7B%0A        statusChangeListeners.remove(listener);%0A    %7D%0A%0A    @Override%0A    public Collection%3CConsumer%3CStatus%3E%3E statusChangeListeners() %7B%0A        return ImmutableSet.copyOf(statusChangeListeners);%0A    %7D%0A%0A    @Override%0A    public String toString() %7B%0A        return toStringHelper(this)%0A                .add(%22proxy%22, proxy)%0A                .toString();%0A    %7D%0A%7D

Add abstract base class for Raft primitives.