View Javadoc
1   package gov.usgs.volcanoes.winston.legacyServer.cmd;
2   
3   import java.nio.ByteBuffer;
4   import java.nio.channels.SocketChannel;
5   import java.text.DecimalFormat;
6   import java.text.NumberFormat;
7   
8   import org.slf4j.Logger;
9   import org.slf4j.LoggerFactory;
10  
11  import gov.usgs.net.Command;
12  import gov.usgs.net.NetTools;
13  import gov.usgs.plot.data.Wave;
14  import gov.usgs.volcanoes.core.Zip;
15  import gov.usgs.volcanoes.core.time.Ew;
16  import gov.usgs.volcanoes.core.time.J2kSec;
17  import gov.usgs.volcanoes.winston.db.Data;
18  import gov.usgs.volcanoes.winston.db.WaveServerEmulator;
19  import gov.usgs.volcanoes.winston.db.WinstonDatabase;
20  import gov.usgs.volcanoes.winston.legacyServer.WWS;
21  
22  /**
23   *
24   * @author Dan Cervelli
25   */
26  abstract public class BaseCommand implements Command {
27    private static final Logger LOGGER = LoggerFactory.getLogger(BaseCommand.class);
28  
29    protected final static int ONE_HOUR = 60 * 60;
30    protected final static int ONE_DAY = 24 * ONE_HOUR;
31  
32    protected NetTools netTools;
33    protected WinstonDatabase winston;
34    protected WWS wws;
35    protected Data data;
36    protected WaveServerEmulator emulator;
37    protected int maxDays;
38    protected DecimalFormat decimalFormat;
39  
40    public BaseCommand(final NetTools nt, final WinstonDatabase db, final WWS wws) {
41      netTools = nt;
42      winston = db;
43      this.wws = wws;
44      maxDays = wws.getMaxDays();
45      emulator = new WaveServerEmulator(db);
46      data = new Data(db);
47      decimalFormat = (DecimalFormat) NumberFormat.getInstance();
48      decimalFormat.setMaximumFractionDigits(3);
49      decimalFormat.setGroupingUsed(false);
50    }
51  
52    protected void sendNoChannelResponse(final String id, final int pin, final String s,
53        final String c, final String n, final String l, final SocketChannel channel) {
54      String loc = "";
55      if (l != null)
56        loc = " " + l;
57      netTools.writeString(id + " " + id + " " + pin + " " + s + " " + c + " " + n + loc + " FN\n",
58          channel);
59    }
60  
61    protected int writeByteBuffer(final String id, ByteBuffer bb, final boolean compress,
62        final SocketChannel channel) {
63      if (bb == null) {
64        netTools.writeString(id + " 0\n", channel);
65        return 0;
66      }
67      if (compress)
68        bb = ByteBuffer.wrap(Zip.compress(bb.array()));
69  
70      netTools.writeString(id + " " + bb.limit() + "\n", channel);
71      return netTools.writeByteBuffer(bb, channel);
72    }
73  
74    protected String getError(final double[] d) {
75      if (d == null || d.length != 2)
76        return "";
77  
78      if (Double.isNaN(d[0]) && Double.isNaN(d[1]))
79        return "FB";
80  
81      if (Double.isNaN(d[0]))
82        return "FL s4 " + Double.toString(Ew.fromEpoch(J2kSec.asEpoch(d[1])));
83  
84      if (Double.isNaN(d[1]))
85        return "FR s4 " + Double.toString(Ew.fromEpoch(J2kSec.asEpoch(d[0])));
86  
87      return "OK";
88    }
89  
90    protected boolean allowTransaction(final double[] d) {
91      return !(d == null || d.length != 2 || Double.isNaN(d[0]) || Double.isNaN(d[1]));
92    }
93  
94    protected double[] checkTimes(final int sid, double t1, double t2) {
95      if (t1 >= t2)
96        return new double[] {Double.NaN, Double.NaN};
97  
98      final double[] tb = data.getTimeSpan(sid);
99  
100     if (t1 < tb[0])
101       t1 = tb[0];
102 
103     // only apply the later bounds check if there is an embargo otherwise we
104     // have to deal
105     // with other people's idea of what now is
106     if (t2 > tb[1])
107       t2 = tb[1];
108 
109     if (t2 < tb[0])
110       return new double[] {Double.NaN, tb[0]};
111 
112     if (t1 > tb[1])
113       return new double[] {tb[1], Double.NaN};
114 
115     return new double[] {t1, t2};
116   }
117 
118   public int writeWaveAsAscii(final Wave wave, final int sid, final String id, final String s,
119       final String c, final String n, final String l, final double t1, final double t2,
120       final String fill, final SocketChannel channel) {
121     final NumberFormat numberFormat = new DecimalFormat("#.######");
122     String sts = null;
123 
124     // find first sample time
125     double ct = wave.getStartTime() - wave.getRegistrationOffset();
126     final double dt = 1 / wave.getSamplingRate();
127     for (int i = 0; i < wave.numSamples(); i++) {
128       if (ct >= (t1 - dt / 2))
129         break;
130       ct += dt;
131     }
132     sts = numberFormat.format(Ew.fromEpoch(J2kSec.asEpoch(ct)));
133     final ByteBuffer bb = ByteBuffer.allocate(wave.numSamples() * 13 + 256);
134     bb.put(id.getBytes());
135     bb.put((byte) ' ');
136     bb.put(Integer.toString(sid).getBytes());
137     bb.put((byte) ' ');
138     bb.put(s.getBytes());
139     bb.put((byte) ' ');
140     bb.put(c.getBytes());
141     bb.put((byte) ' ');
142     bb.put(n.getBytes());
143     if (l != null) {
144       bb.put((byte) ' ');
145       bb.put(l.getBytes());
146     }
147     bb.put(" F s4 ".getBytes());
148     bb.put(sts.getBytes());
149     bb.put((byte) ' ');
150     bb.put(Double.toString(wave.getSamplingRate()).getBytes());
151     bb.put(" ".getBytes());
152     int sample;
153     ct = wave.getStartTime();
154     // int samples = 0;
155     for (int i = 0; i < wave.numSamples(); i++) {
156       if (ct >= (t1 - dt / 2)) {
157         // samples++;
158         sample = wave.buffer[i];
159         if (sample == Wave.NO_DATA)
160           bb.put(fill.getBytes());
161         else
162           bb.put(Integer.toString(wave.buffer[i]).getBytes());
163         bb.put((byte) ' ');
164       }
165       ct += dt;
166       if (ct >= t2)
167         break;
168     }
169     bb.put((byte) '\n');
170     bb.flip();
171     return netTools.writeByteBuffer(bb, channel);
172   }
173 
174   /**
175    * Apply maxDays to time
176    * 
177    * @param t
178    *          time
179    * @return greater of t or now less maxDays
180    */
181   double timeOrMaxDays(final double t) {
182     if (maxDays == 0)
183       return t;
184     else
185       return Math.max(t, J2kSec.now() - (maxDays * ONE_DAY));
186   }
187 }