001: /*
002: * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved
003: *
004: * This file is part of Resin(R) Open Source
005: *
006: * Each copy or derived work must preserve the copyright notice and this
007: * notice unmodified.
008: *
009: * Resin Open Source is free software; you can redistribute it and/or modify
010: * it under the terms of the GNU General Public License as published by
011: * the Free Software Foundation; either version 2 of the License, or
012: * (at your option) any later version.
013: *
014: * Resin Open Source 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, or any warranty
017: * of NON-INFRINGEMENT. See the GNU General Public License for more
018: * details.
019: *
020: * You should have received a copy of the GNU General Public License
021: * along with Resin Open Source; if not, write to the
022: *
023: * Free Software Foundation, Inc.
024: * 59 Temple Place, Suite 330
025: * Boston, MA 02111-1307 USA
026: *
027: * @author Sam
028: */
029:
030: package com.caucho.server.rewrite;
031:
032: import com.caucho.config.ConfigException;
033: import com.caucho.config.types.CronType;
034: import com.caucho.management.server.AbstractManagedObject;
035: import com.caucho.management.server.RewriteRuleMXBean;
036: import com.caucho.util.Alarm;
037: import com.caucho.util.AlarmListener;
038: import com.caucho.util.L10N;
039:
040: import javax.annotation.PostConstruct;
041: import javax.annotation.PreDestroy;
042: import java.util.logging.Logger;
043:
044: abstract public class AbstractRule implements Rule {
045: private static final L10N L = new L10N(AbstractRule.class);
046: private static final Logger log = Logger
047: .getLogger(AbstractRule.class.getName());
048:
049: private final RewriteDispatch _rewriteDispatch;
050:
051: private String _name;
052: private volatile boolean _isEnabled = true;
053: private CronType _enableAt;
054: private CronType _disableAt;
055:
056: private String _logPrefix;
057:
058: private FilterChainMapper _passFilterChainMapper;
059: private FilterChainMapper _failFilterChainMapper;
060:
061: private RewriteRuleAdmin _admin;
062:
063: private EnableAlarmListener _enableAlarmListener;
064: private EnableAlarmListener _disableAlarmListener;
065:
066: public AbstractRule(RewriteDispatch rewriteDispatch) {
067: _logPrefix = getTagName();
068: _rewriteDispatch = rewriteDispatch;
069: }
070:
071: protected RewriteDispatch getRewriteDispatch() {
072: return _rewriteDispatch;
073: }
074:
075: public void setName(String name) {
076: _name = name;
077: }
078:
079: public String getName() {
080: return _name;
081: }
082:
083: public void setEnabled(boolean isEnabled) {
084: if (_isEnabled != isEnabled) {
085: _isEnabled = isEnabled;
086:
087: _rewriteDispatch.clearCache();
088: }
089: }
090:
091: public boolean isEnabled() {
092: return _isEnabled;
093: }
094:
095: public void setDisableAt(CronType disableAt) {
096: _disableAt = disableAt;
097: }
098:
099: public void setEnableAt(CronType enableAt) {
100: _enableAt = enableAt;
101: }
102:
103: public void setPassFilterChainMapper(
104: FilterChainMapper passFilterChainMapper) {
105: _passFilterChainMapper = passFilterChainMapper;
106: }
107:
108: protected final FilterChainMapper getPassFilterChainMapper() {
109: return _passFilterChainMapper;
110: }
111:
112: public void setFailFilterChainMapper(
113: FilterChainMapper failFilterChainMapper) {
114: _failFilterChainMapper = failFilterChainMapper;
115: }
116:
117: protected final FilterChainMapper getFailFilterChainMapper() {
118: return _failFilterChainMapper;
119: }
120:
121: public void setLogPrefix(String logPrefix) {
122: _logPrefix = logPrefix;
123: }
124:
125: public String getLogPrefix() {
126: return _logPrefix;
127: }
128:
129: @PostConstruct
130: public void init() throws ConfigException {
131: if (_name == null && !_isEnabled && _enableAt == null)
132: throw new ConfigException(
133: L
134: .l(
135: "{0} requires 'name' if enabled='false' and enable-at is undefined",
136: getTagName()));
137: if (_enableAt != null)
138: _enableAlarmListener = new EnableAlarmListener(this ,
139: _enableAt, true);
140:
141: if (_disableAt != null)
142: _disableAlarmListener = new EnableAlarmListener(this ,
143: _disableAt, false);
144: }
145:
146: public void register() {
147: if (_admin == null && _name != null) {
148: _admin = createAdmin();
149: _admin.register();
150: }
151: }
152:
153: public void unregister() {
154: RewriteRuleAdmin admin = _admin;
155: _admin = null;
156:
157: if (admin != null)
158: admin.unregister();
159: }
160:
161: protected RewriteRuleAdmin createAdmin() {
162: return new RewriteRuleAdmin(this );
163: }
164:
165: protected void clearCache() {
166: _rewriteDispatch.clearCache();
167: }
168:
169: @PreDestroy
170: public void destroy() {
171: try {
172: unregister();
173: } finally {
174: EnableAlarmListener enableAlarmListener = _enableAlarmListener;
175: _enableAlarmListener = null;
176:
177: EnableAlarmListener disableAlarmListener = _disableAlarmListener;
178: _disableAlarmListener = null;
179:
180: if (enableAlarmListener != null)
181: enableAlarmListener.destroy();
182:
183: if (disableAlarmListener != null)
184: disableAlarmListener.destroy();
185: }
186: }
187:
188: public static class RewriteRuleAdmin extends AbstractManagedObject
189: implements RewriteRuleMXBean {
190: private final AbstractRule _rule;
191:
192: public RewriteRuleAdmin(AbstractRule rule) {
193: _rule = rule;
194: }
195:
196: public String getName() {
197: return _rule.getName();
198: }
199:
200: @Override
201: public String getType() {
202: return "RewriteRule";
203: }
204:
205: public String getState() {
206: if (_rule.isEnabled())
207: return "active";
208: else
209: return "stopped";
210: }
211:
212: public void start() {
213: _rule.setEnabled(true);
214: }
215:
216: public void stop() {
217: _rule.setEnabled(false);
218: }
219:
220: public void register() {
221: registerSelf();
222: }
223:
224: public void unregister() {
225: unregisterSelf();
226: }
227: }
228:
229: private static class EnableAlarmListener implements AlarmListener {
230: private final AbstractRule _rule;
231: private final CronType _cron;
232: private final boolean _isEnable;
233:
234: private volatile Alarm _alarm;
235:
236: public EnableAlarmListener(AbstractRule rule, CronType cron,
237: boolean isEnable) {
238: _rule = rule;
239: _cron = cron;
240: _isEnable = isEnable;
241:
242: String type = isEnable ? "enable" : "disable";
243: _alarm = new Alarm("rewrite-rule-" + type, this );
244:
245: queue();
246: }
247:
248: private void queue() {
249: long now = Alarm.getCurrentTime();
250:
251: long nextTime = _cron.nextTime(now);
252:
253: Alarm alarm = _alarm;
254:
255: if (alarm == null)
256: return;
257:
258: _rule.setEnabled(_isEnable);
259:
260: alarm.queue(nextTime - now);
261: }
262:
263: public void handleAlarm(Alarm alarm) {
264: alarm = _alarm;
265:
266: if (alarm == null)
267: return;
268:
269: _rule.setEnabled(_isEnable);
270:
271: queue();
272: }
273:
274: public void destroy() {
275: Alarm alarm = _alarm;
276: _alarm = null;
277:
278: if (alarm != null)
279: alarm.dequeue();
280: }
281: }
282: }
|