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 */
017package org.apache.camel.component.file.strategy;
018
019import java.io.File;
020import java.util.Map;
021
022import org.apache.camel.CamelContext;
023import org.apache.camel.Expression;
024import org.apache.camel.LoggingLevel;
025import org.apache.camel.component.file.GenericFileExclusiveReadLockStrategy;
026import org.apache.camel.component.file.GenericFileProcessStrategy;
027import org.apache.camel.spi.Language;
028import org.apache.camel.util.ObjectHelper;
029
030public final class FileProcessStrategyFactory {
031
032    private FileProcessStrategyFactory() {
033    }
034
035    public static GenericFileProcessStrategy<File> createGenericFileProcessStrategy(CamelContext context, Map<String, Object> params) {
036
037        // We assume a value is present only if its value not null for String and 'true' for boolean
038        Expression moveExpression = (Expression) params.get("move");
039        Expression moveFailedExpression = (Expression) params.get("moveFailed");
040        Expression preMoveExpression = (Expression) params.get("preMove");
041        boolean isNoop = params.get("noop") != null;
042        boolean isDelete = params.get("delete") != null;
043        boolean isMove = moveExpression != null || preMoveExpression != null || moveFailedExpression != null;
044
045        if (isDelete) {
046            GenericFileDeleteProcessStrategy<File> strategy = new GenericFileDeleteProcessStrategy<File>();
047            strategy.setExclusiveReadLockStrategy(getExclusiveReadLockStrategy(params));
048            if (preMoveExpression != null) {
049                GenericFileExpressionRenamer<File> renamer = new GenericFileExpressionRenamer<File>();
050                renamer.setExpression(preMoveExpression);
051                strategy.setBeginRenamer(renamer);
052            }
053            if (moveFailedExpression != null) {
054                GenericFileExpressionRenamer<File> renamer = new GenericFileExpressionRenamer<File>();
055                renamer.setExpression(moveFailedExpression);
056                strategy.setFailureRenamer(renamer);
057            }
058            return strategy;
059        } else if (isMove || isNoop) {
060            GenericFileRenameProcessStrategy<File> strategy = new GenericFileRenameProcessStrategy<File>();
061            strategy.setExclusiveReadLockStrategy(getExclusiveReadLockStrategy(params));
062            if (!isNoop) {
063                // move on commit is only possible if not noop
064                if (moveExpression != null) {
065                    GenericFileExpressionRenamer<File> renamer = new GenericFileExpressionRenamer<File>();
066                    renamer.setExpression(moveExpression);
067                    strategy.setCommitRenamer(renamer);
068                } else {
069                    strategy.setCommitRenamer(getDefaultCommitRenamer(context));
070                }
071            }
072            // both move and noop supports pre move
073            if (preMoveExpression != null) {
074                GenericFileExpressionRenamer<File> renamer = new GenericFileExpressionRenamer<File>();
075                renamer.setExpression(preMoveExpression);
076                strategy.setBeginRenamer(renamer);
077            }
078            // both move and noop supports move failed
079            if (moveFailedExpression != null) {
080                GenericFileExpressionRenamer<File> renamer = new GenericFileExpressionRenamer<File>();
081                renamer.setExpression(moveFailedExpression);
082                strategy.setFailureRenamer(renamer);
083            }
084            return strategy;
085        } else {
086            // default strategy will move files in a .camel/ subfolder where the file was consumed
087            GenericFileRenameProcessStrategy<File> strategy = new GenericFileRenameProcessStrategy<File>();
088            strategy.setExclusiveReadLockStrategy(getExclusiveReadLockStrategy(params));
089            strategy.setCommitRenamer(getDefaultCommitRenamer(context));
090            return strategy;
091        }
092    }
093
094    private static GenericFileExpressionRenamer<File> getDefaultCommitRenamer(CamelContext context) {
095        // use context to lookup language to let it be loose coupled
096        Language language = context.resolveLanguage("file");
097        Expression expression = language.createExpression("${file:parent}/.camel/${file:onlyname}");
098        return new GenericFileExpressionRenamer<File>(expression);
099    }
100
101    @SuppressWarnings("unchecked")
102    private static GenericFileExclusiveReadLockStrategy<File> getExclusiveReadLockStrategy(Map<String, Object> params) {
103        GenericFileExclusiveReadLockStrategy<File> strategy = (GenericFileExclusiveReadLockStrategy<File>) params.get("exclusiveReadLockStrategy");
104        if (strategy != null) {
105            return strategy;
106        }
107
108        // no explicit strategy set then fallback to readLock option
109        String readLock = (String) params.get("readLock");
110        if (ObjectHelper.isNotEmpty(readLock)) {
111            if ("none".equals(readLock) || "false".equals(readLock)) {
112                return null;
113            } else if ("markerFile".equals(readLock)) {
114                return new MarkerFileExclusiveReadLockStrategy();
115            } else if ("fileLock".equals(readLock)) {
116                strategy = new FileLockExclusiveReadLockStrategy();
117            } else if ("rename".equals(readLock)) {
118                strategy = new FileRenameExclusiveReadLockStrategy();
119            } else if ("changed".equals(readLock)) {
120                FileChangedExclusiveReadLockStrategy readLockStrategy = new FileChangedExclusiveReadLockStrategy();
121                Long minLength = (Long) params.get("readLockMinLength");
122                if (minLength != null) {
123                    readLockStrategy.setMinLength(minLength);
124                }
125                Long minAge = (Long) params.get("readLockMinAge");
126                if (null != minAge) {
127                    readLockStrategy.setMinAge(minAge);
128                }
129                strategy = readLockStrategy;
130            }
131
132            if (strategy != null) {
133                Long timeout = (Long) params.get("readLockTimeout");
134                if (timeout != null) {
135                    strategy.setTimeout(timeout);
136                }
137                Long checkInterval = (Long) params.get("readLockCheckInterval");
138                if (checkInterval != null) {
139                    strategy.setCheckInterval(checkInterval);
140                }
141                LoggingLevel readLockLoggingLevel = (LoggingLevel) params.get("readLockLoggingLevel");
142                if (readLockLoggingLevel != null) {
143                    strategy.setReadLockLoggingLevel(readLockLoggingLevel);
144                }
145                Boolean readLockMarkerFile = (Boolean) params.get("readLockMarkerFile");
146                if (readLockMarkerFile != null) {
147                    strategy.setMarkerFiler(readLockMarkerFile);
148                }
149            }
150        }
151
152        return strategy;
153    }
154}