Implemention Class proposal mechanism in SWT field - eclipse

i know how to implement it,using field assist and search pattern, but the mechanism each time triggers a new search. I am not sure, how the mechanism is implemented in Open Type for example ( i think with indexes). How to use this cache to make in time classpath search
This almost my entire solution. Each time a call createProposalData
private TreeSet<String> data;
private SearchParticipant[] participants = new SearchParticipant[] { SearchEngine
.getDefaultSearchParticipant() };
private SearchPattern pattern;
private IJavaProject prj;
private JavaSearchScope scope;
private SearchEngine searchEngine = new SearchEngine();
private SearchRequestor requestor = new SearchRequestor() {
#Override
public void acceptSearchMatch(SearchMatch match) throws CoreException {
String text = getText(match.getElement());
if (text != null) {
data.add(text);
}
}
public String getText(Object element) {
...
}
};
public ProposalEngine(IJavaProject prj) {
super();
this.prj = prj;
scope = new JavaSearchScope();
try {
scope.add(prj);
} catch (JavaModelException e) {
//
}
}
public Collection<String> createProposalData(final String patternText) {
data = new TreeSet<String>();
try {
pattern = getPatternForSeach(patternText);
searchEngine.search(pattern, participants, scope, requestor, null);
} catch (Exception e) {
// skip
}
return data;
}
protected SearchPattern getPatternForSeach(String patternText) {
return SearchPattern.createPattern(patternText,
IJavaSearchConstants.CLASS_AND_INTERFACE,
IJavaSearchConstants.DECLARATIONS,
SearchPattern.R_CAMELCASE_MATCH);
}

I believe that you are doing exactly what the Open Type dialog is doing. Indexing to speed up search happens underneath JDT API.

Related

mybatis interceptor throw Reflection exception affects cpu performence

I had implement a interceptor of myabtis. but we found a problem, execute interceptor lead to throw so many IllegalAccessException, it affects cpu performence
Shown below is where the problem is, why did not check access permision of feild befor executed code "field.get(target)".
public class GetFieldInvoker implements Invoker {
private final Field field;
public GetFieldInvoker(Field field) {
this.field = field;
}
#Override
public Object invoke(Object target, Object[] args) throws IllegalAccessException {
try {
return field.get(target);
} catch (IllegalAccessException e) {
if (Reflector.canControlMemberAccessible()) {
field.setAccessible(true);
return field.get(target);
} else {
throw e;
}
}
}
#Override
public Class<?> getType() {
return field.getType();
}
}
the intercepor of mine:
#Intercepts({
#Signature(
type = StatementHandler.class,
method = "prepare",
args = {Connection.class, Integer.class})
})
public class SqlIdInterceptor implements Interceptor {
private static final int MAX_LEN = 256;
private final RoomboxLogger logger = RoomboxLogManager.getLogger();
#Override
public Object intercept(Invocation invocation) throws Throwable {
StatementHandler statementHandler = realTarget(invocation.getTarget());
MetaObject metaObject = SystemMetaObject.forObject(statementHandler);
BoundSql boundSql = (BoundSql) metaObject.getValue("delegate.boundSql");
String originalSql = boundSql.getSql();
MappedStatement mappedStatement =
(MappedStatement) metaObject.getValue("delegate.mappedStatement");
String id = mappedStatement.getId();
if (id != null) {
int len = id.length();
if (len > MAX_LEN) {
logger.warn("too long id", "id", id, "len", len);
}
}
String newSQL = "# " + id + "\n" + originalSql;
metaObject.setValue("delegate.boundSql.sql", newSQL);
return invocation.proceed();
}
#SuppressWarnings("unchecked")
public static <T> T realTarget(Object target) {
if (Proxy.isProxyClass(target.getClass())) {
MetaObject metaObject = SystemMetaObject.forObject(target);
return realTarget(metaObject.getValue("h.target"));
}
return (T) target;
}
}
Flame Graph
enter image description here
enter image description here
I need help, how to avoid throw exceptions, is any other way to reslove this problem?
thanks.

Is there any REST API to fetch all rules from Repository in Drools

As you can see, all rules can be listed in project explorer, i am wondering Drools workbench has such a Rest API for this, but I went through online document document, there is no such API. any suggestion on this? thanks in advance.
https://docs.jboss.org/drools/release/latest/drools-docs/html/ch20.html#d0e22619
Best Regards
Yuhua
As far as I know, there is no REST API to do that (public at least). One option do you have though is to use git to get that information from the workbench.
The storage of the workbench is based on git. Each repository in the workbench is actually a git repository. The workbench allows you to clone those repositories and to do whatever you need with them just as with any other git repo out there.
Inside each of the git repositories you will find zero or more maven projects. Indeed, each of the projects you see in the workbench is a real maven project. The different assets in your projects (drl rules, guided rules, decision table, etc.) will be available under the resources directory of the corresponding project.
Hope it helps,
As Esteban Aliverti mentioned, there is no ready to use API to achieve this. However, we can write a custom extension to KIE Server to fetch all the rules deployed.
It is explained in detailed here.
I have similar use case in my application and did the following implementation for fetching rules.
CusomtDroolsKieServerApplicationComponentsService
public class CusomtDroolsKieServerApplicationComponentsService implements KieServerApplicationComponentsService {
private static final String OWNER_EXTENSION = "Drools";
public Collection<Object> getAppComponents(String extension, SupportedTransports type, Object... services) {
// skip calls from other than owning extension
if (!OWNER_EXTENSION.equals(extension)) {
return Collections.emptyList();
}
RulesExecutionService rulesExecutionService = null;
KieServerRegistry context = null;
for (Object object : services) {
if (RulesExecutionService.class.isAssignableFrom(object.getClass())) {
rulesExecutionService = (RulesExecutionService) object;
continue;
} else if (KieServerRegistry.class.isAssignableFrom(object.getClass())) {
context = (KieServerRegistry) object;
continue;
}
}
List<Object> components = new ArrayList<Object>(1);
if (SupportedTransports.REST.equals(type)) {
components.add(new RuleRESTService(rulesExecutionService, context));
}
return components;
}
RuleRestService
#Path("server/containers/instances/{id}/ksession")
public class RuleRESTService {
private RulesExecutionService rulesExecutionService;
private KieServerRegistry registry;
public RuleRESTService() {
}
public RuleRESTService(RulesExecutionService rulesExecutionService, KieServerRegistry registry) {
this.rulesExecutionService = rulesExecutionService;
this.registry = registry;
}
public RulesExecutionService getRulesExecutionService() {
return rulesExecutionService;
}
public void setRulesExecutionService(RulesExecutionService rulesExecutionService) {
this.rulesExecutionService = rulesExecutionService;
}
public KieServerRegistry getRegistry() {
return registry;
}
public void setRegistry(KieServerRegistry registry) {
this.registry = registry;
}
#POST
#Path("/{ksessionId}")
#Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
#Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public Response fetchAllRules(#Context HttpHeaders headers, #PathParam("id") String id,
#PathParam("ksessionId") String ksessionId, String cmdPayload) {
Variant v = getVariant(headers);
try {
System.out.println("CREATING KieContainerInstance ");
KieContainerInstance kci = registry.getContainer(id);
String contentType = getContentType(headers);
MarshallingFormat format = MarshallingFormat.fromType(contentType);
if (format == null) {
format = MarshallingFormat.valueOf(contentType);
}
Marshaller marshaller = kci.getMarshaller(format);
RuleAccessor accessor = new RuleAccessor();
List<RuleData> rules = accessor.fetchAllRules(kci.getKieContainer());
String result = marshaller.marshall(rules);
return createResponse(result, v, Response.Status.OK);
} catch (Exception ex) {
ex.printStackTrace();
String response = "Execution failed with error : " + ex.getMessage();
System.out.println("Returning Failure response with content '{}' :" + response);
return createResponse(response, v, Response.Status.INTERNAL_SERVER_ERROR);
}
}
RuleAccessor
public class RuleAccessor {
public List<RuleData> fetchAllRules(KieContainer kContainer) {
kContainer.getKieBaseNames().stream()
.forEach(kieBase -> rules.addAll(fetchRules(kContainer1.getKieBase(kieBase))));
return rules;
}
public List<RuleData> fetchRules(KieBase kieBase) {
List<RuleData> ruleData = new ArrayList<>();
for (KiePackage kp : kieBase.getKiePackages()) {
RuleData data = new RuleData();
for (Rule r1 : kp.getRules()) {
RuleImpl r = (RuleImpl) r1;
data.agendaGroup(r.getAgendaGroup()).packageId(r.getPackageName()).ruleName(r.getName())
.enabled(Boolean.getBoolean((((EnabledBoolean) r.getEnabled()).toString())))
.effectiveDate(String.valueOf(r.getDateEffective()))
.dateExpires(String.valueOf(r.getDateExpires())).dialect(r.getDialect())
.salience(r.getSalienceValue()).metaData(r.getMetaData());
try {
Resource resource = r.getResource();
Reader reader = resource.getReader();
BufferedReader bufferedReader = new BufferedReader(reader);
String line = null;
StringBuilder builder = new StringBuilder();
while ((line = bufferedReader.readLine()) != null) {
builder.append(line);
}
data.ruleContent(builder.toString());
ruleData.add(data);
} catch (IOException e) {
e.printStackTrace();
}
}
}
return ruleData;
}
public static class RuleData {
private String packageId;
private String ruleName;
private String type;
private String agendaGroup;
private String ruleContent;
private boolean isEnabled;
private String effectiveDate;
private String dateExpires;
private String dialect;
private int salience;
private Map<String, Object> metaData;
public boolean isEnabled() {
return isEnabled;
}
public RuleData enabled(boolean isEnabled) {
this.isEnabled = isEnabled;
return this;
}
public String effectiveDate() {
return effectiveDate;
}
public RuleData effectiveDate(String effectiveDate) {
this.effectiveDate = effectiveDate;
return this;
}
public String getDateExpires() {
return dateExpires;
}
public RuleData dateExpires(String dateExpires) {
this.dateExpires = dateExpires;
return this;
}
public String getDialect() {
return dialect;
}
public RuleData dialect(String dialect) {
this.dialect = dialect;
return this;
}
public int getSalience() {
return salience;
}
public RuleData salience(int salience) {
this.salience = salience;
return this;
}
public Map<String, Object> getMetaData() {
return metaData;
}
public RuleData metaData(Map<String, Object> metaData) {
this.metaData = metaData;
return this;
}
public String getRuleContent() {
return ruleContent;
}
public RuleData ruleContent(String ruleContent) {
this.ruleContent = ruleContent;
return this;
}
public String getPackageId() {
return packageId;
}
public RuleData packageId(String packageId) {
this.packageId = packageId;
return this;
}
public String getRuleName() {
return ruleName;
}
public RuleData ruleName(String ruleName) {
this.ruleName = ruleName;
return this;
}
public String getType() {
return type;
}
public RuleData type(String type) {
this.type = type;
return this;
}
public String getAgendaGroup() {
return agendaGroup;
}
public RuleData agendaGroup(String agendaGroup) {
this.agendaGroup = agendaGroup;
return this;
}
}
}
You can make a REST call to Kie Server from you application to access all the rules available for the given container.
http://localhost:8080/kie-server/services/rest/server/containers/instances/<container-id>/ksession/<session-id>

DataFlavor in JavaFX not recognized correctly

I'm experiencing a problem when D&D a custom object from Swing to JavaFX and I'm wondering if I'm doing something wrong or its probably a Java FX bug.
My Transferable has been defined as the following:
public class TransferableEmployee implements Transferable {
public static final DataFlavor EMPLOYEE_FLAVOR = new DataFlavor(Employee[].class, "Employee");
public static final DataFlavor DEFINITION_FLAVOR = new DataFlavor(PropertyDefinition[].class, "Definition");
private static final DataFlavor FFLAVORS [] = {EMPLOYEE_FLAVOR, DEFINITION_FLAVOR};
private Employee[] employees;
private PropertyDefinition[] propertyDefinitions;
public MintTransferableEmployee(Employee[] employees, PropertyDefinition[] propertyDefinitions) {
this.employees = employees != null ? employees.clone() : null;
this.propertyDefinitions = propertyDefinitions != null ? propertyDefinitions.clone() : null;
}
public DataFlavor[] getTransferDataFlavors() {
return FFLAVORS.clone();
}
public Object getTransferData(DataFlavor aFlavor) throws UnsupportedFlavorException {
Object returnObject = null;
if (aFlavor.equals(EMPLOYEE_FLAVOR)) {
returnObject = employees;
}
else if(aFlavor.equals(DEFINITION_FLAVOR)){
returnObject = propertyDefinitions;
}
else{
throw new UnsupportedFlavorException(aFlavor);
}
return returnObject;
}
public boolean isDataFlavorSupported(DataFlavor aFlavor) {
boolean lReturnValue = false;
for (int i=0, n=FFLAVORS.length; i<n; i++) {
if (aFlavor.equals(FFLAVORS[i])) {
lReturnValue = true;
break;
}
}
return lReturnValue;
}
}
I've created an imageView (FX Component) where I added the setOnDragOver just as the following:
employeePhotoImageView.setOnDragOver(new EventHandler<DragEvent>() {
#Override
public void handle(DragEvent event) {
System.out.println("dragOver");
event.getDragboard().getContentTypes();
event.getDragboard().getContent(DataFormat.lookupMimeType("application/x-java-serialized-object"));
}
});
The getContentTypes() returns a Map with [[application/x-java-serialized-object]], so now I try to get the Content, and this only returns the List of PropertyDefinition but no Employee at all (which in this case, is the one I need).
If I remove the data of the PropertyDefinition in the transferable, the employee is returned in the getContent(DataFormat) method.
For me, this means that JavaFX only works with 1 DataFlavor or somehow it is only returning the last flavor found in the Transferable.
Any clues on this?
Thanks in advanced...

UCMA Generic QuestionAnswer activity

I am working on a UCMA 3.0 workflow application and am attempting to generate queries into our client management system allowing end users to obtain data about specific clients via voice or instant message. I was wondering anyone knows how to create a generic questionanswer activity using UCMA that allows generic input. I know that I can set up expected inputs and grammars, but with the bi-capitalization options, and the likelihood that an end user would know the exact client name (or client number for that matter), I would prefer to allow the user to enter part of the name and then search the database for a list of names that might meet the criteria. Does anyone know of a way, and have sample code that might allow me to do this if it is possible?
I had the same problem and had to write a custom activity to capture generic input from a user. This needs some work to make it production ready. Note the classy catching of system.exception in multiple places, as well as throwing an exception if input isn't received within the timeout period instead of reprompting the user. Also no regex on the user input...
The InstanceDependencyProperty is something else that was frustrating about Workflow. Without using InstanceDependencyProperties you won't be able to retrieve any results after the activity is completed.
Hope this helps!
using System;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Threading;
using System.Workflow.Activities;
using System.Workflow.Activities.Rules;
using System.Workflow.ComponentModel;
using System.Workflow.ComponentModel.Design;
using System.Workflow.ComponentModel.Compiler;
using System.Workflow.ComponentModel.Serialization;
using System.Workflow.Runtime;
using Microsoft.Rtc.Collaboration;
using Microsoft.Rtc.Workflow.Activities;
using Microsoft.Rtc.Workflow.Common;
namespace ActivityLibrary
{
public partial class CaptureIMInput : Activity, IInstanceDependencyContainer
{
#region Private member variables
private CallProvider _callProvider;
private Timer _maximumTimer;
private string _imText;
private bool messageReceived = false;
private bool _maximumTimerElapsed = false;
#endregion
public CaptureIMInput()
{
InitializeComponent();
_instanceDependencyProperties = new Dictionary<string, object>();
}
protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
{
try
{
this._callProvider = Utilities.GetCallProviderFromParent<InstantMessagingCall>(this);
InstantMessagingCall call = (InstantMessagingCall)this._callProvider.Call;
try
{
if (call.State == CallState.Established)
{
call.Flow.EndSendInstantMessage(call.Flow.BeginSendInstantMessage(MainPrompt, null, null));
_maximumTimer = new Timer(new TimerCallback(OnMaximumTimerFired), null, MaximumPrompt, new TimeSpan(0, 0, 0, 0, -1));
call.Flow.MessageReceived += this.InstantMessagingFlow_MessageReceived;
while (!messageReceived)
{
if (_maximumTimerElapsed)
throw new TimeoutException("User input was not detected within alloted time");
}
if (!string.IsNullOrEmpty(_imText))
{
IMText = _imText;
{
this.Stop();
return ActivityExecutionStatus.Closed;
}
}
}
}
catch (Exception ex)
{
throw ex;
}
}
catch (Exception ex)
{
throw ex;
}
return ActivityExecutionStatus.Closed;
}
protected override ActivityExecutionStatus Cancel(ActivityExecutionContext executionContext)
{
this.Stop(); //Clean up timer
return ActivityExecutionStatus.Canceling;
}
private void Stop()
{
if (_maximumTimer != null)
{
_maximumTimer.Dispose();
_maximumTimer = null;
}
}
private void InstantMessagingFlow_MessageReceived(object sender, InstantMessageReceivedEventArgs e)
{
//Can't set dependencyproperties directly from sub-thread
_imText = e.TextBody;
//Mark bool so main while loop exits
messageReceived = true;
}
//Callback to
private void OnMaximumTimerFired(object state)
{
_maximumTimerElapsed = true;
}
#region InstanceDependency dictionary
private Dictionary<string, object> _instanceDependencyProperties;
[Browsable(false)]
public Dictionary<string, object> InstanceDependencyProperties
{
get { return _instanceDependencyProperties; }
}
#endregion
#region Maximum Prompt Timeout
[NonSerialized]
private static readonly InstanceDependencyProperty MaximumPromptProperty = InstanceDependencyProperty.Register("MaximumPrompt", typeof(TimeSpan), typeof(CaptureIMInput), new TimeSpan(0, 0, 30));
[TypeConverter(typeof(TimeSpanConverter))]
public TimeSpan MaximumPrompt
{
get
{
if (base.DesignMode)
return (TimeSpan)InstanceDependencyHelper.GetValue<CaptureIMInput>(this, MaximumPromptProperty);
else
return (TimeSpan)InstanceDependencyHelper.GetValue<CaptureIMInput>(this, this.WorkflowInstanceId, MaximumPromptProperty);
}
set
{
if (base.DesignMode)
InstanceDependencyHelper.SetValue<CaptureIMInput>(this, MaximumPromptProperty, value);
else
InstanceDependencyHelper.SetValue<CaptureIMInput>(this, this.WorkflowInstanceId, MaximumPromptProperty, value);
}
}
#endregion
#region MainPrompt
public static DependencyProperty MainPromptProperty =
DependencyProperty.Register("MainPrompt", typeof(string), typeof(CaptureIMInput));
[ValidationOption(ValidationOption.Required)]
public string MainPrompt
{
get
{
return (string)base.GetValue(MainPromptProperty);
}
set
{
base.SetValue(MainPromptProperty, value);
}
}
#endregion
#region Instant Message Text
public static InstanceDependencyProperty IMTextProperty =
InstanceDependencyProperty.Register("IMText",
typeof(string),
typeof(CaptureIMInput));
[Description("InstantMessaging Text from user")]
[Browsable(true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public string IMText
{
get
{
if (base.DesignMode) return ((string)InstanceDependencyHelper.GetValue<CaptureIMInput>(this, CaptureIMInput.IMTextProperty));
else return ((string)(InstanceDependencyHelper.GetValue<CaptureIMInput>(this, this.WorkflowInstanceId, CaptureIMInput.IMTextProperty)));
}
set
{
if (base.DesignMode) InstanceDependencyHelper.SetValue<CaptureIMInput>(this, CaptureIMInput.IMTextProperty, value);
else InstanceDependencyHelper.SetValue<CaptureIMInput>(this, this.WorkflowInstanceId, CaptureIMInput.IMTextProperty, value);
}
}
#endregion
}
}

Instance-Specific EventHandler to provide data visibility beyond the Class-Level

May I ask for help with the following?
I am attempting to connect and control three pieces of household electronic equipment by computer through a GlobalCache GC-100 and iTach. As you will see in the following code, I created a class ("GlobalCacheAdapter") that can communicate and control the equipment, and created an instance of the class for each piece of equipment. Although each instance seems to work well with communicating and in controlling each piece of equipment, the *feedback returned from the equipment* seems only to be visible at the defining class level's - "ReaderThreadProc" procedure. Further processing of the feedback is required for each piece of equipment and I am uncertain as to how to forward this feedback at the equipment specific instance-level. I suspect that an instance-specific EventHandler will need to be implemented; however I am not aware as to how to implement this type of instance-specific EventHandler in order to complete processing and update the appropriate controls.
Any help wold be greatly appreciated.
using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
// Create three new instances of GlobalCacheAdaptor and connect.
// GC-100 (Elan) 192.168.1.70 4998
// GC-100 (TuneSuite) 192.168.1.70 5000
// GC iTach (Lighting) 192.168.1.71 4999
private GlobalCacheAdaptor elanGlobalCacheAdaptor;
private GlobalCacheAdaptor tuneSuiteGlobalCacheAdaptor;
private GlobalCacheAdaptor lutronGlobalCacheAdaptor;
public Form1()
{
InitializeComponent();
elanGlobalCacheAdaptor = new GlobalCacheAdaptor();
elanGlobalCacheAdaptor.ConnectToDevice(IPAddress.Parse("192.168.1.70"), 4998);
tuneSuiteGlobalCacheAdaptor = new GlobalCacheAdaptor();
tuneSuiteGlobalCacheAdaptor.ConnectToDevice(IPAddress.Parse("192.168.1.70"), 5000);
lutronGlobalCacheAdaptor = new GlobalCacheAdaptor();
lutronGlobalCacheAdaptor.ConnectToDevice(IPAddress.Parse("192.168.1.71"), 4999);
elanTextBox.Text = elanGlobalCacheAdaptor._line;
tuneSuiteTextBox.Text = tuneSuiteGlobalCacheAdaptor._line;
lutronTextBox.Text = lutronGlobalCacheAdaptor._line;
}
private void btnZoneOnOff_Click(object sender, EventArgs e) { elanGlobalCacheAdaptor.SendMessage("sendir,4:3,1,40000,4,1,21,181,21,181,21,181,21,181,21,181,21,181,21,181,21,181,21,181,21,181,21,181,21,800" + Environment.NewLine); }
private void btnSourceInput1_Click(object sender, EventArgs e) { elanGlobalCacheAdaptor.SendMessage("sendir,4:3,1,40000,1,1,20,179,20,179,20,179,20,179,20,179,20,179,20,179,20,278,20,179,20,179,20,179,20,780" + Environment.NewLine); }
private void btnSystemOff_Click(object sender, EventArgs e) { elanGlobalCacheAdaptor.SendMessage("sendir,4:3,1,40000,1,1,20,184,20,184,20,184,20,184,20,184,20,286,20,286,20,286,20,184,20,184,20,184,20,820" + Environment.NewLine); }
private void btnLightOff_Click(object sender, EventArgs e) { lutronGlobalCacheAdaptor.SendMessage("sdl,14,0,0,S2\x0d"); }
private void btnLightOn_Click(object sender, EventArgs e) { lutronGlobalCacheAdaptor.SendMessage("sdl,14,100,0,S2\x0d"); }
private void btnChannel31_Click(object sender, EventArgs e) { tuneSuiteGlobalCacheAdaptor.SendMessage("\xB8\x4D\xB5\x33\x31\x00\x30\x21\xB8\x0D"); }
private void btnChannel30_Click(object sender, EventArgs e) { tuneSuiteGlobalCacheAdaptor.SendMessage("\xB8\x4D\xB5\x33\x30\x00\x30\x21\xB8\x0D"); }
}
}
public class GlobalCacheAdaptor
{
public Socket _multicastListener;
public string _preferredDeviceID;
public IPAddress _deviceAddress;
public Socket _deviceSocket;
public StreamWriter _deviceWriter;
public bool _isConnected;
public int _port;
public IPAddress _address;
public string _line;
public GlobalCacheAdaptor() { }
public static readonly GlobalCacheAdaptor Instance = new GlobalCacheAdaptor();
public bool IsListening { get { return _multicastListener != null; } }
public GlobalCacheAdaptor ConnectToDevice(IPAddress address, int port)
{
if (_deviceSocket != null) _deviceSocket.Close();
try
{
_port = port;
_address = address;
_deviceSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
_deviceSocket.Connect(new IPEndPoint(address, port)); ;
_deviceAddress = address;
var stream = new NetworkStream(_deviceSocket);
var reader = new StreamReader(stream);
var writer = new StreamWriter(stream) { NewLine = "\r", AutoFlush = true };
_deviceWriter = writer;
writer.WriteLine("getdevices");
var readerThread = new Thread(ReaderThreadProc) { IsBackground = true };
readerThread.Start(reader);
_isConnected = true;
return Instance;
}
catch { DisconnectFromDevice(); MessageBox.Show("ConnectToDevice Error."); throw; }
}
public void SendMessage(string message)
{
try
{
var stream = new NetworkStream(_deviceSocket);
var reader = new StreamReader(stream);
var writer = new StreamWriter(stream) { NewLine = "\r", AutoFlush = true };
_deviceWriter = writer;
writer.WriteLine(message);
var readerThread = new Thread(ReaderThreadProc) { IsBackground = true };
readerThread.Start(reader);
}
catch { MessageBox.Show("SendMessage() Error."); }
}
public void DisconnectFromDevice()
{
if (_deviceSocket != null)
{
try { _deviceSocket.Close(); _isConnected = false; }
catch { MessageBox.Show("DisconnectFromDevice Error."); }
_deviceSocket = null;
}
_deviceWriter = null;
_deviceAddress = null;
}
**private void ReaderThreadProc(object state)**
{
var reader = (StreamReader)state;
try
{
while (true)
{
var line = reader.ReadLine();
if (line == null) break;
_line = _line + line + Environment.NewLine;
}
**// Feedback from each piece of equipment is visible here.
// Need to create EventHandler to notify the TextBoxes to update with _line**
}
catch { MessageBox.Show("ReaderThreadProc Error."); }
}
}
From my understanding of the question, you want to do something like this?
You need to know when a GlobalCacheAdapter updates and which one updated in order to update textboxes on a form. My question to you is this - do you actually need to know which updated?
If you declare in your class an event handler like this:
public class GlobalCacheAdaptor
{
public event EventHandler<EventArgs> Updated;
protected virtual void OnUpdated()
{
var handler = Updated;
if (handler != null)
{
handler(this, EventArgs.Empty);
}
}
private void Foo()
{
// When an update is received, raise Updated event
OnUpdated();
}
}
Then in your form subscribe to Updated for all three GlobalCacheHandler instances
public Form1()
{
elanGlobalCacheAdaptor.Updated += (s,e) =>
{
elanTextBox.Text = elanGlobalCacheAdaptor._line;
}
tuneSuiteGlobalCacheAdaptor.Updated += (s,e) =>
{
tuneSuiteTextBox.Text = tuneSuiteGlobalCacheAdaptor._line;
}
lutronGlobalCacheAdaptor.Updated += (s,e) =>
{
lutronTextBox.Text = lutronGlobalCacheAdaptor._line;
}
}
You should be able to update the correct text box when the appropriate cache handler raises the Updated event.
Finally you may need to handle cross-thread interactions. if so, see this article on MSDN, particularly the part "Thread-Safe Calls to a Windows Forms Control"