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.webconsole.base.events; 020 021import java.util.HashMap; 022import java.util.Map; 023import java.util.function.BiConsumer; 024import org.jdrupes.json.JsonArray; 025import org.jgrapes.core.Event; 026 027/** 028 * Sent to a web console component to update some of its properties. 029 * The interpretation of the properties is completely dependent on the 030 * handling web console component. 031 * 032 * This event has a close relationship to the {@link NotifyConletModel} 033 * event. The latter is used by web console component's functions to 034 * send information from the console page to the web console component 035 * model. It passes the information as a {@link JsonArray}. The 036 * interpretation of this information is only known by the web console 037 * component. The {@link UpdateConletModel} event should be 038 * used to to pass information within the application, i.e. on the server 039 * side. 040 * 041 * Depending on the information passed, it may be good practice to 042 * write an event handler for the web console component that converts a 043 * {@link NotifyConletModel} to a {@link UpdateConletModel} that is 044 * fired on its channel instead of handling it immediately. This allows 045 * events sent from the console page and from other components in the 046 * application to be handled in a uniform way. 047 */ 048public class UpdateConletModel extends Event<Void> { 049 050 private String conletId; 051 private Map<Object, Object> properties; 052 053 /** 054 * Creates a new event. 055 * 056 * @param conletId the id of the web console component 057 * @param properties the properties to update 058 */ 059 public UpdateConletModel(String conletId, Map<?, ?> properties) { 060 this.conletId = conletId; 061 @SuppressWarnings("unchecked") 062 Map<Object, Object> props = (Map<Object, Object>) properties; 063 this.properties = props; 064 } 065 066 /** 067 * Creates a new event. This constructor creates an empty map of 068 * properties and is therefore intended to be used together with 069 * {@link #addPreference(Object, Object)}. 070 * 071 * @param conletId the web console component id 072 */ 073 public UpdateConletModel(String conletId) { 074 this(conletId, new HashMap<>()); 075 } 076 077 /** 078 * Returns the web console component id. 079 * 080 * @return the web console component id 081 */ 082 public String conletId() { 083 return conletId; 084 } 085 086 /** 087 * Returns the properties. Every event returns a mutable map, 088 * thus allowing event handlers to modify the map even if 089 * none was passed to the constructor. 090 */ 091 public Map<Object, Object> properties() { 092 if (properties == null) { 093 properties = new HashMap<>(); 094 } 095 return properties; 096 } 097 098 /** 099 * Convenience method for adding properties one-by-one. 100 * 101 * @param key the property key 102 * @param value the property value 103 * @return the event for easy chaining 104 */ 105 public UpdateConletModel addPreference(Object key, Object value) { 106 properties().put(key, value); 107 return this; 108 } 109 110 /** 111 * Convenience method that performs the given action if a property 112 * with the given key exists. 113 * 114 * @param key the property key 115 * @param action the action to perform 116 */ 117 public UpdateConletModel ifPresent( 118 Object key, BiConsumer<Object, Object> action) { 119 if (properties().containsKey(key)) { 120 action.accept(key, properties().get(key)); 121 } 122 return this; 123 } 124}