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