or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

async.mdcore.mdindex.mdmetadata.mdprotocols.mdschemes.mdservers.mdtransports.mdutilities.md

utilities.mddocs/

0

# Utilities and Annotations

1

2

Utility classes and annotations that support Thrift operations, including string processing, partial deserialization support, and field annotations for enhanced functionality.

3

4

## Capabilities

5

6

### String Utilities

7

8

Utility methods for string processing and binary data handling in Thrift operations.

9

10

```java { .api }

11

/**

12

* String utility methods for Thrift operations

13

*/

14

public class StringUtils {

15

/** Convert object to string representation for debugging */

16

public static String toString(Object obj);

17

18

/** Convert binary data to string representation */

19

public static String toBinaryString(byte[] bytes);

20

21

/** Fast binary data decoding */

22

public static byte[] fastBinaryDecode(String str);

23

24

/** Fast binary data encoding */

25

public static String fastBinaryEncode(byte[] bytes);

26

}

27

```

28

29

**Usage Examples:**

30

31

```java

32

import org.apache.thrift.utils.StringUtils;

33

34

// Using string utilities for debugging and data conversion

35

public class StringUtilsExample {

36

public void demonstrateStringUtils() {

37

// Convert binary data for logging

38

byte[] binaryData = {0x48, 0x65, 0x6C, 0x6C, 0x6F}; // "Hello"

39

String binaryString = StringUtils.toBinaryString(binaryData);

40

System.out.println("Binary representation: " + binaryString);

41

42

// Fast encoding/decoding for binary fields

43

String encoded = StringUtils.fastBinaryEncode(binaryData);

44

byte[] decoded = StringUtils.fastBinaryDecode(encoded);

45

46

// Object to string conversion for debugging

47

MyStruct struct = new MyStruct();

48

struct.setName("example");

49

String debugString = StringUtils.toString(struct);

50

System.out.println("Debug string: " + debugString);

51

}

52

}

53

```

54

55

### Partial Deserialization Utilities

56

57

Additional utilities supporting partial deserialization operations beyond the basic TDeserializer functionality.

58

59

```java { .api }

60

/**

61

* Metadata support for partial deserialization operations

62

*/

63

public class ThriftMetadata {

64

/** Get Thrift metadata for a class */

65

public static <T extends TBase> Map<String, Object> getThriftMetadata(Class<T> clazz);

66

67

/** Get field metadata by name */

68

public static <T extends TBase> Object getFieldMetadata(Class<T> clazz, String fieldName);

69

70

/** Get field ID by name */

71

public static <T extends TBase> Integer getFieldId(Class<T> clazz, String fieldName);

72

}

73

74

/**

75

* Utility class for field data encoding and decoding in partial deserialization

76

*/

77

public class TFieldData {

78

/** Encode field data for efficient storage/transmission */

79

public static byte[] encode(Object fieldValue, byte fieldType);

80

81

/** Decode field data from encoded format */

82

public static Object decode(byte[] encodedData, byte fieldType);

83

84

/** Encode field ID for compact representation */

85

public static byte[] encodeId(short fieldId);

86

87

/** Decode field ID from encoded format */

88

public static short decodeId(byte[] encodedId);

89

}

90

91

/**

92

* Comparison utilities for partial Thrift objects

93

*/

94

public class PartialThriftComparer {

95

/** Compare two partial objects for equality */

96

public static boolean isEqualTo(Object obj1, Object obj2);

97

98

/** Compare two partial objects with ordering */

99

public static int compareTo(Object obj1, Object obj2);

100

101

/** Resolve differences between partial objects */

102

public static <T extends TBase> T resolve(T obj1, T obj2, ConflictResolver resolver);

103

104

/**

105

* Interface for resolving conflicts between partial objects

106

*/

107

public interface ConflictResolver {

108

/** Resolve conflict between two field values */

109

Object resolve(String fieldName, Object value1, Object value2);

110

}

111

}

112

```

113

114

**Usage Examples:**

115

116

```java

117

import org.apache.thrift.partial.ThriftMetadata;

118

import org.apache.thrift.partial.TFieldData;

119

import org.apache.thrift.partial.PartialThriftComparer;

120

121

// Working with partial deserialization utilities

122

public class PartialUtilitiesExample {

123

124

public void demonstrateMetadata() {

125

// Get metadata for a Thrift class

126

Map<String, Object> metadata = ThriftMetadata.getThriftMetadata(MyStruct.class);

127

System.out.println("Available fields: " + metadata.keySet());

128

129

// Get specific field information

130

Integer fieldId = ThriftMetadata.getFieldId(MyStruct.class, "name");

131

System.out.println("Field 'name' has ID: " + fieldId);

132

}

133

134

public void demonstrateFieldDataEncoding() {

135

// Encode field data for compact storage

136

String originalValue = "example string";

137

byte[] encoded = TFieldData.encode(originalValue, TType.STRING);

138

139

// Decode field data

140

String decoded = (String) TFieldData.decode(encoded, TType.STRING);

141

System.out.println("Original: " + originalValue);

142

System.out.println("Decoded: " + decoded);

143

144

// Encode field IDs

145

short fieldId = 123;

146

byte[] encodedId = TFieldData.encodeId(fieldId);

147

short decodedId = TFieldData.decodeId(encodedId);

148

}

149

150

public void demonstrateComparison() {

151

MyStruct struct1 = new MyStruct();

152

struct1.setName("example");

153

struct1.setValue(42);

154

155

MyStruct struct2 = new MyStruct();

156

struct2.setName("example");

157

struct2.setValue(43);

158

159

// Compare partial objects

160

boolean isEqual = PartialThriftComparer.isEqualTo(struct1, struct2);

161

int comparison = PartialThriftComparer.compareTo(struct1, struct2);

162

163

// Resolve conflicts

164

PartialThriftComparer.ConflictResolver resolver = (fieldName, value1, value2) -> {

165

// Custom resolution logic

166

if ("value".equals(fieldName)) {

167

// Take the higher value

168

return ((Integer) value1) > ((Integer) value2) ? value1 : value2;

169

}

170

return value1; // Default to first value

171

};

172

173

MyStruct resolved = PartialThriftComparer.resolve(struct1, struct2, resolver);

174

System.out.println("Resolved value: " + resolved.getValue()); // Should be 43

175

}

176

}

177

```

178

179

### Field Annotations

180

181

Annotations for marking field properties and behaviors in Thrift objects.

182

183

```java { .api }

184

/**

185

* Annotation to mark fields as nullable at runtime

186

* Can be used for validation and code generation hints

187

*/

188

@Retention(RetentionPolicy.RUNTIME)

189

@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER})

190

public @interface Nullable {

191

/** Optional description of nullability conditions */

192

String value() default "";

193

}

194

```

195

196

**Usage Examples:**

197

198

```java

199

import org.apache.thrift.annotation.Nullable;

200

201

// Using nullable annotation in Thrift struct implementations

202

public class AnnotatedStruct implements TBase<AnnotatedStruct, AnnotatedStruct._Fields> {

203

204

@Nullable("This field may be null in some contexts")

205

private String optionalField;

206

207

private String requiredField; // Not annotated, assumed non-null

208

209

// Getters and setters

210

@Nullable

211

public String getOptionalField() {

212

return optionalField;

213

}

214

215

public void setOptionalField(@Nullable String optionalField) {

216

this.optionalField = optionalField;

217

}

218

219

public String getRequiredField() {

220

return requiredField;

221

}

222

223

public void setRequiredField(String requiredField) {

224

this.requiredField = requiredField;

225

}

226

}

227

228

// Utility for working with nullable annotations

229

public class NullableUtils {

230

231

public static boolean isNullable(Field field) {

232

return field.isAnnotationPresent(Nullable.class);

233

}

234

235

public static boolean isNullable(Method method) {

236

return method.isAnnotationPresent(Nullable.class);

237

}

238

239

public static String getNullableDescription(Field field) {

240

Nullable annotation = field.getAnnotation(Nullable.class);

241

return annotation != null ? annotation.value() : null;

242

}

243

244

// Validation method using nullable annotations

245

public static <T> void validateNullable(T obj) throws IllegalArgumentException {

246

Class<?> clazz = obj.getClass();

247

Field[] fields = clazz.getDeclaredFields();

248

249

for (Field field : fields) {

250

field.setAccessible(true);

251

try {

252

Object value = field.get(obj);

253

254

// Check non-nullable fields

255

if (!isNullable(field) && value == null) {

256

throw new IllegalArgumentException(

257

"Non-nullable field '" + field.getName() + "' cannot be null");

258

}

259

} catch (IllegalAccessException e) {

260

// Handle reflection error

261

System.err.println("Cannot access field: " + field.getName());

262

}

263

}

264

}

265

}

266

```

267

268

### Integration with Reflection

269

270

Using utilities and annotations with Java reflection for advanced Thrift operations.

271

272

```java

273

import org.apache.thrift.annotation.Nullable;

274

import java.lang.reflect.Field;

275

import java.lang.reflect.Method;

276

277

// Advanced reflection utilities for Thrift objects

278

public class ReflectionUtils {

279

280

/**

281

* Get all nullable fields in a Thrift object

282

*/

283

public static List<Field> getNullableFields(Class<?> clazz) {

284

List<Field> nullableFields = new ArrayList<>();

285

286

for (Field field : clazz.getDeclaredFields()) {

287

if (field.isAnnotationPresent(Nullable.class)) {

288

nullableFields.add(field);

289

}

290

}

291

292

return nullableFields;

293

}

294

295

/**

296

* Create a validation report for a Thrift object

297

*/

298

public static ValidationReport validate(Object obj) {

299

ValidationReport report = new ValidationReport();

300

Class<?> clazz = obj.getClass();

301

302

// Check nullable annotations

303

for (Field field : clazz.getDeclaredFields()) {

304

field.setAccessible(true);

305

try {

306

Object value = field.get(obj);

307

boolean isNullable = field.isAnnotationPresent(Nullable.class);

308

309

if (!isNullable && value == null) {

310

report.addError("Non-nullable field '" + field.getName() + "' is null");

311

} else if (isNullable && value == null) {

312

report.addWarning("Nullable field '" + field.getName() + "' is null");

313

}

314

} catch (IllegalAccessException e) {

315

report.addError("Cannot access field: " + field.getName());

316

}

317

}

318

319

return report;

320

}

321

322

public static class ValidationReport {

323

private List<String> errors = new ArrayList<>();

324

private List<String> warnings = new ArrayList<>();

325

326

public void addError(String error) { errors.add(error); }

327

public void addWarning(String warning) { warnings.add(warning); }

328

329

public boolean hasErrors() { return !errors.isEmpty(); }

330

public List<String> getErrors() { return errors; }

331

public List<String> getWarnings() { return warnings; }

332

333

@Override

334

public String toString() {

335

StringBuilder sb = new StringBuilder();

336

if (!errors.isEmpty()) {

337

sb.append("Errors:\n");

338

for (String error : errors) {

339

sb.append(" - ").append(error).append("\n");

340

}

341

}

342

if (!warnings.isEmpty()) {

343

sb.append("Warnings:\n");

344

for (String warning : warnings) {

345

sb.append(" - ").append(warning).append("\n");

346

}

347

}

348

return sb.toString();

349

}

350

}

351

}

352

353

// Usage example

354

public class ValidationExample {

355

public void validateStruct() {

356

AnnotatedStruct struct = new AnnotatedStruct();

357

struct.setRequiredField("test");

358

// optionalField is left null

359

360

ReflectionUtils.ValidationReport report = ReflectionUtils.validate(struct);

361

362

if (report.hasErrors()) {

363

System.err.println("Validation failed:");

364

System.err.println(report);

365

} else {

366

System.out.println("Validation passed");

367

if (!report.getWarnings().isEmpty()) {

368

System.out.println("Warnings:");

369

System.out.println(report);

370

}

371

}

372

}

373

}

374

```

375

376

### Performance Utilities

377

378

Utilities for optimizing Thrift operations and monitoring performance.

379

380

```java

381

// Performance monitoring utilities

382

public class ThriftPerformanceUtils {

383

384

/**

385

* Measure serialization performance

386

*/

387

public static PerformanceResult measureSerialization(TBase<?, ?> object, TProtocolFactory protocolFactory, int iterations) {

388

long startTime = System.nanoTime();

389

long totalBytes = 0;

390

391

try {

392

for (int i = 0; i < iterations; i++) {

393

TSerializer serializer = new TSerializer(protocolFactory);

394

byte[] data = serializer.serialize(object);

395

totalBytes += data.length;

396

}

397

} catch (TException e) {

398

throw new RuntimeException("Serialization failed", e);

399

}

400

401

long endTime = System.nanoTime();

402

long duration = endTime - startTime;

403

404

return new PerformanceResult(iterations, duration, totalBytes);

405

}

406

407

public static class PerformanceResult {

408

public final int iterations;

409

public final long durationNanos;

410

public final long totalBytes;

411

public final double avgBytesPerObject;

412

public final double objectsPerSecond;

413

414

public PerformanceResult(int iterations, long durationNanos, long totalBytes) {

415

this.iterations = iterations;

416

this.durationNanos = durationNanos;

417

this.totalBytes = totalBytes;

418

this.avgBytesPerObject = (double) totalBytes / iterations;

419

this.objectsPerSecond = iterations / (durationNanos / 1_000_000_000.0);

420

}

421

422

@Override

423

public String toString() {

424

return String.format("Performance: %.2f objects/sec, %.1f bytes/object, %d total bytes",

425

objectsPerSecond, avgBytesPerObject, totalBytes);

426

}

427

}

428

}

429

```

430

431

These utilities and annotations provide additional functionality for working with Thrift objects, including enhanced debugging capabilities, validation support, and performance monitoring tools that complement the core Thrift framework.