FileDocCategorySizeDatePackage
ServerOperation.javaAPI DocphoneME MR2 API (J2ME)17303Wed May 02 18:00:32 BST 2007com.sun.kvem.jsr082.obex

ServerOperation

public final class ServerOperation extends Object implements javax.obex.Operation
The class implements server side of put/get operation.

Fields Summary
private static final boolean
DEBUG
private Object
lock
private HeaderSetImpl
recvHeaders
private ServerConnectionImpl
stream
private int
opcode
private boolean
isGet
private boolean
isAborted
private boolean
requestEnd
private boolean
inputStreamOpened
private boolean
outputStreamOpened
private boolean
inputStreamEof
private OperationInputStream
is
private OperationOutputStream
os
private byte[]
head
Constructors Summary
ServerOperation(ServerConnectionImpl stream)
Constructor for get operation.



         
        
        this.stream = stream;
        opcode = ObexPacketStream.OPCODE_GET;
        isGet = true;
        recvHeaders = new HeaderSetImpl(HeaderSetImpl.OWNER_SERVER);
        int mode = waitForData(stream,
                recvHeaders, ObexPacketStream.OPCODE_GET);
        switch (mode) {
            case 0:
                isAborted = true;
                stream.operationClosed = true;
                break;
            case 2:
                requestEnd = true;
                // no data was received
                inputStreamEof = true;
                stream.packetBegin(head);
                // Response packets can contains both TARGET and CONN ID headers
                stream.packetAddConnectionID(stream.getConnectionID(), null);
                stream.packetAddAuthResponses();
                stream.packetAddHeaders(null);
                break;
        }
    
ServerOperation(ServerConnectionImpl stream, HeaderSetImpl recvHeaders)
Constructor for put operation.

        // data parsing mode already on.
        this.stream = stream;
        opcode = ObexPacketStream.OPCODE_PUT;
        isGet = false;
        this.recvHeaders = recvHeaders;

    
Methods Summary
public voidabort()

        // forbidden on server
        throw new IOException("not permitted");
    
public voidclose()

        stream.operationClosed = true;
    
voiddestroy(int status)
Called by ServerRequestHandler to finish any activity remaining and to return errorcode to client.

        if (DEBUG) {
            System.out.println("server: destroy()");
        }
        try {
            outputStreamOpened = false;
            if (!requestEnd) {
                stream.packetBegin(head);
                stream.packetAddConnectionID(stream.getConnectionID(), null);
                stream.packetAddAuthResponses();
            }
            stream.packetAddHeaders(null);
            close();
            if (isAborted) status = ResponseCodes.OBEX_HTTP_OK;
            stream.setPacketType(status);
            stream.packetEnd(); // send final packet
        } catch (Throwable t) {
            // ignore
        }
        // remaining headers will be lost
        stream.queuedHeaders.removeAllElements();
    
public java.lang.StringgetEncoding()

        return null; // acording to docs
    
public longgetLength()

        Long res = (Long)recvHeaders.getHeader(HeaderSetImpl.LENGTH);
        if (res == null) {
            return -1;
        }
        return res.longValue();
    
public javax.obex.HeaderSetgetReceivedHeaders()

        synchronized (lock) {
            if (stream.operationClosed) {
                throw new IOException("operation closed");
            }
            return new HeaderSetImpl(recvHeaders);
        }
    
public intgetResponseCode()

        // forbidden on server
        throw new IOException("not permitted");
    
public java.lang.StringgetType()

        return (String)recvHeaders.getHeader(HeaderSetImpl.TYPE);
    
public java.io.DataInputStreamopenDataInputStream()

        return new DataInputStream(openInputStream());
    
public java.io.DataOutputStreamopenDataOutputStream()

        return new DataOutputStream(openOutputStream());
    
public java.io.InputStreamopenInputStream()

        if (DEBUG) {
            System.out.println("server: openInputStream()");
        }
        synchronized (lock) {
            if (stream.operationClosed) {
                throw new IOException("operation closed");
            }
            if (inputStreamOpened) {
                throw new IOException("no more input streams available");
            }
            inputStreamOpened = true;            
            return is;
        }
    
public java.io.OutputStreamopenOutputStream()

        if (DEBUG) {
            System.out.println("server: openOutputStream()");
        }
        synchronized (lock) {
            if (stream.operationClosed) {
                throw new IOException("operation closed");
            }
            if (outputStreamOpened) {
                throw new IOException("no more output streams available");
            }
            if (!requestEnd) {
                throw new IOException("input data not read out");
            }
            outputStreamOpened = true;
            return os;
        }
    
private voidpacketExchange()

        if (DEBUG) {
            System.out.println("server: packetExchange()");
        }
        if (stream.operationHeadersOverflow) {
            throw new IOException("operation terminated, too long headers");
        }
        if (!requestEnd) {
            // reading out input stream
            requestEnd =
                stream.packetType == (opcode | ObexPacketStream.OPCODE_FINAL);

            // inordenary case: EOF-DATA but no final bit
            if (stream.isEof && !requestEnd) {
                while (recvHeaders.packetType
                        == ObexPacketStream.OPCODE_PUT) {
                    // not final - waiting for final, data not allowed
                    // after EOFB
                    stream.sendPacket(head, stream.getConnectionID(),
				      null, false);
                    stream.recvPacket();
                    stream.parsePacketHeaders(recvHeaders, 3);
                }

                if (recvHeaders.packetType
                        == ObexPacketStream.OPCODE_ABORT) {
                    stream.operationClosed = true;
                    isAborted = true;
                    throw new IOException("operation aborted");
                }

                if (stream.packetType !=
                        (opcode | ObexPacketStream.OPCODE_FINAL)) {
                    stream.operationClosed = true;
                    stream.brokenLink();
                    throw new IOException("protocol error");
                }
            }
            if (requestEnd) {
                // switch to requestEnd packetExchange mode
                stream.packetBegin(head);
                stream.packetAddConnectionID(stream.getConnectionID(), null);
                stream.packetAddAuthResponses();
                stream.packetAddHeaders(null);
                return;
            }
            // stream.parseEnd();
            stream.sendPacket(ObexPacketStream.PACKET_CONTINUE,
			      stream.getConnectionID(), null, false);
            stream.recvPacket();

            if (stream.packetType == ObexPacketStream.OPCODE_ABORT) {
                stream.parsePacketHeaders(recvHeaders, 3);
                isAborted = true;
                stream.operationClosed = true;
                throw new IOException("operation aborted");
            }

            if ((stream.packetType & ~ObexPacketStream.OPCODE_FINAL)
                    != opcode) {
                stream.operationClosed = true;
                stream.brokenLink();
                throw new IOException("protocol error");
            }
            stream.parsePacketDataBegin(recvHeaders, 3);
            return;
        }
        stream.packetEnd();
        stream.recvPacket();
        stream.parsePacketHeaders(recvHeaders, 3);

        if (stream.packetType == ObexPacketStream.OPCODE_ABORT) {
	    // prepare response packet
            stream.packetBegin(ObexPacketStream.PACKET_SUCCESS);
            stream.packetAddConnectionID(stream.getConnectionID(), null);
            stream.packetAddAuthResponses();
            stream.packetAddHeaders(null);
	    
            isAborted = true;
            stream.operationClosed = true;
            throw new IOException("operation aborted");
        }

        if (stream.packetType == ObexPacketStream.OPCODE_DISCONNECT) {
            stream.sendPacket(ObexPacketStream.PACKET_SUCCESS,
                stream.getConnectionID(), null, false);

            stream.close();
            return;
        }

        if (stream.packetType != (opcode | ObexPacketStream.OPCODE_FINAL)) {
            stream.operationClosed = true;
            stream.brokenLink();
            throw new IOException("protocol error");
        }

        stream.packetBegin(head);
        stream.packetAddConnectionID(stream.getConnectionID(), null);
        stream.packetAddAuthResponses();
        stream.packetAddHeaders(null);
    
public voidsendHeaders(javax.obex.HeaderSet headers)

        if (DEBUG) {
            System.out.println("server: sendHeaders()");
        }
        synchronized (lock) {
            if (stream.operationClosed) {
                throw new IOException("operation closed");
            }
            if (headers == null) {
                throw new NullPointerException("null headerset");
            }
            if (!(headers instanceof HeaderSetImpl)) {
                throw new IllegalArgumentException("wrong headerset class");
            }
            HeaderSetImpl headersImpl = (HeaderSetImpl) headers;
            if (!headersImpl.isSendable()) {
                throw new IllegalArgumentException(
                        "not created with createHeaderSet");
            }

            stream.packetAddHeaders(headersImpl);

            if (requestEnd && isGet) {
                while (!stream.queuedHeaders.isEmpty()) {
                    packetExchange();
                }
            }
        }
    
static intwaitForData(ServerConnectionImpl stream, HeaderSetImpl inputHeaderSet, int op)

        if (DEBUG) {
            System.out.println("server: waitForData()");
        }

        // check of errorcode should be done before after data parsing
        stream.parsePacketDataBegin(inputHeaderSet, 3);

        // special request to check data availability
        int hasData = stream.parsePacketData(inputHeaderSet, null, 0, 0);

        // waiting for data or final bit or abort
        while (true) {
            if (stream.packetType == ObexPacketStream.OPCODE_ABORT) {
                return 0;
            }

            if (hasData == 1 || stream.isEof) {
                return 1; // has data
            }

            if (stream.packetType == (op | ObexPacketStream.OPCODE_FINAL)) {
                return 2; // final
            }

            if (stream.packetType != op) {
                stream.brokenLink();
                throw new IOException("protocol error");
            }

            stream.sendPacket(ObexPacketStream.PACKET_CONTINUE,
			      stream.getConnectionID(), null, false);
            stream.recvPacket();

            // check of errorcode should be done before after data parsing
            stream.parsePacketDataBegin(inputHeaderSet, 3);

            // special request to check data availability
            hasData = stream.parsePacketData(inputHeaderSet, null, 0, 0);
        }