package org.csstudio.dal.spi;
import java.util.HashMap;
import java.util.Iterator;
import javax.naming.directory.DirContext;
import org.csstudio.dal.DynamicValueProperty;
import org.csstudio.dal.RemoteException;
import org.csstudio.dal.context.AbstractApplicationContext;
import org.csstudio.dal.context.LinkListener;
import org.csstudio.dal.context.PropertyFamily;
import org.csstudio.dal.impl.DefaultApplicationContext;
import org.csstudio.dal.proxy.AbstractPlug;
import org.csstudio.dal.simple.RemoteInfo;
public class DefaultPropertyFactoryBroker implements PropertyFactoryBroker {
private static DefaultPropertyFactoryBroker manager;
private final HashMap<String, PropertyFactory> factories = new HashMap<String, PropertyFactory>();
private String[] supportedTypes = null;
private String defaultPlugType=Plugs.SIMULATOR_PLUG_TYPE;
private AbstractApplicationContext ctx;
private LinkPolicy linkPolicy;
private PropertyFactoryService propertyFactoryService=null;
public static final synchronized DefaultPropertyFactoryBroker getInstance() {
if (manager == null) {
manager = new DefaultPropertyFactoryBroker();
final AbstractApplicationContext ctx = new DefaultApplicationContext("Default Property Factory Borker Context");
manager.initialize(ctx, LinkPolicy.ASYNC_LINK_POLICY);
}
return manager;
}
public static final DefaultPropertyFactoryBroker getInstance(final AbstractApplicationContext ctx, final LinkPolicy lp) {
if (ctx == null) {
return getInstance();
}
final DefaultPropertyFactoryBroker manager = new DefaultPropertyFactoryBroker();
manager.initialize(ctx, lp);
return manager;
}
private DefaultPropertyFactoryBroker() {
}
/**
* Return default plug type, which is used for all remote names, which does not
* explicitly declare plug or connection type.
*
* <p>
* By default (if not set) plug type equals to Simulator.
* </p>
*
* @return default plug type
*/
@Override
public String getDefaultPlugType() {
return defaultPlugType;
}
/**
* Sets default plug type, which is used for all remote names, which does not
* explicitly declare plug or connection type.
*
* <p>
* So far supported values are: EPICS, TINE, Simulator.
* By default (if not set) plug type equals to Simulator.
* </p>
*
* @param defautl plug type.
*/
@Override
public void setDefaultPlugType(final String plugType) {
defaultPlugType = plugType;
}
private PropertyFactory getPropertyFactory(String type) throws InstantiationException {
if (type==null || type.equals("null")) {
type=defaultPlugType;
}
synchronized (factories) {
PropertyFactory f = factories.get(type);
if (f != null) {
return f;
}
try {
PropertyFactoryService propertyFactoryService = getPropertyFactoryService();
f = propertyFactoryService.getPropertyFactory(ctx, linkPolicy, type);
factories.put(type, f);
} catch (final Throwable t) {
throw new InstantiationException(t.toString());
}
return f;
}
}
@Override
public String[] getSupportedPlugTypes() {
if (supportedTypes == null) {
supportedTypes = Plugs.getInstance(ctx.getConfiguration()).getPlugNames();
}
return supportedTypes;
}
@Override
public RemoteInfo asyncLinkProperty(final RemoteInfo name,
final Class<? extends DynamicValueProperty<?>> type, final LinkListener<?> l)
throws InstantiationException, RemoteException {
return getPropertyFactory(name.getPlugType()).asyncLinkProperty(name, type, l);
}
@Override
public RemoteInfo asyncLinkProperty(final String name,
final Class<? extends DynamicValueProperty<?>> type, final LinkListener<?> l)
throws InstantiationException, RemoteException {
return asyncLinkProperty(
RemoteInfo.fromString(name,RemoteInfo.DAL_TYPE_PREFIX+defaultPlugType),
type,
l);
}
@Override
public DynamicValueProperty<?> getProperty(final String uniqueName)
throws InstantiationException, RemoteException {
return getProperty(RemoteInfo.fromString(uniqueName,RemoteInfo.DAL_TYPE_PREFIX+defaultPlugType));
}
@Override
public DynamicValueProperty<?> getProperty(final RemoteInfo ri) throws InstantiationException, RemoteException {
String plugType = ri.getPlugType();
return getPropertyFactory(plugType).getProperty(ri);
}
@Override
public <P extends DynamicValueProperty<?>> P getProperty(final String uniqueName,
final Class<P> type,
final LinkListener<?> l) throws InstantiationException, RemoteException {
return getProperty(
RemoteInfo.fromString(uniqueName,RemoteInfo.DAL_TYPE_PREFIX+defaultPlugType),
type,
l);
}
@Override
public <P extends DynamicValueProperty<?>> P getProperty(final RemoteInfo ri,
final Class<P> type,
final LinkListener<?> l) throws InstantiationException, RemoteException {
return getPropertyFactory(ri.getPlugType()).getProperty(ri, type, l);
}
@Override
public PropertyFamily getPropertyFamily() {
// has no sense
return null;
}
public void destroy(final DynamicValueProperty<?> property) {
synchronized (factories) {
final Iterator<PropertyFactory> it = factories.values().iterator();
while (it.hasNext()) {
it.next().getPropertyFamily().destroy(property);
}
}
}
@Override
public AbstractApplicationContext getApplicationContext() {
return ctx;
}
@Override
public DirContext getDefaultDirectory() {
// has no sense
return null;
}
@Override
public LinkPolicy getLinkPolicy() {
return linkPolicy;
}
@Override
public AbstractPlug getPlug() {
// has no sense
return null;
}
@Override
public String getPlugType() {
// has no sense
return null;
}
@Override
public void initialize(final AbstractApplicationContext ctx, final LinkPolicy policy) {
this.ctx = ctx;
this.linkPolicy = policy;
}
@Override
public boolean isPlugShared() {
// has no sense
return false;
}
public void releaseAll() {
synchronized (factories) {
final Iterator<PropertyFactory> it = factories.values().iterator();
while (it.hasNext()) {
it.next().getPropertyFamily().destroyAll();
}
}
}
public void setPropertyFactoryService(final PropertyFactoryService propertyFactoryService) {
this.propertyFactoryService = propertyFactoryService;
}
public PropertyFactoryService getPropertyFactoryService() {
if (propertyFactoryService==null) {
propertyFactoryService= DefaultPropertyFactoryService.getPropertyFactoryService();
}
return propertyFactoryService;
}
}