Class SurfSerializer
- java.lang.Object
-
- io.urf.surf.SurfSerializer
-
public class SurfSerializer extends java.lang.ObjectSimple serializer for the Simple URF (SURF) document format.This serializer recognizes and can serialize the following type for SURF categories of resources:
Objects
Literals
binary
byte[]ByteBuffer
Boolean
Boolean
character
CharacterCodePointCharacter
email address
EmailAddress
IRI
URIURL
number
BigInteger(serialized as decimal)BigDecimal(serialized as decimal)Number(includingInteger,Long, andDouble)
regular expression
Pattern
string
CharSequence(includingString)
telephone number
TelephoneNumber
temporal
Date(serialized as instant)InstantMonthDayLocalDateLocalDateTimeLocalTimeOffsetDateTimeOffsetTimeYearYearMonthZonedDateTime
UUID
UUID
Collections
ListMapSet
This serializer is meant to be used once for generating a single SURF document. It should not be used to serialize multiple documents, as it maintains serialization state.
The serializer should be released after use so as not to leak memory of parsed resources when resources are present with tags/IDs and/or generate aliases.
This implementation is not thread safe.
- Author:
- Garret Wilson
-
-
Field Summary
Fields Modifier and Type Field Description static java.lang.StringGENERATED_ALIAS_PREFIXThe prefix used when generating aliases.
-
Constructor Summary
Constructors Constructor Description SurfSerializer()
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description protected voiddecreaseIndentLevel()Decreases the indention level.protected java.lang.StringdetermineAliasForResource(java.lang.Object resource)Determines an alias to use with a resource, generating one if the graph requires it.protected voiddiscoverResourceReferences(java.lang.Object resource)Discovers whether there are references to the given resource and recursively all nested resources.protected voidformatIndent(java.lang.Appendable appendable)Appends indention characters at the appropriate level if formatting is enabled.protected booleanformatNewLine(java.lang.Appendable appendable)Separates lines by adding a line separation character sequence if formatting is enabled.java.util.Optional<java.lang.String>getAliasForResource(java.lang.Object resource)Returns any alias associated with a resource.java.lang.CharSequencegetIndentSequence()Returns the sequence of characters used for each indention level.java.lang.CharSequencegetLineSeparator()Returns the sequence of characters used to separate lines.protected java.io.CloseableincreaseIndentLevel()Increases the indention level.booleanisFormatted()Returns whether this serializer will format the document with additional whitespace and newlines.booleanisSequenceSeparatorRequired()Whether separators will always be added between sequence items even if newlines are present.protected booleanisSerialized(java.lang.Object resource)Determines whether a given resource has already been serialized.voidserialize(java.io.OutputStream outputStream, java.lang.Object root)Serializes a resource graph to an output stream.voidserialize(java.lang.Appendable appendable, java.lang.Object root)Serializes a resource graph to some appendable destination.java.lang.Stringserialize(java.lang.Object root)Serializes a resource graph to a string.static voidserializeBinary(java.lang.Appendable appendable, byte[] bytes)Serializes a binary literal along with its delimiter from an array of bytes.static voidserializeBinary(java.lang.Appendable appendable, java.nio.ByteBuffer byteBuffer)Serializes a binary literal along with its delimiter from a byte buffer.static voidserializeBoolean(java.lang.Appendable appendable, boolean bool)Serializes a Boolean.static voidserializeCharacter(java.lang.Appendable appendable, int codePoint)Serializes a character surrounded by character delimiters.static voidserializeCharacterCodePoint(java.lang.Appendable appendable, char delimiter, int codePoint)Serializes a character as content, without any delimiters.voidserializeDescription(java.lang.Appendable appendable, SurfObject surfObject)Serializes a resource description.static voidserializeEmailAddress(java.lang.Appendable appendable, com.globalmentor.net.EmailAddress emailAddress)Serializes an email address along with its delimiter.static voidserializeIri(java.lang.Appendable appendable, java.net.URI iri)Serializes an IRI along with its delimiters.voidserializeList(java.lang.Appendable appendable, java.util.List<?> list)Serializes a list.voidserializeMap(java.lang.Appendable appendable, java.util.Map<?,?> map)Serializes a map.static voidserializeNumber(java.lang.Appendable appendable, java.lang.Number number)Serializes a number along with its delimiter if should be represented as a decimal.voidserializeObject(java.lang.Appendable appendable, SurfObject surfObject)Serializes a object representation without the following description.static voidserializeRegularExpression(java.lang.Appendable appendable, java.util.regex.Pattern regularExpression)Serializes a regular expression along with its delimiters.voidserializeResource(java.lang.Appendable appendable, java.lang.Object resource)Serializes a resource to some appendable destination.protected <I> voidserializeSequence(java.lang.Appendable appendable, java.lang.Iterable<I> sequence, com.globalmentor.io.function.IOBiConsumer<java.lang.Appendable,I> itemSerializer)Serializes a general sequence (such as a list).voidserializeSet(java.lang.Appendable appendable, java.util.Set<?> set)Serializes a set.static voidserializeString(java.lang.Appendable appendable, java.lang.CharSequence charSequence)Serializes a string surrounded by string delimiters.static voidserializeTelephoneNumber(java.lang.Appendable appendable, com.globalmentor.itu.TelephoneNumber telephoneNumber)Serializes a telephone number along with its delimiter.static voidserializeTemporal(java.lang.Appendable appendable, java.time.temporal.TemporalAccessor temporal)Serializes a temporal literal along with its delimiter.static voidserializeUuid(java.lang.Appendable appendable, java.util.UUID uuid)Serializes a UUID along with its delimiter.voidsetAliasForResource(java.lang.Object resource, java.lang.String alias)Associates an alias with a resource.voidsetFormatted(boolean formatted)Sets whether the serialization should be formatted.voidsetIndentSequence(java.lang.CharSequence indentSequence)Set the sequence of characters used for each indention level.voidsetLineSeparator(java.lang.CharSequence lineSeparator)Sets the sequence of characters used to separate lines.voidsetSequenceSeparatorRequired(boolean sequenceSeparatorRequired)Sets whether separators will always be added between sequence items even if newlines are present.protected booleansetSerialized(java.lang.Object resource)Sets a resource has having been serialized.
-
-
-
Field Detail
-
GENERATED_ALIAS_PREFIX
public static final java.lang.String GENERATED_ALIAS_PREFIX
The prefix used when generating aliases.- See Also:
- Constant Field Values
-
-
Method Detail
-
isFormatted
public boolean isFormatted()
Returns whether this serializer will format the document with additional whitespace and newlines.This implementation defaults to no formatting.
- Returns:
- Whether serialization output should be formatted.
-
setFormatted
public void setFormatted(boolean formatted)
Sets whether the serialization should be formatted.- Parameters:
formatted- Whether this serializer will format the document with additional whitespace and newlines.
-
getIndentSequence
public java.lang.CharSequence getIndentSequence()
Returns the sequence of characters used for each indention level.This implementation defaults to the horizontal tab character.
- Returns:
- The character(s) used for indention.
-
setIndentSequence
public void setIndentSequence(@Nonnull java.lang.CharSequence indentSequence)Set the sequence of characters used for each indention level.- Parameters:
indentSequence- The character(s) to use for indention.
-
increaseIndentLevel
protected java.io.Closeable increaseIndentLevel()
Increases the indention level. No information is appended.- Returns:
- An object that will automatically unindent when
Closeable.close()is called.
-
formatIndent
protected void formatIndent(@Nonnull java.lang.Appendable appendable) throws java.io.IOExceptionAppends indention characters at the appropriate level if formatting is enabled.If formatting is turned off, no content will be added.
- Parameters:
appendable- The appendable to which serialized data should be appended.- Throws:
java.io.IOException- If there was an error writing the indent.- See Also:
isFormatted(),getIndentSequence()
-
decreaseIndentLevel
protected void decreaseIndentLevel()
Decreases the indention level. No information is appended.
-
getLineSeparator
public java.lang.CharSequence getLineSeparator()
Returns the sequence of characters used to separate lines.This implementation defaults to the platform-dependent line separator for the current system.
- Returns:
- The character(s) used for line endings.
- See Also:
System.lineSeparator()
-
setLineSeparator
public void setLineSeparator(@Nonnull java.lang.CharSequence lineSeparator)Sets the sequence of characters used to separate lines.- Parameters:
lineSeparator- The character(s) to use for line endings.- See Also:
System.lineSeparator()
-
formatNewLine
protected boolean formatNewLine(@Nonnull java.lang.Appendable appendable) throws java.io.IOExceptionSeparates lines by adding a line separation character sequence if formatting is enabled.If formatting is turned off, no content will be added.
- Parameters:
appendable- The appendable to which serialized data should be appended.- Returns:
- Whether or not a line separator sequence was actually appended.
- Throws:
java.io.IOException- If there was an error writing the line separator.- See Also:
isFormatted(),getLineSeparator()
-
isSequenceSeparatorRequired
public boolean isSequenceSeparatorRequired()
Whether separators will always be added between sequence items even if newlines are present.This implementation defaults to not adding sequence separators if not needed.
- Returns:
- Whether sequence separators will always be added even when options.
-
setSequenceSeparatorRequired
public void setSequenceSeparatorRequired(boolean sequenceSeparatorRequired)
Sets whether separators will always be added between sequence items even if newlines are present.- Parameters:
sequenceSeparatorRequired- Whether sequence separators will always be added even when options.
-
discoverResourceReferences
protected void discoverResourceReferences(@Nonnull java.lang.Object resource)Discovers whether there are references to the given resource and recursively all nested resources.This method should not be called more than once for any resource graph, or all resources in the graph will be marked as having references.
- Parameters:
resource- The resource graph for which references should be discovered.
-
getAliasForResource
public java.util.Optional<java.lang.String> getAliasForResource(@Nonnull java.lang.Object resource)Returns any alias associated with a resource.- Parameters:
resource- The resource with which an alias may be associated.- Returns:
- The alias, if any associated with the given resource.
-
setAliasForResource
public void setAliasForResource(@Nonnull java.lang.Object resource, @Nonnull java.lang.String alias)Associates an alias with a resource. This method allows associating aliases with non-object and non-collection resources as well, such as the number 5.Aliases are not allowed to be set for objects with tags or IDs, which themselves serve as labels.
- Parameters:
resource- The resource to associate with an alias.alias- The alias to associate with the resource.- Throws:
java.lang.NullPointerException- if the given resource and/or alias isnull.java.lang.IllegalArgumentException- if the given alias is not a valid name token.java.lang.IllegalArgumentException- if an alias is given for aSurfObjectwith a tag or an ID.
-
determineAliasForResource
protected java.lang.String determineAliasForResource(@Nonnull java.lang.Object resource)Determines an alias to use with a resource, generating one if the graph requires it.- If an alias has already been associated with a resource, it is returned.
- Otherwise if the resource is a compound resource that has references, a new alias is generated, associated with the resource for future use and returned.
- An alias is never generated for a
SurfObjectwith an a tag or an ID, as that serves as a label.
- Parameters:
resource- The resource with which an alias may be associated, ornullif there is no alias.- Returns:
- The alias, if any associated with the given resource.
-
isSerialized
protected boolean isSerialized(@Nonnull java.lang.Object resource)Determines whether a given resource has already been serialized.- Parameters:
resource- The resource to check.- Returns:
trueif the resource has already been serialized.
-
setSerialized
protected boolean setSerialized(@Nonnull java.lang.Object resource)Sets a resource has having been serialized.- Parameters:
resource- The resource to record as serialized.- Returns:
- Whether the resource was previously marked as serialized before this call.
-
serialize
public java.lang.String serialize(@Nonnull @Nullable java.lang.Object root) throws java.io.IOExceptionSerializes a resource graph to a string.This method discovers resource references to that aliases may be generated as needed. This record of resource references is reset after serialization, but any generated aliases remain. This allows the same serializer to be used multiple times for the same graph, with the same aliases being used.
This is a convenience method that delegates to
serialize(Appendable, Object).- Parameters:
root- The root resource, ornullif there is no resource to serialize.- Returns:
- A serialized string representation of the given resource graph.
- Throws:
java.io.IOException- If there was an error writing the serialized data.
-
serialize
public void serialize(@Nonnull java.io.OutputStream outputStream, @Nullable java.lang.Object root) throws java.io.IOExceptionSerializes a resource graph to an output stream.This method discovers resource references to that aliases may be generated as needed. This record of resource references is reset after serialization, but any generated aliases remain. This allows the same serializer to be used multiple times for the same graph, with the same aliases being used.
- Parameters:
outputStream- The output stream to receive serialized data.root- The root resource, ornullif there is no resource to serialize.- Throws:
java.io.IOException- If there was an error writing the serialized data.
-
serialize
public void serialize(@Nonnull java.lang.Appendable appendable, @Nullable java.lang.Object root) throws java.io.IOExceptionSerializes a resource graph to some appendable destination.All references to the resources in the graph must have already been discovered if aliases need to be generated.
- Parameters:
appendable- The appendable to which serialized data should be appended.root- The root resource, ornullif there is no resource to serialize.- Throws:
java.lang.NullPointerException- if the given appendable isnull.java.io.IOException- If there was an error writing the serialized data.
-
serializeResource
public void serializeResource(@Nonnull java.lang.Appendable appendable, @Nullable java.lang.Object resource) throws java.io.IOExceptionSerializes a resource to some appendable destination.All references to the resources in the graph must have already been discovered if aliases need to be generated.
- Parameters:
appendable- The appendable to which serialized data should be appended.resource- The resource to serialize.- Throws:
java.lang.NullPointerException- if the given appendable and/or resource isnull.java.io.IOException- If there was an error appending the serialized data.
-
serializeObject
public void serializeObject(@Nonnull java.lang.Appendable appendable, @Nonnull SurfObject surfObject) throws java.io.IOExceptionSerializes a object representation without the following description.All references to the resources in the graph must have already been discovered if aliases need to be generated.
- Parameters:
appendable- The appendable to which serialized data should be appended.surfObject- The information to be serialized as a SURF object.- Throws:
java.lang.NullPointerException- if the given reader isnull.java.io.IOException- if there is an error appending to the appendable.- See Also:
SURF.OBJECT_BEGIN
-
serializeDescription
public void serializeDescription(@Nonnull java.lang.Appendable appendable, @Nonnull SurfObject surfObject) throws java.io.IOExceptionSerializes a resource description. The description section, including delimiters, will be serialized even if there are no properties.All references to the resources in the graph must have already been discovered if aliases need to be generated.
- Parameters:
appendable- The appendable to which serialized data should be appended.surfObject- The SURF object with the description to be serialized.- Throws:
java.lang.NullPointerException- if the given reader isnull.java.io.IOException- if there is an error appending to the appendable.- See Also:
SURF.DESCRIPTION_BEGIN,SURF.DESCRIPTION_END
-
serializeBinary
public static void serializeBinary(@Nonnull java.lang.Appendable appendable, @Nonnull byte[] bytes) throws java.io.IOExceptionSerializes a binary literal along with its delimiter from an array of bytes.- Parameters:
appendable- The appendable to which serialized data should be appended.bytes- The information to be serialized as a binary literal.- Throws:
java.lang.NullPointerException- if the given reader isnull.java.io.IOException- if there is an error appending to the appendable.- See Also:
SURF.BINARY_BEGIN
-
serializeBinary
public static void serializeBinary(@Nonnull java.lang.Appendable appendable, @Nonnull java.nio.ByteBuffer byteBuffer) throws java.io.IOExceptionSerializes a binary literal along with its delimiter from a byte buffer.- Parameters:
appendable- The appendable to which serialized data should be appended.byteBuffer- The information to be serialized as a binary literal.- Throws:
java.lang.NullPointerException- if the given reader isnull.java.io.IOException- if there is an error appending to the appendable.- See Also:
SURF.BINARY_BEGIN
-
serializeBoolean
public static void serializeBoolean(@Nonnull java.lang.Appendable appendable, @Nonnull boolean bool) throws java.io.IOExceptionSerializes a Boolean.- Parameters:
appendable- The appendable to which serialized data should be appended.bool- The Boolean value to be serialized as a Boolean.- Throws:
java.lang.NullPointerException- if the given reader isnull.java.lang.IllegalArgumentException- if the given code point is not a valid Unicode code point.java.io.IOException- if there is an error appending to the appendable.
-
serializeCharacter
public static void serializeCharacter(@Nonnull java.lang.Appendable appendable, @Nonnull int codePoint) throws java.io.IOExceptionSerializes a character surrounded by character delimiters.- Parameters:
appendable- The appendable to which serialized data should be appended.codePoint- The Unicode code point to be serialized as a character.- Throws:
java.lang.NullPointerException- if the given reader isnull.java.lang.IllegalArgumentException- if the given code point is not a valid Unicode code point.java.io.IOException- if there is an error appending to the appendable.- See Also:
SURF.CHARACTER_DELIMITER,serializeCharacterCodePoint(Appendable, char, int)
-
serializeCharacterCodePoint
public static void serializeCharacterCodePoint(@Nonnull java.lang.Appendable appendable, char delimiter, int codePoint) throws java.io.IOException, com.globalmentor.io.ParseIOExceptionSerializes a character as content, without any delimiters.This implementation does not escape the solidus (slash) character
'/', which is not required to be escaped.- Parameters:
appendable- The appendable to which serialized data should be appended.delimiter- The delimiter that surrounds the character and which should be escaped.codePoint- The code point to serialize.- Throws:
java.lang.NullPointerException- if the given appendable isnull.java.io.IOException- if there is an error appending to the appender.com.globalmentor.io.ParseIOException- if a control character was represented, if the character is not escaped correctly, or the reader has no more characters before the current character is completely parsed.- See Also:
SURF.CHARACTER_REQUIRED_ESCAPED_CHARACTERS
-
serializeEmailAddress
public static void serializeEmailAddress(@Nonnull java.lang.Appendable appendable, @Nonnull com.globalmentor.net.EmailAddress emailAddress) throws java.io.IOExceptionSerializes an email address along with its delimiter.- Parameters:
appendable- The appendable to which serialized data should be appended.emailAddress- The information to be serialized as an email address.- Throws:
java.lang.NullPointerException- if the given reader isnull.java.io.IOException- if there is an error appending to the appendable.- See Also:
SURF.EMAIL_ADDRESS_BEGIN
-
serializeIri
public static void serializeIri(@Nonnull java.lang.Appendable appendable, @Nonnull java.net.URI iri) throws java.io.IOExceptionSerializes an IRI along with its delimiters.This implementation serializes an IRI using an IRI short form if possible.
- Parameters:
appendable- The appendable to which serialized data should be appended.iri- The information to be serialized as an IRI.- Throws:
java.lang.NullPointerException- if the given reader isnull.java.lang.IllegalArgumentException- if the given IRI is not a true, absolute IRI with a scheme.java.io.IOException- if there is an error appending to the appendable.- See Also:
SURF.IRI_BEGIN
-
serializeNumber
public static void serializeNumber(@Nonnull java.lang.Appendable appendable, @Nonnull java.lang.Number number) throws java.io.IOExceptionSerializes a number along with its delimiter if should be represented as a decimal.This implementation represents the following types as decimal:
BigDecimalBigInteger
- Parameters:
appendable- The appendable to which serialized data should be appended.number- The information to be serialized as a number.- Throws:
java.lang.NullPointerException- if the given reader isnull.java.io.IOException- if there is an error appending to the appendable.- See Also:
SURF.NUMBER_DECIMAL_BEGIN
-
serializeRegularExpression
public static void serializeRegularExpression(@Nonnull java.lang.Appendable appendable, @Nonnull java.util.regex.Pattern regularExpression) throws java.io.IOExceptionSerializes a regular expression along with its delimiters.- Parameters:
appendable- The appendable to which serialized data should be appended.regularExpression- The information to be serialized as a regular expression.- Throws:
java.lang.NullPointerException- if the given reader isnull.java.io.IOException- if there is an error appending to the appendable.- See Also:
SURF.REGULAR_EXPRESSION_DELIMITER,SURF.REGULAR_EXPRESSION_ESCAPE
-
serializeString
public static void serializeString(@Nonnull java.lang.Appendable appendable, @Nonnull java.lang.CharSequence charSequence) throws java.io.IOExceptionSerializes a string surrounded by string delimiters.- Parameters:
appendable- The appendable to which serialized data should be appended.charSequence- The information to be serialized as a string.- Throws:
java.lang.NullPointerException- if the given reader isnull.java.io.IOException- if there is an error appending to the appendable.- See Also:
SURF.STRING_DELIMITER,serializeCharacterCodePoint(Appendable, char, int)
-
serializeTelephoneNumber
public static void serializeTelephoneNumber(@Nonnull java.lang.Appendable appendable, @Nonnull com.globalmentor.itu.TelephoneNumber telephoneNumber) throws java.io.IOExceptionSerializes a telephone number along with its delimiter.- Parameters:
appendable- The appendable to which serialized data should be appended.telephoneNumber- The information to be serialized as a telephone number.- Throws:
java.lang.NullPointerException- if the given reader isnull.java.io.IOException- if there is an error appending to the appendable.java.lang.IllegalArgumentException- if the given telephone number is not in global form.- See Also:
SURF.TELEPHONE_NUMBER_BEGIN,TelephoneNumber.isGlobal()
-
serializeTemporal
public static void serializeTemporal(@Nonnull java.lang.Appendable appendable, @Nonnull java.time.temporal.TemporalAccessor temporal) throws java.io.IOExceptionSerializes a temporal literal along with its delimiter.- Parameters:
appendable- The appendable to which serialized data should be appended.temporal- The information to be serialized as a temporal.- Throws:
java.lang.NullPointerException- if the given reader isnull.java.io.IOException- if there is an error appending to the appendable.- See Also:
SURF.TEMPORAL_BEGIN
-
serializeUuid
public static void serializeUuid(@Nonnull java.lang.Appendable appendable, @Nonnull java.util.UUID uuid) throws java.io.IOExceptionSerializes a UUID along with its delimiter.- Parameters:
appendable- The appendable to which serialized data should be appended.uuid- The information to be serialized as a UUID.- Throws:
java.lang.NullPointerException- if the given reader isnull.java.io.IOException- if there is an error appending to the appendable.- See Also:
SURF.UUID_BEGIN
-
serializeList
public void serializeList(@Nonnull java.lang.Appendable appendable, @Nonnull java.util.List<?> list) throws java.io.IOExceptionSerializes a list.All references to the resources in the graph must have already been discovered if aliases need to be generated.
- Parameters:
appendable- The appendable to which serialized data should be appended.list- The information to be serialized as a list.- Throws:
java.lang.NullPointerException- if the given reader isnull.java.io.IOException- if there is an error appending to the appendable.- See Also:
SURF.LIST_BEGIN,SURF.LIST_END
-
serializeMap
public void serializeMap(@Nonnull java.lang.Appendable appendable, @Nonnull java.util.Map<?,?> map) throws java.io.IOExceptionSerializes a map.All references to the resources in the graph must have already been discovered if aliases need to be generated.
- Parameters:
appendable- The appendable to which serialized data should be appended.map- The information to be serialized as a map.- Throws:
java.lang.NullPointerException- if the given reader isnull.java.io.IOException- if there is an error appending to the appendable.- See Also:
SURF.MAP_BEGIN,SURF.MAP_END,SURF.MAP_KEY_DELIMITER,SURF.ENTRY_KEY_VALUE_DELIMITER
-
serializeSet
public void serializeSet(@Nonnull java.lang.Appendable appendable, @Nonnull java.util.Set<?> set) throws java.io.IOExceptionSerializes a set.All references to the resources in the graph must have already been discovered if aliases need to be generated.
- Parameters:
appendable- The appendable to which serialized data should be appended.set- The information to be serialized as a set.- Throws:
java.lang.NullPointerException- if the given reader isnull.java.io.IOException- if there is an error appending to the appendable.- See Also:
SURF.SET_BEGIN,SURF.SET_END
-
serializeSequence
protected <I> void serializeSequence(@Nonnull java.lang.Appendable appendable, @Nonnull java.lang.Iterable<I> sequence, @Nonnull com.globalmentor.io.function.IOBiConsumer<java.lang.Appendable,I> itemSerializer) throws java.io.IOExceptionSerializes a general sequence (such as a list). For each sequence item,IOBiConsumer.accept(Object, Object)is called, passing the outputAppendablealong with the item to be serialized. The item serialization strategy will returnfalseto indicate that there are no further items.- Type Parameters:
I- The type of item in the sequence.- Parameters:
appendable- The appendable to which serialized data should be appended.sequence- An iterable representing the sequence to serialize.itemSerializer- The serialization strategy, which is passed theAppendableto use for serialization, along with each item to serialize.- Throws:
java.lang.NullPointerException- if the given appendable and/or item serializer isnull.java.io.IOException- if there is an error appending to the appender.
-
-