/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.synapse.commons.vfs; import org.apache.axis2.context.MessageContext; import org.apache.axis2.transport.OutTransportInfo; import org.apache.axis2.transport.base.BaseUtils; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.commons.vfs2.provider.UriParser; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; import java.util.Map; /** * The VFS OutTransportInfo is a holder of information to send an outgoing message * (e.g. a Response) to a VFS destination. Thus at a minimum a reference to a * File URI (i.e. directory or a file) are held */ public class VFSOutTransportInfo implements OutTransportInfo { private static final Log log = LogFactory.getLog(VFSOutTransportInfo.class); private String outFileURI = null; private String outFileName = null; private String contentType = null; private int maxRetryCount = 3; private long reconnectTimeout = 30000; private boolean append; private boolean fileLocking; private Map<String, String> fso = null; private boolean sendFileSynchronously = false; //When the folder structure does not exists forcefully create private boolean forceCreateFolder = false; private static final String[] uriParamsToDelete = {VFSConstants.APPEND+"=true", VFSConstants.APPEND+"=false"}; /** * Constructs the VFSOutTransportInfo containing the information about the file to which the * response has to be submitted to. * * @param outFileURI URI of the file to which the message is delivered */ public VFSOutTransportInfo(String outFileURI, boolean fileLocking) { if (outFileURI.startsWith(VFSConstants.VFS_PREFIX)) { String vfsURI = outFileURI.substring(VFSConstants.VFS_PREFIX.length()); String queryParams = UriParser.extractQueryString(new StringBuilder(vfsURI)); //Lets get rid of unwanted query params and clean the URI if(null != queryParams && !"".equals(queryParams) && vfsURI.contains(VFSConstants.APPEND)) { this.outFileURI = cleanURI(vfsURI, queryParams, outFileURI); } else { this.outFileURI = vfsURI; } } else { this.outFileURI = outFileURI; } Map<String,String> properties = BaseUtils.getEPRProperties(outFileURI); String scheme = UriParser.extractScheme(this.outFileURI); properties.put(VFSConstants.SCHEME, scheme); setOutFileSystemOptionsMap(properties); if (properties.containsKey(VFSConstants.SUBFOLDER_TIMESTAMP)) { String strSubfolderFormat = properties.get(VFSConstants.SUBFOLDER_TIMESTAMP); try { SimpleDateFormat sdf = new SimpleDateFormat(strSubfolderFormat); String strDateformat = sdf.format(new Date()); int iIndex = this.outFileURI.indexOf("?"); if (iIndex > -1) { this.outFileURI = this.outFileURI.substring(0, iIndex) + strDateformat + this.outFileURI.substring(iIndex, this.outFileURI.length()); }else{ this.outFileURI += strDateformat; } } catch (Exception e) { log.warn("Error generating subfolder name with date", e); } } if (properties.containsKey(VFSConstants.MAX_RETRY_COUNT)) { String strMaxRetryCount = properties.get(VFSConstants.MAX_RETRY_COUNT); maxRetryCount = Integer.parseInt(strMaxRetryCount); } else { maxRetryCount = VFSConstants.DEFAULT_MAX_RETRY_COUNT; } forceCreateFolder = false; if (properties.containsKey(VFSConstants.FORCE_CREATE_FOLDER)) { String strForceCreateFolder = properties.get(VFSConstants.FORCE_CREATE_FOLDER); if (strForceCreateFolder != null && strForceCreateFolder.toLowerCase().equals("true")) { forceCreateFolder = true; } } if (properties.containsKey(VFSConstants.RECONNECT_TIMEOUT)) { String strReconnectTimeout = properties.get(VFSConstants.RECONNECT_TIMEOUT); reconnectTimeout = Long.parseLong(strReconnectTimeout) * 1000; } else { reconnectTimeout = VFSConstants.DEFAULT_RECONNECT_TIMEOUT; } if (properties.containsKey(VFSConstants.TRANSPORT_FILE_LOCKING)) { String strFileLocking = properties.get(VFSConstants.TRANSPORT_FILE_LOCKING); if (VFSConstants.TRANSPORT_FILE_LOCKING_ENABLED.equals(strFileLocking)) { fileLocking = true; } else if (VFSConstants.TRANSPORT_FILE_LOCKING_DISABLED.equals(strFileLocking)) { fileLocking = false; } } else { this.fileLocking = fileLocking; } if (properties.containsKey(VFSConstants.TRANSPORT_FILE_SEND_FILE_LOCKING)) { String strSendLocking = properties.get(VFSConstants.TRANSPORT_FILE_SEND_FILE_LOCKING); sendFileSynchronously = Boolean.parseBoolean(strSendLocking); } else { sendFileSynchronously = false; } if (properties.containsKey(VFSConstants.APPEND)) { String strAppend = properties.get(VFSConstants.APPEND); append = Boolean.parseBoolean(strAppend); } if (log.isDebugEnabled()) { log.debug("Using the fileURI : " + this.outFileURI); log.debug("Using the maxRetryCount : " + maxRetryCount); log.debug("Using the reconnectionTimeout : " + reconnectTimeout); log.debug("Using the append : " + append); log.debug("File locking : " + (this.fileLocking ? "ON" : "OFF")); } } private String cleanURI(String vfsURI, String queryParams, String originalFileURI) { // Using Apache Commons StringUtils and Java StringBuilder for improved performance. vfsURI = StringUtils.replace(vfsURI, "?" + queryParams, ""); for(String deleteParam: uriParamsToDelete) { queryParams = StringUtils.replace(queryParams, deleteParam, ""); } queryParams = StringUtils.replace(queryParams, "&&", "&"); // We can sometimes be left with && in the URI if(!"".equals(queryParams) && queryParams.toCharArray()[0] == "&".charAt(0)) { queryParams = queryParams.substring(1); } else if("".equals(queryParams)) { return vfsURI; } String[] queryParamsArray = queryParams.split("&"); StringBuilder newQueryParams = new StringBuilder(""); if(queryParamsArray.length > 0) { for(String param : queryParamsArray) { newQueryParams.append(param); newQueryParams.append("&"); } newQueryParams = newQueryParams.deleteCharAt(newQueryParams.length()-1); if(!"".equals(newQueryParams)) { return vfsURI + "?" + newQueryParams; } else { return vfsURI; } } else { return originalFileURI.substring(VFSConstants.VFS_PREFIX.length()); } } public boolean isForceCreateFolder(MessageContext msgCtx) { // first preference to set on the current message context Map transportHeaders = (Map) msgCtx.getProperty(MessageContext.TRANSPORT_HEADERS); if (transportHeaders != null && "true" .equals((String) transportHeaders.get(VFSConstants.FORCE_CREATE_FOLDER))) { return true; } // next check if the OutTransportInfo specifies one return this.isForceCreateFolder(); } public void setContentType(String contentType) { this.contentType = contentType; } public String getOutFileURI() { return outFileURI; } public boolean getSendFileSynchronously(){ return sendFileSynchronously; } public String getOutFileName() { return outFileName; } public int getMaxRetryCount() { return maxRetryCount; } public void setMaxRetryCount(int maxRetryCount) { this.maxRetryCount = maxRetryCount; } public long getReconnectTimeout() { return reconnectTimeout; } public void setReconnectTimeout(long reconnectTimeout) { this.reconnectTimeout = reconnectTimeout; } public boolean isAppend() { return append; } public void setAppend(boolean append) { this.append = append; } public String getContentType() { return contentType; } public boolean isFileLockingEnabled() { return fileLocking; } public Map<String, String> getOutFileSystemOptionsMap() { return fso; } private void setOutFileSystemOptionsMap(Map<String, String> fso) { HashMap<String, String> options = new HashMap<String, String>(); if (VFSConstants.SCHEME_SFTP.equals(fso.get(VFSConstants.SCHEME))) { for (String key: fso.keySet()) { options.put(key.replaceAll(VFSConstants.SFTP_PREFIX, ""), fso.get(key)); } } if (VFSConstants.SCHEME_FTP.equals(fso.get(VFSConstants.SCHEME)) || VFSConstants.SCHEME_FTPS.equals(fso.get(VFSConstants.SCHEME))) { if (fso.get(VFSConstants.FILE_TYPE_PREFIX) != null) { options.put(VFSConstants.FILE_TYPE, fso.get(VFSConstants.FILE_TYPE_PREFIX)); options.put(VFSConstants.SCHEME, fso.get(VFSConstants.SCHEME)); } } this.fso = options; } /** * @return the forceCreateFolder */ public boolean isForceCreateFolder() { return forceCreateFolder; } /** * @param forceCreateFolder the forceCreateFolder to set */ public void setForceCreateFolder(boolean forceCreateFolder) { this.forceCreateFolder = forceCreateFolder; } }