buildframework/helium/sf/java/legacy/src/com/nokia/ant/BuildStatusDef.java
changeset 648 d5a8d436d33b
parent 647 53d1ab72f5bc
parent 645 b8d81fa19e7d
child 649 02d78c9f018e
equal deleted inserted replaced
647:53d1ab72f5bc 648:d5a8d436d33b
     1 /*
       
     2  * Copyright (c) 2007-2008 Nokia Corporation and/or its subsidiary(-ies).
       
     3  * All rights reserved.
       
     4  * This component and the accompanying materials are made available
       
     5  * under the terms of the License "Eclipse Public License v1.0"
       
     6  * which accompanies this distribution, and is available
       
     7  * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8  *
       
     9  * Initial Contributors:
       
    10  * Nokia Corporation - initial contribution.
       
    11  *
       
    12  * Contributors:
       
    13  *
       
    14  * Description: 
       
    15  *
       
    16  */
       
    17 
       
    18 package com.nokia.ant;
       
    19 
       
    20 import java.io.File;
       
    21 import java.io.IOException;
       
    22 import java.util.ArrayList;
       
    23 import java.util.Enumeration;
       
    24 import java.util.HashSet;
       
    25 import java.util.Hashtable;
       
    26 import java.util.Iterator;
       
    27 import java.util.List;
       
    28 import java.util.Vector;
       
    29 
       
    30 import org.apache.tools.ant.BuildException;
       
    31 import org.apache.tools.ant.Project;
       
    32 import org.apache.tools.ant.Target;
       
    33 import org.apache.tools.ant.types.DataType;
       
    34 import org.dom4j.Comment;
       
    35 import org.dom4j.Document;
       
    36 import org.dom4j.DocumentException;
       
    37 import org.dom4j.Element;
       
    38 import org.dom4j.Node;
       
    39 import org.dom4j.Visitor;
       
    40 import org.dom4j.VisitorSupport;
       
    41 import org.dom4j.io.SAXReader;
       
    42 
       
    43 import com.nokia.helium.ant.data.PropertyCommentMeta;
       
    44 import com.nokia.helium.ant.data.PropertyMeta;
       
    45 import com.nokia.helium.core.ant.PostBuildAction;
       
    46 
       
    47 /**
       
    48  * Class to store the status of the signal of a particular target.
       
    49  */
       
    50 public class BuildStatusDef extends DataType implements PostBuildAction {
       
    51     private static final String DEPRECATED = "deprecated:";
       
    52     private HashSet<String> output = new HashSet<String>();
       
    53 
       
    54     @Override
       
    55     public void executeOnPostBuild(Project project, String[] targetNames) {
       
    56         // Run after targets execute so dynamic target names are resolved
       
    57         for (int i = 0; i < targetNames.length; i++) {
       
    58             String[] array = { targetNames[i] };
       
    59             Target target = findTarget(targetNames[i], getProject(), array);
       
    60             targetCallsHeliumTarget(target, getProject());
       
    61         }
       
    62         checkTargetsProperties(getProject());
       
    63         checkDeprecatedProperties(getProject());
       
    64 
       
    65         if (!output.isEmpty()) {
       
    66             log("*** Configuration report ***", Project.MSG_INFO);
       
    67             for (String outputStr : output) {
       
    68                 log(outputStr, Project.MSG_INFO);
       
    69             }
       
    70         }
       
    71     }
       
    72 
       
    73     /**
       
    74      * @param desiredTarget
       
    75      *            Target name to search
       
    76      * @param project
       
    77      *            Object of the project
       
    78      * @param targetNames
       
    79      *            Array of target names
       
    80      * 
       
    81      */
       
    82     @SuppressWarnings("unchecked")
       
    83     public Target findTarget(String desiredTarget, Project project,
       
    84             String[] targetNames) {
       
    85         Hashtable<String, Target> targets;
       
    86         Vector<Target> sorted;
       
    87 
       
    88         // get all targets of the current project
       
    89         targets = project.getTargets();
       
    90 
       
    91         // sort all targets of the current project
       
    92         sorted = project.topoSort(targetNames[0], targets);
       
    93 
       
    94         // Find the desiredTarget Target object
       
    95         for (Target target : sorted) {
       
    96             if (target.getName().equals(desiredTarget)) {
       
    97                 return target;
       
    98             }
       
    99         }
       
   100         throw new BuildException("Could not find target matching "
       
   101                 + desiredTarget + "\n");
       
   102     }
       
   103 
       
   104     /**
       
   105      * If a target defined outside helium are calling a private Helium target
       
   106      * then print warning
       
   107      * 
       
   108      */
       
   109     @SuppressWarnings("unchecked")
       
   110     public void targetCallsHeliumTarget(Target target, Project project) {
       
   111         String location = target.getLocation().getFileName();
       
   112 
       
   113         try {
       
   114             String heliumpath = new File(project.getProperty("helium.dir"))
       
   115                     .getCanonicalPath();
       
   116             String targetpath = new File(location).getCanonicalPath();
       
   117 
       
   118             if (!targetpath.contains(heliumpath)) {
       
   119                 ArrayList<String> antcallTargets = new ArrayList<String>();
       
   120                 Visitor visitorTarget = new AntTargetVisitor(antcallTargets,
       
   121                         project);
       
   122 
       
   123                 Element element = findTargetElement(target, project);
       
   124                 if (element != null) {
       
   125                     element.accept(visitorTarget);
       
   126                 }
       
   127                 for (String depTargetString : antcallTargets) {
       
   128                     String[] array = { depTargetString };
       
   129                     try {
       
   130                         Target depTarget = findTarget(depTargetString, project,
       
   131                                 array);
       
   132                         targetCallsHeliumTarget(depTarget, project);
       
   133                     } catch (BuildException x) {
       
   134                         // We are Ignoring the errors as no need to fail the
       
   135                         // build.
       
   136                         log(
       
   137                                 "Exception occured while target defined outside helium are calling a private Helium target "
       
   138                                         + x.toString(), Project.MSG_DEBUG);
       
   139                         x = null;
       
   140                     }
       
   141                 }
       
   142 
       
   143                 for (Enumeration<String> depsEnum = target.getDependencies(); depsEnum
       
   144                         .hasMoreElements();) {
       
   145                     String depTargetString = depsEnum.nextElement();
       
   146                     String[] array = { depTargetString };
       
   147                     try {
       
   148                         Target depTarget = findTarget(depTargetString, project,
       
   149                                 array);
       
   150                         targetCallsHeliumTarget(depTarget, project);
       
   151                     } catch (BuildException x) {
       
   152                         // We are Ignoring the errors as no need to fail the
       
   153                         // build.
       
   154                         log(
       
   155                                 "Exception occured while target defined outside helium are calling a private Helium target "
       
   156                                         + x.toString(), Project.MSG_DEBUG);
       
   157                         x = null;
       
   158                     }
       
   159                 }
       
   160             } else {
       
   161                 checkIfTargetPrivate(target, project);
       
   162             }
       
   163 
       
   164         } catch (IOException e) {
       
   165             // We are Ignoring the errors as no need to fail the build.
       
   166             log(
       
   167                     "IOException occured while target defined outside helium are calling a private Helium target "
       
   168                             + e.getMessage(), Project.MSG_DEBUG);
       
   169             e.printStackTrace();
       
   170         }
       
   171     }
       
   172 
       
   173     private class AntTargetVisitor extends VisitorSupport {
       
   174         private List<String> targetList;
       
   175         private Project project;
       
   176 
       
   177         public AntTargetVisitor(List<String> targetList, Project project) {
       
   178             this.targetList = targetList;
       
   179             this.project = project;
       
   180         }
       
   181 
       
   182         public void visit(Element node) {
       
   183             String name = node.getName();
       
   184             if (name.equals("antcall") || name.equals("runtarget")) {
       
   185                 String text = node.attributeValue("target");
       
   186                 extractTarget(text);
       
   187             }
       
   188         }
       
   189 
       
   190         private void extractTarget(String text) {
       
   191             String iText = project.replaceProperties(text);
       
   192             targetList.add(iText);
       
   193         }
       
   194 
       
   195     }
       
   196 
       
   197     /**
       
   198      * Find the xml Element for the target
       
   199      * 
       
   200      */
       
   201     @SuppressWarnings("unchecked")
       
   202     public Element findTargetElement(Target target, Project project) {
       
   203         SAXReader xmlReader = new SAXReader();
       
   204 
       
   205         Document antDoc = null;
       
   206 
       
   207         String location = target.getLocation().getFileName();
       
   208 
       
   209         try {
       
   210             File file = new File(location);
       
   211             antDoc = xmlReader.read(file);
       
   212         } catch (DocumentException e) {
       
   213             // We are Ignoring the errors as no need to fail the build.
       
   214             log("Not able read the XML file. " + e.getMessage(),
       
   215                     Project.MSG_WARN);
       
   216         }
       
   217 
       
   218         String projectName = antDoc.valueOf("/project/@name");
       
   219         for (Iterator<Element> iterator = antDoc.selectNodes("//target")
       
   220                 .iterator(); iterator.hasNext();) {
       
   221             Element element = iterator.next();
       
   222 
       
   223             String targetName = element.attributeValue("name");
       
   224             if (targetName.equals(target.getName())
       
   225                     || (projectName + "." + targetName)
       
   226                             .equals(target.getName())) {
       
   227                 return element;
       
   228             }
       
   229         }
       
   230         return null;
       
   231     }
       
   232 
       
   233     /**
       
   234      * If target has comment that says it is private them print warning
       
   235      * 
       
   236      */
       
   237     @SuppressWarnings("unchecked")
       
   238     public void checkIfTargetPrivate(Target target, Project project) {
       
   239         Element targetElement = findTargetElement(target, project);
       
   240         if (targetElement != null) {
       
   241             List<Node> children = targetElement
       
   242                     .selectNodes("preceding-sibling::node()");
       
   243             if (children.size() > 0) {
       
   244                 // Scan past the text nodes, which are most likely whitespace
       
   245                 int index = children.size() - 1;
       
   246                 Node child = children.get(index);
       
   247                 while (index > 0 && child.getNodeType() == Node.TEXT_NODE) {
       
   248                     index--;
       
   249                     child = (Node) children.get(index);
       
   250                 }
       
   251 
       
   252                 // Check if there is a comment node
       
   253                 String commentText = null;
       
   254                 if (child.getNodeType() == Node.COMMENT_NODE) {
       
   255                     Comment macroComment = (Comment) child;
       
   256                     commentText = macroComment.getStringValue().trim();
       
   257                     // log(macroName + " comment: " + commentText,
       
   258                     // Project.MSG_DEBUG);
       
   259                 }
       
   260 
       
   261                 if (commentText != null) {
       
   262                     if (commentText.contains("Private:")) {
       
   263                         output
       
   264                                 .add("Warning: "
       
   265                                         + target.getName()
       
   266                                         + " is private and should only be called by helium");
       
   267                     }
       
   268                     if (commentText.contains("<deprecated>")) {
       
   269                         output.add("Warning: " + target.getName() + "\n"
       
   270                                 + commentText);
       
   271                     }
       
   272                 }
       
   273             }
       
   274         }
       
   275     }
       
   276 
       
   277     /**
       
   278      * To check, is the private properties are overridden by customers.
       
   279      * 
       
   280      * @param project
       
   281      */
       
   282     public void checkTargetsProperties(Project project) {
       
   283         try {
       
   284             String heliumpath = new File(project.getProperty("helium.dir"))
       
   285                     .getCanonicalPath();
       
   286             com.nokia.helium.ant.data.Database db = new com.nokia.helium.ant.data.Database(
       
   287                     project, "private");
       
   288             ArrayList<String> customerProps = getCustomerProperties(project);
       
   289 
       
   290             for (PropertyMeta propertyMeta : db.getProperties()) {
       
   291                 if (propertyMeta.getType().equals("boolean"))
       
   292                 {
       
   293                     String value = project.getProperty(propertyMeta.getName());
       
   294                     if (value != null && !value.equals("true") && !value.equals("false"))
       
   295                     {
       
   296                         output.add("Warning: " + propertyMeta.getName() + " property is boolean type and not set to true or false, value is " + value);
       
   297                     }
       
   298                 }
       
   299             }
       
   300             for (PropertyCommentMeta propertyMeta : db.getCommentProperties()) {
       
   301                 if (propertyMeta.getType().equals("boolean"))
       
   302                 {
       
   303                     String value = project.getProperty(propertyMeta.getName());
       
   304                     if (value != null && !value.equals("true") && !value.equals("false"))
       
   305                     {
       
   306                         output.add("Warning: " + propertyMeta.getName() + " property is boolean type and not set to true or false, value is " + value);
       
   307                     }
       
   308                 }
       
   309             }
       
   310             for (PropertyMeta propertyMeta : db.getProperties()) {
       
   311                 if (propertyMeta.getLocation().contains(heliumpath)
       
   312                         && propertyMeta.getScope().equals("private")
       
   313                         && customerProps.contains(propertyMeta.getName())) {
       
   314                     output.add("Warning: " + propertyMeta.getName()
       
   315                             + " property has been overridden");
       
   316                 }
       
   317             }
       
   318 
       
   319             for (PropertyCommentMeta propertyCommentMeta : db.getCommentProperties()) {
       
   320                 if (propertyCommentMeta.getLocation().contains(heliumpath)
       
   321                         && propertyCommentMeta.getScope().equals("private")
       
   322                         && customerProps
       
   323                                 .contains(propertyCommentMeta.getName())) {
       
   324                     output.add("Warning: " + propertyCommentMeta.getName()
       
   325                             + " property has been overridden");
       
   326                 }
       
   327             }
       
   328         } catch (IOException e) {
       
   329             e.printStackTrace();
       
   330         }
       
   331     }
       
   332 
       
   333     /**
       
   334      * To display the warnings for deprecated properties.
       
   335      * 
       
   336      * @param project
       
   337      */
       
   338     public void checkDeprecatedProperties(Project project) {
       
   339         try {
       
   340             String heliumpath = new File(project.getProperty("helium.dir"))
       
   341                     .getCanonicalPath();
       
   342             com.nokia.helium.ant.data.Database db = new com.nokia.helium.ant.data.Database(
       
   343                     project, "private");
       
   344             ArrayList<String> customerProps = getCustomerProperties(project);
       
   345 
       
   346             for (PropertyMeta propertyMeta : db.getProperties()) {
       
   347                 if (propertyMeta.getLocation().contains(heliumpath)
       
   348                         && (!propertyMeta.getDeprecated().equals(""))
       
   349                         && customerProps.contains(propertyMeta.getName())) {
       
   350                     output.add("Warning: "
       
   351                             + propertyMeta.getName()
       
   352                             + " property has been deprecated "
       
   353                             + propertyMeta.getDeprecated()
       
   354                             + "."
       
   355                             + propertyMeta.getSummary().substring(
       
   356                                     propertyMeta.getSummary().lastIndexOf(
       
   357                                             DEPRECATED)
       
   358                                             + DEPRECATED.length()));
       
   359                 }
       
   360             }
       
   361 
       
   362             for (PropertyCommentMeta propertyCommentMeta : db
       
   363                     .getCommentProperties()) {
       
   364                 if (propertyCommentMeta.getLocation().contains(heliumpath)
       
   365                         && (!propertyCommentMeta.getDeprecated().equals(""))
       
   366                         && customerProps
       
   367                                 .contains(propertyCommentMeta.getName())) {
       
   368                     output.add("Warning: "
       
   369                             + propertyCommentMeta.getName()
       
   370                             + " property has been deprecated "
       
   371                             + propertyCommentMeta.getDeprecated()
       
   372                             + "."
       
   373                             + propertyCommentMeta.getSummary().substring(
       
   374                                     propertyCommentMeta.getSummary()
       
   375                                             .lastIndexOf(DEPRECATED)
       
   376                                             + DEPRECATED.length()));
       
   377                 }
       
   378             }
       
   379         } catch (IOException e) {
       
   380             e.printStackTrace();
       
   381         }
       
   382     }
       
   383 
       
   384     @SuppressWarnings("unchecked")
       
   385     public ArrayList<String> getCustomerProperties(Project project) {
       
   386         ArrayList<String> props = new ArrayList<String>();
       
   387         Database db = new Database(null, null, null);
       
   388         try {
       
   389             String heliumpath = new File(project.getProperty("helium.dir"))
       
   390                     .getCanonicalPath();
       
   391 
       
   392             for (Object object : db.getAntFiles(project)) {
       
   393                 String antFile = (String) object;
       
   394                 antFile = new File(antFile).getCanonicalPath();
       
   395 
       
   396                 if (!antFile.contains(heliumpath)) {
       
   397                     SAXReader xmlReader = new SAXReader();
       
   398                     Document antDoc = xmlReader.read(new File(antFile));
       
   399 
       
   400                     List<Element> propertyNodes = antDoc
       
   401                             .selectNodes("//property | //param");
       
   402                     for (Element propertyNode : propertyNodes) {
       
   403                         props.add(propertyNode.attributeValue("name"));
       
   404                     }
       
   405                 }
       
   406             }
       
   407         } catch (IOException e) {
       
   408             // We are Ignoring the errors as no need to fail the build.
       
   409             log("IOException: Not able read the Customer Properties "
       
   410                     + e.getMessage(), Project.MSG_WARN);
       
   411         } catch (DocumentException e) {
       
   412             // We are Ignoring the errors as no need to fail the build.
       
   413             log("DocumentException: Not able read the Customer Properties "
       
   414                     + e.getMessage(), Project.MSG_WARN);
       
   415         }
       
   416 
       
   417         return props;
       
   418     }
       
   419 
       
   420 }