001: /*
002: * ChainBuilder ESB
003: * Visual Enterprise Integration
004: *
005: * Copyright (C) 2006 Bostech Corporation
006: *
007: * This program is free software; you can redistribute it and/or modify
008: * it under the terms of the GNU General Public License as published by
009: * the Free Software Foundation; either version 2 of the License, or
010: * (at your option) any later version.
011: *
012: * This program is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * General Public License for more details.
016: *
017: * You should have received a copy of the GNU General Public License
018: * along with this program; if not, write to the Free Software
019: * Foundation, Inc.,59 Temple Place, Suite 330, Boston, MA 02111-1307
020: * USA
021: *
022: *
023: * $Id: FtpProviderProcessor.java 12164 2008-02-29 21:58:21Z mpreston $
024: */
025: package com.bostechcorp.cbesb.runtime.component.ftp.processors;
026:
027: import java.io.ByteArrayInputStream;
028: import java.io.File;
029: import java.io.FileInputStream;
030: import java.io.FileOutputStream;
031: import java.io.IOException;
032: import java.io.InputStreamReader;
033: import java.io.OutputStream;
034: import java.util.concurrent.atomic.AtomicInteger;
035:
036: import javax.jbi.JBIException;
037: import javax.jbi.messaging.MessageExchange;
038: import javax.jbi.messaging.NormalizedMessage;
039: import javax.xml.namespace.QName;
040: import javax.xml.transform.Source;
041: import javax.xml.transform.Transformer;
042: import javax.xml.transform.TransformerException;
043: import javax.xml.transform.TransformerFactory;
044: import javax.xml.transform.dom.DOMResult;
045: import javax.xml.transform.dom.DOMSource;
046:
047: import org.apache.commons.net.ftp.FTPClient;
048:
049: import com.bostechcorp.cbesb.common.constant.MetadataConstants;
050: import com.bostechcorp.cbesb.common.runtime.CbesbException;
051: import com.bostechcorp.cbesb.common.runtime.ConfigurationException;
052: import com.bostechcorp.cbesb.common.runtime.DataContentException;
053: import com.bostechcorp.cbesb.common.runtime.ResourcesConnectionException;
054: import com.bostechcorp.cbesb.common.util.ErrorUtil;
055: import com.bostechcorp.cbesb.runtime.ccsl.jbi.messaging.CbProviderProcessor;
056: import com.bostechcorp.cbesb.runtime.ccsl.lib.NormalizedMessageUtil;
057: import com.bostechcorp.cbesb.runtime.ccsl.lib.OutputWriter;
058: import com.bostechcorp.cbesb.runtime.ccsl.nmhandler.NormalizedMessageHandler;
059: import com.bostechcorp.cbesb.runtime.component.ftp.FtpEndpoint;
060: import com.bostechcorp.cbesb.runtime.file.FileOperator;
061: import com.bostechcorp.cbesb.runtime.file.FilePatternMatcher;
062: import com.bostechcorp.cbesb.runtime.ftp.CmdFileParser;
063: import com.bostechcorp.cbesb.runtime.ftp.interpreter.CommandInterpreter;
064:
065: public class FtpProviderProcessor extends CbProviderProcessor {
066:
067: // protected static final String FTP_CONNECT_MODE_ACTIVE = "active";
068: // protected static final String FTP_CONNECT_MODE_PASSIVE = "passive";
069: // protected static final String FTP_TRANSFER_MODE_ASCII = "ascii";
070: // protected static final String FTP_TRANSFER_MODE_BINARY = "binary";
071:
072: protected static final String FILE_COMPLETE_ACTION_ARCHIVE = "archive";
073:
074: protected static final String FTP_REQUEST = "ftp_request";
075: protected static final String FTP_RESPONSE = "ftp_response";
076: protected static final String FTP_SCRIPT_NAMESPACE = "http://cbesb.bostechcorp.com/wsdl/ftp/1.0";
077: protected static final String STATUS = "status";
078: protected static final String RESULT = "result";
079: protected static final String ERROR = "error";
080:
081: protected static final String WRITE_STYLE_NEWLINE = "newline";
082: protected static final String WRITE_STYLE_RAW = "raw";
083:
084: private FtpEndpoint endpoint;
085: private AtomicInteger fileCount = new AtomicInteger(0);
086:
087: public FtpProviderProcessor(FtpEndpoint endpoint) {
088: super (endpoint);
089: this .endpoint = endpoint;
090: }
091:
092: /* (non-Javadoc)
093: * @see com.bostechcorp.cbesb.runtime.ccsl.jbi.messaging.BaseProviderProcessor#processInMessage(javax.xml.namespace.QName, javax.xml.namespace.QName, javax.jbi.messaging.NormalizedMessage)
094: */
095: public void processInMessage(QName service, QName operation,
096: NormalizedMessage in, MessageExchange exchange)
097: throws JBIException, CbesbException {
098:
099: FTPClient ftp = new FTPClient();
100:
101: try {
102:
103: boolean scriptMode = false;
104: NormalizedMessageHandler nmh = new NormalizedMessageHandler(
105: in);
106:
107: String transferDir = endpoint.getTransferDir();
108: if (exchange
109: .getProperty(MetadataConstants.FTP_OUTPUT_TRANSFERMODE) != null
110: && !"".equals(exchange.getProperty(
111: MetadataConstants.FTP_OUTPUT_TRANSFERMODE)
112: .toString())) {
113: transferDir = exchange.getProperty(
114: MetadataConstants.FTP_OUTPUT_TRANSFERMODE)
115: .toString();
116: }
117: if (transferDir != null && !"".equals(transferDir)) {
118: FileOperator.createFolder(transferDir);
119: }
120: String charset = endpoint.getCharset();
121: if (exchange
122: .getProperty(MetadataConstants.FTP_OUTPUT_CHARSET) != null
123: && !"".equals(exchange.getProperty(
124: MetadataConstants.FTP_OUTPUT_CHARSET)
125: .toString())) {
126: charset = exchange.getProperty(
127: MetadataConstants.FTP_OUTPUT_CHARSET)
128: .toString();
129: }
130: if (charset == null || charset.length() < 1) {
131: charset = (new InputStreamReader(
132: new ByteArrayInputStream(new byte[0])))
133: .getEncoding();
134: if (logger.isDebugEnabled())
135: logger
136: .debug("Charset is set to the default value '"
137: + charset + "'.");
138: }
139:
140: String writeStyle = endpoint.getWriteStyle();
141: if (exchange
142: .getProperty(MetadataConstants.FTP_OUTPUT_WRITESTYLE) != null
143: && !"".equals(exchange.getProperty(
144: MetadataConstants.FTP_OUTPUT_WRITESTYLE)
145: .toString())) {
146: writeStyle = exchange.getProperty(
147: MetadataConstants.FTP_OUTPUT_WRITESTYLE)
148: .toString();
149: }
150:
151: if (WRITE_STYLE_RAW.equals(writeStyle)) {
152: for (int i = 0; i < nmh.getRecordCount(); i++) {
153: Source src = nmh.getRecordAtIndex(i);
154: if (src instanceof DOMSource) {
155: DOMSource dom = (DOMSource) src;
156: if (FTP_REQUEST.equals(dom.getNode()
157: .getFirstChild().getNodeName())
158: && FTP_SCRIPT_NAMESPACE.equals(dom
159: .getNode().getFirstChild()
160: .getNamespaceURI())) {
161: scriptMode = true;
162: CommandInterpreter interpreter = new CommandInterpreter();
163: CmdFileParser.runCmdInterpreter(
164: interpreter, dom.getNode()
165: .getFirstChild()
166: .getChildNodes());
167: interpreter.execute(ftp);
168: continue;
169: }
170: }
171: String filePattern = endpoint.getFilePattern();
172: if (exchange
173: .getProperty(MetadataConstants.FTP_OUTPUT_FILENAME) != null
174: && !""
175: .equals(exchange
176: .getProperty(
177: MetadataConstants.FTP_OUTPUT_FILENAME)
178: .toString())) {
179: filePattern = exchange.getProperty(
180: MetadataConstants.FTP_OUTPUT_FILENAME)
181: .toString();
182: }
183: if (filePattern.contains("{COUNT}")) {
184: fileCount.incrementAndGet();
185: }
186: String basename = "BASENAME";
187: if (exchange
188: .getProperty(MetadataConstants.FTP_INPUT_FILENAME) != null
189: && !""
190: .equals(exchange
191: .getProperty(
192: MetadataConstants.FTP_INPUT_FILENAME)
193: .toString())) {
194: logger
195: .debug("Set BASENAME: "
196: + exchange
197: .getProperty(MetadataConstants.FTP_INPUT_FILENAME));
198: basename = exchange.getProperty(
199: MetadataConstants.FTP_INPUT_FILENAME)
200: .toString();
201: } else if (exchange
202: .getProperty(MetadataConstants.FILE_INPUT_FILENAME) != null
203: && !""
204: .equals(exchange
205: .getProperty(
206: MetadataConstants.FILE_INPUT_FILENAME)
207: .toString())) {
208: logger
209: .debug("Set BASENAME: "
210: + exchange
211: .getProperty(MetadataConstants.FILE_INPUT_FILENAME));
212: basename = exchange.getProperty(
213: MetadataConstants.FILE_INPUT_FILENAME)
214: .toString();
215: }
216: String filename = FilePatternMatcher
217: .processFilePattern(basename, filePattern,
218: fileCount.get());
219:
220: FileOperator.createFolder(endpoint.getStageDir());
221: File outFile = new File(endpoint.getStageDir(),
222: filename);
223: OutputStream os = new FileOutputStream(outFile,
224: false);
225: OutputWriter.processOutputStream(src, os,
226: writeStyle, charset);
227: os.close();
228:
229: File move = new File(transferDir + File.separator
230: + outFile.getName());
231: logger.debug("Move file to " + move.getPath());
232: outFile.renameTo(move);
233: }
234: } else if (WRITE_STYLE_NEWLINE.equals(writeStyle)) {
235: String filePattern = endpoint.getFilePattern();
236: if (exchange
237: .getProperty(MetadataConstants.FTP_OUTPUT_FILENAME) != null
238: && !"".equals(exchange.getProperty(
239: MetadataConstants.FTP_OUTPUT_FILENAME)
240: .toString())) {
241: filePattern = exchange.getProperty(
242: MetadataConstants.FTP_OUTPUT_FILENAME)
243: .toString();
244: }
245: if (filePattern.contains("{COUNT}")) {
246: fileCount.incrementAndGet();
247: }
248: String basename = "BASENAME";
249: if (exchange
250: .getProperty(MetadataConstants.FTP_INPUT_FILENAME) != null
251: && !"".equals(exchange.getProperty(
252: MetadataConstants.FTP_INPUT_FILENAME)
253: .toString())) {
254: basename = exchange.getProperty(
255: MetadataConstants.FTP_INPUT_FILENAME)
256: .toString();
257: }
258: String filename = FilePatternMatcher
259: .processFilePattern(basename, filePattern,
260: fileCount.get());
261:
262: FileOperator.createFolder(endpoint.getStageDir());
263: File outFile = new File(endpoint.getStageDir(),
264: filename);
265:
266: for (int i = 0; i < nmh.getRecordCount(); i++) {
267: Source src = nmh.getRecordAtIndex(i);
268: if (src instanceof DOMSource) {
269: DOMSource dom = (DOMSource) src;
270: if (FTP_REQUEST.equals(dom.getNode()
271: .getFirstChild().getNodeName())
272: && FTP_SCRIPT_NAMESPACE.equals(dom
273: .getNode().getFirstChild()
274: .getNodeName())) {
275: scriptMode = true;
276: CommandInterpreter interpreter = new CommandInterpreter();
277: CmdFileParser.runCmdInterpreter(
278: interpreter, dom.getNode()
279: .getFirstChild()
280: .getChildNodes());
281: interpreter.execute(ftp);
282: continue;
283: }
284: }
285: OutputStream os = new FileOutputStream(outFile,
286: true);
287: OutputWriter.processOutputStream(src, os,
288: writeStyle, charset);
289: os.close();
290: }
291:
292: File move = new File(transferDir + File.separator
293: + outFile.getName());
294: logger.debug("Move file to " + move.getPath());
295: outFile.renameTo(move);
296: } else {
297: throw new ConfigurationException(
298: "The value of WriteStyle is not supported. Acceptable values are: \"raw\" or \"newline\".");
299: }
300:
301: if (!scriptMode) {
302: String ftpHost = endpoint.getFtpHost();
303: if (exchange
304: .getProperty(MetadataConstants.FTP_OUTPUT_HOST) != null
305: && !"".equals(exchange.getProperty(
306: MetadataConstants.FTP_OUTPUT_HOST)
307: .toString())) {
308: ftpHost = exchange.getProperty(
309: MetadataConstants.FTP_OUTPUT_HOST)
310: .toString();
311: }
312:
313: String ftpUser = endpoint.getFtpUser();
314: if (exchange
315: .getProperty(MetadataConstants.FTP_OUTPUT_USER) != null
316: && !"".equals(exchange.getProperty(
317: MetadataConstants.FTP_OUTPUT_USER)
318: .toString())) {
319: ftpUser = exchange.getProperty(
320: MetadataConstants.FTP_OUTPUT_USER)
321: .toString();
322: }
323:
324: String ftpPassword = endpoint.getFtpPassword();
325: if (exchange
326: .getProperty(MetadataConstants.FTP_OUTPUT_PASSWORD) != null
327: && !"".equals(exchange.getProperty(
328: MetadataConstants.FTP_OUTPUT_PASSWORD)
329: .toString())) {
330: ftpPassword = exchange.getProperty(
331: MetadataConstants.FTP_OUTPUT_PASSWORD)
332: .toString();
333: }
334: FTPUtils.connectFtp(logger, ftp, ftpHost, ftpUser,
335: ftpPassword);
336:
337: String ftpConnectMode = endpoint.getFtpConnectMode();
338: if (exchange
339: .getProperty(MetadataConstants.FTP_OUTPUT_CONNECTMODE) != null
340: && !""
341: .equals(exchange
342: .getProperty(
343: MetadataConstants.FTP_OUTPUT_CONNECTMODE)
344: .toString())) {
345: ftpConnectMode = exchange.getProperty(
346: MetadataConstants.FTP_OUTPUT_CONNECTMODE)
347: .toString();
348: }
349:
350: String ftpTransferMode = endpoint.getFtpTransferMode();
351: if (exchange
352: .getProperty(MetadataConstants.FTP_OUTPUT_TRANSFERMODE) != null
353: && !""
354: .equals(exchange
355: .getProperty(
356: MetadataConstants.FTP_OUTPUT_TRANSFERMODE)
357: .toString())) {
358: ftpTransferMode = exchange.getProperty(
359: MetadataConstants.FTP_OUTPUT_TRANSFERMODE)
360: .toString();
361: }
362: FTPUtils.setFtpMode(logger, ftp, ftpConnectMode,
363: ftpTransferMode);
364:
365: String destDir = endpoint.getDestDir();
366: if (exchange
367: .getProperty(MetadataConstants.FTP_OUTPUT_DESTDIR) != null
368: && !"".equals(exchange.getProperty(
369: MetadataConstants.FTP_OUTPUT_DESTDIR)
370: .toString())) {
371: destDir = exchange.getProperty(
372: MetadataConstants.FTP_OUTPUT_DESTDIR)
373: .toString();
374: }
375: // Change directory to destDir.
376: boolean changeWorkingDirFlag = ftp
377: .changeWorkingDirectory(destDir);
378: if (!changeWorkingDirFlag) {
379: throw new ConfigurationException(
380: "Error to change FTP working directory: '"
381: + destDir + "'.",
382: "Make sure the destination directory is valid and accessible.");
383: }
384: File[] uploadFiles = FileOperator.scanDir(transferDir);
385: for (int i = 0; i < uploadFiles.length; i++) {
386: FileInputStream fis = new FileInputStream(
387: uploadFiles[i]);
388: ftp.storeFile(uploadFiles[i].getName(), fis);
389: fis.close();
390: if (FILE_COMPLETE_ACTION_ARCHIVE.equals(endpoint
391: .getFileCompleteAction())) {
392: logger.debug("Archive file: "
393: + uploadFiles[i].getName()
394: + " after upload.");
395: if (endpoint.getArchiveDir() == null
396: || "".equals(endpoint.getArchiveDir())) {
397: throw new ConfigurationException(
398: "The attribute [archiveDir] is required when the [fileCompleteAction=\"archive\"].");
399: }
400: File archiveDir = new File(endpoint
401: .getArchiveDir());
402: if (!archiveDir.exists()) {
403: archiveDir.mkdirs();
404: }
405: File archiveFile = new File(archiveDir + "/"
406: + uploadFiles[i].getName());
407: logger.debug("Move file: "
408: + uploadFiles[i].getAbsolutePath()
409: + " to "
410: + archiveFile.getAbsolutePath());
411: uploadFiles[i].renameTo(archiveFile);
412: } else {
413: logger.debug("Delete file: "
414: + uploadFiles[i].getAbsolutePath()
415: + " after upload.");
416: uploadFiles[i].delete();
417: }
418: }
419:
420: }
421: } catch (IOException e) {
422: throw new ResourcesConnectionException(
423: "Exception in writing to the FTP server - "
424: + e.getMessage(),
425: "Make sure the FTP serve is accessible.", e);
426: } finally {
427: FTPUtils.disconnectFtp(logger, ftp);
428: }
429: }
430:
431: /* (non-Javadoc)
432: * @see com.bostechcorp.cbesb.runtime.ccsl.jbi.messaging.BaseProviderProcessor#processInOutMessage(javax.xml.namespace.QName, javax.xml.namespace.QName, javax.jbi.messaging.NormalizedMessage, javax.jbi.messaging.NormalizedMessage, boolean)
433: */
434: public boolean processInOutMessage(QName service, QName operation,
435: NormalizedMessage in, NormalizedMessage out,
436: boolean optionalOut, MessageExchange exchange)
437: throws JBIException, CbesbException {
438: FTPClient ftp = new FTPClient();
439:
440: NormalizedMessageHandler nmh = new NormalizedMessageHandler(in);
441:
442: for (int i = 0; i < nmh.getRecordCount(); i++) {
443: Source src = nmh.getRecordAtIndex(i);
444:
445: DOMSource dom = null;
446: if (src instanceof DOMSource) {
447: dom = (DOMSource) src;
448: } else {
449: DOMResult dr = new DOMResult();
450: TransformerFactory tf = TransformerFactory
451: .newInstance();
452: try {
453: Transformer t = tf.newTransformer();
454: t.transform(src, dr);
455: } catch (TransformerException e) {
456: throw new DataContentException(
457: "Failed while converting data into DOMSource - "
458: + e.getMessage(),
459: "Verify the data is well-formed XML", e);
460: }
461: dom = new DOMSource(dr.getNode());
462: }
463:
464: if (FTP_REQUEST.equals(dom.getNode().getFirstChild()
465: .getNodeName())
466: && FTP_SCRIPT_NAMESPACE.equals(dom.getNode()
467: .getFirstChild().getNamespaceURI())) {
468: CommandInterpreter interpreter = new CommandInterpreter();
469: CmdFileParser.runCmdInterpreter(interpreter, dom
470: .getNode().getFirstChild().getChildNodes());
471: Object obj = interpreter.execute(ftp);
472:
473: StringBuffer buffer = new StringBuffer("");
474: appendFtpResponseOpeningTag(buffer);
475: if (obj instanceof Exception) {
476: Exception e = (Exception) obj;
477: appendElement(buffer, false, "", e.getMessage());
478: } else if (obj instanceof Boolean) {
479: boolean b = ((Boolean) obj).booleanValue();
480: appendElement(buffer, b, "", "");
481: }
482: appendFtpResponseClosingTag(buffer);
483: //setOutMessageContent(out, buffer);
484: // try {
485: NormalizedMessageUtil.addXmlRecord(out, buffer
486: .toString());
487: // } catch (CbesbException e) {
488: // ErrorUtil.printError("FTP Error", e);
489: // }
490: }
491: }
492: return true;
493: }
494:
495: private void appendFtpResponseOpeningTag(StringBuffer buffer) {
496: buffer.append("<" + FTP_RESPONSE + " xmlns=\""
497: + FTP_SCRIPT_NAMESPACE + "\">");
498: }
499:
500: private void appendElement(StringBuffer buffer,
501: boolean elementStatus, String elementResult,
502: String elementError) {
503: buffer.append("<" + STATUS + ">");
504: if (elementStatus) {
505: buffer.append("true");
506: buffer.append("</" + STATUS + ">");
507: buffer.append("<" + RESULT + ">");
508: buffer.append(elementResult);
509: buffer.append("</" + RESULT + ">");
510: } else {
511: buffer.append("false");
512: buffer.append("</" + STATUS + ">");
513: buffer.append("<" + ERROR + ">");
514: buffer.append(elementError);
515: buffer.append("</" + ERROR + ">");
516: }
517: buffer.append("\r\n");
518: }
519:
520: private void appendFtpResponseClosingTag(StringBuffer buffer) {
521: buffer.append("</" + FTP_RESPONSE + ">");
522: }
523:
524: }
|