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 goldengate.ftp.core.data.handler;
22  
23  import goldengate.common.exception.InvalidArgumentException;
24  import goldengate.common.file.DataBlock;
25  import goldengate.ftp.core.command.FtpArgumentCode.TransferStructure;
26  
27  import org.jboss.netty.channel.ChannelHandlerContext;
28  import org.jboss.netty.channel.MessageEvent;
29  import org.jboss.netty.channel.SimpleChannelHandler;
30  import org.jboss.netty.channel.ChannelHandler.Sharable;
31  
32  /**
33   * Third CODEC :<br>
34   * - encode/decode : takes {@link DataBlock} and transforms it to a
35   * {@link DataBlock}<br>
36   * FILE and RECORD are implemented (DataNetworkHandler will do the real job).
37   * PAGE is not implemented.<br>
38   * Note that real actions are taken in the DataNetworkHandler according to the
39   * implementation of FtpFile.
40   *
41   * @author Frederic Bregier
42   *
43   */
44  @Sharable
45  public class FtpDataStructureCodec extends SimpleChannelHandler {
46      /*
47       * 3.1.2. DATA STRUCTURES
48       *
49       * In addition to different representation types, FTP allows the structure
50       * of a file to be specified. Three file structures are defined in FTP:
51       *
52       * file-structure, where there is no internal structure and the file is
53       * considered to be a continuous sequence of data bytes,
54       *
55       * record-structure, where the file is made up of sequential records,
56       *
57       * and page-structure, where the file is made up of independent indexed
58       * pages.
59       *
60       * FileInterface-structure is the default to be assumed if the STRUcture
61       * command has not been used but both file and record structures must be
62       * accepted for "text" files (i.e., files with TYPE ASCII or EBCDIC) by all
63       * FTP implementations. The structure of a file will affect both the
64       * transfer mode of a file (see the Section on Transmission Modes) and the
65       * interpretation and storage of the file.
66       *
67       * The "natural" structure of a file will depend on which host stores the
68       * file. A source-code file will usually be stored on an IBM Mainframe in
69       * fixed length records but on a DEC TOPS-20 as a stream of characters
70       * partitioned into lines, for example by <CRLF>. If the transfer of files
71       * between such disparate sites is to be useful, there must be some way for
72       * one site to recognize the other's assumptions about the file.
73       *
74       * With some sites being naturally file-oriented and others naturally
75       * record-oriented there may be problems if a file with one structure is
76       * sent to a host oriented to the other. If a text file is sent with
77       * record-structure to a host which is file oriented, then that host should
78       * apply an internal transformation to the file based on the record
79       * structure. Obviously, this transformation should be useful, but it must
80       * also be invertible so that an identical file may be retrieved using
81       * record structure.
82       *
83       * In the case of a file being sent with file-structure to a record-oriented
84       * host, there exists the question of what criteria the host should use to
85       * divide the file into records which can be processed locally. If this
86       * division is necessary, the FTP implementation should use the end-of-line
87       * sequence,
88       *
89       * <CRLF> for ASCII, or <NL> for EBCDIC text files, as the delimiter. If an
90       * FTP implementation adopts this technique, it must be prepared to reverse
91       * the transformation if the file is retrieved with file-structure.
92       *
93       * 3.1.2.1. FILE STRUCTURE
94       *
95       * FileInterface structure is the default to be assumed if the STRUcture
96       * command has not been used.
97       *
98       * In file-structure there is no internal structure and the file is
99       * considered to be a continuous sequence of data bytes.
100      *
101      * 3.1.2.2. RECORD STRUCTURE
102      *
103      * Record structures must be accepted for "text" files (i.e., files with
104      * TYPE ASCII or EBCDIC) by all FTP implementations.
105      *
106      * In record-structure the file is made up of sequential records.
107      *
108      * 3.1.2.3. PAGE STRUCTURE
109      *
110      * To transmit files that are discontinuous, FTP defines a page structure.
111      * Files of this type are sometimes known as "random access files" or even
112      * as "holey files". In these files there is sometimes other information
113      * associated with the file as a whole (e.g., a file descriptor), or with a
114      * section of the file (e.g., page access controls), or both. In FTP, the
115      * sections of the file are called pages.
116      *
117      * To provide for various page sizes and associated information, each page
118      * is sent with a page header. The page header has the following defined
119      * fields:
120      *
121      * Header Length
122      *
123      * The number of logical bytes in the page header including this byte. The
124      * minimum header length is 4.
125      *
126      * Page Index
127      *
128      * The logical page number of this section of the file. This is not the
129      * transmission sequence number of this page, but the index used to identify
130      * this page of the file.
131      *
132      * Data Length
133      *
134      * The number of logical bytes in the page data. The minimum data length is
135      * 0.
136      *
137      * Page Type
138      *
139      * The type of page this is. The following page types are defined:
140      *
141      * 0 = Last Page
142      *
143      * This is used to indicate the end of a paged structured transmission. The
144      * header length must be 4, and the data length must be 0.
145      *
146      * 1 = Simple Page
147      *
148      * This is the normal type for simple paged files with no page level
149      * associated control information. The header length must be 4.
150      *
151      * 2 = Descriptor Page
152      *
153      * This type is used to transmit the descriptive information for the file as
154      * a whole.
155      *
156      * 3 = Access Controlled Page
157      *
158      * This type includes an additional header field for paged files with page
159      * level access control information. The header length must be 5.
160      *
161      * Optional Fields
162      *
163      * Further header fields may be used to supply per page control information,
164      * for example, per page access control.
165      *
166      * All fields are one logical byte in length. The logical byte size is
167      * specified by the TYPE command. See Appendix I for further details and a
168      * specific case at the page structure.
169      *
170      * A note of caution about parameters: a file must be stored and retrieved
171      * with the same parameters if the retrieved version is to
172      *
173      * be identical to the version originally transmitted. Conversely, FTP
174      * implementations must return a file identical to the original if the
175      * parameters used to store and retrieve a file are the same.
176      */
177     /**
178      * Structure of transfer
179      */
180     private TransferStructure structure = null;
181 
182     /**
183      * @param structure
184      */
185     public FtpDataStructureCodec(TransferStructure structure) {
186         super();
187         this.structure = structure;
188     }
189 
190     /**
191      * @return the structure
192      */
193     public TransferStructure getStructure() {
194         return structure;
195     }
196 
197     /**
198      * @param structure
199      *            the structure to set
200      */
201     public void setStructure(TransferStructure structure) {
202         this.structure = structure;
203     }
204 
205     /*
206      * (non-Javadoc)
207      *
208      * @see
209      * org.jboss.netty.channel.SimpleChannelHandler#writeRequested(org.jboss
210      * .netty.channel.ChannelHandlerContext,
211      * org.jboss.netty.channel.MessageEvent)
212      */
213     @Override
214     public void writeRequested(ChannelHandlerContext arg0, MessageEvent arg1)
215             throws Exception {
216         Object o = arg1.getMessage();
217         if (!(o instanceof DataBlock)) {
218             // Type unimplemented
219             throw new InvalidArgumentException("Wrong object received in " +
220                     this.getClass().getName() + " codec " +
221                     o.getClass().getName());
222         }
223         if (structure == TransferStructure.FILE) {
224             super.writeRequested(arg0, arg1);
225             return;
226         } else if (structure == TransferStructure.RECORD) {
227             super.writeRequested(arg0, arg1);
228             return;
229         }
230         // Type unimplemented
231         throw new InvalidArgumentException("Structure unimplemented in " +
232                 this.getClass().getName() + " codec " + structure.name());
233     }
234 
235     /*
236      * (non-Javadoc)
237      *
238      * @see
239      * org.jboss.netty.channel.SimpleChannelHandler#messageReceived(org.jboss
240      * .netty.channel.ChannelHandlerContext,
241      * org.jboss.netty.channel.MessageEvent)
242      */
243     @Override
244     public void messageReceived(ChannelHandlerContext arg0, MessageEvent arg1)
245             throws Exception {
246         Object o = arg1.getMessage();
247         if (!(o instanceof DataBlock)) {
248             // Type unimplemented
249             throw new InvalidArgumentException("Wrong object received in " +
250                     this.getClass().getName() + " codec " +
251                     o.getClass().getName());
252         }
253         if (structure == TransferStructure.FILE) {
254             super.messageReceived(arg0, arg1);
255             return;
256         } else if (structure == TransferStructure.RECORD) {
257             super.messageReceived(arg0, arg1);
258             return;
259         }
260         // Type unimplemented
261         throw new InvalidArgumentException("Structure unimplemented in " +
262                 this.getClass().getName() + " codec " + structure.name());
263     }
264 
265 }