001/*
002 * JGrapes Event Driven Framework
003 * Copyright (C) 2016-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.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    @SuppressWarnings("PMD.FieldNamingConventions")
047    protected final Logger logger = Logger.getLogger(getClass().getName());
048    private final Channel componentChannel;
049
050    /**
051     * Creates a new component base with its channel set to
052     * itself.
053     */
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    public Component(Channel componentChannel) {
073        super(null);
074        if (componentChannel == SELF) {
075            this.componentChannel = this;
076        } else {
077            this.componentChannel = componentChannel;
078        }
079        initComponentsHandlers();
080    }
081
082    /**
083     * Creates a new component base like {@link #Component(Channel)}
084     * but with channel mappings for {@link Handler} annotations.
085     *
086     * @param componentChannel the channel that the component's
087     * handlers listen on by default and that 
088     * {@link Manager#fire(Event, Channel...)} sends the event to
089     * @param channelReplacements the channel replacements to apply
090     * to the `channels` elements of the {@link Handler} annotations
091     */
092    public Component(
093            Channel componentChannel, ChannelReplacements channelReplacements) {
094        super(channelReplacements);
095        if (componentChannel == SELF) {
096            this.componentChannel = this;
097        } else {
098            this.componentChannel = componentChannel;
099        }
100        initComponentsHandlers();
101    }
102
103    /*
104     * (non-Javadoc)
105     * 
106     * @see org.jgrapes.core.internal.ComponentVertex#setName(java.lang.String)
107     */
108    @Override
109    public Component setName(String name) {
110        super.setName(name);
111        return this;
112    }
113
114    /*
115     * (non-Javadoc)
116     * 
117     * @see org.jgrapes.core.internal.ComponentVertex#getComponent()
118     */
119    @Override
120    public Component component() {
121        return this;
122    }
123
124    /**
125     * Returns the channel associated with the component.
126     * 
127     * @return the channel as assigned by the constructor.
128     * 
129     * @see org.jgrapes.core.Manager#channel()
130     */
131    @Override
132    public Channel channel() {
133        return componentChannel;
134    }
135
136    /**
137     * Return the object itself as value.
138     */
139    @Override
140    public Object defaultCriterion() {
141        return this;
142    }
143
144    /**
145     * Matches the object itself (using identity comparison) or the
146     * {@link Channel} class.
147     * 
148     * @see Channel#isEligibleFor(Object)
149     */
150    @Override
151    @SuppressWarnings("PMD.CompareObjectsWithEquals")
152    public boolean isEligibleFor(Object value) {
153        return value.equals(Channel.class)
154            || value == defaultCriterion();
155    }
156
157}