View Javadoc

1   /**
2      This file is part of GoldenGate Project (named also GoldenGate or GG).
3   
4      Copyright 2009, Frederic Bregier, and individual contributors by the @author
5      tags. See the COPYRIGHT.txt in the distribution for a full listing of
6      individual contributors.
7   
8      All GoldenGate Project is free software: you can redistribute it and/or 
9      modify it under the terms of the GNU General Public License as published 
10     by the Free Software Foundation, either version 3 of the License, or
11     (at your option) any later version.
12  
13     GoldenGate is distributed in the hope that it will be useful,
14     but WITHOUT ANY WARRANTY; without even the implied warranty of
15     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16     GNU General Public License for more details.
17  
18     You should have received a copy of the GNU General Public License
19     along with GoldenGate .  If not, see <http://www.gnu.org/licenses/>.
20   */
21  package openr66.protocol.localhandler.packet;
22  
23  import openr66.context.ErrorCode;
24  import openr66.protocol.configuration.Configuration;
25  import openr66.protocol.exception.OpenR66ProtocolPacketException;
26  
27  import org.jboss.netty.buffer.ChannelBuffer;
28  import org.jboss.netty.buffer.ChannelBuffers;
29  
30  /**
31   * Request class
32   *
33   * header = "rulename MODETRANS" middle = way+"FILENAME BLOCKSIZE RANK specialId code" end
34   * = "fileInformation"
35   *
36   * @author frederic bregier
37   */
38  public class RequestPacket extends AbstractLocalPacket {
39      public static enum TRANSFERMODE {
40          UNKNOWNMODE, SENDMODE, RECVMODE, SENDMD5MODE, RECVMD5MODE,
41          SENDTHROUGHMODE, RECVTHROUGHMODE, SENDMD5THROUGHMODE, RECVMD5THROUGHMODE;
42      }
43  
44      private static final byte REQVALIDATE = 0;
45  
46      private static final byte REQANSWERVALIDATE = 1;
47  
48      private final String rulename;
49  
50      private final int mode;
51  
52      private String filename;
53  
54      private final int blocksize;
55  
56      private int rank;
57  
58      private long specialId;
59  
60      private byte way;
61  
62      private char code;
63  
64      private final String fileInformation;
65  
66      /**
67       *
68       * @param mode
69       * @return the same mode (RECV or SEND) in MD5 version
70       */
71      public static int getModeMD5(int mode) {
72          switch (mode) {
73              case 1:
74              case 2:
75              case 5:
76              case 6:
77                  return mode+2;
78          }
79          return mode;
80      }
81      /**
82       *
83       * @param mode
84       * @return true if this mode is a RECV(MD5) mode
85       */
86      public static boolean isRecvMode(int mode) {
87          return (mode == TRANSFERMODE.RECVMODE.ordinal() ||
88                  mode == TRANSFERMODE.RECVMD5MODE.ordinal() ||
89                  mode == TRANSFERMODE.RECVTHROUGHMODE.ordinal() ||
90                  mode == TRANSFERMODE.RECVMD5THROUGHMODE.ordinal());
91      }
92      /**
93      *
94      * @param mode
95      * @param isRequested
96      * @return True if this mode is a THROUGH (MD5) mode
97      */
98     public static boolean isSendThroughMode(int mode, boolean isRequested) {
99         return ((!isRequested && isSendThroughMode(mode)) ||
100                (isRequested && isRecvThroughMode(mode)));
101    }
102     /**
103      *
104      * @param mode
105      * @return True if this mode is a SEND THROUGH (MD5) mode
106      */
107     public static boolean isSendThroughMode(int mode) {
108         return (mode == TRANSFERMODE.SENDTHROUGHMODE.ordinal() ||
109                 mode == TRANSFERMODE.SENDMD5THROUGHMODE.ordinal());
110     }
111     /**
112     *
113     * @param mode
114     * @param isRequested
115     * @return True if this mode is a THROUGH (MD5) mode
116     */
117    public static boolean isRecvThroughMode(int mode, boolean isRequested) {
118        return ((!isRequested && isRecvThroughMode(mode)) ||
119                (isRequested && isSendThroughMode(mode)));
120    }
121     /**
122     *
123     * @param mode
124     * @return True if this mode is a RECV THROUGH (MD5) mode
125     */
126    public static boolean isRecvThroughMode(int mode) {
127        return (mode == TRANSFERMODE.RECVTHROUGHMODE.ordinal() ||
128                mode == TRANSFERMODE.RECVMD5THROUGHMODE.ordinal());
129    }
130    /**
131     * 
132     * @param mode
133     * @return True if this mode is a THROUGH mode (with or without MD5)
134     */
135    public static boolean isThroughMode(int mode) {
136        return mode >= TRANSFERMODE.SENDTHROUGHMODE.ordinal() &&
137            mode <= TRANSFERMODE.RECVMD5THROUGHMODE.ordinal();
138    }
139     /**
140      *
141      * @param mode
142      * @return true if this mode is a MD5 mode
143      */
144     public static boolean isMD5Mode(int mode) {
145         return (mode == TRANSFERMODE.RECVMD5MODE.ordinal() ||
146                 mode == TRANSFERMODE.SENDMD5MODE.ordinal() ||
147                 mode == TRANSFERMODE.SENDMD5THROUGHMODE.ordinal() ||
148                 mode == TRANSFERMODE.RECVMD5THROUGHMODE.ordinal());
149     }
150     /**
151      *
152      * @param mode1
153      * @param mode2
154      * @return true if both modes are compatible (both send, or both recv)
155      */
156     public static boolean isCompatibleMode(int mode1, int mode2) {
157         return ((RequestPacket.isRecvMode(mode1) && RequestPacket.isRecvMode(mode2))
158                 || ((!RequestPacket.isRecvMode(mode1)) &&
159                         (!RequestPacket.isRecvMode(mode2))));
160     }
161     /**
162      * @param headerLength
163      * @param middleLength
164      * @param endLength
165      * @param buf
166      * @return the new RequestPacket from buffer
167      * @throws OpenR66ProtocolPacketException
168      */
169     public static RequestPacket createFromBuffer(int headerLength,
170             int middleLength, int endLength, ChannelBuffer buf)
171             throws OpenR66ProtocolPacketException {
172         if (headerLength - 1 <= 0) {
173             throw new OpenR66ProtocolPacketException("Not enough data");
174         }
175         if (middleLength <= 1) {
176             throw new OpenR66ProtocolPacketException("Not enough data");
177         }
178         final byte[] bheader = new byte[headerLength - 1];
179         final byte[] bmiddle = new byte[middleLength - 1];
180         final byte[] bend = new byte[endLength];
181         if (headerLength - 1 > 0) {
182             buf.readBytes(bheader);
183         }
184         byte valid = buf.readByte();
185         if (middleLength > 1) {
186             buf.readBytes(bmiddle);
187         }
188         if (endLength > 0) {
189             buf.readBytes(bend);
190         }
191         final String sheader = new String(bheader);
192         final String smiddle = new String(bmiddle);
193         final String send = new String(bend);
194         final String[] aheader = sheader.split(" ");
195         if (aheader.length != 2) {
196             throw new OpenR66ProtocolPacketException("Not enough data");
197         }
198         final String[] amiddle = smiddle.split(" ");
199         if (amiddle.length != 5) {
200             throw new OpenR66ProtocolPacketException("Not enough data");
201         }
202         int blocksize = Integer.parseInt(amiddle[1]);
203         if (blocksize < 100) {
204             blocksize = Configuration.configuration.BLOCKSIZE;
205         }
206         int rank = Integer.parseInt(amiddle[2]);
207         long specialId = Long.parseLong(amiddle[3]);
208         char code = amiddle[4].charAt(0);
209         return new RequestPacket(aheader[0], Integer.parseInt(aheader[1]),
210                 amiddle[0], blocksize, rank, specialId, valid, send, code);
211     }
212 
213     /**
214      * @param rulename
215      * @param mode
216      * @param filename
217      * @param blocksize
218      * @param rank
219      * @param specialId
220      * @param valid
221      * @param fileInformation
222      */
223     private RequestPacket(String rulename, int mode, String filename,
224             int blocksize, int rank, long specialId, byte valid,
225             String fileInformation, char code) {
226         this.rulename = rulename;
227         this.mode = mode;
228         this.filename = filename;
229         if (blocksize < 100) {
230             this.blocksize = Configuration.configuration.BLOCKSIZE;
231         } else {
232             this.blocksize = blocksize;
233         }
234         this.rank = rank;
235         this.specialId = specialId;
236         way = valid;
237         this.fileInformation = fileInformation;
238         this.code = code;
239     }
240 
241     /**
242      * @param rulename
243      * @param mode
244      * @param filename
245      * @param blocksize
246      * @param rank
247      * @param specialId
248      * @param fileInformation
249      */
250     public RequestPacket(String rulename, int mode, String filename,
251             int blocksize, int rank, long specialId, String fileInformation) {
252         this(rulename, mode, filename, blocksize, rank, specialId,
253                 REQVALIDATE, fileInformation, ErrorCode.InitOk.code);
254     }
255     /*
256      * (non-Javadoc)
257      *
258      * @see openr66.protocol.localhandler.packet.AbstractLocalPacket#createEnd()
259      */
260     @Override
261     public void createEnd() throws OpenR66ProtocolPacketException {
262         if (fileInformation != null) {
263             end = ChannelBuffers.wrappedBuffer(fileInformation.getBytes());
264         }
265     }
266 
267     /*
268      * (non-Javadoc)
269      *
270      * @see
271      * openr66.protocol.localhandler.packet.AbstractLocalPacket#createHeader()
272      */
273     @Override
274     public void createHeader() throws OpenR66ProtocolPacketException {
275         if (rulename == null || mode <= 0) {
276             throw new OpenR66ProtocolPacketException("Not enough data");
277         }
278         header = ChannelBuffers.wrappedBuffer(rulename.getBytes(), " "
279                 .getBytes(), Integer.toString(mode).getBytes());
280     }
281 
282     /*
283      * (non-Javadoc)
284      *
285      * @see
286      * openr66.protocol.localhandler.packet.AbstractLocalPacket#createMiddle()
287      */
288     @Override
289     public void createMiddle() throws OpenR66ProtocolPacketException {
290         if (filename == null) {
291             throw new OpenR66ProtocolPacketException("Not enough data");
292         }
293         byte[] away = new byte[1];
294         away[0] = way;
295         middle = ChannelBuffers.wrappedBuffer(away, filename.getBytes(), " "
296                 .getBytes(), Integer.toString(blocksize).getBytes(), " "
297                 .getBytes(), Integer.toString(rank).getBytes(), " ".getBytes(),
298                 Long.toString(specialId).getBytes()," ".getBytes(),
299                 Character.toString(code).getBytes());
300     }
301 
302     @Override
303     public byte getType() {
304         return LocalPacketFactory.REQUESTPACKET;
305     }
306 
307     /*
308      * (non-Javadoc)
309      *
310      * @see openr66.protocol.localhandler.packet.AbstractLocalPacket#toString()
311      */
312     @Override
313     public String toString() {
314         return "RequestPacket: " + rulename + " : " + mode + " : " + filename +
315                 " : " + fileInformation + " : " + blocksize + " : " + rank +
316                 " : " + way + " : " + code;
317     }
318 
319     /**
320      * @return the rulename
321      */
322     public String getRulename() {
323         return rulename;
324     }
325 
326     /**
327      * @return the filename
328      */
329     public String getFilename() {
330         return filename;
331     }
332 
333     /**
334      * @return the mode
335      */
336     public int getMode() {
337         return mode;
338     }
339 
340     /**
341      *
342      * @return True if this packet concerns a Retrieve operation
343      */
344     public boolean isRetrieve() {
345         return isRecvMode(mode);
346     }
347 
348     /**
349      * @return the fileInformation
350      */
351     public String getFileInformation() {
352         return fileInformation;
353     }
354 
355     /**
356      * @return the blocksize
357      */
358     public int getBlocksize() {
359         return blocksize;
360     }
361 
362     /**
363      * @return the rank
364      */
365     public int getRank() {
366         return rank;
367     }
368 
369     /**
370      * @param rank the rank to set
371      */
372     public void setRank(int rank) {
373         this.rank = rank;
374     }
375     /**
376      * @param specialId
377      *            the specialId to set
378      */
379     public void setSpecialId(long specialId) {
380         this.specialId = specialId;
381     }
382 
383     /**
384      * @return the specialId
385      */
386     public long getSpecialId() {
387         return specialId;
388     }
389 
390     /**
391      * @return True if this packet is to be validated
392      */
393     public boolean isToValidate() {
394         return way == REQVALIDATE;
395     }
396 
397     /**
398      * Validate the request
399      */
400     public void validate() {
401         way = REQANSWERVALIDATE;
402         middle = null;
403     }
404 
405     /**
406      * @param filename
407      *            the filename to set
408      */
409     public void setFilename(String filename) {
410         this.filename = filename;
411     }
412 
413     /**
414      * @return the code
415      */
416     public char getCode() {
417         return code;
418     }
419     /**
420      * @param code the code to set
421      */
422     public void setCode(char code) {
423         this.code = code;
424     }
425 
426 }