Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openj9
Path: blob/master/sourcetools/com.ibm.jpp.preprocessor/com/ibm/jpp/om/ConfigObject.java
6004 views
1
/*******************************************************************************
2
* Copyright (c) 1999, 2019 IBM Corp. and others
3
*
4
* This program and the accompanying materials are made available under
5
* the terms of the Eclipse Public License 2.0 which accompanies this
6
* distribution and is available at https://www.eclipse.org/legal/epl-2.0/
7
* or the Apache License, Version 2.0 which accompanies this distribution and
8
* is available at https://www.apache.org/licenses/LICENSE-2.0.
9
*
10
* This Source Code may also be made available under the following
11
* Secondary Licenses when the conditions for such availability set
12
* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
13
* General Public License, version 2 with the GNU Classpath
14
* Exception [1] and GNU General Public License, version 2 with the
15
* OpenJDK Assembly Exception [2].
16
*
17
* [1] https://www.gnu.org/software/classpath/license.html
18
* [2] http://openjdk.java.net/legal/assembly-exception.html
19
*
20
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
21
*******************************************************************************/
22
package com.ibm.jpp.om;
23
24
import java.io.File;
25
import java.util.ArrayList;
26
import java.util.Enumeration;
27
import java.util.HashMap;
28
import java.util.HashSet;
29
import java.util.Iterator;
30
import java.util.List;
31
import java.util.Map;
32
import java.util.Map.Entry;
33
import java.util.Properties;
34
import java.util.Set;
35
36
import com.ibm.jpp.commandline.CommandlineLogger;
37
import com.ibm.jpp.commandline.CommandlineNowarnLogger;
38
39
/**
40
* A config object is a preprocessor configuration used to generate a version of the
41
* J9 Java Class Libraries (JCL).
42
* <p>
43
* A <code>ConfigObject</code> identifies all of the flags associated with said preprocessor
44
* configuration and at the same time defines the output path, source paths, classpath entries,
45
* and dependent jobs. Dependent jobs are <code>ConfigObject</code> dependencies that need to
46
* be preprocessed before and that inherit the options and output path of the parent.
47
* <p>
48
* Furthermore, <code>ConfigObject</code>s are collected in a {@link ConfigurationRegistry} which
49
* guarantees name uniqueness. Note that name uniqueness is not guaranteed across registryies.
50
*
51
* @see com.ibm.jpp.om.ConfigurationRegistry
52
* @see com.ibm.jpp.om.MetaRegistry
53
* @see com.ibm.jpp.om.Src
54
*/
55
public class ConfigObject {
56
private final String name;
57
private final boolean isConfiguration; // If this is a configuration or a set
58
private String outputPath;
59
private String outputPathKeyword;
60
61
private String testsTempOutputPath;
62
private String testsOutputPath;
63
private String testsTempBootOutputPath;
64
private String testsBootOutputPath;
65
66
private final Map<String, String> defaultTestsResources;
67
private final Map<String, String> testsResources;
68
private boolean useTestResourcesDefaults = false;
69
70
private String baseDir;
71
private final Set<String> addDependFlagSet;
72
private final Set<String> removeDependFlagSet;
73
private final Set<String> requiredIncludeFlagSet;
74
private final Set<String> flagSet;
75
private final Set<String> removeFlagSet;
76
private String[] flagArray = null;
77
private final List<String> optionSet; // The order matters, pairs of name/value
78
private final List<String> compilerOptionSet; // The order matters, pairs of name/value
79
private final List<Src> sources;
80
private final List<ClassPathEntry> classPathEntries;
81
private final Map<String, ConfigObject> dependJobs;
82
private String JDKCompliance;
83
private boolean metadata = false;
84
/* [PR 119756] config project prefix and postfix support in jpp_configuration.xml file */
85
// prefixes and suffixes
86
private String outputPathPrefix = "";
87
private String outputPathSuffix = "";
88
private String testsOutputPathPrefix = "";
89
private String testsOutputPathSuffix = "";
90
private String bootTestsOutputPathPrefix = "";
91
private String bootTestsOutputPathSuffix = "";
92
93
/* [PR 120359] New classpath entry is needed for configurations */
94
private String configXMLParserError = "";
95
// Registry containing this ConfigObject (aka parent registry)
96
private ConfigurationRegistry registry;
97
98
/**
99
* Class constructor.
100
*
101
* @param name the configuration's name
102
* @param isConfiguration <code>true</code> if this is a configuration, <code>false</code> if this is a set
103
*/
104
public ConfigObject(String name, boolean isConfiguration) {
105
this(name, "", isConfiguration);
106
}
107
108
/**
109
* Class constructor.
110
*
111
* @param name the configuration's name
112
* @param baseDir the base directory for this configuration
113
* @param isConfiguration <code>true</code> if this is a configuration, <code>false</code> if this is a set
114
*/
115
public ConfigObject(String name, String baseDir, boolean isConfiguration) {
116
this.name = name;
117
this.baseDir = baseDir;
118
this.isConfiguration = isConfiguration;
119
120
flagSet = new HashSet<>();
121
requiredIncludeFlagSet = new HashSet<>();
122
removeFlagSet = new HashSet<>();
123
addDependFlagSet = new HashSet<>();
124
removeDependFlagSet = new HashSet<>();
125
126
classPathEntries = new ArrayList<>();
127
optionSet = new ArrayList<>();
128
compilerOptionSet = new ArrayList<>();
129
sources = new ArrayList<>();
130
dependJobs = new HashMap<>();
131
/* [PR 121295] Support for resources' prefixes and directories */
132
defaultTestsResources = new HashMap<>();
133
testsResources = new HashMap<>();
134
}
135
136
/**
137
* Returns whether this ConfigObject is a configuration or not.
138
*
139
* @return <code>true</code> if this config object is a configuration, <code>false</code> otherwise
140
*
141
* @see #isSet()
142
*/
143
public boolean isConfiguration() {
144
return isConfiguration;
145
}
146
147
/**
148
* Returns whether this ConfigObject is a set or not.
149
*
150
* @return <code>true</code> if this config object is a set, <code>false</code> otherwise
151
*
152
* @see #isConfiguration()
153
*/
154
public boolean isSet() {
155
return !isConfiguration;
156
}
157
158
/**
159
* Returns this ConfigObject's name (or label).
160
*
161
* @return the name
162
*/
163
public String getName() {
164
return name;
165
}
166
167
/**
168
* Returns whether or not tests can be generated for this config.
169
*
170
* @return <code>true</code> if tests can be generated, <code>false</code> otherwise
171
*/
172
public boolean canGenerateTests() {
173
return (registry.getTestsProject() != null && !registry.getTestsProject().equals(""));
174
}
175
176
/**
177
* Sets this ConfigObject's JDK Compiler compliance version.
178
*
179
* @param version the JDK version
180
*/
181
public void setJDKCompliance(String version) {
182
JDKCompliance = version;
183
}
184
185
/**
186
* Returns this ConfigObject's JDK Compiler compliance version.
187
*
188
* @return the JDK compliance version
189
*/
190
public String getJDKCompliance() {
191
return JDKCompliance;
192
}
193
194
/**
195
* Sets whether or not preprocessor metadata will be generated for this config.
196
*
197
* @param metadata <code>true</code> if metadata is to be generated,
198
* <code>false</code> otherwise
199
*/
200
public void enableMetadata(boolean metadata) {
201
this.metadata = metadata;
202
}
203
204
/**
205
* Returns whether or not preprocessor metadata is enabled.
206
*
207
* @return <code>true</code> if metadata will be written, <code>false</code> otherwise
208
*/
209
public boolean isMetadataEnabled() {
210
return metadata;
211
}
212
213
/**
214
* Adds a classpath entry to this ConfigObject. This classpath entry will be
215
* used by the eclipse plugin to generate a project classpath.
216
*
217
* @param path the classpath
218
* @param type the type of classpath
219
* @param isExported <code>true</code> if this entry is contributed to dependent projects, <code>false</code> otherwise
220
*/
221
public void addClassPathEntry(String path, String type, boolean isExported) {
222
classPathEntries.add(new ClassPathEntry(path, type, isExported));
223
}
224
225
/**
226
* Adds a classpath entry to this ConfigObject. This classpath entry will be
227
* used by the eclipse plugin to generate a project classpath.
228
*
229
* @param path the classpath
230
* @param type the type of classpath
231
* @param sourcePath the classpath's source path
232
* @param isExported <code>true</code> if this entry is contributed to dependent projects, <code>false</code> otherwise
233
*/
234
public void addClassPathEntry(String path, String type, String sourcePath, boolean isExported) {
235
classPathEntries.add(new ClassPathEntry(path, type, sourcePath, isExported));
236
}
237
238
/**
239
* Adds a classpath entry to this ConfigObject. This classpath entry will be
240
* used by the eclipse plugin to generate a project classpath.
241
*
242
* @param classpath the classpath entry
243
*/
244
public void addClassPathEntry(ClassPathEntry classpath) {
245
classPathEntries.add(classpath);
246
}
247
248
/**
249
* Returns this ConfigObject's classpath entries.
250
*
251
* @return the classpath entries
252
*/
253
public ClassPathEntry[] getClassPathEntries() {
254
return classPathEntries.toArray(new ClassPathEntry[classPathEntries.size()]);
255
}
256
257
/**
258
* Adds a flag to this ConfigObject.
259
*
260
* @param flag the flag to be added
261
*/
262
public void addFlag(String flag) {
263
flagSet.add(flag);
264
}
265
266
/* [PR 117967] idea 491: Automatically create the jars required for test bootpath */
267
/**
268
* Adds a flag to removeFlagSet.
269
*
270
* @param flag the flag to be added
271
*/
272
public void addFlagToRemoveFlagSet(String flag) {
273
removeFlagSet.add(flag);
274
}
275
276
/**
277
* Removes a flag from this ConfigObject.
278
*
279
* @param flag the flag to be removed
280
*/
281
public void removeFlag(String flag) {
282
flagSet.remove(flag);
283
}
284
285
/* [PR 117967] idea 491: Automatically create the jars required for test bootpath */
286
/**
287
* Removes a flag from requiredflagset
288
*
289
* @param flag the flag to be removed
290
*/
291
public void removeRequiredFlag(String flag) {
292
requiredIncludeFlagSet.remove(flag);
293
}
294
295
/**
296
* Returns the flags associated with this ConfigObject.
297
* <p>
298
* <b>Note:</b> the flagSet isn't completely correct until updateWithDependencies
299
* is called, when the removes and adding of sets happens
300
*
301
* @return the ConfigObject flags
302
*/
303
public Set<String> getFlags() {
304
return flagSet;
305
}
306
307
/**
308
* Returns the flags associated with this ConfigObject.
309
* <p>
310
* <b>Note:</b> the flagSet isn't completely correct until updateWithDependencies
311
* is called, when the removes and adding of sets happens
312
*
313
* @return the ConfigObject flags
314
*
315
* @see #getFlags()
316
*/
317
public String[] getFlagsAsArray() {
318
if (flagArray == null || flagArray.length != flagSet.size()) {
319
flagArray = new String[flagSet.size()];
320
flagSet.toArray(flagArray);
321
}
322
return flagArray;
323
}
324
325
/**
326
* Adds a flag dependency to another configuration or set
327
*
328
* @param name the dependency name
329
*/
330
public void addFlagDependency(String name) {
331
addDependFlagSet.add(name);
332
}
333
334
/**
335
* Removes a flag dependency to another configuration or set
336
*
337
* @param name the dependency name
338
*/
339
public void removeFlagDependency(String name) {
340
removeDependFlagSet.add(name);
341
}
342
343
/**
344
* Adds a new required include flag to this ConfigObject.
345
*
346
* @param newFlag the new flag to be added.
347
*/
348
public void addRequiredIncludeFlag(String newFlag) {
349
requiredIncludeFlagSet.add(newFlag);
350
}
351
352
/**
353
* Returns the required include flags.
354
*
355
* @return the required include flags
356
*/
357
public Set<String> getRequiredIncludeFlagSet() {
358
return requiredIncludeFlagSet;
359
}
360
361
/**
362
* Adds a dependency on another ConfigObject, which then must be preprocessed
363
* first.
364
*
365
* @param dependName the name of the dependent ConfigObject
366
* @param config the dependent ConfigObject
367
*/
368
public void addDependJob(String dependName, ConfigObject config) {
369
dependJobs.put(dependName, config);
370
}
371
372
/**
373
* Returns this ConfigObject's complete configuration dependencies through recursion.
374
*
375
* @return the configuration dependencies
376
*/
377
public Map<String, ConfigObject> getAllDependJobs() {
378
Map<String, ConfigObject> allDependencies = new HashMap<>();
379
allDependencies.putAll(dependJobs);
380
381
// Recursively get the configuration dependencies
382
if (!dependJobs.isEmpty()) {
383
ConfigObject[] dependConfigs = dependJobs.values().toArray(new ConfigObject[dependJobs.size()]);
384
385
for (ConfigObject dependConfig : dependConfigs) {
386
if (dependConfig != null) {
387
allDependencies.putAll(dependConfig.getDependJobs());
388
}
389
}
390
}
391
392
return allDependencies;
393
}
394
395
/**
396
* Returns this ConfigObject's immediate configuration dependencies.
397
*
398
* @return the configuration dependencies
399
*/
400
public Map<String, ConfigObject> getDependJobs() {
401
return dependJobs;
402
}
403
404
/**
405
* Returns this ConfigObject's parent registry
406
*
407
* @return the parent registry
408
*/
409
public ConfigurationRegistry getRegistry() {
410
return registry;
411
}
412
413
/**
414
* Sets this ConfigObject's parent registry
415
*
416
* @param registry the registry to set
417
*/
418
public void setRegistry(ConfigurationRegistry registry) {
419
this.registry = registry;
420
}
421
422
/**
423
* Checks whether this ConfigObject has flag dependencies that need to be
424
* resolved with {@link #updateWithDependencies()}.
425
*
426
* @return <code>true</code> if there are flag dependencies to be resolved, <code>false</code> otherwise
427
*/
428
public boolean checkDependencies() {
429
return (!addDependFlagSet.isEmpty() && !removeDependFlagSet.isEmpty()) ? true : registry.getConfigurationNamesAsSet().containsAll(addDependFlagSet);
430
}
431
432
/**
433
* Updates the flag dependencies in this ConfigObject.
434
*/
435
public void updateWithDependencies() {
436
for (String configName : addDependFlagSet) {
437
ConfigObject configuration = registry.getConfiguration(configName);
438
flagSet.addAll(configuration.getFlags());
439
requiredIncludeFlagSet.addAll(configuration.getRequiredIncludeFlagSet());
440
}
441
442
for (String configName : removeDependFlagSet) {
443
ConfigObject configuration = registry.getConfiguration(configName);
444
flagSet.removeAll(configuration.getFlags());
445
requiredIncludeFlagSet.removeAll(configuration.getRequiredIncludeFlagSet());
446
}
447
448
flagSet.removeAll(removeFlagSet);
449
requiredIncludeFlagSet.removeAll(removeFlagSet);
450
}
451
452
/**
453
* Adds global options to this ConfigObject. These options will apply to all
454
* sources.
455
*
456
* @param name the option name
457
* @param value the option value
458
*/
459
public void addOption(String name, String value) {
460
optionSet.add(name);
461
optionSet.add(value);
462
}
463
464
/* [PR 119500] Design 955 Core.JCL : Support bootpath JCL testing */
465
/**
466
* Removes a global option from this ConfigObject. These options will apply to all
467
* sources.
468
*
469
* @param name the option name
470
*/
471
public void removeOption(String name) {
472
for (int i = 0; i < optionSet.size();) {
473
String option = optionSet.get(i);
474
if (option.equals(name)) {
475
optionSet.remove(i);
476
optionSet.remove(i);
477
} else {
478
i += 2;
479
}
480
}
481
}
482
483
/* [PR 118829] Desing 894: Core.JCL : Support for compiler options in preprocessor plugin */
484
/**
485
* Adds compiler options to this ConfigObject. These options will apply to
486
* config projects' compiler options
487
*
488
* @param name the option name
489
* @param value the option value
490
*/
491
public void addCompilerOption(String name, String value) {
492
compilerOptionSet.add(name);
493
compilerOptionSet.add(value);
494
}
495
496
/**
497
* Returns the global options associated with this ConfigObject.
498
*
499
* @return the global options
500
*/
501
public Properties getOptions() {
502
Properties options = new Properties();
503
int setSize = optionSet.size();
504
for (int i = 0; i < setSize; i += 2) {
505
options.setProperty(optionSet.get(i), optionSet.get(i + 1));
506
}
507
return options;
508
}
509
510
/**
511
* Returns the compiler options associated with this ConfigObject.
512
*
513
* @return the compiler options
514
*/
515
public Properties getCompilerOptions() {
516
Properties coptions = new Properties();
517
int setSize = compilerOptionSet.size();
518
for (int i = 0; i < setSize; i += 2) {
519
coptions.setProperty(compilerOptionSet.get(i), compilerOptionSet.get(i + 1));
520
}
521
return coptions;
522
}
523
524
/**
525
* Sets this ConfigObject's base directory.
526
*
527
* @param newBaseDir the new base dir
528
*/
529
public void setBaseDir(String newBaseDir) {
530
baseDir = newBaseDir;
531
}
532
533
/**
534
* Returns this ConfigObject's base directory.
535
*
536
* @return the base directory
537
*/
538
public String getbaseDir() {
539
return baseDir;
540
}
541
542
/**
543
* Sets the outputPath keyword to get output project names.
544
* @param outputPath outpath value in jpp_configuration.xml
545
*/
546
/* [PR 119756] config project prefix and postfix support in jpp_configuration.xml file */
547
public void setOutputPathKeyword(String outputPath) {
548
if (!outputPath.startsWith(File.separator) && !outputPath.startsWith(":", 1)) {
549
int index = Math.max(outputPath.indexOf("\\"), outputPath.indexOf("/"));
550
if (index != -1) {
551
outputPathKeyword = outputPath.substring(0, index).trim();
552
} else {
553
outputPathKeyword = outputPath.trim();
554
}
555
}
556
}
557
558
/**
559
* outputPath name without prefix and suffix
560
* @return outputPathKeyword
561
*/
562
/* [PR 120359] New classpath entry is needed for configurations */
563
public String getOutputPathKeyword() {
564
return outputPathKeyword;
565
}
566
567
/**
568
* Sets this ConfigObject's output path
569
*
570
* @param newOutputPath the new output path
571
*/
572
public void setOutputPath(String newOutputPath) {
573
if (!newOutputPath.startsWith(File.separator) && !newOutputPath.startsWith(":", 1)) {
574
StringBuffer buffer = new StringBuffer(baseDir);
575
buffer.append(outputPathPrefix + outputPathKeyword + outputPathSuffix + "/src");
576
outputPath = buffer.toString();
577
} else {
578
outputPath = newOutputPath;
579
}
580
}
581
582
/**
583
* Sets this ConfigObject's tests output path
584
*
585
*/
586
/* [PR 119756] config project prefix and postfix support in jpp_configuration.xml file */
587
public void setTestsOutputPaths() {
588
if (outputPathKeyword != null) {
589
testsTempOutputPath = baseDir + testsOutputPathPrefix + outputPathKeyword + testsOutputPathSuffix + "/preprocessedTests";
590
testsOutputPath = baseDir + testsOutputPathPrefix + outputPathKeyword + testsOutputPathSuffix + "/src";
591
} else {
592
int lastIndex = Math.max(outputPath.lastIndexOf("\\"), outputPath.lastIndexOf("/"));
593
String token = outputPath.substring(0, lastIndex);
594
testsTempOutputPath = token + " Tests/preprocessedTests";
595
testsOutputPath = token + " Tests/src";
596
}
597
}
598
599
/**
600
* Sets this ConfigObject's boot tests output path
601
*
602
*/
603
/* [PR 119756] config project prefix and postfix support in jpp_configuration.xml file */
604
public void setBootTestsOutputPaths() {
605
if (outputPathKeyword != null) {
606
testsTempBootOutputPath = baseDir + bootTestsOutputPathPrefix + outputPathKeyword + bootTestsOutputPathSuffix + "/preprocessedBootPathTests";
607
testsBootOutputPath = baseDir + bootTestsOutputPathPrefix + outputPathKeyword + bootTestsOutputPathSuffix + "/src";
608
} else {
609
int lastIndex = Math.max(outputPath.lastIndexOf("\\"), outputPath.lastIndexOf("/"));
610
String token = outputPath.substring(0, lastIndex);
611
testsTempBootOutputPath = token + " Tests BootPath/preprocessedBootPathTests";
612
testsBootOutputPath = token + " Tests BootPath/src";
613
}
614
}
615
616
/* [PR 117967] idea 491: Automatically create the jars required for test bootpath */
617
public void setOutputPathforJCLBuilder(String newOutputPath) {
618
String path;
619
if (!newOutputPath.startsWith(File.separator) && !newOutputPath.startsWith(":", 1)) {
620
StringBuffer buffer = new StringBuffer(baseDir);
621
buffer.append(newOutputPath);
622
path = buffer.toString();
623
} else {
624
path = newOutputPath;
625
}
626
627
outputPath = path;
628
testsTempOutputPath = path;
629
testsTempBootOutputPath = path;
630
}
631
632
/* [PR 117967] idea 491: Automatically create the jars required for test bootpath */
633
/**
634
* Returns this ConfigObject's tests boot path
635
*/
636
public String getTestsBootPath() {
637
return testsTempBootOutputPath;
638
}
639
640
/* [PR 118220] Incremental builder is not called when file is deleted in base library */
641
/**
642
* Returns this ConfigObject's tests Outputpath
643
*/
644
public String getTestsOutputPath() {
645
return testsOutputPath;
646
}
647
648
/**
649
* Returns this ConfigObject's tests Outputpath
650
*/
651
/* [PR 119753] classes.txt and AutoRuns are not updated when new test class is added */
652
public String getBootTestsOutputPath() {
653
return testsBootOutputPath;
654
}
655
656
/**
657
* Returns this ConfigObject's outputPathPrefix
658
*/
659
/* [PR 119756] config project prefix and postfix support in jpp_configuration.xml file */
660
public String getOutputPathPrefix() {
661
return outputPathPrefix;
662
}
663
664
/**
665
* Returns this ConfigObject's outputPathSuffix
666
*/
667
/* [PR 119756] config project prefix and postfix support in jpp_configuration.xml file */
668
public String getOutputPathSuffix() {
669
return outputPathSuffix;
670
}
671
672
/**
673
* Returns this ConfigObject's testsOutputPathPrefix
674
*/
675
/* [PR 119756] config project prefix and postfix support in jpp_configuration.xml file */
676
public String getTestsOutputPathPrefix() {
677
return testsOutputPathPrefix;
678
}
679
680
/**
681
* Returns this ConfigObject's testsOutputPathSuffix
682
*/
683
/* [PR 119756] config project prefix and postfix support in jpp_configuration.xml file */
684
public String getTestsOutputPathSuffix() {
685
return testsOutputPathSuffix;
686
}
687
688
/**
689
* Returns this ConfigObject's bootTestsOutputPathPrefix
690
*/
691
/* [PR 119756] config project prefix and postfix support in jpp_configuration.xml file */
692
public String getBootTestsOutputPathPrefix() {
693
return bootTestsOutputPathPrefix;
694
}
695
696
/**
697
* Returns this ConfigObject's bootTestsOutputPathSuffix
698
*/
699
/* [PR 119756] config project prefix and postfix support in jpp_configuration.xml file */
700
public String getBootTestsOutputPathSuffix() {
701
return bootTestsOutputPathSuffix;
702
}
703
704
/**
705
* Sets this ConfigObject's OutputPath Prefix
706
*/
707
/* [PR 119756] config project prefix and postfix support in jpp_configuration.xml file */
708
public void setOutputPathPrefix(String prefix) {
709
outputPathPrefix = prefix;
710
}
711
712
/**
713
* Sets this ConfigObject's OutputPath Suffix
714
*/
715
public void setOutputPathSuffix(String suffix) {
716
outputPathSuffix = suffix;
717
}
718
719
/**
720
* Sets this ConfigObject's Tests OutputPath Prefix
721
*/
722
public void setTestsOutputPathPrefix(String prefix) {
723
testsOutputPathPrefix = prefix;
724
}
725
726
/**
727
* Sets this ConfigObject's Tests OutputPath Suffix
728
*/
729
public void setTestsOutputPathSuffix(String suffix) {
730
testsOutputPathSuffix = suffix;
731
}
732
733
/**
734
* Sets this ConfigObject's Boot Tests OutputPath Prefix
735
*/
736
public void setBootTestsOutputPathPrefix(String prefix) {
737
bootTestsOutputPathPrefix = prefix;
738
}
739
740
/**
741
* Sets this ConfigObject's Boot Tests OutputPath Suffix
742
*/
743
public void setBootTestsOutputPathSuffix(String suffix) {
744
bootTestsOutputPathSuffix = suffix;
745
}
746
747
/**
748
* Sets this ConfigObject's tests boot path
749
*/
750
public void setTestsBootPath(String bootpath) {
751
testsTempBootOutputPath = bootpath;
752
}
753
754
/**
755
* Sets the global resources prefixes to this config object
756
* @param res resources prefixes
757
*/
758
/* [PR 121295] Support for resources' prefixes and directories */
759
public void setDefaultTestsResourcesPrefixes(Map<String, String> res) {
760
defaultTestsResources.putAll(res);
761
if (defaultTestsResources.keySet().size() == 0) {
762
defaultTestsResources.put("*", "j9ts_");
763
}
764
}
765
766
/**
767
* Sets the config objects's resources prefix. It parses all resources' prefixes and removes the prefixes that are overwritten.
768
* @param dir Directory
769
* @param prefix Prefix of resources
770
*/
771
/* [PR 121295] Support for resources' prefixes and directories */
772
public void setTestsResourcesPrefix(String dir, String prefix) {
773
if (!dir.equals("*")) {
774
String dirSlash = dir + "/";
775
776
for (Iterator<String> iter = testsResources.keySet().iterator(); iter.hasNext();) {
777
String nextDir = iter.next();
778
779
if (nextDir.startsWith(dirSlash) || nextDir.equals(dir)) {
780
iter.remove();
781
}
782
}
783
} else {
784
testsResources.clear();
785
}
786
testsResources.put(dir, prefix);
787
}
788
789
public void setUseTestResourcesDefaults(boolean def) {
790
useTestResourcesDefaults = def;
791
}
792
793
public Map<String, String> getTestsResourcesPrefixes() {
794
Map<String, String> prefixes = new HashMap<>();
795
if (useTestResourcesDefaults) {
796
prefixes.putAll(defaultTestsResources);
797
798
for (String dir : testsResources.keySet()) {
799
String dirSlash = dir + "/";
800
801
for (Iterator<String> iter = prefixes.keySet().iterator(); iter.hasNext();) {
802
String nextDir = iter.next();
803
804
if (nextDir.startsWith(dirSlash) || nextDir.equals(dir)) {
805
iter.remove();
806
}
807
}
808
}
809
prefixes.putAll(testsResources);
810
} else if (testsResources.keySet().size() != 0) {
811
prefixes = testsResources;
812
} else {
813
prefixes = defaultTestsResources;
814
}
815
return prefixes;
816
}
817
818
/**
819
* Returns this ConfigObject's output path.
820
*
821
* @return the output path
822
*
823
* @see #getOutputDir()
824
*/
825
public String getOutputPath() {
826
return outputPath;
827
}
828
829
/**
830
* Returns this ConfigObject's output path relative to the base directory.
831
*
832
* @return the relative output path
833
*/
834
public String getRelativeOutputPath() {
835
int pathLength = (baseDir != null && outputPath.length() > baseDir.length()) ? baseDir.length() : 0;
836
return (outputPath != null) ? outputPath.substring(pathLength) : null;
837
}
838
839
/**
840
* Returns this ConfigObject's tests output path relative to the base directory.
841
*
842
* @return the relative tests output path
843
*/
844
/* [PR 119756] config project prefix and postfix support in jpp_configuration.xml file */
845
public String getRelativeTestsOutputPath() {
846
int pathLength = (baseDir != null && testsOutputPath.length() > baseDir.length()) ? baseDir.length() : 0;
847
return (testsOutputPath != null) ? testsOutputPath.substring(pathLength) : null;
848
}
849
850
/**
851
* Returns this ConfigObject's boot tests output path relative to the base directory.
852
*
853
* @return the relative boo
854
* ttests output path
855
*/
856
/* [PR 119756] config project prefix and postfix support in jpp_configuration.xml file */
857
public String getRelativeBootTestsOutputPath() {
858
int pathLength = (baseDir != null && testsBootOutputPath.length() > baseDir.length()) ? baseDir.length() : 0;
859
return (testsBootOutputPath != null) ? testsBootOutputPath.substring(pathLength) : null;
860
}
861
862
/**
863
* Returns this ConfigObject's output directory.
864
*
865
* @return the output dir
866
*
867
* @see #getOutputPath()
868
* @see #getRelativeOutputPath()
869
*/
870
public File getOutputDir() {
871
return (outputPath != null) ? new File(outputPath) : null;
872
}
873
874
/**
875
* Adds a config source to this ConfigObject.
876
*
877
* @param newSource the new config source
878
*/
879
public void addSource(Src newSource) {
880
sources.add(newSource);
881
}
882
883
/**
884
* Returns the number of sources defined for this ConfigObject.
885
*
886
* @return the number of defined sources
887
*/
888
public int getSourceCount() {
889
return sources.size();
890
}
891
892
/**
893
* Returns the sources defined for this ConfigObject.
894
*
895
* @return the config sources
896
*/
897
public Src[] getSources() {
898
return sources.toArray(new Src[sources.size()]);
899
}
900
901
/**
902
* Returns this ConfigObject's source paths relative to the base directory.
903
*
904
* @return the relative source paths
905
*
906
* @see #getRelativeSrcDirs()
907
*/
908
public String[] getRelativeSrcPaths() {
909
String[] returnArray = new String[sources.size()];
910
for (int i = 0; i < returnArray.length; i++) {
911
returnArray[i] = sources.get(i).getRelativeSrcPath();
912
}
913
return returnArray;
914
}
915
916
/**
917
* Returns this ConfigObject's source directories relative to the base directory.
918
*
919
* @return the relative source dirs
920
*
921
* @see #getRelativeSrcPaths()
922
*/
923
public File[] getRelativeSrcDirs() {
924
File[] returnArray = new File[sources.size()];
925
for (int i = 0; i < returnArray.length; i++) {
926
returnArray[i] = sources.get(i).getRelativeSrcFolder();
927
}
928
return returnArray;
929
}
930
931
/**
932
* Returns this ConfigObject's absolute source directories.
933
*
934
* @return the absolute source dirs
935
*/
936
public String[] getAbsoluteSrcPaths() {
937
String[] returnArray = new String[sources.size()];
938
for (int i = 0; i < returnArray.length; i++) {
939
returnArray[i] = baseDir + sources.get(i).getRelativeSrcPath();
940
}
941
return returnArray;
942
}
943
944
/**
945
* Returns this ConfigObject's absolute source directories.
946
*
947
* @return the absolute source dirs
948
*/
949
public File[] getAbsoluteSrcDirs() {
950
File[] returnArray = new File[sources.size()];
951
for (int i = 0; i < returnArray.length; i++) {
952
returnArray[i] = new File(baseDir + sources.get(i).getRelativeSrcPath());
953
}
954
return returnArray;
955
}
956
957
/**
958
* Preprocesses this configuration object. If the ConfigObject has any config dependencies,
959
* those will be preprocessed first (automatically).
960
* <p>
961
* <b>NOTE:</b> the dependencies will inherit the configuration options and the output
962
* directory of the parent.
963
*
964
* @param incremental <code>true</code> if this build is incremental
965
* @param noWarn <code>true</code> if a logger with no warnings is to be used
966
*/
967
public boolean build(boolean incremental, boolean noWarn) {
968
return build(incremental, noWarn, new BuilderExtension[0], null);
969
}
970
971
/* [PR 121491] Use correct build method and correct commandline input values for preprocessing jobs */
972
public boolean buildTests(boolean incremental, boolean noWarn) {
973
return buildTests(incremental, noWarn, new BuilderExtension[0], null);
974
}
975
976
/* [PR 121584]Add option to jcl-builder to use testsBootPath JavaDoc */
977
public boolean buildTestBootpath(boolean incremental, boolean noWarn, boolean useTestBootpathJavaDoc) {
978
return buildTestBootpath(incremental, noWarn, useTestBootpathJavaDoc, new BuilderExtension[0], null, false);
979
}
980
981
/**
982
* Preprocesses this configuration object. If the ConfigObject has any config dependencies,
983
* those will be preprocessed first (automatically).
984
* <p>
985
* <b>NOTE:</b> the dependencies will inherit the configuration options and the output
986
* directory of the parent.
987
*
988
* @param incremental <code>true</code> if this build is incremental
989
* @param noWarn <code>true</code> if a logger with no warnings is to be used
990
* @param extensions builder extensions to be added to the preprocess
991
* @param logger the build logger to use, if <code>null</code> one will be created
992
*/
993
public boolean build(boolean incremental, boolean noWarn, BuilderExtension[] extensions, Logger logger) {
994
// Preprocess all dependent jobs first
995
if (!dependJobs.isEmpty()) {
996
for (Entry<String, ConfigObject> entry : dependJobs.entrySet()) {
997
ConfigObject dependConfig = entry.getValue();
998
999
if (dependConfig != null) {
1000
Properties options = this.getOptions();
1001
Enumeration<?> keys = options.keys();
1002
while (keys.hasMoreElements()) {
1003
String keyName = keys.nextElement().toString();
1004
dependConfig.addOption(keyName, options.getProperty(keyName));
1005
}
1006
1007
// requires setting the destDir
1008
String tempOutputPath = dependConfig.getOutputPath();
1009
dependConfig.setOutputPath(this.getOutputPath());
1010
dependConfig.build(incremental, noWarn, extensions, logger);
1011
1012
// Return the output path to its initial value
1013
dependConfig.setOutputPath(tempOutputPath);
1014
} else {
1015
System.err.println("\nCould not find dependent configuration: " + entry.getKey());
1016
}
1017
}
1018
}
1019
1020
boolean result = true;
1021
int multipleSources = 0;
1022
// Preprocess this ConfigObject
1023
for (int i = 0; i < sources.size(); ++i) {
1024
Src source = sources.get(i);
1025
File srcPath = new File(this.baseDir + source.getRelativeSrcPath());
1026
if (!source.isSimpleCopy()) {
1027
if (srcPath.exists()) {
1028
Builder builder = new Builder();
1029
builder.setConfiguration(this);
1030
builder.setIncremental(incremental);
1031
builder.setMetadata(metadata);
1032
builder.setOptions(source.getOptions());
1033
1034
for (BuilderExtension extension : extensions) {
1035
builder.addExtension(extension);
1036
}
1037
1038
if (logger != null) {
1039
builder.setLogger(logger);
1040
} else if (noWarn) {
1041
builder.setLogger(new CommandlineNowarnLogger());
1042
} else {
1043
builder.setLogger(new CommandlineLogger());
1044
}
1045
1046
// Allow the builder to be aware of other sources (if there are any).
1047
// In the current setup the builder only preprocesses one source at a time
1048
// so it's not aware of other sources. This becomes an issue when external
1049
// messages must be written out. This allows the ExternalMessagesExtension
1050
// to check if it should load the messages already in the output file.
1051
if (++multipleSources > 1) {
1052
builder.setMultipleSources(true);
1053
}
1054
1055
builder.setSourceDir(srcPath);
1056
result &= builder.build();
1057
} else {
1058
System.out.println("Potential source : " + srcPath.toString() + " does not exist");
1059
result = false;
1060
}
1061
} else {
1062
String simpleOutput = source.getSimpleCopyOutput();
1063
1064
SimpleCopy simpleCopy = new SimpleCopy();
1065
simpleCopy.setBaseDir(baseDir);
1066
simpleCopy.setSourcePath(srcPath);
1067
simpleCopy.setSimpleOutput(simpleOutput);
1068
simpleCopy.setOutputDir(this.getOutputDir());
1069
result &= simpleCopy.copy();
1070
}
1071
}
1072
return result;
1073
}
1074
1075
/* [PR 121491] Use correct build method and correct commandline input values for preprocessing jobs */
1076
public boolean buildTests(boolean incremental, boolean noWarn, BuilderExtension[] extensions, Logger logger) {
1077
return buildTests(incremental, noWarn, extensions, logger, false);
1078
}
1079
1080
/**
1081
* Preprocesses this configuration object's automated tests.
1082
*
1083
* @param incremental <code>true</code> if this build is incremental
1084
* @param noWarn <code>true</code> if a logger with no warnings is to be used
1085
* @param extensions builder extensions to be added to the preprocess
1086
* @param logger the build logger to use, if <code>null</code> one will be created
1087
* @return <code>true</code> if the classes.txt is updated, <code>false</code> otherwise.
1088
*/
1089
public boolean buildTests(boolean incremental, boolean noWarn, BuilderExtension[] extensions, Logger logger, boolean callFromEclipse) {
1090
boolean result = true;
1091
int multipleSources = 0;
1092
List<Src> testsSources = this.registry.getTestsSources();
1093
String sourceRoot = this.registry.getSourceRoot();
1094
Builder builder = new Builder();
1095
builder.setConfiguration(this);
1096
builder.setIncremental(incremental);
1097
builder.setMetadata(metadata);
1098
/* [PR 116982] Preprocessor should not put INCLUDE-IF warnings on Automated Tests */
1099
if (this.registry.getConfigVersion() < 3) {
1100
builder.setNoWarnIncludeIf(true);
1101
builder.setIncludeIfUnsure(true);
1102
}
1103
for (BuilderExtension extension : extensions) {
1104
builder.addExtension(extension);
1105
}
1106
1107
if (logger != null) {
1108
builder.setLogger(logger);
1109
} else if (noWarn) {
1110
builder.setLogger(new CommandlineNowarnLogger());
1111
} else {
1112
builder.setLogger(new CommandlineLogger());
1113
}
1114
if (callFromEclipse) {
1115
if (this.registry.getConfigVersion() < 3) {
1116
builder.setOutputDir(new File(testsTempOutputPath));
1117
} else {
1118
builder.setOutputDir(new File(testsOutputPath));
1119
}
1120
}
1121
1122
/* Process explicit source paths for automated tests */
1123
if (testsSources != null) {
1124
for (int i = 0; i < testsSources.size(); i++) {
1125
File testsSrc = null;
1126
String srcfolder = testsSources.get(i).getRelativeSrcPath();
1127
if (callFromEclipse) {
1128
testsSrc = new File(this.baseDir + this.registry.getTestsProject(), srcfolder);
1129
} else {
1130
testsSrc = new File(this.baseDir + sourceRoot + srcfolder);
1131
}
1132
if (testsSrc.exists()) {
1133
// Allow the builder to be aware of other sources (if there are any).
1134
// // In the current setup the builder only preprocesses one source at a time
1135
// // so it's not aware of other sources. This becomes an issue when external
1136
// // messages must be written out. This allows the ExternalMessagesExtension
1137
// // to check if it should load the messages already in the output file.
1138
if (++multipleSources > 1) {
1139
builder.setMultipleSources(true);
1140
}
1141
builder.setSourceDir(testsSrc);
1142
result &= builder.build();
1143
} else {
1144
// this is just a warning, and does not indicate a failure
1145
System.out.println("Warning: Tests source directory does not exist: " + testsSrc.getAbsolutePath());
1146
}
1147
}
1148
}
1149
1150
/* [PR 119039] Design 917: Multiple source folder support for automated tests */
1151
for (Src source : sources) {
1152
if (!source.isSimpleCopy()) {
1153
String srcfolder = source.getRelativeSrcPath();
1154
if (srcfolder.startsWith(sourceRoot)) {
1155
/* [PR 121491] Use correct build method and correct commandline input values for preprocessing jobs */
1156
File testsSrc = null;
1157
if (callFromEclipse) {
1158
srcfolder = srcfolder.substring(sourceRoot.length());
1159
testsSrc = new File(this.baseDir + this.registry.getTestsProject(), srcfolder);
1160
} else {
1161
testsSrc = new File(this.baseDir + source.getRelativeSrcPath());
1162
}
1163
if (testsSrc.exists()) {
1164
// Allow the builder to be aware of other sources (if there are any).
1165
// In the current setup the builder only preprocesses one source at a time
1166
// so it's not aware of other sources. This becomes an issue when external
1167
// messages must be written out. This allows the ExternalMessagesExtension
1168
// to check if it should load the messages already in the output file.
1169
if (++multipleSources > 1) {
1170
builder.setMultipleSources(true);
1171
}
1172
builder.setSourceDir(testsSrc);
1173
result &= builder.build();
1174
} else {
1175
// this is just a warning, and does not indicate a failure
1176
System.out.println("Warning: Tests source directory does not exist: " + testsSrc.getAbsolutePath());
1177
}
1178
}
1179
}
1180
}
1181
return result;
1182
}
1183
1184
/* [PR 117967] idea 491: Automatically create the jars required for test bootpath */
1185
public boolean buildTestBootpath(boolean incremental, boolean noWarn, boolean useTestBootpathJavaDoc, BuilderExtension[] extensions, Logger logger, boolean callFromEclipse) {
1186
boolean result = true;
1187
int multipleSources = 0;
1188
String sourceRoot = this.registry.getSourceRoot();
1189
/* [PR 119039] Design 917: Multiple source folder support for automated tests */
1190
for (int i = 0; i < sources.size(); i++) {
1191
if (!sources.get(i).isSimpleCopy()) {
1192
String srcfolder = sources.get(i).getRelativeSrcPath();
1193
if (srcfolder.startsWith(sourceRoot)) {
1194
/* [PR 121491] Use correct build method and correct commandline input values for preprocessing jobs */
1195
File testsSrc = null;
1196
if (callFromEclipse) {
1197
srcfolder = srcfolder.substring(sourceRoot.length());
1198
testsSrc = new File(this.baseDir + this.registry.getTestsProject() + File.separator + srcfolder);
1199
} else {
1200
testsSrc = new File(this.baseDir + sources.get(i).getRelativeSrcPath());
1201
}
1202
if (testsSrc.exists()) {
1203
Builder builder = new Builder();
1204
builder.setConfiguration(this);
1205
builder.setIncremental(incremental);
1206
builder.setMetadata(metadata);
1207
/* [PR 116982] Preprocessor should not put INCLUDE-IF warnings on Automated Tests */
1208
builder.setNoWarnIncludeIf(true);
1209
/* [PR 121584]Add option to jcl-builder to use testsBootPath JavaDoc */
1210
builder.setIncludeIfUnsure(useTestBootpathJavaDoc);
1211
builder.setIsTestsBoot(true);
1212
1213
for (BuilderExtension extension : extensions) {
1214
builder.addExtension(extension);
1215
}
1216
1217
if (logger != null) {
1218
builder.setLogger(logger);
1219
} else if (noWarn) {
1220
builder.setLogger(new CommandlineNowarnLogger());
1221
} else {
1222
builder.setLogger(new CommandlineLogger());
1223
}
1224
1225
// Allow the builder to be aware of other sources (if there are any).
1226
// In the current setup the builder only preprocesses one source at a time
1227
// so it's not aware of other sources. This becomes an issue when external
1228
// messages must be written out. This allows the ExternalMessagesExtension
1229
// to check if it should load the messages already in the output file.
1230
if (++multipleSources > 1) {
1231
builder.setMultipleSources(true);
1232
}
1233
1234
builder.setSourceDir(testsSrc);
1235
if (callFromEclipse) {
1236
builder.setOutputDir(new File(testsTempBootOutputPath));
1237
}
1238
result &= builder.build();
1239
} else {
1240
// this is just a warning, and does not indicate a failure
1241
System.out.println("Warning: Tests source directory does not exist: " + testsSrc.getAbsolutePath());
1242
}
1243
}
1244
}
1245
}
1246
return result;
1247
}
1248
1249
/**
1250
* Returns a string representation of the config object with build info.
1251
*
1252
* @return the string representation of the config object
1253
*
1254
* @see java.lang.Object#toString()
1255
*/
1256
@Override
1257
public String toString() {
1258
return this.toString(true);
1259
}
1260
1261
/**
1262
* Returns a string representation of the config object with build info.
1263
* Build info includes the sources for the configuration and the output
1264
* directory.
1265
*
1266
* @param hasBuildInfo display build information
1267
* @return the string representation of the config object
1268
*
1269
* @see java.lang.Object#toString()
1270
*/
1271
public String toString(boolean hasBuildInfo) {
1272
StringBuffer buffer = new StringBuffer("\nName: ");
1273
buffer.append(name);
1274
1275
if (isConfiguration) {
1276
buffer.append(" (Configuration)");
1277
buffer.append("\nFlags: ");
1278
buffer.append(flagSet.toString());
1279
buffer.append("\nOptions: ");
1280
buffer.append(getOptions().toString());
1281
if (hasBuildInfo) {
1282
buffer.append("\nSources: ");
1283
buffer.append(sources.toString());
1284
buffer.append("\nOutput: ");
1285
buffer.append(getRelativeOutputPath());
1286
}
1287
} else {
1288
buffer.append(" (Set)");
1289
buffer.append("\nFlags: ");
1290
buffer.append(flagSet.toString());
1291
}
1292
return buffer.toString();
1293
}
1294
1295
/**
1296
* Indicates whether or not this ConfigObject is equal to a given object. The only
1297
* criteria used for comparison is the config name.
1298
*
1299
* @return <code>true</code> if the config objects have the same name, <code>false</code> otherwise
1300
*
1301
* @see java.lang.Object#equals(java.lang.Object)
1302
*/
1303
@Override
1304
public boolean equals(Object obj) {
1305
if (obj instanceof ConfigObject) {
1306
ConfigObject tempConfig = (ConfigObject) obj;
1307
1308
if (name.equals(tempConfig.getName())) {
1309
if (registry == null || registry.equals(tempConfig.getRegistry())) {
1310
return true;
1311
}
1312
}
1313
}
1314
1315
return false;
1316
}
1317
1318
/**
1319
* @see java.lang.Object#hashCode()
1320
*/
1321
@Override
1322
public int hashCode() {
1323
if (registry == null) {
1324
return name.hashCode();
1325
}
1326
1327
return name.hashCode() + registry.hashCode();
1328
}
1329
1330
/* [PR 120359] New classpath entry is needed for configurations */
1331
public void setXMLParserError(String error) {
1332
configXMLParserError += error;
1333
}
1334
1335
public String getXMLParserError() {
1336
return configXMLParserError;
1337
}
1338
}
1339
1340