Added documentation, nexus OSS deployment settings.
This commit is contained in:
parent
3fc0efca5f
commit
7890c2cd19
41
README.md
41
README.md
|
@ -1,41 +1,8 @@
|
|||
# record-net
|
||||
Simple, performant message library for Java, using records.
|
||||
Simple, performant message library for Java, using records. It allows you to
|
||||
serialize and deserialize records and their contents for use in network or
|
||||
filesystem IO.
|
||||
|
||||
record-net gives you the advantages of reflection, without the runtime costs. By registering message types before starting your work, record-net is able to generate custom serializers and deserializers for all registered message types, which translates to read and write speeds that are nearly equivalent to directly writing bytes to a stream.
|
||||
|
||||
Here's an example of how you can use record-net:
|
||||
|
||||
```java
|
||||
import com.andrewlalis.record_net.Message;
|
||||
import com.andrewlalis.record_net.impl.TypeMappedSerializer;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.Socket;
|
||||
|
||||
class Example {
|
||||
record ChatMessage(
|
||||
long timestamp,
|
||||
String username,
|
||||
String msg
|
||||
) implements Message {
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
var ser = new TypeMappedSerializer();
|
||||
ser.registerType(1, ChatMessage.class);
|
||||
var socket = new Socket("127.0.0.1", 8081);
|
||||
var bOut = new ByteArrayOutputStream();
|
||||
var msg = new ChatMessage(
|
||||
System.currentTimeMillis(),
|
||||
"andrew",
|
||||
"Hello world!"
|
||||
);
|
||||
ser.writeMessage(msg, socket.getOutputStream());
|
||||
ChatMessage response = (ChatMessage) ser.readMessage(socket.getInputStream());
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Get record-net
|
||||
This project is published as a package on GitHub. You can view available packages [here](https://github.com/andrewlalis/record-net/packages). Alternatively, [you can get this project on jitpack.io](https://jitpack.io/#andrewlalis/record-net).
|
||||
## Example
|
||||
|
|
119
pom.xml
119
pom.xml
|
@ -6,7 +6,7 @@
|
|||
|
||||
<groupId>com.andrewlalis</groupId>
|
||||
<artifactId>record-net</artifactId>
|
||||
<version>2.0.0</version>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<name>Record-Net</name>
|
||||
<description>A simple library for reading and writing records deterministically and efficiently.</description>
|
||||
<url>https://github.com/andrewlalis/record-net</url>
|
||||
|
@ -35,24 +35,121 @@
|
|||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<!-- Setup for deploying to GitHub packages with mvn deploy. -->
|
||||
<distributionManagement>
|
||||
<repository>
|
||||
<id>github</id>
|
||||
<name>Github record-net Apache Maven Packages</name>
|
||||
<url>https://maven.pkg.github.com/andrewlalis/record-net</url>
|
||||
</repository>
|
||||
</distributionManagement>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-source-plugin</artifactId>
|
||||
<version>3.2.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>attach-sources</id>
|
||||
<goals>
|
||||
<goal>jar-no-fork</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<version>3.3.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>attach-javadocs</id>
|
||||
<goals>
|
||||
<goal>jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-gpg-plugin</artifactId>
|
||||
<version>3.1.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>sign-artifacts</id>
|
||||
<phase>verify</phase>
|
||||
<goals>
|
||||
<goal>sign</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>net.ju-n.maven.plugins</groupId>
|
||||
<artifactId>checksum-maven-plugin</artifactId>
|
||||
<version>1.4</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>checksum-maven-plugin-files</id>
|
||||
<phase>verify</phase>
|
||||
<goals>
|
||||
<goal>files</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<fileSets>
|
||||
<fileSet>
|
||||
<directory>${project.build.directory}</directory>
|
||||
<includes>
|
||||
<include>*.pom</include>
|
||||
<include>*.jar</include>
|
||||
</includes>
|
||||
</fileSet>
|
||||
</fileSets>
|
||||
<algorithms>
|
||||
<algorithm>SHA-1</algorithm>
|
||||
<algorithm>MD5</algorithm>
|
||||
<algorithm>SHA-256</algorithm>
|
||||
<algorithm>SHA-512</algorithm>
|
||||
</algorithms>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.sonatype.plugins</groupId>
|
||||
<artifactId>nexus-staging-maven-plugin</artifactId>
|
||||
<version>1.6.13</version>
|
||||
<extensions>true</extensions>
|
||||
<configuration>
|
||||
<serverId>ossrh</serverId>
|
||||
<nexusUrl>https://s01.oss.sonatype.org</nexusUrl>
|
||||
<autoReleaseAfterClose>false</autoReleaseAfterClose>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<scm>
|
||||
<url>https://github.com/andrewlalis/record-net</url>
|
||||
<connection>scm:git:git://github.com/andrewlalis/record-net.git</connection>
|
||||
<developerConnection>scm:git:ssh://github.com:andrewlalis/record-net.git</developerConnection>
|
||||
</scm>
|
||||
|
||||
<licenses>
|
||||
<license>
|
||||
<name>MIT License</name>
|
||||
<url>https://github.com/andrewlalis/record-net/blob/main/LICENSE</url>
|
||||
<distribution>repo</distribution>
|
||||
<url>https://www.opensource.org/licenses/mit-license.php</url>
|
||||
</license>
|
||||
</licenses>
|
||||
|
||||
<developers>
|
||||
<developer>
|
||||
<name>Andrew Lalis</name>
|
||||
<email>andrewlalisofficial@gmail.com</email>
|
||||
</developer>
|
||||
</developers>
|
||||
|
||||
<distributionManagement>
|
||||
<snapshotRepository>
|
||||
<id>ossrh</id>
|
||||
<url>https://s01.oss.sonatype.org/content/repositories/snapshots</url>
|
||||
</snapshotRepository>
|
||||
<repository>
|
||||
<id>ossrh</id>
|
||||
<url>https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/</url>
|
||||
</repository>
|
||||
</distributionManagement>
|
||||
</project>
|
|
@ -6,6 +6,10 @@ import java.io.IOException;
|
|||
import java.lang.reflect.Array;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* A utility class that contains functions for IO operations on certain data
|
||||
* types. It cannot be instantiated; use its static methods only.
|
||||
*/
|
||||
public final class IOUtil {
|
||||
private IOUtil() {}
|
||||
|
||||
|
|
|
@ -3,7 +3,20 @@ package com.andrewlalis.record_net;
|
|||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.RecordComponent;
|
||||
|
||||
/**
|
||||
* A collection of the information that's needed about a record in order to
|
||||
* serialize and deserialize it at runtime.
|
||||
* @param components The record's ordered array of components.
|
||||
* @param constructor The canonical constructor for the record.
|
||||
* @param <T> The type of the record.
|
||||
*/
|
||||
record RecordInfo<T>(RecordComponent[] components, Constructor<T> constructor) {
|
||||
/**
|
||||
* Prepares an instance of RecordInfo for a given record class.
|
||||
* @param type The record class.
|
||||
* @return The RecordInfo object.
|
||||
* @param <T> The type of the record.
|
||||
*/
|
||||
public static <T> RecordInfo<T> forType(Class<T> type) {
|
||||
if (!type.isRecord()) throw new IllegalArgumentException(type + " is not a record.");
|
||||
RecordComponent[] c = type.getRecordComponents();
|
||||
|
@ -18,6 +31,4 @@ record RecordInfo<T>(RecordComponent[] components, Constructor<T> constructor) {
|
|||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -6,11 +6,21 @@ import java.util.HashMap;
|
|||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* The default {@link RecordSerializer} implementation that performs
|
||||
* serialization and deserialization using a set of pre-registered, known
|
||||
* record types.
|
||||
*/
|
||||
public class RecordMappedSerializer implements RecordSerializer {
|
||||
private final Map<Integer, Class<?>> messageTypes = new HashMap<>();
|
||||
private final Map<Class<?>, Integer> messageTypeIds = new HashMap<>();
|
||||
private final Map<Class<?>, RecordInfo<?>> messageRecordInfo = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Registers a new record class to this serializer.
|
||||
* @param id The id to assign to this type.
|
||||
* @param type The record class.
|
||||
*/
|
||||
public void registerType(int id, Class<?> type) {
|
||||
if (!type.isRecord()) throw new IllegalArgumentException("Only records are permitted.");
|
||||
this.messageTypes.put(id, type);
|
||||
|
@ -18,6 +28,20 @@ public class RecordMappedSerializer implements RecordSerializer {
|
|||
this.messageRecordInfo.put(type, RecordInfo.forType(type));
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a new record class to this serializer, using the class' hash
|
||||
* code as its id.
|
||||
* @param type The record class.
|
||||
*/
|
||||
public void registerType(Class<?> type) {
|
||||
this.registerType(type.hashCode(), type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a certain class has been registered for use with this serializer.
|
||||
* @param type The type to check.
|
||||
* @return True if the type is registered and may be used, or false otherwise.
|
||||
*/
|
||||
public boolean isTypeSupported(Class<?> type) {
|
||||
return messageTypeIds.containsKey(type);
|
||||
}
|
||||
|
@ -62,7 +86,10 @@ public class RecordMappedSerializer implements RecordSerializer {
|
|||
if (type.equals(UUID.class)) {
|
||||
return IOUtil.readUUID(dIn);
|
||||
}
|
||||
return IOUtil.readPrimitive(type, dIn);
|
||||
if (type.isPrimitive()) {
|
||||
return IOUtil.readPrimitive(type, dIn);
|
||||
}
|
||||
throw new UnsupportedMessageTypeException(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -4,7 +4,25 @@ import java.io.IOException;
|
|||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
* Defines the basic interface for serialization and deserialization of
|
||||
* messages to and from streams.
|
||||
* @see RecordMappedSerializer
|
||||
*/
|
||||
public interface RecordSerializer {
|
||||
/**
|
||||
* Reads a message from an input stream.
|
||||
* @param in The input stream to read from.
|
||||
* @return The object that was read.
|
||||
* @throws IOException If an error occurs.
|
||||
*/
|
||||
Object readMessage(InputStream in) throws IOException;
|
||||
|
||||
/**
|
||||
* Writes a message to an output stream.
|
||||
* @param msg The message to write.
|
||||
* @param out The output stream to write to.
|
||||
* @throws IOException If an error occurs.
|
||||
*/
|
||||
void writeMessage(Object msg, OutputStream out) throws IOException;
|
||||
}
|
||||
|
|
|
@ -1,8 +1,19 @@
|
|||
package com.andrewlalis.record_net;
|
||||
|
||||
/**
|
||||
* An exception that's thrown when a {@link RecordSerializer} reads a message
|
||||
* whose id is unknown (not previously registered with the serializer).
|
||||
*/
|
||||
public class UnknownMessageIdException extends RuntimeException {
|
||||
/**
|
||||
* The id of the message as it was received.
|
||||
*/
|
||||
public final int messageId;
|
||||
|
||||
/**
|
||||
* Constructs the exception with a given id.
|
||||
* @param messageId The id of the message.
|
||||
*/
|
||||
public UnknownMessageIdException(int messageId) {
|
||||
super("Unknown record-net message id " + messageId);
|
||||
this.messageId = messageId;
|
||||
|
|
|
@ -1,16 +1,22 @@
|
|||
package com.andrewlalis.record_net;
|
||||
|
||||
/**
|
||||
* An exception that's thrown when attempting to serialize or deserialize an
|
||||
* unsupported type. Unsupported types are any complex types not registered
|
||||
* with a serializer, or unsupported by {@link IOUtil}.
|
||||
*/
|
||||
public class UnsupportedMessageTypeException extends RuntimeException {
|
||||
/**
|
||||
* The type that's not supported.
|
||||
*/
|
||||
public Class<?> messageType;
|
||||
public int messageId;
|
||||
|
||||
/**
|
||||
* Constructs a new exception with the given type.
|
||||
* @param messageType The unsupported type.
|
||||
*/
|
||||
public UnsupportedMessageTypeException(Class<?> messageType) {
|
||||
super("The message type " + messageType.getSimpleName() + " is not supported.");
|
||||
this.messageType = messageType;
|
||||
}
|
||||
|
||||
public UnsupportedMessageTypeException(int messageId) {
|
||||
super("The message with id " + messageId + " is not supported.");
|
||||
this.messageId = messageId;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
/**
|
||||
* The record_net module definition.
|
||||
*/
|
||||
module com.andrewlalis.record_net {
|
||||
exports com.andrewlalis.record_net;
|
||||
}
|
Loading…
Reference in New Issue