blob: ee202843c2e3bdd26512460f8885e04c138d4749 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 1997-2009 by ProSyst Software GmbH
* http://www.prosyst.com
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* ProSyst Software GmbH - initial API and implementation
*******************************************************************************/
package org.eclipse.equinox.internal.ds;
import org.eclipse.equinox.internal.ds.impl.ComponentInstanceImpl;
import org.eclipse.equinox.internal.ds.model.ServiceComponentProp;
import org.eclipse.osgi.util.NLS;
import org.osgi.framework.*;
import org.osgi.service.component.ComponentConstants;
import org.osgi.service.component.ComponentException;
import org.osgi.service.log.LogService;
/**
* @author Stoyan Boshev
* @author Pavlin Dobrev
* @version 1.2
*/
final class ServiceReg implements ServiceFactory {
static boolean dontDisposeInstances = true;
// tracking the instance usage and re-instantiation
private int useCount = 0;
private ComponentInstanceImpl instance;
// model
private ServiceComponentProp scp;
static {
String tmp = Activator.bc.getProperty("equinox.scr.dontDisposeInstances"); //$NON-NLS-1$
dontDisposeInstances = (tmp != null) ? !tmp.equalsIgnoreCase("false") : true; //$NON-NLS-1$
}
ServiceReg(ServiceComponentProp scp, ComponentInstanceImpl instance) {
this.scp = scp;
this.instance = instance;
}
// ServiceFactory.getService method.
public Object getService(Bundle bundle, ServiceRegistration registration) {
try {
if (instance == null) {
instance = InstanceProcess.staticRef.buildComponent(bundle, scp, null, false);
//instance could be null if the component is already disposed
if (instance == null) {
return null;
}
}
synchronized (this) {
useCount++;
}
if (Activator.DEBUG) {
Activator.log.debug("ServiceReg.getService(): service '" + scp.name + "' is used " + Integer.toString(useCount) + " time(s), object = " + instance.getInstance(), null); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
return instance.getInstance();
} catch (Exception e) {
if (!(e instanceof ComponentException)) {
Activator.log(null, LogService.LOG_ERROR, NLS.bind(Messages.CANNOT_CREATE_INSTANCE, scp.name), e);
return null;
}
throw (ComponentException) e;
}
}
// ServiceFactory.ungetService method.
public void ungetService(Bundle bundle, ServiceRegistration registration, Object service) {
boolean shallDispose = false;
synchronized (this) {
useCount--;
if (useCount == 0) {
shallDispose = true;
}
}
if (shallDispose) {
if (!dontDisposeInstances && !scp.serviceComponent.immediate) {
//dispose instance only if disposing is allowed and the component is not immediate one.
//Immediate components are custom case - according to me, their instances should not be disposed
// because they are probably needed during the whole component's life
if (Activator.DEBUG) {
Activator.log.debug("ServiceReg.ungetService(): service '" + scp.name + "' no longer used, disposing object = " + service, null); //$NON-NLS-1$ //$NON-NLS-2$
}
// dispose only the instance - don't dispose the component
// itself!
scp.disposeObj(service, ComponentConstants.DEACTIVATION_REASON_UNSPECIFIED);
// delete the instance so it can be garbage collected!
instance = null;
} else {
if (Activator.DEBUG) {
Activator.log.debug("ServiceReg.ungetService(): service '" + scp.name + "' is used " + Integer.toString(useCount) + " time(s)", null); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
}
} else {
if (useCount < 0) {
Activator.log(null, LogService.LOG_WARNING, "ServiceReg.ungetService(): " + NLS.bind(Messages.SERVICE_USAGE_COUNT, scp.name, Integer.toString(useCount)), new Exception("Debug callstack")); //$NON-NLS-1$ //$NON-NLS-2$
} else if (Activator.DEBUG) {
Activator.log.debug("ServiceReg.ungetService(): service '" + scp.name + "' is used " + Integer.toString(useCount) + " time(s)", null); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
}
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#toString()
*/
public String toString() {
return scp.name + " Service Registration"; //$NON-NLS-1$
}
}