1 25 package org.snipsnap.server; 26 27 import org.apache.xmlrpc.WebServer; 28 import org.jdesktop.jdic.desktop.Desktop; 29 import org.mortbay.http.HttpListener; 30 import org.mortbay.jetty.Server; 31 import org.mortbay.util.InetAddrPort; 32 import org.mortbay.util.MultiException; 33 import org.snipsnap.config.ServerConfiguration; 34 import org.snipsnap.user.Digest; 35 36 import java.io.BufferedOutputStream ; 37 import java.io.BufferedReader ; 38 import java.io.File ; 39 import java.io.FileInputStream ; 40 import java.io.FileOutputStream ; 41 import java.io.IOException ; 42 import java.io.InputStreamReader ; 43 import java.io.OutputStream ; 44 import java.net.InetAddress ; 45 import java.net.MalformedURLException ; 46 import java.net.URL ; 47 import java.net.UnknownHostException ; 48 import java.util.Date ; 49 import java.util.Iterator ; 50 import java.util.Properties ; 51 import java.util.prefs.BackingStoreException ; 52 import java.util.prefs.Preferences ; 53 54 60 public class AppServer { 61 protected static Properties serverPrefsDefaults; 62 protected static Preferences serverPrefs; 63 64 protected static Server jettyServer; 65 66 69 public static void main(String args[]) { 70 serverPrefs = getServerPrefs(); 72 System.setProperty(ServerConfiguration.VERSION, serverPrefs.get(ServerConfiguration.VERSION, "<unknown version>")); 73 74 printCopyright(); 75 parseArguments(args); 76 77 Runtime.getRuntime().addShutdownHook(new Thread () { 79 public void run() { 80 Shutdown.shutdown(); 81 } 82 }); 83 84 String enc = serverPrefs.get(ServerConfiguration.ENCODING, "UTF-8"); 86 System.setProperty("file.encoding", enc); 87 System.setProperty("org.mortbay.util.URI.charset", enc); 88 89 try { 91 jettyServer = new Server(getResource("/conf/jetty.conf", "./conf/jetty.conf")); 92 jettyServer.addWebApplication("/install", AppServer.class.getResource("/snipsnap-installer.war").toString()); 93 jettyServer.start(); 94 } catch (IOException e) { 95 System.err.println("AppServer: warning: admin server configuration not found: " + e); 96 } catch (MultiException e) { 97 Iterator exceptions = e.getExceptions().iterator(); 98 while (exceptions.hasNext()) { 99 Exception ex = (Exception ) exceptions.next(); 100 ex.printStackTrace(); 101 System.out.println("ERROR: can't start server: " + ex.getMessage()); 102 } 103 System.exit(-1); 104 } 105 106 try { 107 URL xmlRpcServerUrl = new URL (serverPrefs.get(ServerConfiguration.ADMIN_URL, 108 serverPrefsDefaults.getProperty(ServerConfiguration.ADMIN_URL))); 109 WebServer xmlRpcServer = new WebServer(xmlRpcServerUrl.getPort()); 110 xmlRpcServer.addHandler("$default", new AdminXmlRpcHandler()); 112 xmlRpcServer.start(); 113 } catch (Exception e) { 114 System.out.println("ERROR: can't start administrative server interface (XML-RPC): " + e.getMessage()); 115 e.printStackTrace(); 116 } 117 118 String webAppRoot = serverPrefs.get(ServerConfiguration.WEBAPP_ROOT, 119 serverPrefsDefaults.getProperty((ServerConfiguration.WEBAPP_ROOT))); 120 System.out.println(">> Applications: " + new File (webAppRoot).getAbsolutePath()); 121 int errors = ApplicationLoader.loadApplications(serverPrefs.get(ServerConfiguration.WEBAPP_ROOT, 123 serverPrefsDefaults.getProperty((ServerConfiguration.WEBAPP_ROOT)))); 124 if (errors == 0 && ApplicationLoader.getApplicationCount() == 0) { 125 System.out.println("ATTENTION: Server is still unconfigured!"); 126 System.out.println("ATTENTION: Point your browser to the following address:"); 127 HttpListener listener = jettyServer.getListeners()[0]; 128 String host = listener.getHost(); 129 if (InetAddrPort.__0_0_0_0.equals(host)) { 130 try { 131 host = InetAddress.getLocalHost().getCanonicalHostName(); 132 } catch (UnknownHostException e) { 133 host = System.getProperty("host", "localhost"); 134 } 135 } 136 String url = "http://" + host + ":" + listener.getPort() + "/install/" + serverPrefs.get(ServerConfiguration.ADMIN_PASS, ""); 137 System.out.println("ATTENTION: " + url); 138 System.out.println("ATTENTION: To force setup of a specific host and port add '?expert=true'"); 139 System.out.println("ATTENTION: to the above URL."); 140 141 String system = System.getProperty("os.name"); 143 if (system.startsWith("Mac OS X")) { 144 try { 145 Runtime.getRuntime().exec("/usr/bin/open " + url); 146 } catch (IOException e) { 147 System.err.println("AppServer: unable to execute open web browser on MacOS X"); 148 } 149 } else { 150 try { 151 Desktop.browse(new URL (url)); 152 } catch (Exception e) { 153 System.err.println("AppServer: unable to open web browser on " + system); 154 } catch (Error err) { 155 System.err.println("AppServer: unable to open web browser on " + system); 156 } 157 } 158 } else { 159 System.out.println(ApplicationLoader.getApplicationCount() + " applications loaded and running (" + errors + " errors)."); 160 } 161 } 162 163 169 private static Preferences getServerPrefs() { 170 serverPrefs = Preferences.userNodeForPackage(ServerConfiguration.class); 171 int keyCount = 0; 172 try { 173 keyCount = serverPrefs.keys().length; 174 } catch (BackingStoreException e) { 175 System.err.println("AppServer: WARNING: no preferences backing store available! Using defaults."); 176 } 177 178 serverPrefsDefaults = new Properties (); 179 try { 181 serverPrefsDefaults.load(AppServer.class.getResourceAsStream("/conf/snipsnap.conf")); 182 } catch (IOException e) { 183 System.err.println("AppServer: Unable to read server defaults: " + e.getMessage()); 184 e.printStackTrace(); 185 } 186 187 if (keyCount == 0) { 189 System.err.println("AppServer: unconfigured server, loading preferences"); 190 191 serverPrefs.put(ServerConfiguration.ADMIN_PASS, 193 Digest.getDigest("" + new Date ()).substring(0, 5).toLowerCase()); 194 195 Properties serverInfoProperties = new Properties (); 197 Iterator defaultsIt = serverPrefsDefaults.keySet().iterator(); 198 while (defaultsIt.hasNext()) { 199 String key = (String ) defaultsIt.next(); 200 System.err.println("AppServer: default preference: " + key + "=" + serverPrefsDefaults.get(key)); 201 serverInfoProperties.put(key, serverPrefsDefaults.get(key)); 202 } 203 204 try { 206 serverInfoProperties.load(AppServer.class.getResourceAsStream("/conf/snipsnap.conf")); 207 } catch (IOException e) { 208 System.err.println("AppServer: Unable to read server defaults: " + e.getMessage()); 209 e.printStackTrace(); 210 } 211 212 try { 214 File propFile = new File ("conf/server.conf"); 215 serverInfoProperties.load(new FileInputStream (propFile)); 216 System.err.println("AppServer: converted old server configuration, please remove '" + propFile + "'"); 217 } catch (IOException e) { 218 } 220 221 Iterator oldConfigIt = serverInfoProperties.keySet().iterator(); 223 while (oldConfigIt.hasNext()) { 224 String key = (String ) oldConfigIt.next(); 225 System.err.println("AppServer: converted old preference: " + key + "=" + serverInfoProperties.get(key)); 226 serverPrefs.put(key, (String ) serverInfoProperties.get(key)); 227 } 228 229 File webappRoot = new File (serverInfoProperties.getProperty(ServerConfiguration.WEBAPP_ROOT)); 230 System.err.println("webappRoot=" + webappRoot.getAbsolutePath()); 231 if (!webappRoot.exists() || !webappRoot.canWrite()) { 232 webappRoot = new File (System.getProperty("user.home"), "applications"); 233 } 234 serverPrefs.put(ServerConfiguration.WEBAPP_ROOT, webappRoot.getAbsolutePath()); 235 236 try { 237 serverPrefs.flush(); 238 } catch (BackingStoreException e) { 239 System.err.println("AppServer: unable to store server configuration: " + e.getMessage()); 240 e.printStackTrace(); 241 } 242 243 File confDir = new File ("conf"); 244 if (!confDir.exists() && !confDir.canWrite()) { 245 confDir = webappRoot; 246 } 247 try { 248 OutputStream configSave = new BufferedOutputStream (new FileOutputStream (new File (confDir, "snipsnap.xml"))); 249 serverPrefs.exportSubtree(configSave); 250 } catch (Exception e) { 251 System.err.println("AppServer: unable to store server configuation backup: " + e.getMessage()); 252 e.printStackTrace(); 253 } 254 } 255 256 String jarVersion = serverPrefsDefaults.getProperty(ServerConfiguration.VERSION); 257 String version = serverPrefs.get(ServerConfiguration.VERSION, null); 258 if (null == version || !(jarVersion != null && jarVersion.equals(version))) { 259 serverPrefs.put(ServerConfiguration.VERSION, jarVersion); 260 try { 261 serverPrefs.flush(); 262 } catch (BackingStoreException e) { 263 System.err.println("AppServer: unable to store server configuration " + e.getMessage()); 264 e.printStackTrace(); 265 } 266 } 267 268 return serverPrefs; 269 } 270 271 private static void printCopyright() { 272 System.out.println("SnipSnap " + System.getProperty(ServerConfiguration.VERSION)); 273 274 try { 276 BufferedReader copyrightReader = new BufferedReader (new InputStreamReader (AppServer.class.getResourceAsStream("/conf/copyright.txt"))); 277 String line = null; 278 while ((line = copyrightReader.readLine()) != null) { 279 System.out.println(line); 280 } 281 } catch (IOException e) { 282 } 284 } 285 286 293 private static Preferences parseArguments(String args[]) { 294 for (int i = 0; i < args.length; i++) { 295 if ("-help".equals(args[i])) { 296 usage(""); 297 System.exit(0); 298 } 299 300 if ("-root".equals(args[i])) { 302 if (args.length >= i + 1 && !args[i + 1].startsWith("-")) { 303 serverPrefs.put(ServerConfiguration.WEBAPP_ROOT, args[++i]); 304 } else { 305 usage("an argument is required for -root"); 306 } 307 } else if ("-url".equals(args[i])) { 308 if (args.length >= i + 1 && !args[i + 1].startsWith("-")) { 309 serverPrefs.put(ServerConfiguration.ADMIN_URL, args[++i]); 310 } else { 311 usage("an argument is required for -url"); 312 } 313 } else if ("-killconfig".equals(args[i])) { 314 try { 315 serverPrefs.removeNode(); 316 serverPrefs.flush(); 317 } catch (BackingStoreException e) { 318 System.out.println("Error: cannot remove configuration ..."); 319 e.printStackTrace(); 320 } 321 System.exit(0); 322 } else if ("-showconfig".equals(args[i])) { 323 try { 324 serverPrefs.sync(); 325 serverPrefs.exportSubtree(System.out); 326 } catch (Exception e) { 327 System.out.println("Error: cannot display configuration ..."); 328 e.printStackTrace(); 329 } 330 System.exit(0); 331 } 332 } 333 return serverPrefs; 334 } 335 336 342 private static URL getResource(String jarResource, String fileResource) { 343 File file = new File (fileResource); 344 URL url = null; 345 if (file.exists()) { 346 try { 347 url = file.toURL(); 348 } catch (MalformedURLException e) { 349 System.err.println("Warning: unable to load '" + file + "': " + e.getMessage()); 350 } 351 } 352 353 if (null == url) { 354 url = AppServer.class.getResource(jarResource); 355 } 356 357 return url; 358 } 359 360 365 private static void usage(String message) { 366 System.out.println(message); 367 System.out.println("usage: " + AppServer.class.getName() + " [-root <dir>] [-url <url>]"); 368 System.out.println(" -root directory, where to find the applications for this server"); 369 System.out.println(" -url URL, admin server URL (http://host:port/)"); 370 System.out.println(" -killconfig remove server configuration from system"); 371 System.out.println(" -showconfig show server configuration, dump it"); 372 System.out.println(" -help this help text"); 373 System.exit(0); 374 } 375 } 376 | Popular Tags |