net.ostis.sc.memory.impl.remote.rgp.RGPSession.java Source code

Java tutorial

Introduction

Here is the source code for net.ostis.sc.memory.impl.remote.rgp.RGPSession.java

Source

/*
 * This source file is part of OSTIS (Open Semantic Technology for Intelligent
 * Systems) For the latest info, see http://www.ostis.net
 *
 * Copyright (c) 2011 OSTIS
 *
 * OSTIS is free software: you can redistribute it and/or modify it under the
 * terms of the GNU Lesser General Public License as published by the Free
 * Software Foundation, either version 3 of the License, or (at your option) any
 * later version.
 *
 * OSTIS is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
 * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with OSTIS. If not, see <http://www.gnu.org/licenses/>.
 */
package net.ostis.sc.memory.impl.remote.rgp;

import java.io.EOFException;
import java.io.IOException;
import java.net.Socket;
import java.net.SocketException;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;

import net.ostis.sc.memory.SCActivity;
import net.ostis.sc.memory.SCAddr;
import net.ostis.sc.memory.SCConstraint;
import net.ostis.sc.memory.SCConstraintBase;
import net.ostis.sc.memory.SCConstraintInfo;
import net.ostis.sc.memory.SCContent;
import net.ostis.sc.memory.SCIterator;
import net.ostis.sc.memory.SCMemory;
import net.ostis.sc.memory.SCSegment;
import net.ostis.sc.memory.SCSession;
import net.ostis.sc.memory.SCType;
import net.ostis.sc.memory.SCWait;
import net.ostis.sc.memory.STDConstraints;

import org.apache.commons.lang3.Pair;

/**
 * @author Dmitry Lazurkin
 */
public class RGPSession implements SCSession, Runnable {

    private RGPMemory memory;

    private final Socket controlSocket;

    private final Socket eventSocket;

    private Thread eventThread;

    private RGPProtocolStream controlStream;

    private RGPProtocolStream eventStream;

    private RGPObjectsRegistry objectsRegistry;

    private Map<String, RGPSegment> openedSegments = new TreeMap<String, RGPSegment>();

    private Map<SCWait, RGPWait> wait2proxyWait = new HashMap<SCWait, RGPWait>();
    private Map<SCActivity, RGPActivity> activity2proxyActivity = new HashMap<SCActivity, RGPActivity>();

    private ThreadLocal<Integer> curArgsCount = new ThreadLocal<Integer>();
    private ThreadLocal<Integer> curRetval = new ThreadLocal<Integer>();

    boolean closed = false;

    public RGPSession(RGPMemory memory, Socket controlSocket, Socket eventSocket)
            throws IOException, RGPProtocolException {
        this.memory = memory;
        this.controlSocket = controlSocket;
        this.eventSocket = eventSocket;
        this.objectsRegistry = new RGPObjectsRegistry(this);
        this.controlStream = new RGPProtocolStream(controlSocket.getInputStream(), controlSocket.getOutputStream(),
                objectsRegistry);
        this.eventStream = new RGPProtocolStream(eventSocket.getInputStream(), eventSocket.getOutputStream(),
                objectsRegistry);

        eventThread = new Thread(this);
        eventThread.setName("RGP Events Listener");
        eventThread.setDaemon(true);
        eventThread.start();

        login();
    }

    @Override
    public void run() {
        try {
            while (!eventThread.isInterrupted()) {
                RGPCommandId replyId = eventStream.readCommandId();

                if (replyId == RGPCommandId.REQ_ACTIVATE_WAIT) {
                    int argsCount = eventStream.readArgsCount();

                    RGPWait wait = eventStream.readWait();
                    SCWait.Type waitType = eventStream.readWaitType();

                    --argsCount;
                    --argsCount;

                    Object[] params = new Object[argsCount];
                    for (int i = 0; i < argsCount; ++i) {
                        RGPArgumentType type = eventStream.readArgType();
                        switch (type) {
                        case SC_ADDR:
                            params[i] = eventStream.readAddrImpl();
                            break;
                        default:
                            break;
                        }
                    }

                    boolean result = wait.activate(waitType, params);
                    eventStream.writeCommandId(RGPCommandId.REP_RETURN);
                    eventStream.writeArgsCount(2);
                    eventStream.writeRetval(0);
                    eventStream.write(result);
                } else if (replyId == RGPCommandId.REQ_ACTIVATE) {
                    @SuppressWarnings("unused")
                    int argsCount = eventStream.readArgsCount();

                    RGPActivity activity = eventStream.readActivity();

                    --argsCount;

                    RGPAddr _this = eventStream.readAddr();
                    RGPAddr prm1 = eventStream.readAddr();
                    RGPAddr prm2 = eventStream.readAddr();
                    RGPAddr prm3 = eventStream.readAddr();
                    activity.activate(this, _this, prm1, prm2, prm3);
                }

                if (closed)
                    break;

                eventStream.writeCommandId(RGPCommandId.REP_RETURN);
                eventStream.writeArgsCount(1);
                eventStream.writeRetval(0);
            }
        } catch (SocketException e) {
            return;
        } catch (EOFException e) {
            return;
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    int getCurArgsCount() {
        return curArgsCount.get();
    }

    int getCurRetval() {
        return curRetval.get();
    }

    RGPObjectsRegistry getObjectsRegistry() {
        return objectsRegistry;
    }

    RGPProtocolStream getStream() {
        if (Thread.currentThread().equals(eventThread)) {
            return eventStream;
        } else {
            return controlStream;
        }
    }

    void fillNewSegment(RGPSegment segment) {
        RGPProtocolStream stream = getStream();
        synchronized (stream) {
            synchronized (segment) {
                try {
                    writeCommandStart(RGPCommandId.REQ_GET_SEG_INFO, 1);
                    stream.write(segment);

                    readReturn();
                    assertRetvalOk();

                    segment.setSign(stream.readAddr());
                    segment.setURI(stream.readString());
                    segment.setDead(stream.readBoolean());
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    void fillNewAddr(RGPAddr addr) {
        RGPProtocolStream stream = getStream();
        synchronized (stream) {
            synchronized (addr) {
                try {
                    writeCommandStart(RGPCommandId.REQ_GET_EL_INFO, 1);
                    stream.write(addr);

                    readReturn();
                    assertRetvalOk();

                    addr.setSegment(stream.readSegment());
                    addr.setDead(stream.readBoolean());
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    void readReturn() throws IOException, RGPProtocolException {
        synchronized (getStream()) {
            RGPProtocolStream stream = getStream();

            RGPCommandId replyId = stream.readCommandId();

            if (replyId != RGPCommandId.REP_RETURN)
                throw new RuntimeException("Expectes " + RGPCommandId.REP_RETURN + ", but recieved " + replyId);

            curArgsCount.set(stream.readArgsCount());

            if (curArgsCount.get() < 1)
                throw new RuntimeException(RGPCommandId.REP_RETURN + " with arguments count 0");

            curArgsCount.set(curArgsCount.get() - 1);

            curRetval.set(stream.readRetval());
        }
    }

    void assertRetvalOk() {
        if (curRetval.get() != 0)
            throw new RuntimeException("Retval is " + curRetval.get());
    }

    void writeCommandStart(RGPCommandId id, int argsCount) throws IOException {
        synchronized (getStream()) {
            RGPProtocolStream stream = getStream();
            stream.writeCommandId(id);
            stream.writeArgsCount(argsCount);
        }
    }

    private void login() throws IOException, RGPProtocolException {
        writeCommandStart(RGPCommandId.REQ_LOGIN, 1);
        getStream().write(true);
        readReturn();
        assertRetvalOk();
    }

    @Override
    public SCMemory getMemory() {
        return memory;
    }

    @Override
    public void close() {
        synchronized (getStream()) {
            try {
                writeCommandStart(RGPCommandId.REQ_CLOSE, 0);

                readReturn();
                assertRetvalOk();

                eventThread.interrupt();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    controlSocket.close();
                    eventSocket.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                closed = true;
            }
        }
    }

    @Override
    public SCSegment createSegment(String uri) {
        synchronized (getStream()) {
            RGPSegment segment = openedSegments.get(uri);
            if (segment == null) {
                try {
                    RGPProtocolStream stream = getStream();
                    writeCommandStart(RGPCommandId.REQ_CREATE_SEGMENT, 1);
                    stream.write(uri.toString());

                    readReturn();
                    assertRetvalOk();

                    segment = stream.readSegment();
                    RGPAddr sign = stream.readAddr();
                    if (segment.isNew()) {
                        segment.setSign(sign);
                        segment.setURI(uri);
                        openedSegments.put(uri, segment);
                    }

                    return segment;
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            return segment;
        }
    }

    @Override
    public void closeSegment(SCSegment segment) {
        synchronized (getStream()) {
        }
    }

    @Override
    public SCSegment openSegment(String uri) {
        synchronized (getStream()) {
            RGPSegment segment = openedSegments.get(uri);
            if (segment == null) {
                try {
                    RGPProtocolStream stream = getStream();
                    writeCommandStart(RGPCommandId.REQ_OPEN_SEGMENT, 1);
                    stream.write(uri.toString());

                    readReturn();
                    assertRetvalOk();

                    segment = stream.readSegment();
                    RGPAddr sign = stream.readAddr();
                    if (segment.isNew()) {
                        segment.setSign(sign);
                        segment.setURI(uri);
                        openedSegments.put(uri, segment);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            return segment;
        }
    }

    @Override
    public SCAddr findByIdtf(String idtf, SCSegment segment) {
        synchronized (getStream()) {
            try {
                RGPProtocolStream stream = getStream();
                writeCommandStart(RGPCommandId.REQ_FIND_BY_IDTF, 2);
                stream.write(idtf);
                stream.write((RGPSegment) segment);

                readReturn();

                RGPAddr addr = null;
                if (curArgsCount.get() > 0) {
                    addr = stream.readAddr();
                    if (addr.isNew())
                        addr.setSegment(segment);
                }

                return addr;
            } catch (Exception e) {
                e.printStackTrace();
            }

            return null;
        }
    }

    @Override
    public String getIdtf(SCAddr element) {
        synchronized (getStream()) {
            try {
                RGPProtocolStream stream = getStream();
                writeCommandStart(RGPCommandId.REQ_GET_IDTF, 1);
                stream.write((RGPAddr) element);

                readReturn();
                assertRetvalOk();

                return stream.readString();
            } catch (Exception e) {
                e.printStackTrace();
            }

            return null;
        }
    }

    @Override
    public void setIdtf(SCAddr addr, String idtf) {
        synchronized (getStream()) {
            try {
                RGPProtocolStream stream = getStream();
                writeCommandStart(RGPCommandId.REQ_SET_IDTF, 2);
                stream.write((RGPAddr) addr);
                stream.write(idtf);

                readReturn();
                assertRetvalOk();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public boolean isSegmentOpened(String uri) {
        return openedSegments.containsKey(uri);
    }

    @Override
    public synchronized void unlink(String uri) {
        // TODO Auto-generated method stub

    }

    @Override
    public SCAddr createElement(SCSegment segment, SCType type) {
        synchronized (getStream()) {
            try {
                RGPProtocolStream stream = getStream();
                writeCommandStart(RGPCommandId.REQ_CREATE_EL, 2);
                stream.write((RGPSegment) segment);
                stream.write(type);

                readReturn();

                RGPAddr addr = null;
                if (curArgsCount.get() > 0) {
                    addr = stream.readAddr();
                    if (addr.isNew())
                        addr.setSegment(segment);
                }

                return addr;
            } catch (Exception e) {
                e.printStackTrace();
            }

            return null;
        }
    }

    @Override
    public SCAddr gen3_f_a_f(SCAddr e1, SCSegment seg2, SCType t2, SCAddr e3) {
        synchronized (getStream()) {
            try {
                RGPProtocolStream stream = getStream();
                writeCommandStart(RGPCommandId.REQ_GEN3_F_A_F, 4);
                stream.write((RGPAddr) e1);
                stream.write((RGPSegment) seg2);
                stream.write(t2);
                stream.write((RGPAddr) e3);

                readReturn();

                RGPAddr addr = null;
                if (curArgsCount.get() > 0) {
                    addr = stream.readAddr();
                    if (addr.isNew())
                        addr.setSegment(seg2);
                }

                return addr;
            } catch (Exception e) {
                e.printStackTrace();
            }

            return null;
        }
    }

    @Override
    public Pair<SCAddr, SCAddr> gen5_f_a_f_a_f(SCAddr e1, SCSegment seg2, SCType t2, SCAddr e3, SCSegment seg4,
            SCType t4, SCAddr e5) {
        synchronized (getStream()) {
            try {
                RGPProtocolStream stream = getStream();
                writeCommandStart(RGPCommandId.REQ_GEN3_F_A_F, 4);
                stream.write((RGPAddr) e1);
                stream.write((RGPSegment) seg2);
                stream.write(t2);
                stream.write((RGPAddr) e3);
                stream.write((RGPSegment) seg4);
                stream.write(t4);
                stream.write((RGPAddr) e5);

                readReturn();

                RGPAddr addr2 = null;
                RGPAddr addr4 = null;
                if (curArgsCount.get() > 0) {
                    addr2 = stream.readAddr();
                    if (addr2.isNew())
                        addr2.setSegment(seg2);

                    addr4 = stream.readAddr();
                    if (addr4.isNew())
                        addr4.setSegment(seg4);
                }

                return new Pair<SCAddr, SCAddr>(addr2, addr4);
            } catch (Exception e) {
                e.printStackTrace();
            }

            return null;
        }
    }

    @Override
    public void eraseElement(SCAddr element) {
        synchronized (getStream()) {
            try {
                RGPProtocolStream stream = getStream();
                writeCommandStart(RGPCommandId.REQ_ERASE_EL, 1);
                stream.write((RGPAddr) element);

                readReturn();
                assertRetvalOk(); // TODO: throw exception
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public void mergeElement(SCAddr from, SCAddr to) {
        synchronized (getStream()) {
        }
    }

    @Override
    public SCAddr getBegin(SCAddr arc) {
        synchronized (getStream()) {
            try {
                RGPProtocolStream stream = getStream();
                writeCommandStart(RGPCommandId.REQ_GET_EL_BEGIN, 1);
                stream.write((RGPAddr) arc);

                readReturn();
                assertRetvalOk();

                RGPAddr addr = null;
                if (curArgsCount.get() > 0)
                    addr = stream.readAddr();

                return addr;
            } catch (Exception e) {
                e.printStackTrace();
            }

            return null;
        }
    }

    @Override
    public void setBegin(SCAddr arc, SCAddr from) {
        synchronized (getStream()) {
            try {
                RGPProtocolStream stream = getStream();
                writeCommandStart(RGPCommandId.REQ_SET_EL_BEGIN, 2);
                stream.write((RGPAddr) arc);
                stream.write((RGPAddr) from);

                readReturn();
                assertRetvalOk();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public SCAddr getEnd(SCAddr arc) {
        synchronized (getStream()) {
            try {
                RGPProtocolStream stream = getStream();
                writeCommandStart(RGPCommandId.REQ_GET_EL_END, 1);
                stream.write((RGPAddr) arc);

                readReturn();
                assertRetvalOk();

                RGPAddr addr = null;
                if (curArgsCount.get() > 0)
                    addr = stream.readAddr();

                return addr;
            } catch (Exception e) {
                e.printStackTrace();
            }

            return null;
        }
    }

    @Override
    public void setEnd(SCAddr arc, SCAddr to) {
        synchronized (getStream()) {
            try {
                RGPProtocolStream stream = getStream();
                writeCommandStart(RGPCommandId.REQ_SET_EL_END, 2);
                stream.write((RGPAddr) arc);
                stream.write((RGPAddr) to);

                readReturn();
                assertRetvalOk();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public SCType getType(SCAddr el) {
        synchronized (getStream()) {
            try {
                RGPProtocolStream stream = getStream();
                writeCommandStart(RGPCommandId.REQ_GET_EL_TYPE, 1);
                stream.write((RGPAddr) el);

                readReturn();
                assertRetvalOk();

                return stream.readType();
            } catch (Exception e) {
                e.printStackTrace();
            }

            return null;
        }
    }

    @Override
    public void changeType(SCAddr element, SCType type) {
        synchronized (getStream()) {
            try {
                RGPProtocolStream stream = getStream();
                writeCommandStart(RGPCommandId.REQ_CHANGE_EL_TYPE, 2);
                stream.write((RGPAddr) element);
                stream.write(type);

                readReturn();
                assertRetvalOk();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public SCContent getContent(SCAddr element) {
        synchronized (getStream()) {
            SCContent content = null;

            try {
                RGPProtocolStream stream = getStream();
                writeCommandStart(RGPCommandId.REQ_GET_EL_CONTENT, 1);
                stream.write((RGPAddr) element);

                readReturn();
                assertRetvalOk();
                content = stream.readContent();
            } catch (Exception e) {
                e.printStackTrace();
            }

            return content;
        }
    }

    @Override
    public void setContent(SCAddr element, SCContent content) {
        synchronized (getStream()) {
            try {
                RGPProtocolStream stream = getStream();
                writeCommandStart(RGPCommandId.REQ_SET_EL_CONTENT, 2);
                stream.write((RGPAddr) element);
                stream.write(content);

                readReturn();
                assertRetvalOk();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public SCIterator createIterator(SCConstraint constraint) {
        synchronized (getStream()) {
            RGPIterator iterator = null;

            try {
                SCConstraintInfo info = constraint.getInfo();
                RGPProtocolStream stream = getStream();
                writeCommandStart(RGPCommandId.REQ_CREATE_ITERATOR, 1 + info.getParamsCount());
                stream.write(constraint.getInfo());

                int paramsCount = info.getParamsCount();
                for (int i = 0; i < paramsCount; ++i) {
                    Object param = constraint.get(i);
                    SCConstraintInfo.ParamType t = info.getParamType(i);

                    if (t == SCConstraintInfo.ParamType.SC_ADDR) {
                        stream.write((RGPAddr) param);
                    } else if (t == SCConstraintInfo.ParamType.SC_TYPE) {
                        stream.write((SCType) param);
                    } else if (t == SCConstraintInfo.ParamType.SC_SEGMENT) {
                        stream.write((RGPSegment) param);
                    } else if (t == SCConstraintInfo.ParamType.SC_BOOLEAN) {
                        stream.write((Boolean) param);
                    }
                }

                readReturn();
                assertRetvalOk();

                iterator = stream.readIterator();
                curArgsCount.set(curArgsCount.get() - 1);

                if (info.getName().equals(STDConstraints.CONSTR_ON_SEGMENT.getName()))
                    iterator.setNeedValues(new Integer[] { 0 });
                iterator.setConstraint(constraint);
                iterator.setSession(this);
                iterator.fetchState();
            } catch (Exception e) {
                e.printStackTrace();
            }

            return iterator;
        }
    }

    @Override
    public void eraseIterator(SCIterator iterator) {
        RGPIterator it = (RGPIterator) iterator;
        it.erase();
    }

    @Override
    public boolean searchOneshort(SCConstraintBase constraint, Object... arguments) {
        synchronized (getStream()) {
            // TODO Auto-generated method stub
            return false;
        }
    }

    @Override
    public void attachWait(SCWait wait, SCWait.Type type, Object... params) {
        synchronized (getStream()) {
            try {
                RGPProtocolStream stream = getStream();
                writeCommandStart(RGPCommandId.REQ_ATTACH_WAIT, 1 + params.length);
                stream.write(type);

                for (Object param : params) {
                    if (param instanceof SCAddr) {
                        stream.write((RGPAddr) param);
                    } else if (param instanceof SCSegment) {
                        stream.write((RGPSegment) param);
                    } else if (param instanceof SCType) {
                        stream.write((SCType) param);
                    }
                }

                readReturn();
                assertRetvalOk();
                RGPWait proxyWait = stream.readWait();
                proxyWait.setWait(wait);
                wait2proxyWait.put(wait, proxyWait);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public void detachWait(SCWait wait) {
        synchronized (getStream()) {
            RGPWait proxyWait = wait2proxyWait.get(wait);
            if (proxyWait == null)
                throw new RuntimeException("Detach for unregistred wait");

            try {
                RGPProtocolStream stream = getStream();
                writeCommandStart(RGPCommandId.REQ_DETACH_WAIT, 1);
                stream.write(proxyWait);

                readReturn();
                assertRetvalOk();

                wait2proxyWait.remove(wait);
                objectsRegistry.unregister(proxyWait);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public void activate(SCAddr element, SCAddr... arguments) {
        synchronized (getStream()) {
            try {
                RGPProtocolStream stream = getStream();
                writeCommandStart(RGPCommandId.REQ_ACTIVATE, 4);
                stream.write((RGPAddr) element);

                for (SCAddr addr : arguments)
                    stream.write((RGPAddr) addr);

                readReturn();
                assertRetvalOk();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public void reimplement(SCAddr element, SCActivity activity) {
        synchronized (getStream()) {
            try {
                RGPProtocolStream stream = getStream();
                writeCommandStart(RGPCommandId.REQ_REIMPLEMENT, 1);
                stream.write((RGPAddr) element);

                readReturn();
                assertRetvalOk();
                RGPActivity proxyActivity = stream.readActivity();
                proxyActivity.setActivity(activity);
                activity2proxyActivity.put(activity, proxyActivity);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}