or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

annotation-config.mdaot-support.mdbean-definition.mdbean-factory.mdindex.mdproperty-access.mdxml-config.md

property-access.mddocs/

0

# Property Access and Type Conversion

1

2

Powerful property binding system with automatic type conversion, nested property access, and comprehensive editor support for converting between string representations and Java objects. This system forms the foundation for Spring's data binding capabilities in web applications and configuration processing.

3

4

## Capabilities

5

6

### Property Accessor Interface

7

8

Core interface for accessing and modifying properties on target objects with support for nested properties and automatic type conversion.

9

10

```java { .api }

11

/**

12

* Common interface for classes that can access named properties (such as bean properties of an object or fields in an object).

13

*/

14

interface PropertyAccessor {

15

/** Path separator for nested properties. */

16

String NESTED_PROPERTY_SEPARATOR = ".";

17

/** Path separator for nested properties. */

18

char NESTED_PROPERTY_SEPARATOR_CHAR = '.';

19

/** Marker that indicates the start of a property key for an indexed or mapped property. */

20

String PROPERTY_KEY_PREFIX = "[";

21

/** Marker that indicates the start of a property key for an indexed or mapped property. */

22

char PROPERTY_KEY_PREFIX_CHAR = '[';

23

/** Marker that indicates the end of a property key for an indexed or mapped property. */

24

String PROPERTY_KEY_SUFFIX = "]";

25

/** Marker that indicates the end of a property key for an indexed or mapped property. */

26

char PROPERTY_KEY_SUFFIX_CHAR = ']';

27

28

/**

29

* Determine whether the specified property is readable.

30

* @param propertyName the property to check

31

* @return whether the property is readable

32

*/

33

boolean isReadableProperty(String propertyName);

34

35

/**

36

* Determine whether the specified property is writable.

37

* @param propertyName the property to check

38

* @return whether the property is writable

39

*/

40

boolean isWritableProperty(String propertyName);

41

42

/**

43

* Determine the property type for the specified property.

44

* @param propertyName the property to check

45

* @return the type of the property, or null if not determinable

46

* @throws InvalidPropertyException if there is no such property or if the property isn't readable

47

*/

48

Class<?> getPropertyType(String propertyName) throws BeansException;

49

50

/**

51

* Return a type descriptor for the specified property.

52

* @param propertyName the property to check

53

* @return the type descriptor for the particular property

54

* @throws InvalidPropertyException if there is no such property or if the property isn't readable

55

*/

56

TypeDescriptor getPropertyTypeDescriptor(String propertyName) throws BeansException;

57

58

/**

59

* Get the current value of the specified property.

60

* @param propertyName the name of the property to get the value of

61

* @return the value of the property

62

* @throws InvalidPropertyException if there is no such property or if the property isn't readable

63

* @throws PropertyAccessException if the property was valid but the accessor method failed

64

*/

65

Object getPropertyValue(String propertyName) throws BeansException;

66

67

/**

68

* Set the specified value as current property value.

69

* @param propertyName the name of the property to set the value of

70

* @param value the new value

71

* @throws InvalidPropertyException if there is no such property or if the property isn't writable

72

* @throws PropertyAccessException if the property was valid but the accessor method failed or a type mismatch occurred

73

*/

74

void setPropertyValue(String propertyName, Object value) throws BeansException;

75

76

/**

77

* Set the specified value as current property value.

78

* @param pv an object containing the new property value

79

* @throws InvalidPropertyException if there is no such property or if the property isn't writable

80

* @throws PropertyAccessException if the property was valid but the accessor method failed or a type mismatch occurred

81

*/

82

void setPropertyValue(PropertyValue pv) throws BeansException;

83

84

/**

85

* Perform a batch update from a Map.

86

* @param map Map containing properties to set, as name-value pairs

87

* @throws InvalidPropertyException if there is no such property or if the property isn't writable

88

* @throws PropertyBatchUpdateException if one or more PropertyAccessExceptions occurred for specific properties during the batch update

89

*/

90

void setPropertyValues(Map<?, ?> map) throws BeansException;

91

92

/**

93

* The preferred way to perform a batch update.

94

* @param pvs PropertyValues to set on the target object

95

* @throws InvalidPropertyException if there is no such property or if the property isn't writable

96

* @throws PropertyBatchUpdateException if one or more PropertyAccessExceptions occurred for specific properties during the batch update

97

*/

98

void setPropertyValues(PropertyValues pvs) throws BeansException;

99

100

/**

101

* Perform a batch update with more control over behavior.

102

* @param pvs PropertyValues to set on the target object

103

* @param ignoreUnknown should we ignore unknown properties (not found in the bean)

104

* @throws InvalidPropertyException if there is no such property or if the property isn't writable

105

* @throws PropertyBatchUpdateException if one or more PropertyAccessExceptions occurred for specific properties during the batch update

106

*/

107

void setPropertyValues(PropertyValues pvs, boolean ignoreUnknown) throws BeansException;

108

109

/**

110

* Perform a batch update with full control over behavior.

111

* @param pvs PropertyValues to set on the target object

112

* @param ignoreUnknown should we ignore unknown properties (not found in the bean)

113

* @param ignoreInvalid should we ignore invalid properties (found but not accessible)

114

* @throws InvalidPropertyException if there is no such property or if the property isn't writable

115

* @throws PropertyBatchUpdateException if one or more PropertyAccessExceptions occurred for specific properties during the batch update

116

*/

117

void setPropertyValues(PropertyValues pvs, boolean ignoreUnknown, boolean ignoreInvalid) throws BeansException;

118

}

119

```

120

121

### Bean Wrapper Interface

122

123

Central interface for accessing and manipulating the properties of a bean instance, combining property access with comprehensive type conversion.

124

125

```java { .api }

126

/**

127

* The central interface of Spring's low-level JavaBeans infrastructure.

128

*/

129

interface BeanWrapper extends ConfigurablePropertyAccessor {

130

/**

131

* Change the wrapped object. Implementations are required to allow the type of the wrapped object to change.

132

* @param object the new wrapped object

133

*/

134

void setWrappedInstance(Object object);

135

136

/**

137

* Return the bean instance wrapped by this object.

138

* @return the bean instance, or null if none set

139

*/

140

Object getWrappedInstance();

141

142

/**

143

* Return the type of the wrapped bean instance.

144

* @return the type of the wrapped bean instance, or null if no wrapped object has been set

145

*/

146

Class<?> getWrappedClass();

147

148

/**

149

* Obtain the PropertyDescriptors for the wrapped object (as determined by standard JavaBeans introspection).

150

* @return the PropertyDescriptors for the wrapped object

151

*/

152

PropertyDescriptor[] getPropertyDescriptors();

153

154

/**

155

* Obtain the property descriptor for a specific property of the wrapped object.

156

* @param propertyName the property to obtain the descriptor for

157

* @return the property descriptor for the specified property

158

* @throws InvalidPropertyException if there is no such property

159

*/

160

PropertyDescriptor getPropertyDescriptor(String propertyName) throws InvalidPropertyException;

161

}

162

```

163

164

### Bean Wrapper Implementation

165

166

Default implementation of the BeanWrapper interface that provides comprehensive property access and type conversion capabilities.

167

168

```java { .api }

169

/**

170

* Default BeanWrapper implementation that should be sufficient for all typical use cases.

171

*/

172

class BeanWrapperImpl extends AbstractNestablePropertyAccessor implements BeanWrapper {

173

/**

174

* Create a new empty BeanWrapperImpl. Wrapped instance needs to be set afterwards.

175

*/

176

public BeanWrapperImpl();

177

178

/**

179

* Create a new BeanWrapperImpl for the given object.

180

* @param object the object wrapped by this BeanWrapper

181

*/

182

public BeanWrapperImpl(Object object);

183

184

/**

185

* Create a new BeanWrapperImpl, wrapping a new instance of the specified class.

186

* @param clazz class to instantiate and wrap

187

*/

188

public BeanWrapperImpl(Class<?> clazz);

189

190

/**

191

* Create a new BeanWrapperImpl for the given object, registering a nested path that the object is in.

192

* @param object the object wrapped by this BeanWrapper

193

* @param nestedPath the nested path of the object

194

* @param rootObject the root object at the top of the path

195

*/

196

public BeanWrapperImpl(Object object, String nestedPath, Object rootObject);

197

198

/**

199

* Set a bean instance to hold, without any unwrapping of Optional.

200

* @param object the actual target object

201

*/

202

public void setBeanInstance(Object object);

203

204

/**

205

* Convert the given value for the specified property to the latter's type.

206

* @param value the value to convert (may be null)

207

* @param propertyName the target property

208

* @return the converted value

209

* @throws TypeMismatchException if type conversion failed

210

*/

211

public Object convertForProperty(Object value, String propertyName) throws TypeMismatchException;

212

}

213

```

214

215

### Property Values Support

216

217

Container for PropertyValue objects, typically representing one update for a JavaBean.

218

219

```java { .api }

220

/**

221

* Holder containing one or more PropertyValue objects, typically comprising one update for a specific target bean.

222

*/

223

interface PropertyValues {

224

/**

225

* Return an array of the PropertyValue objects held in this object.

226

* @return an array of the PropertyValue objects held in this object (never null)

227

*/

228

PropertyValue[] getPropertyValues();

229

230

/**

231

* Return the property value with the given name, if any.

232

* @param propertyName the name to search for

233

* @return the property value, or null if none

234

*/

235

PropertyValue getPropertyValue(String propertyName);

236

237

/**

238

* Return the changes since the previous PropertyValues.

239

* @param old the old property values

240

* @return the updated or new properties

241

*/

242

PropertyValues changesSince(PropertyValues old);

243

244

/**

245

* Is there a property value (or other processing entry) for this property?

246

* @param propertyName the name of the property we're interested in

247

* @return whether there is a property value for this property

248

*/

249

boolean contains(String propertyName);

250

251

/**

252

* Does this holder not contain any PropertyValue objects at all?

253

* @return whether this holder does not contain any PropertyValue objects

254

*/

255

boolean isEmpty();

256

257

/**

258

* Return the number of PropertyValue objects held in this object.

259

* @return the number of PropertyValue objects held in this object

260

*/

261

int size();

262

}

263

264

/**

265

* The default implementation of the PropertyValues interface.

266

*/

267

class MutablePropertyValues implements PropertyValues {

268

/**

269

* Creates a new empty MutablePropertyValues object.

270

*/

271

public MutablePropertyValues();

272

273

/**

274

* Deep copy constructor.

275

* @param original the PropertyValues to copy

276

*/

277

public MutablePropertyValues(PropertyValues original);

278

279

/**

280

* Construct a new MutablePropertyValues object from a Map.

281

* @param original a Map with property values keyed by property name Strings

282

*/

283

public MutablePropertyValues(Map<?, ?> original);

284

285

/**

286

* Construct a new MutablePropertyValues object using the given List of PropertyValue objects as-is.

287

* @param propertyValueList a List of PropertyValue objects

288

*/

289

public MutablePropertyValues(List<PropertyValue> propertyValueList);

290

291

/**

292

* Return the underlying List of PropertyValue objects in its raw form.

293

* @return the underlying List of PropertyValue objects

294

*/

295

public List<PropertyValue> getPropertyValueList();

296

297

/**

298

* Add all property values from the given PropertyValues object.

299

* @param other the PropertyValues object to add property values from

300

* @return this in order to allow for adding multiple property values in a chain

301

*/

302

public MutablePropertyValues addPropertyValues(PropertyValues other);

303

304

/**

305

* Add all property values from the given Map.

306

* @param other a Map with property values keyed by property name Strings

307

* @return this in order to allow for adding multiple property values in a chain

308

*/

309

public MutablePropertyValues addPropertyValues(Map<?, ?> other);

310

311

/**

312

* Add a PropertyValue object, replacing any existing one for the corresponding property or getting merged with it (if applicable).

313

* @param pv the PropertyValue object to add

314

* @return this in order to allow for adding multiple property values in a chain

315

*/

316

public MutablePropertyValues addPropertyValue(PropertyValue pv);

317

318

/**

319

* Add a PropertyValue object, replacing any existing one for the corresponding property.

320

* @param propertyName name of the property

321

* @param propertyValue value of the property

322

* @return this in order to allow for adding multiple property values in a chain

323

*/

324

public MutablePropertyValues addPropertyValue(String propertyName, Object propertyValue);

325

326

/**

327

* Add a PropertyValue object, replacing any existing one for the corresponding property.

328

* @param propertyName name of the property

329

* @param propertyValue value of the property

330

* @return this in order to allow for adding multiple property values in a chain

331

*/

332

public MutablePropertyValues add(String propertyName, Object propertyValue);

333

334

/**

335

* Remove the given PropertyValue, if contained.

336

* @param pv the PropertyValue to remove

337

*/

338

public void removePropertyValue(PropertyValue pv);

339

340

/**

341

* Overloaded version of removePropertyValue that takes a property name.

342

* @param propertyName name of the property to remove

343

*/

344

public void removePropertyValue(String propertyName);

345

}

346

347

/**

348

* Object to hold information and value for an individual bean property.

349

*/

350

class PropertyValue extends BeanMetadataAttributeAccessor {

351

/**

352

* Create a new PropertyValue instance.

353

* @param name the name of the property (never null)

354

* @param value the value of the property (possibly before type conversion)

355

*/

356

public PropertyValue(String name, Object value);

357

358

/**

359

* Copy constructor.

360

* @param original the PropertyValue to copy (never null)

361

*/

362

public PropertyValue(PropertyValue original);

363

364

/**

365

* Constructor that exposes a new value for an original value holder.

366

* @param original the PropertyValue to link to (never null)

367

* @param newValue the new value to apply

368

*/

369

public PropertyValue(PropertyValue original, Object newValue);

370

371

/**

372

* Return the name of the property.

373

* @return the name of the property (never null)

374

*/

375

public String getName();

376

377

/**

378

* Return the value of the property.

379

* @return the value of the property (possibly before type conversion)

380

*/

381

public Object getValue();

382

383

/**

384

* Return the original PropertyValue instance for this value holder.

385

* @return the original PropertyValue (either a source of this value holder or this value holder itself)

386

*/

387

public PropertyValue getOriginalPropertyValue();

388

389

/**

390

* Set whether this is an optional value, that is, to be ignored when no corresponding property exists on the target class.

391

* @param optional whether this is an optional value

392

*/

393

public void setOptional(boolean optional);

394

395

/**

396

* Return whether this is an optional value, that is, to be ignored when no corresponding property exists on the target class.

397

* @return whether this is an optional value

398

*/

399

public boolean isOptional();

400

401

/**

402

* Return whether this holder contains a converted value already (true), or whether the value still needs to be converted (false).

403

* @return whether this holder contains a converted value already

404

*/

405

public synchronized boolean isConverted();

406

407

/**

408

* Set the converted value of the constructor argument, after processed type conversion.

409

* @param value the converted value

410

*/

411

public synchronized void setConvertedValue(Object value);

412

413

/**

414

* Return the converted value of the constructor argument, after processed type conversion.

415

* @return the converted value

416

*/

417

public synchronized Object getConvertedValue();

418

}

419

```

420

421

### Type Conversion Support

422

423

Core interfaces and classes for type conversion between different object types.

424

425

```java { .api }

426

/**

427

* Interface that defines type conversion methods.

428

*/

429

interface TypeConverter {

430

/**

431

* Convert the value to the required type (if necessary from a String).

432

* @param value the value to convert

433

* @param requiredType the type we must convert to (or null if not known)

434

* @return the new value, possibly the result of type conversion

435

* @throws TypeMismatchException if type conversion failed

436

*/

437

<T> T convertIfNecessary(Object value, Class<T> requiredType) throws TypeMismatchException;

438

439

/**

440

* Convert the value to the required type (if necessary from a String).

441

* @param value the value to convert

442

* @param requiredType the type we must convert to (or null if not known)

443

* @param methodParam the method parameter that is the target of the conversion

444

* @return the new value, possibly the result of type conversion

445

* @throws TypeMismatchException if type conversion failed

446

*/

447

<T> T convertIfNecessary(Object value, Class<T> requiredType, MethodParameter methodParam) throws TypeMismatchException;

448

449

/**

450

* Convert the value to the required type (if necessary from a String).

451

* @param value the value to convert

452

* @param requiredType the type we must convert to (or null if not known)

453

* @param field the reflective field that is the target of the conversion

454

* @return the new value, possibly the result of type conversion

455

* @throws TypeMismatchException if type conversion failed

456

*/

457

<T> T convertIfNecessary(Object value, Class<T> requiredType, Field field) throws TypeMismatchException;

458

459

/**

460

* Convert the value to the required type (if necessary from a String).

461

* @param value the value to convert

462

* @param requiredType the type we must convert to (or null if not known)

463

* @param typeDescriptor the type descriptor to use (may be null)

464

* @return the new value, possibly the result of type conversion

465

* @throws TypeMismatchException if type conversion failed

466

*/

467

<T> T convertIfNecessary(Object value, Class<T> requiredType, TypeDescriptor typeDescriptor) throws TypeMismatchException;

468

}

469

470

/**

471

* Simple implementation of the TypeConverter interface that does not operate on a specific target object.

472

*/

473

class SimpleTypeConverter extends TypeConverterSupport {

474

/**

475

* Create a new SimpleTypeConverter.

476

*/

477

public SimpleTypeConverter();

478

}

479

```

480

481

**Usage Examples:**

482

483

```java

484

import org.springframework.beans.BeanWrapper;

485

import org.springframework.beans.BeanWrapperImpl;

486

import org.springframework.beans.MutablePropertyValues;

487

import org.springframework.beans.PropertyValue;

488

489

// Basic property access

490

Person person = new Person();

491

BeanWrapper wrapper = new BeanWrapperImpl(person);

492

493

// Set simple properties

494

wrapper.setPropertyValue("name", "John Doe");

495

wrapper.setPropertyValue("age", 30);

496

wrapper.setPropertyValue("active", true);

497

498

// Get property values

499

String name = (String) wrapper.getPropertyValue("name");

500

Integer age = (Integer) wrapper.getPropertyValue("age");

501

502

// Nested property access

503

wrapper.setPropertyValue("address.street", "123 Main St");

504

wrapper.setPropertyValue("address.city", "New York");

505

506

// Batch property updates

507

MutablePropertyValues pvs = new MutablePropertyValues();

508

pvs.addPropertyValue("name", "Jane Smith");

509

pvs.addPropertyValue("email", "jane@example.com");

510

pvs.addPropertyValue("birthDate", "1990-01-15");

511

512

wrapper.setPropertyValues(pvs);

513

514

// Array and collection property access

515

wrapper.setPropertyValue("hobbies[0]", "Reading");

516

wrapper.setPropertyValue("hobbies[1]", "Swimming");

517

518

// Map property access

519

wrapper.setPropertyValue("attributes[title]", "Manager");

520

wrapper.setPropertyValue("attributes[department]", "Engineering");

521

522

// Type conversion example

523

SimpleTypeConverter converter = new SimpleTypeConverter();

524

Date date = converter.convertIfNecessary("2023-01-15", Date.class);

525

List<String> list = converter.convertIfNecessary("a,b,c", List.class);

526

```

527

528

### Property Editor Support

529

530

Registry and support for PropertyEditor instances used in type conversion.

531

532

```java { .api }

533

/**

534

* Interface for strategies that register custom property editors with a property editor registry.

535

*/

536

interface PropertyEditorRegistrar {

537

/**

538

* Register custom PropertyEditors with the given PropertyEditorRegistry.

539

* @param registry the PropertyEditorRegistry to register the custom PropertyEditors with

540

*/

541

void registerCustomEditors(PropertyEditorRegistry registry);

542

}

543

544

/**

545

* Encapsulates methods for registering JavaBeans PropertyEditors.

546

*/

547

interface PropertyEditorRegistry {

548

/**

549

* Register the given custom property editor for all properties of the given type.

550

* @param requiredType the type of the property

551

* @param propertyEditor the editor to register

552

*/

553

void registerCustomEditor(Class<?> requiredType, PropertyEditor propertyEditor);

554

555

/**

556

* Register the given custom property editor for the given type and property, or for all properties of the given type.

557

* @param requiredType the type of the property (can be null if a property is given but should be specified in any case for consistency checking)

558

* @param propertyPath the path of the property (name or nested path), or null if registering an editor for all properties of the given type

559

* @param propertyEditor the editor to register

560

*/

561

void registerCustomEditor(Class<?> requiredType, String propertyPath, PropertyEditor propertyEditor);

562

563

/**

564

* Find a custom property editor for the given type and property.

565

* @param requiredType the type of the property (can be null if a property is given but should be specified in any case for consistency checking)

566

* @param propertyPath the path of the property (name or nested path), or null if looking for an editor for all properties of the given type

567

* @return the registered editor, or null if none

568

*/

569

PropertyEditor findCustomEditor(Class<?> requiredType, String propertyPath);

570

}

571

```

572

573

### Property Editors Collection

574

575

Comprehensive collection of built-in PropertyEditor implementations for converting between string representations and Java objects.

576

577

```java { .api }

578

/**

579

* Property editor for Boolean/boolean properties.

580

*/

581

class CustomBooleanEditor extends PropertyEditorSupport {

582

public CustomBooleanEditor(boolean allowEmpty);

583

public CustomBooleanEditor(String trueString, String falseString, boolean allowEmpty);

584

}

585

586

/**

587

* Property editor for any Number subclass such as Short, Integer, Long, BigInteger, Float, Double, BigDecimal.

588

*/

589

class CustomNumberEditor extends PropertyEditorSupport {

590

public CustomNumberEditor(Class<? extends Number> numberClass, boolean allowEmpty) throws IllegalArgumentException;

591

public CustomNumberEditor(Class<? extends Number> numberClass, NumberFormat numberFormat, boolean allowEmpty) throws IllegalArgumentException;

592

}

593

594

/**

595

* Property editor for Date properties.

596

*/

597

class CustomDateEditor extends PropertyEditorSupport {

598

public CustomDateEditor(DateFormat dateFormat, boolean allowEmpty);

599

public CustomDateEditor(DateFormat dateFormat, boolean allowEmpty, int exactDateLength);

600

}

601

602

/**

603

* Property editor for Character properties.

604

*/

605

class CharacterEditor extends PropertyEditorSupport {

606

public CharacterEditor(boolean allowEmpty);

607

}

608

609

/**

610

* Property editor for Collections, converting any source Collection to a given target Collection type.

611

*/

612

class CustomCollectionEditor extends PropertyEditorSupport {

613

public CustomCollectionEditor(Class<? extends Collection> collectionType);

614

public CustomCollectionEditor(Class<? extends Collection> collectionType, boolean nullAsEmptyCollection);

615

}

616

617

/**

618

* Property editor for Maps, converting any source Map to a given target Map type.

619

*/

620

class CustomMapEditor extends PropertyEditorSupport {

621

public CustomMapEditor(Class<? extends Map> mapType);

622

public CustomMapEditor(Class<? extends Map> mapType, boolean nullAsEmptyMap);

623

}

624

625

/**

626

* Editor for String arrays.

627

*/

628

class StringArrayPropertyEditor extends PropertyEditorSupport {

629

public static final String DEFAULT_SEPARATOR = ",";

630

631

public StringArrayPropertyEditor();

632

public StringArrayPropertyEditor(String separator);

633

public StringArrayPropertyEditor(String separator, String charsToDelete);

634

public StringArrayPropertyEditor(String separator, String charsToDelete, boolean emptyArrayAsNull);

635

public StringArrayPropertyEditor(String separator, String charsToDelete, boolean emptyArrayAsNull, boolean trimValues);

636

}

637

638

/**

639

* Property editor for java.io.File descriptors.

640

*/

641

class FileEditor extends PropertyEditorSupport {

642

public FileEditor();

643

public FileEditor(ResourceEditor resourceEditor);

644

}

645

646

/**

647

* Editor for java.io.InputStream, converting from a Spring resource location String.

648

*/

649

class InputStreamEditor extends PropertyEditorSupport {

650

public InputStreamEditor();

651

public InputStreamEditor(ResourceEditor resourceEditor);

652

}

653

654

/**

655

* Editor for java.io.Reader, converting from a Spring resource location String.

656

*/

657

class ReaderEditor extends PropertyEditorSupport {

658

public ReaderEditor();

659

public ReaderEditor(ResourceEditor resourceEditor);

660

}

661

662

/**

663

* Editor for java.net.URL, converting from a Spring resource location String.

664

*/

665

class URLEditor extends PropertyEditorSupport {

666

public URLEditor();

667

public URLEditor(ResourceEditor resourceEditor);

668

}

669

670

/**

671

* Editor for java.net.URI, converting from a Spring resource location String.

672

*/

673

class URIEditor extends PropertyEditorSupport {

674

public URIEditor();

675

public URIEditor(ClassLoader classLoader);

676

public URIEditor(ClassLoader classLoader, boolean encode);

677

}

678

679

/**

680

* Editor for java.nio.file.Path, converting from a Spring resource location String.

681

*/

682

class PathEditor extends PropertyEditorSupport {

683

public PathEditor();

684

public PathEditor(ResourceEditor resourceEditor);

685

}

686

687

/**

688

* Editor for java.util.Locale, converting from a String representation to a Locale object.

689

*/

690

class LocaleEditor extends PropertyEditorSupport {

691

public LocaleEditor();

692

}

693

694

/**

695

* Editor for java.util.TimeZone, converting from a String representation to a TimeZone object.

696

*/

697

class TimeZoneEditor extends PropertyEditorSupport {

698

public TimeZoneEditor();

699

}

700

701

/**

702

* Editor for java.time.ZoneId, converting from a String representation to a ZoneId object.

703

*/

704

class ZoneIdEditor extends PropertyEditorSupport {

705

public ZoneIdEditor();

706

}

707

708

/**

709

* Editor for java.util.regex.Pattern, converting from a String representation to a Pattern object.

710

*/

711

class PatternEditor extends PropertyEditorSupport {

712

public PatternEditor();

713

public PatternEditor(int flags);

714

}

715

716

/**

717

* Editor for java.nio.charset.Charset, converting from a String representation to a Charset object.

718

*/

719

class CharsetEditor extends PropertyEditorSupport {

720

public CharsetEditor();

721

}

722

723

/**

724

* Editor for java.lang.Class, converting from a String representation to a Class object.

725

*/

726

class ClassEditor extends PropertyEditorSupport {

727

public ClassEditor();

728

public ClassEditor(ClassLoader classLoader);

729

}

730

731

/**

732

* Property editor for an array of Classes, converting from a comma-delimited String to a Class array.

733

*/

734

class ClassArrayEditor extends PropertyEditorSupport {

735

public ClassArrayEditor();

736

public ClassArrayEditor(ClassLoader classLoader);

737

}

738

739

/**

740

* Editor for java.util.UUID, converting from a String representation to a UUID object.

741

*/

742

class UUIDEditor extends PropertyEditorSupport {

743

public UUIDEditor();

744

}

745

746

/**

747

* Editor for java.util.Currency, converting from a String representation to a Currency object.

748

*/

749

class CurrencyEditor extends PropertyEditorSupport {

750

public CurrencyEditor();

751

}

752

```

753

754

### Utility Classes for Property Access

755

756

Utility classes that provide helper methods for property access operations.

757

758

```java { .api }

759

/**

760

* Static convenience methods for JavaBeans.

761

*/

762

class BeanUtils {

763

/**

764

* Instantiate a class using its 'no-arg' constructor.

765

* @param clazz the class to instantiate

766

* @return the new instance

767

* @throws BeanInstantiationException if the bean cannot be instantiated

768

*/

769

public static <T> T instantiateClass(Class<T> clazz) throws BeanInstantiationException;

770

771

/**

772

* Instantiate a class using the given constructor.

773

* @param ctor the constructor to use

774

* @param args the constructor arguments to apply

775

* @return the new instance

776

* @throws BeanInstantiationException if the bean cannot be instantiated

777

*/

778

public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException;

779

780

/**

781

* Find a method with the given method name and parameter types.

782

* @param clazz the class to introspect

783

* @param methodName the name of the method

784

* @param paramTypes the parameter types of the method

785

* @return the Method object, or null if none found

786

*/

787

public static Method findMethod(Class<?> clazz, String methodName, Class<?>... paramTypes);

788

789

/**

790

* Find a method with the given method name and minimal parameters.

791

* @param clazz the class to introspect

792

* @param methodName the name of the method

793

* @return the Method object, or null if none found

794

*/

795

public static Method findMethodWithMinimalParameters(Class<?> clazz, String methodName) throws IllegalArgumentException;

796

797

/**

798

* Find a method with the given method name and minimal parameters.

799

* @param methods the candidate methods

800

* @param methodName the name of the method

801

* @return the Method object, or null if none found

802

*/

803

public static Method findMethodWithMinimalParameters(Method[] methods, String methodName) throws IllegalArgumentException;

804

805

/**

806

* Find a method with the given method name and the given parameter types.

807

* @param clazz the class to introspect

808

* @param methodName the name of the method

809

* @param paramTypes the parameter types of the method

810

* @return the Method object, or null if none found

811

*/

812

public static Method resolveSignature(String signature, Class<?> clazz);

813

814

/**

815

* Retrieve the JavaBeans PropertyDescriptors of a given class.

816

* @param clazz the Class to retrieve the PropertyDescriptors for

817

* @return an array of PropertyDescriptors for the given class

818

* @throws BeansException if an error occurs

819

*/

820

public static PropertyDescriptor[] getPropertyDescriptors(Class<?> clazz) throws BeansException;

821

822

/**

823

* Retrieve the JavaBeans PropertyDescriptor for the given property.

824

* @param clazz the Class to retrieve the PropertyDescriptor for

825

* @param propertyName the name of the property

826

* @return the PropertyDescriptor for the given property

827

* @throws BeansException if an error occurs

828

*/

829

public static PropertyDescriptor getPropertyDescriptor(Class<?> clazz, String propertyName) throws BeansException;

830

831

/**

832

* Find a JavaBeans PropertyDescriptor for the given method.

833

* @param method the method to find a corresponding PropertyDescriptor for

834

* @return the corresponding PropertyDescriptor, or null if none

835

* @throws BeansException if an error occurs

836

*/

837

public static PropertyDescriptor findPropertyForMethod(Method method) throws BeansException;

838

839

/**

840

* Find a JavaBeans PropertyDescriptor for the given method.

841

* @param method the method to find a corresponding PropertyDescriptor for

842

* @param clazz the (most specific) class to introspect for descriptors

843

* @return the corresponding PropertyDescriptor, or null if none

844

* @throws BeansException if an error occurs

845

*/

846

public static PropertyDescriptor findPropertyForMethod(Method method, Class<?> clazz) throws BeansException;

847

848

/**

849

* Find a JavaBeans setter method for the given property.

850

* @param clazz the Class to find the method on

851

* @param propertyName the property name

852

* @return the setter method, or null if none

853

*/

854

public static Method findPropertyType(String propertyName, Class<?>... beanClasses);

855

856

/**

857

* Obtain a new MethodParameter object for the write method of the specified property.

858

* @param pd the PropertyDescriptor for the property

859

* @return a corresponding MethodParameter object

860

*/

861

public static MethodParameter getWriteMethodParameter(PropertyDescriptor pd);

862

863

/**

864

* Check if the given type represents a "simple" property.

865

* @param type the type to check

866

* @return whether the given type represents a "simple" property

867

*/

868

public static boolean isSimpleProperty(Class<?> type);

869

870

/**

871

* Check if the given type represents a "simple" value type.

872

* @param type the type to check

873

* @return whether the given type represents a "simple" value type

874

*/

875

public static boolean isSimpleValueType(Class<?> type);

876

877

/**

878

* Copy the property values of the given source bean into the target bean.

879

* @param source the source bean

880

* @param target the target bean

881

* @throws BeansException if the copying failed

882

*/

883

public static void copyProperties(Object source, Object target) throws BeansException;

884

885

/**

886

* Copy the property values of the given source bean into the given target bean.

887

* @param source the source bean

888

* @param target the target bean

889

* @param editable the class (or interface) to restrict property setting to

890

* @throws BeansException if the copying failed

891

*/

892

public static void copyProperties(Object source, Object target, Class<?> editable) throws BeansException;

893

894

/**

895

* Copy the property values of the given source bean into the given target bean.

896

* @param source the source bean

897

* @param target the target bean

898

* @param ignoreProperties array of property names to ignore

899

* @throws BeansException if the copying failed

900

*/

901

public static void copyProperties(Object source, Object target, String... ignoreProperties) throws BeansException;

902

}

903

904

/**

905

* Utility methods for property access, particularly for bean property paths.

906

*/

907

class PropertyAccessorUtils {

908

/**

909

* Determine whether the given registered path matches the given property path.

910

* @param registeredPath the registered path

911

* @param propertyPath the property path to check

912

* @return whether the paths match

913

*/

914

public static boolean matchesProperty(String registeredPath, String propertyPath);

915

916

/**

917

* Determine the canonical name for the given property path.

918

* @param propertyPath the original property path

919

* @return the canonical property path

920

*/

921

public static String canonicalPropertyName(String propertyPath);

922

923

/**

924

* Determine all canonical names for the given property paths.

925

* @param propertyNames the original property names

926

* @return the canonical property names array

927

*/

928

public static String[] canonicalPropertyNames(String[] propertyNames);

929

930

/**

931

* Return the actual property name for the given property path.

932

* @param propertyPath the property path to check

933

* @return the actual property name, or null if none

934

*/

935

public static String getPropertyName(String propertyPath);

936

937

/**

938

* Check whether the given property path indicates an indexed or nested property.

939

* @param propertyPath property path to check

940

* @return whether the path indicates an indexed or nested property

941

*/

942

public static boolean isNestedOrIndexedProperty(String propertyPath);

943

944

/**

945

* Determine the first nested property separator in the given property path.

946

* @param propertyPath the property path to check

947

* @return the index of the nested property separator, or -1 if none

948

*/

949

public static int getFirstNestedPropertySeparatorIndex(String propertyPath);

950

951

/**

952

* Determine the first nested property separator in the given property path.

953

* @param propertyPath the property path to check

954

* @return the index of the nested property separator, or -1 if none

955

*/

956

public static int getLastNestedPropertySeparatorIndex(String propertyPath);

957

}

958

959

/**

960

* Utility class for working with property descriptors.

961

*/

962

class PropertyDescriptorUtils {

963

/**

964

* See PropertyDescriptor.hashCode().

965

* @param pd the PropertyDescriptor

966

* @return the hash code

967

*/

968

public static int hashCode(PropertyDescriptor pd);

969

970

/**

971

* See PropertyDescriptor.equals(Object).

972

* @param pd the PropertyDescriptor

973

* @param otherPd the other PropertyDescriptor

974

* @return whether they are equal

975

*/

976

public static boolean equals(PropertyDescriptor pd, PropertyDescriptor otherPd);

977

}

978

```

979

980

### Type Conversion Support

981

982

Additional classes and interfaces for advanced type conversion.

983

984

```java { .api }

985

/**

986

* Interface for type conversion between Object instances.

987

*/

988

interface TypeConverter {

989

/**

990

* Convert the value to the required type (may be an array or collection).

991

* @param value the value to convert (may be null)

992

* @param requiredType the type we must convert to (must not be null)

993

* @return the new value, possibly the result of type conversion

994

* @throws TypeMismatchException if type conversion failed

995

*/

996

<T> T convertIfNecessary(Object value, Class<T> requiredType) throws TypeMismatchException;

997

998

/**

999

* Convert the value to the required type.

1000

* @param value the value to convert (may be null)

1001

* @param requiredType the type we must convert to (must not be null)

1002

* @param methodParam the method parameter that is the target of the conversion

1003

* @return the new value, possibly the result of type conversion

1004

* @throws TypeMismatchException if type conversion failed

1005

*/

1006

<T> T convertIfNecessary(Object value, Class<T> requiredType, MethodParameter methodParam) throws TypeMismatchException;

1007

1008

/**

1009

* Convert the value to the required type.

1010

* @param value the value to convert (may be null)

1011

* @param requiredType the type we must convert to (must not be null)

1012

* @param field the reflective field that is the target of the conversion

1013

* @return the new value, possibly the result of type conversion

1014

* @throws TypeMismatchException if type conversion failed

1015

*/

1016

<T> T convertIfNecessary(Object value, Class<T> requiredType, Field field) throws TypeMismatchException;

1017

1018

/**

1019

* Convert the value to the required type.

1020

* @param value the value to convert (may be null)

1021

* @param requiredType the type we must convert to (must not be null)

1022

* @param typeDescriptor the type descriptor to use (may be null)

1023

* @return the new value, possibly the result of type conversion

1024

* @throws TypeMismatchException if type conversion failed

1025

*/

1026

default <T> T convertIfNecessary(Object value, Class<T> requiredType, TypeDescriptor typeDescriptor) throws TypeMismatchException {

1027

throw new UnsupportedOperationException("TypeDescriptor resolution not supported");

1028

}

1029

}

1030

1031

/**

1032

* Simple implementation of the TypeConverter interface that does not operate on a specific target object.

1033

*/

1034

class SimpleTypeConverter extends PropertyEditorRegistrySupport implements TypeConverter {

1035

/**

1036

* Create a new SimpleTypeConverter.

1037

*/

1038

public SimpleTypeConverter();

1039

1040

/**

1041

* Set a ConversionService to use as fallback.

1042

* @param conversionService the ConversionService to use as fallback

1043

*/

1044

public void setConversionService(ConversionService conversionService);

1045

1046

/**

1047

* Return the ConversionService used as fallback.

1048

* @return the ConversionService used as fallback, or null if none

1049

*/

1050

public ConversionService getConversionService();

1051

}

1052

```

1053