001    /*
002      GRANITE DATA SERVICES
003      Copyright (C) 2011 GRANITE DATA SERVICES S.A.S.
004    
005      This file is part of Granite Data Services.
006    
007      Granite Data Services is free software; you can redistribute it and/or modify
008      it under the terms of the GNU Library General Public License as published by
009      the Free Software Foundation; either version 2 of the License, or (at your
010      option) any later version.
011    
012      Granite Data Services is distributed in the hope that it will be useful, but
013      WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
014      FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License
015      for more details.
016    
017      You should have received a copy of the GNU Library General Public License
018      along with this library; if not, see <http://www.gnu.org/licenses/>.
019    */
020    
021    package org.granite.builder.properties;
022    
023    import java.util.ArrayList;
024    import java.util.HashMap;
025    import java.util.IdentityHashMap;
026    import java.util.List;
027    import java.util.Map;
028    import java.util.regex.Pattern;
029    
030    import org.granite.builder.util.StringUtil;
031    
032    import com.thoughtworks.xstream.annotations.XStreamAlias;
033    import com.thoughtworks.xstream.annotations.XStreamAsAttribute;
034    
035    /**
036     * @author Franck WOLFF
037     */
038    @XStreamAlias(value="source")
039    public class Gas3Source implements Validable, Comparable<Gas3Source> {
040    
041            @XStreamAsAttribute
042            private String path;
043            
044            @XStreamAsAttribute
045            private String includes;
046            
047            @XStreamAsAttribute
048            private String excludes;
049            
050            @XStreamAsAttribute
051            private String output;
052    
053            private transient Map<Pattern, Map<String, String>> includePatterns;
054            private transient List<Pattern> excludePatterns;
055            
056            public Gas3Source(String path, String includes, String excludes, String output) {
057                    this.path = path;
058                    setIncludes(includes);
059                    setExcludes(excludes);
060                    this.output = output;
061            }
062            
063            public boolean match(String path, String file) {
064                    if (!this.path.equals(path))
065                            return false;
066                    
067                    compilePatterns();
068                    
069                    for (Pattern pattern : excludePatterns) {
070                            if (pattern.matcher(file).matches())
071                                    return false;
072                    }
073                    
074                    for (Pattern pattern : includePatterns.keySet()) {
075                            if (pattern.matcher(file).matches())
076                                    return true;
077                    }
078    
079                    return includePatterns.isEmpty();
080            }
081            
082            public Map<String, String> getAttributes(String path, String file) {
083                    if (!this.path.equals(path))
084                            return null;
085                    
086                    compilePatterns();
087                    
088                    for (Pattern pattern : excludePatterns) {
089                            if (pattern.matcher(file).matches())
090                                    return null;
091                    }
092                    
093                    for (Pattern pattern : includePatterns.keySet()) {
094                            if (pattern.matcher(file).matches())
095                                    return includePatterns.get(pattern);
096                    }
097    
098                    return (includePatterns.isEmpty() ? new HashMap<String, String>() : null);
099            }
100    
101            public String getPath() {
102                    return path;
103            }
104            public void setPath(String path) {
105                    this.path = path;
106            }
107    
108            public String getIncludes() {
109                    return includes;
110            }
111            public void setIncludes(String includes) {
112                    this.includes = includes;
113                    this.includePatterns = null;
114            }
115    
116            public String getExcludes() {
117                    return excludes;
118            }
119            public void setExcludes(String excludes) {
120                    this.excludes = excludes;
121                    this.excludePatterns = null;
122            }
123    
124            public String getOutput() {
125                    return output;
126            }
127            public void setOutput(String output) {
128                    this.output = output;
129            }
130    
131            public String getOutputDir() {
132                    if (output == null)
133                            return "";
134                    String[] dirs = StringUtil.split(output, ';');
135                    if (dirs.length > 0)
136                            return dirs[0];
137                    return "";
138            }
139    
140            public String getBaseOutputDir() {
141                    return getBaseOutputDir(false);
142            }
143    
144            public String getBaseOutputDir(boolean fallback) {
145                    if (output == null)
146                            return "";
147                    String[] dirs = StringUtil.split(output, ';');
148                    if (dirs.length > 1 && dirs[1].length() > 0)
149                            return dirs[1];
150                    return (fallback && dirs.length > 0 ? dirs[0] : "");
151            }
152            
153            @Override
154            public void validate(ValidationResults results) {
155                    if (path == null || output == null)
156                            results.getErrors().add("source: path and output cannot be null");
157            }
158    
159            @Override
160            public boolean equals(Object obj) {
161                    if (obj == this)
162                            return true;
163                    if (!(obj instanceof Gas3Source))
164                            return false;
165                    Gas3Source g3s = (Gas3Source)obj;
166                    return (path == null ? g3s.path == null : path.equals(g3s.path));
167            }
168    
169            @Override
170            public int hashCode() {
171                    return path != null ? path.hashCode() : 0;
172            }
173    
174            @Override
175            public int compareTo(Gas3Source o) {
176                    if (path == null)
177                            return -1;
178                    if (o.path == null)
179                            return 1;
180                    return path.compareTo(o.path);
181            }
182            
183            private void compilePatterns() {
184                    if (includePatterns == null) {
185                            if (includePatterns == null)
186                                    includePatterns = new IdentityHashMap<Pattern, Map<String, String>>();
187                            else
188                                    includePatterns.clear();
189                            if (includes != null) {
190                                    for (String include : StringUtil.split(includes, ';')) {
191                                            Map<String, String> attributes = new HashMap<String, String>();
192                                            int index = include.indexOf('[');
193                                            if (index != -1) {
194                                                    try {
195                                                            for (String attribute : StringUtil.split(include.substring(index + 1, include.length() - 1), ',')) {
196                                                                    String[] keyValue = attribute.split(Pattern.quote("="), 2);
197                                                                    attributes.put(keyValue[0], keyValue[1]);
198                                                            }
199                                                    }
200                                                    catch (Exception e) {
201                                                            System.err.println("Illegal include pattern '" + include + "': " + e);
202                                                    }
203                                                    include = include.substring(0, index);
204                                            }
205                                            include = include.trim();
206                                            if (include.length() > 0)
207                                                    includePatterns.put(Pattern.compile(StringUtil.regexifyPathPattern(include)), attributes);
208                                    }
209                            }
210                    }
211            
212                    if (excludePatterns == null) {
213                            if (excludePatterns == null)
214                                    excludePatterns = new ArrayList<Pattern>();
215                            else
216                                    excludePatterns.clear();
217                            if (excludes != null) {
218                                    for (String exclude : StringUtil.split(excludes, ';')) {
219                                            if (exclude.length() > 0)
220                                                    excludePatterns.add(Pattern.compile(StringUtil.regexifyPathPattern(exclude)));
221                                    }
222                            }
223                    }
224            }
225    }