001/*
002 * (C) Copyright 2006-2010 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
018 */
019package org.nuxeo.common.utils;
020
021import java.io.File;
022import java.util.Map;
023
024/**
025 * A file reference that can handle file name patterns. A file pattern can use named variable that will be substituted
026 * with the actual value of the file that matched the pattern.
027 * <p>
028 * Example: For a file pattern <code>nuxeo-automation-core-{v:.*}.jar</code> that will match a file named
029 * <code>nuxeo-automation-core-5.3.2.jar</code> the pattern variable will be <code>v=5.3.2</code>.
030 * <p>
031 * Note that only one pattern variable is supported.
032 * 
033 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a>
034 */
035public abstract class FileRef {
036
037    public static FileRef newFileRef(String path) {
038        return newFileRef(new File(path));
039    }
040
041    public static FileRef newFileRef(File file) {
042        if (file.getName().indexOf('{') > -1) {
043            return new PatternFileRef(file);
044        }
045        return new ExactFileRef(file);
046    }
047
048    /**
049     * Gets the file referenced by this object. If the FileRef could not be resolved then null is returned.
050     * 
051     * @return the referred file or null if none was found.
052     */
053    public abstract File getFile();
054
055    /**
056     * Whether the referred file has a name pattern.
057     */
058    public abstract boolean hasPattern();
059
060    /**
061     * Fill the given map with pattern variables.
062     */
063    public abstract void fillPatternVariables(Map<String, Object> vars);
064
065    public static class ExactFileRef extends FileRef {
066        protected final File file;
067
068        public ExactFileRef(String path) {
069            this(new File(path));
070        }
071
072        public ExactFileRef(File file) {
073            this.file = file;
074        }
075
076        public File getFile() {
077            return file;
078        }
079
080        public boolean hasPattern() {
081            return false;
082        }
083
084        public void fillPatternVariables(Map<String, Object> vars) {
085            // do nothing
086        }
087    }
088
089    public static class PatternFileRef extends FileRef {
090        protected File file;
091
092        protected String key;
093
094        protected String value;
095
096        public PatternFileRef(String path) {
097            this(new File(path));
098        }
099
100        public PatternFileRef(File file) {
101            File dir = file.getParentFile();
102            File[] files = dir.listFiles();
103            if (files != null) {
104                FileMatcher fm = FileMatcher.getMatcher(file);
105                for (File f : files) {
106                    if (fm.match(f.getName())) {
107                        key = fm.getKey();
108                        value = fm.getValue();
109                        this.file = f;
110                        break;
111                    }
112                }
113            }
114        }
115
116        public File getFile() {
117            return file;
118        }
119
120        public String getValue() {
121            return value;
122        }
123
124        public String getKey() {
125            return key;
126        }
127
128        public boolean hasPattern() {
129            return key != null;
130        }
131
132        public void fillPatternVariables(Map<String, Object> vars) {
133            if (key != null) {
134                vars.put(key, value);
135            }
136        }
137    }
138
139}