Skip to content

Commit 01ccc2a

Browse files
committed
Add write
1 parent dd239d2 commit 01ccc2a

File tree

1 file changed

+67
-0
lines changed
  • src/main/java/org/codehaus/plexus/components/secdispatcher/internal

1 file changed

+67
-0
lines changed

src/main/java/org/codehaus/plexus/components/secdispatcher/internal/SecUtil.java

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,26 @@
1717

1818
import java.io.IOException;
1919
import java.io.InputStream;
20+
import java.io.OutputStream;
21+
import java.nio.ByteBuffer;
22+
import java.nio.charset.StandardCharsets;
2023
import java.nio.file.Files;
2124
import java.nio.file.NoSuchFileException;
2225
import java.nio.file.Path;
26+
import java.nio.file.StandardCopyOption;
2327
import java.util.HashMap;
2428
import java.util.LinkedHashSet;
2529
import java.util.List;
2630
import java.util.Map;
31+
import java.util.concurrent.ThreadLocalRandom;
2732

33+
import org.codehaus.plexus.components.secdispatcher.SecDispatcher;
2834
import org.codehaus.plexus.components.secdispatcher.SecDispatcherException;
2935
import org.codehaus.plexus.components.secdispatcher.model.Config;
3036
import org.codehaus.plexus.components.secdispatcher.model.ConfigProperty;
3137
import org.codehaus.plexus.components.secdispatcher.model.SettingsSecurity;
3238
import org.codehaus.plexus.components.secdispatcher.model.io.stax.SecurityConfigurationStaxReader;
39+
import org.codehaus.plexus.components.secdispatcher.model.io.stax.SecurityConfigurationStaxWriter;
3340

3441
import static java.util.Objects.requireNonNull;
3542

@@ -102,4 +109,64 @@ public static Map<String, String> getConfig(SettingsSecurity sec, String name) {
102109
}
103110
return null;
104111
}
112+
113+
public static void write(Path target, SettingsSecurity configuration) throws IOException {
114+
requireNonNull(target, "file must not be null");
115+
requireNonNull(configuration, "sec must not be null");
116+
configuration.setModelVersion(SecDispatcher.class.getPackage().getImplementationVersion());
117+
configuration.setModelEncoding(StandardCharsets.UTF_8.name());
118+
writeFile(target, configuration, false);
119+
}
120+
121+
public static void writeWithBackup(Path target, SettingsSecurity configuration) throws IOException {
122+
requireNonNull(target, "file must not be null");
123+
requireNonNull(configuration, "sec must not be null");
124+
configuration.setModelVersion(SecDispatcher.class.getPackage().getImplementationVersion());
125+
configuration.setModelEncoding(StandardCharsets.UTF_8.name());
126+
writeFile(target, configuration, true);
127+
}
128+
129+
private static final boolean IS_WINDOWS =
130+
System.getProperty("os.name", "unknown").startsWith("Windows");
131+
132+
private static void writeFile(Path target, SettingsSecurity configuration, boolean doBackup) throws IOException {
133+
requireNonNull(target, "target is null");
134+
Path parent = requireNonNull(target.getParent(), "target must have parent");
135+
Files.createDirectories(parent);
136+
Path tempFile = parent.resolve(target.getFileName() + "."
137+
+ Long.toUnsignedString(ThreadLocalRandom.current().nextLong()) + ".tmp");
138+
try (OutputStream out = Files.newOutputStream(tempFile)) {
139+
new SecurityConfigurationStaxWriter().write(out, configuration);
140+
if (doBackup && Files.isRegularFile(target)) {
141+
Files.copy(target, parent.resolve(target.getFileName() + ".bak"), StandardCopyOption.REPLACE_EXISTING);
142+
}
143+
if (IS_WINDOWS) {
144+
copy(tempFile, target);
145+
} else {
146+
Files.move(tempFile, target, StandardCopyOption.REPLACE_EXISTING);
147+
}
148+
} catch (XMLStreamException e) {
149+
throw new IOException("XML Processing error", e);
150+
} finally {
151+
Files.deleteIfExists(tempFile);
152+
}
153+
}
154+
155+
/**
156+
* On Windows we use pre-NIO2 way to copy files, as for some reason it works. Beat me why.
157+
*/
158+
private static void copy(Path source, Path target) throws IOException {
159+
ByteBuffer buffer = ByteBuffer.allocate(1024 * 32);
160+
byte[] array = buffer.array();
161+
try (InputStream is = Files.newInputStream(source);
162+
OutputStream os = Files.newOutputStream(target)) {
163+
while (true) {
164+
int bytes = is.read(array);
165+
if (bytes < 0) {
166+
break;
167+
}
168+
os.write(array, 0, bytes);
169+
}
170+
}
171+
}
105172
}

0 commit comments

Comments
 (0)