001/*
002 *    $RCSfile$
003 *
004 *     $Author: barseghian $
005 *       $Date: 2012-08-09 23:50:32 +0000 (Thu, 09 Aug 2012) $
006 *   $Revision: 30396 $
007 *
008 *  For Details: http://kepler-project.org
009 *
010 * Copyright (c) 2007 The Regents of the University of California.
011 * All rights reserved.
012 *
013 * Permission is hereby granted, without written agreement and without
014 * license or royalty fees, to use, copy, modify, and distribute this
015 * software and its documentation for any purpose, provided that the
016 * above copyright notice and the following two paragraphs appear in
017 * all copies of this software.
018 *
019 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
020 * FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
021 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
022 * IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY
023 * OF SUCH DAMAGE.
024 *
025 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
026 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
027 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
028 * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY
029 * OF CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT,
030 * UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
031 */
032package org.kepler.monitor;
033
034import java.awt.event.ActionEvent;
035import java.awt.event.ActionListener;
036import java.beans.PropertyChangeListener;
037import java.beans.PropertyChangeSupport;
038import java.util.Collections;
039import java.util.HashMap;
040import java.util.Map;
041import java.util.Set;
042
043import javax.swing.Timer;
044
045import org.apache.commons.logging.Log;
046import org.apache.commons.logging.LogFactory;
047
048/**
049 * A set of properties subject to be monitored.
050 * 
051 * <p>
052 * Any object interesting in being notified about changes in these properties
053 * should register itself as a {@link PropertyChangeListener}.
054 * 
055 * @author Carlos Rueda
056 * @version $Id: MonitoredStatus.java 30396 2012-08-09 23:50:32Z barseghian $
057 */
058public class MonitoredStatus {
059
060        /** Convenience attributes for a "state" property */
061        public static class State {
062
063                /** The name of the state property. */
064                public static final String STATE = "state";
065
066                /** Value for an "idle" state. */
067                public static final Object IDLE = "IDLE";
068
069                /** Value for a "waiting" state. */
070                public static final Object WAITING = "WAITING";
071
072                /** Value for a "running" state. */
073                public static final Object RUNNING = "RUNNING";
074
075                /** Value for an "error" state. */
076                public static final Object ERROR = "ERROR";
077
078                /** Names for quality properties*/
079                public static final String QUALITY_SCORE = "qualityscore";
080                
081                public static final String HIGH_QUALITY = "highquality";
082
083                public static final String LOW_QUALITY = "lowquality";
084                
085                public static final Object NO_QUALITY_SCORE = "NO_QUALITY_SCORE"; 
086        }
087
088        /**
089         * Gets the names of the properties of this monitored object.
090         * 
091         * @return the names
092         */
093        public Set<String> getPropertyNames() {
094                return Collections.unmodifiableSet(props.keySet());
095        }
096
097        /**
098         * Sets the value of a monitored property. Registered listeners will be
099         * notified of this event.
100         * 
101         * @param propName
102         *            property name
103         * @param propValue
104         *            the value
105         */
106        public void setProperty(String propName, Object propValue) {
107                _lastUpdate = System.currentTimeMillis();
108                Object oldValue = props.put(propName, propValue);
109                
110                _firePropertyChange(propName, oldValue, propValue);
111                
112                
113        }
114        
115        /**
116         * Gets the current value of a monitored property.
117         * 
118         * @param propName
119         * @return the value
120         */
121        public Object getProperty(String propName) {
122                Object propValue = props.get(propName);
123                return propValue;
124        }
125
126        /**
127         * Adds a property change listener to this monitored status.
128         */
129        public void addPropertyChangeListener(PropertyChangeListener listener) {
130                _propertyChangeSupport.addPropertyChangeListener(listener);
131        }
132
133        /**
134         * Removes a property change listener from this monitored status.
135         */
136        public void removePropertyChangeListener(PropertyChangeListener listener) {
137                _propertyChangeSupport.removePropertyChangeListener(listener);
138        }
139
140        /**
141         * Gets the property timer.
142         */
143        public PropertyTimer getPropertyTimer() {
144                if (_propertyTimer == null) {
145                        _propertyTimer = new PropertyTimer();
146                }
147                return _propertyTimer;
148        }
149
150        // /////////////////////////////////////////////////////////////////
151        // // private members ////
152
153        /**
154         * Calls
155         * <code>_propertyChangeSupport.firePropertyChange(propertyName, oldValue, newValue)</code>
156         * 
157         * @see java.beans.PropertyChangeSupport#firePropertyChange(String, Object,
158         *      Object)
159         */
160        private final void _firePropertyChange(String propertyName,
161                        Object oldValue, Object newValue) {
162                _propertyChangeSupport.firePropertyChange(propertyName, oldValue,
163                                newValue);
164        }
165
166        /** the property change support */
167        private PropertyChangeSupport _propertyChangeSupport = new PropertyChangeSupport(
168                        this);
169
170        /** Map propName-&gt;propvalue */
171        private Map<String, Object> props = new HashMap<String, Object>();
172
173        /** The last time {@link #setProperty(String, Object)} was called. */
174        private long _lastUpdate = 0;
175
176        /**
177         * For automatic update of a property in this status object. In handles an
178         * internal timer that calls setProperty(propName, propValue) if, whenever
179         * the timer is triggered, the current time minus the time when the
180         * setProperty method was last called is greater than the given delay.
181         */
182        public class PropertyTimer {
183                private int delay = 1000;
184                private String propName = State.STATE;
185                private Object propValue = State.WAITING;
186
187                private final Timer _timer = new Timer(delay, new ActionListener() {
188                        public void actionPerformed(ActionEvent ev) {
189                                long current = System.currentTimeMillis();
190                                long curr_delay = current - _lastUpdate;
191                                if (curr_delay > delay) {
192                                        setProperty(propName, propValue);
193                                }
194                        }
195                });
196
197                /** Sets the delay for the timer. By default, 1000ms */
198                public void setDelay(int delay) {
199                        this.delay = delay;
200                        _timer.setDelay(delay);
201                        _timer.restart();
202                        if (isDebugging) {
203                                log.debug(this);
204                        }
205                }
206
207                /** Sets the property name for the timer. By default, {@link State#STATE} */
208                public void setPropertyName(String propName) {
209                        this.propName = propName;
210                }
211
212                /**
213                 * Sets the property value for the timer. By default,
214                 * {@link State#WAITING}
215                 */
216                public void setPropertyValue(Object propValue) {
217                        this.propValue = propValue;
218                }
219
220                /** Starts the timer. */
221                public void start() {
222                        _timer.start();
223                        if (isDebugging) {
224                                log.debug(this);
225                        }
226                }
227
228                /** Stops the timer. */
229                public void stop() {
230                        _timer.stop();
231                        if (isDebugging) {
232                                log.debug(this);
233                        }
234                }
235
236                public String toString() {
237                        return "delay=" + delay + ", propName=" + propName + ", propValue="
238                                        + propValue;
239                }
240        }
241
242        private PropertyTimer _propertyTimer;
243        
244        private static final Log log = LogFactory.getLog(MonitoredStatus.class);
245        private static final boolean isDebugging = log.isDebugEnabled();
246
247}