Experimental I18N/hardcoded strings checker. javaee5_merge1
authorjlahoda@netbeans.org
Tue, 13 Sep 2005 18:57:19 +0000
changeset 6401d5057e8c7372
parent 6400 99d998affb38
child 6402 f8bbd865ff58
Experimental I18N/hardcoded strings checker.
editor.hints.i18n/build.xml
editor.hints.i18n/manifest.mf
editor.hints.i18n/nbproject/project.properties
editor.hints.i18n/nbproject/project.xml
editor.hints.i18n/src/org/netbeans/modules/editor/hints/i18n/Bundle.properties
editor.hints.i18n/src/org/netbeans/modules/editor/hints/i18n/I18NChecker.java
editor.hints.i18n/src/org/netbeans/modules/editor/hints/i18n/layer.xml
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/editor.hints.i18n/build.xml	Tue Sep 13 18:57:19 2005 +0000
     1.3 @@ -0,0 +1,17 @@
     1.4 +<?xml version="1.0" encoding="UTF-8"?>
     1.5 +<!--
     1.6 +                Sun Public License Notice
     1.7 +
     1.8 +The contents of this file are subject to the Sun Public License
     1.9 +Version 1.0 (the "License"). You may not use this file except in
    1.10 +compliance with the License. A copy of the License is available at
    1.11 +http://www.sun.com/
    1.12 +
    1.13 +The Original Code is NetBeans. The Initial Developer of the Original
    1.14 +Code is Sun Microsystems, Inc. Portions Copyright 1997-2005 Sun
    1.15 +Microsystems, Inc. All Rights Reserved.
    1.16 +-->
    1.17 +<project basedir="." default="netbeans" name="contrib/editorhints/i18n">
    1.18 +    <description>Builds, tests, and runs the project org.netbeans.modules.editor.hints.i18n</description>
    1.19 +    <import file="../../../nbbuild/templates/projectized.xml"/>
    1.20 +</project>
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/editor.hints.i18n/manifest.mf	Tue Sep 13 18:57:19 2005 +0000
     2.3 @@ -0,0 +1,6 @@
     2.4 +Manifest-Version: 1.0
     2.5 +OpenIDE-Module: org.netbeans.modules.editor.hints.i18n
     2.6 +OpenIDE-Module-Layer: org/netbeans/modules/editor/hints/i18n/layer.xml
     2.7 +OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/editor/hints/i18n/Bundle.properties
     2.8 +OpenIDE-Module-Specification-Version: 1.0
     2.9 +
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/editor.hints.i18n/nbproject/project.properties	Tue Sep 13 18:57:19 2005 +0000
     3.3 @@ -0,0 +1,10 @@
     3.4 +#                 Sun Public License Notice
     3.5 +# 
     3.6 +# The contents of this file are subject to the Sun Public License
     3.7 +# Version 1.0 (the "License"). You may not use this file except in
     3.8 +# compliance with the License. A copy of the License is available at
     3.9 +# http://www.sun.com/
    3.10 +# 
    3.11 +# The Original Code is NetBeans. The Initial Developer of the Original
    3.12 +# Code is Sun Microsystems, Inc. Portions Copyright 1997-2005 Sun
    3.13 +# Microsystems, Inc. All Rights Reserved.
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/editor.hints.i18n/nbproject/project.xml	Tue Sep 13 18:57:19 2005 +0000
     4.3 @@ -0,0 +1,114 @@
     4.4 +<?xml version="1.0" encoding="UTF-8"?>
     4.5 +<!--
     4.6 +                Sun Public License Notice
     4.7 +
     4.8 +The contents of this file are subject to the Sun Public License
     4.9 +Version 1.0 (the "License"). You may not use this file except in
    4.10 +compliance with the License. A copy of the License is available at
    4.11 +http://www.sun.com/
    4.12 +
    4.13 +The Original Code is NetBeans. The Initial Developer of the Original
    4.14 +Code is Sun Microsystems, Inc. Portions Copyright 1997-2005 Sun
    4.15 +Microsystems, Inc. All Rights Reserved.
    4.16 +-->
    4.17 +<project xmlns="http://www.netbeans.org/ns/project/1">
    4.18 +    <type>org.netbeans.modules.apisupport.project</type>
    4.19 +    <configuration>
    4.20 +        
    4.21 +    
    4.22 +    
    4.23 +    <data xmlns="http://www.netbeans.org/ns/nb-module-project/2">
    4.24 +            <code-name-base>org.netbeans.modules.editor.hints.i18n</code-name-base>
    4.25 +            
    4.26 +            
    4.27 +            
    4.28 +            <module-dependencies>
    4.29 +                <dependency>
    4.30 +                    <code-name-base>org.netbeans.modules.editor.lib</code-name-base>
    4.31 +                    <build-prerequisite/>
    4.32 +                    <compile-dependency/>
    4.33 +                    <run-dependency>
    4.34 +                        <release-version>1</release-version>
    4.35 +                    </run-dependency>
    4.36 +                </dependency>
    4.37 +                <dependency>
    4.38 +                    <code-name-base>org.netbeans.modules.i18n</code-name-base>
    4.39 +                    <build-prerequisite/>
    4.40 +                    <compile-dependency/>
    4.41 +                    <run-dependency>
    4.42 +                        <release-version>1</release-version>
    4.43 +                        <specification-version>1.18</specification-version>
    4.44 +                    </run-dependency>
    4.45 +                </dependency>
    4.46 +                <dependency>
    4.47 +                    <code-name-base>org.netbeans.modules.properties</code-name-base>
    4.48 +                    <build-prerequisite/>
    4.49 +                    <compile-dependency/>
    4.50 +                    <run-dependency>
    4.51 +                        <release-version>1</release-version>
    4.52 +                        <specification-version>1.15</specification-version>
    4.53 +                    </run-dependency>
    4.54 +                </dependency>
    4.55 +                <dependency>
    4.56 +                    <code-name-base>org.netbeans.modules.properties.syntax</code-name-base>
    4.57 +                    <build-prerequisite/>
    4.58 +                    <compile-dependency/>
    4.59 +                    <run-dependency>
    4.60 +                        <release-version>1</release-version>
    4.61 +                        <specification-version>1.15</specification-version>
    4.62 +                    </run-dependency>
    4.63 +                </dependency>
    4.64 +                <dependency>
    4.65 +                    <code-name-base>org.netbeans.spi.editor.hints</code-name-base>
    4.66 +                    <build-prerequisite/>
    4.67 +                    <compile-dependency/>
    4.68 +                    <run-dependency>
    4.69 +                        <release-version>0</release-version>
    4.70 +                        <specification-version>1.0</specification-version>
    4.71 +                    </run-dependency>
    4.72 +                </dependency>
    4.73 +                <dependency>
    4.74 +                    <code-name-base>org.openide.filesystems</code-name-base>
    4.75 +                    <build-prerequisite/>
    4.76 +                    <compile-dependency/>
    4.77 +                    <run-dependency>
    4.78 +                        <specification-version>6.2</specification-version>
    4.79 +                    </run-dependency>
    4.80 +                </dependency>
    4.81 +                <dependency>
    4.82 +                    <code-name-base>org.openide.loaders</code-name-base>
    4.83 +                    <build-prerequisite/>
    4.84 +                    <compile-dependency/>
    4.85 +                    <run-dependency>
    4.86 +                        <specification-version>5.5</specification-version>
    4.87 +                    </run-dependency>
    4.88 +                </dependency>
    4.89 +                <dependency>
    4.90 +                    <code-name-base>org.openide.nodes</code-name-base>
    4.91 +                    <build-prerequisite/>
    4.92 +                    <compile-dependency/>
    4.93 +                    <run-dependency>
    4.94 +                        <specification-version>6.5</specification-version>
    4.95 +                    </run-dependency>
    4.96 +                </dependency>
    4.97 +                <dependency>
    4.98 +                    <code-name-base>org.openide.text</code-name-base>
    4.99 +                    <build-prerequisite/>
   4.100 +                    <compile-dependency/>
   4.101 +                    <run-dependency>
   4.102 +                        <specification-version>6.6</specification-version>
   4.103 +                    </run-dependency>
   4.104 +                </dependency>
   4.105 +                <dependency>
   4.106 +                    <code-name-base>org.openide.util</code-name-base>
   4.107 +                    <build-prerequisite/>
   4.108 +                    <compile-dependency/>
   4.109 +                    <run-dependency>
   4.110 +                        <specification-version>6.4</specification-version>
   4.111 +                    </run-dependency>
   4.112 +                </dependency>
   4.113 +            </module-dependencies>
   4.114 +            <public-packages/>
   4.115 +        </data>
   4.116 +    </configuration>
   4.117 +</project>
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/editor.hints.i18n/src/org/netbeans/modules/editor/hints/i18n/Bundle.properties	Tue Sep 13 18:57:19 2005 +0000
     5.3 @@ -0,0 +1,12 @@
     5.4 +#                 Sun Public License Notice
     5.5 +# 
     5.6 +# The contents of this file are subject to the Sun Public License
     5.7 +# Version 1.0 (the "License"). You may not use this file except in
     5.8 +# compliance with the License. A copy of the License is available at
     5.9 +# http://www.sun.com/
    5.10 +# 
    5.11 +# The Original Code is NetBeans. The Initial Developer of the Original
    5.12 +# Code is Sun Microsystems, Inc. Portions Copyright 1997-2005 Sun
    5.13 +# Microsystems, Inc. All Rights Reserved.
    5.14 +
    5.15 +OpenIDE-Module-Name=I18N Checker
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/editor.hints.i18n/src/org/netbeans/modules/editor/hints/i18n/I18NChecker.java	Tue Sep 13 18:57:19 2005 +0000
     6.3 @@ -0,0 +1,181 @@
     6.4 +/*
     6.5 + *                 Sun Public License Notice
     6.6 + *
     6.7 + * The contents of this file are subject to the Sun Public License
     6.8 + * Version 1.0 (the "License"). You may not use this file except in
     6.9 + * compliance with the License. A copy of the License is available at
    6.10 + * http://www.sun.com/
    6.11 + *
    6.12 + * The Original Code is NetBeans. The Initial Developer of the Original
    6.13 + * Code is Sun Microsystems, Inc. Portions Copyright 1997-2005 Sun
    6.14 + * Microsystems, Inc. All Rights Reserved.
    6.15 + */
    6.16 +package org.netbeans.modules.editor.hints.i18n;
    6.17 +
    6.18 +import java.io.IOException;
    6.19 +import java.util.ArrayList;
    6.20 +import java.util.Arrays;
    6.21 +import java.util.Collections;
    6.22 +import java.util.List;
    6.23 +import javax.swing.text.BadLocationException;
    6.24 +import javax.swing.text.Document;
    6.25 +import javax.swing.text.StyledDocument;
    6.26 +import org.netbeans.modules.i18n.HardCodedString;
    6.27 +import org.netbeans.modules.i18n.I18nString;
    6.28 +import org.netbeans.modules.i18n.java.JavaI18nSupport;
    6.29 +import org.netbeans.modules.properties.BundleStructure;
    6.30 +import org.netbeans.modules.properties.Element;
    6.31 +import org.netbeans.modules.properties.Element.ItemElem;
    6.32 +import org.netbeans.modules.properties.PropertiesDataObject;
    6.33 +import org.netbeans.modules.properties.PropertiesStructure;
    6.34 +import org.netbeans.spi.editor.hints.ChangeInfo;
    6.35 +import org.netbeans.spi.editor.hints.ErrorDescription;
    6.36 +import org.netbeans.spi.editor.hints.ErrorDescriptionFactory;
    6.37 +import org.netbeans.spi.editor.hints.Fix;
    6.38 +import org.netbeans.spi.editor.hints.support.ErrorParserSupport;
    6.39 +import org.openide.ErrorManager;
    6.40 +import org.openide.cookies.LineCookie;
    6.41 +import org.openide.cookies.SaveCookie;
    6.42 +import org.openide.filesystems.FileObject;
    6.43 +import org.openide.loaders.DataObject;
    6.44 +import org.openide.loaders.DataObjectNotFoundException;
    6.45 +import org.openide.text.Line;
    6.46 +import org.openide.text.NbDocument;
    6.47 +
    6.48 +/**
    6.49 + *
    6.50 + * @author Jan Lahoda
    6.51 + */
    6.52 +public class I18NChecker extends ErrorParserSupport {
    6.53 +    
    6.54 +    /** Creates a new instance of I18NChecker */
    6.55 +    public I18NChecker() {
    6.56 +    }
    6.57 +
    6.58 +    public List parseForErrors(final Document doc) {
    6.59 +        //TODO: generate unique 
    6.60 +        try {
    6.61 +            final DataObject od = (DataObject) doc.getProperty(Document.StreamDescriptionProperty);
    6.62 +            final JavaI18nSupport support = new JavaI18nSupport(od);
    6.63 +            final HardCodedString[] hcs = support.getFinder().findAllHardCodedStrings();
    6.64 +            final List result = new ArrayList();
    6.65 +            final FileObject bundleFO = od.getPrimaryFile().getParent().getFileObject("Bundle.properties");
    6.66 +            final PropertiesDataObject bundle = (PropertiesDataObject) (bundleFO != null ? DataObject.find(bundleFO) : null); //TODO: cast
    6.67 +            
    6.68 +            if (hcs != null) {
    6.69 +                for (int cntr = 0; cntr < hcs.length; cntr++) {
    6.70 +                    final HardCodedString hardCoded = hcs[cntr];
    6.71 +
    6.72 +                    if (hardCoded.getLength() == 2)
    6.73 +                        continue; //ignore empty strings
    6.74 +                    
    6.75 +                    Fix addToBundle = new Fix() {
    6.76 +                        public String getText() {
    6.77 +                            return (bundle == null ? "Create new bundle and r" : "R") + "eplace with localized string";
    6.78 +                        }
    6.79 +                        public ChangeInfo implement() {
    6.80 +                            PropertiesDataObject bundleInt = bundle;
    6.81 +                            
    6.82 +                            if (bundleInt == null) {
    6.83 +                                try {
    6.84 +                                    FileObject bundleFO = od.getPrimaryFile().getParent().createData("Bundle.properties");
    6.85 +                                    assert bundleFO != null;
    6.86 +                                    bundleInt = (PropertiesDataObject) DataObject.find(bundleFO); //TODO: cast
    6.87 +                                } catch (IOException ex) {
    6.88 +                                    ex.printStackTrace();
    6.89 +                                }
    6.90 +                            }
    6.91 +                            
    6.92 +                            if (bundleInt == null) {
    6.93 +                                //something was wrong, cannot continue:
    6.94 +                                return null;
    6.95 +                            }
    6.96 +                            
    6.97 +                            final I18nString string = support.getDefaultI18nString(hardCoded);
    6.98 +                            
    6.99 +                            string.setReplaceFormat(null);
   6.100 +                            string.getSupport().getResourceHolder().setResource(bundleInt);
   6.101 +                            
   6.102 +                            support.getResourceHolder().addProperty(string.getKey(), string.getValue(), string.getComment());
   6.103 +                            support.getReplacer().replace(hardCoded, string);
   6.104 +                            
   6.105 +                            SaveCookie sc = (SaveCookie) bundleInt.getCookie(SaveCookie.class);
   6.106 +                            
   6.107 +                            if (sc != null) {
   6.108 +                                try {
   6.109 +                                    sc.save();
   6.110 +                                } catch (IOException e) {
   6.111 +                                    ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e);
   6.112 +                                }
   6.113 +                            }
   6.114 +                            
   6.115 +                            return null;
   6.116 +                        }
   6.117 +                    };
   6.118 +                    
   6.119 +                    Fix addNOI18N = new Fix() {
   6.120 +                        public String getText() {
   6.121 +                            return "Add // NOI18N";
   6.122 +                        }
   6.123 +                        
   6.124 +                        public ChangeInfo implement() {
   6.125 +                            try {
   6.126 +                                int line = NbDocument.findLineNumber((StyledDocument) doc, hardCoded.getStartPosition().getOffset());
   6.127 +                                int writeOffset = NbDocument.findLineOffset((StyledDocument) doc, line + 1) - 1; //TODO: last line in the document not handled correctly
   6.128 +                                
   6.129 +                                doc.insertString(writeOffset, " // NOI18N", null);
   6.130 +                            } catch (BadLocationException ex) {
   6.131 +                                ErrorManager.getDefault().notify(ex);
   6.132 +                            }
   6.133 +                            return null;
   6.134 +                        }
   6.135 +                    };
   6.136 +                    result.add(ErrorDescriptionFactory.createErrorDescription(ErrorDescription.SEVERITY_VERIFIER, "Hardcoded String", Arrays.asList(new Object[] {addToBundle, addNOI18N}), getLinePart(doc, od, hcs[cntr])));
   6.137 +                }
   6.138 +            }
   6.139 +            
   6.140 +            return result;
   6.141 +        } catch (DataObjectNotFoundException ex) {
   6.142 +            ErrorManager.getDefault().notify(ex);
   6.143 +        }
   6.144 +        return Collections.EMPTY_LIST;
   6.145 +    }
   6.146 +    
   6.147 +    private Line.Part getLinePart(Document doc, DataObject od, HardCodedString hcs) {
   6.148 +        LineCookie lc = (LineCookie) od.getCookie(LineCookie.class);
   6.149 +        int startOffset = hcs.getStartPosition().getOffset();
   6.150 +        
   6.151 +        return lc.getLineSet().getOriginal(NbDocument.findLineNumber((StyledDocument) doc, startOffset)).createPart(NbDocument.findLineColumn((StyledDocument) doc, startOffset), hcs.getLength());
   6.152 +    }
   6.153 +    
   6.154 +    /** Adds new property (key-valkue pair) to resource object. 
   6.155 +     * @param key key value, if it is <code>null</code> nothing is done
   6.156 +     * @param value 'value' value, can be <code>null</code>
   6.157 +     * @param comment comment, can be <code>null</code>
   6.158 +     * @param forceNewValue if there already exists a key forces to reset its value
   6.159 +     */
   6.160 +    public ItemElem addProperty(PropertiesDataObject resource, Object key, Object value, String comment, boolean forceNewValue) {//TODO: force value, always create unique lables (see above)
   6.161 +        if(resource == null || key == null) return null;
   6.162 +
   6.163 +        String keyValue     = key.toString();
   6.164 +        String valueValue   = value == null ? "" : value.toString();
   6.165 +        String commentValue = comment;
   6.166 +        
   6.167 +        // write to bundle primary file
   6.168 +        BundleStructure bundleStructure = ((PropertiesDataObject)resource).getBundleStructure();
   6.169 +        PropertiesStructure propStructure = bundleStructure.getNthEntry(0).getHandler().getStructure();
   6.170 +        ItemElem item = propStructure.getItem(keyValue);
   6.171 +
   6.172 +        if(item == null) {
   6.173 +            // Item doesn't exist in this entry -> create it.
   6.174 +            propStructure.addItem(keyValue, valueValue, commentValue);
   6.175 +            item = propStructure.getItem(keyValue);
   6.176 +        } else if(!item.getValue().equals(valueValue) && forceNewValue) {
   6.177 +            item.setValue(valueValue);
   6.178 +            item.setComment(commentValue);
   6.179 +        }
   6.180 +        
   6.181 +        return item;
   6.182 +    }
   6.183 +    
   6.184 +}
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/editor.hints.i18n/src/org/netbeans/modules/editor/hints/i18n/layer.xml	Tue Sep 13 18:57:19 2005 +0000
     7.3 @@ -0,0 +1,32 @@
     7.4 +<?xml version="1.0" encoding="UTF-8"?>
     7.5 +<!--
     7.6 +                Sun Public License Notice
     7.7 +
     7.8 +The contents of this file are subject to the Sun Public License
     7.9 +Version 1.0 (the "License"). You may not use this file except in
    7.10 +compliance with the License. A copy of the License is available at
    7.11 +http://www.sun.com/
    7.12 +
    7.13 +The Original Code is NetBeans. The Initial Developer of the Original
    7.14 +Code is Sun Microsystems, Inc. Portions Copyright 1997-2005 Sun
    7.15 +Microsystems, Inc. All Rights Reserved.
    7.16 +-->
    7.17 +<!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.1//EN" "http://www.netbeans.org/dtds/filesystem-1_1.dtd">
    7.18 +<filesystem>
    7.19 +    <folder name="Editors">
    7.20 +        <folder name="text">
    7.21 +            <folder name="x-java">
    7.22 +                <folder name="Hints">
    7.23 +                    <file name="org-netbeans-modules-editor-hints-i18n-I18NChecker.instance"/>
    7.24 +                </folder>
    7.25 +            </folder>
    7.26 +            <!--Does not work very well:-->
    7.27 +<!--            <folder name="x-properties">
    7.28 +                <folder name="Hints">
    7.29 +                    <file name="org-netbeans-modules-editor-hints-i18n-BundleChecker.instance"/>
    7.30 +                </folder>
    7.31 +            </folder>-->
    7.32 +        </folder>
    7.33 +    </folder>
    7.34 +</filesystem>
    7.35 +