1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package com.ochafik.admin.visualstudio;
20
21 import java.io.File;
22 import java.io.FileFilter;
23 import java.io.IOException;
24 import java.util.ArrayList;
25 import java.util.Arrays;
26 import java.util.Collections;
27 import java.util.HashMap;
28 import java.util.List;
29 import java.util.Map;
30 import java.util.TreeSet;
31 import static com.ochafik.admin.visualstudio.VisualStudioUtils.*;
32
33 import javax.xml.xpath.XPathExpressionException;
34
35 import org.w3c.dom.Document;
36 import org.w3c.dom.Node;
37
38 import com.ochafik.xml.XMLUtils;
39 import com.ochafik.xml.XPathUtils;
40
41 public class Project implements Comparable<Project> {
42 public final Solution solution;
43 public File projectFile;
44 public String name, id;
45 public List<String> depsIds = new ArrayList<String>();
46 public Map<String, String> activeConfigurationNameBySolutionConfigurationName = new HashMap<String, String>();
47
48 public Map<String, Configuration> configurations = new HashMap<String, Configuration>();
49 public Map<File, FileConfiguration> fileConfigurations = new HashMap<File, FileConfiguration>();
50 public List<File> files = new ArrayList<File>();
51
52 public Project(Solution solution, File projectFile, String name, String id) {
53 this.solution = solution;
54 this.projectFile = projectFile;
55 this.name = name;
56 this.id = id;
57 }
58 public int compareTo(Project o) {
59 return name.compareTo(o.name);
60 }
61
62 String resolve(String s, Configuration configuration) {
63 String res = resolveVariables(s, solution, this, configuration);
64 return res == null || res.length() == 0 ? null : res;
65 }
66
67 public String resolveStringByXPath(String xPathString, Object source, Configuration configuration) throws XPathExpressionException {
68 return resolve(XPathUtils.findStringByXPath(xPathString, source), configuration);
69 }
70 @SuppressWarnings("unchecked")
71 public List<String> resolveListByXPath(String xPathString, Object source, String separatorPattern, Configuration configuration) throws XPathExpressionException {
72 String s = resolve(XPathUtils.findStringByXPath(xPathString, source), configuration);
73 return s == null ? Collections.EMPTY_LIST : Arrays.asList(s.split(separatorPattern));
74 }
75 public TreeSet<String> resolveSetByXPath(String xPathString, Object source, String separatorPattern, Configuration configuration) throws XPathExpressionException {
76 return new TreeSet<String>(resolveListByXPath(xPathString, source, separatorPattern, configuration));
77 }
78
79 Configuration parseConfiguration(Node configNode) throws XPathExpressionException {
80 Configuration config = new Configuration();
81 config.name = resolve(XPathUtils.findStringByXPath("@Name", configNode), config);
82 if (config.name == null)
83 return null;
84
85 config.outputDirectory = resolve(XPathUtils.findStringByXPath("@OutputDirectory", configNode), config);
86
87 Node compilerTool = XPathUtils.findNodeByXPath("Tool[@Name='VCCLCompilerTool']", configNode);
88 if (compilerTool != null) {
89 config.includes = resolveListByXPath("@AdditionalIncludeDirectories", compilerTool, ";", config);
90 config.preprocessorDefinitions = resolveSetByXPath("@PreprocessorDefinitions", compilerTool, ";", config);
91 }
92 config.outputFile = resolve(XPathUtils.findStringByXPath("Tool[@Name='VCLinkerTool']/@OutputFile", configNode), config);
93
94
95
96 return config;
97 }
98
99 public void parse(FileFilter fileFilter, boolean parseFileConfigurations, Solution solution) throws Exception {
100 if (!projectFile.exists() || !projectFile.isFile())
101 throw new IOException("Cannot find project file " + projectFile);
102
103 Document document = XMLUtils.readXML(projectFile);
104 File projectPath = projectFile.getParentFile();
105
106 for (Node configurationNode : XPathUtils.findNodesIterableByXPath("VisualStudioProject/Configurations/Configuration", document)) {
107 Configuration config = parseConfiguration(configurationNode);
108 if (config != null)
109 configurations.put(config.name, config);
110 }
111 for (Node fileNode : XPathUtils.findNodesIterableByXPath("//Files//File", document)) {
112 String relativePath = resolveStringByXPath("@RelativePath", fileNode, null);
113 if (relativePath == null)
114 continue;
115
116 File file = relFile(projectPath, relativePath);
117 if (fileFilter != null && !fileFilter.accept(file))
118 continue;
119
120 files.add(file);
121
122 if (parseFileConfigurations) {
123 FileConfiguration fileConfiguration = new FileConfiguration();
124 fileConfiguration.file = file;
125 fileConfigurations.put(file, fileConfiguration);
126 for (Node fileConfigurationNode : XPathUtils.findNodesIterableByXPath("FileConfiguration", fileNode)) {
127 Configuration config = parseConfiguration(fileConfigurationNode);
128 if (config != null)
129 fileConfiguration.configurations.put(config.name, config);
130 }
131 }
132 }
133 }
134
135 static File relFile(File base, String relPath) {
136 relPath = relPath.replace('\\', File.separatorChar).replace('/', File.separatorChar);
137 return new File(base, relPath);
138 }
139 }