001package csheets.ext.share.core;
002
003import java.io.IOException;
004import java.net.*;
005import java.util.*;
006import java.util.logging.*;
007
008import csheets.core.Cell;
009
010/**
011 * Class that implement the server in the extension
012 * 
013 * @author Andre
014 * 
015 */
016public class Server extends Observable implements Runnable {
017        /** the connection port */
018        /** the cells we will pass throw network */
019        private Cell[][] cells;
020        /** server socket */
021        private ServerSocket svr;
022        /** connection passoword */
023        private String password;
024        /** observer class */
025        private Observer observer;
026        /** the properties of the connection */
027        private String properties;
028        /** the sockets list */
029        private final ArrayList<Socket> sockets = new ArrayList<Socket>();
030        /** the cell listeners */
031        private final CellNetworkListenerServer listener = new CellNetworkListenerServer();
032        /** the running instance */
033        private static Server instance = null;
034
035        /**
036         * Create a new server
037         */
038        private Server() {
039        }
040
041        /**
042         * Method that returns the running instance of the server
043         * 
044         * @return the running instance of the server
045         */
046        public static synchronized Server getInstance() {
047                if (instance == null)
048                        instance = new Server();
049                return instance;
050        }
051
052        /**
053         * Method that returns the listener of the cells
054         * 
055         * @return the listener of the cells
056         */
057        public CellNetworkListenerServer getListener() {
058                return listener;
059        }
060
061        /**
062         * Method that returns the properties of the connection
063         * 
064         * @return the properties of the connection
065         */
066        public String getProperties() {
067                return properties;
068        }
069
070        /**
071         * Create internaly a new client
072         * 
073         * @param cells
074         *            the cells we will pass throw network
075         * @param svr
076         *            the server socket
077         * @param password
078         *            the connection password
079         * @param properties
080         *            the connection properties
081         * @param observer
082         *            the observer class
083         */
084        private Server(Cell[][] cells, ServerSocket svr, String password,
085                        String properties, Observer observer) {
086                this.cells = cells;
087                this.svr = svr;
088                this.password = password;
089                this.properties = properties;
090                this.observer = observer;
091        }
092
093        /**
094         * Return the cells to be share
095         * 
096         * @return the shared cells
097         */
098        public Cell[][] getCells() {
099                return cells;
100        }
101
102        /**
103         * Method that will start the server and share the cells throw network
104         * 
105         * @param port
106         *            connection port
107         * @param cells
108         *            value that will be shared throw network
109         * @param password
110         *            the connection password
111         * @param properties
112         *            the connection properties
113         * @param observer
114         *            the observer class
115         */
116        public void startServer(int port, Cell[][] cells, String password,
117                        String properties, Observer observer) {
118
119                try {
120                        for (int i = 0; i < cells.length; i++) {
121                                for (int j = 0; j < cells[i].length; j++) {
122                                        cells[i][j].addCellListener(listener);
123                                }
124                        }
125                        svr = new ServerSocket(port);
126                        this.cells = cells;
127                        this.password = password;
128                        this.properties = properties;
129                        this.observer = observer;
130                        addObserver(observer);
131
132                        Thread thr = new Thread(getInstance());
133                        thr.start();
134
135                        ServerDiscover.getInstance().findClients(port, observer);
136                } catch (Exception e) {
137                        Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, e);
138                        setChanged();
139                        notifyObservers();
140                        clearChanged();
141                }
142
143        }
144
145        /**
146         * Return the connection sockets
147         * 
148         * @return the connection sockets
149         */
150        public ArrayList<Socket> getSockets() {
151                return sockets;
152        }
153
154        /**
155         * running thread
156         */
157        @Override
158        public void run() {
159                try {
160                        while (true) {
161                                Socket sock = svr.accept();
162                                sockets.add(sock);
163                                addObserver(observer);
164
165                                Thread thr = new Thread(new ThreadServer(cells, sock, password,
166                                                observer));
167                                thr.start();
168
169                                if (properties.equals("wr")) {
170                                        Thread tr = new Thread(new ThreadServerReceiving(sock,
171                                                        getListener(), observer));
172                                        tr.start();
173                                }
174                        }
175
176                } catch (IOException e) {
177                        // JOptionPane.showMessageDialog(null, "Connection Error");
178                        Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, e);
179                        setChanged();
180                        notifyObservers();
181                        clearChanged();
182                }
183        }
184}