View Javadoc

1   /**
2    *  MicroEmulator
3    *  Copyright (C) 2006-2007 Bartek Teodorczyk <barteo@barteo.net>
4    *  Copyright (C) 2006-2007 Vlad Skarzhevskyy
5    *
6    *  It is licensed under the following two licenses as alternatives:
7    *    1. GNU Lesser General Public License (the "LGPL") version 2.1 or any newer version
8    *    2. Apache License (the "AL") Version 2.0
9    *
10   *  You may not use this file except in compliance with at least one of
11   *  the above two licenses.
12   *
13   *  You may obtain a copy of the LGPL at
14   *      http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt
15   *
16   *  You may obtain a copy of the AL at
17   *      http://www.apache.org/licenses/LICENSE-2.0
18   *
19   *  Unless required by applicable law or agreed to in writing, software
20   *  distributed under the License is distributed on an "AS IS" BASIS,
21   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22   *  See the LGPL or the AL for the specific language governing permissions and
23   *  limitations.
24   *
25   *  @version $Id: MIDletTimer.java 1771 2008-07-24 02:14:33Z vlads $
26   */
27  package org.microemu.app.util;
28  
29  import java.util.Date;
30  import java.util.HashMap;
31  import java.util.Iterator;
32  import java.util.Map;
33  import java.util.Timer;
34  import java.util.TimerTask;
35  import java.util.WeakHashMap;
36  
37  import org.microemu.MIDletBridge;
38  import org.microemu.MIDletContext;
39  import org.microemu.log.Logger;
40  
41  /**
42   * Terminate all timers on MIDlet exit. TODO Name all the timer Threads created
43   * by MIDlet in Java 5
44   * 
45   * @author vlads
46   */
47  public class MIDletTimer extends Timer {
48  
49  	private static Map midlets = new WeakHashMap();
50  
51  	private String name;
52  
53  	private MIDletContext midletContext;
54  
55  	public MIDletTimer() {
56  		super();
57  		StackTraceElement[] ste = new Throwable().getStackTrace();
58  		name = ste[1].getClassName() + "." + ste[1].getMethodName();
59  	}
60  
61  	public void schedule(TimerTask task, Date time) {
62  		register(this);
63  		super.schedule(task, time);
64  	}
65  
66  	public void schedule(TimerTask task, Date firstTime, long period) {
67  		register(this);
68  		super.schedule(task, firstTime, period);
69  	}
70  
71  	public void schedule(TimerTask task, long delay) {
72  		register(this);
73  		super.schedule(task, delay);
74  	}
75  
76  	public void schedule(TimerTask task, long delay, long period) {
77  		register(this);
78  		super.schedule(task, delay, period);
79  	}
80  
81  	public void scheduleAtFixedRate(TimerTask task, Date firstTime, long period) {
82  		register(this);
83  		super.schedule(task, firstTime, period);
84  	}
85  
86  	public void scheduleAtFixedRate(TimerTask task, long delay, long period) {
87  		register(this);
88  		super.scheduleAtFixedRate(task, delay, period);
89  	}
90  
91  	public void cancel() {
92  		unregister(this);
93  		super.cancel();
94  	}
95  
96  	private void terminate() {
97  		super.cancel();
98  	}
99  
100 	private static void register(MIDletTimer timer) {
101 		if (timer.midletContext == null) {
102 			timer.midletContext = MIDletBridge.getMIDletContext();
103 		}
104 		if (timer.midletContext == null) {
105 			Logger.error("Creating Timer with no MIDlet context", new Throwable());
106 			return;
107 		}
108 		Map timers = (Map) midlets.get(timer.midletContext);
109 		if (timers == null) {
110 			// Can't use WeakHashMap Timers are disposed by JVM
111 			timers = new HashMap();
112 			midlets.put(timer.midletContext, timers);
113 		}
114 		// Logger.debug("Register timer created from [" + timer.name + "]");
115 		timers.put(timer, timer.midletContext);
116 	}
117 
118 	private static void unregister(MIDletTimer timer) {
119 		if (timer.midletContext == null) {
120 			// Logger.error("Timer with no MIDlet context", new Throwable());
121 			return;
122 		}
123 		Map timers = (Map) midlets.get(timer.midletContext);
124 		if (timers == null) {
125 			return;
126 		}
127 		// Logger.debug("Unregister timer created from [" + timer.name + "]");
128 		timers.remove(timer);
129 	}
130 
131 	/**
132 	 * Terminate all Threads created by MIDlet
133 	 */
134 	public static void contextDestroyed(MIDletContext midletContext) {
135 		if (midletContext == null) {
136 			return;
137 		}
138 		Map timers = (Map) midlets.get(midletContext);
139 		if (timers != null) {
140 			terminateTimers(timers);
141 			midlets.remove(midletContext);
142 		}
143 	}
144 
145 	private static void terminateTimers(Map timers) {
146 		for (Iterator iter = timers.keySet().iterator(); iter.hasNext();) {
147 			Object o = iter.next();
148 			if (o == null) {
149 				continue;
150 			}
151 			if (o instanceof MIDletTimer) {
152 				MIDletTimer tm = (MIDletTimer) o;
153 				Logger.warn("MIDlet timer created from [" + tm.name + "] still running");
154 				tm.terminate();
155 			} else {
156 				Logger.debug("unrecognized Object [" + o.getClass().getName() + "]");
157 			}
158 		}
159 		;
160 	}
161 
162 }