001: /*
002: * $Id: FileMessageRequester.java 11343 2008-03-13 10:58:26Z tcarlson $
003: * --------------------------------------------------------------------------------------
004: * Copyright (c) MuleSource, Inc. All rights reserved. http://www.mulesource.com
005: *
006: * The software in this package is published under the terms of the CPAL v1.0
007: * license, a copy of which has been included with this distribution in the
008: * LICENSE.txt file.
009: */
010:
011: package org.mule.transport.file;
012:
013: import org.mule.DefaultMuleMessage;
014: import org.mule.MuleServer;
015: import org.mule.api.DefaultMuleException;
016: import org.mule.api.MuleException;
017: import org.mule.api.MuleMessage;
018: import org.mule.api.endpoint.InboundEndpoint;
019: import org.mule.api.transport.MessageAdapter;
020: import org.mule.transport.AbstractMessageRequester;
021: import org.mule.transport.DefaultMessageAdapter;
022: import org.mule.transport.file.filters.FilenameWildcardFilter;
023: import org.mule.transport.file.i18n.FileMessages;
024: import org.mule.util.FileUtils;
025:
026: import java.io.File;
027: import java.io.FileNotFoundException;
028: import java.io.FilenameFilter;
029: import java.net.URLDecoder;
030:
031: /**
032: * <code>FileMessageDispatcher</code> is used to read/write files to the filesystem
033: */
034: public class FileMessageRequester extends AbstractMessageRequester {
035: private final FileConnector connector;
036:
037: public FileMessageRequester(InboundEndpoint endpoint) {
038: super (endpoint);
039: this .connector = (FileConnector) endpoint.getConnector();
040: }
041:
042: /**
043: * There is no associated session for a file connector
044: *
045: * @throws org.mule.api.MuleException
046: */
047: public Object getDelegateSession() throws MuleException {
048: return null;
049: }
050:
051: /**
052: * Will attempt to do a receive from a directory, if the endpointUri resolves to
053: * a file name the file will be returned, otherwise the first file in the
054: * directory according to the filename filter configured on the connector.
055: *
056: * @param timeout this is ignored when doing a receive on this dispatcher
057: * @return a message containing file contents or null if there was notthing to
058: * receive
059: * @throws Exception
060: */
061:
062: protected MuleMessage doRequest(long timeout) throws Exception {
063: File file = FileUtils.newFile(endpoint.getEndpointURI()
064: .getAddress());
065: File result = null;
066: FilenameFilter filenameFilter = null;
067: String filter = (String) endpoint.getProperty("filter");
068: if (filter != null) {
069: filter = URLDecoder.decode(filter, MuleServer
070: .getMuleContext().getConfiguration()
071: .getDefaultEncoding());
072: filenameFilter = new FilenameWildcardFilter(filter);
073: }
074: if (file.exists()) {
075: if (file.isFile()) {
076: result = file;
077: } else if (file.isDirectory()) {
078: result = FileMessageDispatcher.getNextFile(endpoint
079: .getEndpointURI().getAddress(), filenameFilter);
080: }
081: if (result != null) {
082: boolean checkFileAge = connector.getCheckFileAge();
083: if (checkFileAge) {
084: long fileAge = connector.getFileAge();
085: long lastMod = result.lastModified();
086: long now = System.currentTimeMillis();
087: long this FileAge = now - lastMod;
088: if (this FileAge < fileAge) {
089: if (logger.isDebugEnabled()) {
090: logger
091: .debug("The file has not aged enough yet, will return nothing for: "
092: + result.getCanonicalPath());
093: }
094: return null;
095: }
096: }
097:
098: // Don't we need to try to obtain a file lock as we do with receiver
099:
100: FileConnector fc = ((FileConnector) connector);
101:
102: String sourceFileOriginalName = result.getName();
103:
104: // This isn't nice but is needed as MessageAdaptor is required to
105: // resolve
106: // destination file name, and StreamingReceiverFileInputStream is
107: // required to create MessageAdaptor
108: DefaultMessageAdapter fileParserMsgAdaptor = new DefaultMessageAdapter(
109: null);
110: fileParserMsgAdaptor.setProperty(
111: FileConnector.PROPERTY_ORIGINAL_FILENAME,
112: sourceFileOriginalName);
113:
114: // set up destination file
115: File destinationFile = null;
116: String movDir = fc.getMoveToDirectory();
117: if (movDir != null) {
118: String destinationFileName = sourceFileOriginalName;
119: String moveToPattern = fc.getMoveToPattern();
120: if (moveToPattern != null) {
121: destinationFileName = ((FileConnector) connector)
122: .getFilenameParser().getFilename(
123: fileParserMsgAdaptor,
124: moveToPattern);
125: }
126: // don't use new File() directly, see MULE-1112
127: destinationFile = FileUtils.newFile(movDir,
128: destinationFileName);
129: }
130:
131: MessageAdapter msgAdapter = null;
132: try {
133: if (fc.isStreaming()) {
134: msgAdapter = connector
135: .getMessageAdapter(new ReceiverFileInputStream(
136: result, fc.isAutoDelete(),
137: destinationFile));
138: } else {
139: msgAdapter = connector
140: .getMessageAdapter(result);
141: }
142: } catch (FileNotFoundException e) {
143: // we can ignore since we did manage to acquire a lock, but just
144: // in case
145: logger.error("File being read disappeared!", e);
146: return null;
147: }
148: msgAdapter.setProperty(
149: FileConnector.PROPERTY_ORIGINAL_FILENAME,
150: sourceFileOriginalName);
151:
152: if (!fc.isStreaming()) {
153: moveOrDelete(result, destinationFile);
154: return new DefaultMuleMessage(msgAdapter);
155: } else {
156: // If we are streaming no need to move/delete now, that will be
157: // done when stream is closed
158: return new DefaultMuleMessage(msgAdapter);
159: }
160: }
161: }
162: return null;
163: }
164:
165: private void moveOrDelete(final File sourceFile,
166: File destinationFile) throws DefaultMuleException {
167:
168: if (destinationFile != null) {
169: // move sourceFile to new destination
170: if (!FileUtils.moveFile(sourceFile, destinationFile)) {
171: throw new DefaultMuleException(FileMessages
172: .failedToMoveFile(sourceFile.getAbsolutePath(),
173: destinationFile.getAbsolutePath()));
174: }
175: }
176: if (((FileConnector) connector).isAutoDelete()) {
177: // no moveTo directory
178: if (destinationFile == null) {
179: // delete source
180: if (!sourceFile.delete()) {
181: throw new DefaultMuleException(FileMessages
182: .failedToDeleteFile(sourceFile
183: .getAbsolutePath()));
184: }
185: } else {
186: // nothing to do here since moveFile() should have deleted
187: // the source file for us
188: }
189: }
190:
191: }
192:
193: protected void doDispose() {
194: // no op
195: }
196:
197: protected void doConnect() throws Exception {
198: // no op
199: }
200:
201: protected void doDisconnect() throws Exception {
202: // no op
203: }
204:
205: }
|