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 }