blob: 8cf5ae4166ee8d8d24fd3c03d55b94e8a33fb94b [file] [log] [blame]
Richard S. Hall930fecc2005-08-16 18:33:34 +00001/*
2 * Copyright 2005 The Apache Software Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17package org.apache.osgi.framework;
18
19import org.apache.osgi.framework.searchpolicy.R4SearchPolicy;
20import org.apache.osgi.framework.searchpolicy.R4Wire;
21import org.apache.osgi.framework.util.FelixConstants;
22import org.osgi.framework.Bundle;
23import org.osgi.framework.ServiceReference;
24
25class ServiceReferenceImpl implements ServiceReference
26{
27 private ServiceRegistrationImpl m_registration = null;
28 private Bundle m_bundle = null;
29
30 public ServiceReferenceImpl(ServiceRegistrationImpl reg, Bundle bundle)
31 {
32 m_registration = reg;
33 m_bundle = bundle;
34 }
35
36 protected ServiceRegistrationImpl getServiceRegistration()
37 {
38 return m_registration;
39 }
40
41 public Object getProperty(String s)
42 {
43 return m_registration.getProperty(s);
44 }
45
46 public String[] getPropertyKeys()
47 {
48 return m_registration.getPropertyKeys();
49 }
50
51 public Bundle getBundle()
52 {
53 return m_bundle;
54 }
55
56 public Bundle[] getUsingBundles()
57 {
58 return m_registration.getUsingBundles();
59 }
60
61 public boolean equals(Object obj)
62 {
63 try
64 {
65 ServiceReferenceImpl ref = (ServiceReferenceImpl) obj;
66 return ref.m_registration == m_registration;
67 }
68 catch (ClassCastException ex)
69 {
70 // Ignore and return false.
71 }
72 catch (NullPointerException ex)
73 {
74 // Ignore and return false.
75 }
76
77 return false;
78 }
79
80 public int hashCode()
81 {
82 if (m_registration.getReference() != null)
83 {
84 if (m_registration.getReference() != this)
85 {
86 return m_registration.getReference().hashCode();
87 }
88 return super.hashCode();
89 }
90 return 0;
91 }
92
93 public String toString()
94 {
95 String[] ocs = (String[]) getProperty("objectClass");
96 String oc = "[";
97 for(int i = 0; i < ocs.length; i++)
98 {
99 oc = oc + ocs[i];
100 if (i < ocs.length - 1)
101 oc = oc + ", ";
102 }
103 oc = oc + "]";
104 return oc;
105 }
106
107 public boolean isAssignableTo(Bundle requester, String className)
108 {
109 // Always return true if the requester is the same as the provider.
110 if (requester == m_bundle)
111 {
112 return true;
113 }
114
115 // Boolean flag.
116 boolean allow = true;
117 // Get the package.
118 String pkgName =
119 org.apache.osgi.moduleloader.Util.getClassPackage(className);
120 // Get package wiring from service provider and requester.
121 R4Wire requesterWire = R4SearchPolicy.getWire(
122 ((BundleImpl) requester).getInfo().getCurrentModule(), pkgName);
123 R4Wire providerWire = R4SearchPolicy.getWire(
124 ((BundleImpl) m_bundle).getInfo().getCurrentModule(), pkgName);
125
126 // There are three situations that may occur here:
127 // 1. The requester does not have a wire for the package.
128 // 2. The provider does not have a wire for the package.
129 // 3. Both have a wire for the package.
130 // For case 1, we do not filter the service reference since we
131 // assume that the bundle is using reflection or that it won't
132 // use that class at all since it does not import it. For
133 // case 2, we have to try to load the class from the class
134 // loader of the service object and then compare the class
135 // loaders to determine if we should filter the service
136 // refernce. In case 3, we simply compare the exporting
137 // modules from the package wiring to determine if we need
138 // to filter the service reference.
139
140 // Case 1: Always include service reference.
141 if (requesterWire == null)
142 {
143 // This is an intentional no-op.
144 }
145 // Case 2: Only include service reference if the service
146 // object uses the same class as the requester.
147 else if (providerWire == null)
148 {
149 try
150 {
151 // Load the class from the requesting bundle.
152 Class requestClass =
153 ((BundleImpl) requester).getInfo().getCurrentModule().getClassLoader()
154 .loadClass(className);
155 // Get the service registration and ask it to check
156 // if the service object is assignable to the requesting
157 // bundle's class.
158 allow = getServiceRegistration().isClassAccessible(requestClass);
159 }
160 catch (Exception ex)
161 {
162 // This should not happen, filter to be safe.
163 allow = false;
164 }
165 }
166 // Case 3: Include service reference if the wires have the
167 // same source module.
168 else
169 {
170 allow = providerWire.m_module.equals(requesterWire.m_module);
171 }
172
173 return allow;
174 }
175}