or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

index.mdjaxb-lifecycle.mdjaxb-model.mdobject-locators.mdstrategic-patterns.mdutilities.md

object-locators.mddocs/

0

# Object Location Tracking

1

2

Object locator system for tracking navigation paths through object hierarchies. Essential for debugging, error reporting, and providing context during strategic operations. The locator system enables precise error reporting and supports JAXB validation integration.

3

4

## Capabilities

5

6

### Core Interfaces

7

8

#### ObjectLocator

9

10

Main interface that denotes a location in an object structure, extending both ValidationEventLocator and Reportable for comprehensive location tracking and reporting.

11

12

```java { .api }

13

interface ObjectLocator extends ValidationEventLocator, Reportable {

14

ObjectLocator getParentLocator();

15

ObjectLocator[] getPath();

16

String getPathAsString();

17

PropertyObjectLocator property(String propertyName, Object propertyValue);

18

ItemObjectLocator item(int itemIndex, Object itemValue);

19

}

20

```

21

22

#### Specialized Locator Interfaces

23

24

```java { .api }

25

interface RootObjectLocator extends ObjectLocator {

26

// Marker interface for root object locators

27

}

28

29

interface PropertyObjectLocator extends ObjectLocator {

30

String getPropertyName();

31

Object getObject();

32

}

33

34

interface ItemObjectLocator extends ObjectLocator {

35

int getIndex();

36

Object getObject();

37

}

38

```

39

40

### Abstract Base Implementation

41

42

```java { .api }

43

abstract class AbstractObjectLocator implements ObjectLocator {

44

protected AbstractObjectLocator(ObjectLocator parentLocator, Object object);

45

46

// ObjectLocator methods

47

public ObjectLocator getParentLocator();

48

public ObjectLocator[] getPath();

49

public String getPathAsString();

50

public Object getObject();

51

public ItemObjectLocator item(int index, Object value);

52

public PropertyObjectLocator property(String name, Object value);

53

54

// ValidationEventLocator methods (return default values)

55

public int getColumnNumber();

56

public int getLineNumber();

57

public int getOffset();

58

public URL getURL();

59

public Node getNode();

60

61

// Reportable methods

62

public String getMessageCode();

63

public String getMessage();

64

public String getMessage(ResourceBundle bundle);

65

66

// Abstract methods for subclasses

67

protected abstract String getStepAsString();

68

protected abstract String getDefaultMessage();

69

}

70

```

71

72

### Concrete Implementations

73

74

```java { .api }

75

final class DefaultRootObjectLocator extends AbstractObjectLocator implements RootObjectLocator {

76

public DefaultRootObjectLocator(Object rootObject);

77

public Object[] getMessageParameters();

78

}

79

80

final class DefaultPropertyObjectLocator extends AbstractObjectLocator implements PropertyObjectLocator {

81

protected DefaultPropertyObjectLocator(ObjectLocator parentLocator, String propertyName, Object propertyValue);

82

public String getPropertyName();

83

public Object[] getMessageParameters();

84

}

85

86

final class DefaultItemObjectLocator extends AbstractObjectLocator implements ItemObjectLocator {

87

protected DefaultItemObjectLocator(ObjectLocator parentLocator, int itemIndex, Object itemValue);

88

public int getIndex();

89

public Object[] getMessageParameters();

90

}

91

```

92

93

### Utility Classes

94

95

```java { .api }

96

final class LocatorUtils {

97

// SAX Locator formatting

98

static String getLocation(Locator locator);

99

100

// Null-safe property locator creation

101

static PropertyObjectLocator property(ObjectLocator parent, String name, Object value);

102

static PropertyObjectLocator property(ObjectLocator parent, String name, boolean value);

103

static PropertyObjectLocator property(ObjectLocator parent, String name, byte value);

104

static PropertyObjectLocator property(ObjectLocator parent, String name, char value);

105

static PropertyObjectLocator property(ObjectLocator parent, String name, double value);

106

static PropertyObjectLocator property(ObjectLocator parent, String name, float value);

107

static PropertyObjectLocator property(ObjectLocator parent, String name, int value);

108

static PropertyObjectLocator property(ObjectLocator parent, String name, long value);

109

static PropertyObjectLocator property(ObjectLocator parent, String name, short value);

110

111

// Null-safe item locator creation

112

static ItemObjectLocator item(ObjectLocator parent, int index, Object value);

113

static ItemObjectLocator item(ObjectLocator parent, int index, boolean value);

114

static ItemObjectLocator item(ObjectLocator parent, int index, byte value);

115

static ItemObjectLocator item(ObjectLocator parent, int index, char value);

116

static ItemObjectLocator item(ObjectLocator parent, int index, double value);

117

static ItemObjectLocator item(ObjectLocator parent, int index, float value);

118

static ItemObjectLocator item(ObjectLocator parent, int index, int value);

119

static ItemObjectLocator item(ObjectLocator parent, int index, long value);

120

static ItemObjectLocator item(ObjectLocator parent, int index, short value);

121

}

122

```

123

124

## Usage Examples

125

126

### Basic Object Path Tracking

127

128

```java

129

import org.jvnet.jaxb2_commons.locator.*;

130

import org.jvnet.jaxb2_commons.locator.util.LocatorUtils;

131

132

// Create root locator for a customer object

133

Customer customer = new Customer();

134

customer.setName("John Doe");

135

customer.setAddress(new Address());

136

customer.getAddress().setStreet("123 Main St");

137

138

DefaultRootObjectLocator rootLocator = new DefaultRootObjectLocator(customer);

139

140

// Navigate to properties

141

PropertyObjectLocator nameLocator = rootLocator.property("name", customer.getName());

142

PropertyObjectLocator addressLocator = rootLocator.property("address", customer.getAddress());

143

PropertyObjectLocator streetLocator = addressLocator.property("street", customer.getAddress().getStreet());

144

145

// Get path information

146

System.out.println(streetLocator.getPathAsString());

147

// Output: <customer>.address.street

148

149

ObjectLocator[] path = streetLocator.getPath();

150

// Returns array: [rootLocator, addressLocator, streetLocator]

151

```

152

153

### Using LocatorUtils for Null-Safe Operations

154

155

```java

156

import org.jvnet.jaxb2_commons.locator.util.LocatorUtils;

157

158

// Null-safe property creation (handles null parent gracefully)

159

ObjectLocator parentLocator = null; // or any ObjectLocator

160

PropertyObjectLocator safeLocator = LocatorUtils.property(parentLocator, "name", "John");

161

// Returns locator even if parent is null

162

163

// Primitive type handling with auto-boxing

164

PropertyObjectLocator intLocator = LocatorUtils.property(parentLocator, "age", 25);

165

PropertyObjectLocator booleanLocator = LocatorUtils.property(parentLocator, "active", true);

166

167

// Array/collection item tracking

168

List<String> items = Arrays.asList("first", "second", "third");

169

ObjectLocator listLocator = new DefaultRootObjectLocator(items);

170

for (int i = 0; i < items.size(); i++) {

171

ItemObjectLocator itemLocator = LocatorUtils.item(listLocator, i, items.get(i));

172

System.out.println(itemLocator.getPathAsString());

173

// Output: <list>[0], <list>[1], <list>[2]

174

}

175

```

176

177

### Integration with Strategic Patterns

178

179

```java

180

public class Order implements Equals2 {

181

private String orderId;

182

private List<OrderItem> items;

183

184

@Override

185

public boolean equals(ObjectLocator thisLocator, ObjectLocator thatLocator,

186

Object object, EqualsStrategy2 strategy) {

187

if (!(object instanceof Order)) {

188

return false;

189

}

190

Order that = (Order) object;

191

192

// Using LocatorUtils for property navigation

193

boolean orderIdEquals = strategy.equals(

194

LocatorUtils.property(thisLocator, "orderId", this.orderId),

195

LocatorUtils.property(thatLocator, "orderId", that.orderId),

196

this.orderId, that.orderId,

197

(this.orderId != null), (that.orderId != null)

198

);

199

200

boolean itemsEquals = strategy.equals(

201

LocatorUtils.property(thisLocator, "items", this.items),

202

LocatorUtils.property(thatLocator, "items", that.items),

203

this.items, that.items,

204

(this.items != null), (that.items != null)

205

);

206

207

return orderIdEquals && itemsEquals;

208

}

209

}

210

```

211

212

### Error Reporting with Locators

213

214

```java

215

// Custom validation using locators for precise error reporting

216

public class CustomerValidator {

217

public void validate(Customer customer) {

218

DefaultRootObjectLocator rootLocator = new DefaultRootObjectLocator(customer);

219

220

if (customer.getName() == null || customer.getName().trim().isEmpty()) {

221

PropertyObjectLocator nameLocator = LocatorUtils.property(rootLocator, "name", customer.getName());

222

throw new ValidationException("Name is required at: " + nameLocator.getPathAsString());

223

}

224

225

if (customer.getAddresses() != null) {

226

PropertyObjectLocator addressesLocator = LocatorUtils.property(rootLocator, "addresses", customer.getAddresses());

227

for (int i = 0; i < customer.getAddresses().size(); i++) {

228

Address address = customer.getAddresses().get(i);

229

ItemObjectLocator addressLocator = LocatorUtils.item(addressesLocator, i, address);

230

231

if (address.getZipCode() == null) {

232

PropertyObjectLocator zipLocator = LocatorUtils.property(addressLocator, "zipCode", address.getZipCode());

233

throw new ValidationException("Zip code is required at: " + zipLocator.getPathAsString());

234

// Error message: "Zip code is required at: <customer>.addresses[2].zipCode"

235

}

236

}

237

}

238

}

239

}

240

```

241

242

### JAXB Validation Integration

243

244

```java

245

// Implementing Reportable for internationalized error messages

246

public class CustomValidationError extends AbstractObjectLocator implements Reportable {

247

private final String messageCode;

248

private final Object[] parameters;

249

250

public CustomValidationError(ObjectLocator parent, String property, Object value,

251

String messageCode, Object... parameters) {

252

super(parent, value);

253

this.messageCode = messageCode;

254

this.parameters = parameters;

255

}

256

257

@Override

258

public String getMessageCode() {

259

return messageCode;

260

}

261

262

@Override

263

public Object[] getMessageParameters() {

264

return parameters;

265

}

266

267

@Override

268

protected String getStepAsString() {

269

return getPropertyName();

270

}

271

272

@Override

273

protected String getDefaultMessage() {

274

return "Validation error at " + getPathAsString();

275

}

276

}

277

278

// Usage in JAXB validation event handler

279

public class ValidationEventHandler implements javax.xml.bind.ValidationEventHandler {

280

@Override

281

public boolean handleEvent(ValidationEvent event) {

282

ValidationEventLocator locator = event.getLocator();

283

284

// Convert JAXB locator to our ObjectLocator if needed

285

if (locator instanceof ObjectLocator) {

286

ObjectLocator objectLocator = (ObjectLocator) locator;

287

System.err.println("Validation error at: " + objectLocator.getPathAsString());

288

System.err.println("Message: " + objectLocator.getMessage());

289

}

290

291

return true; // Continue validation

292

}

293

}

294

```

295

296

## Object Path Tracking Architecture

297

298

The locator system works as a hierarchical path tracking mechanism:

299

300

1. **Root Level**: `DefaultRootObjectLocator` represents the starting point of navigation

301

2. **Property Navigation**: `DefaultPropertyObjectLocator` tracks object property access

302

3. **Collection Navigation**: `DefaultItemObjectLocator` tracks array/list element access

303

4. **Path Building**: Each locator maintains parent reference enabling full path reconstruction

304

5. **String Representation**: Paths are formatted as `<root>.property[index].subProperty[subIndex]...`

305

306

This architecture provides complete traceability through complex object hierarchies, making it invaluable for debugging JAXB binding issues, validation errors, and strategic operation failures.