Skip to content

Commit df3e098

Browse files
committed
More changes to have a more error prone system for dumping the NgxEntry instances
1 parent d308122 commit df3e098

File tree

12 files changed

+225
-71
lines changed

12 files changed

+225
-71
lines changed

pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,8 @@
8989
<artifactId>maven-compiler-plugin</artifactId>
9090
<version>3.5.1</version>
9191
<configuration>
92-
<source>1.7</source>
93-
<target>1.7</target>
92+
<source>1.8</source>
93+
<target>1.8</target>
9494
<encoding>UTF-8</encoding>
9595
</configuration>
9696
</plugin>

src/main/java/com/github/odiszapc/nginxparser/NgxAbstractEntry.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
import java.util.List;
2323

2424
public abstract class NgxAbstractEntry implements NgxEntry {
25-
private Collection<NgxToken> tokens = new ArrayList<NgxToken>();
25+
private Collection<NgxToken> tokens = new ArrayList<>();
2626

2727
public NgxAbstractEntry(String... rawValues) {
2828
for (String val : rawValues) {

src/main/java/com/github/odiszapc/nginxparser/NgxBlock.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public void addEntry(NgxEntry entry) {
3737

3838
@Override
3939
public String toString() {
40-
return super.toString() + " {";
40+
return super.toString();
4141
}
4242

4343

@@ -140,4 +140,11 @@ public <T extends NgxEntry> List<NgxEntry> findAll(Class<T> clazz, List<NgxEntry
140140

141141
return res;
142142
}
143+
144+
@Override
145+
public void write(NgxPrintWriter writer) {
146+
writer.openBlock(toString())
147+
.write(getEntries())
148+
.closeBlock();
149+
}
143150
}

src/main/java/com/github/odiszapc/nginxparser/NgxComment.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,9 @@ public String getValue() {
3434
public String toString() {
3535
return "#" + getValue();
3636
}
37+
38+
@Override
39+
public void write(NgxPrintWriter printWriter) {
40+
printWriter.appendLine(toString());
41+
}
3742
}

src/main/java/com/github/odiszapc/nginxparser/NgxDumper.java

Lines changed: 62 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -16,94 +16,96 @@
1616

1717
package com.github.odiszapc.nginxparser;
1818

19+
import java.io.ByteArrayOutputStream;
20+
import java.io.IOException;
1921
import java.io.OutputStream;
20-
import java.io.PrintWriter;
21-
import java.io.StringWriter;
22+
import java.nio.file.Files;
23+
import java.nio.file.Path;
24+
import java.nio.file.Paths;
25+
import java.nio.file.StandardOpenOption;
26+
import java.util.Iterator;
2227

2328
/**
2429
* NgxDumper is used to serialize an existing or manually created NgxConfig object
2530
*/
2631
public class NgxDumper {
2732

2833
private NgxConfig config;
29-
private final static int PAD_SIZE = 2;
30-
private final static String PAD_SYMBOL = " ";
31-
private final static String LBRACE = "{";
32-
private final static String RBRACE = "}";
33-
private final static String LF = "\n";
34-
private final static String CRLF = "\r\n";
3534

3635
public NgxDumper(NgxConfig config) {
3736
this.config = config;
3837
}
3938

39+
/**
40+
* Dump the content of the config to a file.
41+
*
42+
* This method is used to write the NgxConfig directly to a file.
43+
*
44+
* If the file does not exist, it will be created.
45+
*
46+
* @param path the {@link Path} the config should be written to
47+
* @throws IOException if anything goes wrong while writing or if the file is not writable
48+
*/
49+
public void dumpToFile(Path path) throws IOException {
50+
if(!Files.exists(path)) {
51+
Files.createFile(path);
52+
}
53+
if(!Files.isWritable(path)) {
54+
throw new IOException("The file cannot be written to: " + path);
55+
}
56+
57+
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
58+
dump(outputStream);
59+
Files.write(path, outputStream.toByteArray(), StandardOpenOption.TRUNCATE_EXISTING);
60+
}
61+
62+
/**
63+
* Dump the content of the config to a file.
64+
*
65+
* This method is for convenience and redirects directly to {@link #dumpToFile(Path)}
66+
*
67+
* @param destination the file the config should be written to
68+
* @throws IOException if anything goes wrong while writing
69+
* @see #dumpToFile(Path)
70+
*/
71+
public void dumpToFile(String destination) throws IOException {
72+
dumpToFile(Paths.get(destination));
73+
}
74+
4075
/**
4176
* Converts config int String
77+
*
4278
* @return Serialized config
4379
*/
4480
public String dump() {
45-
StringWriter writer = new StringWriter();
46-
writeToStream(config, new PrintWriter(writer), 0);
47-
return writer.toString();
81+
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
82+
writeToStream(config, outputStream);
83+
return outputStream.toString();
4884
}
4985

5086
/**
5187
* Serializes config and sends result to the provided OutputStream
88+
*
5289
* @param out stream to write to
5390
*/
5491
public void dump(OutputStream out) {
55-
writeToStream(config, new PrintWriter(out), 0);
92+
writeToStream(config, out);
5693
}
5794

58-
private void writeToStream(NgxBlock config, PrintWriter writer, int level) {
59-
for (NgxEntry entry : config) {
60-
NgxEntryType type = NgxEntryType.fromClass(entry.getClass());
61-
switch (type) {
62-
case BLOCK:
63-
NgxBlock block = (NgxBlock) entry;
64-
writer.append(getOffset(level))
65-
.append(block.toString())
66-
.append(getLineEnding());
67-
writeToStream(block, writer, level + 1);
68-
writer
69-
.append(getOffset(level))
70-
.append(RBRACE)
71-
.append(getLineEnding());
72-
break;
73-
case IF:
74-
NgxIfBlock ifBlock = (NgxIfBlock) entry;
75-
writer
76-
.append(getOffset(level))
77-
.append(ifBlock.toString())
78-
.append(LBRACE)
79-
.append(getLineEnding());
80-
writeToStream(ifBlock, writer, level + 1);
81-
writer
82-
.append(getOffset(level))
83-
.append(RBRACE)
84-
.append(getLineEnding());
85-
break;
86-
case COMMENT:
87-
case PARAM:
88-
writer
89-
.append(getOffset(level))
90-
.append(entry.toString())
91-
.append(getLineEnding());
92-
break;
95+
private void writeToStream(NgxBlock config, OutputStream outputStream) {
96+
try (NgxPrintWriter writer = new NgxPrintWriter(outputStream)) {
97+
Iterator<NgxEntry> iterator = config.iterator();
98+
while (iterator.hasNext()) {
99+
NgxEntry current = iterator.next();
100+
current.write(writer);
101+
if (current instanceof NgxBlock && iterator.hasNext()) {
102+
// Extra new line, between two top level blocks
103+
writer.newLine();
104+
}
93105
}
106+
} catch (Exception e) {
107+
// TODO Better Exception handling, like custom Exception types within a custom hierarchy
108+
throw new IllegalStateException(e);
94109
}
95-
writer.flush();
96-
}
97-
98-
public String getOffset(int level) {
99-
String offset = "";
100-
for (int i = 0; i < level; i++) {
101-
offset += PAD_SYMBOL;
102-
}
103-
return offset;
104-
}
105-
106-
public String getLineEnding() {
107-
return LF;
108110
}
109111
}

src/main/java/com/github/odiszapc/nginxparser/NgxEntry.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616

1717
package com.github.odiszapc.nginxparser;
1818

19-
2019
public interface NgxEntry {
21-
20+
void write(NgxPrintWriter printWriter);
2221
}

src/main/java/com/github/odiszapc/nginxparser/NgxIfBlock.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
public class NgxIfBlock extends NgxBlock {
2222

23+
@Override
2324
public String toString() {
2425
ArrayList<NgxToken> tokens = new ArrayList<>(getTokens());
2526
String ifToken = tokens.remove(0).getToken(); // The "if"
@@ -33,6 +34,6 @@ public String toString() {
3334

3435
String result = tokenBuilder.toString();
3536

36-
return result.substring(0, result.length() -1) + ") ";
37+
return result.substring(0, result.length() -1) + ")";
3738
}
3839
}

src/main/java/com/github/odiszapc/nginxparser/NgxParam.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,9 @@ public String toString() {
3030

3131
return s + ";";
3232
}
33+
34+
@Override
35+
public void write(NgxPrintWriter printWriter) {
36+
printWriter.appendLine(toString());
37+
}
3338
}
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
package com.github.odiszapc.nginxparser;
2+
3+
import java.io.OutputStream;
4+
import java.io.PrintWriter;
5+
import java.util.Collection;
6+
7+
public class NgxPrintWriter implements AutoCloseable {
8+
9+
private final static String PAD_SYMBOL = " ";
10+
private final static String LBRACE = "{";
11+
private final static String RBRACE = "}";
12+
private final static String LF = "\n";
13+
private final PrintWriter printWriter;
14+
private int level = 0;
15+
16+
public NgxPrintWriter(OutputStream outputStream) {
17+
this.printWriter = new PrintWriter(outputStream);
18+
}
19+
20+
public NgxPrintWriter openBlock(String prefix) {
21+
append(prefix);
22+
printWriter.append(" ").append(LBRACE);
23+
level += 1;
24+
25+
return newLine();
26+
}
27+
28+
public NgxPrintWriter closeBlock() {
29+
level -= 1;
30+
append(RBRACE);
31+
32+
return newLine();
33+
}
34+
35+
public NgxPrintWriter newLine() {
36+
printWriter.append(LF);
37+
38+
return this;
39+
}
40+
41+
public NgxPrintWriter append(String string) {
42+
this.printWriter.append(constructOffset(level))
43+
.append(string);
44+
45+
return this;
46+
}
47+
48+
public NgxPrintWriter appendLine(String string) {
49+
this.printWriter.append(constructOffset(level))
50+
.append(string)
51+
.append(LF);
52+
53+
return this;
54+
}
55+
56+
public NgxPrintWriter write(Collection<NgxEntry> entries) {
57+
for (NgxEntry entry : entries) {
58+
entry.write(this);
59+
}
60+
61+
return this;
62+
}
63+
64+
public void flush() {
65+
printWriter.flush();
66+
}
67+
68+
private String constructOffset(int level) {
69+
StringBuilder offset = new StringBuilder();
70+
for (int i = 0; i < level; i++) {
71+
offset.append(PAD_SYMBOL);
72+
}
73+
return offset.toString();
74+
}
75+
76+
@Override
77+
public void close() {
78+
printWriter.close();
79+
}
80+
}

src/test/java/com/github/odiszapc/nginxparser/AlterConfigTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ public void removeOneLocation() throws Exception {
2121
" }\n" +
2222
"}\n";
2323

24-
assertEquals(new NgxDumper(conf).dump(), expected);
24+
assertEquals(expected, new NgxDumper(conf).dump());
2525
}
2626

2727
@Test

src/test/java/com/github/odiszapc/nginxparser/DumperTest.java

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public void testC1() throws Exception {
2929
"timer_resolution 100ms;\n" +
3030
"worker_rlimit_nofile 8192;\n" +
3131
"worker_priority -10;\n";
32-
Assert.assertEquals(TestUtils.dump("common/c1.conf"), expected);
32+
Assert.assertEquals(expected, TestUtils.dump("common/c1.conf"));
3333
}
3434

3535
@Test
@@ -41,7 +41,7 @@ public void testC2() throws Exception {
4141
" worker_connections 2048;\n" +
4242
" use epoll;\n" +
4343
"}\n";
44-
Assert.assertEquals(TestUtils.dump("common/c2.conf"), expected);
44+
Assert.assertEquals(expected, TestUtils.dump("common/c2.conf"));
4545
}
4646

4747
@Test
@@ -51,6 +51,39 @@ public void testC3() throws Exception {
5151
"#worker_processes 2;\n" +
5252
"worker_priority -10;\n" +
5353
"proxy_pass http://unix:/opt/apps/ipn/ipn.sock:/;\n";
54-
Assert.assertEquals(TestUtils.dump("common/c3.conf"), expected);
54+
Assert.assertEquals(expected, TestUtils.dump("common/c3.conf"));
55+
}
56+
57+
@Test
58+
public void testC8() throws Exception {
59+
final String expected = "" +
60+
"server {\n" +
61+
" if ($host == test.example.com) {\n" +
62+
" return 301 https://$host$request_uri;\n" +
63+
" }\n" +
64+
" # managed by certbot\n" +
65+
""+
66+
" listen 80;\n" +
67+
" return 404;\n" +
68+
" # managed by Certbot\n" +
69+
"}\n" +
70+
"\n" +
71+
"server {\n" +
72+
" server_name test.example.com;\n" +
73+
" location / {\n" +
74+
" proxy_pass http://localhost:8080;\n" +
75+
" }\n" +
76+
" listen 443 ssl;\n" +
77+
" # managed by Certbot\n" +
78+
" ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;\n" +
79+
" # managed by Certbot\n" +
80+
" ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;\n" +
81+
" # managed by Certbot\n" +
82+
" include /etc/letsencrypt/options-ssl-nginx.conf;\n" +
83+
" # managed by Certbot\n" +
84+
" ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;\n" +
85+
" # managed by Certbot\n" +
86+
"}\n";
87+
Assert.assertEquals(expected, TestUtils.dump("common/c8.conf"));
5588
}
5689
}

0 commit comments

Comments
 (0)