package de.fu.alp5.foreign.distributed;
import java.io.IOException;
import java.rmi.AlreadyBoundException;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.server.UnicastRemoteObject;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
/**
* Analyzing a list of words by their language. Foreign words are collected in a
* list. Each worker has an Integer identifying the access space of the text to
* analyze in order to balance work load between WordAnalyserWorker.
*
* @author Konrad Reiche
*
*/
public class TextAnalyzerWorkerImpl implements TextAnalyzerWorker {
List<String> text;
List<String> dictionary;
List<String> foreignDictionary;
Set<String> localForeignWordSet;
int accessIndex;
int numberOfThreads;
CountDownLatch countDownLatch;
TextAnalyzer remoteTextAnalyzer;
/**
* Exports and binds a stub of this instance in order to provide remote
* access.
*/
public TextAnalyzerWorkerImpl(String textPath, String dictionaryPath,
String foreignDictionaryPath) throws IOException {
super();
this.text = TextAnalyzerImpl.convertTextFileToList(textPath);
this.dictionary = TextAnalyzerImpl
.convertTextFileToList(dictionaryPath);
this.foreignDictionary = TextAnalyzerImpl
.convertTextFileToList(foreignDictionaryPath);
this.localForeignWordSet = new HashSet<String>();
TextAnalyzerWorker stub = (TextAnalyzerWorker) UnicastRemoteObject
.exportObject((TextAnalyzerWorker) this);
try {
LocateRegistry.getRegistry().bind("TextAnalyzerWorker", stub);
} catch (AlreadyBoundException e) {
// ignored
}
}
/**
* Starts the analyzing. Every worker has assigned words to check. The words
* to check are determined by the given value of accessIndex.
*
* When finished the instance of this object is unbound and unexported.
*/
public void analyze() throws RemoteException {
for (int i = accessIndex; i < text.size(); i += numberOfThreads) {
String word = text.get(i);
checkWord(word);
}
UnicastRemoteObject.unexportObject((TextAnalyzerWorkerImpl) this, true);
try {
LocateRegistry.getRegistry().unbind("WordAnalyzerWorker");
} catch (NotBoundException e) {
}
}
/**
* Initializes the Worker with needed informations.
*/
public void initialize(int numberOfThreads, int accessIndex,
String remoteHost) throws RemoteException {
this.numberOfThreads = numberOfThreads;
this.accessIndex = accessIndex;
try {
this.remoteTextAnalyzer = (TextAnalyzer) LocateRegistry
.getRegistry(remoteHost).lookup("TextAnalyzer");
} catch (NotBoundException e) {
System.err.println("TextAnalyzer is not bound on " + remoteHost);
}
}
/**
* Checks a word for its language. If the word is already in the local
* foreign word set the method returns as this word is already known.
*
* If the word is in the dictionary it does not have to be added and thus
* the method returns.
*
* If the word is in the foreign dictionary the word is newly added to the
* global foreign word set of the TextAnalyzer. Further every word of the
* global foreign word set is copied to the local one.
*
* If none of these cases matches the method returns also and thus the word
* is ignored.
*
*/
private void checkWord(String word) throws RemoteException {
for (String localForeignWord : localForeignWordSet) {
if (word.equals(localForeignWord)) {
return;
}
}
for (String dictionaryWord : dictionary) {
if (word.equals(dictionaryWord)) {
return;
}
}
for (String foreignDictionaryWord : foreignDictionary) {
if (word.equals(foreignDictionaryWord)) {
remoteTextAnalyzer.addForeignWord(word);
remoteTextAnalyzer.getGlobalForeignWordSet().addAll(
localForeignWordSet);
}
}
}
}