001/* 002 * $Id: AddeThread.java,v 1.7 2011/03/24 16:06:34 davep Exp $ 003 * 004 * This file is part of McIDAS-V 005 * 006 * Copyright 2007-2011 007 * Space Science and Engineering Center (SSEC) 008 * University of Wisconsin - Madison 009 * 1225 W. Dayton Street, Madison, WI 53706, USA 010 * https://www.ssec.wisc.edu/mcidas 011 * 012 * All Rights Reserved 013 * 014 * McIDAS-V is built on Unidata's IDV and SSEC's VisAD libraries, and 015 * some McIDAS-V source code is based on IDV and VisAD source code. 016 * 017 * McIDAS-V is free software; you can redistribute it and/or modify 018 * it under the terms of the GNU Lesser Public License as published by 019 * the Free Software Foundation; either version 3 of the License, or 020 * (at your option) any later version. 021 * 022 * McIDAS-V is distributed in the hope that it will be useful, 023 * but WITHOUT ANY WARRANTY; without even the implied warranty of 024 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 025 * GNU Lesser Public License for more details. 026 * 027 * You should have received a copy of the GNU Lesser Public License 028 * along with this program. If not, see http://www.gnu.org/licenses. 029 */ 030package edu.wisc.ssec.mcidasv.servermanager; 031 032import java.io.InputStream; 033import java.io.InputStreamReader; 034 035import org.bushe.swing.event.EventBus; 036 037import edu.wisc.ssec.mcidasv.Constants; 038import edu.wisc.ssec.mcidasv.McIDASV; 039 040/** 041 * Thread that actually execs mcservl 042 */ 043public class AddeThread extends Thread { 044 045 public enum McservEvent { ACTIVE, DIED, STARTED, STOPPED }; 046 047 /** */ 048 Process proc; 049 050 /** */ 051 private final EntryStore entryStore; 052 053 public AddeThread(final EntryStore entryStore) { 054 this.entryStore = entryStore; 055 } 056 057 public void run() { 058 StringBuffer err = new StringBuffer(); 059 String[] cmds = entryStore.getAddeCommands(); 060 String[] env = (McIDASV.isWindows()) ? entryStore.getWindowsAddeEnv() : entryStore.getUnixAddeEnv(); 061 try { 062 //start ADDE binary with "-p PORT" and set environment appropriately 063 proc = Runtime.getRuntime().exec(cmds, env); 064 065 //create thread for reading inputStream (process' stdout) 066 StreamReaderThread outThread = new StreamReaderThread(proc.getInputStream(), new StringBuffer()); 067 068 //create thread for reading errorStream (process' stderr) 069 StreamReaderThread errThread = new StreamReaderThread(proc.getErrorStream(), err); 070 071 //start both threads 072 outThread.start(); 073 errThread.start(); 074 075 //wait for process to end 076 int result = proc.waitFor(); 077 078 //finish reading whatever's left in the buffers 079 outThread.join(); 080 errThread.join(); 081 082 if (result != 0) { 083 entryStore.stopLocalServer(entryStore.getRestarting()); 084 String errString = err.toString(); 085 086 // If the server couldn't start for a known reason, try again on another port 087 // Retry up to 10 times 088 if ((result==35584 || errString.indexOf("Error binding to port") >= 0) && 089 Integer.parseInt(EntryStore.getLocalPort()) < Integer.parseInt(Constants.LOCAL_ADDE_PORT) + 10) { 090 EntryStore.setLocalPort(EntryStore.nextLocalPort()); 091 entryStore.startLocalServer(entryStore.getRestarting()); 092 } 093 } 094 } catch (InterruptedException e) { 095 McservEvent type = McservEvent.DIED; 096 if (entryStore.getRestarting()) { 097 type = McservEvent.STARTED; 098 } 099 EventBus.publish(type); 100 } catch (Exception e) { 101 EventBus.publish(McservEvent.DIED); 102 } 103 } 104 105 /** 106 * 107 */ 108 public void stopProcess() { 109 proc.destroy(); 110 } 111 112// /** 113// * 114// */ 115// public String toString() { 116// return String.format("[AddeThread@%x: ADDE_ENV=%s, ADDE_COMMANDS=%s]", hashCode(), ADDE_ENV, ADDE_COMMANDS); 117// } 118 119 /** 120 * Thread to read the stderr and stdout of mcservl 121 */ 122 private static class StreamReaderThread extends Thread { 123 /** */ 124 private final StringBuffer mOut; 125 126 /** */ 127 private final InputStreamReader mIn; 128 129 /** */ 130 public StreamReaderThread(final InputStream in, final StringBuffer out) { 131 mOut = out; 132 mIn = new InputStreamReader(in); 133 } 134 135 /** */ 136 public void run() { 137 int ch; 138 try { 139 while (-1 != (ch = mIn.read())) { 140 mOut.append((char)ch); 141 } 142 } catch (Exception e) { 143 mOut.append("\nRead error: "+e.getMessage()); 144 } 145 } 146 } 147}