[Bug 303523] LTTng/TMF udpates:
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf / src / org / eclipse / linuxtools / tmf / component / TmfProvider.java
1 /*******************************************************************************
2 * Copyright (c) 2009, 2010 Ericsson
3 *
4 * All rights reserved. This program and the accompanying materials are
5 * made available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
8 *
9 * Contributors:
10 * Francois Chouinard - Initial API and implementation
11 *******************************************************************************/
12
13 package org.eclipse.linuxtools.tmf.component;
14
15 import java.lang.reflect.Array;
16 import java.util.Vector;
17
18 import org.eclipse.linuxtools.tmf.event.TmfData;
19 import org.eclipse.linuxtools.tmf.request.ITmfRequestHandler;
20 import org.eclipse.linuxtools.tmf.request.TmfDataRequest;
21
22 /**
23 * <b><u>TmfProvider</u></b>
24 * <p>
25 * The TmfProvider<T> is a provider for a data of type <T>.
26 * <p>
27 * This abstract class implements the housekeeking methods to register/
28 * deregister the event provider and to handle generically the event requests.
29 * <p>
30 * The concrete class can either re-implement processRequest() entirely or
31 * just implement the hooks (initializeContext() and getNext()).
32 * <p>
33 * TODO: Add support for providing multiple data types.
34 */
35 public abstract class TmfProvider<T extends TmfData> extends TmfComponent implements ITmfRequestHandler<T> {
36
37 private Class<T> fType;
38
39 // ------------------------------------------------------------------------
40 // Constructors (enforce that a type be supplied)
41 // ------------------------------------------------------------------------
42
43 @SuppressWarnings("unused")
44 private TmfProvider() {
45 }
46
47 @SuppressWarnings("unused")
48 private TmfProvider(TmfProvider<T> other) {
49 }
50
51 protected TmfProvider(Class<T> type) {
52 fType = type;
53 register();
54 }
55
56 @Override
57 public void register() {
58 super.register();
59 TmfProviderManager.register(fType, this);
60 }
61
62 @Override
63 public void deregister() {
64 TmfProviderManager.deregister(fType, this);
65 super.deregister();
66 }
67
68 // ------------------------------------------------------------------------
69 // ITmfRequestHandler
70 // ------------------------------------------------------------------------
71
72 // TODO: Request coalescing, filtering, result dispatching
73
74 public void processRequest(final TmfDataRequest<T> request, boolean waitForCompletion) {
75
76 //Process the request
77 processDataRequest(request);
78
79 // Wait for completion if needed
80 if (waitForCompletion) {
81 request.waitForCompletion();
82 }
83 }
84
85 protected void processDataRequest(final TmfDataRequest<T> request) {
86
87 // Process the request
88 Thread thread = new Thread() {
89
90 @Override
91 public void run() {
92
93 // Extract the generic information
94 int blockSize = request.getBlockize();
95 int nbRequested = request.getNbRequested();
96
97 // Create the result buffer
98 Vector<T> result = new Vector<T>();
99 int nbRead = 0;
100
101 // Initialize the execution
102 ITmfContext context = setContext(request);
103
104 // Get the ordered events
105 T data = getNext(context);
106 while (data != null && !request.isCancelled() && nbRead < nbRequested && !isCompleted(request, data))
107 {
108 result.add(data);
109 if (++nbRead % blockSize == 0) {
110 pushData(request, result);
111 }
112 // To avoid an unnecessary read passed the last data requested
113 if (nbRead < nbRequested)
114 data = getNext(context);
115 }
116 pushData(request, result);
117 request.done();
118 }
119 };
120 thread.start();
121 }
122
123 /**
124 * Format the result data and forwards it to the requester.
125 * Note: after handling, the data is *removed*.
126 *
127 * @param request
128 * @param data
129 */
130 @SuppressWarnings("unchecked")
131 private void pushData(TmfDataRequest<T> request, Vector<T> data) {
132 synchronized(request) {
133 if (!request.isCompleted()) {
134 T[] result = (T[]) Array.newInstance(fType, data.size());
135 data.toArray(result);
136 request.setData(result);
137 request.handleData();
138 data.removeAllElements();
139 }
140 }
141 }
142
143 /**
144 * Initialize the provider based on the request. The context is
145 * application specific and will be updated by getNext().
146 *
147 * @param request
148 * @return
149 */
150 public abstract ITmfContext setContext(TmfDataRequest<T> request);
151
152 /**
153 * Return the next piece of data based on the context supplied. The context
154 * would typically be updated for the subsequent read.
155 *
156 * @param context
157 * @return
158 */
159 public abstract T getNext(ITmfContext context);
160
161 /**
162 * Checks if the data meets the request completion criteria.
163 *
164 * @param request
165 * @param data
166 * @return
167 */
168 public abstract boolean isCompleted(TmfDataRequest<T> request, T data);
169
170 }
This page took 0.038798 seconds and 5 git commands to generate.