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        @Override
077        public File getFile() {
078            return file;
079        }
080
081        @Override
082        public boolean hasPattern() {
083            return false;
084        }
085
086        @Override
087        public void fillPatternVariables(Map<String, Object> vars) {
088            // do nothing
089        }
090    }
091
092    public static class PatternFileRef extends FileRef {
093        protected File file;
094
095        protected String key;
096
097        protected String value;
098
099        public PatternFileRef(String path) {
100            this(new File(path));
101        }
102
103        public PatternFileRef(File file) {
104            File dir = file.getParentFile();
105            File[] files = dir.listFiles();
106            if (files != null) {
107                FileMatcher fm = FileMatcher.getMatcher(file);
108                for (File f : files) {
109                    if (fm.match(f.getName())) {
110                        key = fm.getKey();
111                        value = fm.getValue();
112                        this.file = f;
113                        break;
114                    }
115                }
116            }
117        }
118
119        @Override
120        public File getFile() {
121            return file;
122        }
123
124        public String getValue() {
125            return value;
126        }
127
128        public String getKey() {
129            return key;
130        }
131
132        @Override
133        public boolean hasPattern() {
134            return key != null;
135        }
136
137        @Override
138        public void fillPatternVariables(Map<String, Object> vars) {
139            if (key != null) {
140                vars.put(key, value);
141            }
142        }
143    }
144
145}