View Javadoc

1   /*
2   	Copyright (c) 2009 Olivier Chafik, All Rights Reserved
3   	
4   	This file is part of JNAerator (http://jnaerator.googlecode.com/).
5   	
6   	JNAerator is free software: you can redistribute it and/or modify
7   	it under the terms of the GNU General Public License as published by
8   	the Free Software Foundation, either version 3 of the License, or
9   	(at your option) any later version.
10  	
11  	JNAerator is distributed in the hope that it will be useful,
12  	but WITHOUT ANY WARRANTY; without even the implied warranty of
13  	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  	GNU General Public License for more details.
15  	
16  	You should have received a copy of the GNU General Public License
17  	along with JNAerator.  If not, see <http://www.gnu.org/licenses/>.
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  		/*if (config.outputFile == null)
94  			config.outputFile = name + ".dll";*/
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 }