package infosapient.server;
/**
* @author: Copyright (c) 2001, Workplace Performance Tools, All Rights Reserved.
* License to use this program is provided under the COMMON PUBLIC LICENSE 0.5
* THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE
* ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES
* RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
* @version $Revision: 1.1.1.1 $
*/
import java.rmi.server.*;
import java.rmi.*;
import java.util.Vector;
import java.util.Properties;
import java.util.Date;
import java.io.*;
import infosapient.system.FzyAttribute;
import infosapient.system.FzySet;
import infosapient.system.FSEvent;
import infosapient.client.InfoSapientClient;
import infosapient.client.InfoSapientClientImpl;
import infosapient.control.InfoSapientController;
public class InfoSapientKnowledgeWorker
extends Object
implements Runnable, infosapient.system.Observer {
/** InfoSapientClientImpl used to communicate with the objects requesting knowledgebase sessions */
private InfoSapientClientImpl InfoSapientClient;
/** Attribute name. Used in error processing and notification. */
private String attrName;
/** Attribute. Used in error processing and notification. */
private FzyAttribute fa;
/** Goal set. Used in error processing and notification. */
private FzySet fs;
/** Consultation session parameters sent from client to this thread. Used for rules processing. */
private Properties runParameters;
/** The type of knowledgebase this thread handles. */
private String kbTypeName = null;
/** Controller used for mediating requests from rules engine */
private infosapient.control.InfoSapientController alc = null;
/** Name of this thread. */
private String name = null;
/**
* Create a knowledgeWorker with the kb name to load, the name of this thread, and the properties required to connect to the InfoSapientService
* @param String - knowledgebase key in kb.properties file
* @param String - worker name.
* @param Properties - connection properties required.
*/
protected InfoSapientKnowledgeWorker(String kbTName, String n) {
try {
kbTypeName = kbTName;
String theKBFileName =
(String) InfoSapientServiceImpl.getKBASES().get(kbTypeName);
String canonicalFN =
InfoSapientServiceImpl.getSERVER_PROPERTIES().get("root")
+ File.separator
+ theKBFileName;
setName(n);
runParameters = null;
alc = new InfoSapientController(canonicalFN);
alc.addObserver(this);
} catch (Exception e) {
InfoSapientServiceImpl.p(
getName()
+ "-"
+ (new Date())
+ ">>"
+ e.getMessage()
+ ":Unrecoverable error. Terminating this thread.");
e.printStackTrace();
System.exit(1);
}
}
/**
* Create a knowledgeWorker with the kb name to load, the name of this thread, and the properties required to connect to the InfoSapientService
* @param String - knowledgebase key in kb.properties file
* @param String - worker name.
* @param Properties - connection properties required.
*/
protected InfoSapientKnowledgeWorker(
String kbTName,
String n,
Properties goal) {
try {
kbTypeName = kbTName;
String theKBFileName =
(String) InfoSapientServiceImpl.getKBASES().get(kbTypeName);
String canonicalFN =
InfoSapientServiceImpl.getSERVER_PROPERTIES().get("root")
+ File.separator
+ theKBFileName;
setName(n);
runParameters = null;
alc = new InfoSapientController(canonicalFN);
alc.addObserver(this);
} catch (Exception e) {
InfoSapientServiceImpl.p(
getName()
+ "-"
+ (new Date())
+ ">>"
+ e.getMessage()
+ ":Unrecoverable error. Terminating this thread.");
e.printStackTrace();
System.exit(1);
}
}
/**
* Insert the method's description here.
* Creation date: (04/08/01 10:17:05 AM)
* @return infosapient.client.InfoSapientClientImpl
*/
protected infosapient.client.InfoSapientClientImpl getInfoSapientClient() {
return InfoSapientClient;
}
public String getName() {
return name;
}
final synchronized void handleClient() throws Exception {
synchronized (alc) {
alc.execute(runParameters);
alc.notifyAll();
}
}
final void handleThreadPool() {
try {
runParameters = null;
Vector pool =
(Vector) InfoSapientServiceImpl.getWorker_POOLS_Table().get(kbTypeName);
synchronized (pool) {
if (pool.size() >= InfoSapientServiceImpl.getMAXWORKERS()) {
/* too many threads, exit this one */
return;
} else {
pool.addElement(this);
}
}
} catch (Exception e) {
InfoSapientServiceImpl.p(
getName()
+ ".handeThreadPool()"
+ "-"
+ (new Date())
+ ">>"
+ e.getMessage()
+ ":Unrecoverable error. Terminating this thread.");
System.exit(1);
} finally {
try {
getInfoSapientClient().getService().remove(getInfoSapientClient());
} catch (java.rmi.RemoteException re) {
InfoSapientServiceImpl.p(
getName()
+ ".handeThreadPool()"
+ "-"
+ (new Date())
+ ">>"
+ re.getMessage()
+ ":Unrecoverable error. Terminating this thread.");
}
}
}
/**
* InfoSapientin in a loop until runParameters have been set. When that happens, start the kb session by invoking handleClient().
* When finished -- set runParameters to null, put me back into the thread pool, remove me from the InfoSapientService registry.
*/
public final synchronized void run() {
while (true) {
if (runParameters == null) {
try {
wait();
} catch (InterruptedException e) {
continue;
}
}
try {
handleClient();
} catch (Exception e) {
InfoSapientServiceImpl.p(e.getMessage());
} finally {
handleThreadPool();
notifyAll();
}
}
}
void setGoalProperties(Properties wp) {
synchronized (wp) {
runParameters = wp;
}
}
/**
* Insert the method's description here.
* Creation date: (04/08/01 10:17:05 AM)
* @param newInfoSapientClient infosapient.client.InfoSapientClientImpl
*/
protected void setInfoSapientClient(
infosapient.client.InfoSapientClientImpl newInfoSapientClient) {
InfoSapientClient = newInfoSapientClient;
}
void setName(String n) {
name = n;
}
/*
* Implementation of Observer.
* Used to send and receive messages from remote and non-remote clients.
* <ul>Depending on value of obj (typically a infosapient.system.FSEvent)
* <li>Send request for missing data to remote client,</li>
* <li>Send solution to remote client,</li>
* <li>Send error/warning(s) to remote client,</li>
* <li>Receive value of missing data from remote client,</li>
* <li>Pass value of missing data to non-remote client.</li> </ul>
* @param Observable - the object of interest to this thread
* @param Object - the actual message being sent.
*/
public final void update(infosapient.system.Observable obs, Object obj) {
infosapient.system.FSEvent event;
try {
if (obj instanceof infosapient.system.FSEvent) {
event = (infosapient.system.FSEvent) obj;
String command = event.getCmd();
command.trim();
/*
* send request for missing data to client
*/
if (command.equalsIgnoreCase("Attribute:askPrompt"))
getInfoSapientClient().send(
command,
event.getPackage(),
getInfoSapientClient().getObjID());
else
/*
* send solution to client
*/
if (command.equalsIgnoreCase("solution")) {
Properties results = (Properties) event.getPackage();
getInfoSapientClient().send(
command,
results,
getInfoSapientClient().getObjID());
/*
* send errors to client
*/
} else
if (command.equalsIgnoreCase("error")) {
getInfoSapientClient().send(
command,
event.getPackage(),
getInfoSapientClient().getObjID());
} else
if (command.equalsIgnoreCase("warning")) {
getInfoSapientClient().send(
command,
event.getPackage(),
getInfoSapientClient().getObjID());
if (event.getPackage() instanceof Exception) {
InfoSapientServiceImpl.p(
(new Date())
+ ":"
+ getName()
+ " "
+ ((Exception) event.getPackage()).getMessage());
} else
if (event.getPackage() instanceof String) {
InfoSapientServiceImpl.p(
(new Date()) + ":" + getName() + " " + (String) event.getPackage());
}
}
}
} catch (Exception e) {
}
}
}