com.sap.cds.adapter.odata.v4.metadata.provider.EdmxI18nInputStream Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of cds-adapter-odata-v4 Show documentation
Show all versions of cds-adapter-odata-v4 Show documentation
OData V4 adapter for CDS Services Java
/**************************************************************************
* (C) 2019-2024 SAP SE or an SAP affiliate company. All rights reserved. *
**************************************************************************/
package com.sap.cds.adapter.odata.v4.metadata.provider;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import com.google.common.xml.XmlEscapers;
class EdmxI18nInputStream extends InputStream {
private static final int[] IPATTERN = new int[] { '{', 'i', '1', '8', 'n', '>' };
private final Map i18n;
private final Map escapedI18n;
private final BufferedInputStream buffer;
private byte[] replacement;
private int replacementOffset;
public EdmxI18nInputStream(InputStream is, Map i18n) {
buffer = new BufferedInputStream(is);
if (i18n == null) {
this.i18n = Collections.emptyMap();
this.escapedI18n = Collections.emptyMap();
} else {
this.i18n = i18n;
this.escapedI18n = new HashMap<>(); // no need to replace all keys every time
}
}
@Override
public int read() throws IOException {
// if replacement available read replacement bytes
if (replacement != null) {
if (replacementOffset < replacement.length) {
return replacement[replacementOffset++] & 0xff;
}
replacement = null;
}
if (lookAhead()) {
return read();
}
return buffer.read();
}
private boolean lookAhead() throws IOException {
buffer.mark(IPATTERN.length);
// detect pattern
for (int i = 0; i < IPATTERN.length; i++) {
if (buffer.read() != IPATTERN[i]) {
buffer.reset();
return false;
}
}
// get the i18n key
int cc;
ByteArrayOutputStream result = new ByteArrayOutputStream();
while ((cc = buffer.read()) >= 0) {
if (cc == '}') {
// get i18n value
String i18nKey = result.toString(StandardCharsets.UTF_8);
replacementOffset = 0;
if (!i18n.containsKey(i18nKey)) {
buffer.reset();
return false;
}
replacement = escapedI18n.computeIfAbsent(i18nKey, k -> {
String raw = i18n.get(k);
return raw != null ? XmlEscapers.xmlAttributeEscaper().escape(raw) : null;
}).getBytes(StandardCharsets.UTF_8);
return true;
}
result.write(cc);
}
buffer.reset();
return false;
}
}