001/*
002 * (C) Copyright 2006-2011 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     bstefanescu, jcarsique
018 */
019package org.nuxeo.common.utils;
020
021import java.io.File;
022import java.util.Map;
023import java.util.regex.Matcher;
024import java.util.regex.Pattern;
025
026/**
027 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a>
028 */
029public class FileMatcher {
030
031    private static final Pattern VAR = Pattern.compile("(.*)?\\{(.+):(.+)\\}(.*)?");
032
033    public static FileMatcher getMatcher(String path) {
034        Matcher m = VAR.matcher(path);
035        if (m.matches()) {
036            String prefix = m.group(1);
037            String key = m.group(2).trim();
038            String value = m.group(3).trim();
039            String suffix = m.group(4);
040            Pattern pattern = null;
041            if (prefix.length() == 0) {
042                if (suffix.length() == 0) {
043                    pattern = Pattern.compile("(" + value + ")");
044                } else {
045                    pattern = Pattern.compile("(" + value + ")" + suffix);
046                }
047            } else if (suffix.length() == 0) {
048                pattern = Pattern.compile(prefix + "(" + value + ")");
049            } else {
050                pattern = Pattern.compile(prefix + "(" + value + ")" + suffix);
051            }
052            return new FileMatcher(pattern, key);
053        }
054        return new FileMatcher(null, path);
055    }
056
057    public static FileMatcher getMatcher(File file) {
058        return getMatcher(file.getName());
059    }
060
061    /**
062     * Look for a matching file for the given path.
063     *
064     * @param path Searched file path, optionally including the pattern.
065     * @param map The pattern variable will be put in the given map if any. Since 5.5, map can be null.
066     * @return File found. Null if none.
067     */
068    public static File getMatchingFile(String path, Map<String, Object> map) {
069        File file = new File(path);
070        FileMatcher matcher = getMatcher(path);
071        if (matcher.getPattern() == null) {
072            return file;
073        }
074        // a pattern -> find the first file that match that pattern
075        File dir = file.getParentFile();
076        File[] list = dir.listFiles();
077        if (list != null) {
078            for (File f : list) {
079                if (matcher.match(f.getName())) {
080                    if (map != null) {
081                        map.put(matcher.getKey(), matcher.getValue());
082                    }
083                    return f;
084                }
085            }
086        }
087        return null;
088    }
089
090    protected final Pattern pattern;
091
092    protected final String key;
093
094    protected String value;
095
096    public FileMatcher(Pattern pattern, String key) {
097        this.pattern = pattern;
098        this.key = key;
099    }
100
101    public String getKey() {
102        return pattern != null ? key : null;
103    }
104
105    public Pattern getPattern() {
106        return pattern;
107    }
108
109    public String getValue() {
110        return value;
111    }
112
113    public boolean match(String name) {
114        value = null;
115        if (pattern != null) {
116            Matcher m = pattern.matcher(name);
117            if (m.matches()) {
118                value = m.group(1);
119                return true;
120            }
121            return false;
122        } else if (name.equals(key)) {
123            return true;
124        }
125        return false;
126    }
127
128}