/*
Copyright (c) 2009-2013 Olivier Chafik, All Rights Reserved
This file is part of JNAerator (http://jnaerator.googlecode.com/).
JNAerator is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
JNAerator is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with JNAerator. If not, see <http://www.gnu.org/licenses/>.
*/
package com.ochafik.admin.visualstudio;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeSet;
import static com.ochafik.admin.visualstudio.VisualStudioUtils.*;
import javax.xml.xpath.XPathExpressionException;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import com.ochafik.xml.XMLUtils;
import com.ochafik.xml.XPathUtils;
public class Project implements Comparable<Project> {
public final Solution solution;
public File projectFile;
public String name, id;
public List<String> depsIds = new ArrayList<String>();
public Map<String, String> activeConfigurationNameBySolutionConfigurationName = new LinkedHashMap<String, String>();
public Map<String, Configuration> configurations = new LinkedHashMap<String, Configuration>();
public Map<File, FileConfiguration> fileConfigurations = new LinkedHashMap<File, FileConfiguration>();
public List<File> files = new ArrayList<File>();
public Project(Solution solution, File projectFile, String name, String id) {
this.solution = solution;
this.projectFile = projectFile;
this.name = name;
this.id = id;
}
public int compareTo(Project o) {
return name.compareTo(o.name);
}
String resolve(String s, Configuration configuration) {
String res = resolveVariables(s, solution, this, configuration);
return res == null || res.length() == 0 ? null : res;
}
public String resolveStringByXPath(String xPathString, Object source, Configuration configuration) throws XPathExpressionException {
return resolve(XPathUtils.findStringByXPath(xPathString, source), configuration);
}
@SuppressWarnings("unchecked")
public List<String> resolveListByXPath(String xPathString, Object source, String separatorPattern, Configuration configuration) throws XPathExpressionException {
String s = resolve(XPathUtils.findStringByXPath(xPathString, source), configuration);
return s == null ? Collections.EMPTY_LIST : Arrays.asList(s.split(separatorPattern));
}
public TreeSet<String> resolveSetByXPath(String xPathString, Object source, String separatorPattern, Configuration configuration) throws XPathExpressionException {
return new TreeSet<String>(resolveListByXPath(xPathString, source, separatorPattern, configuration));
}
Configuration parseConfiguration(Node configNode) throws XPathExpressionException {
Configuration config = new Configuration();
config.name = resolve(XPathUtils.findStringByXPath("@Name", configNode), config);
if (config.name == null) {
return null;
}
config.outputDirectory = resolve(XPathUtils.findStringByXPath("@OutputDirectory", configNode), config);
Node compilerTool = XPathUtils.findNodeByXPath("Tool[@Name='VCCLCompilerTool']", configNode);
if (compilerTool != null) {
config.includes = resolveListByXPath("@AdditionalIncludeDirectories", compilerTool, ";", config);
config.preprocessorDefinitions = resolveSetByXPath("@PreprocessorDefinitions", compilerTool, ";", config);
}
config.outputFile = resolve(XPathUtils.findStringByXPath("Tool[@Name='VCLinkerTool']/@OutputFile", configNode), config);
/*if (config.outputFile == null)
config.outputFile = name + ".dll";*/
return config;
}
public void parse(FileFilter fileFilter, boolean parseFileConfigurations, Solution solution) throws Exception {
if (!projectFile.exists() || !projectFile.isFile()) {
throw new IOException("Cannot find project file " + projectFile);
}
Document document = XMLUtils.readXML(projectFile);
File projectPath = projectFile.getParentFile();
for (Node configurationNode : XPathUtils.findNodesIterableByXPath("VisualStudioProject/Configurations/Configuration", document)) {
Configuration config = parseConfiguration(configurationNode);
if (config != null) {
configurations.put(config.name, config);
}
}
for (Node fileNode : XPathUtils.findNodesIterableByXPath("//Files//File", document)) {
String relativePath = resolveStringByXPath("@RelativePath", fileNode, null);
if (relativePath == null) {
continue;
}
File file = relFile(projectPath, relativePath);
if (fileFilter != null && !fileFilter.accept(file)) {
continue;
}
files.add(file);
if (parseFileConfigurations) {
FileConfiguration fileConfiguration = new FileConfiguration();
fileConfiguration.file = file;
fileConfigurations.put(file, fileConfiguration);
for (Node fileConfigurationNode : XPathUtils.findNodesIterableByXPath("FileConfiguration", fileNode)) {
Configuration config = parseConfiguration(fileConfigurationNode);
if (config != null) {
fileConfiguration.configurations.put(config.name, config);
}
}
}
}
}
static File relFile(File base, String relPath) {
relPath = relPath.replace('\\', File.separatorChar).replace('/', File.separatorChar);
return new File(base, relPath);
}
}