Site Navigation:

sbean

Patterns discovered by introspection

A sample {@link org.otvl.sbeansamp} coming with the distribution demonstrates what are the default patterns discovered by the SBean API. The sample class Sample1 comes with various properties corresponding to the default SBean patterns. An UML view of this sample is provided here:

The various patterns are detailed in the following sections.

Simple properties

Simple properties are attributes with getter/setter methods as defined by the Java Beans specification:

public class Sample1

{

private int att1;

private String att2;

private Sample2 theSample2;

public int getAtt1() {

int vAtt1 = att1;

return vAtt1;

}

public void setAtt1(int att1) {

this.att1 = att1;

}

public String getAtt2() {

String vAtt2 = att2;

return vAtt2;

}

public void setAtt2(String att2) {

this.att2 = att2;

}

public Sample2 getTheSample2() {

Sample2 vTheSample2 = theSample2;

return vTheSample2;

}

public void setTheSample2(Sample2 theSample2) {

this.theSample2 = theSample2;

}

}

The implementation of the accessors is left completely free. The introspection utility also allows raw access to properties ie the property "att1" may be coded "public int att1;" without accessors.

Indexed properties

Indexed properties are java.Collection.List attributes with getter/setter methods with the same signature as the List class and with the following naming convention:

public class Sample1

{

private java.util.ArrayList theSamples3 = new java.util.ArrayList() ;

public Sample3 getTheSamples3(int index) {

Sample3 vTheSamples3 = (Sample3)theSamples3.get(index);

return vTheSamples3;

}

public java.util.Iterator iteratorTheSamples3() {

java.util.Iterator vIterator = theSamples3.iterator();

return vIterator;

}

public int sizeTheSamples3() {

int vSize = theSamples3.size();

return vSize;

}

public void addTheSamples3(int index, Sample3 aSample3) {

this.theSamples3.add(index, aSample3);

}

public void addTheSamples3(Sample3 aSample3) {

this.theSamples3.add(this.theSamples3.size(), aSample3);

}

public void removeTheSamples3(int index) {

this.theSamples3.remove(index);

}

public void clearTheSamples3() {

this.theSamples3.clear();

}

}

Here again, the implementation of the accessors is left completely free. The introspection utility also allows raw access to Lists ie the property "theSample3" may be coded "public java.util.ArrayList theSample3;" without accessors. The only issue is that the type of the property cannot be determined in this case: all that is known is that the property is an Object.

The pattern used for JavaBeans' indexed properties can also be used, see below.

Mapped properties

Mapped properties are java.Collection.Map attributes with getter/setter methods with the same signature as the Map class and with the following naming convention:

public class Sample1

{

private java.util.HashMap s3byId = new java.util.HashMap() ;

public Sample3 getS3byId(Object key) {

Sample3 vS3byId = (Sample3)s3byId.get(key);

return vS3byId;

}

public java.util.Collection valuesS3byId() {

java.util.Collection vValues = s3byId.values();

return vValues;

}

public java.util.Set keySetS3byId() {

java.util.Set vKeySet = s3byId.keySet();

return vKeySet;

}

public int sizeS3byId() {

int vSize = s3byId.size();

return vSize;

}

public void putS3byId(Object key, Sample3 aSample3) {

this.s3byId.put(key, aSample3);

}

public void removeS3byId(Object key) {

this.s3byId.remove(key);

}

public void clearS3byId() {

this.s3byId.clear();

}

}

Here again, the implementation of the accessors is left completely free. The introspection utility also allows raw access to Maps ie the property "s3byId" may be coded "public java.util.HashMap s3byId;" without accessors. The only issue is that the type of the property cannot be determined in this case: all that is known is that the property is an Object.

JavaBeans' indexed properties

The following pattern for JavaBeans' indexed properties can also be used:

public class SbTest2

{

private SbTest3[] a3 = null ;

public SbTest3 getA3(int index) {

SbTest3 vA3 = a3[index];

return vA3;

}

public SbTest3 [] getA3() {

SbTest3 [] vA3 = null;

if(a3 != null) {

vA3 = new SbTest3[a3.length];

System.arraycopy(a3,0,vA3,0,a3.length);

}

return vA3;

}

public void setA3(int index, SbTest3 aSbTest3) {

this.a3[index] = aSbTest3;

}

public void setA3(SbTest3 [] allSbTest3) {

if(allSbTest3 != null) {

a3 = new SbTest3[allSbTest3.length];

System.arraycopy(allSbTest3,0,a3,0,allSbTest3.length);

} else {

a3 = null;

}

}

}

As you can see with this implementation, the indexed setter is not perfectly implemented: if the target array has not enough cells for the requested index, the setter will throw a run-time exception. If you have to deal with such an implementation (which could be generated by some tool, for instance, or worse, not being open source), you can ask to the sbean library to resize the array for you automatically when setting values. For that, you have to configure the factory {@link org.otvl.sbean.PropertyAccessMethodBuilder} using its configure method with the OPTION_RESIZE_ARRAY set to "true".

SBeanClass.getPropertyAccessMethodBuilder().configure(

PropertyAccessMethodBuilder.OPTION_RESIZE_ARRAY, "true"

);

Note that you must configure the factory before loading any class, or else you will have to empty the properties cache for the corresponding class to force the proper configuration of newly loaded properties. See the class {@link org.otvl.sbean.SBeanClass} for more information.

Other patterns

You can define other patterns to discover these kind of properties by redefining a {@link org.otvl.sbean.PropertyAccessMethodBuilder} class and registering it with the SBeanClass's{@link org.otvl.sbean.SBeanClass#setPropertyAccessMethodBuilder}method.