001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.servicemix.vfs;
018
019 import java.io.IOException;
020 import java.io.OutputStream;
021
022 import javax.jbi.messaging.MessageExchange;
023 import javax.jbi.messaging.MessagingException;
024 import javax.jbi.messaging.NormalizedMessage;
025
026 import org.apache.commons.logging.Log;
027 import org.apache.commons.logging.LogFactory;
028 import org.apache.commons.vfs.FileContent;
029 import org.apache.commons.vfs.FileObject;
030 import org.apache.commons.vfs.FileSystemManager;
031 import org.apache.servicemix.common.endpoints.ProviderEndpoint;
032 import org.apache.servicemix.components.util.DefaultFileMarshaler;
033 import org.apache.servicemix.components.util.FileMarshaler;
034
035 /**
036 * An endpoint which receives messages from the NMR and writes the message to
037 * the virtual file system.
038 *
039 * @org.apache.xbean.XBean element="sender"
040 *
041 * @author lhein
042 */
043 public class VFSSendingEndpoint extends ProviderEndpoint implements VFSEndpointType {
044 private static final Log logger = LogFactory.getLog(VFSSendingEndpoint.class);
045
046 private FileObject file;
047 private FileMarshaler marshaler = new DefaultFileMarshaler();
048 private String path;
049 private FileSystemManager fileSystemManager;
050
051 /**
052 * resolves the given path to a file object
053 */
054 protected void resolvePath() throws Exception {
055 if (file == null) {
056 file = FileObjectResolver.resolveToFileObject(getFileSystemManager(), getPath());
057 }
058 }
059
060 @Override
061 protected void processInOnly(MessageExchange exchange, NormalizedMessage in)
062 throws Exception {
063 // resolve the file path
064 resolvePath();
065
066 OutputStream out = null;
067 String tmpName = null;
068 String name = null;
069 FileObject tmpFile = null;
070 FileObject newFile = null;
071 FileContent content = null;
072 try {
073 name = marshaler.getOutputName(exchange, in);
074 if (name == null) {
075 throw new MessagingException("No output name available. Cannot output message!");
076 }
077 tmpName = marshaler.getTempOutputName(exchange, in);
078 file.close(); // remove any cached informations
079 if (tmpName != null) {
080 // writing to temp file first
081 tmpFile = tmpName != null ? file.resolveFile(tmpName) : null;
082 tmpFile.close();
083 content = tmpFile.getContent();
084 } else {
085 // writing to target file
086 newFile = file.resolveFile(name);
087 newFile.close(); // remove any cached informations
088 content = newFile.getContent();
089 }
090 // remove any cached informations
091 content.close();
092 if (content != null) {
093 out = content.getOutputStream();
094 }
095 if (out == null) {
096 throw new MessagingException("No output stream available for output name: " + name);
097 }
098 marshaler.writeMessage(exchange, in, out, name);
099 }
100 finally {
101 if (out != null) {
102 try {
103 out.close();
104 }
105 catch (IOException e) {
106 logger.error("Caught exception while closing stream on error: " + e, e);
107 }
108 }
109 if (tmpName != null && name != null && !name.equals(tmpName)) {
110 if (!tmpFile.canRenameTo(newFile)) {
111 throw new IOException("File " + tmpName + " could not be renamed to " + name);
112 } else {
113 tmpFile.moveTo(newFile);
114 }
115 }
116 }
117 }
118
119 /**
120 * Specifies a <code>String</code> object representing the path of the
121 * file/folder to be polled.<br /><br />
122 * <b><u>Examples:</u></b><br />
123 * <ul>
124 * <li>file:///home/lhein/pollFolder</li>
125 * <li>zip:file:///home/lhein/pollFolder/myFile.zip</li>
126 * <li>jar:http://www.myhost.com/files/Examples.jar</li>
127 * <li>jar:../lib/classes.jar!/META-INF/manifest.mf</li>
128 * <li>tar:gz:http://anyhost/dir/mytar.tar.gz!/mytar.tar!/path/in/tar/README.txt</li>
129 * <li>tgz:file://anyhost/dir/mytar.tgz!/somepath/somefile</li>
130 * <li>gz:/my/gz/file.gz</li>
131 * <li>http://myusername@somehost/index.html</li>
132 * <li>webdav://somehost:8080/dist</li>
133 * <li>ftp://myusername:mypassword@somehost/pub/downloads/somefile.tgz</li>
134 * <li>sftp://myusername:mypassword@somehost/pub/downloads/somefile.tgz</li>
135 * <li>smb://somehost/home</li>
136 * <li>tmp://dir/somefile.txt</li>
137 * <li>res:path/in/classpath/image.png</li>
138 * <li>ram:///any/path/to/file.txt</li>
139 * <li>mime:file:///your/path/mail/anymail.mime!/filename.pdf</li>
140 * </ul>
141 *
142 * For further details have a look at {@link http://commons.apache.org/vfs/filesystems.html}.
143 * <br /><br />
144 *
145 * @param path a <code>String</code> object that represents a file/folder/vfs
146 */
147 public void setPath(String path) {
148 this.path = path;
149 }
150
151 public String getPath() {
152 return this.path;
153 }
154
155 /**
156 * sets the file system manager
157 *
158 * @param fileSystemManager the file system manager
159 */
160 public void setFileSystemManager(FileSystemManager fileSystemManager) {
161 this.fileSystemManager = fileSystemManager;
162 }
163
164 public FileSystemManager getFileSystemManager() {
165 return this.fileSystemManager;
166 }
167
168 /**
169 * Specifies a <code>FileMarshaler</code> object that will marshal file data
170 * into the NMR. The default file marshaller can read valid XML data.
171 * <code>FileMarshaler</code> objects are implementations of
172 * <code>org.apache.servicemix.components.util.FileMarshaler</code>.
173 *
174 * @param marshaler a <code>FileMarshaler</code> object that can read data
175 * from the file system.
176 */
177 public void setMarshaler(FileMarshaler marshaler) {
178 this.marshaler = marshaler;
179 }
180
181 public FileMarshaler getMarshaler() {
182 return marshaler;
183 }
184 }