001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     * 
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     * 
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    
018    package org.apache.commons.pool;
019    
020    /**
021     * <p>Object created by {@link WaiterFactory}. Maintains active / valid state,
022     * last passivated and idle times.  Waits with configurable latency when 
023     * {@link #doWait()} method is called.</p>
024     *
025     * <p>This class is *not* threadsafe.</p>
026     */
027    public class Waiter {
028        private boolean active = false;
029        private boolean valid = true;
030        private long latency = 0;
031        private long lastPassivated = 0;
032        private long lastIdleTimeMs = 0;
033        
034        public Waiter(boolean active, boolean valid, long latency) {
035            this.active = active;
036            this.valid = valid;
037            this.latency = latency;
038            this.lastPassivated = System.currentTimeMillis();
039        }
040    
041        /**
042         * Wait for {@link #getLatency()} ms.
043         */
044        public void doWait() {
045            try {
046                Thread.sleep(latency);
047            } catch (InterruptedException ex) {
048                // ignore
049            }
050        }
051    
052        /**
053         * Whether or not the instance is active.
054         * 
055         * @return true if the last lifecycle event for this instance was activation.
056         */
057        public boolean isActive() {
058            return active;
059        }
060    
061        /**
062         * <p>Sets the active state and updates {@link #getLastIdleTimeMs() lastIdleTime}
063         * or {@link #getLastPassivated() lastPassivated} as appropriate.</p>
064         * 
065         * <p>If the active state is changing from inactive to active, lastIdleTime
066         * is updated with the current time minus lastPassivated.  If the state is
067         * changing from active to inactive, lastPassivated is updated with the
068         * current time.</p>
069         * 
070         * <p>{@link WaiterFactory#activateObject(Object)} and
071         * {@link WaiterFactory#passivateObject(Object)} invoke this method on their
072         * actual parameter, passing <code>true</code> and <code>false</code>,
073         * respectively.</p>
074         * 
075         * @param active new active state
076         */
077        public void setActive(boolean active) {
078            final boolean activeState = this.active;
079            if (activeState == active) {
080                return;
081            }
082            this.active = active;
083            final long currentTime = System.currentTimeMillis();
084            if (active) {  // activating
085                lastIdleTimeMs = currentTime - lastPassivated;
086            } else {       // passivating
087                lastPassivated = currentTime;
088            }
089        }
090    
091        public long getLatency() {
092            return latency;
093        }
094    
095        public void setLatency(long latency) {
096            this.latency = latency;
097        }
098    
099        public boolean isValid() {
100            return valid;
101        }
102    
103        public void setValid(boolean valid) {
104            this.valid = valid;
105        }
106        
107        /**
108         * <p>Returns the system time of this instance's last passivation.</p>
109         * 
110         * <p>When an instance is created, this field is initialized to the system time.</p>
111         * 
112         * @return time of last passivation
113         */
114        public long getLastPassivated() {
115            return lastPassivated;
116        }
117        
118        /**
119         * <p>Returns the last idle time for this instance in ms.</p>
120         * 
121         * <p>When an instance is created, and each subsequent time it is passivated,
122         * the {@link #getLastPassivated() lastPassivated} property is updated with the
123         * current time.  When the next activation occurs, <code>lastIdleTime</code> is
124         * updated with the elapsed time since passivation.<p>
125         * 
126         * @return last idle time
127         */
128        public long getLastIdleTimeMs() {
129            return lastIdleTimeMs;
130        }
131        
132    }