001/*
002 * JGrapes Event Driven Framework
003 * Copyright (C) 2017-2018 Michael N. Lipp
004 * 
005 * This program is free software; you can redistribute it and/or modify it 
006 * under the terms of the GNU Affero General Public License as published by 
007 * the Free Software Foundation; either version 3 of the License, or 
008 * (at your option) any later version.
009 * 
010 * This program is distributed in the hope that it will be useful, but 
011 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
012 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License 
013 * for more details.
014 * 
015 * You should have received a copy of the GNU Affero General Public License along 
016 * with this program; if not, see <http://www.gnu.org/licenses/>.
017 */
018
019package org.jgrapes.util.events;
020
021import java.util.ArrayList;
022import java.util.Collections;
023import java.util.List;
024import org.jgrapes.core.Event;
025
026/**
027 * An event that triggers updates or deletions in a key/value store.
028 */
029public class KeyValueStoreUpdate extends Event<Void> {
030
031    private final List<Action> actions = new ArrayList<>();
032
033    /**
034     * Adds a new update action to the event.
035     * 
036     * @param key the key
037     * @param value the value
038     * @return the event for easy chaining
039     */
040    public KeyValueStoreUpdate update(String key, String value) {
041        actions.add(new Update(key, value));
042        return this;
043    }
044
045    /**
046     * Adds a new update action to the event that stores the given value
047     * on the path formed by the path segments.
048     * 
049     * @param value the value
050     * @param segments the path segments
051     * @return the event for easy chaining
052     */
053    public KeyValueStoreUpdate storeAs(String value, String... segments) {
054        actions.add(new Update("/" + String.join("/", segments), value));
055        return this;
056    }
057
058    /**
059     * Adds a new deletion action to the event.
060     * 
061     * @param key the key
062     * @return the event for easy chaining
063     */
064    public KeyValueStoreUpdate delete(String key) {
065        actions.add(new Deletion(key));
066        return this;
067    }
068
069    /**
070     * Adds a new deletion action that clears all keys with the given
071     * path prefix.
072     * 
073     * @param segments the path segments
074     * @return the event for easy chaining
075     */
076    public KeyValueStoreUpdate clearAll(String... segments) {
077        actions.add(new Deletion("/" + String.join("/", segments)));
078        return this;
079    }
080
081    /**
082     * Returns the actions.
083     * 
084     * @return the actions
085     */
086    public List<Action> actions() {
087        return Collections.unmodifiableList(actions);
088    }
089
090    /**
091     * The base class for all actions.
092     */
093    @SuppressWarnings("PMD.AbstractClassWithoutAbstractMethod")
094    public abstract static class Action {
095
096        private final String key;
097
098        /**
099         * Instantiates a new action.
100         *
101         * @param key the key
102         */
103        public Action(String key) {
104            this.key = key;
105        }
106
107        /**
108         * Key.
109         *
110         * @return the string
111         */
112        public String key() {
113            return key;
114        }
115    }
116
117    /**
118     * A key (and value) deletion.
119     */
120    public static class Deletion extends Action {
121
122        /**
123         * Instantiates a new deletion.
124         *
125         * @param key the key
126         */
127        public Deletion(String key) {
128            super(key);
129        }
130    }
131
132    /**
133     * A value update.
134     */
135    public static class Update extends Action {
136        private final String value;
137
138        /**
139         * Instantiates a new update.
140         *
141         * @param key the key
142         * @param value the value
143         */
144        public Update(String key, String value) {
145            super(key);
146            this.value = value;
147        }
148
149        /**
150         * Value.
151         *
152         * @return the string
153         */
154        public String value() {
155            return value;
156        }
157    }
158}