EMMA Coverage Report (generated Sun Feb 05 10:43:15 CET 2012)
[all classes][de.uka.ipd.sdq.codegen.simucontroller.dockmodel]

COVERAGE SUMMARY FOR SOURCE FILE [DocksModel.java]

nameclass, %method, %block, %line, %
DocksModel.java0%   (0/4)0%   (0/28)0%   (0/590)0%   (0/126)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class DocksModel0%   (0/1)0%   (0/21)0%   (0/477)0%   (0/100)
<static initializer> 0%   (0/1)0%   (0/4)0%   (0/2)
DocksModel (BundleContext): void 0%   (0/1)0%   (0/33)0%   (0/10)
access$0 (): Logger 0%   (0/1)0%   (0/2)0%   (0/1)
access$1 (DocksModel, SimulationDockService, String): DockModel 0%   (0/1)0%   (0/5)0%   (0/1)
addDock (SimulationDockService): DockModel 0%   (0/1)0%   (0/5)0%   (0/1)
addDock (SimulationDockService, String): DockModel 0%   (0/1)0%   (0/38)0%   (0/7)
addListeners (): void 0%   (0/1)0%   (0/32)0%   (0/9)
createRemoteServiceListener (BundleContext): ServiceDiscoveryListener 0%   (0/1)0%   (0/6)0%   (0/1)
createServiceListener (): ServiceListener 0%   (0/1)0%   (0/5)0%   (0/1)
finalize (): void 0%   (0/1)0%   (0/14)0%   (0/5)
findDocksByDistance (boolean): List 0%   (0/1)0%   (0/2)0%   (0/1)
findExisitingDocks (): void 0%   (0/1)0%   (0/38)0%   (0/6)
getAllDocks (): Collection 0%   (0/1)0%   (0/15)0%   (0/2)
getBestFreeDock (): DockModel 0%   (0/1)0%   (0/7)0%   (0/2)
getDockById (String): DockModel 0%   (0/1)0%   (0/32)0%   (0/4)
getDockByURI (URI): DockModel 0%   (0/1)0%   (0/39)0%   (0/5)
getLocalDocks (): List 0%   (0/1)0%   (0/5)0%   (0/1)
getRemoteDocks (): List 0%   (0/1)0%   (0/5)0%   (0/1)
handleEvent (Event): void 0%   (0/1)0%   (0/128)0%   (0/28)
registerEventListener (): void 0%   (0/1)0%   (0/26)0%   (0/6)
removeDock (DockModel): void 0%   (0/1)0%   (0/36)0%   (0/7)
     
class DocksModel$10%   (0/1)0%   (0/2)0%   (0/18)0%   (0/7)
DocksModel$1 (DocksModel): void 0%   (0/1)0%   (0/6)0%   (0/2)
compare (DockModel, DockModel): int 0%   (0/1)0%   (0/12)0%   (0/5)
     
class DocksModel$20%   (0/1)0%   (0/3)0%   (0/74)0%   (0/18)
DocksModel$2 (DocksModel, BundleContext): void 0%   (0/1)0%   (0/9)0%   (0/2)
announceService (String, URI): void 0%   (0/1)0%   (0/55)0%   (0/13)
discardService (String, URI): void 0%   (0/1)0%   (0/10)0%   (0/3)
     
class DocksModel$30%   (0/1)0%   (0/2)0%   (0/21)0%   (0/6)
DocksModel$3 (DocksModel): void 0%   (0/1)0%   (0/6)0%   (0/2)
serviceChanged (ServiceEvent): void 0%   (0/1)0%   (0/15)0%   (0/4)

1package de.uka.ipd.sdq.codegen.simucontroller.dockmodel;
2 
3import java.util.Collection;
4import java.util.Collections;
5import java.util.Comparator;
6import java.util.HashMap;
7import java.util.Hashtable;
8import java.util.List;
9import java.util.Observable;
10import java.util.concurrent.PriorityBlockingQueue;
11 
12import org.apache.log4j.Logger;
13import org.osgi.framework.BundleContext;
14import org.osgi.framework.InvalidSyntaxException;
15import org.osgi.framework.ServiceEvent;
16import org.osgi.framework.ServiceListener;
17import org.osgi.framework.ServiceReference;
18import org.osgi.framework.ServiceRegistration;
19import org.osgi.service.event.Event;
20import org.osgi.service.event.EventConstants;
21import org.osgi.service.event.EventHandler;
22import org.osgi.util.tracker.ServiceTracker;
23 
24import ch.ethz.iks.r_osgi.RemoteOSGiService;
25import ch.ethz.iks.r_osgi.RemoteServiceReference;
26import ch.ethz.iks.r_osgi.URI;
27import ch.ethz.iks.r_osgi.service_discovery.ServiceDiscoveryListener;
28import de.uka.ipd.sdq.codegen.simucontroller.dockmodel.events.DockAddedEvent;
29import de.uka.ipd.sdq.codegen.simucontroller.dockmodel.events.DockDeletedEvent;
30import de.uka.ipd.sdq.simucomframework.simulationdock.SimulationDockService;
31 
32/**
33 * The dock model class is used to store the central model of the simulation docks. A simulation dock is an OSGi service capable of
34 * accepting a simulation bundle. It simulates the bundle informing is dock model via OSGi events of its progress. The dock model
35 * uses the events to synchronize its view. It also uses remote OSGi events to discover new remote docks.
36 * @author Steffen Becker
37 *
38 */
39public class DocksModel extends Observable implements EventHandler {
40        /** Logger of this class. */
41        private static final Logger logger = Logger.getLogger(DocksModel.class);
42 
43        /**
44         * A hashmap for mapping dock IDs to the respective dock models. Used when events arrive to retrieve the affected dock.
45         */
46        private HashMap<String,DockModel> clientDocks = new HashMap<String, DockModel>();
47 
48        /**
49         * A priority queue of available docks. Used in {@link getBestFreeDock} to retrieve the best available next dock.
50         */
51        private PriorityBlockingQueue<DockModel> freeDocks = new PriorityBlockingQueue<DockModel>(10,new Comparator<DockModel>(){
52 
53                /** Basis sorting strategy: Prefer remote docks over local docks
54                 * @param o1 First argument
55                 * @param o2 Second argument
56                 * @return The sort order of the arguments
57                 */
58                public int compare(DockModel o1, DockModel o2) {
59                        if (o1.isRemote())
60                                return -1;
61                        if (o2.isRemote())
62                                return 1;
63                        return 0;
64                }
65 
66        });
67 
68        /**
69         * The event listener registered with OSGi by this model
70         */
71        private ServiceRegistration eventListener = null;
72 
73        /**
74         * Context object for OSGi interaction
75         */
76        private BundleContext context = null;
77 
78        /**
79         * Listener for local dock service discoveries
80         */
81        private ServiceListener localServiceListener;
82 
83        /**
84         * Listener for remote dock discoveries
85         */
86        private ServiceRegistration remoteServiceListener;
87 
88        /**
89         * Constructor of the dock model
90         * @param context The bundle context of the plugin which contains the dock model. Used to interact with OSGi's event service and remote
91         * OSGi
92         */
93        public DocksModel(BundleContext context) {
94                this.context = context;
95                findExisitingDocks();
96                addListeners();
97                registerEventListener();
98        }
99 
100        /**
101         * Unregister the listener
102         * @see java.lang.Object#finalize()
103         */
104        @Override
105        protected void finalize() throws Throwable {
106                context.removeServiceListener(localServiceListener);
107                remoteServiceListener.unregister();
108                eventListener.unregister();
109                super.finalize();
110        }
111 
112 
113        /**
114         * Register the local and remote listener for discovering dock events
115         */
116        private void addListeners() {
117                try {
118                        localServiceListener = createServiceListener();
119                        context.addServiceListener(localServiceListener);
120 
121                        remoteServiceListener = context.registerService(
122                                        ServiceDiscoveryListener.class.getName(),
123                                        createRemoteServiceListener(context),
124                                        new Hashtable<String, String[]>());
125                } catch (Exception e) {
126                        throw new RuntimeException("Unable to register dock listners ",e);
127                }
128        }
129 
130        private ServiceDiscoveryListener createRemoteServiceListener(
131                        final BundleContext context) {
132                return new ServiceDiscoveryListener(){
133 
134                        public void announceService(String iface, URI uri) {
135                                ServiceReference sRef = context.getServiceReference(RemoteOSGiService.class.getName());
136                                ServiceTracker remoteService = new ServiceTracker(context,sRef,null);
137                                remoteService.open();
138                                RemoteOSGiService roserv = (RemoteOSGiService) remoteService.getService();
139                                RemoteServiceReference[] rserv;
140                                try {
141                                        rserv = roserv.connect(uri);
142                                } catch (Exception e) {
143                                        String msg = "Unable to connect to remote server ";
144                                        logger.error(msg, e);
145                                        throw new RuntimeException(msg,e);
146                                }
147// FIXME: Build-Eclipse and local Eclipse have a different opinion which Exceptions should be caught.
148// Thus, used general Exception.
149//                                } catch (RemoteOSGiException e) {
150//                                        e.printStackTrace();
151//                                        throw new RuntimeException("Unable to connect to remote server ",e);
152//                                }
153//                                catch (IOException e) {
154//                                        e.printStackTrace();
155//                                        throw new RuntimeException("Unable to connect to remote server ",e);
156//                                }
157                                SimulationDockService service = (SimulationDockService) roserv.getRemoteService(rserv[0]);
158                                DocksModel.this.addDock(service,uri.toString());
159                                remoteService.close();
160                        }
161 
162                        public void discardService(String iface, URI uri) {
163                                DockModel dock = DocksModel.this.getDockByURI(uri);
164                                DocksModel.this.removeDock(dock);
165                        }};
166        }
167 
168        private ServiceListener createServiceListener() {
169                return new ServiceListener(){
170 
171                        public void serviceChanged(ServiceEvent event) {
172                                if (event.getServiceReference().getProperty("objectClass").equals(SimulationDockService.class.getName())){
173                                        if (event.getType() == ServiceEvent.REGISTERED) {
174                                                // TODO
175                                        }
176                                        if (event.getType() == ServiceEvent.UNREGISTERING) {
177                                                // TODO
178                                        }
179                                }
180                        }
181 
182                };
183        }
184 
185        /** Called by service unregister events to remove the dock from this model
186         * @param dock The dock which has been removed externally
187         */
188        protected void removeDock(DockModel dock) {
189                synchronized(clientDocks){
190                        clientDocks.remove(dock.getID());
191                        if (freeDocks.contains(dock)) {
192                                freeDocks.remove(dock);
193                        } else {
194                                // TODO: Lost a busy dock....
195                        }
196                        setChanged();
197                        notifyObservers(new DockDeletedEvent(dock));
198                }
199        }
200 
201        /** Retrieve a dock status model by the docks URI. Returns null if the dock is unknown or a local dock.
202         * @param uri The URI of the dock to retrieve
203         * @return The requested dock or null if the dock does not exist or is local
204         */
205        protected DockModel getDockByURI(URI uri) {
206                synchronized(clientDocks){
207                        for (DockModel m : clientDocks.values()) {
208                                if (m.getRemoteMaschineURI() != null && m.getRemoteMaschineURI().equals(uri.toString())) {
209                                        return m;
210                                }
211                        }
212                }
213                return null;
214        }
215 
216        /** Initialise this dock model's status when this dock model is first initialised
217         */
218        private void findExisitingDocks() {
219                // Initially get all local Docks
220                try {
221                        ServiceReference[] services = context.getAllServiceReferences(SimulationDockService.class.getName(), null);
222                        for (ServiceReference ref : services) {
223                                // TODO: This does not track the services lifecyle :-(
224                                this.addDock((SimulationDockService) context.getService(ref));
225                        }
226                } catch (InvalidSyntaxException e1) {
227                        logger.error("Dock model status could not be initializd properly. Invalid filter expression used.", e1);
228                }
229        }
230 
231        /** Returns a collection of all docks currently known in this dock model
232         * @return A collection of all docks currently known in this dock model
233         */
234        public Collection<DockModel> getAllDocks() {
235                synchronized(clientDocks){
236                        return Collections.unmodifiableCollection(this.clientDocks.values());
237                }
238        }
239 
240        /** Gets the next best free dock from the list of unused docks. Waits for a dock to become available if all docks are busy.
241         * The dock is removed from the list of free docks.
242         *
243         * @return The next best dock available to process a request
244         * @throws InterruptedException Execption when the thread is terminated
245         */
246        public DockModel getBestFreeDock() throws InterruptedException {
247                DockModel result = freeDocks.take();
248                return result;
249        }
250 
251        /** Return a list of all local docks
252         * @return A list of local docks
253         */
254        public List<DockModel> getLocalDocks() {
255                return Collections.unmodifiableList(findDocksByDistance(false));
256        }
257 
258        /** Return a list of all remote docks
259         * @return A list of remote docks
260         */
261        public List<DockModel> getRemoteDocks() {
262                return Collections.unmodifiableList(findDocksByDistance(true));
263        }
264 
265        private List<DockModel> findDocksByDistance(boolean remote) {
266                return null;
267        }
268 
269        /**
270         * Method to handle OSGi Events sent by the SimulationDock to inform about
271         * status updates (non-Javadoc).
272         *
273         * The method is not intended to be called directly!
274         *
275         * @see org.osgi.service.event.EventHandler#handleEvent(org.osgi.service.event.Event)
276         */
277        public void handleEvent(Event event) {
278                String dockId = (String) event.getProperty("DOCK_ID");
279                DockModel dock = this.getDockById(dockId);
280                if (event.getTopic().endsWith("UPDATE_SIM_STATUS")) {
281                        dock.setPercentDone((Integer)event.getProperty("PERCENT_DONE"));
282                        dock.setSimTime((Double)event.getProperty("CURRENT_TIME"));
283                        dock.setMeasurementCount((Long)event.getProperty("MEASUREMENTS_TAKEN"));
284                }
285                if (event.getTopic().endsWith("DOCK_BUSY")) {
286                        dock.setIdle(false);
287                        synchronized(freeDocks){
288                                if (freeDocks.contains(dock)) {
289                                        freeDocks.remove(dock);
290                                }
291                        }
292                }
293                if (event.getTopic().endsWith("DOCK_IDLE")) {
294                        dock.setIdle(true);
295                        freeDocks.put(dock);
296                }
297                if (event.getTopic().endsWith("PERFORMED_STEP")) {
298                        dock.setIsStepping(false);
299                }
300                if (event.getTopic().endsWith("SIM_STARTED")) {
301                        dock.setStarted(true);
302                        dock.setIsSuspended(false);
303                }
304                if (event.getTopic().endsWith("SIM_STOPPED")) {
305                        dock.setStarted(false);
306                }
307                if (event.getTopic().endsWith("SIM_SUSPENDED")) {
308                        dock.setIsSuspended(true);
309                }
310                if (event.getTopic().endsWith("SIM_RESUMED")) {
311                        dock.setIsSuspended(false);
312                }
313                if (event.getTopic().endsWith("STARTED_STEP")) {
314                        dock.setIsStepping(true);
315                }
316        }
317 
318        /** Return the dock status model with of the dock with the given ID
319         * @param dockId ID of the dock to retrieve. The dock with the given ID has to exist
320         * @return The model of the requested dock
321         */
322        public DockModel getDockById(String dockId) {
323                synchronized (clientDocks) {
324                        if (!clientDocks.containsKey(dockId))
325                                throw new IllegalArgumentException("Dock model does not contain dock with ID "+dockId);
326                        return clientDocks.get(dockId);
327                }
328        }
329 
330        /** Registers this object as event listener for dock events raised by local and remote simulation docks
331         */
332        private void registerEventListener() {
333                String[] topics = new String[] { "de/uka/ipd/sdq/simucomframework/simucomdock/*" };
334                Hashtable<String, String[]> ht = new Hashtable<String, String[]>();
335                ht.put(EventConstants.EVENT_TOPIC, topics);
336                eventListener = context.registerService(
337                                EventHandler.class.getName(), this, ht);
338        }
339 
340        /**
341         * Adds a new dock. Called by discovery events of local docks.
342         * @param service The reference to the simulation dock's public interface
343         * @return A new dock status model representing the newly discovered dock
344         */
345        private DockModel addDock(SimulationDockService service) {
346                return addDock(service,null);
347        }
348 
349        /**
350         * Adds a new dock. Called by discovery events of remote docks.
351         * @param service The reference to the simulation dock's public interface
352         * @param remoteMaschineURI The URI of the remote service
353         * @return A new dock status model representing the newly discovered dock
354         */
355        private DockModel addDock(SimulationDockService service, String remoteMaschineURI) {
356                DockModel result = new DockModel(service,remoteMaschineURI);
357 
358                synchronized (clientDocks) {  // Only one thread my update the client dock list
359                        clientDocks.put(result.getID(),result);
360                        freeDocks.put(result);
361                        setChanged();
362                        notifyObservers(new DockAddedEvent(result));
363                }
364 
365                return result;
366        }
367 
368}

[all classes][de.uka.ipd.sdq.codegen.simucontroller.dockmodel]
EMMA 2.0.9414 (unsupported private build) (C) Vladimir Roubtsov