1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.microemu.app.util;
23
24 import java.util.Date;
25 import java.util.HashMap;
26 import java.util.Iterator;
27 import java.util.Map;
28 import java.util.Timer;
29 import java.util.TimerTask;
30 import java.util.WeakHashMap;
31
32 import org.microemu.MIDletBridge;
33 import org.microemu.MIDletContext;
34 import org.microemu.log.Logger;
35
36
37
38
39
40
41 public class MIDletTimer extends Timer {
42
43 private static Map midlets = new WeakHashMap();
44
45 private class OneTimeTimerTaskWrapper extends TimerTask {
46
47 TimerTask task;
48
49 OneTimeTimerTaskWrapper(TimerTask task) {
50 this.task = task;
51 }
52
53 public void run() {
54 unregister(MIDletTimer.this);
55 task.run();
56 }
57
58 }
59
60 private String name;
61
62 private MIDletContext midletContext;
63
64 public MIDletTimer() {
65 super();
66 StackTraceElement[] ste = new Throwable().getStackTrace();
67 name = ste[1].getClassName() + "." + ste[1].getMethodName();
68 }
69
70 public void schedule(TimerTask task, Date time) {
71 register(this);
72 super.schedule(new OneTimeTimerTaskWrapper(task), time);
73 }
74
75 public void schedule(TimerTask task, Date firstTime, long period) {
76 register(this);
77 super.schedule(task, firstTime, period);
78 }
79
80 public void schedule(TimerTask task, long delay) {
81 register(this);
82 super.schedule(new OneTimeTimerTaskWrapper(task), delay);
83 }
84
85 public void schedule(TimerTask task, long delay, long period) {
86 register(this);
87 super.schedule(task, delay, period);
88 }
89
90 public void scheduleAtFixedRate(TimerTask task, Date firstTime, long period) {
91 register(this);
92 super.schedule(task, firstTime, period);
93 }
94
95 public void scheduleAtFixedRate(TimerTask task, long delay, long period) {
96 register(this);
97 super.scheduleAtFixedRate(task, delay, period);
98 }
99
100 public void cancel() {
101 unregister(this);
102 super.cancel();
103 }
104
105 private void terminate() {
106 super.cancel();
107 }
108
109 private static void register(MIDletTimer timer) {
110 if (timer.midletContext == null) {
111 timer.midletContext = MIDletBridge.getMIDletContext();
112 }
113 if (timer.midletContext == null) {
114 Logger.error("Creating Timer with no MIDlet context", new Throwable());
115 return;
116 }
117 Map timers = (Map)midlets.get(timer.midletContext);
118 if (timers == null) {
119
120 timers = new HashMap();
121 midlets.put(timer.midletContext, timers);
122 }
123
124 timers.put(timer, timer.midletContext);
125 }
126
127 private static void unregister(MIDletTimer timer) {
128 if (timer.midletContext == null) {
129 Logger.error("Timer with no MIDlet context", new Throwable());
130 return;
131 }
132 Map timers = (Map)midlets.get(timer.midletContext);
133 if (timers == null) {
134 return;
135 }
136
137 timers.remove(timer);
138 }
139
140
141
142
143 public static void contextDestroyed(MIDletContext midletContext) {
144 if (midletContext == null) {
145 return;
146 }
147 Map timers = (Map)midlets.get(midletContext);
148 if (timers != null) {
149 terminateTimers(timers);
150 midlets.remove(midletContext);
151 }
152 }
153
154 private static void terminateTimers(Map timers) {
155 for (Iterator iter = timers.keySet().iterator(); iter.hasNext();) {
156 Object o = iter.next();
157 if (o == null) {
158 continue;
159 }
160 if (o instanceof MIDletTimer) {
161 MIDletTimer tm = (MIDletTimer)o;
162 Logger.warn("MIDlet timer created from [" + tm.name + "] still running");
163 tm.terminate();
164 } else {
165 Logger.debug("unrecognized Object [" + o.getClass().getName() + "]");
166 }
167 };
168 }
169
170 }