Skip to content

Commit 99438fb

Browse files
committed
added way to manipulate current JCP text buffers as string variables: jcp.text.buffer.all,jcp.text.buffer.middle,jcp.text.buffer.prefix and jcp.text.buffer.postfix
1 parent ff6b0d9 commit 99438fb

File tree

9 files changed

+154
-57
lines changed

9 files changed

+154
-57
lines changed

changelog.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
__7.3.0 (SNAPSHOT)__
22

3+
- added way to manipulate current JCP text buffers as string variables: `jcp.text.buffer.all`,`jcp.text.buffer.middle`,`jcp.text.buffer.prefix` and `jcp.text.buffer.postfix`
34
- added way to find `PreprocessorExtension` and `SpecialVariableProcessor` among Java services
45
- refactoring of API for `SpecialVariableProcessor` and `CommentTextProcessor`
56
- replaced single string property `actionPreprocessorExtension` by string list `actionPreprocessorExtensions` to provide way for many preprocessor extensions.

jcp/src/main/java/com/igormaznitsa/jcp/containers/FileInfoContainer.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
import com.igormaznitsa.jcp.exceptions.FilePositionInfo;
3434
import com.igormaznitsa.jcp.exceptions.PreprocessorException;
3535
import com.igormaznitsa.jcp.utils.PreprocessorUtils;
36-
import com.igormaznitsa.jcp.utils.ResetablePrinter;
36+
import com.igormaznitsa.jcp.utils.ResettablePrinter;
3737
import java.io.File;
3838
import java.io.IOException;
3939
import java.util.ArrayList;
@@ -437,7 +437,7 @@ private void flushTextBufferForRemovedComments(
437437
final AtomicReference<Map.Entry<String, String>> firstDetectedUncommentLinePtr,
438438
final int stringIndex,
439439
final List<String> textPieces,
440-
final ResetablePrinter resetablePrinter,
440+
final ResettablePrinter resettablePrinter,
441441
final PreprocessingState state,
442442
final PreprocessorContext context)
443443
throws IOException {
@@ -456,7 +456,7 @@ private void flushTextBufferForRemovedComments(
456456

457457
if (accumulated.isEmpty()) {
458458
if (lastEol) {
459-
resetablePrinter.print(context.getEol());
459+
resettablePrinter.print(context.getEol());
460460
}
461461
} else {
462462
final List<CommentTextProcessor> processors = context.getCommentTextProcessors();
@@ -495,7 +495,7 @@ private void flushTextBufferForRemovedComments(
495495
text = results.stream().collect(Collectors.joining(context.getEol()));
496496
}
497497
}
498-
resetablePrinter.print(text + (lastEol ? context.getEol() : ""));
498+
resettablePrinter.print(text + (lastEol ? context.getEol() : ""));
499499
}
500500
}
501501

@@ -544,8 +544,8 @@ public PreprocessingState preprocessFileWithNotification(final PreprocessingStat
544544
new AtomicReference<>();
545545

546546
while (!Thread.currentThread().isInterrupted()) {
547-
final ResetablePrinter thePrinter =
548-
requireNonNull(theState.getPrinter(), "Printer must be defined");
547+
final ResettablePrinter thePrinter =
548+
requireNonNull(theState.getSelectedPrinter(), "Printer must be defined");
549549

550550
String rawString = theState.nextLine();
551551
final boolean presentedNextLine = theState.hasReadLineNextLineInEnd();

jcp/src/main/java/com/igormaznitsa/jcp/context/JCPSpecialVariableProcessor.java

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@
4040
*/
4141
public class JCPSpecialVariableProcessor implements SpecialVariableProcessor {
4242

43+
public static final String VAR_JCP_BUFFER_ALL = "jcp.text.buffer.all";
44+
public static final String VAR_JCP_BUFFER_MIDDLE = "jcp.text.buffer.middle";
45+
public static final String VAR_JCP_BUFFER_PREFIX = "jcp.text.buffer.prefix";
46+
public static final String VAR_JCP_BUFFER_POSTFIX = "jcp.text.buffer.postfix";
4347
public static final String VAR_DEST_DIR = "jcp.dst.dir";
4448
public static final String VAR_VERSION = "jcp.version";
4549
public static final String VAR_DEST_FILE_NAME = "jcp.dst.name";
@@ -84,12 +88,25 @@ public static List<NameReferencePair> getReference() {
8488
result.add(
8589
new NameReferencePair(VAR_TIMESTAMP, "Source file timestamp (EEE MMM dd HH:mm:ss yyyy)"));
8690

91+
result.add(new NameReferencePair(VAR_JCP_BUFFER_ALL,
92+
"Whole current text buffer for preprocessing file"));
93+
result.add(new NameReferencePair(VAR_JCP_BUFFER_MIDDLE,
94+
"Current middle text buffer for preprocessing file"));
95+
result.add(new NameReferencePair(VAR_JCP_BUFFER_PREFIX,
96+
"Current prefix text buffer for preprocessing file"));
97+
result.add(new NameReferencePair(VAR_JCP_BUFFER_POSTFIX,
98+
"Current postfix text buffer for preprocessing file"));
99+
87100
return result;
88101
}
89102

90103
@Override
91104
public Set<String> getVariableNames() {
92105
return Set.of(
106+
VAR_JCP_BUFFER_PREFIX,
107+
VAR_JCP_BUFFER_MIDDLE,
108+
VAR_JCP_BUFFER_POSTFIX,
109+
VAR_JCP_BUFFER_ALL,
93110
VAR_DEST_DIR,
94111
VAR_DEST_FILE_NAME,
95112
VAR_DEST_FULLPATH,
@@ -112,6 +129,17 @@ public Value getVariable(final String varName, final PreprocessorContext context
112129
final PreprocessingState state = context.getPreprocessingState();
113130

114131
switch (varName) {
132+
case VAR_JCP_BUFFER_ALL:
133+
return Value.valueOf(context.getPreprocessingState().getCurrentText());
134+
case VAR_JCP_BUFFER_POSTFIX:
135+
return Value.valueOf(context.getPreprocessingState().findPrinter(
136+
PreprocessingState.PrinterType.POSTFIX).getText());
137+
case VAR_JCP_BUFFER_MIDDLE:
138+
return Value.valueOf(context.getPreprocessingState().findPrinter(
139+
PreprocessingState.PrinterType.NORMAL).getText());
140+
case VAR_JCP_BUFFER_PREFIX:
141+
return Value.valueOf(context.getPreprocessingState().findPrinter(
142+
PreprocessingState.PrinterType.PREFIX).getText());
115143
case VAR_DEST_DIR:
116144
return Value.valueOf(state.getRootFileInfo().getTargetFolder());
117145
case VAR_DEST_FILE_NAME:
@@ -164,6 +192,22 @@ public void setVariable(final String varName, final Value value,
164192
final PreprocessorContext context) {
165193
final PreprocessingState state = context.getPreprocessingState();
166194
switch (varName) {
195+
case VAR_JCP_BUFFER_ALL: {
196+
state.setBufferText(value.toString());
197+
}
198+
break;
199+
case VAR_JCP_BUFFER_POSTFIX: {
200+
state.setBufferText(value.toString(), PreprocessingState.PrinterType.POSTFIX);
201+
}
202+
break;
203+
case VAR_JCP_BUFFER_MIDDLE: {
204+
state.setBufferText(value.toString(), PreprocessingState.PrinterType.NORMAL);
205+
}
206+
break;
207+
case VAR_JCP_BUFFER_PREFIX: {
208+
state.setBufferText(value.toString(), PreprocessingState.PrinterType.PREFIX);
209+
}
210+
break;
167211
case VAR_DEST_DIR:
168212
if (value.getType() != ValueType.STRING) {
169213
throw new IllegalArgumentException("Only STRING type allowed");

jcp/src/main/java/com/igormaznitsa/jcp/context/PreprocessingState.java

Lines changed: 74 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,16 @@
2424
import static com.igormaznitsa.jcp.removers.AbstractCommentRemover.makeCommentRemover;
2525
import static com.igormaznitsa.jcp.utils.IOUtils.closeQuietly;
2626
import static com.igormaznitsa.jcp.utils.PreprocessorUtils.findFirstActiveFileContainer;
27+
import static java.util.Objects.requireNonNull;
28+
import static java.util.Objects.requireNonNullElse;
2729

2830
import com.igormaznitsa.jcp.containers.FileInfoContainer;
2931
import com.igormaznitsa.jcp.containers.PreprocessingFlag;
3032
import com.igormaznitsa.jcp.containers.TextFileDataContainer;
3133
import com.igormaznitsa.jcp.exceptions.FilePositionInfo;
3234
import com.igormaznitsa.jcp.exceptions.PreprocessorException;
3335
import com.igormaznitsa.jcp.utils.PreprocessorUtils;
34-
import com.igormaznitsa.jcp.utils.ResetablePrinter;
36+
import com.igormaznitsa.jcp.utils.ResettablePrinter;
3537
import java.io.BufferedInputStream;
3638
import java.io.BufferedOutputStream;
3739
import java.io.BufferedWriter;
@@ -52,7 +54,6 @@
5254
import java.util.EnumSet;
5355
import java.util.LinkedList;
5456
import java.util.List;
55-
import java.util.Objects;
5657
import java.util.Optional;
5758
import java.util.Set;
5859
import java.util.concurrent.atomic.AtomicBoolean;
@@ -79,15 +80,15 @@ public final class PreprocessingState {
7980
private final LinkedList<TextFileDataContainer> ifStack = new LinkedList<>();
8081
private final LinkedList<TextFileDataContainer> includeStack = new LinkedList<>();
8182
private final LinkedList<ExcludeIfInfo> deferredExcludeStack = new LinkedList<>();
82-
private final ResetablePrinter prefixPrinter = new ResetablePrinter(1024);
83-
private final ResetablePrinter postfixPrinter = new ResetablePrinter(64 * 1024);
84-
private final ResetablePrinter normalPrinter = new ResetablePrinter(1024);
83+
private final ResettablePrinter prefixPrinter = new ResettablePrinter(1024);
84+
private final ResettablePrinter postfixPrinter = new ResettablePrinter(64 * 1024);
85+
private final ResettablePrinter normalPrinter = new ResettablePrinter(1024);
8586
private final boolean overrideOnlyIfContentChanged;
8687
private final EnumSet<PreprocessingFlag> preprocessingFlags =
8788
EnumSet.noneOf(PreprocessingFlag.class);
8889
private final PreprocessorContext context;
8990
private final boolean mockMode;
90-
private ResetablePrinter currentPrinter;
91+
private ResettablePrinter selectedPrinter;
9192
private TextFileDataContainer activeIf;
9293
private TextFileDataContainer activeWhile;
9394
private String lastReadString;
@@ -96,8 +97,8 @@ public final class PreprocessingState {
9697
PreprocessingState(final PreprocessorContext context, final Charset inEncoding,
9798
final Charset outEncoding) {
9899
this.mockMode = true;
99-
this.globalInCharacterEncoding = Objects.requireNonNull(inEncoding);
100-
this.globalOutCharacterEncoding = Objects.requireNonNull(outEncoding);
100+
this.globalInCharacterEncoding = requireNonNull(inEncoding);
101+
this.globalOutCharacterEncoding = requireNonNull(outEncoding);
101102
this.rootReference = null;
102103
this.lastReadString = "";
103104
this.rootFileInfo = new FileInfoContainer(new File("global"), "global", true);
@@ -114,10 +115,10 @@ public final class PreprocessingState {
114115
this.context = context;
115116

116117
this.overrideOnlyIfContentChanged = overrideOnlyIfContentChanged;
117-
this.globalInCharacterEncoding = Objects.requireNonNull(inEncoding);
118-
this.globalOutCharacterEncoding = Objects.requireNonNull(outEncoding);
118+
this.globalInCharacterEncoding = requireNonNull(inEncoding);
119+
this.globalOutCharacterEncoding = requireNonNull(outEncoding);
119120

120-
this.rootFileInfo = Objects.requireNonNull(rootFile, "The root file is null");
121+
this.rootFileInfo = requireNonNull(rootFile, "The root file is null");
121122
init();
122123
rootReference = openFile(rootFile.getSourceFile());
123124
}
@@ -129,11 +130,11 @@ public final class PreprocessingState {
129130

130131
this.context = context;
131132

132-
this.globalInCharacterEncoding = Objects.requireNonNull(inEncoding);
133-
this.globalOutCharacterEncoding = Objects.requireNonNull(outEncoding);
133+
this.globalInCharacterEncoding = requireNonNull(inEncoding);
134+
this.globalOutCharacterEncoding = requireNonNull(outEncoding);
134135
this.overrideOnlyIfContentChanged = overrideOnlyIfContentChanged;
135136

136-
this.rootFileInfo = Objects.requireNonNull(rootFile, "The root file is null");
137+
this.rootFileInfo = requireNonNull(rootFile, "The root file is null");
137138
init();
138139
rootReference = rootContainer;
139140
includeStack.push(rootContainer);
@@ -161,8 +162,8 @@ public String getLastReadString() {
161162

162163
public void pushExcludeIfData(final FileInfoContainer infoContainer,
163164
final String excludeIfCondition, final int stringIndex) {
164-
Objects.requireNonNull(infoContainer, "File info is null");
165-
Objects.requireNonNull(excludeIfCondition, "Condition is null");
165+
requireNonNull(infoContainer, "File info is null");
166+
requireNonNull(excludeIfCondition, "Condition is null");
166167

167168
if (stringIndex < 0) {
168169
throw new IllegalArgumentException("Unexpected string index [" + stringIndex + ']');
@@ -171,6 +172,9 @@ public void pushExcludeIfData(final FileInfoContainer infoContainer,
171172
deferredExcludeStack.push(new ExcludeIfInfo(infoContainer, excludeIfCondition, stringIndex));
172173
}
173174

175+
public ResettablePrinter getSelectedPrinter() {
176+
return this.selectedPrinter;
177+
}
174178

175179
public List<ExcludeIfInfo> popAllExcludeIfInfoData() {
176180
final List<ExcludeIfInfo> result = new ArrayList<>(deferredExcludeStack);
@@ -188,22 +192,29 @@ public Set<PreprocessingFlag> getPreprocessingFlags() {
188192
return preprocessingFlags;
189193
}
190194

191-
192-
public ResetablePrinter getPrinter() throws IOException {
193-
return currentPrinter;
195+
public ResettablePrinter findPrinter(final PrinterType type) {
196+
switch (requireNonNull(type, "Type is null")) {
197+
case NORMAL:
198+
return this.normalPrinter;
199+
case POSTFIX:
200+
return this.postfixPrinter;
201+
case PREFIX:
202+
return this.prefixPrinter;
203+
default:
204+
throw new IllegalArgumentException("Unsupported type detected [" + type.name() + ']');
205+
}
194206
}
195207

196-
public void setPrinter(final PrinterType type) {
197-
Objects.requireNonNull(type, "Type is null");
198-
switch (type) {
208+
public void selectPrinter(final PrinterType type) {
209+
switch (requireNonNull(type, "Type is null")) {
199210
case NORMAL:
200-
currentPrinter = normalPrinter;
211+
this.selectedPrinter = this.normalPrinter;
201212
break;
202213
case POSTFIX:
203-
currentPrinter = postfixPrinter;
214+
this.selectedPrinter = this.postfixPrinter;
204215
break;
205216
case PREFIX:
206-
currentPrinter = prefixPrinter;
217+
this.selectedPrinter = this.prefixPrinter;
207218
break;
208219
default:
209220
throw new IllegalArgumentException("Unsupported type detected [" + type.name() + ']');
@@ -217,7 +228,7 @@ public TextFileDataContainer getRootTextContainer() {
217228

218229

219230
public TextFileDataContainer openFile(final File file) throws IOException {
220-
Objects.requireNonNull(file, "The file is null");
231+
requireNonNull(file, "The file is null");
221232

222233
final AtomicBoolean endedByNextLineContainer = new AtomicBoolean();
223234

@@ -276,7 +287,6 @@ public TextFileDataContainer popTextContainer() {
276287
return this.includeStack.pop();
277288
}
278289

279-
280290
public FileInfoContainer getRootFileInfo() {
281291
return rootFileInfo;
282292
}
@@ -422,15 +432,50 @@ private void init() {
422432
preprocessingFlags.clear();
423433
resetPrinters();
424434

425-
setPrinter(PrinterType.NORMAL);
435+
selectPrinter(PrinterType.NORMAL);
426436
}
427437

428438
public void resetPrinters() {
429439
normalPrinter.reset();
430440
prefixPrinter.reset();
431441
postfixPrinter.reset();
432442

433-
currentPrinter = normalPrinter;
443+
selectedPrinter = normalPrinter;
444+
}
445+
446+
public void setBufferText(final String text) {
447+
this.prefixPrinter.reset();
448+
this.normalPrinter.reset();
449+
this.postfixPrinter.reset();
450+
this.setBufferText(text, PrinterType.NORMAL);
451+
}
452+
453+
public void setBufferText(final String text, final PrinterType printerType) {
454+
switch (printerType) {
455+
case NORMAL: {
456+
this.normalPrinter.reset();
457+
this.normalPrinter.print(requireNonNullElse(text, ""));
458+
}
459+
break;
460+
case PREFIX: {
461+
this.prefixPrinter.reset();
462+
this.prefixPrinter.print(requireNonNullElse(text, ""));
463+
}
464+
break;
465+
case POSTFIX: {
466+
this.postfixPrinter.reset();
467+
this.postfixPrinter.print(requireNonNullElse(text, ""));
468+
}
469+
break;
470+
default:
471+
throw new IllegalArgumentException("Unsupported printer type: " + printerType);
472+
}
473+
}
474+
475+
public String getCurrentText() {
476+
return this.prefixPrinter.getText()
477+
+ this.normalPrinter.getText()
478+
+ this.postfixPrinter.getText();
434479
}
435480

436481
public void saveBuffersToStreams(final OutputStream prefix, final OutputStream normal,

jcp/src/main/java/com/igormaznitsa/jcp/directives/PostfixDirectiveHandler.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,11 +57,11 @@ public AfterDirectiveProcessingBehaviour execute(final String string,
5757
if (!string.isEmpty()) {
5858
switch (string.charAt(0)) {
5959
case '+': {
60-
state.setPrinter(PreprocessingState.PrinterType.POSTFIX);
60+
state.selectPrinter(PreprocessingState.PrinterType.POSTFIX);
6161
}
6262
break;
6363
case '-': {
64-
state.setPrinter(PreprocessingState.PrinterType.NORMAL);
64+
state.selectPrinter(PreprocessingState.PrinterType.NORMAL);
6565
}
6666
break;
6767
default: {

jcp/src/main/java/com/igormaznitsa/jcp/directives/PrefixDirectiveHandler.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,11 +57,11 @@ public AfterDirectiveProcessingBehaviour execute(final String string,
5757
if (!string.isEmpty()) {
5858
switch (string.charAt(0)) {
5959
case '+': {
60-
state.setPrinter(PreprocessingState.PrinterType.PREFIX);
60+
state.selectPrinter(PreprocessingState.PrinterType.PREFIX);
6161
}
6262
break;
6363
case '-': {
64-
state.setPrinter(PreprocessingState.PrinterType.NORMAL);
64+
state.selectPrinter(PreprocessingState.PrinterType.NORMAL);
6565
}
6666
break;
6767
default: {

jcp/src/main/java/com/igormaznitsa/jcp/extension/PreprocessorExtension.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@
3636
*/
3737
public interface PreprocessorExtension extends ExecutionAllowable {
3838

39+
/**
40+
* Undefined arity. In case of functions it means to check only name.
41+
*/
3942
int ANY_ARITY = -1;
4043

4144
@Override

0 commit comments

Comments
 (0)