001/** 002 * Copyright (C) 2014 Universidade de Aveiro, DETI/IEETA, Bioinformatics Group - http://bioinformatics.ua.pt/ 003 * 004 * This file is part of Dicoogle/dicoogle. 005 * 006 * Dicoogle/dicoogle is free software: you can redistribute it and/or modify 007 * it under the terms of the GNU General Public License as published by 008 * the Free Software Foundation, either version 3 of the License, or 009 * (at your option) any later version. 010 * 011 * Dicoogle/dicoogle is distributed in the hope that it will be useful, 012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 014 * GNU General Public License for more details. 015 * 016 * You should have received a copy of the GNU General Public License 017 * along with Dicoogle. If not, see <http://www.gnu.org/licenses/>. 018 */ 019package pt.ua.dicoogle; 020 021import org.dcm4che2.data.TransferSyntax; 022import org.slf4j.Logger; 023import org.slf4j.LoggerFactory; 024import org.xml.sax.SAXException; 025import pt.ua.dicoogle.DicomLog.LogDICOM; 026import pt.ua.dicoogle.DicomLog.LogXML; 027import pt.ua.dicoogle.core.*; 028import pt.ua.dicoogle.plugins.PluginController; 029import pt.ua.dicoogle.rGUI.client.windows.ConnectWindow; 030import pt.ua.dicoogle.sdk.Utils.Platform; 031import pt.ua.dicoogle.sdk.utils.TagsStruct; 032 033 034import javax.swing.*; 035import java.awt.*; 036import java.io.File; 037import java.io.FileNotFoundException; 038import java.io.IOException; 039import java.net.InetAddress; 040import java.net.SocketException; 041import java.net.URI; 042import java.net.UnknownHostException; 043import java.util.*; 044 045/** 046 * Main class for Dicoogle 047 * @author Filipe Freitas 048 * @author Luís A. Bastião Silva <bastiao@ua.pt> 049 * @author Samuel Campos <samuelcampos@ua.pt> 050 * @author Eduardo Pinho <eduardopinho@ua.pt> 051 */ 052public class Main 053{ 054 private static final Logger logger = LoggerFactory.getLogger(Main.class); 055 056 private static boolean optimizeMemory = true; 057 private static boolean isGUIServer = false; 058 //indicates whether the client and the server were pulled at the same time 059 private static boolean isFixedClient = false; 060 private static int remoteGUIPort = 0; 061 public static boolean MAC_OS_X = (System.getProperty("os.name").toLowerCase().startsWith("mac os x")); 062 /** 063 * Generate a random integer number between 0 and 100 064 * 065 * This is used to verify if the RMI client is in the same 066 * process as the RMI server. 067 * The client as 1/1000 probability to hit the correct number 068 * if it is not in the same process. 069 */ 070 public static int randomInteger = (new Random()).nextInt(1001); 071 072 /** 073 * Starts the graphical user interface for Dicoogle 074 * @param args the command line arguments 075 */ 076 public static void main(String[] args) 077 { 078 //System.setProperty("log4j.configurationFile", "log4j-2.xml"); 079 //PropertyConfigurator.configure("log4j.properties"); 080 if (Platform.getMode() == Platform.MODE.BUNDLE) 081 { 082 File homeDir = new File(Platform.homePath()); 083 if (!homeDir.exists()) 084 { 085 homeDir.mkdir(); 086 } 087 } 088 089 if (args.length == 0) 090 { 091 isFixedClient = true; 092 093 LaunchDicoogle(); 094 LaunchWebApplication(); 095 } else { 096 097 if (args[0].equals("-v")) 098 { 099 isFixedClient = true; 100 //DebugManager.getInstance().setDebug(true); 101 LaunchDicoogle(); 102 //DebugManager.getInstance().debug("Starting Client Thread"); 103 LaunchWebApplication(); 104 } 105 if (args[0].equals("-s")) 106 { 107 LaunchDicoogle(); 108 } else if (args[0].equals("-g") || args[0].equals("--gui")) 109 { 110 LaunchDicoogle(); 111 LaunchGUIClient(); 112 } else if (args[0].equals("-c")) 113 { 114 LaunchGUIClient(); 115 } 116 else if (args[0].equals("-w") || args[0].equals("--web") || args[0].equals("--webapp")) { 117 // open browser 118 LaunchDicoogle(); 119 LaunchWebApplication(); 120 } 121 else if (args[0].equals("-h") || args[0].equals("--h") || args[0].equals("-help") || args[0].equals("--help")) 122 { 123 System.out.println("Dicoogle PACS: help"); 124 System.out.println("-s : Start the server"); 125 System.out.println("-w : Start the server and load web application in default browser (default)"); 126 System.out.println("-g : [deprecated] Start the server and run the desktop client application"); 127 System.out.println("-c : [deprecated] Run the desktop client application"); 128 } 129 else 130 { 131 System.out.println("Wrong arguments!"); 132 } 133 } 134 /** Register System Exceptions Hook */ 135 ExceptionHandler.registerExceptionHandler(); 136 137 optimizeMemoryUsage(); 138 } 139 140 /** 141 * This function creates a TimerTask to periodically run Garbage Colector 142 * 143 */ 144 private static void optimizeMemoryUsage() 145 { 146 if (optimizeMemory) 147 { 148 class FreeMemoryTask extends TimerTask 149 { 150 151 @Override 152 public void run() 153 { 154 Runtime.getRuntime().gc(); 155 System.out.println("\nFree Memory: " + Runtime.getRuntime().freeMemory() / 1024 / 1024 156 + "\nTotal Memory: " + Runtime.getRuntime().totalMemory() / 1024 / 1024 157 + "\nMax Memory: " + Runtime.getRuntime().maxMemory() / 1024 / 1024); 158 } 159 } 160 161 //FreeMemoryTask freeMemTask = new FreeMemoryTask(); 162 //Timer timer = new Timer(); 163 //timer.schedule(freeMemTask, 5000, 5000); 164 } 165 } 166 167 public static boolean LaunchWebApplication() { 168 if (!Desktop.isDesktopSupported() || !Desktop.getDesktop().isSupported(Desktop.Action.BROWSE)) { 169 logger.warn("Desktop browsing is not supported in this machine! " 170 + "Request to open web application ignored."); 171 return false; 172 } else { 173 try { 174 ServerSettings settings = ServerSettings.getInstance(); 175 URI uri = URI.create("http://localhost:" + settings.getWeb().getServerPort()); 176 Desktop.getDesktop().browse(uri); 177 return true; 178 } catch (IOException ex) { 179 logger.warn("Request to open web application ignored", ex); 180 return false; 181 } 182 } 183 } 184 185 public static void LaunchDicoogle() 186 { 187 try 188 { 189 //System.out.println("\n"+addressString(localAddresses()) + "\n"); 190 System.setProperty("java.rmi.server.hostname", addressString(localAddresses())); 191 } catch (SocketException ex) { 192 logger.warn(ex.getMessage(), ex); 193 } 194 195 logger.debug("Starting Dicoogle"); 196 /* This logic will be not neccessary. This should be sent to the Plugins. 197 try 198 { 199 Anonymous.getInstance().start(); 200 } catch(Exception e) { 201 logger.warn("Could not start Anonimize service", e); 202 }*/ 203 204 205 logger.debug("Loading configuration file: {}", Platform.homePath()); 206 207 /* Load all Server Settings from XML */ 208 ServerSettings settings = new XMLSupport().getXML(); 209 210 try 211 { 212 TagsStruct _tags = new TagsXML().getXML(); 213 214 //load DICOM Services Log 215 LogDICOM ll = new LogXML().getXML(); 216 217 } catch (SAXException | IOException ex) { 218 logger.error(ex.getMessage(), ex); 219 } 220 221 /*** 222 * Connect to P2P 223 */ 224 /** Verify if it have a defined node */ 225 if (!settings.isNodeNameDefined()) 226 { 227 String hostname = "Dicoogle"; 228 229 try 230 { 231 InetAddress addr = InetAddress.getLocalHost(); 232 233 // Get hostname 234 hostname = addr.getHostName(); 235 } catch (UnknownHostException e) 236 { 237 } 238 239 String response = (String) JOptionPane.showInputDialog(null, 240 "What is the name of the machine?", 241 "Enter Node name", 242 JOptionPane.QUESTION_MESSAGE, null, null, 243 hostname); 244 245 settings.setNodeName(response); 246 settings.setNodeNameDefined(true); 247 248 // Save Settings in XML 249 XMLSupport _xml = new XMLSupport(); 250 _xml.printXML(); 251 } 252 253 logger.debug("Name: {}", ServerSettings.getInstance().getNodeName()); 254 255 TransferSyntax.add(new TransferSyntax("1.2.826.0.1.3680043.2.682.1.40", false,false, false, true)); 256 TransferSyntax.add(new TransferSyntax("1.2.840.10008.1.2.4.70", true,false, false, true)); 257 TransferSyntax.add(new TransferSyntax("1.2.840.10008.1.2.5.50", false,false, false, true)); 258 259 PluginController PController = PluginController.getInstance(); 260 261 // Start the Inicial Services of Dicoogle 262 pt.ua.dicoogle.server.ControlServices.getInstance(); 263 264 // Lauch Async Index 265 // It monitors a folder, and when a file is touched an event 266 // triggers and index is updated. 267 if (ServerSettings.getInstance().isMonitorWatcher()) { 268 AsyncIndex asyncIndex = new AsyncIndex(); 269 } 270 //Signals that this application is GUI Server 271 isGUIServer = true; 272 273 //GUIServer GUIserv = new GUIServer(); 274 } 275 276 @Deprecated 277 private static void LaunchGUIClient() 278 { 279 280 /* Load all Client Settings from XML */ 281 ClientSettings settings = new XMLClientSupport().getXML(); 282 283 if (isGUIServer) 284 { 285 remoteGUIPort = ServerSettings.getInstance().getRemoteGUIPort(); 286 287 RunClient rc = new RunClient(); 288 rc.run(); 289 } else 290 { 291 ConnectWindow.getInstance(); 292 } 293 294 } 295 296 public static boolean isFixedClient() 297 { 298 return isFixedClient; 299 } 300 301 public static int getRemoteGUIPort() 302 { 303 return remoteGUIPort; 304 } 305 306 private static Set<InetAddress> localAddresses() throws SocketException 307 { 308 Set<InetAddress> localAddrs = new HashSet<>(); 309 310 /*Enumeration<NetworkInterface> ifaces = NetworkInterface.getNetworkInterfaces(); 311 312 while (ifaces.hasMoreElements()) { 313 NetworkInterface iface = ifaces.nextElement(); 314 Enumeration<InetAddress> addrs = iface.getInetAddresses(); 315 while (addrs.hasMoreElements()) 316 localAddrs.add(addrs.nextElement()); 317 } 318 * 319 */ 320 InetAddress in; 321 try 322 { 323 in = InetAddress.getLocalHost(); 324 InetAddress[] all = InetAddress.getAllByName(in.getHostName()); 325 localAddrs.addAll(Arrays.asList(all)); 326 327 } catch (UnknownHostException ex) 328 { 329 logger.error(ex.getMessage(), ex); 330 } 331 332 return localAddrs; 333 } 334 335 /** 336 * 337 * @param addrs 338 * @return 339 */ 340 private static String addressString(Collection<InetAddress> addrs) 341 { 342 String s = ""; 343 for (InetAddress addr : addrs) 344 { 345 if (addr.isLoopbackAddress()) 346 { 347 continue; 348 } 349 if (s.length() > 0) 350 { 351 s += "!"; 352 } 353 s += addr.getHostAddress(); 354 } 355 return s; 356 } 357 358 private static class RunClient implements Runnable 359 { 360 361 @Override 362 public void run() 363 { 364 ConnectWindow.getInstance(); 365 } 366 } 367}