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/Builder.java
6004 views
1
/*******************************************************************************
2
* Copyright (c) 1999, 2020 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.io.IOException;
26
import java.io.OutputStream;
27
import java.util.ArrayList;
28
import java.util.Calendar;
29
import java.util.Date;
30
import java.util.GregorianCalendar;
31
import java.util.HashMap;
32
import java.util.List;
33
import java.util.Map;
34
import java.util.Properties;
35
36
/**
37
* J9 JCL Perprocessor builder. The builder is responsible for all the tasks related to preprocessing
38
* a group of files. This includes managing the extensions, notifying others, verifying preprocess options,
39
* handling preprocessor warnings, and actually preprocessing the sources.
40
*/
41
public class Builder {
42
43
public static boolean isForced(Map<?, ?> options) {
44
return Boolean.TRUE.equals(options.get("force"));
45
}
46
47
private Properties options = new Properties();
48
private BuilderExtension[] extensions = new BuilderExtension[0];
49
50
private Logger logger = new NullLogger();
51
private ConfigurationRegistry registry;
52
private ConfigObject configObject = null;
53
private boolean isIncremental = false;
54
private boolean enabledMetadata = false;
55
56
private File sourceDir = null;
57
58
/**
59
* The value is a String[] containing the relative paths of all of the build
60
* files for a given sourceDir.
61
*/
62
private final Map<File, String[]> buildFilesBySourceDir = new HashMap<>();
63
/*[PR 118220] Incremental builder is not called when file is deleted in base library*/
64
private final Map<File, List<String>> deleteFilesBySourceDir = new HashMap<>();
65
private final Map<File, List<String>> buildResourcesBySourceDir = new HashMap<>();
66
67
private int buildFileCount = 0;
68
private int deleteFileCount = 0;
69
private int builtFileCount = 0;
70
private int buildResourcesCount = 0;
71
private File outputDir = null;
72
private boolean verdict = false;
73
private boolean includeIfUnsure = false;
74
/*[PR 117967] idea 491: Automatically create the jars required for test bootpath*/
75
private boolean isTestsBootPath = false;
76
private boolean noWarnIncludeIf = false;
77
private boolean noWarnInvalidFlags = false;
78
private boolean multipleSources = false;
79
private boolean updateAllCopyrights = false;
80
81
/**
82
* J9 JCL Preprocessor builder constructor. Initializes the needed extensions.
83
*/
84
public Builder() {
85
addExtension(new ExternalMessagesExtension());
86
addExtension(new MacroExtension());
87
addExtension(new JxeRulesExtension());
88
addExtension(new EclipseMetadataExtension());
89
addExtension(new JitAttributesExtension());
90
addExtension(new TagExtension());
91
}
92
93
/**
94
* Sets the preprocess options.
95
*
96
* @param options the preprocess options
97
*/
98
public void setOptions(Properties options) {
99
if (options != null) {
100
this.options.putAll(options);
101
}
102
this.options = options;
103
}
104
105
/**
106
* Returns the preprocess options for this builder.
107
*
108
* @return the preprocess options
109
*/
110
public Properties getOptions() {
111
return this.options;
112
}
113
114
/**
115
* Adds an extension to the builder.
116
*
117
* @param extension the extension to add
118
*/
119
public void addExtension(BuilderExtension extension) {
120
if (extension == null) {
121
throw new NullPointerException();
122
}
123
124
BuilderExtension[] newExtensions = new BuilderExtension[extensions.length + 1];
125
if (extensions.length > 0) {
126
System.arraycopy(extensions, 0, newExtensions, 0, extensions.length);
127
}
128
newExtensions[newExtensions.length - 1] = extension;
129
this.extensions = newExtensions;
130
131
extension.setBuilder(this);
132
}
133
134
/**
135
* Returns the builder extensions/
136
*
137
* @return the builder extensions
138
*/
139
public BuilderExtension[] getExtensions() {
140
return extensions;
141
}
142
143
/**
144
* Returns the logger associated with this builder.
145
*
146
* @return the logger
147
*/
148
public Logger getLogger() {
149
return logger;
150
}
151
152
/**
153
* Sets this builder's logger.
154
*
155
* @param logger the new logger
156
*/
157
public void setLogger(Logger logger) {
158
this.logger = logger;
159
}
160
161
/**
162
* Sets whether the build is incremental or not.
163
*
164
* @param isIncremental <code>true</code> if the build is incremental, <code>false</code> otherwise
165
*/
166
public void setIncremental(boolean isIncremental) {
167
this.isIncremental = isIncremental;
168
}
169
170
/**
171
* Returns whether or not this builder will only do an incremental build.
172
*
173
* @return <code>true</code> if the build is incremental, <code>false</code> otherwise
174
*/
175
public boolean isIncremental() {
176
return this.isIncremental;
177
}
178
179
/**
180
* Sets whether or not preprocessor metadata will be generated.
181
*
182
* @param enabledMetadata <code>true</code> if metadata is to be generated,
183
* <code>false</code> otherwise
184
*/
185
public void setMetadata(boolean enabledMetadata) {
186
this.enabledMetadata = enabledMetadata;
187
}
188
189
/**
190
* Returns whether or not preprocessor metadata is enabled.
191
*
192
* @return <code>true</code> if metadata will be written, <code>false</code> otherwise
193
*/
194
public boolean isMetadataEnabled() {
195
return this.enabledMetadata;
196
}
197
198
/**
199
* Sets whether or not the preprocessor should include files that do not
200
* have a INCLUDE-IF tag.
201
*
202
* @param include <code>true</code> if files with no INCLUDE-IF should
203
* be included, <code>false</code> otherwise
204
*/
205
public void setIncludeIfUnsure(boolean include) {
206
this.includeIfUnsure = include;
207
}
208
209
/*[PR 117967] idea 491: Automatically create the jars required for test bootpath*/
210
/**
211
* Sets whether or not the preprocessor is running to generate Tests Boot Path project
212
*
213
* @param isTestsBoot <code>true</code> if preprocessor is running to generate Tests Boot Path project,
214
* <code>false</code> otherwise
215
*/
216
public void setIsTestsBoot(boolean isTestsBoot) {
217
this.isTestsBootPath = isTestsBoot;
218
}
219
220
/*[PR 117967] idea 491: Automatically create the jars required for test bootpath*/
221
/**
222
* Sets whether or not the preprocessor should give warningsor errors about the files that do not
223
* have a INCLUDE-IF tag.
224
*
225
* @param warning <code>true</code> if files with no INCLUDE-IF should
226
* be marked with warning or error, <code>false</code> otherwise
227
*/
228
public void setNoWarnIncludeIf(boolean warning) {
229
this.noWarnIncludeIf = warning;
230
}
231
232
/**
233
* Sets the configuration to preprocess.
234
*
235
* @param config the configuration to preprocess
236
*/
237
public void setConfiguration(ConfigObject config) {
238
if (config.isSet()) {
239
System.err.println("Warning: Builder is using " + config + ", a set, not a configuration.");
240
}
241
this.configObject = config;
242
this.registry = config.getRegistry();
243
this.outputDir = config.getOutputDir();
244
}
245
246
/**
247
* Returns this builder's output directory.
248
*
249
* @return the output directory
250
*/
251
public File getOutputDir() {
252
return this.outputDir;
253
}
254
255
/**
256
* Sets this builder's output directory.
257
*
258
* @param outputDir the new output directory
259
*/
260
public void setOutputDir(File outputDir) {
261
if (outputDir == null) {
262
throw new NullPointerException();
263
}
264
this.outputDir = outputDir;
265
}
266
267
/**
268
* Returns this builder's configuration source directories.
269
*
270
* @return the config's source dirs
271
*/
272
public File getSourceDir() {
273
return this.sourceDir;
274
}
275
276
/**
277
* Sets the proprocess job's source directory.
278
*
279
* @param sourceDir the source directory to preprocess
280
*/
281
public void setSourceDir(File sourceDir) {
282
if (sourceDir == null) {
283
throw new NullPointerException();
284
} else {
285
this.sourceDir = sourceDir;
286
}
287
}
288
289
/**
290
* Set builder aware of other sources (to be used by the ExternalMessagesExtension).
291
*
292
* @param multipleSources <code>true</code> if there are other sources, <code>false</code> otherwise
293
*/
294
public void setMultipleSources(boolean multipleSources) {
295
this.multipleSources = multipleSources;
296
}
297
298
/**
299
* Returns whether or not the configuration that setup this builder has multiple sources.
300
*
301
* @return <code>true</code> if there are other sources, <code>false</code> otherwise
302
*/
303
public boolean hasMultipleSources() {
304
return multipleSources;
305
}
306
307
/**
308
* Performs the build.
309
*/
310
public boolean build() {
311
//create output dir even if no file is gonna be included in preprocess
312
getOutputDir().mkdirs();
313
if (validateOptions()) {
314
computeBuildFiles();
315
notifyBuildBegin();
316
317
PreprocessorFactory factory = newPreprocessorFactory();
318
boolean force = isForced(this.options);
319
320
//Ignore folders that do not exist (warning thrown in computeBuildFiles()
321
if (sourceDir != null) {
322
File metadataDir = new File(outputDir.getParentFile(), "jppmd");
323
String[] buildFiles = buildFilesBySourceDir.get(sourceDir);
324
getLogger().log("\nPreprocessing " + sourceDir.getAbsolutePath(), 1);
325
builtFileCount = 0;
326
327
for (String buildFile : buildFiles) {
328
File sourceFile = new File(sourceDir, buildFile);
329
File outputFile = new File(outputDir, buildFile);
330
File metadataFile = new File(metadataDir, buildFile + ".jppmd");
331
332
notifyBuildFileBegin(sourceFile, outputFile, buildFile);
333
334
try (OutputStream metadataOutput = new PhantomOutputStream(metadataFile);
335
OutputStream output = new PhantomOutputStream(outputFile, force)) {
336
337
// configure the preprocessor and let extensions do the same
338
JavaPreprocessor jpp;
339
340
if (enabledMetadata) {
341
jpp = factory.newPreprocessor(metadataOutput, sourceFile, output, outputFile);
342
} else {
343
jpp = factory.newPreprocessor(sourceFile, output);
344
}
345
346
Calendar cal = new GregorianCalendar();
347
if (!updateAllCopyrights) {
348
cal.setTime(new Date(sourceFile.lastModified()));
349
}
350
jpp.addValidFlags(registry.getValidFlags());
351
/*[PR 120411] Use a javadoc tag instead of TestBootpath preprocessor tag*/
352
jpp.setTestBootPath(isTestsBootPath);
353
notifyConfigurePreprocessor(jpp);
354
355
// preprocess
356
boolean included = false;
357
try {
358
included = jpp.preprocess();
359
if (included) {
360
builtFileCount++;
361
}
362
handlePreprocessorWarnings(jpp, sourceFile);
363
} catch (Throwable t) {
364
handlePreprocessorException(t, sourceFile);
365
}
366
367
if (!included && outputFile.exists()) {
368
outputFile.delete();
369
}
370
371
if (!included && metadataFile.exists()) {
372
metadataFile.delete();
373
}
374
} catch (Throwable t) {
375
getLogger().log("Exception occured in file " + sourceFile.getAbsolutePath() + ", preprocess failed.", 3, t);
376
handleBuildException(t);
377
} finally {
378
notifyBuildFileEnd(sourceFile, outputFile, buildFile);
379
}
380
}
381
382
logger.log(builtFileCount + " of " + buildFileCount + " file(s) included in preprocess", 1);
383
384
/*[PR 118220] Incremental builder is not called when file is deleted in base library*/
385
List<String> deleteFiles = deleteFilesBySourceDir.get(sourceDir);
386
if (deleteFiles != null && deleteFiles.size() != 0) {
387
int deletedFilesCount = 0;
388
for (String file : deleteFiles) {
389
File deleteFile = new File(outputDir, file);
390
if (deleteFile.exists()) {
391
deletedFilesCount++;
392
deleteFile.delete();
393
}
394
}
395
getLogger().log(deletedFilesCount + " of " + deleteFileCount
396
+ " file(s) deleted in preprocess from " + outputDir.getAbsolutePath(), 1);
397
}
398
}
399
/*[PR 119753] classes.txt and AutoRuns are not updated when new test class is added */
400
List<String> buildResources = buildResourcesBySourceDir.get(sourceDir);
401
if (buildResources != null && buildResources.size() != 0) {
402
int copiedResourcesCount = 0;
403
int deletedResorucesCount = 0;
404
String outputpath;
405
if (isTestsBootPath) {
406
outputpath = configObject.getBootTestsOutputPath();
407
} else {
408
outputpath = configObject.getTestsOutputPath();
409
}
410
for (String file : buildResources) {
411
File resource_out = new File(outputpath, file);
412
File resource_src = new File(sourceDir, file);
413
if (resource_src.exists()) {
414
copyResource(resource_src, resource_out);
415
copiedResourcesCount++;
416
} else {
417
resource_out.delete();
418
deletedResorucesCount++;
419
}
420
}
421
422
getLogger().log("Total Build Resource Count : " + buildResourcesCount, 1);
423
getLogger().log(" - " + copiedResourcesCount + " resource" + (copiedResourcesCount > 1 ? "s are " : " is ") + "copied to " + outputpath, 1);
424
getLogger().log(" - " + deletedResorucesCount + " resource" + (deletedResorucesCount > 1 ? "s are " : " is ") + "deleted from " + outputpath, 1);
425
}
426
427
notifyBuildEnd();
428
}
429
430
if (logger.getErrorCount() == 0) {
431
if (verdict) {
432
getLogger().log("PREPROCESS WAS SUCCESSFUL", 1);
433
}
434
return true;
435
} else {
436
if (verdict) {
437
getLogger().log("PREPROCESS WAS NOT SUCCESSFUL", 1);
438
}
439
return false;
440
}
441
}
442
443
/*[PR 119753] classes.txt and AutoRuns are not updated when new test class is added */
444
public static void copyResource(File source, File destination) {
445
destination.delete();
446
447
try {
448
SimpleCopy.copyFile(source, destination);
449
} catch (IOException e) {
450
System.err.println("ERROR - Could not copy the file to destination");
451
System.err.println(" Source: " + source.toString());
452
System.err.println(" Destination: " + destination.toString());
453
e.printStackTrace();
454
}
455
}
456
457
/**
458
* Validates the build options.
459
*/
460
private boolean validateOptions() {
461
boolean isValid = true;
462
463
if (configObject == null) {
464
configObject = registry.getConfiguration(options.getProperty("config"));
465
}
466
this.options.putAll(configObject.getOptions());
467
468
// check for the verdict option
469
if (options.containsKey("verdict")) {
470
this.verdict = true;
471
}
472
473
if (options.containsKey("includeifunsure")) {
474
setIncludeIfUnsure(true);
475
}
476
if (options.containsKey("nowarnincludeif")) {
477
setNoWarnIncludeIf(true);
478
}
479
480
if (options.containsKey("nowarninvalidflags")) {
481
this.noWarnInvalidFlags = true;
482
}
483
484
if (options.containsKey("updateallcopyrights")) {
485
this.updateAllCopyrights = true;
486
}
487
488
// call the method for all the extensions
489
String extensionName = "";
490
try {
491
for (BuilderExtension extension : extensions) {
492
extensionName = extension.getName();
493
extension.validateOptions(this.options);
494
}
495
} catch (BuilderConfigurationException e) {
496
logger.log("A configuration exception occured", Logger.SEVERITY_FATAL, e);
497
isValid = false;
498
} catch (Exception e) {
499
StringBuffer buffer = new StringBuffer("An exception occured while invoking validateOptions() for the extension \"");
500
buffer.append(extensionName);
501
buffer.append("\"");
502
logger.log(buffer.toString(), Logger.SEVERITY_ERROR, e);
503
}
504
return isValid;
505
}
506
507
/**
508
* Notifies the extensions that the build is beginning.
509
*/
510
private void notifyBuildBegin() {
511
// call the method for all the extensions
512
String extensionName = "";
513
try {
514
for (BuilderExtension extension : extensions) {
515
extensionName = extension.getName();
516
logger.setMessageSource(extensionName);
517
extension.notifyBuildBegin();
518
logger.setMessageSource(null);
519
}
520
} catch (Exception e) {
521
StringBuffer buffer = new StringBuffer("An exception occured while invoking notifyBuildBegin() for the extension \"");
522
buffer.append(extensionName);
523
buffer.append("\"");
524
logger.log(buffer.toString(), Logger.SEVERITY_ERROR, e);
525
}
526
}
527
528
/**
529
* Notifies the extensions that the build is ending.
530
*/
531
private void notifyBuildEnd() {
532
// call the method for all the extensions
533
String extensionName = "";
534
try {
535
for (BuilderExtension extension : extensions) {
536
extensionName = extension.getName();
537
logger.setMessageSource(extensionName);
538
extension.notifyBuildEnd();
539
logger.setMessageSource(null);
540
}
541
} catch (Exception e) {
542
StringBuffer buffer = new StringBuffer("An exception occured while invoking notifyBuildEnd() for the extension \"");
543
buffer.append(extensionName);
544
buffer.append("\"");
545
logger.log(buffer.toString(), Logger.SEVERITY_ERROR, e);
546
}
547
}
548
549
/**
550
* Notifies the extensions that the build is beginning on the specified
551
* file.
552
*/
553
private void notifyBuildFileBegin(File sourceFile, File outputFile, String relativePath) {
554
// call the method for all the extensions
555
String extensionName = "";
556
try {
557
for (BuilderExtension extension : extensions) {
558
extensionName = extension.getName();
559
logger.setMessageSource(extensionName);
560
extension.notifyBuildFileBegin(sourceFile, outputFile, relativePath);
561
logger.setMessageSource(null);
562
}
563
} catch (Exception e) {
564
StringBuffer buffer = new StringBuffer("An exception occured while invoking notifyBuildFileBegin() for the extension \"");
565
buffer.append(extensionName);
566
buffer.append("\"");
567
logger.log(buffer.toString(), Logger.SEVERITY_ERROR, e);
568
}
569
}
570
571
/**
572
* Notifies the extensions that the build is ending on the specified file.
573
*/
574
private void notifyBuildFileEnd(File sourceFile, File outputFile, String relativePath) {
575
// call the method for all the extensions
576
String extensionName = "";
577
try {
578
for (BuilderExtension extension : extensions) {
579
extensionName = extension.getName();
580
logger.setMessageSource(extensionName);
581
extension.notifyBuildFileEnd(sourceFile, outputFile, relativePath);
582
logger.setMessageSource(null);
583
}
584
} catch (Exception e) {
585
StringBuffer buffer = new StringBuffer("An exception occured while invoking notifyBuildFileEnd() for the extension \"");
586
buffer.append(extensionName);
587
buffer.append("\"");
588
logger.log(buffer.toString(), Logger.SEVERITY_ERROR, e);
589
}
590
}
591
592
/**
593
* Notifies the extensions that they should configure the preprocessor.
594
*/
595
private void notifyConfigurePreprocessor(JavaPreprocessor preprocessor) {
596
preprocessor.setIncludeIfUnsure(this.includeIfUnsure);
597
preprocessor.setNoWarnIncludeIf(this.noWarnIncludeIf);
598
599
// call the method for all the extensions
600
String extensionName = "";
601
try {
602
for (BuilderExtension extension : extensions) {
603
extensionName = extension.getName();
604
logger.setMessageSource(extensionName);
605
extension.notifyConfigurePreprocessor(preprocessor);
606
logger.setMessageSource(null);
607
}
608
} catch (Exception e) {
609
StringBuffer buffer = new StringBuffer("An exception occured while invoking notifyConfigurePreprocessor() for the extension \"");
610
buffer.append(extensionName);
611
buffer.append("\"");
612
logger.log(buffer.toString(), Logger.SEVERITY_ERROR, e);
613
}
614
}
615
616
/**
617
* Handles exceptions thrown while building.
618
*/
619
private void handleBuildException(Throwable t) {
620
if (t instanceof Error) {
621
logger.log("An error occured while building", Logger.SEVERITY_FATAL, t);
622
throw (Error) t;
623
} else {
624
logger.log("An exception occured while building", Logger.SEVERITY_ERROR, t);
625
}
626
}
627
628
/**
629
* Handles exceptions thrown by the preprocessor.
630
*/
631
private void handlePreprocessorException(Throwable t, File sourceFile) {
632
if (t instanceof Error) {
633
logger.log("An error occured while invoking the preprocessor", "preprocessor", Logger.SEVERITY_FATAL, sourceFile, t);
634
throw (Error) t;
635
} else {
636
logger.log("An exception occured while invoking the preprocessor", "preprocessor", Logger.SEVERITY_ERROR, sourceFile, t);
637
}
638
}
639
640
/**
641
* Handles warnings generated by the preprocessor.
642
*/
643
private void handlePreprocessorWarnings(JavaPreprocessor jpp, File sourceFile) {
644
if (jpp.hasWarnings()) {
645
for (PreprocessorWarning warning : jpp.getWarnings()) {
646
int severity = warning.shouldFail() ? Logger.SEVERITY_ERROR : Logger.SEVERITY_WARNING;
647
/*[PR 117967] idea 491: Automatically create the jars required for test bootpath*/
648
if (warning.getMessage().startsWith("No INCLUDE-IF") && sourceFile.getAbsolutePath().endsWith(".java") && !includeIfUnsure && !isTestsBootPath) {
649
severity = Logger.SEVERITY_ERROR;
650
}
651
652
if (warning.getMessage().startsWith("Ignoring copyright")) {
653
severity = Logger.SEVERITY_INFO;
654
}
655
656
logger.log(warning.getMessage(), "preprocessor", severity, sourceFile, warning.getLine(), warning.getCharstart(), warning.getCharend());
657
}
658
}
659
660
if (!noWarnInvalidFlags) {
661
for (PreprocessorWarning warning : jpp.getInvalidFlags()) {
662
logger.log(warning.getMessage(), "preprocessor", Logger.SEVERITY_ERROR, sourceFile, warning.getLine(), warning.getCharstart(), warning.getCharend());
663
}
664
}
665
}
666
667
/**
668
* Determines whether the specified source file should be built.
669
*/
670
private boolean shouldBuild(File sourceFile, File outputFile, String relativePath) {
671
// call the method for all the extensions
672
for (BuilderExtension extension : extensions) {
673
logger.setMessageSource(extension.getName());
674
boolean shouldBuild = extension.shouldBuild(sourceFile, outputFile, relativePath);
675
logger.setMessageSource(null);
676
if (!shouldBuild) {
677
return false;
678
}
679
}
680
681
return true;
682
}
683
684
/*[PR 118220] Incremental builder is not called when file is deleted in base library*/
685
/**
686
* Returns the deleted Files
687
*/
688
/*[PR 119753] classes.txt and AutoRuns are not updated when new test class is added */
689
private List<String> getDeletedFiles(File sourceDir) {
690
// call the method for all the extensions
691
for (BuilderExtension extension : extensions) {
692
logger.setMessageSource(extension.getName());
693
List<String> elements = extension.getDeleteFiles(sourceDir);
694
logger.setMessageSource(null);
695
if (elements != null) {
696
return elements;
697
}
698
}
699
700
return null;
701
}
702
703
/*[PR 119753] classes.txt and AutoRuns are not updated when new test class is added */
704
private List<String> getBuildResources(File sourceDir) {
705
// call the method for all the extensions
706
for (BuilderExtension extension : extensions) {
707
logger.setMessageSource(extension.getName());
708
List<String> elements = extension.getBuildResources(sourceDir);
709
logger.setMessageSource(null);
710
if (elements != null) {
711
return elements;
712
}
713
}
714
return null;
715
}
716
717
/**
718
* Creates a new PreprocessorFactory object.
719
*/
720
private PreprocessorFactory newPreprocessorFactory() {
721
PreprocessorFactory factory = new PreprocessorFactory();
722
/*[PR 117967] idea 491: Automatically create the jars required for test bootpath*/
723
factory.setFlags(this.configObject.getFlagsAsArray());
724
factory.setRequiredIncludeFlags(this.configObject.getRequiredIncludeFlagSet());
725
return factory;
726
}
727
728
/**
729
* Recursively searches the given root directory to find all files. The file
730
* paths are returned, relative to the root directory.
731
*/
732
private List<String> getFiles(File rootDirectory) {
733
List<String> fileList = new ArrayList<>();
734
File[] files = rootDirectory.listFiles();
735
736
if (files == null) {
737
StringBuffer msg = new StringBuffer("Error reading the source directory \"");
738
msg.append(rootDirectory.getAbsolutePath());
739
msg.append("\" - No Files copied");
740
getLogger().log(msg.toString(), 2);
741
verdict = false;
742
} else {
743
getFiles(files, "", fileList);
744
}
745
746
return fileList;
747
}
748
749
/**
750
* This is a helper function to getFiles(File);
751
*/
752
private static void getFiles(File[] files, String relativePath, List<String> fileList) {
753
for (File file : files) {
754
if (file.isFile()) {
755
fileList.add(relativePath + file.getName());
756
} else {
757
String childRelativePath = relativePath + file.getName() + File.separator;
758
getFiles(file.listFiles(), childRelativePath, fileList);
759
}
760
}
761
}
762
763
private void computeBuildFiles() {
764
if (sourceDir.exists()) {
765
List<String> allFiles = getFiles(sourceDir);
766
List<String> buildFiles = new ArrayList<>(allFiles.size());
767
for (int j = 0; j < allFiles.size(); j++) {
768
String currentFile = allFiles.get(j).toString();
769
if (shouldBuild(sourceDir, outputDir, currentFile)) {
770
buildFiles.add(currentFile);
771
}
772
}
773
774
String[] buildFilesArray = buildFiles.toArray(new String[buildFiles.size()]);
775
buildFilesBySourceDir.put(sourceDir, buildFilesArray);
776
buildFileCount += buildFilesArray.length;
777
/*[PR 118220] Incremental builder is not called when file is deleted in base library*/
778
/*[PR 119753] classes.txt and AutoRuns are not updated when new test class is added */
779
List<String> deleteFiles = getDeletedFiles(sourceDir);
780
if (deleteFiles != null && deleteFiles.size() != 0) {
781
deleteFileCount = deleteFiles.size();
782
deleteFilesBySourceDir.put(sourceDir, deleteFiles);
783
}
784
785
List<String> buildResources = getBuildResources(sourceDir);
786
if (buildResources != null && buildResources.size() != 0) {
787
buildResourcesCount = buildResources.size();
788
buildResourcesBySourceDir.put(sourceDir, buildResources);
789
}
790
} else {
791
logger.log("Error: Source directory does not exist: " + sourceDir.getAbsolutePath(), Logger.SEVERITY_ERROR, new NullPointerException());
792
sourceDir = null;
793
}
794
}
795
796
/**
797
* Returns the number of files preprocessed.
798
*
799
* @return the number of files preprocessed
800
*/
801
public int getBuildFileCount() {
802
return buildFileCount;
803
}
804
805
}
806
807