001 /**
002 *
003 * Copyright 2004 Protique Ltd
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * 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
019 package org.activemq.capacity;
020 import java.util.Iterator;
021 import EDU.oswego.cs.dl.util.concurrent.CopyOnWriteArrayList;
022
023 /**
024 * BasicCapacityMonitor implementation
025 * @version $Revision: 1.1.1.1 $
026 */
027 public class BasicCapacityMonitor implements CapacityMonitor {
028 private String name;
029 private long valueLimit;
030 private long currentValue = 0;
031 private int currentCapacity = 100;
032 private int roundedCapacity = 100;
033 private int roundingFactor = 10;
034 private CopyOnWriteArrayList listeners = new CopyOnWriteArrayList();
035
036 /**
037 * Construct a CapacityMonitor
038 *
039 * @param name
040 * @param valueLimit
041 */
042 public BasicCapacityMonitor(String name, long valueLimit) {
043 this.name = name;
044 this.valueLimit = valueLimit;
045 }
046
047 /**
048 * Get the name of the CapacityMonitor
049 *
050 * @return
051 */
052 public String getName() {
053 return name;
054 }
055
056 /**
057 * @param newName
058 */
059 public void setName(String newName){
060 name = newName;
061 }
062
063 /**
064 * Get the rounding factor - default is 10
065 * @return the rounding factor
066 */
067 public int getRoundingFactor(){
068 return roundingFactor;
069 }
070
071 /**
072 * Set the rounding factor (between 1-100)
073 * @param newRoundingFactor
074 */
075 public void setRoundingFactor(int newRoundingFactor){
076 if (newRoundingFactor < 1 || newRoundingFactor > 100){
077 throw new IllegalArgumentException("invalid roundingFactor: " + newRoundingFactor);
078 }
079 roundingFactor = newRoundingFactor;
080 }
081
082 /**
083 * Add a CapacityMonitorEventListener
084 *
085 * @param l
086 */
087 public void addCapacityEventListener(CapacityMonitorEventListener l) {
088 listeners.add(l);
089 }
090
091 /**
092 * Remove a CapacityMonitorEventListener
093 *
094 * @param l
095 */
096 public void removeCapacityEventListener(CapacityMonitorEventListener l) {
097 listeners.remove(l);
098 }
099
100 /**
101 * Get the current capscity of the service as a percentage
102 *
103 * @return
104 */
105 public int getCurrentCapacity() {
106 return currentCapacity;
107 }
108
109 /**
110 * Calculates the capacity rounded down to the rounding factor
111 * @return
112 */
113 public int getRoundedCapacity(){
114 return roundedCapacity;
115 }
116
117 /**
118 * Get the current value of the CapacityMonitor
119 *
120 * @return
121 */
122 public long getCurrentValue() {
123 return currentValue;
124 }
125
126 /**
127 * set the current value of the capacity
128 *
129 * @param newCurrentValue
130 */
131 public void setCurrentValue(long newCurrentValue) {
132 currentValue = newCurrentValue;
133 int newCapacity = calculateCapacity();
134 int newRoundedCapacity = newCapacity > 0 ? (newCapacity/roundingFactor)*roundingFactor : 0;
135 updateCapacityChanged(newRoundedCapacity);
136 currentCapacity = newCapacity;
137 roundedCapacity = newRoundedCapacity;
138 }
139
140 /**
141 * @return The upper limit of the value of the CapacityMonitor
142 */
143 public long getValueLimit() {
144 return valueLimit;
145 }
146
147 /**
148 * set a new value limit for the CapacityMonitor
149 *
150 * @param newValueLimit
151 */
152 public void setValueLimit(long newValueLimit) {
153 valueLimit = newValueLimit;
154 //this could have changed the capacity
155 setCurrentValue(currentValue);
156
157 }
158
159 /**
160 * @return a CapacityMontorEvent for the currentCapacity
161 */
162 public CapacityMonitorEvent generateCapacityMonitorEvent(){
163 CapacityMonitorEvent event = new CapacityMonitorEvent(name, roundedCapacity);
164 return event;
165 }
166
167 private void updateCapacityChanged(int newRoundedCapacity) {
168 if (listeners.size() > 0 && newRoundedCapacity != roundedCapacity) {
169 CapacityMonitorEvent event = new CapacityMonitorEvent(name, newRoundedCapacity);
170 for (Iterator i = listeners.iterator();i.hasNext();) {
171 CapacityMonitorEventListener listener = (CapacityMonitorEventListener) i.next();
172 listener.capacityChanged(event);
173 }
174 }
175
176 }
177
178 private int calculateCapacity() {
179 int result = 100;
180 if (currentValue != 0){
181 result = (int) (100-(currentValue * 100)/valueLimit);
182 }
183 return result;
184 }
185 }