This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

View | Details | Raw Unified | Return to bug 59792
Collapse All | Expand All

(-)apisupport/harness/release/README (-6 / +9 lines)
Lines 561-568 Link Here
561
netbeans.home - location of "platform*" cluster of the NetBeans IDE installation
561
netbeans.home - location of "platform*" cluster of the NetBeans IDE installation
562
you are running. *Only defined* when you run an Ant script *inside* the IDE.
562
you are running. *Only defined* when you run an Ant script *inside* the IDE.
563
563
564
nbjdk.active - name of a Java platform (JDK) to use when building and
564
nbjdk.active [since 5.1 M1] - name of a Java platform (JDK) to use when building
565
running. Will try to load (e.g. from ${userdir}/build.properties, where Java
565
and running. Will try to load (e.g. from ${userdir}/build.properties, where Java
566
Platform Manager stores its information) the properties
566
Platform Manager stores its information) the properties
567
567
568
    nbjdk.home=${platforms.${nbjdk.active}.home}
568
    nbjdk.home=${platforms.${nbjdk.active}.home}
Lines 662-669 Link Here
662
test-unit-sys-prop.<NAME> - will set a system property <NAME> when running your
662
test-unit-sys-prop.<NAME> - will set a system property <NAME> when running your
663
unit tests.
663
unit tests.
664
664
665
tools.jar - set to location of tools.jar in active JDK. Useful in case your module
665
tools.jar [since 5.1 M1] - set to location of tools.jar in active JDK. Useful in
666
needs to compile against JDK-only classes. Meaningless on Mac OS X.
666
case your module needs to compile against JDK-only classes. Meaningless on Mac
667
OS X.
667
668
668
To support builds of JNLP based applications (described at 
669
To support builds of JNLP based applications (described at 
669
http://installer.netbeans.org/docs/jnlpInstaller.html) additional may be used 
670
http://installer.netbeans.org/docs/jnlpInstaller.html) additional may be used 
Lines 819-830 Link Here
819
branding.token - optional token defining an application branding.
820
branding.token - optional token defining an application branding.
820
821
821
disabled.clusters - comma-separated list of cluster names in the target platform
822
disabled.clusters - comma-separated list of cluster names in the target platform
822
(e.g. "ide6") which should be completely excluded from the application.
823
(e.g. "ide6") which should be completely excluded from the application. Since 5.1 M1,
824
should be stored in platform.properties, not project.properties.
823
825
824
disabled.modules - comma-separated list of code name bases of modules in the
826
disabled.modules - comma-separated list of code name bases of modules in the
825
target platform (e.g. "org.netbeans.modules.autoupdate") which should be
827
target platform (e.g. "org.netbeans.modules.autoupdate") which should be
826
excluded from the application. There is no need to specify modules already
828
excluded from the application. There is no need to specify modules already
827
excluded by ${disabled.clusters}.
829
excluded by ${disabled.clusters}. Since 5.1 M1, should be stored in
830
platform.properties, not project.properties.
828
831
829
modules - list of contained modules. Path format; entries resolved against the
832
modules - list of contained modules. Path format; entries resolved against the
830
suite directory as needed.
833
suite directory as needed.
(-)apisupport/harness/release/build.xml (-1 / +14 lines)
Lines 42-49 Link Here
42
    </target>
42
    </target>
43
43
44
    <target name="build-init" depends="basic-init,nbm-license-init">
44
    <target name="build-init" depends="basic-init,nbm-license-init">
45
        <condition property="public.package.jar.dir" value="${suite.dir}/build/public-package-jars">
46
            <isset property="suite.dir"/>
47
        </condition>
48
        <property name="public.package.jar.dir" location="build/public-package-jars"/>
49
        <mkdir dir="${public.package.jar.dir}"/>
45
        <!-- Similar to projectized.xml but does not try to set NBM homepage/distribution, nor is javahelp.excludes predefined, but javadoc.title is defaulted. -->
50
        <!-- Similar to projectized.xml but does not try to set NBM homepage/distribution, nor is javahelp.excludes predefined, but javadoc.title is defaulted. -->
46
        <parseprojectxml project="." publicpackagesproperty="public.packages" friendsproperty="friends" javadocpackagesproperty="module.javadoc.packages" idedependenciesproperty="ide.dependencies" moduledependenciesproperty="module.dependencies" moduleclasspathproperty="module.classpath" classpathextensionsproperty="class.path.extensions"/>
51
        <parseprojectxml
52
            project="."
53
            publicpackagesproperty="public.packages"
54
            friendsproperty="friends"
55
            javadocpackagesproperty="module.javadoc.packages"
56
            moduledependenciesproperty="module.dependencies"
57
            moduleclasspathproperty="module.classpath"
58
            publicpackagejardir="${public.package.jar.dir}"
59
            classpathextensionsproperty="class.path.extensions"/>
47
        <condition property="is.regular">
60
        <condition property="is.regular">
48
            <not>
61
            <not>
49
                <or>
62
                <or>
(-)apisupport/project/src/org/netbeans/modules/apisupport/project/ui/customizer/ModuleProperties.java (-1 / +1 lines)
Lines 128-134 Link Here
128
        if (def == null) {
128
        if (def == null) {
129
            def = ""; // NOI18N
129
            def = ""; // NOI18N
130
        }
130
        }
131
        if (def.equals(value)) {
131
        if (value == null || def.equals(value)) {
132
            getProjectProperties().remove(key);
132
            getProjectProperties().remove(key);
133
        } else {
133
        } else {
134
            getProjectProperties().setProperty(key, value);
134
            getProjectProperties().setProperty(key, value);
(-)apisupport/project/src/org/netbeans/modules/apisupport/project/ui/customizer/SuiteProperties.java (-12 / +19 lines)
Lines 24-29 Link Here
24
import org.netbeans.modules.apisupport.project.ui.customizer.CustomizerComponentFactory.SuiteSubModulesListModel;
24
import org.netbeans.modules.apisupport.project.ui.customizer.CustomizerComponentFactory.SuiteSubModulesListModel;
25
import org.netbeans.modules.apisupport.project.universe.NbPlatform;
25
import org.netbeans.modules.apisupport.project.universe.NbPlatform;
26
import org.netbeans.spi.project.support.ant.AntProjectHelper;
26
import org.netbeans.spi.project.support.ant.AntProjectHelper;
27
import org.netbeans.spi.project.support.ant.EditableProperties;
27
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
28
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
28
29
29
/**
30
/**
Lines 170-189 Link Here
170
            SuiteUtils.replaceSubModules(this);
171
            SuiteUtils.replaceSubModules(this);
171
        }
172
        }
172
        
173
        
173
        if (changedDisabledModules) {
174
        if (changedDisabledModules || changedDisabledClusters) {
174
            String[] separated = (String[])disabledModules.clone();
175
            EditableProperties ep = getHelper().getProperties("nbproject/platform.properties"); // NOI18N
175
            for (int i = 0; i < disabledModules.length - 1; i++) {
176
            if (changedDisabledModules) {
176
                separated[i] = disabledModules[i] + ',';
177
                String[] separated = (String[]) disabledModules.clone();
178
                for (int i = 0; i < disabledModules.length - 1; i++) {
179
                    separated[i] = disabledModules[i] + ',';
180
                }
181
                ep.setProperty(DISABLED_MODULES_PROPERTY, separated);
182
                // Do not want it left in project.properties if it was there before (from 5.0):
183
                setProperty(DISABLED_MODULES_PROPERTY, (String) null);
177
            }
184
            }
178
            setProperty(DISABLED_MODULES_PROPERTY, separated);
185
            if (changedDisabledClusters) {
179
        }
186
                String[] separated = (String[]) disabledClusters.clone();
180
        
187
                for (int i = 0; i < disabledClusters.length - 1; i++) {
181
        if (changedDisabledClusters) {
188
                    separated[i] = disabledClusters[i] + ',';
182
            String[] separated = (String[])disabledClusters.clone();
189
                }
183
            for (int i = 0; i < disabledClusters.length - 1; i++) {
190
                ep.setProperty(DISABLED_CLUSTERS_PROPERTY, separated);
184
                separated[i] = disabledClusters[i] + ',';
191
                setProperty(DISABLED_CLUSTERS_PROPERTY, (String) null);
185
            }
192
            }
186
            setProperty(DISABLED_CLUSTERS_PROPERTY, separated);
193
            getHelper().putProperties("nbproject/platform.properties", ep); // NOI18N
187
        }
194
        }
188
        
195
        
189
        super.storeProperties();
196
        super.storeProperties();
(-)nbbuild/antsrc/org/netbeans/nbbuild/JarWithModuleAttributes.java (-13 / +3 lines)
Lines 29-35 Link Here
29
29
30
/**
30
/**
31
 * Task just like <jar> but predefines various module attributes.
31
 * Task just like <jar> but predefines various module attributes.
32
 * Would not be necessary if this were implemented: http://issues.apache.org/bugzilla/show_bug.cgi?id=34366
33
 * Cf. projectized.xml#jar
32
 * Cf. projectized.xml#jar
34
 * @author Jesse Glick
33
 * @author Jesse Glick
35
 */
34
 */
Lines 72-81 Link Here
72
            if (cp != null) {
71
            if (cp != null) {
73
                added.addConfiguredAttribute(new Manifest.Attribute("Class-Path", cp));
72
                added.addConfiguredAttribute(new Manifest.Attribute("Class-Path", cp));
74
            }
73
            }
75
            String ideDeps = getProject().getProperty("ide.dependencies");
76
            if (ideDeps != null) {
77
                added.addConfiguredAttribute(new Manifest.Attribute("OpenIDE-Module-IDE-Dependencies", ideDeps));
78
            }
79
            String moduleDeps = getProject().getProperty("module.dependencies");
74
            String moduleDeps = getProject().getProperty("module.dependencies");
80
            if (moduleDeps != null) {
75
            if (moduleDeps != null) {
81
                added.addConfiguredAttribute(new Manifest.Attribute("OpenIDE-Module-Module-Dependencies", moduleDeps));
76
                added.addConfiguredAttribute(new Manifest.Attribute("OpenIDE-Module-Module-Dependencies", moduleDeps));
Lines 130-142 Link Here
130
                    }
125
                    }
131
                }
126
                }
132
                SortedMap/*<String,Integer>*/ additions = new TreeMap();
127
                SortedMap/*<String,Integer>*/ additions = new TreeMap();
133
                String[] deps = {ideDeps, moduleDeps};
128
                if (moduleDeps != null) {
134
                for (int i = 0; i < 2; i++) {
129
                    String[] individualDeps = COMMA_SPACE.split(moduleDeps);
135
                    String dep = deps[i];
136
                    if (dep == null) {
137
                        continue;
138
                    }
139
                    String[] individualDeps = COMMA_SPACE.split(dep);
140
                    for (int j = 0; j < individualDeps.length; j++) {
130
                    for (int j = 0; j < individualDeps.length; j++) {
141
                        Matcher m = IMPL_DEP.matcher(individualDeps[j]);
131
                        Matcher m = IMPL_DEP.matcher(individualDeps[j]);
142
                        if (m.matches()) {
132
                        if (m.matches()) {
Lines 170-176 Link Here
170
                } else {
160
                } else {
171
                    added.addConfiguredAttribute(new Manifest.Attribute("OpenIDE-Module-Specification-Version", specVersBase));
161
                    added.addConfiguredAttribute(new Manifest.Attribute("OpenIDE-Module-Specification-Version", specVersBase));
172
                }
162
                }
173
            } else if ((ideDeps != null && ideDeps.indexOf('=') != -1) || (moduleDeps != null && moduleDeps.indexOf('=') != -1)) {
163
            } else if (moduleDeps != null && moduleDeps.indexOf('=') != -1) {
174
                getProject().log("Warning: in " + ownCnb + ", not using spec.version.base, yet declaring implementation dependencies; may lead to problems with Auto Update", Project.MSG_WARN);
164
                getProject().log("Warning: in " + ownCnb + ", not using spec.version.base, yet declaring implementation dependencies; may lead to problems with Auto Update", Project.MSG_WARN);
175
            } else if (implVers != null) {
165
            } else if (implVers != null) {
176
                try {
166
                try {
(-)nbbuild/antsrc/org/netbeans/nbbuild/ModuleListParser.java (-3 / +18 lines)
Lines 294-300 Link Here
294
            String cnb2 = XMLUtil.findText(cnbEl2);
294
            String cnb2 = XMLUtil.findText(cnbEl2);
295
            prereqs.add(cnb2);
295
            prereqs.add(cnb2);
296
        }
296
        }
297
        Entry entry = new Entry(cnb, jar, (File[]) exts.toArray(new File[exts.size()]), dir, path, (String[]) prereqs.toArray(new String[prereqs.size()]));
297
        String cluster = fakeproj.getProperty("cluster.dir"); // may be null
298
        Entry entry = new Entry(cnb, jar, (File[]) exts.toArray(new File[exts.size()]), dir, path, (String[]) prereqs.toArray(new String[prereqs.size()]), cluster);
298
        if (entries.containsKey(cnb)) {
299
        if (entries.containsKey(cnb)) {
299
            throw new IOException("Duplicated module " + cnb + ": found in " + entries.get(cnb) + " and " + entry);
300
            throw new IOException("Duplicated module " + cnb + ": found in " + entries.get(cnb) + " and " + entry);
300
        } else {
301
        } else {
Lines 390-396 Link Here
390
                                exts[l] = new File(dir, pieces[l].replace('/', File.separatorChar));
391
                                exts[l] = new File(dir, pieces[l].replace('/', File.separatorChar));
391
                            }
392
                            }
392
                        }
393
                        }
393
                        Entry entry = new Entry(codenamebase, m, exts, dir, null, null);
394
                        Entry entry = new Entry(codenamebase, m, exts, dir, null, null, clusters[i].getName());
394
                        if (entries.containsKey(codenamebase)) {
395
                        if (entries.containsKey(codenamebase)) {
395
                            throw new IOException("Duplicated module " + codenamebase + ": found in " + entries.get(codenamebase) + " and " + entry);
396
                            throw new IOException("Duplicated module " + codenamebase + ": found in " + entries.get(codenamebase) + " and " + entry);
396
                        } else {
397
                        } else {
Lines 550-563 Link Here
550
        private final File sourceLocation;
551
        private final File sourceLocation;
551
        private final String netbeansOrgPath;
552
        private final String netbeansOrgPath;
552
        private final String[] buildPrerequisites;
553
        private final String[] buildPrerequisites;
554
        private final String clusterName;
553
        
555
        
554
        Entry(String cnb, File jar, File[] classPathExtensions, File sourceLocation, String netbeansOrgPath, String[] buildPrerequisites) {
556
        Entry(String cnb, File jar, File[] classPathExtensions, File sourceLocation, String netbeansOrgPath, String[] buildPrerequisites, String clusterName) {
555
            this.cnb = cnb;
557
            this.cnb = cnb;
556
            this.jar = jar;
558
            this.jar = jar;
557
            this.classPathExtensions = classPathExtensions;
559
            this.classPathExtensions = classPathExtensions;
558
            this.sourceLocation = sourceLocation;
560
            this.sourceLocation = sourceLocation;
559
            this.netbeansOrgPath = netbeansOrgPath;
561
            this.netbeansOrgPath = netbeansOrgPath;
560
            this.buildPrerequisites = buildPrerequisites;
562
            this.buildPrerequisites = buildPrerequisites;
563
            this.clusterName = clusterName;
561
        }
564
        }
562
        
565
        
563
        /**
566
        /**
Lines 594-599 Link Here
594
         */
597
         */
595
        public String[] getBuildPrerequisites() {
598
        public String[] getBuildPrerequisites() {
596
            return buildPrerequisites;
599
            return buildPrerequisites;
600
        }
601
        
602
        /**
603
         * Return the name of the cluster in which this module resides.
604
         * If this entry represents an external module in source form,
605
         * then the cluster will be null. If the module represents a netbeans.org
606
         * module or a binary module in a platform, then the cluster name will
607
         * be the (base) name of the directory containing the "modules" subdirectory
608
         * (sometimes "lib" or "core") where the JAR is.
609
         */
610
        public String getClusterName() {
611
            return clusterName;
597
        }
612
        }
598
        
613
        
599
        public String toString() {
614
        public String toString() {
(-)nbbuild/antsrc/org/netbeans/nbbuild/ParseProjectXml.java (-100 / +246 lines)
Lines 20-32 Link Here
20
import java.io.IOException;
20
import java.io.IOException;
21
import java.io.InputStream;
21
import java.io.InputStream;
22
import java.io.OutputStream;
22
import java.io.OutputStream;
23
import java.io.OutputStreamWriter;
24
import java.io.Writer;
25
import java.util.ArrayList;
23
import java.util.ArrayList;
24
import java.util.Arrays;
25
import java.util.HashSet;
26
import java.util.Hashtable;
26
import java.util.Hashtable;
27
import java.util.Iterator;
27
import java.util.Iterator;
28
import java.util.List;
28
import java.util.List;
29
import java.util.Set;
30
import java.util.StringTokenizer;
31
import java.util.jar.Attributes;
29
import java.util.jar.JarFile;
32
import java.util.jar.JarFile;
33
import java.util.regex.Pattern;
34
import java.util.zip.CRC32;
35
import java.util.zip.ZipEntry;
36
import java.util.zip.ZipInputStream;
37
import java.util.zip.ZipOutputStream;
30
import org.apache.tools.ant.BuildException;
38
import org.apache.tools.ant.BuildException;
31
import org.apache.tools.ant.Project;
39
import org.apache.tools.ant.Project;
32
import org.apache.tools.ant.Task;
40
import org.apache.tools.ant.Task;
Lines 98-113 Link Here
98
        javadocPackagesProperty = s;
106
        javadocPackagesProperty = s;
99
    }
107
    }
100
108
101
    private String ideDependenciesProperty;
102
    /**
103
     * Set the property to set a list of
104
     * OpenIDE-Module-IDE-Dependencies to, based on the list of stated
105
     * run-time dependencies.
106
     */
107
    public void setIdeDependenciesProperty(String s) {
108
        ideDependenciesProperty = s;
109
    }
110
111
    private String moduleDependenciesProperty;
109
    private String moduleDependenciesProperty;
112
    /**
110
    /**
113
     * Set the property to set a list of
111
     * Set the property to set a list of
Lines 154-159 Link Here
154
        moduleClassPathProperty = s;
152
        moduleClassPathProperty = s;
155
    }
153
    }
156
    
154
    
155
    private File publicPackageJarDir;
156
    /**
157
     * Set the location of a directory in which to look for and create
158
     * JARs containing just the public packages of appropriate
159
     * compile-time dependencies.
160
     */
161
    public void setPublicPackageJarDir(File d) {
162
        publicPackageJarDir = d;
163
    }
164
    
157
    private String classPathExtensionsProperty;
165
    private String classPathExtensionsProperty;
158
    /**
166
    /**
159
     * Set the property to set the declared Class-Path attribute to.
167
     * Set the property to set the declared Class-Path attribute to.
Lines 248-283 Link Here
248
                }
256
                }
249
            }
257
            }
250
            ModuleListParser modules = null;
258
            ModuleListParser modules = null;
259
            Dep[] deps = null;
251
            if (moduleDependenciesProperty != null || moduleClassPathProperty != null) {
260
            if (moduleDependenciesProperty != null || moduleClassPathProperty != null) {
252
                String nball = getProject().getProperty("nb_all");
261
                String nball = getProject().getProperty("nb_all");
253
                Hashtable properties = getProject().getProperties();
262
                Hashtable properties = getProject().getProperties();
254
                properties.put("project", project.getAbsolutePath());
263
                properties.put("project", project.getAbsolutePath());
255
                modules = new ModuleListParser(properties, getModuleType(pDoc), getProject());
264
                modules = new ModuleListParser(properties, getModuleType(pDoc), getProject());
265
                deps = getDeps(pDoc, modules);
256
            }
266
            }
257
            if (ideDependenciesProperty != null || moduleDependenciesProperty != null) {
267
            if (moduleDependenciesProperty != null) {
258
                Dep[] deps = getDeps(pDoc);
259
                if (ideDependenciesProperty != null) {
260
                    Dep ide = null;
261
                    for (int i = 0; i < deps.length; i++) {
262
                        if (deps[i].codenamebase.equals("IDE")) {
263
                            ide = deps[i];
264
                            break;
265
                        }
266
                    }
267
                    if (ide != null) {
268
                        define(ideDependenciesProperty, ide.toString(modules));
269
                    }
270
                }
271
                if (moduleDependenciesProperty != null) {
268
                if (moduleDependenciesProperty != null) {
272
                    StringBuffer b = new StringBuffer();
269
                    StringBuffer b = new StringBuffer();
273
                    for (int i = 0; i < deps.length; i++) {
270
                    for (int i = 0; i < deps.length; i++) {
274
                        if (deps[i].codenamebase.equals("IDE")) {
271
                        if (!deps[i].run) {
275
                            continue;
272
                            continue;
276
                        }
273
                        }
277
                        if (b.length() > 0) {
274
                        if (b.length() > 0) {
278
                            b.append(", ");
275
                            b.append(", ");
279
                        }
276
                        }
280
                        b.append(deps[i].toString(modules));
277
                        b.append(deps[i]);
281
                    }
278
                    }
282
                    if (b.length() > 0) {
279
                    if (b.length() > 0) {
283
                        define(moduleDependenciesProperty, b.toString());
280
                        define(moduleDependenciesProperty, b.toString());
Lines 293-299 Link Here
293
                define(codeNameBaseSlashesProperty, cnb.replace('.', '/'));
290
                define(codeNameBaseSlashesProperty, cnb.replace('.', '/'));
294
            }
291
            }
295
            if (moduleClassPathProperty != null) {
292
            if (moduleClassPathProperty != null) {
296
                String cp = computeClasspath(pDoc, modules);
293
                String cp = computeClasspath(pDoc, modules, deps);
297
                if (cp != null) {
294
                if (cp != null) {
298
                    define(moduleClassPathProperty, cp);
295
                    define(moduleClassPathProperty, cp);
299
                }
296
                }
Lines 419-430 Link Here
419
    }
416
    }
420
417
421
    private final class Dep {
418
    private final class Dep {
422
        /** will be e.g. org.netbeans.modules.form or IDE */
419
        private final ModuleListParser modules;
420
        /** will be e.g. org.netbeans.modules.form */
423
        public String codenamebase;
421
        public String codenamebase;
424
        public String release = null;
422
        public String release = null;
425
        public String spec = null;
423
        public String spec = null;
426
        public boolean impl = false;
424
        public boolean impl = false;
427
        public String toString(ModuleListParser modules) throws IOException, BuildException {
425
        public boolean compile = false;
426
        public boolean run = false;
427
        
428
        public Dep(ModuleListParser modules) {
429
            this.modules = modules;
430
        }
431
        
432
        public String toString() throws BuildException {
428
            StringBuffer b = new StringBuffer(codenamebase);
433
            StringBuffer b = new StringBuffer(codenamebase);
429
            if (release != null) {
434
            if (release != null) {
430
                b.append('/');
435
                b.append('/');
Lines 445-465 Link Here
445
            }
450
            }
446
            return b.toString();
451
            return b.toString();
447
        }
452
        }
448
        private String implementationVersionOf(ModuleListParser modules, String cnb) throws IOException {
453
        
449
            File jar = computeClasspathModuleLocation(modules, cnb);
454
        private String implementationVersionOf(ModuleListParser modules, String cnb) throws BuildException {
455
            File jar = computeClasspathModuleLocation(modules, cnb, null, null);
450
            if (!jar.isFile()) {
456
            if (!jar.isFile()) {
451
                throw new BuildException("No such classpath entry: " + jar, getLocation());
457
                throw new BuildException("No such classpath entry: " + jar, getLocation());
452
            }
458
            }
453
            JarFile jarFile = new JarFile(jar, false);
454
            try {
459
            try {
455
                return jarFile.getManifest().getMainAttributes().getValue("OpenIDE-Module-Implementation-Version");
460
                JarFile jarFile = new JarFile(jar, false);
456
            } finally {
461
                try {
457
                jarFile.close();
462
                    return jarFile.getManifest().getMainAttributes().getValue("OpenIDE-Module-Implementation-Version");
463
                } finally {
464
                    jarFile.close();
465
                }
466
            } catch (IOException e) {
467
                throw new BuildException(e, getLocation());
468
            }
469
        }
470
471
        private boolean matches(Attributes attr) {
472
            if (release != null) {
473
                String givenCodeName = attr.getValue("OpenIDE-Module");
474
                int slash = givenCodeName.indexOf('/');
475
                int givenRelease = -1;
476
                if (slash != -1) {
477
                    assert codenamebase.equals(givenCodeName.substring(0, slash));
478
                    givenRelease = Integer.parseInt(givenCodeName.substring(slash + 1));
479
                }
480
                int dash = release.indexOf('-');
481
                if (dash == -1) {
482
                    if (Integer.parseInt(release) != givenRelease) {
483
                        return false;
484
                    }
485
                } else {
486
                    int lower = Integer.parseInt(release.substring(0, dash));
487
                    int upper = Integer.parseInt(release.substring(dash + 1));
488
                    if (givenRelease < lower || givenRelease > upper) {
489
                        return false;
490
                    }
491
                }
492
            }
493
            if (spec != null) {
494
                String givenSpec = attr.getValue("OpenIDE-Module-Specification-Version");
495
                if (givenSpec == null) {
496
                    return false;
497
                }
498
                // XXX cannot use org.openide.modules.SpecificationVersion from here
499
                int[] specVals = digitize(spec);
500
                int[] givenSpecVals = digitize(givenSpec);
501
                int len1 = specVals.length;
502
                int len2 = givenSpecVals.length;
503
                int max = Math.max(len1, len2);
504
                for (int i = 0; i < max; i++) {
505
                    int d1 = ((i < len1) ? specVals[i] : 0);
506
                    int d2 = ((i < len2) ? givenSpecVals[i] : 0);
507
                    if (d1 < d2) {
508
                        break;
509
                    } else if (d1 > d2) {
510
                        return false;
511
                    }
512
                }
458
            }
513
            }
514
            if (impl) {
515
                if (attr.getValue("OpenIDE-Module-Implementation-Version") == null) {
516
                    return false;
517
                }
518
            }
519
            return true;
520
        }
521
        private int[] digitize(String spec) throws NumberFormatException {
522
            StringTokenizer tok = new StringTokenizer(spec, ".");
523
            int len = tok.countTokens();
524
            int[] digits = new int[len];
525
            for (int i = 0; i < len; i++) {
526
                digits[i] = Integer.parseInt(tok.nextToken());
527
            }
528
            return digits;
459
        }
529
        }
530
        
460
    }
531
    }
461
532
462
    private Dep[] getDeps(Document pDoc) throws BuildException {
533
    private Dep[] getDeps(Document pDoc, ModuleListParser modules) throws BuildException {
463
        Element cfg = getConfig(pDoc);
534
        Element cfg = getConfig(pDoc);
464
        Element md = XMLUtil.findElement(cfg, "module-dependencies", NBM_NS);
535
        Element md = XMLUtil.findElement(cfg, "module-dependencies", NBM_NS);
465
        if (md == null) {
536
        if (md == null) {
Lines 470-476 Link Here
470
        Iterator it = l.iterator();
541
        Iterator it = l.iterator();
471
        while (it.hasNext()) {
542
        while (it.hasNext()) {
472
            Element dep = (Element)it.next();
543
            Element dep = (Element)it.next();
473
            Dep d = new Dep();
544
            Dep d = new Dep(modules);
474
            Element cnb = XMLUtil.findElement(dep, "code-name-base", NBM_NS);
545
            Element cnb = XMLUtil.findElement(dep, "code-name-base", NBM_NS);
475
            if (cnb == null) {
546
            if (cnb == null) {
476
                throw new BuildException("No <code-name-base>", getLocation());
547
                throw new BuildException("No <code-name-base>", getLocation());
Lines 479-490 Link Here
479
            if (t == null) {
550
            if (t == null) {
480
                throw new BuildException("No text in <code-name-base>", getLocation());
551
                throw new BuildException("No text in <code-name-base>", getLocation());
481
            }
552
            }
482
            if (t.equals("org.openide")) {
483
                t = "IDE";
484
            }
485
            d.codenamebase = t;
553
            d.codenamebase = t;
486
            Element rd = XMLUtil.findElement(dep, "run-dependency", NBM_NS);
554
            Element rd = XMLUtil.findElement(dep, "run-dependency", NBM_NS);
487
            if (rd != null) {
555
            if (rd != null) {
556
                d.run = true;
488
                Element rv = XMLUtil.findElement(rd, "release-version", NBM_NS);
557
                Element rv = XMLUtil.findElement(rd, "release-version", NBM_NS);
489
                if (rv != null) {
558
                if (rv != null) {
490
                    t = XMLUtil.findText(rv);
559
                    t = XMLUtil.findText(rv);
Lines 501-513 Link Here
501
                    }
570
                    }
502
                    d.spec = t;
571
                    d.spec = t;
503
                }
572
                }
504
                // <implementation-version> added in /2:
505
                Element iv = XMLUtil.findElement(rd, "implementation-version", NBM_NS);
573
                Element iv = XMLUtil.findElement(rd, "implementation-version", NBM_NS);
506
                if (iv != null) {
574
                if (iv != null) {
507
                    d.impl = true;
575
                    d.impl = true;
508
                }
576
                }
509
                deps.add(d);
510
            }
577
            }
578
            d.compile = XMLUtil.findElement(dep, "compile-dependency", NBM_NS) != null;
579
            deps.add(d);
511
        }
580
        }
512
        return (Dep[])deps.toArray(new Dep[deps.size()]);
581
        return (Dep[])deps.toArray(new Dep[deps.size()]);
513
    }
582
    }
Lines 536-608 Link Here
536
        }
605
        }
537
    }
606
    }
538
607
539
    private String computeClasspath(Document pDoc, ModuleListParser modules) throws BuildException, IOException, SAXException {
608
    private String computeClasspath(Document pDoc, ModuleListParser modules, Dep[] deps) throws BuildException, IOException, SAXException {
540
        Element data = getConfig(pDoc);
609
        String myCnb = getCodeNameBase(pDoc);
541
        Element moduleDependencies = XMLUtil.findElement(data, "module-dependencies", NBM_NS);
542
        List/*<Element>*/ deps = XMLUtil.findSubElements(moduleDependencies);
543
        StringBuffer cp = new StringBuffer();
610
        StringBuffer cp = new StringBuffer();
544
        Iterator it = deps.iterator();
611
        String excludedClustersProp = getProject().getProperty("disabled.clusters");
545
        while (it.hasNext()) {
612
        Set/*<String>*/ excludedClusters = excludedClustersProp != null ?
546
            Element dep = (Element)it.next();
613
            new HashSet(Arrays.asList(excludedClustersProp.split(" *, *"))) :
547
            if (XMLUtil.findElement(dep, "compile-dependency", NBM_NS) == null) {
614
            null;
615
        String excludedModulesProp = getProject().getProperty("disabled.modules");
616
        Set/*<String>*/ excludedModules = excludedModulesProp != null ?
617
            new HashSet(Arrays.asList(excludedModulesProp.split(" *, *"))) :
618
            null;
619
        for (int i = 0; i < deps.length; i++) {
620
            Dep dep = deps[i];
621
            if (!dep.compile) {
548
                continue;
622
                continue;
549
            }
623
            }
550
            if (cp.length() > 0) {
624
            String cnb = dep.codenamebase;
551
                cp.append(':');
625
            File depJar = computeClasspathModuleLocation(modules, cnb, excludedClusters, excludedModules);
626
            
627
            Attributes attr;
628
            JarFile jarFile = new JarFile(depJar, false);
629
            try {
630
                attr = jarFile.getManifest().getMainAttributes();
631
            } finally {
632
                jarFile.close();
552
            }
633
            }
553
            Element cnbEl = XMLUtil.findElement(dep, "code-name-base", NBM_NS);
554
            String cnb = XMLUtil.findText(cnbEl);
555
            
634
            
556
            if ("org.openide".equals (cnb)) {
635
            if (!dep.matches(attr)) { // #68631
557
                // XXX special handling of splited openide, can be removed
636
                throw new BuildException("Cannot compile against a module: " + depJar + " because of dependency: " + dep, getLocation());
558
                // after 5.0 release or when apisupport improved
559
                getProject ().log ("Do not depend on org.openide anymore, depend on its libraries. Update " + getProjectFile (), getProject().MSG_WARN);
560
                
561
                cp.append (computeClasspathModuleLocation (modules, "org.openide.util").getAbsolutePath ());
562
                cp.append(File.pathSeparatorChar);
563
                cp.append (computeClasspathModuleLocation (modules, "org.openide.util.enumerations").getAbsolutePath ());
564
                cp.append(File.pathSeparatorChar);
565
                cp.append (computeClasspathModuleLocation (modules, "org.openide.filesystems").getAbsolutePath ());
566
                cp.append(File.pathSeparatorChar);
567
                cp.append (computeClasspathModuleLocation (modules, "org.openide.modules").getAbsolutePath ());
568
                cp.append(File.pathSeparatorChar);
569
                cp.append (computeClasspathModuleLocation (modules, "org.openide.awt").getAbsolutePath ());
570
                cp.append(File.pathSeparatorChar);
571
                cp.append (computeClasspathModuleLocation (modules, "org.openide.dialogs").getAbsolutePath ());
572
                cp.append(File.pathSeparatorChar);
573
                cp.append (computeClasspathModuleLocation (modules, "org.openide.loaders").getAbsolutePath ());
574
                cp.append(File.pathSeparatorChar);
575
                cp.append (computeClasspathModuleLocation (modules, "org.openide.nodes").getAbsolutePath ());
576
                cp.append(File.pathSeparatorChar);
577
                cp.append (computeClasspathModuleLocation (modules, "org.openide.explorer").getAbsolutePath ());
578
                cp.append(File.pathSeparatorChar);
579
                cp.append (computeClasspathModuleLocation (modules, "org.openide.actions").getAbsolutePath ());
580
                cp.append(File.pathSeparatorChar);
581
                cp.append (computeClasspathModuleLocation (modules, "org.openide.text").getAbsolutePath ());
582
                cp.append(File.pathSeparatorChar);
583
                cp.append (computeClasspathModuleLocation (modules, "org.openide.windows").getAbsolutePath ());
584
                cp.append(File.pathSeparatorChar);
585
                cp.append (computeClasspathModuleLocation (modules, "org.openide.options").getAbsolutePath ());
586
                cp.append(File.pathSeparatorChar);
587
                cp.append (computeClasspathModuleLocation (modules, "org.openide.compat").getAbsolutePath ());
588
                
589
                continue;
590
            }
637
            }
591
                        
638
592
            cp.append(computeClasspathModuleLocation(modules, cnb).getAbsolutePath());
639
            List/*<File>*/ additions = new ArrayList();
640
            additions.add(depJar);
593
            // #52354: look for <class-path-extension>s in dependent modules.
641
            // #52354: look for <class-path-extension>s in dependent modules.
594
            ModuleListParser.Entry entry = modules.findByCodeNameBase(cnb);
642
            ModuleListParser.Entry entry = modules.findByCodeNameBase(cnb);
595
            if (entry != null) {
643
            if (entry != null) {
596
                File[] exts = entry.getClassPathExtensions();
644
                File[] exts = entry.getClassPathExtensions();
597
                for (int i = 0; i < exts.length; i++) {
645
                for (int j = 0; j < exts.length; j++) {
646
                    additions.add(exts[j]);
647
                }
648
            }
649
            
650
            if (!dep.impl) {
651
                String friends = attr.getValue("OpenIDE-Module-Friends");
652
                if (friends != null && !Arrays.asList(friends.split(" *, *")).contains(myCnb)) {
653
                    throw new BuildException("The module " + myCnb + " is not a friend of " + depJar, getLocation());
654
                }
655
                String pubpkgs = attr.getValue("OpenIDE-Module-Public-Packages");
656
                if ("-".equals(pubpkgs)) {
657
                    throw new BuildException("The module " + depJar + " has no public packages and so cannot be compiled against", getLocation());
658
                } else if (pubpkgs != null) {
659
                    File splitJar = createPublicPackageJar(additions, pubpkgs, publicPackageJarDir, cnb);
660
                    additions.clear();
661
                    additions.add(splitJar);
662
                }
663
            }
664
            
665
            Iterator it = additions.iterator();
666
            while (it.hasNext()) {
667
                if (cp.length() > 0) {
598
                    cp.append(':');
668
                    cp.append(':');
599
                    cp.append(exts[i].getAbsolutePath());
600
                }
669
                }
670
                cp.append(((File) it.next()).getAbsolutePath());
601
            }
671
            }
602
        }
672
        }
603
        // Also look for <class-path-extension>s for myself and put them in my own classpath.
673
        // Also look for <class-path-extension>s for myself and put them in my own classpath.
604
        String cnb = getCodeNameBase(pDoc);
674
        ModuleListParser.Entry entry = modules.findByCodeNameBase(myCnb);
605
        ModuleListParser.Entry entry = modules.findByCodeNameBase(cnb);
606
        assert entry != null;
675
        assert entry != null;
607
        File[] exts = entry.getClassPathExtensions();
676
        File[] exts = entry.getClassPathExtensions();
608
        for (int i = 0; i < exts.length; i++) {
677
        for (int i = 0; i < exts.length; i++) {
Lines 612-625 Link Here
612
        return cp.toString();
681
        return cp.toString();
613
    }
682
    }
614
    
683
    
615
    private File computeClasspathModuleLocation(ModuleListParser modules, String cnb) throws BuildException {
684
    private File computeClasspathModuleLocation(ModuleListParser modules, String cnb, Set/*<String>*/ excludedClusters, Set/*<String>*/ excludedModules) throws BuildException {
616
        ModuleListParser.Entry module = modules.findByCodeNameBase(cnb);
685
        ModuleListParser.Entry module = modules.findByCodeNameBase(cnb);
617
        if (module == null) {
686
        if (module == null) {
618
            throw new BuildException("No dependent module " + cnb, getLocation());
687
            throw new BuildException("No dependent module " + cnb, getLocation());
619
        }
688
        }
620
        // XXX if that module is projectized, check its public
689
        if (excludedClusters != null && excludedClusters.contains(module.getClusterName())) { // #68716
621
        // packages; if it has none, halt the build, unless we are
690
            throw new BuildException("Module " + cnb + " part of cluster " + module.getClusterName() + " which is excluded from the target platform", getLocation());
622
        // declaring an impl dependency
691
        }
692
        if (excludedModules != null && excludedModules.contains(cnb)) { // again #68716
693
            throw new BuildException("Module " + cnb + " excluded from the target platform", getLocation());
694
        }
623
        return module.getJar();
695
        return module.getJar();
624
    }
696
    }
625
    
697
    
Lines 646-651 Link Here
646
            list.append(reltext);
718
            list.append(reltext);
647
        }
719
        }
648
        return list != null ? list.toString() : null;
720
        return list != null ? list.toString() : null;
721
    }
722
723
    /**
724
     * Create a compact JAR containing only classes in public packages.
725
     * Forces the compiler to honor public package restrictions.
726
     * @see "#59792"
727
     */
728
    private File createPublicPackageJar(List/*<File>*/ jars, String pubpkgs, File dir, String cnb) throws IOException {
729
        File ppjar = new File(dir, cnb.replace('.', '-') + ".jar");
730
        if (ppjar.exists()) {
731
            // Check if it is up to date first. Must be as new as any input JAR.
732
            boolean uptodate = true;
733
            long stamp = ppjar.lastModified();
734
            Iterator it = jars.iterator();
735
            while (it.hasNext()) {
736
                File jar = (File) it.next();
737
                if (jar.lastModified() > stamp) {
738
                    uptodate = false;
739
                    break;
740
                }
741
            }
742
            if (uptodate) {
743
                log("Distilled " + ppjar + " was already up to date", Project.MSG_VERBOSE);
744
                return ppjar;
745
            }
746
        }
747
        log("Distilling " + ppjar + " from " + jars);
748
        String corePattern = pubpkgs.
749
                replaceAll(" +", "").
750
                replaceAll("\\.", "/").
751
                replaceAll(",", "|").
752
                replaceAll("\\*\\*", "(.+/)?").
753
                replaceAll("\\*", "");
754
        Pattern p = Pattern.compile("(" + corePattern + ")[^/]+\\.class");
755
        // E.g.: (org/netbeans/api/foo/|org/netbeans/spi/foo/)[^/]+\.class
756
        OutputStream os = new FileOutputStream(ppjar);
757
        try {
758
            ZipOutputStream zos = new ZipOutputStream(os);
759
            Iterator it = jars.iterator();
760
            while (it.hasNext()) {
761
                File jar = (File) it.next();
762
                InputStream is = new FileInputStream(jar);
763
                try {
764
                    ZipInputStream zis = new ZipInputStream(is);
765
                    ZipEntry inEntry;
766
                    while ((inEntry = zis.getNextEntry()) != null) {
767
                        String path = inEntry.getName();
768
                        if (!p.matcher(path).matches()) {
769
                            continue;
770
                        }
771
                        ByteArrayOutputStream baos = new ByteArrayOutputStream();
772
                        byte[] buf = new byte[4096];
773
                        int read;
774
                        while ((read = zis.read(buf)) != -1) {
775
                            baos.write(buf, 0, read);
776
                        }
777
                        byte[] data = baos.toByteArray();
778
                        ZipEntry outEntry = new ZipEntry(path);
779
                        outEntry.setSize(data.length);
780
                        CRC32 crc = new CRC32();
781
                        crc.update(data);
782
                        outEntry.setCrc(crc.getValue());
783
                        zos.putNextEntry(outEntry);
784
                        zos.write(data);
785
                    }
786
                } finally {
787
                    is.close();
788
                }
789
            }
790
            zos.close();
791
        } finally {
792
            os.close();
793
        }
794
        return ppjar;
649
    }
795
    }
650
796
651
}
797
}
(-)nbbuild/templates/projectized.xml (-1 / +12 lines)
Lines 20-26 Link Here
20
    <target name="init" depends="basic-init,files-init,build-init"/>
20
    <target name="init" depends="basic-init,files-init,build-init"/>
21
    
21
    
22
    <target name="build-init" depends="basic-init">
22
    <target name="build-init" depends="basic-init">
23
        <parseprojectxml project="." publicpackagesproperty="public.packages" friendsproperty="friends" javadocpackagesproperty="module.javadoc.packages" idedependenciesproperty="ide.dependencies" moduledependenciesproperty="module.dependencies" moduleclasspathproperty="module.classpath" domainproperty="nbm.domain" classpathextensionsproperty="class.path.extensions"/>
23
        <property name="public.package.jar.dir" location="${nb_all}/nbbuild/build/public-package-jars"/>
24
        <mkdir dir="${public.package.jar.dir}"/>
25
        <parseprojectxml
26
            project="."
27
            publicpackagesproperty="public.packages"
28
            friendsproperty="friends"
29
            javadocpackagesproperty="module.javadoc.packages"
30
            moduledependenciesproperty="module.dependencies"
31
            moduleclasspathproperty="module.classpath"
32
            publicpackagejardir="${public.package.jar.dir}"
33
            domainproperty="nbm.domain"
34
            classpathextensionsproperty="class.path.extensions"/>
24
        <condition property="is.regular">
35
        <condition property="is.regular">
25
            <not>
36
            <not>
26
                <or>
37
                <or>

Return to bug 59792