CustomLSInput.java
package org.thewonderlemming.c4plantuml.graphml.validation;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.thewonderlemming.c4plantuml.graphml.Build;
import org.w3c.dom.ls.LSInput;
import org.w3c.dom.ls.LSResourceResolver;
/**
* A basic implementation of {@link LSInput}, in order to implement our custom {@link LSResourceResolver}.
*
* @author thewonderlemming
*
*/
public class CustomLSInput implements LSInput {
private static final Logger LOGGER = LoggerFactory.getLogger(CustomLSInput.class);
private static final int ONE_KBYTE = 1024;
private String baseURI;
private String publicId;
private String resourceDataAsString;
private String systemId;
/**
* A fluent builder to ease the construction of {@link CustomLSInput}, since its constructor contains several
* arguments which are all strings.
*
* @return a new instance of {@link CustomLSInput}.
*/
public static WithBaseURI<WithPublicId<WithResourceFilename<WithSystemId<Build<CustomLSInput>>>>> newBuilder() {
return baseURI -> publicId -> resourceFilename -> systemId -> () -> new CustomLSInput(
baseURI,
publicId,
resourceFilename,
systemId);
}
private static final void printUnsupportedOperation(final String methodName) {
LOGGER.warn("Unsupported operation {}. The call will be ignored.", methodName);
}
private static String readResourceContentAsString(final InputStream resourceStream) {
try (final ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
final byte[] buffer = new byte[ONE_KBYTE];
int length;
while ((length = resourceStream.read(buffer)) != -1) {
baos.write(buffer, 0, length);
}
return baos.toString(StandardCharsets.UTF_8.name());
} catch (final UnsupportedEncodingException e) {
LOGGER.error("Unsupported encoding exception should not occur here with encoding 'UTF_8'!");
} catch (final IOException e) {
LOGGER.error("Could not retrieve the LSInput because of the following: {}", e.getMessage(), e);
}
return "";
}
private static String readResourceContentAsString(final String resourceFilename) {
try (final InputStream is = CustomLSInput.class.getResourceAsStream(resourceFilename)) {
return readResourceContentAsString(is);
} catch (final IOException e) {
LOGGER.error("Could not retrieve the LSInput because of the following: {}", e.getMessage(), e);
}
return "";
}
private CustomLSInput(final String baseURI, final String publicId, final String resourceFilename,
final String systemId) {
this.baseURI = baseURI;
this.publicId = publicId;
this.systemId = systemId;
this.resourceDataAsString = readResourceContentAsString(resourceFilename);
}
/**
* {@inheritDoc}
*/
@Override
public String getBaseURI() {
return this.baseURI;
}
/**
* {@inheritDoc}
*/
@Override
public InputStream getByteStream() {
return new ByteArrayInputStream(this.resourceDataAsString.getBytes());
}
/**
* {@inheritDoc}
* <p>
* Unsupported operation.
*/
@Override
public boolean getCertifiedText() {
printUnsupportedOperation("getCertifiedText");
return false;
}
/**
* {@inheritDoc}
*/
@Override
public Reader getCharacterStream() {
try (final InputStream bais = new ByteArrayInputStream(this.resourceDataAsString.getBytes())) {
return new InputStreamReader(bais, StandardCharsets.UTF_8);
} catch (final IOException e) {
LOGGER
.error("Could not return character stream for {} because of the following: {}",
this.publicId,
e.getMessage(),
e);
}
return null;
}
/**
* {@inheritDoc}
*/
@Override
public String getEncoding() {
return StandardCharsets.UTF_8.name();
}
/**
* {@inheritDoc}
*/
@Override
public String getPublicId() {
return this.publicId;
}
/**
* {@inheritDoc}
*/
@Override
public String getStringData() {
return this.resourceDataAsString;
}
/**
* {@inheritDoc}
*/
@Override
public String getSystemId() {
return this.systemId;
}
/**
* {@inheritDoc}
*/
@Override
public void setBaseURI(final String baseURI) {
this.baseURI = baseURI;
}
/**
* {@inheritDoc}
*/
@Override
public void setByteStream(final InputStream byteStream) {
try (final BufferedInputStream bis = new BufferedInputStream(byteStream)) {
this.resourceDataAsString = bis.toString();
} catch (final IOException e) {
LOGGER.error("Could not set byte stream because of the following: {}", e.getMessage(), e);
}
}
/**
* {@inheritDoc}
* <p>
* Unsupported operation.
*/
@Override
public void setCertifiedText(final boolean certifiedText) {
printUnsupportedOperation("setCertifiedText");
}
/**
* {@inheritDoc}
* <p>
* Unsupported operation.
*/
@Override
public void setCharacterStream(final Reader characterStream) {
printUnsupportedOperation("setCharacterStream");
}
/**
* {@inheritDoc}
* <p>
* Unsupported operation.
*/
@Override
public void setEncoding(final String encoding) {
printUnsupportedOperation("setEncoding");
}
/**
* {@inheritDoc}
*/
@Override
public void setPublicId(final String publicId) {
this.publicId = publicId;
}
/**
* {@inheritDoc}
* <p>
* Unsupported operation.
*/
@Override
public void setStringData(final String stringData) {
printUnsupportedOperation("setStringData");
}
/**
* {@inheritDoc}
*/
@Override
public void setSystemId(final String systemId) {
this.systemId = systemId;
}
}