package org.kevoree.library.javase.pipe;
import org.kevoree.ContainerNode;
import org.kevoree.ContainerRoot;
import org.kevoree.Group;
import org.kevoree.annotation.GroupType;
import org.kevoree.annotation.Library;
import org.kevoree.annotation.Start;
import org.kevoree.annotation.Stop;
import org.kevoree.framework.AbstractGroupType;
import org.kevoree.framework.KevoreeXmiHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;
import java.util.HashMap;
import java.util.Map;
/**
* User: Erwan Daubert - erwan.daubert@gmail.com
* Date: 16/11/11
* Time: 19:50
*
* @author Erwan Daubert
* @version 1.0
*/
@Library(name = "JavaSE")
@GroupType
public class PipeGroup extends AbstractGroupType implements PipeInstance {
private Logger logger = LoggerFactory.getLogger(PipeGroup.class);
private Map<String, RandomAccessFile> outputStreams;
private PipeReader reader;
@Start
public void startPipeGroup () throws IOException, InterruptedException {
outputStreams = new HashMap<String, RandomAccessFile>();
if (isWindows()) {
initializeOnWindows();
} else {
initializeOnLinux();
}
reader = new PipeReader(this);
}
@Stop
public void stopPipeGroup () {
for (RandomAccessFile stream : outputStreams.values()) {
try {
stream.close();
} catch (IOException e) {
}
}
reader.stop();
}
/*@Override
public Object dispatch (Message msg) {
for (KevoreePort p : getBindedPorts()) {
forward(p, msg);
}
for (KevoreeChannelFragment cf : getOtherFragments()) {
forward(cf, msg);
}
return null;
}
@Override
public ChannelFragmentSender createSender (final String remoteNodeName, final String remoteChannelName) {
return new ChannelFragmentSender() {
@Override
public Object sendMessageToRemote (Message message) {
if (isWindows()) {
dispatchOnWindows(message);
} else {
try {
dispatchOnUnix(message, remoteNodeName);
} catch (IOException e) {
logger.warn(
"Unable to use the pipe for " + remoteChannelName + " from " + getNodeName() + " to "
+ remoteNodeName, e);
}
}
return null;
}
};
}*/
/*void forward (Message msg) {
for (KevoreePort p : getBindedPorts()) {
forward(p, msg);
}
}*/
private void initializeOnWindows () {
// TODO
}
private void initializeOnLinux () throws IOException, InterruptedException {
final Process p = Runtime.getRuntime()
.exec("mkfifo -m 777 " + System.getProperty("java.io.tmpdir") + File.separator + this
.getName() + "_" + this.getNodeName());
new Thread() {
public void run () {
InputStream inStream = p.getInputStream();
InputStream errStream = p.getErrorStream();
byte[] bytes = new byte[1024];
try {
int length = inStream.read(bytes);
errStream.read(bytes);
while (length != -1) {
length = inStream.read(bytes);
// System.out.write(bytes, 0, length);
errStream.read(bytes);
}
} catch (IOException e) {
// e.printStackTrace();
}
}
}.start();
p.waitFor();
}
private void dispatchOnWindows (ContainerRoot msg) {
// TODO
}
private void dispatchOnUnix (ContainerRoot msg, String nodeName) throws IOException {
if (outputStreams.get(nodeName) == null) {
outputStreams.put(nodeName,
new RandomAccessFile(new File(System.getProperty("java.io.tmpdir") + File.separator + this
.getName() + "_" + nodeName), "rw"));
}
ByteArrayOutputStream out = new ByteArrayOutputStream();
KevoreeXmiHelper.saveStream(out, msg);
outputStreams.get(nodeName).writeInt(out.size());
outputStreams.get(nodeName).write(out.toByteArray());
out.close();
}
public static boolean isWindows () {
String os = System.getProperty("os.name").toLowerCase();
return (os.contains("win"));
}
@Override
public void triggerModelUpdate () {
for (Group g : this.getModelService().getLastModel().getGroupsForJ()) {
if (g.getName().equals(this.getName())) {
for (ContainerNode node : g.getSubNodesForJ()) {
if (!node.getName().equals(this.getNodeName())) {
if (isWindows()) {
dispatchOnWindows(this.getModelService().getLastModel());
} else {
try {
dispatchOnUnix(this.getModelService().getLastModel(), node.getName());
} catch (IOException e) {
logger.warn(
"Unable to use the pipe for " + this.getName() + " from " + getNodeName()
+ " to "
+ node.getName(), e);
}
}
}
}
}
}
}
@Override
public void push (ContainerRoot model, String targetNodeName) {
}
@Override
public ContainerRoot pull (String targetNodeName) {
return null;
}
@Override
public void localForward (byte[] data, int length) {
try {
ByteArrayInputStream stream = new ByteArrayInputStream(data, 0, length);
ContainerRoot model = KevoreeXmiHelper.loadStream(stream);
this.getModelService().updateModel(model);
} catch (Exception e) {
logger.warn("Unable to convert data received as a model", e);
}
}
}