001    /*
002     * Copyright (C) 2008-2010 by Holger Arndt
003     *
004     * This file is part of the Universal Java Matrix Package (UJMP).
005     * See the NOTICE file distributed with this work for additional
006     * information regarding copyright ownership and licensing.
007     *
008     * UJMP is free software; you can redistribute it and/or modify
009     * it under the terms of the GNU Lesser General Public License as
010     * published by the Free Software Foundation; either version 2
011     * of the License, or (at your option) any later version.
012     *
013     * UJMP is distributed in the hope that it will be useful,
014     * but WITHOUT ANY WARRANTY; without even the implied warranty of
015     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
016     * GNU Lesser General Public License for more details.
017     *
018     * You should have received a copy of the GNU Lesser General Public
019     * License along with UJMP; if not, write to the
020     * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
021     * Boston, MA  02110-1301  USA
022     */
023    
024    package org.ujmp.core.objectmatrix.impl;
025    
026    import java.io.ByteArrayInputStream;
027    import java.io.ByteArrayOutputStream;
028    import java.io.ObjectInputStream;
029    import java.io.ObjectOutputStream;
030    import java.net.DatagramPacket;
031    import java.net.DatagramSocket;
032    
033    import org.ujmp.core.Coordinates;
034    import org.ujmp.core.Matrix;
035    import org.ujmp.core.exceptions.MatrixException;
036    import org.ujmp.core.objectmatrix.stub.AbstractSparseObjectMatrix;
037    
038    public class ServerObjectMatrixUDP extends AbstractSparseObjectMatrix {
039            private static final long serialVersionUID = 3907994158174208114L;
040    
041            private static final int BUFFERSIZE = 512;
042    
043            public static final int GETDOUBLEVALUE = 0;
044    
045            public static final int SETDOUBLEVALUE = 1;
046    
047            public static final int GETDIMENSIONCOUNT = 2;
048    
049            private Matrix matrix = null;
050    
051            private DatagramSocket socket = null;
052    
053            private DatagramPacket receivedPacket = null;
054    
055            private ServerThread thread = null;
056    
057            public ServerObjectMatrixUDP(Matrix matrix, int port) {
058                    this.matrix = matrix;
059    
060                    try {
061                            receivedPacket = new DatagramPacket(new byte[BUFFERSIZE], BUFFERSIZE);
062                            thread = new ServerThread();
063                            socket = new DatagramSocket(port);
064                            thread.start();
065                    } catch (Exception e) {
066                            throw new MatrixException("could not open socket", e);
067                    }
068            }
069    
070            public long[] getSize() {
071                    return matrix.getSize();
072            }
073    
074            public double getAsDouble(long... coordinates) throws MatrixException {
075                    return matrix.getAsDouble(coordinates);
076            }
077    
078            public Object getObject(long... coordinates) throws MatrixException {
079                    return matrix.getAsObject(coordinates);
080            }
081    
082            public long getValueCount() {
083                    return matrix.getValueCount();
084            }
085    
086            public void setAsDouble(double value, long... coordinates) throws MatrixException {
087                    matrix.setAsDouble(value, coordinates);
088            }
089    
090            public void setObject(Object o, long... coordinates) throws MatrixException {
091                    matrix.setAsObject(o, coordinates);
092            }
093    
094            class ServerThread extends Thread {
095    
096                    public ServerThread() {
097    
098                    }
099    
100                    public void run() {
101    
102                            try {
103    
104                                    while (true) {
105    
106                                            socket.receive(receivedPacket);
107    
108                                            ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(
109                                                            receivedPacket.getData()));
110                                            ByteArrayOutputStream bos = new ByteArrayOutputStream(BUFFERSIZE);
111                                            ObjectOutputStream oos = new ObjectOutputStream(bos);
112    
113                                            int command = ois.readInt();
114                                            Coordinates coordinates = null;
115                                            double value = 0.0;
116                                            switch (command) {
117                                            case SETDOUBLEVALUE:
118                                                    coordinates = (Coordinates) ois.readObject();
119                                                    value = ois.readDouble();
120                                                    setAsDouble(value, coordinates.co);
121                                                    oos.writeInt(SETDOUBLEVALUE);
122                                                    break;
123                                            case GETDOUBLEVALUE:
124                                                    coordinates = (Coordinates) ois.readObject();
125                                                    value = getAsDouble(coordinates.co);
126                                                    oos.writeInt(GETDOUBLEVALUE);
127                                                    oos.writeDouble(value);
128                                                    break;
129                                            case GETDIMENSIONCOUNT:
130                                                    int dimension = ois.readInt();
131                                                    int result = (int) getSize(dimension);
132                                                    oos.writeInt(GETDIMENSIONCOUNT);
133                                                    oos.writeInt(result);
134                                                    break;
135                                            }
136    
137                                            oos.flush();
138    
139                                            DatagramPacket sentPacket = new DatagramPacket(bos.toByteArray(), bos.size(),
140                                                            receivedPacket.getAddress(), receivedPacket.getPort());
141                                            socket.send(sentPacket);
142    
143                                    }
144    
145                            } catch (Exception e) {
146                                    throw new MatrixException("error in data transmission", e);
147                            }
148                    }
149            }
150    
151            public boolean contains(long... coordinates) {
152                    return matrix.contains(coordinates);
153            }
154    
155            public boolean isReadOnly() {
156                    return matrix.isReadOnly();
157            }
158    
159    }