<?xml version="1.0" encoding="UTF-8"?> <!-- -*- sgml-indent-step: 2 -*- -->
<!--
The contents of this file are subject to the terms of the Common Development
and Distribution License (the License). You may not use this file except in
compliance with the License.

You can obtain a copy of the License at http://www.netbeans.org/cddl.html
or http://www.netbeans.org/cddl.txt.

When distributing Covered Code, include this CDDL Header Notice in each file
and include the License file at http://www.netbeans.org/cddl.txt.
If applicable, add the following below the CDDL Header, with the fields
enclosed by brackets [] replaced by your own identifying information:
"Portions Copyrighted [year] [name of copyright owner]"

The Original Software is NetBeans. The Initial Developer of the Original
Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
Microsystems, Inc. All Rights Reserved.
-->

<!--
Monitors source code for bad constructions and overlooked common problems.
Author: Jesse Glick

To implement:
- XML syntax check and validation for files with DTD (RFE in IssueZilla?)
- //NOI18N check (who knows most about this?)
- common Czenglish mistakes in bundles (pkeegan would know best)
- newlines: text files should have proper line endings acc. to platform, and end in linefeed, no tabs
- JavaHelp sanity: targets exist in various modules
- use of NbBundle.getBundle(getClass()) etc.
- use of netbeans.debug.exceptions (change to ErrorManager)
- bundle values beginning or ending with a space (but see JLF recommendations on ui.netbeans.org)
- readObject etc. methods with incorrect signature (e.g. returning Object)
- standalone usage checker for library JARs (all classes must resolvable) (or part of openide test suite)
- System.getProperty("java.version").startsWith(...) [cf. #16813]
- static resource bundle variables (should load using NbBundle if and when needed)
-->

<project name="Source Monitor" default="all" basedir=".">

  <property name="mailhost" value="localhost"/>
  <property name="nb_all" location=".."/>
  <path id="nbantext">
    <pathelement location="nbantext.jar"/>
  </path>

  <target name="init">
    <ant dir="." target="bootstrap"/>
    <taskdef name="checklicense" classname="org.netbeans.nbbuild.CheckLicense" classpathref="nbantext"/>
    <taskdef name="findbad" classname="org.netbeans.nbbuild.FindBadConstructions" classpathref="nbantext"/>
    <taskdef name="kvetch" classname="org.netbeans.nbbuild.Kvetcher" classpathref="nbantext"/>
    <taskdef name="repeat" classname="org.netbeans.nbbuild.Repeat" classpathref="nbantext"/>
    <taskdef name="checkbundles" classname="org.netbeans.nbbuild.CheckBundles" classpathref="nbantext"/>
  </target>

  <!-- the same configuration of module list as in build.xml -->
  <target name="init-module-list" depends="init">
    <!-- Read the user property file at first -->
    <property file="user.build.properties"/>

    <!-- Read standard property file -->
    <property file="build.properties"/>

    <!-- Define modules. -->
    <!-- The following is not permitted by Ant: -->
    <!-- <property name="modules" value="${config.modules.${moduleconfig}}"/> -->
    <!-- So this is a little trick to do it anyway. -->
    <echo file="moduledefs-tmp.properties">modules=$${config.modules.${moduleconfig}}
fixedmodules=$${config.fixedmodules.${moduleconfig}}
</echo>
    <property file="moduledefs-tmp.properties"/>
    <property name="allmodules" value="${fixedmodules},${modules}"/>
  </target>

  <target name="all" depends="check-licenses,check-dbl-checked-locking,check-bundle-snafus" description="Run all implemented tests."/>

  <target name="kvetch" depends="init" description="Run tests, and send mail to culprits. Under development.">
    <kvetch mailhost="${mailhost}"
            target="all"
            from="jesse.glick@sun.com"
            subject="Possible problems in sources you own on netbeans.org"
    >
      <explanation><![CDATA[This mail is being automatically sent by nbbuild/monitor.xml:kvetch.
If you receive it, it means that there *may* be something wrong in sources you own.
Please take a look at the warnings listed here, and correct them if necessary.
If you think the warnings were printed in error, that is your sources are fine and
the tool is simply generating unnecessary messages, please reply with details and
an exception can be made for your code so you do not get further mail about it.
]]></explanation>
      <culprit>
        <to name="jesse.glick@sun.com"/>
        <regexp pattern="^${nb_all}/((ant|apisupport|core|openide)/(.|\n)+)" group="1"/>
      </culprit>
      <!-- XXX add more -->
    </kvetch>
  </target>

  <target name="check-licenses" depends="init" description="Check whether CDDL is in every source file.">
    <echo message="Looking for source files, will take a moment..."/>
    <checklicense fragment="CDDL">
      <!-- This fileset will only check CVS-controlled text files: -->
      <cvsfileset dir=".." mode="text">
        <!-- Templates are for users and are not licensed: -->
        <exclude name="**/templates/"/>
        <exclude name="**/*.template"/>
        <exclude name="**/*_"/>
        <exclude name="**/*_java"/>
        <exclude name="**/*-"/>
        <exclude name="editor/demosrc/properties-addon/org/netbeans/editor/example/res/template.properties"/>
        <exclude name="**/tojar/"/>
        <exclude name="contrib/docbook/src/org/netbeans/modules/docbook/*-template.xml"/>
        <!-- Similar for things copied to distro and minor examples: -->
        <exclude name="**/release/"/>
        <exclude name="xtest/examples/"/>
        <!-- Trivial test data: -->
        <exclude name="core/test/unit/src/org/netbeans/core/modules/jars/"/>
        <exclude name="**/test*/**/data/"/>
        <exclude name="core/test/perf/src/org/netbeans/core/resources/"/>
        <exclude name="**/*.pass"/>
        <exclude name="**/*.ref"/>
        <!-- Generated docs: -->
        <exclude name="openide/api/doc/org/openide/filesystems/doc-files/resolverDocumentation.html"/>
        <!-- For help, see below: -->
        <exclude name="**/javahelp/"/>
        <exclude name="**/api/doc/"/>
        <exclude name="**/docs/"/>
        <!-- Web pages need no notice: -->
        <exclude name="*/www/"/>
        <!-- Cannot hold licenses: -->
        <exclude name="**/*.mf"/>
        <exclude name="**/*.group"/>
        <exclude name="**/*.ent"/>
        <exclude name="**/*.MAKEME"/>
        <exclude name="**/*.cfg"/>
        <!-- Generally no IP: -->
        <exclude name="**/*.txt"/>
        <exclude name="**/*.html"/>
        <exclude name="**/README"/>
        <exclude name="CVSROOT/"/>
        <exclude name="nbbuild/tagref"/>
        <exclude name="jndi/src/org/netbeans/modules/jndi/resources/providers/*.impl"/>
        <!-- Minor runtime objects which need to be fast to parse: -->
        <exclude name="**/*.settings"/>
        <exclude name="**/*etting*.xml"/>
        <exclude name="**/antlib.xml"/>
        <exclude name="**/META-INF/"/>
        <exclude name="**/*.ws*"/>
        <exclude name="editor/src/org/netbeans/modules/editor/resources/AnnotationTypes/bookmark.xml"/>
        <!-- Generated by tools: -->
        <exclude name="**/*.form"/>
        <exclude name="**/.nbattrs"/>
        <exclude name="**/*l10n.list*"/>
        <exclude name="**/sub.locale.xml"/>
        <exclude name="installer/"/>
        <exclude name="ide/launcher/macosx/NetBeansLauncher/"/>
        <!-- From beyond: -->
        <exclude name="core/javahelp/src/org/netbeans/modules/javahelp/resources/*.dtd"/>
        <exclude name="editor/src/org/netbeans/modules/editor/resources/DTDs/"/>
        <exclude name="**/external/"/>
        <exclude name="contrib/**/external/"/>
        <exclude name="web/examples/"/>
      </cvsfileset>
    </checklicense>
    <echo message="Now looking for copyrighted documentation..."/>
    <checklicense fragment="Copyright">
      <cvsfileset dir=".." mode="text">
        <include name="**/javahelp/"/>
        <exclude name="core/javahelp/manifest.mf"/>
        <exclude name="core/javahelp/src/META-INF/services/"/>
        <include name="**/api/doc/"/>
        <!-- Generally no IP: -->
        <exclude name="**/*.txt"/>
        <!-- Cannot hold licenses: -->
        <exclude name="**/package-list"/>
        <!-- Generated by tools: -->
        <exclude name="**/*.pgml"/>
        <exclude name="**/*.argo"/>
        <exclude name="**/*.xmi"/>
      </cvsfileset>
    </checklicense>
  </target>

  <target name="check-dbl-checked-locking" depends="init" description="Check sources for uses of double-checked locking.">
    <echo message="Looking for source files, will take a moment..."/>
    <findbad>
      <cvsfileset dir="..">
        <include name="**/*.java"/>
      </cvsfileset>
      <construction regexp="^.*if \((.+)\) \{.*^.*synchronized \(.+\) \{.*^.*if \(\1\) \{.*^" message="Possible double-checked locking (remove outer test)" showmatch="0"/>
    </findbad>
  </target>

  <target name="check-bundle-snafus" depends="init" description="Check bundles for undoubled ' in message formats and style errors.">
    <echo message="Looking for bundles, will take a moment..."/>
    <findbad>
      <cvsfileset dir="..">
        <include name="**/*.properties"/>
      </cvsfileset>
      <construction regexp="\{\d+\}.*[^']'([^'{}]|$)|[^']'[^'{}].*\{\d+\}" message="Undoubled ' in message format (double it to escape it)" showmatch="0"/>
      <!-- [Cc]an't|[Cc]ouldn't|[Dd]on't|[Dd]oesn't|[Dd]idn't|[Ww]on't|[Ss]houldn't|[Hh]asn't|[Hh]aven't|[Oo]ughtn't|[Aa]ren't|[Ii]sn't|[Ww]asn't -->
      <construction regexp="\b[A-Za-z][a-z]+n't\b" message="Contraction (spell it out)" showmatch="0"/>
    </findbad>
  </target>

  <target name="check-noi18n-comments" depends="init-module-list" description="print info about configured modules">
    <echo message="Running NOI18N check..."/>
    <echo message="Selected modules: ${allmodules}"/>
    <apply executable="perl" type="file" parallel="true">
      <arg file="misc/i18ncheck.pl"/>
      <fileset dir="..">
        <patternset>
          <include name="${allmodules}/**/*.java"/>
          <exclude name="**/build/"/>
          <exclude name="**/test/"/>
          <exclude name="**/antsrc/"/>
        </patternset>
      </fileset>
    </apply>
  </target>

  <target name="check-bundle-usage" depends="init-module-list" description="Check bundles for unused strings.">
    <repeat target="check-bundle-usage-in-module" name="modulename" values="${allmodules}"/>
  </target>
  
  <!-- expects ${modulename} to be set -->
  <target name="check-bundle-usage-in-module">
    <echo message="Looking for unused keys in bundles in module ${modulename}"/>
    <checkbundles srcdir="../${modulename}"/>
  </target>
</project>
