Hi!
I need to read my tiles definitions from something that is not a URL, so
I'm in the process of writing a custom DAO (it's either that or a custom
URLStreamHandler...) I've been analyzing the implementation in tiles 3
as an exemple, and now I think it could be improved for reusability and
performance.
Currently in tiles 3, the responsibilities for loading tiles definitions
from files are divided as follow:
a. discovering the applicable Locale: LocaleResolver
b. transforming URLs according to the locale: DefinitionsDAO
c. provide default URLs for missing files, according to the Locale
hierachy ("en_US" => "en" => ""): DefinitionsDAO
d. loading the raw data from URLs: DefinitionsDAO
e. parsing the raw data into Definition objects: DefinitionsReader
f. eventual caching the Definition objects: DefinitionsDAO
g. resolving wildcards in Definition: PatternDefinitionResolver
h. resolving definition inheritance: DefinitionsDAO or
DefinitionsFactory or TilesContainer, depending on the implementation.
i. eventual caching of the Definition objects after resolving
inheritance: DefinitionsDAO.
j. coordination with PatternDefinitionResolver and DefinitionsReader:
DefinitionsDAO.
k. coordination between LocaleResolver and DefinitionsDAO:
DefinitionsFactory.
There are also the URLReader and RefreshMonitor interfaces: I'm not sure
what they are used for, even if I like RefreshMonitor.
In order to understand it better, I've looked at the example
configurations, too:
- BasicTilesContainerFactory resolves inheritance in DefinitionsDAO.
- CompleteAutoloadTilesContainerFactory resolves inheritance in both
DefinitionsDAO and TilesContainer.
- The database example in tiles-test-db resolves it in
DefinitionsFactory, but never caches anything (oversight?)
All of this seems a bit complex to me. I think there is some code
duplication in there (resolving inheritance, multiple or missing
caches...). And there is this thread
(http://struts.1045723.n5.nabble.com/Tiles-Cache-Memory-Usage-td3553392.html),
which suggests the cache is not as efficient at it could be.
I think the DAO could benefit from a redesign, to further separate
concerns. Did I miss something in my analysis? some extra constraint, or
some known issue that may have been raised already?
So this is what I'm considering:
- add an InheritanceResolver implementation, to factor out the
inheritance algorithm (possibly with a DefinitionsPostProcessor
interface that could be used by the PatternDefinitionResolver, too).
- add a Cache interface, with implementation for in-memory caching.
- move these resposiblities, as well as the responsibility for managing
the Locale hierarchy, out of the DAO (steps c, f, g, h, i)
- have the DefinitionsFactory orchestrate the whole thing, because only
it can manage it efficiently (except for DefinitionsReader which is
XML-specific).
So far it's only an idea, and I'm not sure how much work it involves
(especially when it comes to testing). But I'd value your input, as much
your critical opinion as any any help you would like to provide.
Thanks,
Nick