diff --git a/src/main/java/net/openhft/chronicle/wire/AbstractWire.java b/src/main/java/net/openhft/chronicle/wire/AbstractWire.java index b8717a56b2..c196709dc0 100644 --- a/src/main/java/net/openhft/chronicle/wire/AbstractWire.java +++ b/src/main/java/net/openhft/chronicle/wire/AbstractWire.java @@ -41,8 +41,16 @@ import static net.openhft.chronicle.core.UnsafeMemory.MEMORY; import static net.openhft.chronicle.wire.Wires.*; +/** + * Represents the AbstractWire class which serves as a base for all Wire implementations. + * This class provides fundamental shared behaviors, configurations, and initializations for Wire types. + */ public abstract class AbstractWire implements Wire { + + // Default padding configuration loaded from the system properties. public static final boolean DEFAULT_USE_PADDING = Jvm.getBoolean("wire.usePadding", false); + + // Message used when a header is detected inside another header. private static final String INSIDE_HEADER_MESSAGE = "you cant put a header inside a header, check that " + "you have not nested the documents. If you are using Chronicle-Queue please " + "ensure that you have a unique instance of the Appender per thread, in " + @@ -68,6 +76,7 @@ public abstract class AbstractWire implements Wire { private boolean insideHeader; private HeadNumberChecker headNumberChecker; private boolean usePadding = DEFAULT_USE_PADDING; + private boolean generateTuples = GENERATE_TUPLES; @SuppressWarnings("rawtypes") protected AbstractWire(@NotNull Bytes> bytes, boolean use8bit) { @@ -76,6 +85,38 @@ protected AbstractWire(@NotNull Bytes> bytes, boolean use8bit) { notCompleteIsNotPresent = bytes.sharedMemory(); } + /** + * Sets the flag to determine whether this Wire should generate tuples. When enabled, + * this feature allows the Wire to create and handle tuple data structures dynamically. + *
+ * Usage of this feature should be aligned with the specific requirements of the Wire's + * operational context. Enabling tuple generation may impact how data is processed and + * represented within the Wire. + * + * @param generateTuples A boolean value indicating whether to enable or disable + * tuple generation. + */ + @Override + public void generateTuples(boolean generateTuples) { + this.generateTuples = generateTuples; + } + + /** + * Retrieves the current status of the tuple generation feature within this Wire. + * When enabled, this feature allows for the dynamic creation and handling of tuple + * data structures within the Wire. + *
+ * The return value of this method indicates whether the Wire is currently configured + * to generate and handle tuples, which can be crucial for understanding the Wire's + * current data processing behavior. + * + * @return A boolean value indicating whether tuple generation is currently enabled. + */ + @Override + public boolean generateTuples() { + return generateTuples; + } + private static long throwNotEnoughSpace(long maxlen, @NotNull Bytes> bytes) { throw new IllegalStateException("not enough space to write " + maxlen + " was " + bytes.writeRemaining() + " limit " + bytes.writeLimit() + " type " + bytes.getClass()); } diff --git a/src/main/java/net/openhft/chronicle/wire/BinaryWire.java b/src/main/java/net/openhft/chronicle/wire/BinaryWire.java index 9841330d71..22c6241d2b 100644 --- a/src/main/java/net/openhft/chronicle/wire/BinaryWire.java +++ b/src/main/java/net/openhft/chronicle/wire/BinaryWire.java @@ -3561,7 +3561,7 @@ public Object typePrefixOrObject(Class tClass) { try { return sb == null ? null : classLookup().forName(sb); } catch (ClassNotFoundRuntimeException e) { - if (Wires.dtoInterface(tClass) && GENERATE_TUPLES) { + if (Wires.dtoInterface(tClass) && generateTuples()) { return Wires.tupleFor(tClass, sb.toString()); } if (THROW_CNFRE) diff --git a/src/main/java/net/openhft/chronicle/wire/TextWire.java b/src/main/java/net/openhft/chronicle/wire/TextWire.java index 703ffcd01d..7b2bf7a45c 100644 --- a/src/main/java/net/openhft/chronicle/wire/TextWire.java +++ b/src/main/java/net/openhft/chronicle/wire/TextWire.java @@ -1881,7 +1881,7 @@ public Object typePrefixOrObject(Class tClass) { return o; } } - if (Wires.dtoInterface(tClass) && GENERATE_TUPLES && ObjectUtils.implementationToUse(tClass) == tClass) + if (Wires.dtoInterface(tClass) && generateTuples() && ObjectUtils.implementationToUse(tClass) == tClass) return Wires.tupleFor(tClass, null); return null; } @@ -1889,7 +1889,7 @@ public Object typePrefixOrObject(Class tClass) { @Nullable private Object handleCNFE(Class tClass, ClassNotFoundRuntimeException e, StringBuilder stringBuilder) { if (tClass == null) { - if (GENERATE_TUPLES) { + if (generateTuples()) { return Wires.tupleFor(null, stringBuilder.toString()); } String message = "Unable to load " + stringBuilder + ", is a class alias missing."; @@ -1916,7 +1916,7 @@ private Object handleCNFE(Class tClass, ClassNotFoundRuntimeException e, StringB } } - } else if (GENERATE_TUPLES && tClass.getClassLoader() != null && tClass.isInterface()) { + } else if (generateTuples() && tClass.getClassLoader() != null && tClass.isInterface()) { return Wires.tupleFor(tClass, stringBuilder.toString()); } diff --git a/src/main/java/net/openhft/chronicle/wire/WireIn.java b/src/main/java/net/openhft/chronicle/wire/WireIn.java index fd7f39cd93..6c402621ba 100644 --- a/src/main/java/net/openhft/chronicle/wire/WireIn.java +++ b/src/main/java/net/openhft/chronicle/wire/WireIn.java @@ -235,6 +235,35 @@ default boolean hasMetaDataPrefix() { return false; } + /** + * Sets the state of tuple generation for the implementing class. + *
+ * Implementing classes are expected to override this method to provide meaningful functionality + * if they support dynamic tuple generation. + * + * @param generateTuples A boolean value indicating the desired state of tuple generation. + * Setting this to true in the default implementation will result in an exception. + * @throws UnsupportedOperationException if the method is invoked with true in its default implementation, + * indicating that tuple generation is not supported. + */ + default void generateTuples(boolean generateTuples) { + if (generateTuples) + throw new UnsupportedOperationException(); + } + + /** + * Retrieves the current state of tuple generation in the implementing class. + *
+ * Implementing classes should override this method to return the actual state of tuple generation + * if they support this feature. + * + * @return A boolean value indicating whether tuple generation is currently enabled. The default + * implementation always returns false. + */ + default boolean generateTuples() { + return false; + } + enum HeaderType { NONE, DATA, META_DATA, EOF } diff --git a/src/main/java/net/openhft/chronicle/wire/WireTypeConverter.java b/src/main/java/net/openhft/chronicle/wire/WireTypeConverter.java index c2cbff82bb..c34beefc5f 100644 --- a/src/main/java/net/openhft/chronicle/wire/WireTypeConverter.java +++ b/src/main/java/net/openhft/chronicle/wire/WireTypeConverter.java @@ -18,7 +18,7 @@ public CharSequence yamlToJson(CharSequence yaml) { return delegate.yamlToJson(yaml); } - public void addAlias(Class newClass, String oldTypeName) { + public void addAlias(Class> newClass, String oldTypeName) { delegate.addAlias(newClass, oldTypeName); } } diff --git a/src/main/java/net/openhft/chronicle/wire/Wires.java b/src/main/java/net/openhft/chronicle/wire/Wires.java index 071d20f8c0..ec82f4fbe6 100644 --- a/src/main/java/net/openhft/chronicle/wire/Wires.java +++ b/src/main/java/net/openhft/chronicle/wire/Wires.java @@ -803,19 +803,38 @@ static Marshallable newInstance(Constructor constructor, String typeName) { } } + /** + * Generates and returns a tuple instance for the specified class and type name. + * This method is particularly useful for creating tuples for data types or classes + * that are not available locally, enabling data to be read from a WireIn and passed on. + *
+ * This method ensures the class type specified is an interface and leverages the + * Marshallable function to generate the tuple. If the specified class is null or + * is the Object class, it defaults to using the Marshallable class. + *
+ * Note: If the provided class type is not an interface or if the required tuple
+ * cannot be generated for the given type name, the method returns null and logs a
+ * warning.
+ *
+ * @param