/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package com.eas.opc.da; import com.eas.opc.OPCCommon; import com.eas.opc.da.dcom.IOPCGroupStateMgt; import com.eas.opc.da.dcom.IOPCServer; import com.eas.opc.da.dcom.IOPCServer.AddGroupResult; import com.eas.opc.da.dcom.OPCSERVERSTATUS; import com.eas.opc.da.dcom.OPCShutdownListener; import java.io.IOException; import java.net.UnknownHostException; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.NoSuchElementException; import java.util.logging.Level; import java.util.logging.LogManager; import java.util.logging.Logger; import org.jinterop.dcom.common.JIException; import org.jinterop.dcom.common.JISystem; /** * * @author pk */ public class OPCDAServerConnection extends OPCCommon { protected IOPCServer opcServer; private final List<Group> knownGroups = new ArrayList<>(); private final Map<Integer, Group> knownGroupsByServerHandle = new HashMap<>(); private final Map<String, Group> knownGroupsByName = new HashMap<>(); private final List<OPCShutdownListener> shutdownListeners = new ArrayList<>(); static { try { JISystem.setInBuiltLogHandler(true); } catch (SecurityException | IOException ex) { Logger.getLogger(OPCDAServerConnection.class.getName()).log(Level.SEVERE, null, ex); } LogManager.getLogManager().getLogger("org.jinterop").setLevel(Level.WARNING); } @Override public void connect(String progID, String domain, String hostname, String username, String password) throws JIException, UnknownHostException { super.connect(progID, domain, hostname, username, password); opcServer = new IOPCServer(comServer); opcServer.addShutdownListener(new InternalShutDownListener()); } public void addShutdownListener(OPCShutdownListener l) throws JIException { synchronized (shutdownListeners) { shutdownListeners.add(l); opcServer.addShutdownListener(l); } } public void removeShutdownListener(OPCShutdownListener l) throws JIException { synchronized (shutdownListeners) { shutdownListeners.remove(l); opcServer.removeShutdownListener(l); } } @Override public void disconnect() { cleanup(); opcServer = null; super.disconnect(); } public String getErrorString(long errorCode, int localeID) throws JIException { return opcServer.getErrorString(errorCode, localeID); } public ServerStatus getStatus() throws JIException { return new ServerStatus(opcServer.getStatus()); } public Group addGroup(String name, boolean isActive, int requestedUpdateRate, int clientHandle, Integer timeBias, Float percentDeadBand, int localeID) throws JIException { final AddGroupResult addResult = opcServer.addGroup(name, isActive, requestedUpdateRate, clientHandle, timeBias, percentDeadBand, localeID, IOPCGroupStateMgt.IID_IOPCGroupStateMgt); final IOPCGroupStateMgt groupStateMgt = new IOPCGroupStateMgt(addResult.getIface()); final int revisedUpdateRate = addResult.getRevisedUpdateRate(); final int serverHandle = addResult.getServerGroup(); final Group group = new Group(name, isActive, requestedUpdateRate, revisedUpdateRate, clientHandle, serverHandle, timeBias, percentDeadBand, localeID, groupStateMgt); synchronized (this) { knownGroups.add(group); knownGroupsByName.put(name, group); knownGroupsByServerHandle.put(serverHandle, group); } return group; } public void removeGroup(Group group, boolean force) throws JIException { boolean groupKnown = false; synchronized (this) { if (knownGroupsByServerHandle.get(group.getServerHandle()) == group || knownGroupsByName.get(group.getName()) == group || knownGroups.contains(group)) { knownGroups.remove(group); knownGroupsByName.remove(group.getName()); knownGroupsByServerHandle.remove(group.getServerHandle()); groupKnown = true; } } if (groupKnown) opcServer.removeGroup(group.getServerHandle(), force); else throw new NoSuchElementException("Unknown group."); } public Group addGroup(String name, boolean isActive, int requestedUpdateRate, int clientHandle) throws JIException { return addGroup(name, isActive, requestedUpdateRate, clientHandle, null, null, getLocaleID()); } public Group[] getKnownGroups() { synchronized (this) { Group[] result = new Group[knownGroups.size()]; result = knownGroups.toArray(result); return result; } } public Group getGroupByName(String name) { synchronized (this) { return knownGroupsByName.get(name); } } protected void cleanup() { synchronized (this) { for (Group group : knownGroups) { try { group.cleanup(); } catch (JIException ex) { Logger.getLogger(OPCDAServerConnection.class.getName()).log(Level.SEVERE, "Failed to cleanup group " + group, ex); } try { opcServer.removeGroup(group.getServerHandle(), false); } catch (JIException ex) { Logger.getLogger(OPCDAServerConnection.class.getName()).log(Level.SEVERE, "Failed to remove group " + group, ex); } } knownGroups.clear(); knownGroupsByName.clear(); knownGroupsByServerHandle.clear(); } synchronized (shutdownListeners) { for (OPCShutdownListener l : shutdownListeners) { try { opcServer.removeShutdownListener(l); } catch (JIException ex) { Logger.getLogger(OPCDAServerConnection.class.getName()).log(Level.SEVERE, "Failed to remove shutdown listener " + l, ex); } } shutdownListeners.clear(); } } /** * OPCSERVERSTATE constants. */ public static enum ServerState { RUNNING(1), FAILED(2), NOCONFIG(3), SUSPENDED(4), TEST(5); private final int id; private ServerState(int id) { this.id = id; } public static ServerState getState(int id) { switch (id) { case 1: return RUNNING; case 2: return FAILED; case 3: return NOCONFIG; case 4: return SUSPENDED; case 5: return TEST; default: throw new IllegalArgumentException(String.format("Unknown OPCSERVERSTATE constant %d", id)); //NOI18N } } public int getId() { return id; } } public static final class ServerStatus { private final int bandWidth; private final short buildNumber; private final Date currentTime; private final int groupCount; private final Date lastUpdateTime; private final short majorVersion; private final short minorVersion; private final short reserved; private final ServerState serverState; private final Date startTime; private final String vendorInfo; private ServerStatus(OPCSERVERSTATUS src) { bandWidth = src.getBandWidth(); buildNumber = src.getBuildNumber(); currentTime = src.getCurrentTime().getTime(); groupCount = src.getGroupCount(); lastUpdateTime = src.getLastUpdateTime().getTime(); majorVersion = src.getMajorVersion(); minorVersion = src.getMinorVersion(); reserved = src.getReserved(); serverState = ServerState.getState(src.getServerState()); startTime = src.getStartTime().getTime(); vendorInfo = src.getVendorInfo(); } public int getBandWidth() { return bandWidth; } public short getBuildNumber() { return buildNumber; } public Date getCurrentTime() { return currentTime; } public int getGroupCount() { return groupCount; } public Date getLastUpdateTime() { return lastUpdateTime; } public short getMajorVersion() { return majorVersion; } public short getMinorVersion() { return minorVersion; } public short getReserved() { return reserved; } public ServerState getServerState() { return serverState; } public Date getStartTime() { return startTime; } public String getVendorInfo() { return vendorInfo; } } private class InternalShutDownListener implements OPCShutdownListener { public void shutdownRequested(String reason) { OPCDAServerConnection.this.cleanup(); try { OPCDAServerConnection.this.opcServer.removeShutdownListener(this); } catch (JIException ex) { Logger.getLogger(OPCDAServerConnection.class.getName()).log(Level.SEVERE, "Failed to remove internal shutdown listener.", ex); } } } }