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.IdempotentRepository;
028import org.apache.camel.spi.Language;
029import org.apache.camel.util.ObjectHelper;
030
031public final class FileProcessStrategyFactory {
032
033    private FileProcessStrategyFactory() {
034    }
035
036    public static GenericFileProcessStrategy<File> createGenericFileProcessStrategy(CamelContext context, Map<String, Object> params) {
037
038        // We assume a value is present only if its value not null for String and 'true' for boolean
039        Expression moveExpression = (Expression) params.get("move");
040        Expression moveFailedExpression = (Expression) params.get("moveFailed");
041        Expression preMoveExpression = (Expression) params.get("preMove");
042        boolean isNoop = params.get("noop") != null;
043        boolean isDelete = params.get("delete") != null;
044        boolean isMove = moveExpression != null || preMoveExpression != null || moveFailedExpression != null;
045
046        if (isDelete) {
047            GenericFileDeleteProcessStrategy<File> strategy = new GenericFileDeleteProcessStrategy<File>();
048            strategy.setExclusiveReadLockStrategy(getExclusiveReadLockStrategy(params));
049            if (preMoveExpression != null) {
050                GenericFileExpressionRenamer<File> renamer = new GenericFileExpressionRenamer<File>();
051                renamer.setExpression(preMoveExpression);
052                strategy.setBeginRenamer(renamer);
053            }
054            if (moveFailedExpression != null) {
055                GenericFileExpressionRenamer<File> renamer = new GenericFileExpressionRenamer<File>();
056                renamer.setExpression(moveFailedExpression);
057                strategy.setFailureRenamer(renamer);
058            }
059            return strategy;
060        } else if (isMove || isNoop) {
061            GenericFileRenameProcessStrategy<File> strategy = new GenericFileRenameProcessStrategy<File>();
062            strategy.setExclusiveReadLockStrategy(getExclusiveReadLockStrategy(params));
063            if (!isNoop) {
064                // move on commit is only possible if not noop
065                if (moveExpression != null) {
066                    GenericFileExpressionRenamer<File> renamer = new GenericFileExpressionRenamer<File>();
067                    renamer.setExpression(moveExpression);
068                    strategy.setCommitRenamer(renamer);
069                } else {
070                    strategy.setCommitRenamer(getDefaultCommitRenamer(context));
071                }
072            }
073            // both move and noop supports pre move
074            if (preMoveExpression != null) {
075                GenericFileExpressionRenamer<File> renamer = new GenericFileExpressionRenamer<File>();
076                renamer.setExpression(preMoveExpression);
077                strategy.setBeginRenamer(renamer);
078            }
079            // both move and noop supports move failed
080            if (moveFailedExpression != null) {
081                GenericFileExpressionRenamer<File> renamer = new GenericFileExpressionRenamer<File>();
082                renamer.setExpression(moveFailedExpression);
083                strategy.setFailureRenamer(renamer);
084            }
085            return strategy;
086        } else {
087            // default strategy will move files in a .camel/ subfolder where the file was consumed
088            GenericFileRenameProcessStrategy<File> strategy = new GenericFileRenameProcessStrategy<File>();
089            strategy.setExclusiveReadLockStrategy(getExclusiveReadLockStrategy(params));
090            strategy.setCommitRenamer(getDefaultCommitRenamer(context));
091            return strategy;
092        }
093    }
094
095    private static GenericFileExpressionRenamer<File> getDefaultCommitRenamer(CamelContext context) {
096        // use context to lookup language to let it be loose coupled
097        Language language = context.resolveLanguage("file");
098        Expression expression = language.createExpression("${file:parent}/.camel/${file:onlyname}");
099        return new GenericFileExpressionRenamer<File>(expression);
100    }
101
102    @SuppressWarnings("unchecked")
103    private static GenericFileExclusiveReadLockStrategy<File> getExclusiveReadLockStrategy(Map<String, Object> params) {
104        GenericFileExclusiveReadLockStrategy<File> strategy = (GenericFileExclusiveReadLockStrategy<File>) params.get("exclusiveReadLockStrategy");
105        if (strategy != null) {
106            return strategy;
107        }
108
109        // no explicit strategy set then fallback to readLock option
110        String readLock = (String) params.get("readLock");
111        if (ObjectHelper.isNotEmpty(readLock)) {
112            if ("none".equals(readLock) || "false".equals(readLock)) {
113                return null;
114            } else if ("markerFile".equals(readLock)) {
115                strategy = new MarkerFileExclusiveReadLockStrategy();
116            } else if ("fileLock".equals(readLock)) {
117                strategy = new FileLockExclusiveReadLockStrategy();
118            } else if ("rename".equals(readLock)) {
119                strategy = new FileRenameExclusiveReadLockStrategy();
120            } else if ("changed".equals(readLock)) {
121                FileChangedExclusiveReadLockStrategy readLockStrategy = new FileChangedExclusiveReadLockStrategy();
122                Long minLength = (Long) params.get("readLockMinLength");
123                if (minLength != null) {
124                    readLockStrategy.setMinLength(minLength);
125                }
126                Long minAge = (Long) params.get("readLockMinAge");
127                if (null != minAge) {
128                    readLockStrategy.setMinAge(minAge);
129                }
130                strategy = readLockStrategy;
131            } else if ("idempotent".equals(readLock)) {
132                FileIdempotentRepositoryReadLockStrategy readLockStrategy = new FileIdempotentRepositoryReadLockStrategy();
133                Boolean readLockRemoveOnRollback = (Boolean) params.get("readLockRemoveOnRollback");
134                if (readLockRemoveOnRollback != null) {
135                    readLockStrategy.setRemoveOnRollback(readLockRemoveOnRollback);
136                }
137                Boolean readLockRemoveOnCommit = (Boolean) params.get("readLockRemoveOnCommit");
138                if (readLockRemoveOnCommit != null) {
139                    readLockStrategy.setRemoveOnCommit(readLockRemoveOnCommit);
140                }
141                IdempotentRepository repo = (IdempotentRepository) params.get("readLockIdempotentRepository");
142                if (repo != null) {
143                    readLockStrategy.setIdempotentRepository(repo);
144                }
145                strategy = readLockStrategy;
146            } else if ("idempotent-changed".equals(readLock)) {
147                FileIdempotentChangedRepositoryReadLockStrategy readLockStrategy = new FileIdempotentChangedRepositoryReadLockStrategy();
148                Boolean readLockRemoveOnRollback = (Boolean) params.get("readLockRemoveOnRollback");
149                if (readLockRemoveOnRollback != null) {
150                    readLockStrategy.setRemoveOnRollback(readLockRemoveOnRollback);
151                }
152                Boolean readLockRemoveOnCommit = (Boolean) params.get("readLockRemoveOnCommit");
153                if (readLockRemoveOnCommit != null) {
154                    readLockStrategy.setRemoveOnCommit(readLockRemoveOnCommit);
155                }
156                IdempotentRepository repo = (IdempotentRepository) params.get("readLockIdempotentRepository");
157                if (repo != null) {
158                    readLockStrategy.setIdempotentRepository(repo);
159                }
160                Long minLength = (Long) params.get("readLockMinLength");
161                if (minLength != null) {
162                    readLockStrategy.setMinLength(minLength);
163                }
164                Long minAge = (Long) params.get("readLockMinAge");
165                if (null != minAge) {
166                    readLockStrategy.setMinAge(minAge);
167                }
168                strategy = readLockStrategy;
169            } else if ("idempotent-rename".equals(readLock)) {
170                FileIdempotentRenameRepositoryReadLockStrategy readLockStrategy = new FileIdempotentRenameRepositoryReadLockStrategy();
171                Boolean readLockRemoveOnRollback = (Boolean) params.get("readLockRemoveOnRollback");
172                if (readLockRemoveOnRollback != null) {
173                    readLockStrategy.setRemoveOnRollback(readLockRemoveOnRollback);
174                }
175                Boolean readLockRemoveOnCommit = (Boolean) params.get("readLockRemoveOnCommit");
176                if (readLockRemoveOnCommit != null) {
177                    readLockStrategy.setRemoveOnCommit(readLockRemoveOnCommit);
178                }
179                IdempotentRepository repo = (IdempotentRepository) params.get("readLockIdempotentRepository");
180                if (repo != null) {
181                    readLockStrategy.setIdempotentRepository(repo);
182                }
183                strategy = readLockStrategy;
184            }
185
186            if (strategy != null) {
187                Long timeout = (Long) params.get("readLockTimeout");
188                if (timeout != null) {
189                    strategy.setTimeout(timeout);
190                }
191                Long checkInterval = (Long) params.get("readLockCheckInterval");
192                if (checkInterval != null) {
193                    strategy.setCheckInterval(checkInterval);
194                }
195                LoggingLevel readLockLoggingLevel = (LoggingLevel) params.get("readLockLoggingLevel");
196                if (readLockLoggingLevel != null) {
197                    strategy.setReadLockLoggingLevel(readLockLoggingLevel);
198                }
199                Boolean readLockMarkerFile = (Boolean) params.get("readLockMarkerFile");
200                if (readLockMarkerFile != null) {
201                    strategy.setMarkerFiler(readLockMarkerFile);
202                }
203                Boolean readLockDeleteOrphanLockFiles = (Boolean) params.get("readLockDeleteOrphanLockFiles");
204                if (readLockDeleteOrphanLockFiles != null) {
205                    strategy.setDeleteOrphanLockFiles(readLockDeleteOrphanLockFiles);
206                }
207            }
208        }
209
210        return strategy;
211    }
212}