CLI: Add method which writes build target information in .cproject 67/12067/1
authorhyunsik.noh <hyunsik.noh@samsung.com>
Tue, 12 Nov 2013 09:40:09 +0000 (18:40 +0900)
committerhyunsik.noh <hyunsik.noh@samsung.com>
Tue, 12 Nov 2013 09:40:09 +0000 (18:40 +0900)
The added method changes build target information in .cproject. Because the headless build dose not
save the current build target information automatically.

Change-Id: Id3d00f849eafa4bd5f599b2fe1a8e57f6baa2485
Signed-off-by: hyunsik.noh <hyunsik.noh@samsung.com>
org.tizen.ncli.ide/src/org/tizen/ncli/ide/subcommands/BuildNativeCLICommand.java

index a0cf248..72bbf91 100644 (file)
@@ -1,6 +1,16 @@
 package org.tizen.ncli.ide.subcommands;
 
 import java.io.File;
+import java.util.List;
+
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.TransformerFactoryConfigurationError;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
 
 import org.tizen.common.core.application.InstallPathConfig;
 import org.tizen.common.util.HostUtil;
@@ -8,6 +18,10 @@ import org.tizen.common.util.StringUtil;
 import org.tizen.nativecommon.build.CommonConfigurationManager;
 import org.tizen.nativecommon.build.SmartBuildInterface;
 import org.tizen.nativecommon.build.exception.SBIException;
+import org.w3c.dom.Document;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
 
 public class BuildNativeCLICommand extends AbstractSubCommand<BuildNative> {
     private String platformId;
@@ -29,7 +43,7 @@ public class BuildNativeCLICommand extends AbstractSubCommand<BuildNative> {
             + "-Ea CLI=true "
             + "-T org.tizen.nativecpp.tool.sbi.gnu.cpp.compiler sbi.gnu.cpp.compiler.option=%s";
 
-    private void makeBuildCommand() {
+    private void setArgs() {
         sbi = SmartBuildInterface.getInstance();
 
         if (workingDir == null) {
@@ -47,10 +61,40 @@ public class BuildNativeCLICommand extends AbstractSubCommand<BuildNative> {
         }
         dataPath = importPath + "/../" + "headless";
 
-        log.debug("Import Path: " + importPath);
-        log.debug("Ide Path: " + idePath);
-        log.debug("Build Path: " + buildPath);
-        log.debug("Data Path: " + dataPath);
+        log.info("Import Path: " + importPath);
+        log.info("Ide Path: " + idePath);
+        log.info("Build Path: " + buildPath);
+        log.info("Data Path: " + dataPath);
+    }
+
+    private boolean isValidateArgs() {
+        if (!isVaildImportPathAndConfiguration(importPath, buildConfiguration)) {
+            return false;
+        }
+        try {
+            // The build target must be created if there is no input for platform id and toolchain id
+            if (isValidPair(platformId, toolchainId)) {
+                createTarget(buildTarget, platformId, toolchainId);
+            } else {
+                // target is exist? no -> exit
+                boolean isExist = false;
+                List<String> targets = sbi.getTargetList();
+                for (String target : targets) {
+                    if (buildTarget.equals(target)) {
+                        isExist = true;
+                        break;
+                    }
+                }
+                if (!isExist) {
+                    System.out.println("[ERROR] There is no build target named " + buildTarget);
+                    return false;
+                }
+            }
+        } catch (SBIException e) {
+            System.out.println("[ERROR] Create the build target: " + e.getMessage());
+            return false;
+        }
+        return true;
     }
 
     /*
@@ -60,23 +104,46 @@ public class BuildNativeCLICommand extends AbstractSubCommand<BuildNative> {
      */
     @Override
     protected BuildNative call() {
-        makeBuildCommand();
-        try {
-            if (isValidPair(platformId, toolchainId)) {
-                createTarget(buildTarget, platformId, toolchainId);
-            }
-        } catch (SBIException e) {
-            System.out.println("[Fail] Create the build target: " + e.getMessage());
+        setArgs();
+        if (!isValidateArgs()) {
+            System.out.println("[ERROR] Build Failed - invalid arguments");
             return null;
         }
-
         String command = String.format(HEADLESS_CMD, idePath, importPath, buildPath, dataPath, buildTarget);
-        System.out.println(command);
         System.out.println(HostUtil.returnExecute(command));
-
+        //TODO: how to know building project works well?
+        setBuildTargetInfo(importPath, buildConfiguration);
         return null;
     }
 
+    private boolean isVaildImportPathAndConfiguration(String path, String configuration) {
+        String cprojectPath = path + "/" + ".cproject";
+        File cprojectFile = new File(cprojectPath);
+
+        if (!cprojectFile.exists()) {
+            System.out.println("[ERROR] There is no .cproject file in " + path + ".");
+            return false;
+        }
+        String configurations = "";
+        try {
+            Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(cprojectFile);
+            NodeList list = doc.getElementsByTagName("configuration");
+            for (int i = 0; i < list.getLength(); i++) {
+                NamedNodeMap attributeMap = list.item(i).getAttributes();
+                String value = attributeMap.getNamedItem("name").getNodeValue();
+                configurations = configurations + " " + value;
+                if (configuration.equals(value)) {
+                    return true;
+                }
+            }
+        } catch (Exception e) {
+            System.out.println("[ERROR] Validate the build configuration: " + e.getMessage());
+        }
+        System.out.println("[ERROR] The " + configuration + " is a wrong build configuration.");
+        System.out.println("[ERROR] You can use one of [" + configurations.trim() + "]");
+        return false;
+    }
+
     private boolean isValidPair(String rootstrapId, String toolchainId) throws SBIException {
         if (rootstrapId == null || toolchainId == null) {
             return false;
@@ -89,14 +156,169 @@ public class BuildNativeCLICommand extends AbstractSubCommand<BuildNative> {
     }
 
     private boolean isSameArch(String rootstrapId, String toolchainId) throws SBIException {
+        boolean result = false;
         String platformArch = getPlatformArch(rootstrapId);
         String toolchainArch = getToolchainArch(toolchainId);
-        return CommonConfigurationManager.isSameArchType(platformArch, toolchainArch);
+        result = CommonConfigurationManager.isSameArchType(platformArch, toolchainArch);
+        if (!result) {
+            System.out.println("[ERROR] " + platformArch + " and " + toolchainArch + " are not the same architecutre type");
+        }
+        return result;
     }
 
     private boolean supportToolchainType(String rootstrapId, String toolchainId) throws SBIException {
+        boolean result = false;
         String toolchainType = sbi.getToolchainTypeFromToolchainID(toolchainId);
-        return sbi.doesRootstrapSupportToolchainType(rootstrapId, toolchainType);
+        result = sbi.doesRootstrapSupportToolchainType(rootstrapId, toolchainType);
+        if (!result) {
+            System.out.println("[ERROR] " + rootstrapId + " and " + toolchainId + " has different support type");
+        }
+        return result;
+    }
+
+    private boolean setBuildTargetInfo(String path, String configuration) {
+        boolean [] setResult = {false, false};
+        String cprojectPath = path + "/" + ".cproject";
+        File cprojectFile = new File(cprojectPath);
+
+        if (!cprojectFile.exists()) {
+            System.out.println("[ERROR] There is no .cproject file in " + path);
+            return false;
+        }
+        Document doc = null;
+        try {
+            doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(cprojectFile);
+            NodeList list = doc.getElementsByTagName("configuration");
+            for (int i = 0; i < list.getLength(); i++) {
+                Node node = list.item(i);
+                NamedNodeMap attributeMap = node.getAttributes();
+                String value = attributeMap.getNamedItem("name").getNodeValue();
+                
+                String[][] criteria = {
+                        {"C++ Compiler", "sbi.gnu.cpp.compiler.option"},
+                        {"C Compiler", "sbi.gnu.c.compiler.option"}
+                        };
+                int index = 0;
+                Node toolNode = null;
+                if(configuration.equals(value)) {
+                    while(index < 2) {
+                        if(toolNode == null) {
+                            toolNode = findToolNode(node, criteria[index][0]);
+                        }
+                        if(node != null) {
+                            setResult[index] = setTargetInfo(toolNode, "option", criteria[index][1], buildTarget);
+                            if(setResult[index] == false) {
+                                System.out.println("[ERROR] Could not set the build target info: " +criteria[index][1]);
+                                return false;
+                            }
+                            node = toolNode;
+                            index++;
+                        }
+                        while(true) {
+                            toolNode = toolNode.getNextSibling();
+                            if(toolNode.hasChildNodes()) {
+                                break;
+                            }
+                        }
+                    }
+                }
+            }
+        } catch (Exception e) {
+            System.out.println("[ERROR] Could not set the build target info: " + e.getMessage());
+            return false;
+        }
+        boolean result = setResult[0]&&setResult[1];
+        if(result) {
+            try {
+                Transformer transformer = TransformerFactory.newInstance().newTransformer();
+                DOMSource source = new DOMSource(doc);
+                StreamResult streamResult = new StreamResult(cprojectFile);
+                transformer.transform(source, streamResult); 
+            } catch (TransformerConfigurationException e) {
+                System.out.println("[ERROR] Could not transform to .cproject file");
+                log.info("[ERROR] TransformerConfigurationException: " + e.getMessage());
+            } catch (TransformerFactoryConfigurationError e) {
+                System.out.println("[ERROR] Could not transform to .cproject file");
+                log.info("[ERROR] TransformerFactoryConfigurationError: " + e.getMessage());
+            } catch (TransformerException e) {
+                System.out.println("[ERROR] Could not transform to .cproject file");
+                log.info("[ERROR] TransformerException: " + e.getMessage());
+            }
+        }
+        return result;
+    }
+    
+    private Node findToolNode(Node node, String name) {
+        Node toolNode = null;
+        NodeList children = null;
+        if(node.hasChildNodes()) {
+            children = node.getChildNodes();
+        } else {
+            return null;
+        }
+        NamedNodeMap attributeMap = null;
+        String value = null;
+        
+        int i = 0;
+        while( i < children.getLength()) {
+            node = children.item(i);
+            if ("tool".equals(node.getNodeName())) {
+                attributeMap = node.getAttributes();
+                value = attributeMap.getNamedItem("name").getNodeValue();
+                if(name.equals(value)) {
+                    return node;
+                }
+            } else {
+                toolNode = findToolNode(node, name);
+            }
+            if(toolNode == null) {
+                i++;
+            } else {
+                break;
+            }
+        }
+        return toolNode;
+    }
+        
+    private boolean setTargetInfo(Node node, String tag, String superClass, String target) {
+        boolean found = false;
+        NodeList children = null;
+        if(node.hasChildNodes()) {
+            children = node.getChildNodes();
+        } else {
+            return false;
+        }
+        NamedNodeMap attributeMap = null;
+        String value = null;
+        
+        int i = 0;
+        while( i < children.getLength()) {
+            node = children.item(i);
+            if ("option".equals(node.getNodeName())) {
+                attributeMap = node.getAttributes();
+                value = attributeMap.getNamedItem("superClass").getNodeValue();
+                if(superClass.equals(value)) {
+                    NodeList list = node.getChildNodes();
+                    for(int j = 0; j < list.getLength(); j++) {
+                        node = list.item(j);
+                        if("listOptionValue".equals(node.getNodeName())) {
+                            attributeMap = node.getAttributes();
+                            node.getAttributes().getNamedItem("value").setNodeValue(buildTarget);
+                            break;
+                        }
+                    }
+                    return true;
+                }
+            } else {
+                found = setTargetInfo(node, tag, superClass, target);
+            }
+            if(found == false) {
+                i++;
+            } else {
+                break;
+            }
+        }
+        return found;
     }
 
     private String getPlatformArch(String rootstrapId) throws SBIException {