blob: 5b3c853a0e9712b85203f41ebfb5bf7bfea8da0f [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.felix.ipojo.handler.temporal;
import java.lang.reflect.Array;
import org.apache.felix.ipojo.FieldInterceptor;
import org.apache.felix.ipojo.util.DependencyModel;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Filter;
import org.osgi.framework.ServiceReference;
/**
* Temporal dependency.
* A temporal dependency waits (block) for the availability of the service.
* If no provider arrives in the specified among of time, a runtime exception is thrown.
* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
*/
public class TemporalDependency extends DependencyModel implements FieldInterceptor {
/**
* Timeout.
*/
private long m_timeout;
/**
* Constructor.
* @param spec : service specification
* @param agg : is the dependency aggregate ?
* @param filter : LDAP filter
* @param context : service context
* @param timeout : timeout
* @param handler : Handler managing this dependency
*/
public TemporalDependency(Class spec, boolean agg, Filter filter, BundleContext context, long timeout, TemporalHandler handler) {
super(spec, agg, true, filter, null, DependencyModel.DYNAMIC_BINDING_POLICY, context, handler);
this.m_timeout = timeout;
}
/**
* The dependency has been reconfigured.
* @param arg0 : new service references
* @param arg1 : old service references
* @see org.apache.felix.ipojo.util.DependencyModel#onDependencyReconfiguration(org.osgi.framework.ServiceReference[], org.osgi.framework.ServiceReference[])
*/
public void onDependencyReconfiguration(ServiceReference[] arg0, ServiceReference[] arg1) {
throw new UnsupportedOperationException("Reconfiguration not yet supported");
}
/**
* A provider arrives.
* @param arg0 : service reference of the new provider.
* @see org.apache.felix.ipojo.util.DependencyModel#onServiceArrival(org.osgi.framework.ServiceReference)
*/
public void onServiceArrival(ServiceReference arg0) {
// Notify if a thread is waiting.
synchronized (this) {
notifyAll();
}
}
/**
* A provider leaves.
* Nothing to do.
* @param arg0 : leaving service references.
* @see org.apache.felix.ipojo.util.DependencyModel#onServiceDeparture(org.osgi.framework.ServiceReference)
*/
public synchronized void onServiceDeparture(ServiceReference arg0) { }
/**
* The code require a value of the monitored field.
* If providers are available, the method return service object(s) immediately.
* Else, the thread is blocked until an arrival. If no provider arrives during
* the among of time specified, the method throws a Runtime Exception.
* @param arg0 : POJO instance asking for the service
* @param arg1 : field name
* @param arg2 : previous value
* @return the object to inject.
* @see org.apache.felix.ipojo.FieldInterceptor#onGet(java.lang.Object, java.lang.String, java.lang.Object)
*/
public synchronized Object onGet(Object arg0, String arg1, Object arg2) {
ServiceReference[] refs = getServiceReferences();
if (refs != null) {
// Immediate return.
if (isAggregate()) {
Object[] svc = (Object[]) Array.newInstance(getSpecification(), refs.length);
for (int i = 0; i < svc.length; i++) {
svc[i] = getService(refs[i]);
}
return svc;
} else {
return getService(refs[0]);
}
} else {
// Begin to wait ...
long enter = System.currentTimeMillis();
boolean exhausted = false;
ServiceReference ref = null;
synchronized (this) {
while (getServiceReference() == null && ! exhausted) {
try {
wait(1);
} catch (InterruptedException e) {
// We was interrupted ....
} finally {
long end = System.currentTimeMillis();
exhausted = (end - enter) > m_timeout;
}
}
}
// Check
if (exhausted) {
// Timeout, throw an exception
throw new RuntimeException("Service " + getSpecification().getName() + " unavailable : timeout");
} else {
ref = getServiceReference();
if (isAggregate()) {
Object[] svc = (Object[]) Array.newInstance(getSpecification(), 1);
svc[0] = ref;
return svc[0];
} else {
return getService(ref);
}
}
}
}
/**
* The monitored field receives a value.
* Nothing to do.
* @param arg0 : POJO setting the value.
* @param arg1 : field name
* @param arg2 : received value
* @see org.apache.felix.ipojo.FieldInterceptor#onSet(java.lang.Object, java.lang.String, java.lang.Object)
*/
public void onSet(Object arg0, String arg1, Object arg2) { }
}