1 /*
2  * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 package com.sun.hotspot.igv.connection;
26 
27 import com.sun.hotspot.igv.data.GraphDocument;
28 import com.sun.hotspot.igv.data.services.GroupCallback;
29 import com.sun.hotspot.igv.settings.Settings;
30 import java.io.IOException;
31 import java.net.InetSocketAddress;
32 import java.nio.channels.ServerSocketChannel;
33 import java.nio.channels.SocketChannel;
34 import java.util.prefs.PreferenceChangeEvent;
35 import java.util.prefs.PreferenceChangeListener;
36 import org.openide.DialogDisplayer;
37 import org.openide.NotifyDescriptor;
38 import org.openide.util.RequestProcessor;
39 
40 /**
41  *
42  * @author Thomas Wuerthinger
43  */
44 public class Server implements PreferenceChangeListener {
45     private final boolean binary;
46     private ServerSocketChannel serverSocket;
47     private final GraphDocument rootDocument;
48     private final GroupCallback callback;
49     private int port;
50     private Runnable serverRunnable;
51 
Server(GraphDocument rootDocument, GroupCallback callback, boolean binary)52     public Server(GraphDocument rootDocument, GroupCallback callback, boolean binary) {
53         this.binary = binary;
54         this.rootDocument = rootDocument;
55         this.callback = callback;
56         initializeNetwork();
57         Settings.get().addPreferenceChangeListener(this);
58     }
59 
60     @Override
preferenceChange(PreferenceChangeEvent e)61     public void preferenceChange(PreferenceChangeEvent e) {
62 
63         int curPort = Integer.parseInt(Settings.get().get(binary ? Settings.PORT_BINARY : Settings.PORT, binary ? Settings.PORT_BINARY_DEFAULT : Settings.PORT_DEFAULT));
64         if (curPort != port) {
65             initializeNetwork();
66         }
67     }
68 
initializeNetwork()69     private void initializeNetwork() {
70 
71         int curPort = Integer.parseInt(Settings.get().get(binary ? Settings.PORT_BINARY : Settings.PORT, binary ? Settings.PORT_BINARY_DEFAULT : Settings.PORT_DEFAULT));
72         this.port = curPort;
73         try {
74             serverSocket = ServerSocketChannel.open();
75             serverSocket.bind(new InetSocketAddress(curPort));
76         } catch (Throwable ex) {
77             NotifyDescriptor message = new NotifyDescriptor.Message("Could not create server. Listening for incoming binary data is disabled.", NotifyDescriptor.ERROR_MESSAGE);
78             DialogDisplayer.getDefault().notifyLater(message);
79             return;
80         }
81 
82         Runnable runnable = new Runnable() {
83 
84             @Override
85             public void run() {
86                 while (true) {
87                     try {
88                         SocketChannel clientSocket = serverSocket.accept();
89                         if (serverRunnable != this) {
90                             clientSocket.close();
91                             return;
92                         }
93                         RequestProcessor.getDefault().post(new Client(clientSocket, rootDocument, callback, binary), 0, Thread.MAX_PRIORITY);
94                     } catch (IOException ex) {
95                         serverSocket = null;
96                         NotifyDescriptor message = new NotifyDescriptor.Message("Error during listening for incoming connections. Listening for incoming binary data is disabled.", NotifyDescriptor.ERROR_MESSAGE);
97                         DialogDisplayer.getDefault().notifyLater(message);
98                         return;
99                     }
100                 }
101             }
102         };
103 
104         serverRunnable = runnable;
105 
106         RequestProcessor.getDefault().post(runnable, 0, Thread.MAX_PRIORITY);
107     }
108 }
109