001/* 002 * JGrapes Event Driven Framework 003 * Copyright (C) 2016-2026 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.core; 020 021import java.util.logging.Logger; 022import org.jgrapes.core.annotation.Handler; 023import org.jgrapes.core.annotation.HandlerDefinition.ChannelReplacements; 024import org.jgrapes.core.internal.ComponentVertex; 025 026/** 027 * This class can be used as base class for implementing a component. 028 * <P> 029 * This class implements the {@link Manager} interface. Contrary 030 * to classes that only implement {@link ComponentType}, derived 031 * classes therefore don't need a manager attribute to get access to the 032 * component management methods provided by this interface. 033 * <P> 034 * This class also implements the {@code Channel} interface in such a way 035 * that each instance of this class can be used as an independent 036 * channel. Note that events that have a component as one of their 037 * channels are always handled by the component's handlers, i.e. in 038 * addition to the channels explicitly defined for a handler. 039 * 040 * @see Handler 041 * @see ComponentType 042 */ 043public abstract class Component extends ComponentVertex 044 implements ComponentType, Channel { 045 046 protected final Logger logger = Logger.getLogger(getClass().getName()); 047 private final Channel componentChannel; 048 049 /** 050 * Creates a new component base with its channel set to 051 * itself. 052 */ 053 @SuppressWarnings("PMD.ConstructorCallsOverridableMethod") 054 public Component() { 055 super(null); 056 componentChannel = this; 057 initComponentsHandlers(); 058 } 059 060 /** 061 * Creates a new component base with its channel set to the given 062 * channel. As a special case {@link Channel#SELF} can be 063 * passed to the constructor to make the component use itself 064 * as channel. The special value is necessary as you 065 * obviously cannot pass an object to be constructed to its 066 * constructor. 067 * 068 * @param componentChannel the channel that the component's 069 * handlers listen on by default and that 070 * {@link Manager#fire(Event, Channel...)} sends the event to 071 */ 072 @SuppressWarnings("PMD.ConstructorCallsOverridableMethod") 073 public Component(Channel componentChannel) { 074 super(null); 075 if (componentChannel == SELF) { 076 this.componentChannel = this; 077 } else { 078 this.componentChannel = componentChannel; 079 } 080 initComponentsHandlers(); 081 } 082 083 /** 084 * Creates a new component base like {@link #Component(Channel)} 085 * but with channel mappings for {@link Handler} annotations. 086 * 087 * @param componentChannel the channel that the component's 088 * handlers listen on by default and that 089 * {@link Manager#fire(Event, Channel...)} sends the event to 090 * @param channelReplacements the channel replacements to apply 091 * to the `channels` elements of the {@link Handler} annotations 092 */ 093 @SuppressWarnings({ "PMD.LooseCoupling", 094 "PMD.ConstructorCallsOverridableMethod" }) 095 public Component( 096 Channel componentChannel, ChannelReplacements channelReplacements) { 097 super(channelReplacements); 098 if (componentChannel == SELF) { 099 this.componentChannel = this; 100 } else { 101 this.componentChannel = componentChannel; 102 } 103 initComponentsHandlers(); 104 } 105 106 /* 107 * (non-Javadoc) 108 * 109 * @see org.jgrapes.core.internal.ComponentVertex#setName(java.lang.String) 110 */ 111 @Override 112 public Component setName(String name) { 113 super.setName(name); 114 return this; 115 } 116 117 /* 118 * (non-Javadoc) 119 * 120 * @see org.jgrapes.core.internal.ComponentVertex#getComponent() 121 */ 122 @Override 123 public Component component() { 124 return this; 125 } 126 127 /** 128 * Returns the channel associated with the component. 129 * 130 * @return the channel as assigned by the constructor. 131 * 132 * @see org.jgrapes.core.Manager#channel() 133 */ 134 @Override 135 public Channel channel() { 136 return componentChannel; 137 } 138 139 /** 140 * Return the object itself as value. 141 */ 142 @Override 143 public Object defaultCriterion() { 144 return this; 145 } 146 147 /** 148 * Matches the object itself (using identity comparison) or the 149 * {@link Channel} class. 150 * 151 * @see Channel#isEligibleFor(Object) 152 */ 153 @Override 154 @SuppressWarnings("PMD.CompareObjectsWithEquals") 155 public boolean isEligibleFor(Object value) { 156 return value.equals(Channel.class) 157 || value == defaultCriterion(); 158 } 159 160}