mirror of
https://github.com/scm-manager/scm-manager.git
synced 2026-01-31 03:39:14 +01:00
Include filename of corrupt file in store exception
This commit is contained in:
committed by
Thomas Zerr
parent
a378ad97e3
commit
e98a6ff093
2
gradle/changelog/error.yaml
Normal file
2
gradle/changelog/error.yaml
Normal file
@@ -0,0 +1,2 @@
|
||||
- type: fixed
|
||||
description: Enhanced error message including filename of corrupt file
|
||||
@@ -123,92 +123,99 @@ class JAXBConfigurationEntryStore<V> implements ConfigurationEntryStore<V> {
|
||||
private void load() {
|
||||
LOG.debug("load configuration from {}", file);
|
||||
execute(() ->
|
||||
context.withUnmarshaller(u -> {
|
||||
try (AutoCloseableXMLReader reader = XmlStreams.createReader(file)) {
|
||||
context.withUnmarshaller(
|
||||
u -> {
|
||||
try (AutoCloseableXMLReader reader = XmlStreams.createReader(file)) {
|
||||
|
||||
// configuration
|
||||
reader.nextTag();
|
||||
|
||||
// entry start
|
||||
reader.nextTag();
|
||||
|
||||
while (reader.isStartElement() && reader.getLocalName().equals(TAG_ENTRY)) {
|
||||
|
||||
// read key
|
||||
// configuration
|
||||
reader.nextTag();
|
||||
|
||||
String key = reader.getElementText();
|
||||
|
||||
// read value
|
||||
// entry start
|
||||
reader.nextTag();
|
||||
|
||||
JAXBElement<V> element = u.unmarshal(reader, type);
|
||||
while (reader.isStartElement() && reader.getLocalName().equals(TAG_ENTRY)) {
|
||||
|
||||
if (!element.isNil()) {
|
||||
V v = element.getValue();
|
||||
|
||||
LOG.trace("add element {} to configuration entry store", v);
|
||||
|
||||
entries.put(key, v);
|
||||
} else {
|
||||
LOG.warn("could not unmarshall object of entry store");
|
||||
}
|
||||
|
||||
// closed or new entry tag
|
||||
if (reader.nextTag() == END_ELEMENT) {
|
||||
|
||||
// fixed format, start new entry
|
||||
// read key
|
||||
reader.nextTag();
|
||||
|
||||
String key = reader.getElementText();
|
||||
|
||||
// read value
|
||||
reader.nextTag();
|
||||
|
||||
JAXBElement<V> element = u.unmarshal(reader, type);
|
||||
|
||||
if (!element.isNil()) {
|
||||
V v = element.getValue();
|
||||
|
||||
LOG.trace("add element {} to configuration entry store", v);
|
||||
|
||||
entries.put(key, v);
|
||||
} else {
|
||||
LOG.warn("could not unmarshall object of entry store");
|
||||
}
|
||||
|
||||
// closed or new entry tag
|
||||
if (reader.nextTag() == END_ELEMENT) {
|
||||
|
||||
// fixed format, start new entry
|
||||
reader.nextTag();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})).withLockedFileForRead(file);
|
||||
},
|
||||
file.getAbsoluteFile()
|
||||
)
|
||||
).withLockedFileForRead(file);
|
||||
}
|
||||
|
||||
private void store() {
|
||||
LOG.debug("store configuration to {}", file);
|
||||
|
||||
context.withMarshaller(m -> {
|
||||
m.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
|
||||
context.withMarshaller(
|
||||
m -> {
|
||||
m.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
|
||||
|
||||
CopyOnWrite.withTemporaryFile(
|
||||
temp -> {
|
||||
try (AutoCloseableXMLWriter writer = XmlStreams.createWriter(temp)) {
|
||||
writer.writeStartDocument();
|
||||
CopyOnWrite.withTemporaryFile(
|
||||
temp -> {
|
||||
try (AutoCloseableXMLWriter writer = XmlStreams.createWriter(temp)) {
|
||||
writer.writeStartDocument();
|
||||
|
||||
// configuration start
|
||||
writer.writeStartElement(TAG_CONFIGURATION);
|
||||
writer.writeAttribute("type", "config-entry");
|
||||
// configuration start
|
||||
writer.writeStartElement(TAG_CONFIGURATION);
|
||||
writer.writeAttribute("type", "config-entry");
|
||||
|
||||
for (Entry<String, V> e : entries.entrySet()) {
|
||||
for (Entry<String, V> e : entries.entrySet()) {
|
||||
|
||||
// entry start
|
||||
writer.writeStartElement(TAG_ENTRY);
|
||||
// entry start
|
||||
writer.writeStartElement(TAG_ENTRY);
|
||||
|
||||
// key start
|
||||
writer.writeStartElement(TAG_KEY);
|
||||
writer.writeCharacters(e.getKey());
|
||||
// key start
|
||||
writer.writeStartElement(TAG_KEY);
|
||||
writer.writeCharacters(e.getKey());
|
||||
|
||||
// key end
|
||||
writer.writeEndElement();
|
||||
|
||||
// value
|
||||
JAXBElement<V> je = new JAXBElement<>(QName.valueOf(TAG_VALUE), type,
|
||||
e.getValue());
|
||||
|
||||
m.marshal(je, writer);
|
||||
|
||||
// entry end
|
||||
// key end
|
||||
writer.writeEndElement();
|
||||
|
||||
// value
|
||||
JAXBElement<V> je = new JAXBElement<>(QName.valueOf(TAG_VALUE), type,
|
||||
e.getValue());
|
||||
|
||||
m.marshal(je, writer);
|
||||
|
||||
// entry end
|
||||
writer.writeEndElement();
|
||||
}
|
||||
|
||||
// configuration end
|
||||
writer.writeEndElement();
|
||||
writer.writeEndDocument();
|
||||
}
|
||||
|
||||
// configuration end
|
||||
writer.writeEndElement();
|
||||
writer.writeEndDocument();
|
||||
}
|
||||
},
|
||||
file.toPath()
|
||||
);
|
||||
});
|
||||
},
|
||||
file.toPath()
|
||||
);
|
||||
},
|
||||
file.getAbsoluteFile()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,33 +64,35 @@ final class TypedStoreContext<T> {
|
||||
T unmarshal(File file) {
|
||||
log.trace("unmarshal file {}", file);
|
||||
AtomicReference<T> ref = new AtomicReference<>();
|
||||
withUnmarshaller(unmarshaller -> {
|
||||
T value = parameters.getType().cast(unmarshaller.unmarshal(file));
|
||||
ref.set(value);
|
||||
});
|
||||
withUnmarshaller(
|
||||
unmarshaller -> {
|
||||
T value = parameters.getType().cast(unmarshaller.unmarshal(file));
|
||||
ref.set(value);
|
||||
},
|
||||
file.getAbsoluteFile());
|
||||
return ref.get();
|
||||
}
|
||||
|
||||
void marshal(Object object, File file) {
|
||||
log.trace("marshal file {}", file);
|
||||
withMarshaller(marshaller -> marshaller.marshal(object, XmlStreams.createWriter(file)));
|
||||
withMarshaller(marshaller -> marshaller.marshal(object, XmlStreams.createWriter(file)), file.getAbsoluteFile());
|
||||
}
|
||||
|
||||
void withMarshaller(ThrowingConsumer<Marshaller> consumer) {
|
||||
void withMarshaller(ThrowingConsumer<Marshaller> consumer, Object context) {
|
||||
Marshaller marshaller = createMarshaller();
|
||||
withClassLoader(consumer, marshaller);
|
||||
withClassLoader(consumer, marshaller, context);
|
||||
}
|
||||
|
||||
void withUnmarshaller(ThrowingConsumer<Unmarshaller> consumer) {
|
||||
void withUnmarshaller(ThrowingConsumer<Unmarshaller> consumer, Object context) {
|
||||
Unmarshaller unmarshaller = createUnmarshaller();
|
||||
withClassLoader(consumer, unmarshaller);
|
||||
withClassLoader(consumer, unmarshaller, context);
|
||||
}
|
||||
|
||||
Class<T> getType() {
|
||||
return parameters.getType();
|
||||
}
|
||||
|
||||
private <C> void withClassLoader(ThrowingConsumer<C> consumer, C consume) {
|
||||
private <C> void withClassLoader(ThrowingConsumer<C> consumer, C consume, Object context) {
|
||||
ClassLoader contextClassLoader = null;
|
||||
Optional<ClassLoader> classLoader = parameters.getClassLoader();
|
||||
if (classLoader.isPresent()) {
|
||||
@@ -100,7 +102,7 @@ final class TypedStoreContext<T> {
|
||||
try {
|
||||
consumer.consume(consume);
|
||||
} catch (Exception e) {
|
||||
throw new StoreException("failure during marshalling/unmarshalling", e);
|
||||
throw new StoreException("failure during marshalling/unmarshalling '" + context + "'", e);
|
||||
} finally {
|
||||
if (contextClassLoader != null) {
|
||||
Thread.currentThread().setContextClassLoader(contextClassLoader);
|
||||
@@ -135,7 +137,8 @@ final class TypedStoreContext<T> {
|
||||
|
||||
@FunctionalInterface
|
||||
interface ThrowingConsumer<T> {
|
||||
@SuppressWarnings("java:S112") // we need to throw Exception here
|
||||
@SuppressWarnings("java:S112")
|
||||
// we need to throw Exception here
|
||||
void consume(T item) throws Exception;
|
||||
}
|
||||
|
||||
|
||||
@@ -59,16 +59,19 @@ class TypedStoreContextTest {
|
||||
|
||||
File file = tempDir.resolve("test.xml").toFile();
|
||||
|
||||
context.withMarshaller(marshaller -> {
|
||||
marshaller.marshal(new Sample("wow"), file);
|
||||
});
|
||||
context.withMarshaller(
|
||||
marshaller -> {
|
||||
marshaller.marshal(new Sample("wow"), file);
|
||||
},
|
||||
file);
|
||||
|
||||
AtomicReference<Sample> ref = new AtomicReference<>();
|
||||
|
||||
context.withUnmarshaller(unmarshaller -> {
|
||||
Sample sample = (Sample) unmarshaller.unmarshal(file);
|
||||
ref.set(sample);
|
||||
});
|
||||
context.withUnmarshaller(
|
||||
unmarshaller -> {
|
||||
Sample sample = (Sample) unmarshaller.unmarshal(file);
|
||||
ref.set(sample);
|
||||
}, file);
|
||||
|
||||
assertThat(ref.get().value).isEqualTo("wow");
|
||||
}
|
||||
@@ -85,9 +88,12 @@ class TypedStoreContextTest {
|
||||
TypedStoreContext<Sample> context = TypedStoreContext.of(params);
|
||||
|
||||
AtomicReference<ClassLoader> ref = new AtomicReference<>();
|
||||
context.withMarshaller(marshaller -> {
|
||||
ref.set(Thread.currentThread().getContextClassLoader());
|
||||
});
|
||||
context.withMarshaller(
|
||||
marshaller -> {
|
||||
ref.set(Thread.currentThread().getContextClassLoader());
|
||||
},
|
||||
"nothing"
|
||||
);
|
||||
|
||||
assertThat(ref.get()).isSameAs(classLoader);
|
||||
assertThat(Thread.currentThread().getContextClassLoader()).isSameAs(contextClassLoader);
|
||||
|
||||
Reference in New Issue
Block a user