blob: 321b2adb6a3514c01da6feb9d68b4679a688ce94 [file] [log] [blame]
Marcel Offermans613a6202009-03-11 22:31:44 +00001/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19package org.apache.felix.das.util;
20
21
22import java.io.InputStream;
23import java.util.ArrayList;
24import java.util.Arrays;
25import java.util.Collection;
26import java.util.Dictionary;
Marcel Offermansb8f9bcb2011-04-11 20:46:19 +000027import java.util.HashSet;
Marcel Offermans613a6202009-03-11 22:31:44 +000028import java.util.List;
Marcel Offermansb8f9bcb2011-04-11 20:46:19 +000029import java.util.Set;
Marcel Offermans613a6202009-03-11 22:31:44 +000030
31import org.apache.felix.das.DriverAttributes;
32import org.apache.felix.das.Log;
33import org.osgi.framework.Bundle;
34import org.osgi.framework.BundleContext;
35import org.osgi.framework.BundleException;
36import org.osgi.framework.ServiceReference;
37import org.osgi.service.device.Constants;
38import org.osgi.service.device.DriverLocator;
39
40
41/**
42 * TODO: add javadoc
43 *
44 * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
45 */
46public class DriverLoader
47{
48
49 private final BundleContext m_context;
50
51 private final Log m_log;
52
53 public final static String DRIVER_LOCATION_PREFIX = "_DD_";
54
55 /**
56 * to keep track of all loaded drivers
57 */
58 private final List<ServiceReference> m_loadedDrivers;
59
60
61 public DriverLoader( Log log, BundleContext context )
62 {
63 m_log = log;
64 m_context = context;
65 m_loadedDrivers = new ArrayList<ServiceReference>();
66 }
67
68
69 @SuppressWarnings("all")
Marcel Offermansb8f9bcb2011-04-11 20:46:19 +000070 public Set<String> findDrivers( Collection<DriverLocator> locators, Dictionary dict )
Marcel Offermans613a6202009-03-11 22:31:44 +000071 {
Marcel Offermansb8f9bcb2011-04-11 20:46:19 +000072 final Set<String> list = new HashSet<String>();
Marcel Offermans613a6202009-03-11 22:31:44 +000073 for ( DriverLocator locator : locators )
74 {
75 list.addAll( findDrivers( locator, dict ) );
76 }
77
78 return list;
79 }
80
81
82 @SuppressWarnings("all")
83 private List<String> findDrivers( DriverLocator locator, Dictionary dict )
84 {
85 final List<String> list = new ArrayList<String>();
86 try
87 {
88 String[] ids = locator.findDrivers( dict );
89 if ( ids != null )
90 {
91 list.addAll( Arrays.asList( ids ) );
92 }
93 }
94 catch ( Exception e )
95 {
96 // ignore, will also frequently happen (?)
97 // m_log.error("findDrivers failed for: " + locator, e);
98 }
99
100 return list;
101 }
102
103
104 /**
105 * load all drivers that belong to the given driver Ids
106 *
107 * @param locator
108 * @param driverIds
109 */
110 public List<ServiceReference> loadDrivers( List<DriverLocator> locators, String[] driverIds )
111 {
112 List<ServiceReference> driverRefs = new ArrayList<ServiceReference>();
113
114 for ( String driverId : driverIds )
115 {
116 driverRefs.addAll( loadDriver( locators, driverId ) );
117 }
118
119 return driverRefs;
120 }
121
122
123 private List<ServiceReference> loadDriver( List<DriverLocator> locators, String driverId )
124 {
125 List<ServiceReference> driverRefs = new ArrayList<ServiceReference>();
126
127 for ( DriverLocator driverLocator : locators )
128 {
129 List<ServiceReference> drivers = loadDriver( driverLocator, driverId );
130 driverRefs.addAll( drivers );
131 if ( drivers.size() > 0 )
132 {
133 break;
134 }
135 }
136
137 return driverRefs;
138 }
139
140
141 private List<ServiceReference> loadDriver( DriverLocator locator, String driverId )
142 {
143 List<ServiceReference> driverRefs = new ArrayList<ServiceReference>();
144 try
145 {
146 InputStream in = locator.loadDriver( driverId );
147 // System.out.println(driverId + ", " + locator + " returned: " +
148 // in);
149 Bundle driverBundle = m_context.installBundle( DRIVER_LOCATION_PREFIX + driverId, in );
150
151 driverBundle.start();
152
153 ServiceReference[] refs = driverBundle.getRegisteredServices();
154
155 driverRefs.addAll( Arrays.asList( refs ) );
156 // keep track of them locally
157 m_loadedDrivers.addAll( Arrays.asList( refs ) );
158
159 }
160 catch ( Throwable t )
161 {
162 // ignore, this will happen frequently, if there are multiple
163 // locators
164 }
165 return driverRefs;
166 }
167
168
169 public void unload( DriverAttributes finalDriver )
170 {
171
172 ServiceReference finalRef = null;
173 if ( finalDriver != null )
174 {
175 finalRef = finalDriver.getReference();
176 m_log.debug( "unloading all except: " + finalRef.getProperty( Constants.DRIVER_ID ) );
177 }
178 for ( ServiceReference ref : m_loadedDrivers )
179 {
180 if ( !ref.equals( finalRef ) )
181 {
182 try
183 {
184 m_log.debug( "uninstalling: " + ref.getProperty( Constants.DRIVER_ID ) );
185 ref.getBundle().uninstall();
186 }
187 catch ( BundleException e )
188 {
189 m_log.warning( "unable to uninstall: " + ref.getProperty( Constants.DRIVER_ID ) );
190 }
191 }
192 }
193 }
194}