shows how avc-binding-dom relies on conventions for method names.
Naming Conventions
The avc-binding-dom API relies on conventions in method names to implement their behaviour.
The following method names are recognized:
getXxx()
=> (any type) retrieve a value or an array of valuesisXxx()
,hasXxx()
=> (boolean) same asgetXxx()
isNullXxx()
=> (boolean) tell if a given DOM node is present or notsizeOfXxx()
=> (int) retrieve count of selected nodes
The important prefixes are get
, is
(but not isNull
) and has
. If you want methods with behaviours similar to isNullXxx()
or sizeOfXxx()
, you can use the following annotations:
@XPath(value = "count(xxx) = 0", failFunction = "true()") boolean getMyIsNullXxx(); @XPath(value = "count(xxx)", failFunction = "0") int getMySizeOfXxx();
For a isNullXxx()
method, the contract is to return true
if there is no node selected by the XPath expression, false
otherwise.
For a sizeOfXxx()
method, the contract is to return the number of nodes selected by the XPath expression.
Consider for instance the following annotated interface:
@XPath("/books") public interface Books { @XPath("book") Book[] getBooks(); interface Book { @XPath("@title") String getTitle(); @XPath("@lang") String getLang(); @XPath("author") String getAuthor(); boolean isNullAuthor(); int sizeOfAuthor(); @XPath(value = "author", function = "string-length()") int getAuthorLength(); @XPath(value = "author", function = "string-length()", failFunction = "0") int getAuthorLengthSafe(); @XPath(value = "author", function = "normalize-space()") String getAuthorNormalized(); } }
Say we bind it to the following XML document:
<books> <book title="Treasure Island" lang="en"> <author> Robert Louis Stevenson</author> </book> <book title="L'Île au trésor" lang="fr"> </book> </books>
We would then get the following assertions:
assertEquals("Treasure Island", books.getBooks()[0].getTitle()); assertEquals(" Robert Louis Stevenson", books.getBooks()[0].getAuthor()); assertFalse(books.getBooks()[0].isNullAuthor()); assertEquals(1, books.getBooks()[0].sizeOfAuthor()); assertEquals(26, books.getBooks()[0].getAuthorLength()); assertEquals(26, books.getBooks()[0].getAuthorLengthSafe()); assertEquals("Robert Louis Stevenson", books.getBooks()[0].getAuthorNormalized()); assertEquals("L'Île au trésor", books.getBooks()[1].getTitle()); assertEquals("", books.getBooks()[1].getAuthor()); assertTrue(books.getBooks()[1].isNullAuthor()); assertEquals(0, books.getBooks()[1].sizeOfAuthor()); // assertEquals(..., books.getBooks()[0].getAuthorLength()); // would crash! assertEquals(0, books.getBooks()[1].getAuthorLengthSafe()); assertEquals("", books.getBooks()[1].getAuthorNormalized());
(This sample code is in the project's test sources: NamingConventionExamplesTest.)
Same Fields = Same Annotations
For a given "field", @XPath, @Namespaces and @Nodes, annotations can be declared for any one of its accessor methods.
That means the following copying-and-pasting is not necessary:
@XPath("aaa/bbb/ccc") String[] getTelephoneNumbers(); @XPath("aaa/bbb/ccc") int sizeOfTelephoneNumbers(); @XPath("aaa/bbb/ccc") boolean isNullTelephoneNumbers(); @XPath("ddd/eee") String getAddress(); @XPath("ddd/eee") boolean isNullAddress(); @XPath("fff/ggg") boolean isSomeoneFamous(); @XPath("fff/ggg") boolean isNullSomeoneFamous();
Only one declaration is enough for each "field":
@XPath("aaa/bbb/ccc") String[] getTelephoneNumbers(); int sizeOfTelephoneNumbers(); boolean isNullTelephoneNumbers(); @XPath("ddd/eee") String getAddress(); boolean isNullAddress(); @XPath("fff/ggg") boolean isSomeoneFamous(); boolean isNullSomeoneFamous();
Return Types
Read details about Return Types if some examples above do not seem clear to you.