/* 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); } }