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