001    /*
002     * ============================================================================
003     * GNU Lesser General Public License
004     * ============================================================================
005     *
006     * Beanlet - JSE Application Container.
007     * Copyright (C) 2006  Leon van Zantvoort
008     * 
009     * This library is free software; you can redistribute it and/or
010     * modify it under the terms of the GNU Lesser General Public
011     * License as published by the Free Software Foundation; either
012     * version 2.1 of the License, or (at your option) any later version.
013     * 
014     * This library is distributed in the hope that it will be useful,
015     * but WITHOUT ANY WARRANTY; without even the implied warranty of
016     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
017     * Lesser General Public License for more details.
018     * 
019     * You should have received a copy of the GNU Lesser General Public
020     * License along with this library; if not, write to the Free Software
021     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
022     * 
023     * Leon van Zantvoort
024     * 243 Acalanes Drive #11
025     * Sunnyvale, CA 94086
026     * USA
027     *
028     * zantvoort@users.sourceforge.net
029     * http://beanlet.org
030     */
031    package org.beanlet;
032    
033    /**
034     * <p>Represents a reference to a beanlet.</p>
035     * 
036     * <p>Beanlets references are used to uniquely identify the underlying beanlet
037     * and to control the lifecycle of the beanlet.</p>
038     * 
039     * <p>Invocations made on a beanlet proxy that points to a stateful beanlet are
040     * always performed on the same beanlet instance. In case of a stateless 
041     * beanlet, it is not specified which beanlet instance is used to execute the 
042     * invocation.</p>
043     * 
044     * <p>Beanlet references can be removed, either explicitly by calling 
045     * {@link #invalidate} or alternatively, once it is no longer stronly reachable, 
046     * by the garbage collector. Beanlet references that have been removed can no
047     * longer be used to perform calls on the underlying beanlet. Such calls will
048     * result in an unchecked exception thrown by the application container. The 
049     * {@link #isRemoved} method can be used to check whether a reference has 
050     * been removed.</p>
051     * 
052     * @author Leon van Zantvoort
053     */
054    public interface BeanletReference<T> {
055    
056        /**
057         * Returns meta data for the underlying beanlet.
058         */
059        BeanletMetaData<T> getBeanletMetaData();
060        
061        /**
062         * Returns the beanlet.
063         *
064         * @return the beanlet.
065         */
066        Object getBeanlet();
067    
068        /**
069         * Returns the beanlet if this object is an instance of the beanlet type
070         * as specified by {@link BeanletMetaData#getType}. This might not always 
071         * be the case, for example for proxy beanlets. In this case a 
072         * {@code BeanletNotOfRequiredTypeException} exception is thrown.
073         *
074         * @return the beanlet.
075         * @throws BeanletNotOfRequiredTypeException if beanlet is not an instance
076         * of beanlet type.
077         */
078        T getTypedBeanlet() throws BeanletNotOfRequiredTypeException;
079        
080        /**
081         * Returns {@code true} if specified {@code event} is supported by this
082         * reference.
083         */
084        boolean isExecutable(Event event);
085        
086        /**
087         * Executes the specified {@code event}.
088         * 
089         * @throws BeanletEventException result of event execution.
090         */
091        Object execute(Event event) throws BeanletEventException;
092        
093        /**
094         * Causes this reference to be invalidated and removed. As a result,
095         * {@code isValid} returns {@code false}. Events can still be executed
096         * while the reference is being invalidated.
097         * 
098         * This method is idempotent.
099         */
100        void invalidate();
101        
102        /**
103         * Returns {@code true} if this reference if valid. If {@code false} is 
104         * returned, the reference is being destroyed and finally removed, resulting
105         * in {@code isRemoved} to return {@code true}.
106         *
107         * @return {@code true} if this reference is valid, {@code false} otherwise.
108         */
109        boolean isValid();
110        
111        /**
112         * Remove the reference immediately. The reference is not being invalidated.
113         */
114        void remove();
115        
116        /**
117         * Returns {@code true} if this reference has been removed, it
118         * can no longer execute events, {@code false} otherwise.
119         *
120         * @return {@code true} if this reference is removed, {@code false} otherwise.
121         */
122        boolean isRemoved();
123    }