/*-
* Copyright © 2009 Diamond Light Source Ltd.
*
* This file is part of GDA.
*
* GDA is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License version 3 as published by the Free
* Software Foundation.
*
* GDA is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along
* with GDA. If not, see <http://www.gnu.org/licenses/>.
*/
package uk.ac.gda.dal;
import java.util.Properties;
import javax.naming.NamingException;
import javax.naming.directory.DirContext;
import org.csstudio.dal.DoubleProperty;
import org.csstudio.dal.LongProperty;
import org.csstudio.dal.NumericPropertyCharacteristics;
import org.csstudio.dal.PropertyCharacteristics;
import org.csstudio.dal.RemoteException;
import org.csstudio.dal.SimpleProperty;
import org.csstudio.dal.context.AbstractApplicationContext;
import org.csstudio.dal.context.ConnectionException;
import org.csstudio.dal.device.AbstractDevice;
import org.csstudio.dal.impl.PropertyUtilities;
import org.csstudio.dal.proxy.AbstractPlug;
import org.csstudio.dal.proxy.DeviceProxy;
import org.csstudio.dal.proxy.DirectoryProxy;
import org.csstudio.dal.proxy.PropertyProxy;
import org.csstudio.dal.simple.RemoteInfo;
import org.epics.css.dal.directory.Attributes;
import org.epics.css.dal.directory.DirectoryUtilities;
import uk.ac.gda.dal.propproxy.DoublePropertyProxyImpl;
import uk.ac.gda.dal.propproxy.HighLimitPropertyProxyImpl;
import uk.ac.gda.dal.propproxy.LongPropertyProxyImpl;
import uk.ac.gda.dal.propproxy.LowLimitPropertyProxyImpl;
import uk.ac.gda.dal.propproxy.MoveByPropertyProxyImpl;
import uk.ac.gda.dal.propproxy.OffsetPropertyProxyImpl;
import uk.ac.gda.dal.propproxy.PropertyProxyImpl;
import uk.ac.gda.dal.propproxy.StopPropertyProxyImpl;
import uk.ac.gda.dal.propproxy.StringPropertyProxyImpl;
import uk.ac.gda.dal.propproxy.StringScannableStatusPropertyProxyImpl;
import uk.ac.gda.dal.propproxy.UnitsPropertyProxyImpl;
import com.cosylab.naming.URIName;
public class GdaPlug extends AbstractPlug {
public static final String PLUG_TYPE = "GDA";
public static final String DEFAULT_AUTHORITY = "DEFAULT";
public static final String SCHEME_SUFFIX = "GDA";
private static GdaPlug instance;
private DirContext gdaContext;
protected GdaPlug(Properties configuration) {
super(configuration);
}
public GdaPlug(AbstractApplicationContext ctx) {
super(ctx);
}
public static GdaPlug getInstance() {
return getInstance((Properties) null);
}
public static synchronized GdaPlug getInstance(Properties conf) {
if (instance == null)
instance = new GdaPlug(conf);
return instance;
}
public static synchronized GdaPlug getInstance(AbstractApplicationContext ctx) {
return new GdaPlug(ctx);
}
@Override
protected DirectoryProxy createNewDirectoryProxy(String uniqueName) throws ConnectionException {
throw new RuntimeException("Error in factory implementation, PropertyProxy must be created first.");
}
@Override
protected Class<? extends AbstractDevice> getDeviceImplementationClass(String uniqueDeviceName) {
throw new UnsupportedOperationException("Devices not supported");
}
@Override
protected Class<? extends DeviceProxy<?>> getDeviceProxyImplementationClass(String uniqueDeviceName) throws RemoteException {
throw new UnsupportedOperationException("Devices not supported");
}
@Override
public String getPlugType() {
return PLUG_TYPE;
}
@Override
public Class<? extends SimpleProperty<?>> getPropertyImplementationClass(Class<? extends SimpleProperty<?>> type, String propertyName) throws RemoteException {
if (type == null)
type = DoubleProperty.class;
Class<? extends SimpleProperty<?>> impl = super.getPropertyImplementationClass(type, propertyName);
if (impl == null)
return PropertyUtilities.getImplementationClass(type);
return impl;
}
@Override
protected Class<? extends SimpleProperty<?>> getPropertyImplementationClass(String uniquePropertyName) throws RemoteException {
throw new RuntimeException("Unsupported property type.");
}
@Override
protected Class<? extends PropertyProxy<?, ?>> getPropertyProxyImplementationClass(String uniquePropertyName) throws RemoteException {
return null;
}
@Override
public Class<? extends PropertyProxy<?,?>> getPropertyProxyImplementationClass(Class<? extends SimpleProperty<?>> type, Class<? extends SimpleProperty<?>> implType, String propertyName) throws RemoteException {
Class<? extends PropertyProxy<?,?>> impl = super.getPropertyProxyImplementationClass(type, implType, propertyName);
if (impl == null) {
int index = propertyName.lastIndexOf(".");
if (index != -1) {
String methodName = propertyName.substring(index + 1);
if (methodName.equals("isBusy"))
return StringScannableStatusPropertyProxyImpl.class;
if (methodName.equals("position"))
return DoublePropertyProxyImpl.class;
if (methodName.equals("strPos"))
return StringPropertyProxyImpl.class;
if (methodName.equals("stop"))
return StopPropertyProxyImpl.class;
if (methodName.equals("lowlimit"))
return LowLimitPropertyProxyImpl.class;
if (methodName.equals("highlimit"))
return HighLimitPropertyProxyImpl.class;
if (methodName.equals("userunits"))
return UnitsPropertyProxyImpl.class;
if (methodName.equals("moveby"))
return MoveByPropertyProxyImpl.class;
if (methodName.equals("offset"))
return OffsetPropertyProxyImpl.class;
}
if (type != null) {
if (type.equals(DoubleProperty.class))
return DoublePropertyProxyImpl.class;
else if (type.equals(LongProperty.class))
return LongPropertyProxyImpl.class;
}
return StringPropertyProxyImpl.class;
}
return impl;
}
@Override
public void releaseInstance() throws Exception {
// noop, since it is a singleton
}
@Override
public DirContext getDefaultDirectory() {
try {
DirContext initialContext = DirectoryUtilities.getInitialContext();
URIName name = new URIName(RemoteInfo.DAL_TYPE_PREFIX + SCHEME_SUFFIX, null, null, null);
URIName nameS = (URIName) name.getPrefix(1);
Object simContext = initialContext.lookup(nameS);
if (simContext == null)
gdaContext = (DirContext) initialContext.createSubcontext(nameS);
else
gdaContext = (DirContext) simContext;
// bind proxy implementations
URIName ppi = new URIName(null, DEFAULT_AUTHORITY, "PropertyProxyImpl", null);
Attributes characteristics = new org.epics.css.dal.directory.Attributes();
characteristics.put(PropertyCharacteristics.C_DESCRIPTION, "Simulated Property");
characteristics.put(PropertyCharacteristics.C_POSITION, new Double(0));
characteristics.put(PropertyCharacteristics.C_PROPERTY_TYPE, "property");
characteristics.put(NumericPropertyCharacteristics.C_RESOLUTION, 0xFFFF);
characteristics.put(NumericPropertyCharacteristics.C_SCALE_TYPE, "linear");
characteristics.put(NumericPropertyCharacteristics.C_UNITS, "amper");
gdaContext.bind(ppi, new PropertyProxyImpl<Object>(ppi.toString(), instance), characteristics);
ppi = new URIName(null, DEFAULT_AUTHORITY, "DoublePropertyPropertyImpl", null);
Attributes characteristicsD = new org.epics.css.dal.directory.Attributes(); //TODO Attribute from Dal Simulator plugin
characteristicsD.put(PropertyCharacteristics.C_DESCRIPTION, "Simulated Property");
characteristicsD.put(PropertyCharacteristics.C_POSITION, new Double(0));
characteristicsD.put(PropertyCharacteristics.C_PROPERTY_TYPE, "property");
characteristicsD.put(NumericPropertyCharacteristics.C_RESOLUTION, 0xFFFF);
characteristicsD.put(NumericPropertyCharacteristics.C_SCALE_TYPE, "linear");
characteristicsD.put(NumericPropertyCharacteristics.C_UNITS, "amper");
characteristicsD.put(NumericPropertyCharacteristics.C_FORMAT, "%.4f");
characteristicsD.put(NumericPropertyCharacteristics.C_GRAPH_MAX, new Double(10));
characteristicsD.put(NumericPropertyCharacteristics.C_GRAPH_MIN, new Double(-10));
characteristicsD.put(NumericPropertyCharacteristics.C_MAXIMUM, new Double(10));
characteristicsD.put(NumericPropertyCharacteristics.C_MINIMUM, new Double(-10));
gdaContext.bind(ppi, new DoublePropertyProxyImpl(instance, ppi.toString()), characteristicsD);
ppi = new URIName(null, DEFAULT_AUTHORITY, "StringPropertyProxyImpl", null);
Attributes characteristicsS = new org.epics.css.dal.directory.Attributes();
characteristicsS.put(PropertyCharacteristics.C_DESCRIPTION, "Simulated Property");
characteristicsS.put(PropertyCharacteristics.C_POSITION, new Double(0));
characteristicsS.put(PropertyCharacteristics.C_PROPERTY_TYPE, "property");
gdaContext.bind(ppi, new StringScannableStatusPropertyProxyImpl(instance, ppi.toString()), characteristicsS);
return gdaContext;
} catch (NamingException e) {
e.printStackTrace();
throw new RuntimeException("Failed to instantiate context.", e);
}
}
@Override
public RemoteInfo createRemoteInfo(String uniqueName) throws NamingException {
// TODO Auto-generated method stub
return null;
}
@Override
protected <T extends PropertyProxy<?, ?>> T createNewPropertyProxy(String uniqueName, Class<T> type) throws ConnectionException {
try {
final PropertyProxy<?,?> p = type.getConstructor(GdaPlug.class, String.class).newInstance(this, uniqueName);
// add to directory cache
if (p instanceof DirectoryProxy) {
putDirectoryProxyToCache((DirectoryProxy<?>) p);
}
return type.cast(p);
} catch (final Exception e) {
throw new ConnectionException(this,
"Failed to instantiate property proxy '" + uniqueName
+ "' for type '" + type.getName() + "'.", e);
}
}
@Override
protected <T extends DeviceProxy<?>> T createNewDeviceProxy(String uniqueName, Class<T> type) throws ConnectionException {
throw new UnsupportedOperationException("Devices not supported");
}
}