blob: fa0d90ad38e054eb208b7004998f8c31c8e043ef [file] [log] [blame]
Felix Meschbergerefb2d082008-08-19 13:18:47 +00001/*
2* Licensed to the Apache Software Foundation (ASF) under one or more
3* contributor license agreements. See the NOTICE file distributed with
4* this work for additional information regarding copyright ownership.
5* The ASF licenses this file to You under the Apache License, Version 2.0
6* (the "License"); you may not use this file except in compliance with
7* the License. You may obtain a copy of the License at
8*
9* http://www.apache.org/licenses/LICENSE-2.0
10*
11* Unless required by applicable law or agreed to in writing, software
12* distributed under the License is distributed on an "AS IS" BASIS,
13* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14* See the License for the specific language governing permissions and
15* limitations under the License.
16*/
17package org.apache.felix.shell.remote;
18
19
20import org.apache.felix.shell.ShellService;
21import org.osgi.framework.*;
22import org.osgi.service.log.LogService;
23
24
25/**
26 * Implements a mediator pattern class for services from the OSGi container.
27 * <p/>
28 *
29 * @author Dieter Wimberger (wimpi)
30 */
31class ServiceMediator
32{
33
34 private BundleContext m_BundleContext;
35
36 private ShellService m_FelixShellService;
37 private Latch m_FelixShellServiceLatch;
38
39 private LogService m_LogService;
40 private Latch m_LogServiceLatch;
41
42
43 /**
44 * Returns a reference to the <tt>ShellService</tt> (Felix).
45 *
46 * @param wait time in milliseconds to wait for the reference if it isn't available.
47 * @return the reference to the <tt>ShellService</tt> as obtained from the OSGi service layer.
48 */
49 public ShellService getFelixShellService( long wait )
50 {
51 try
52 {
53 if ( wait < 0 )
54 {
55 m_FelixShellServiceLatch.acquire();
56 }
57 else if ( wait > 0 )
58 {
59 m_FelixShellServiceLatch.attempt( wait );
60 }
61 }
62 catch ( InterruptedException e )
63 {
64 e.printStackTrace( System.err );
65 }
66
67 return m_FelixShellService;
68 }//getFelixShellService
69
70
71 public LogService getLogServiceLatch( long wait )
72 {
73 try
74 {
75 if ( wait < 0 )
76 {
77 m_LogServiceLatch.acquire();
78 }
79 else if ( wait > 0 )
80 {
81 m_LogServiceLatch.attempt( wait );
82 }
83 }
84 catch ( InterruptedException e )
85 {
86 e.printStackTrace( System.err );
87 }
88 return m_LogService;
89 }//getLogService
90
91
92 public void info( String msg )
93 {
94 if ( m_LogService != null )
95 {
96 m_LogService.log( LogService.LOG_INFO, msg );
97 }
98 else
99 {
100 sysout( msg );
101 }
102 }//info
103
104
105 public void error( String msg, Throwable t )
106 {
107 if ( m_LogService != null )
108 {
109 m_LogService.log( LogService.LOG_ERROR, msg, t );
110 }
111 else
112 {
113 syserr( msg, t );
114 }
115 }//error
116
117
118 public void error( String msg )
119 {
120 if ( m_LogService != null )
121 {
122 m_LogService.log( LogService.LOG_ERROR, msg );
123 }
124 else
125 {
126 syserr( msg, null );
127 }
128 }//error
129
130
131 public void debug( String msg )
132 {
133 if ( m_LogService != null )
134 {
135 m_LogService.log( LogService.LOG_DEBUG, msg );
136 }
137 else
138 {
139 sysout( msg );
140 }
141 }//debug
142
143
144 public void warn( String msg )
145 {
146 if ( m_LogService != null )
147 {
148 m_LogService.log( LogService.LOG_WARNING, msg );
149 }
150 else
151 {
152 syserr( msg, null );
153 }
154 }//warn
155
156
157 private void sysout( String msg )
158 {
159 //Assemble String
160 StringBuffer sbuf = new StringBuffer();
161 Bundle b = m_BundleContext.getBundle();
162 sbuf.append( b.getHeaders().get( Constants.BUNDLE_NAME ) );
163 sbuf.append( " [" );
164 sbuf.append( b.getBundleId() );
165 sbuf.append( "] " );
166 sbuf.append( msg );
167 System.out.println( sbuf.toString() );
168 }//sysout
169
170
171 private void syserr( String msg, Throwable t )
172 {
173 //Assemble String
174 StringBuffer sbuf = new StringBuffer();
175 Bundle b = m_BundleContext.getBundle();
176 sbuf.append( b.getHeaders().get( Constants.BUNDLE_NAME ) );
177 sbuf.append( " [" );
178 sbuf.append( b.getBundleId() );
179 sbuf.append( "] " );
180 sbuf.append( msg );
181 System.err.println( sbuf.toString() );
182 if ( t != null )
183 {
184 t.printStackTrace( System.err );
185 }
186 }//logToSystem
187
188
189 /**
190 * Activates this mediator to start tracking the required services using the
191 * OSGi service layer.
192 *
193 * @param bc the bundle's context.
194 * @return true if activated successfully, false otherwise.
195 */
196 public boolean activate( BundleContext bc )
197 {
198 //get the context
199 m_BundleContext = bc;
200
201 m_FelixShellServiceLatch = createWaitLatch();
202 m_LogServiceLatch = createWaitLatch();
203
204 //prepareDefinitions listener
205 ServiceListener serviceListener = new ServiceListenerImpl();
206
207 //prepareDefinitions the filter
208 String filter = "(|(objectclass=" + ShellService.class.getName() + ")" + "(objectclass="
209 + LogService.class.getName() + "))";
210
211 try
212 {
213 //add the listener to the bundle context.
214 bc.addServiceListener( serviceListener, filter );
215
216 //ensure that already registered Service instances are registered with
217 //the manager
218 ServiceReference[] srl = bc.getServiceReferences( null, filter );
219 for ( int i = 0; srl != null && i < srl.length; i++ )
220 {
221 serviceListener.serviceChanged( new ServiceEvent( ServiceEvent.REGISTERED, srl[i] ) );
222 }
223 }
224 catch ( InvalidSyntaxException ex )
225 {
226 ex.printStackTrace( System.err );
227 return false;
228 }
229 return true;
230 }//activate
231
232
233 /**
234 * Deactivates this mediator, nulling out all references.
235 * If called when the bundle is stopped, the framework should actually take
236 * care of unregistering the <tt>ServiceListener</tt>.
237 */
238 public void deactivate()
239 {
240 m_FelixShellService = null;
241 m_FelixShellServiceLatch = null;
242 m_BundleContext = null;
243 }//deactivate
244
245
246 /**
247 * Creates a simple wait latch to be used for the mechanism that allows entities
248 * in the bundles to wait for references.
249 *
250 * @return a new Latch instance.
251 */
252 private Latch createWaitLatch()
253 {
254 return new Latch();
255 }//createWaitLatch
256
257 /**
258 * The <tt>ServiceListener</tt> implementation.
259 */
260 private class ServiceListenerImpl implements ServiceListener
261 {
262
263 public void serviceChanged( ServiceEvent ev )
264 {
265 ServiceReference sr = ev.getServiceReference();
266 Object o = null;
267 switch ( ev.getType() )
268 {
269 case ServiceEvent.REGISTERED:
270 o = m_BundleContext.getService( sr );
271 if ( o == null )
272 {
273 return;
274 }
275 else if ( o instanceof ShellService )
276 {
277 m_FelixShellService = ( ShellService ) o;
278 m_FelixShellServiceLatch.release();
279 }
280 else if ( o instanceof LogService )
281 {
282 m_LogService = ( LogService ) o;
283 m_LogServiceLatch.release();
284 }
285 else
286 {
287 m_BundleContext.ungetService( sr );
288 }
289 break;
290 case ServiceEvent.UNREGISTERING:
291 o = m_BundleContext.getService( sr );
292 if ( o == null )
293 {
294 return;
295 }
296 else if ( o instanceof ShellService )
297 {
298 m_FelixShellService = null;
299 m_FelixShellServiceLatch = createWaitLatch();
300 }
301 else if ( o instanceof LogService )
302 {
303 m_LogService = null;
304 m_LogServiceLatch = createWaitLatch();
305 }
306 else
307 {
308 m_BundleContext.ungetService( sr );
309 }
310 break;
311 }
312 }
313 }//inner class ServiceListenerImpl
314
315 public static long WAIT_UNLIMITED = -1;
316 public static long NO_WAIT = 0;
317
318}//class ServiceMediator