001: package com.tagtraum.jo;
002:
003: import com.tagtraum.framework.log.Log;
004:
005: import javax.servlet.*;
006: import javax.swing.event.ChangeEvent;
007: import javax.swing.event.ChangeListener;
008: import java.io.IOException;
009: import java.util.Enumeration;
010: import java.util.Vector;
011:
012: /**
013: *
014: * @author <a href="mailto:hs@tagtraum.com">Hendrik Schreiber</a>
015: * @version 1.1beta1 ($Revision: 1.2 $)
016: */
017: public class JoFilterHolder implements I_JoWebAppElement {
018:
019: private static final int DESTROY_TIMEOUT = 10000; // ms
020: private I_JoServletContextPeer peer;
021: private Filter filter;
022: private String filterClassname;
023: private JoFilterConfig filterConfig;
024: private Log log = Log.getLog();
025: private UnavailableException unavailableException;
026: private long unavailableSince;
027: private int threadCount;
028: private String name;
029: private String displayName;
030: private String description;
031: private JoIcon icon;
032: private String logPrefix = "";
033: private Vector changeListeners;
034:
035: public JoFilterHolder() {
036: this .filterConfig = new JoFilterConfig();
037: this .changeListeners = new Vector();
038: this .icon = new JoIcon();
039: }
040:
041: public void setName(String name) {
042: this .name = name;
043: }
044:
045: public String getName() {
046: return name;
047: }
048:
049: public String getDisplayName() {
050: return displayName;
051: }
052:
053: public void setDisplayName(String displayName) {
054: this .displayName = displayName;
055: }
056:
057: public String getDescription() {
058: return description;
059: }
060:
061: public void setDescription(String description) {
062: this .description = description;
063: }
064:
065: public void setIcon(JoIcon icon) {
066: this .icon = icon;
067: }
068:
069: public JoIcon getIcon() {
070: return icon;
071: }
072:
073: public String getInitParameter(String aKey) {
074: return filterConfig.getInitParameter(aKey);
075: }
076:
077: public void setInitParameter(String aKey, String aValue) {
078: filterConfig.setInitParameter(aKey, aValue);
079: }
080:
081: public Enumeration getInitParameterNames() {
082: return filterConfig.getInitParameterNames();
083: }
084:
085: public ClassLoader getClassLoader() {
086: // TODO: what the heck is this for...?
087: return null;
088: }
089:
090: public void setServletContextPeer(I_JoServletContextPeer peer) {
091: this .peer = peer;
092: this .filterConfig.setServletContext(peer.getServletContext());
093: this .log = Log.getLog(peer.getHost().getName());
094: this .logPrefix = "[" + peer.getName() + "]: ";
095: }
096:
097: public void setFilterClassname(String filterClassname) {
098: this .filterClassname = filterClassname;
099: }
100:
101: public String getFilterClassname() {
102: return filterClassname;
103: }
104:
105: public void service(ServletRequest request,
106: ServletResponse response, FilterChain filterChain)
107: throws IOException, ServletException {
108: synchronized (this ) {
109: threadCount++;
110: }
111: try {
112: checkUnavailable();
113: initializeFilter();
114: filter(request, response, filterChain);
115: } finally {
116: synchronized (this ) {
117: threadCount--;
118: }
119: }
120: }
121:
122: public synchronized void destroy() {
123: // TODO: review doug lea classes for this.
124: long destroyStart = System.currentTimeMillis();
125: while (threadCount != 0
126: && System.currentTimeMillis() - destroyStart < DESTROY_TIMEOUT) {
127: try {
128: wait(500);
129: } catch (InterruptedException e) {
130: // ignore
131: }
132: }
133: if (filter != null)
134: filter.destroy();
135: filter = null;
136: }
137:
138: private void filter(ServletRequest request,
139: ServletResponse response, FilterChain filterChain)
140: throws IOException, ServletException {
141: try {
142: filter.doFilter(request, response, filterChain);
143: } catch (UnavailableException e) {
144: if (!e.isPermanent())
145: unavailableSince = System.currentTimeMillis();
146: unavailableException = e;
147: throw e;
148: }
149: }
150:
151: private synchronized void checkUnavailable()
152: throws UnavailableException {
153: if (unavailableException != null) {
154: if (unavailableException.isPermanent())
155: throw unavailableException;
156: else if ((System.currentTimeMillis() - unavailableException
157: .getUnavailableSeconds() * 1000) < unavailableSince)
158: throw unavailableException;
159: else
160: unavailableException = null;
161: }
162: }
163:
164: private synchronized void initializeFilter()
165: throws ServletException {
166: if (filter == null) {
167: try {
168: filter = (Filter) Class.forName(filterClassname, true,
169: peer.getClassLoader()).newInstance();
170: } catch (Exception e) {
171: if (log.isLog(Log.ERROR)) {
172: log.log(logPrefix
173: + "Failed to instantiate filter: "
174: + e.toString(), Log.ERROR);
175: log.log(e, Log.ERROR);
176: }
177: unavailableException = new UnavailableException(
178: "Failed to instantiate filter: " + e.toString());
179: throw unavailableException;
180: }
181: try {
182: filter.init(filterConfig);
183: } catch (UnavailableException e) {
184: if (!e.isPermanent())
185: unavailableSince = System.currentTimeMillis();
186: unavailableException = e;
187: throw e;
188: }
189: fireChangeEvent();
190: }
191: }
192:
193: public synchronized boolean isLoaded() {
194: return filter != null;
195: }
196:
197: /**
198: * Eventlistener for possible UI.
199: */
200: public void addChangeListener(ChangeListener cl) {
201: if (!changeListeners.contains(cl))
202: changeListeners.add(cl);
203: }
204:
205: /**
206: * Eventlistener for possible UI.
207: */
208: public boolean removeChangeListener(ChangeListener cl) {
209: return changeListeners.remove(cl);
210: }
211:
212: /**
213: * Eventlistener for possible UI.
214: */
215: private void fireChangeEvent() {
216: ChangeEvent ce = new ChangeEvent(this );
217: for (int i = 0; i < changeListeners.size(); i++) {
218: ((ChangeListener) changeListeners.get(i)).stateChanged(ce);
219: }
220: }
221:
222: public String toString() {
223: return this .name + " " + this.filterClassname;
224: }
225:
226: }
|