0% found this document useful (0 votes)
12 views56 pages

Metadata Framework Pattern Language

Uploaded by

thiago
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
12 views56 pages

Metadata Framework Pattern Language

Uploaded by

thiago
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Pattern Language for the Internal Structure

of Metadata-Based Frameworks

Eduardo Guerra1, Jerffeson de Souza2, and Clovis Fernandes1


1
Aeronautical Institute of Technology – ITA
Praça Marechal Eduardo Gomes, 50 - Vl Acácias - SJ Campos – SP, Brazil
guerraem@[Link], clovistf@[Link]
2
State University of Ceará – UECE
Av. Paranjana, 1700 , Campus do Itaperi - Fortaleza – CE, Brazil
jeff@[Link]

Abstract. Metadata-based frameworks are those that process their logic based
on the metadata of classes whose instances they are working with. Many recent
frameworks use this approach to get a higher reuse level and to be more suita-
bly adapted to the application needs. However, there is not yet a complete best
practices documentation or reference architecture for the development of meta-
data-based frameworks. This paper presents a pattern language that focuses on
recurring solutions used in the internal structure of metadata-based frameworks
addressing the main problems faced in this kind of development. Based on the
pattern language, a reference architecture which identifies a base structure and
the main hotspots for metadata-based frameworks is defined.

Keywords: Metadata, Design Patterns, Pattern Language, Annotation,


Attribute-oriented Programming, Framework, Reference Architecture.

1 Introduction

Many mature frameworks and APIs used in the industry nowadays are based on
metadata such as Hibernate [2], EJB 3 [34] and JUnit [40]. However, most of them
have flexibility problems that can make it difficult or prevent their use in some
applications. For instance, the metadata reading mechanism of some frameworks
cannot be extended, which makes it difficult to retrieve metadata from other sources
or formats. This lack of flexibility in the metadata reading may demand changes, such
as annotation refactorings [54]. Examples of other design concerns are the following:
(a) how to make metadata extensible?; (b) how can the framework logic be adapted
according to class metadata?; (c) and how can specific framework metadata be shared
among other frameworks or components?
This paper presents a pattern language for metadata-based frameworks. The aim of
this research is to identify best practices both in the understanding and in the devel-
opment of this kind of framework. The recurring solutions for common problems are
documented in a pattern language. The next subsections of the introduction explore

J. Noble et al. (Eds.): TPLOP III, LNCS 7840, pp. 55–110, 2013.
© Springer-Verlag Berlin Heidelberg 2013
56 E. Guerra, J. de Souza, and C. Fernandes

important concepts about frameworks and metadata. Then, the goal, relevance, and
intended audience of this work are presented and explained.

1.1 Frameworks
A framework is a set of classes that supports reuse at larger granularity. It defines an
object-oriented abstract design for a particular kind of application which enables not
only source code reuse, but also design reuse [32]. The framework abstract structure
can be filled with classes from its own library or application-specific ones, providing
flexibility for the developer to adapt its behavior to each application. Besides
flexibility, a good framework also increases the team productivity and makes
application maintenance easier [59, 10].
A framework must contain points, called hotspots, where applications can
customize their behavior [46]. Points that cannot be changed are called frozen spots.
These two points usually define the framework general architecture, which consists of
its basic components and the relationships among them.
In the first frameworks, the application classes had to be compatible with the
framework protocol, usually by extending an abstract class or implementing an
interface. The framework structures have evolved and recent ones use introspection
[7, 13] to access at runtime the application classes metadata, such as their
superclasses, methods, and attributes. As a result, it allows application classes to be
decoupled from the framework abstract classes and interfaces. The framework can,
for instance, search the class structure for the right method to invoke. The use of this
technique provides more flexibility for the application, since the framework reads the
classes dynamically, allowing their structure to evolve more easily [12].
For some frameworks, however, the information found in the class definition is not
enough, since they need a domain-specific or application-specific metadata to
customize their behavior [51]. Thus, they use additional class metadata defined by
the application developer to customize framework behavior. In this paper this kind
of framework is called a Metadata-based Framework, which can be defined as one
that processes their logic based on the metadata from the classes whose instances they
are working with [20, 22].

1.2 Metadata

“Metadata” is an overloaded term in computer science and can be interpreted


differently according to the context. In the context of object-oriented programming,
metadata is information about the program structure itself such as classes, methods,
and attributes. A class, for example, has intrinsic metadata like its name, its superclass,
its interfaces, its methods, and its attributes. In metadata-based frameworks, the
developer also must define some additional application-specific or domain-specific
metadata.
Even in this context, metadata can be used for many purposes. There are several
examples of this, such as source code generation [6], compile-time verification [8, 48],
and class transformation [47]. The metadata-based frameworks consume metadata at
Pattern Language for the Internal Structure of Metadata-Based Frameworks 57

runtime and use it for framework adaptation. This distinction is important because the
same goal could be achieved using different strategies [16].
The metadata consumed by the framework can be defined in different ways.
Naming Conventions [4] use patterns in the name of classes and methods that have a
special meaning for the framework. For instance, Java Beans specification [28]
defines the use of access method names beginning with 'get' and 'set', and JUnit 3 [40]
interprets method names beginning with 'test' as test cases implementation. Ruby on
Rails [49] is an example of a framework known by using naming conventions. The
conventions can also consider other information besides naming, such as an attribute
type or the method parameters. The practice known as marker interface uses an empty
interface to add a piece of metadata in a class.
Conventions usage can save a lot of configuration work, but it can only represent a
limited amount of information. For some scenarios the metadata needed are more
complex and code conventions are not enough. An alternative can be setting the
information programmatically in the framework, but it is not used in practice in the
majority of the frameworks. Another option is metadata definition in external sources,
like XML files and databases. The possibility to modify the metadata at deploy-time
or even at runtime without recompiling the code is an advantage of this type of
definition. However, the definition is more verbose because it has to reference and
identify program elements. Furthermore, the distance that configuration keeps from
the source code is not intuitive for some developers.
Another alternative that has become popular in the software community is the use
of code annotations, which is supported by some programming languages like Java
[33] and C# [41; 43]. When using this technique, the developer can add custom
metadata elements directly into the class source code, keeping its definition less
verbose and closer to the source code. The use of code annotations is also called
attribute-oriented programing [51] and can be defined as a program-level marking
technique that allows developers to mark programming elements, such as classes and
methods, to indicate application-specific or domain-specific semantics [55]. This
technique introduces a declarative approach inside an imperative programming
language.
For languages that do not support a native custom metadata configuration, an
alternative can be the usage of hot comments [26], which is a software comment with
an interpretable well-formed expression. The JavaDoc comments are an example of
the usage of hot comments. XDoclet [56], a very popular tool before Java annotations,
used JavaDoc comments to add custom metadata in programming elements. This
information was often used to generate XML metadata descriptors to be consumed by
frameworks.

1.3 Goals and Intended Audience

The intended audience for this work are framework developers and software
architects who need to create frameworks whose behavior is based on class metadata.
The pattern language explores each solution individually, presenting its forces and
corresponding consequences in its usage. It also clearly identifies the main framework
58 E. Guerra, J. de Souza, and C. Fernandes

hotspots and frozen spots for this kind of framework. This paper is intended to be
used as a guide for the design of metadata-based frameworks internal structure.
Previously to this study, there was not a work that identified best practices in the
development of this kind of framework. Despite there being patterns with a similar
structure, their usage in the context of metadata-based frameworks has never been
registered before. Some of the patterns may be used in other contexts than
frameworks, however it is not on the scope of this paper to document this kind of
applicability.
The usage and development of this kind of framework is increasing and this fact
can be verified by the use of a metadata-based approach in Java EE 6 specifications
[29, 38, 36]. In this context, this work has the important role to disseminate the best
practices for this kind of software, making it easier for framework developers to
address the most common problems that can arise in their design.

2 Pattern Language Description

This section presents the proposed Pattern Language for Metadata-based


Frameworks whose goal is to identify both the major problems occurring in
implementing metadata-based frameworks and the recurring solutions for them found
in existing ones. To reach this aim, an extensive study was carried out including a
deep analysis of the internal structure of many existing open source metadata-based
frameworks. Other frameworks were developed by the authors' research group to
experiment existing and alternative solutions in different contexts. Solutions and best
practices for recursive problems in this context were initially identified and
documented in patterns [22]. As this research matured, the relationship among the
patterns were consolidated and structured in this pattern language.
The pattern language is composed of new patterns and specializations of existing
ones. The pattern specializations present how existing practices are applied to a
problem in this specific context. Despite the pattern structure and dynamics being
similar to other patterns, the pattern context, forces, and consequences are different
and specific to metadata-based frameworks. Since some patterns propose general
solutions, it is not always obvious for a developer where they should be applied in this
kind of framework. The documentation of these pattern specializations is also
important in the context of the whole pattern language, since it registers their
relationships with other solutions.
It is out of the scope of this pattern language to describe how metadata-based
frameworks can be attached to an application architecture. The simplest case is when
the framework entry point class is instantiated and used by the application, but it can
also be transparent for clients in an application class Proxy [17], embedded in a
container like in the EJB specification [34, 36] or even weaved with an aspect [23].
How the framework is instantiated does not provoke any change to its internal
structure. For simplicity, the pattern language will consider, without loss of generality,
that the client directly invokes the framework's methods.
Since the pattern context is frameworks, the pattern sections Structure, Participants
and Dynamics are focused on object-oriented implementations. The diagrams
Pattern Language for the Internal Structure of Metadata-Based Frameworks 59

presented in these sections are for illustration and should not be interpreted as the
only possible implementation of the related pattern. Some pattern solutions could
possibly be implemented in a different programming paradigm; however this is not
addressed in this work.
The patterns are not intended to be language-specific and the documented solutions
do not depend at all on any specific language feature. Although additional metadata
can be defined in XML documents or in databases, most of the known uses were
found in languages with features allowing the addition of custom metadata directly on
the program code elements, such as Java annotations and C# attributes.

2.1 Patterns Overview


This section's goal is to give an initial idea of the pattern language and how each
pattern fits in its context. The following gives a small description of each pattern:

• Metadata Container - This pattern decouples the metadata reading from the
framework's logic by creating a container to represent metadata at runtime. A
metadata reader populates the instance of this class, which is then used by the
framework.
• Metadata Repository - This pattern creates a repository to store metadata at
runtime, avoiding unnecessary metadata readings. The repository manages
the metadata reading and is accessed by the framework to retrieve the
metadata container.
• Metadata Reader Strategy - This pattern creates an abstraction of the
metadata reading algorithm allowing it to have different implementations. It
allows the framework to read metadata from different kinds of sources.
• Metadata Reader Chain - This pattern enables the metadata from more than
one source to be combined during the reading. It uses a metadata reader that
invokes a chain of other ones to compose the metadata reading algorithm.
• Metadata Reader Adapter - This pattern uses the metadata repository of
another framework to get the existing metadata and set information in the
metadata container. It allows metadata sharing among frameworks.
• Metadata Reader Delegate - In this pattern, the metadata reader delegates the
responsibility to interpret pieces of metadata defined in annotations or XML
elements to other classes. It allows the metadata understood by the
framework to be extended by the application.
• Metadata Processor - In this pattern, the metadata container is composed of
classes that maintain logic to process pieces of metadata. By implementing
these class abstractions, it is possible to extend the framework behavior.
• Metadata Processing Layers - In this pattern, the logic processing is
composed of many different layers, each one with different responsibilities. It
allows each layer to evolve independently and also the framework
functionality to be extended by adding new layers.
60 E. Guerra, J. de Souza, and C. Fernandes

2.2 Pattern Language Navigation


There are a lot of paths that can be followed in the patterns implementation on a metada-
ta-based framework. The running example presented with the patterns shows a possible
path, but it is not the only one. Fig. 1 presents a roadmap that can help in the pattern
language adoption. It starts with the implementation of Metadata Container and after that
there are many possible paths that can be followed based on the framework needs.

to decuple
metadata reading
from processing...
to enable
extensions to read to represent
Metadata new metadata metadata at
pieces... runtime...
Reader Delegate

to extend
metadata schema
associated to new to read metadata
framework logic... from more than
to extend logic
Metadata one source...
associated to a Container
Metadata metadata piece...
Processor
to avoid Metadata
unnecessary Reader Strategy
to add new
metadata
metadata
readings... to combine
processing
responsibilities... metadata from more
than one source...
to retrieve
Metadata metadata read by
Repository other framework...
Metadata
Processing Metadata
Layers Reader Chain

to enable
external
Metadata
metadata Reader Adapter
to access access...
metadata in
each layer...

Fig. 1. Pattern Language Navigation

The pattern format used in the pattern language uses sections to organize its
information. This kind of organization enables the reader to choose a subset of the
sections which portrays a particular vision of the pattern language. The following
paragraphs describe some possible paths in the pattern sections which can be followed
to read this work.
For readers who prefer to have a more abstract view of solutions without
concerning about implementation details, a possible path is to skip the Running
Example section. The set of Running Example sections correspond to a pattern story
which can be read separately from the patterns themselves. Another possibility for
people who prefer to start thinking in more concrete problems is to read the entire
running example first and then read more abstract information about the solutions in
the patterns.
Pattern Language for the Internal Structure of Metadata-Based Frameworks 61

The solutions described by the patterns in the Structure, Participants, and


Dynamics sections are focused on the object-oriented programming paradigm.
Readers more interested in the abstract solution given by the pattern, perhaps for
implementing it in a different program paradigm, can skip these sections and focus
more on the Motivation, Problem, Forces, Solution, and Consequences sections.

2.3 Patterns Classification and Dependence


Fig. 2 illustrates the patterns classification and dependence. The dashed arrows
represent that one pattern uses another pattern [44], meaning that for the
implementation of a pattern, it is mandatory the implementation of the other. For
instance, Metadata Reader Strategy uses Metadata Container. Other possible
relationships between patterns are described in the Related Patterns section of
each one.

Structural Patterns Logic Processing Patterns

Metadata Container Metadata Processor

Metadata Repository Metadata Processing Layers

Metadata Reader Adapter Delegate Metadata Reader

Metadata Reader Strategy Metadata Reader Chain

Metadata Reading Patterns

Fig. 2. Patterns Classification and Dependence

The patterns are classified in the following three mutually exclusive categories:

• Structural Patterns - These patterns document best practices about how to


internally structure the classes of a metadata-based framework. They can be
considered as the base of the pattern language, since many other patterns
depend on their implementation. The structural patterns identify the main
62 E. Guerra, J. de Souza, and C. Fernandes

frozen spots that define the internal framework architecture. They are
described in Section 3.
• Metadata Reading Patterns - These patterns document recurring solutions
about the reading of metadata by the framework. They provide solutions to
improve the flexibility in the reading process, allowing metadata sharing and
metadata extension. The metadata reading patterns identify the main kinds of
hotspots that can exist associated to the metadata reading process. They are
described in Section 4.
• Logic Processing Patterns - These patterns document solutions in the design
of the classes that process the main logic of the framework. They allow logic
processing based on the class metadata to be extended and modified. The
logic processing patterns identify the main kinds of hotspots that can exist
associated to the framework metadata processing. They are described in
Section 5.

2.4 Frameworks Used as Examples

This section briefly presents the group of frameworks used in the research to identify
best practices in dealing with metadata. They are also used as examples in the pattern
language. The frameworks will be referenced by the name in bold and the references
are not repeated in the pattern’s Known Uses section. Other references that are not
properly frameworks are also used as known uses in some of the identified patterns.

• ACE Framework [5] uses metadata to map functionalities of a web


application to mobile applications in Java. This framework supports this
mapping for new applications, using annotations, and for legacy applications,
using XML files.
• Esfinge Framework [9] is a framework for the business layer of a corporate
Java EE application. It provides a layered structure that allows layers to be
easily created and inserted.
• Hibernate [2] is a framework that uses metadata for object-relational
mapping for implementing a persistence layer. The metadata can be defined
by means of XML files or annotations.
• Hibernate Validator [24] is framework that checks in-memory instances of
a class for constraint violations. The version used in the analysis is the
release 4.0 alpha that implements the specification Bean Validation [37].
• JAXB API [35] is a Java standard for XML binding, which uses annotations
on application classes to map them to the target XML Schema. The reference
implementation is used in the analysis.
• JBoss Application Server 5 [30] is an implementation of an application
server that supports the EJB 3 specification [34].
• JColtrane [31] is a framework to parse XML files based on SAX [50] events.
It uses annotations to define conditions for each method to be executed.
• MentalLink [21] is a framework that uses annotations for mapping between
instances of an ontology and objects.
Pattern Language for the Internal Structure of Metadata-Based Frameworks 63

• MetadataSharing [52] is an implementation of metadata sharing among


frameworks. A repository reads the metadata from many sources and then
provides an API for the frameworks to retrieve the information that they need.
• NUnit [27] is a testing framework for .NET applications. It uses metadata
defined in attributes to configure what each method means in the test
execution, such as initialization, finalization, and test cases.
• NHibernate [39] is a framework for .NET applications for object-relational
mapping using metadata. It is a similar to Hibernate, but for the .NET
platform. Its NHibernate Validator component was also considered in the
analysis.
• Ohgma [11] is a framework to implement Adaptive Object Models [61, 62,
57] in the .NET platform. It provides not only the core features to create a
dynamic model, but also to persist and represent in user interface instances of
this model.
• SwingBean framework [53] provides graphical components for creating
forms and tables for a Swing desktop application in Java. These components
use the metadata of an application domain class defined in an XML
document to configure how the information should be retrieved or presented.
• XapMap [60], which stands for Cross Application Mapping, is a framework
that maps entities of the same domain but implemented in different class
structures. It provides a component that creates an instance of one structure
based on an instance of another one. It also provides a proxy that
encapsulates the access of an instance of one structure based on another
one's API.

2.5 Running Example

The pattern language is illustrated in this work by means of a running example featur-
ing the Comparison Component, a framework that compares instances of the same
class and returns a list of differences among them. It will compare all the application
class properties searching for differences. The metadata will be used to configure
characteristics in the comparison algorithm for each class, such as properties to ig-
nore, numeric tolerance, and objects to go deep into the comparison.
To understand completely this running example, it is advised for the reader to
be familiar with Java language, specially to its metadata facility feature, usually
referred to as code annotations. It is also important to understand the Java
Reflection API, which is both used to dynamically invoke methods and to retrieve
class metadata.
The comparison component provides three annotations to configure how the
classes should be compared: @Ignore annotates properties that should not be
included in the comparison; @Tolerance annotates numeric properties that should
consider a specific numeric tolerance; @DeepComparison annotates compound
properties that should be compared by using its own comparison component.
64 E. Guerra, J. de Souza, and C. Fernandes

The framework entry point, represented by the class ComparisonComponent,


has only one public method called compare(). This method receives two instances
of the same class, considering that they are different versions of the same business
entity. This method also returns an instance list of Difference, which is a class
that has three properties representing the property name, the property value in the new
instance, and the property value in the old instance. Listing 1 presents the initial
implementation of Comparison Component without using any one of the proposed
patterns. In each pattern, this implementation will be refactored to increase its
flexibility and, in some cases, enabling the creation of new functionalities.

Listing 1. The initial source code for ComparisonComponent.


public class ComparisonComponent {
public List<Difference> compare(Object oldObj, Object newObj)
throws CompareException {
List<Difference> difs = new ArrayList<Difference>();
if (![Link]().isAssignableFrom([Link]())) {
throw new CompareException("Not compatible types");
}
Class clazz = [Link]();
for (Method method : [Link]()) {
try {
boolean isGetter = [Link]().startsWith("get");
boolean noParameters = ([Link]().length == 0);
boolean notGetClass = ![Link]().equals("getClass");
boolean noIgnore = ![Link]([Link]);
if (isGetter && noParameters && notGetClass && noIgnore) {
Object oldValue = [Link](oldObj);
Object newValue = [Link](newObj);
String propName = [Link]().
substring(3, 4).toLowerCase() +
[Link]().substring(4);
if ([Link]([Link])) {
Tolerance tol = [Link]([Link]);
compareWithTolerance(difs, [Link](),
newValue, oldValue, propName);
} else if ([Link]([Link])
&& newValue != null && oldValue != null) {
List<Difference> difsProp = compare(newValue, oldValue);
for (Difference d : difsProp) {
[Link](propName + "." + [Link]());
[Link](d);
}
} else {
compareRegular(difs, propName, newValue, oldValue);
}
}
} catch (Exception e) {
throw new CompareException("Error retrieving property", e);
}
}
return difs;
}
private void compareWithTolerance(List<Difference> difs, double tolerance,
Object newValue, Object oldValue, String prop) {
double dif = [Link](((Double) newValue) - ((Double) oldValue));
if (dif > tolerance) {
[Link](new Difference(prop, newValue, oldValue));
}
}
private void compareRegular(List<Difference> difs, String prop,
Object newValue, Object oldValue) {
if (newValue == null) {
Pattern Language for the Internal Structure of Metadata-Based Frameworks 65

if (oldValue != null) {
[Link](new Difference(prop, newValue, oldValue));
}
} else if (![Link](oldValue)) {
[Link](new Difference(prop, newValue, oldValue));
}
}
}

The implementation of the compare() method in Listing 1 first verifies if both


instances are from the same class. After that, it retrieves all getter methods from the
class and compares the values retrieved from both instances based on the metadata.
The private methods compareRegular() and compareWithTolerance()
are used by the compare() method respectively for the regular comparison and for
the comparison using tolerance.

3 Structural Patterns

3.1 Metadata Container

Also Known as
Metadata Descriptor, Metadata Recipient

Context
Every metadata-based framework has to perform two distinct tasks: reading class
metadata and executing its logic based on that information. The term framework main
logic is used to indicate the functionality provided by the framework for the
applications. If these two responsibilities are implemented mixed in the source code,
the main logic execution will be coupled to that particular form of metadata definition
and to the metadata reading process.
The drawback of this design choice is that it may impede the addition of new
behavior both in metadata reading and in framework main logic. For instance, a
change in how metadata are defined would impact entirely the framework process.
Consequently, it can also impact the framework flexibility and maintainability.
Observing the ComparisonComponent implementation presented in Listing 1,
the annotations are read at the same time that they are processed. For instance, the
addition of a new annotation would demand a change that involves all the logic and
not only the metadata reading. As another example, to read the same metadata from
an XML file, it would be very difficult to reuse part of this source code.

Problem
How to decouple the metadata reading from the framework main logic?

Forces
• For a small metadata set, the source code complexity to read and process
metadata in the same method is still manageable.
66 E. Guerra, J. de Souza, and C. Fernandes

• The reading of metadata in all framework instantiations can make the


framework stateless but it can become a performance bottleneck as well.
• The existence of an internal representation of the metadata can consume
more runtime memory, which is a problem especially in embedded
applications.
• The creation of an internal representation for metadata adds indirection in
the source code which uses it.
• A representation of the metadata at runtime can be used to share this
information among frameworks.
• Metadata reading mixed with framework main logic creates a dependence
between the framework logic and how the metadata is defined.
• The creation of an internal representation for metadata adds indirection and
can add unnecessary complexity for simple cases.

Solution
Metadata Container proposes creating a representation of metadata at runtime. This
representation is used to exchange information between metadata reading process
and framework main logic, as the main interface among them.
The metadata reading process should receive the target class and return a Metadata
Container populated with all the information necessary for the framework execution.
With the instance of the Metadata Container, the framework main logic can retrieve
the desired metadata without relying on how it is defined.

Structure
In Metadata Container, the application class metadata is stored in an instance that
represents it at runtime. Figure 3 illustrates the pattern structure. The
MetadataContainer is the class that represents the metadata structure. It is also
the main interface between the class responsible for reading metadata and the class
that contains the framework main logic, respectively MetadataReader and
FrameworkController.
The ApplicationClass represents the class for which the framework metadata
is configured. This class is used by the MetadataReader in the metadata
extraction and its instances are used by the FrameworkController in the
execution of the main logic. The ApplicationClient represents the class which
invokes the framework functionality in the application.
The FrameworkController can store the MetadataContainer instance
internally as represented in the diagram. This is usually done when the class with the
metadata is received by the FrameworkController in the constructor.
Alternatively, the FrameworkController can be stateless and accepts
invocations receiving the class with metadata as a parameter, consequently invoking
the MetadataReader for each one.
Pattern Language for the Internal Structure of Metadata-Based Frameworks 67

MetadataContainer ApplicationClass

create

Class described with metadata

MetadataReader FrameworkController ApplicationClient

+getMetadataContainer() use +execute()

Fig. 3. Metadata Container structure

Participants
• MetadataReader - It is responsible for reading metadata wherever it is
defined. It is used by FrameworkController to create an instance of
MetadataContainer representing the ApplicationClass metadata.
• MetadataContainer - It is responsible for representing the
ApplicationClass metadata at runtime. It is the main interface among
MetadataReader and FrameworkController.
• FrameworkController - It is the framework class where the
functionality is invoked by the application, also known as the framework
entry point. It is responsible for executing the main logic and for being a
controller for the other classes. It uses the data from
MetadataContainer retrieved by means of MetadataReader to
execute its logic.
• ApplicationClient - It represents the application class that invokes
implicitly or explicitly the FrameworkController to execute the
framework functionality.
• ApplicationClass - It represents the application class that has
additional domain-specific or application-specific metadata, which is used by
FrameworkController in its main logic.

Dynamics
When the application client accesses the entry point of the metadata-based framework,
it invokes the MetadataReader that reads the metadata and returns an instance of
the MetadataContainer populated with the class metadata. During the execution
of the main logic, the FrameworkController accesses the required metadata
using the MetadataContainer instance. The corresponding sequence diagram is
shown in Figure 4.
As an alternative implementation of this pattern, the ApplicationClient can
create the MetadataContainer instance explicitly. When using this approach, the
client uses the MetadataReader to create the MetadataContainer and passes
it to the FrameworkController in its constructor or as a method parameter.
68 E. Guerra, J. de Souza, and C. Fernandes

Consequences
• (+) The metadata reading process is decoupled from the framework main logic.
• (+) The metadata can be retrieved by other frameworks using the Metadata
Container instance.
• (+) The framework became more testable, by enabling the metadata reading
and the logic processing to be tested separately.
• (+) A framework instantiation can reuse the same Metadata Container
instance in distinct invocations, avoiding unnecessary metadata reading and
improving the application performance.
• (-) If the framework uses a simple and small metadata schema, the use of this
pattern can complicate unnecessarily its structure.
• (-) Both metadata reading and framework logic became coupled with the
Metadata Container structure.

:ApplicationClient :FrameworkController :MetadataReader

execute()

getMetadataContainer()

create
container:MetadataContainer

populate with metadata

container

main logic

retrieves metadata

Fig. 4. Metadata Container sequence diagram

Known Uses
Hibernate uses, as a Metadata Container, an implementation of the interface
ClassMetadata that can be retrieved from a SessionFactory instance. The
SessionFactory is the class responsible for creating instances of Session,
which is used by the application to interact with the framework. ClassMetadata
contains all the information about a persistent class used by the framework.
Differently, in SwingBean, the class XMLDescriptorFactory provides
a Facade [17] for the client to retrieve metadata, represented by the
Pattern Language for the Internal Structure of Metadata-Based Frameworks 69

FieldDescriptor interface. The client uses this instance to create graphical


components, passing it as an argument to their constructor.
NUnit testing framework contains a class called TestSuite that contains all the
information necessary for the execution of a test class, such as what methods should
be executed before and after each test method. This class can be considered a
Metadata Container which is created and consumed in each execution.

Running Example
To increase its flexibility, the Comparison Component, defined earlier in the Running
Example, is refactored to decouple the metadata reading from the comparison logic.
This step is necessary to allow both the implementation of metadata reading from
other sources and the extension of the components logic.
In this example, the metadata container is represented by a class named
ComparisonDescriptor, which is composed of a map of instances of
PropertyDescriptor. The class PropertyDescriptor provides
information about just one class property: property name, numeric tolerance, and
whether it should be compared “deeply”. In addition, the class
ComparisonDescriptor has a map with the properties that should be included in
the comparison. Each map entry contains the property name linked with the respective
PropertyDescriptor instance.
The ComparisonMetadataReader class is represented in Listing 2. The
createContainer() method receives a class as a parameter and returns the
respective instance of ComparisonDescriptor created by using the annotations
in the properties getter methods. When a property presents the annotation @Ignore,
it is not included in the ComparisonDescriptor instance. The information
provided by other annotations are obtained and stored in the descriptor.

Listing 2. Source code of ComparisonMetadataReader.


public class ComparisonMetadataReader {
public ComparisonDescriptor createContainer(Class c) {
ComparisonDescriptor descr = new ComparisonDescriptor();
for (Method method : [Link]()) {
boolean isGetter = [Link]().startsWith("get");
boolean noParameters = ([Link]().length == 0);
boolean notGetClass = ![Link]().equals("getClass");
boolean noIgnore = ![Link]([Link]);
if (isGetter && noParameters && notGetClass && noIgnore) {
PropertyDescriptor prop = new PropertyDescriptor();
String getter = [Link]();
String propName = [Link](3, 4).toLowerCase() +
[Link](4);
[Link](propName);
[Link]([Link](
[Link]));
if ([Link]([Link])) {
Tolerance t = [Link]([Link]);
[Link]([Link]());
}
[Link](prop);
}
}
return descr;
}
}
70 E. Guerra, J. de Souza, and C. Fernandes

The ComparisonComponent presented in Listing 1 is refactored to retrieve the


ComparisonDescriptor from the ComparisonMetadataReader. It uses
the Reflection API [13] to retrieve the properties values based on the information
contained in the respective PropertyDescriptor. Then, it delegates the
comparison to one of the methods compareWithTolerance(),
compareRegular() or compare() method, in case of deep comparison.

Related Patterns
Metadata Container is the foundation of the proposed pattern language. Indeed in
Figure 1, one can observe that all patterns depend directly or indirectly on it. The
rationale behind this is that the decoupling between the logic and the metadata reading
provides a structure that allows for each part to evolve independently.
This pattern can be considered related to Data Accessor [45], which encapsulates
physical data access details in a single component, decoupling data access
responsibilities. Accordingly, Metadata Container uses the same principle to decouple
the metadata reading.
This same concept is also used in Property Loader [58], which loads and provides
access to external configurable properties at runtime. In this pattern, the application
uses the Property Loader to decouple its logic from the property reading. The greatest
difference from Metadata Container is that the class which loads the properties and
provides access to them is the same. In the proposed pattern, since metadata can have
a complex structure, Metadata Container is used to store these values to be accessed
by the framework.

3.2 Metadata Repository


Also Known as
Metadata Cache, Central Metadata Provider

Context
The functionalities of a framework are usually invoked more than once in the same
application. For a metadata-based framework this fact means that the Metadata
Container should be retrieved more than once. Specially when metadata is defined by
external sources, the process of metadata reading can become a bottleneck for the
application performance. The framework instances can keep the Metadata Container
to other invocations; however, if other instances are created, the reading process
would need to be repeated. It is also not desirable for the framework controller to
accumulate the responsibility of managing the Metadata Container instances.
In this context, it is important to make the metadata available not only for distinct
framework instantiations, but also among the framework components of the same
instance. Having a central place to retrieve the Metadata Container, it would not be
necessary to pass it as a parameter to other framework classes. This availability is also
important to enable external classes to retrieve this information.
For instance, the previous ComparisonComponent implementations read the
metadata in every invocation of the method compare(). In a scenario where many
comparisons of the same class should be made, this can waste processing time.
Pattern Language for the Internal Structure of Metadata-Based Frameworks 71

Problem
How to make metadata available for repeated use while avoiding unnecessary
metadata readings?

Forces
• Having a single instance of the framework entry point can be easier in some
architectures, but under other circumstances, it is not possible. For instance,
when the framework entry point is a proxy, it should have an instance for
each application class instance encapsulated.
• The framework controller should not be responsible for managing instances
of Metadata Container.
• Having a central place to retrieve metadata can open the possibility for
external classes to retrieve metadata.
• When metadata is cached, the additional runtime memory consumed is
traded for a reduced processing time in metadata reading.
• Lazyly loading the metadata can allow a fast initialization, but it can slow the
application execution when the metadata is retrieved for the first time.
• Pre-loading the metadata can accelerate the application execution, but it can
also slow down the application initialization.
• If the framework allows for changing metadata at runtime, any
implementation which caches the metadata read in memory should handle
concurrency issues.

Solution
Metadata Repository proposes creating a central repository where metadata can be
retrieved. This repository is responsible for managing the metadata reading process
and internally storing the Metadata Container instances already obtained.
Consequently, it can perform the metadata reading at the most appropriate time, such
as in the application initialization or in the first time which that metadata is needed.
His internal metadata storage avoid unnecessary metadata readings.
The Metadata Repository can also be used for all the framework components
to easily access a class metadata. This can avoid passing the Metadata Container
as a parameter to all of them. This repository can also enable an external access
to the framework metadata, which can be used by the application or by other
metadata-based frameworks.

Structure
In Metadata Repository, a single class instance is responsible for managing the
metadata reading and internally storing the class metadata. In the first reading of the
metadata, the Repository caches the information and makes it available to any
other component that needs it. The Metadata Repository can be implemented as a
Singleton [17], however other patterns such as Dependency Injection and Service
Locator [14] can also be applied.
Figure 5 introduces a class diagram of the pattern. In this structure,
FrameworkController does not directly access MetadataReader. In fact all
of the metadata accesses occur via Repository, which has a common base of
72 E. Guerra, J. de Souza, and C. Fernandes

metadata, represented by instances of MetadataContainer, which is shared


between all FrameworkController instances.

Participants
• MetadataReader - It is responsible for reading the metadata wherever it
is defined. It is used by Repository to retrieve instances of
MetadataContainer and store it internally.
• MetadataContainer - It is responsible for representing the metadata of
an application class at runtime. It is stored internally by the Repository.
• FrameworkController - It is the framework entry point. It is
responsible for executing the main logic and for being a controller for the
other classes. It uses Repository to retrieve metadata represented in
instances of MetadataContainer.
• Repository - It is responsible for managing the access to
MetadataReader and internally storing the instances of
MetadataContainer. It has a single instance and provides metadata to
all instances of FrameworkController or to any other classes that
might need it.

MetadataContainer

create use

«singleton»
MetadataReader Repository FrameworkController

+getMetadataContainer()
use +getInstance() use +execute()
+getMetadata()

Fig. 5. Metadata Repository structure

Dynamics
The sequence diagram in Figure 6 illustrates the algorithm for accessing metadata
using the Repository. Moreover, if the metadata is not read yet, Repository
collaborates with MetadataReader to retrieve the metadata represented by an
instance of MetadataContainer. Then, in further accesses, the metadata is
already stored inside Repository and is returned without an additional reading.

Consequences
• (+) The unnecessary metadata reading can be avoided and therefore the
application performance can be improved.
Pattern Language for the Internal Structure of Metadata-Based Frameworks 73

• (+) The application can choose to use the repository to load all metadata
when the application starts or to load it only when the application needs them.
• (+) The metadata is available in a central point to be accessed by other
software components, facilitating to share metadata.
• (+) Different framework classes can access the metadata directly from the
repository, eliminating the need to pass MetadataContainer as a
parameter among them.
• (-) For a framework whose instantiation uses a singleton class shared by all
the application, the creation of a repository may be unnecessary.
• (-) For frameworks which need to process metadata only once, such as for
testing or instance creation, repository is unnecessary.
• (-) For applications that can change the metadata at runtime, it is necessary to
control the access in the MetadataContainer for concurrent
modification.
• (-) The storage of metadata in the repository can increase the usage of
runtime memory by the application in exchange of a saving in the metadata
reading processing.

:FrameworkController :Repository :MetadataReader

getMetadata()

if [not exists MetadataContainer]


getMetadataContainer()

create
container:MetadataContainer

populate with metadata

container

if [exists MetadataContainer]
Access Internal Cache

container

Fig. 6. Sequence of FrameworkController using Metadata Repository

Known Uses
The Hibernate framework provides the class SessionFactory, which is
responsible for creating Session. Further, the Session class provides an API for
the application to persist and retrieve entities from the database. The
SessionFactory has an encapsulated repository and provides methods to retrieve
74 E. Guerra, J. de Souza, and C. Fernandes

metadata. As a consequence, each instance of Session created receives a reference


to this SessionFactory, which is a central place to retrieve the metadata for all
instances.
The NHibernate contains a class named Mappings which contains the metadata
already obtained by the framework and can be considered a Metadata Repository. This
class is invoked when the framework loads configurations and mappings. This data is
then retrieved by other components during the framework execution.
XapMap provides a component that creates an instance of one schema based on an
instance of the other schema and also provides a proxy that encapsulates the access of
an instance of one schema based on the other schema API. Both components of the
framework access the metadata through a singleton repository, which guarantees that
the metadata will not be read again for the same class, even if it is accessed by
different classes.

Running Example
The application that uses the Comparison Component creates an instance of
ComparisonComponent and then calls the compare() method to get the
differences between two instances of the same class. In the current implementation,
whenever the compare() method is called, a new metadata reading occurs.
To avoid the possible performance loss that unnecessary metadata readings can
cause, the Metadata Repository pattern is applied to the Comparison Component.
Listing 3 represents the Repository class, which is a singleton, and provides
metadata to all ComparisonComponent instances. The class
ComparisonComponent also needs to be changed to use the class Repository
instead of directly accessing the ComparisonMetadataReader.

Listing 3. Source code of Repository.


public class Repository {

private static Repository instance;

public static Repository getInstance(){


if(instance == null){
instance = new Repository();
}
return instance;
}

private ComparisonMetadataReader reader;


private Map<Class, ComparisonDescriptor> cache;

private Repository(){
reader = new ComparisonMetadataReader();
cache = new HashMap<Class, ComparisonDescriptor>();
}
public ComparisonDescriptor getMetadata(Class clazz){
if([Link](clazz)){
return [Link](clazz);
}
ComparisonDescriptor cd = [Link](clazz);
[Link](clazz, cd);
return cd;
}
}
Pattern Language for the Internal Structure of Metadata-Based Frameworks 75

Related Patterns
Metadata Repository is important to allow metadata sharing. Therefore the Metadata
Reader Adapter uses the repository of another component to read and adapt the
metadata format. The Metadata Processing Layers divides the logic of the metadata-
based component in many processing layers and using Metadata Repository is
recommended to provide a common place to access metadata without the need to pass
the Metadata Container as a parameter among them.
Metadata Repository can be considered an adaptation of the pattern Repository [15],
which is specific for the information retrieved from data-mapping layers. This pattern
is also related to the patterns Cache Accessor and Demand Cache [45], which provide
a structure for caching data retrieved from a data source. It is important to highlight
that the Metadata Repository differs from those patterns because it is not used only for
performance reasons, but also performs an import role for metadata sharing and
facilitates the metadata access from different framework classes. Other patterns
related to cache [45] can also be applied in a Metadata Repository implementation to
improve its functionality.

4 Metadata Reading Patterns

4.1 Metadata Reader Strategy

Also Known as
Metadata Reader Switch, Exchangeable Metadata Reader

Context
The metadata reading is an important part of a metadata-based framework. The choice
of how the metadata about the application classes should be defined is crucial to the
framework usability. Since the framework can be used in different applications, they
can have different needs for the metadata definition.
Different strategies for metadata definition have different consequences on the
application that uses it. For instance, annotations are usually less verbose and closer to
the source code, while XML files can easily be changed without the need to recompile
the code. If the metadata should be defined for legacy code, the use of code
annotations is not possible.
If the metadata definition provided by the framework does not fulfill the
application requirements, its usage is usually discarded. When this incompatibility is
identified late in the framework adoption, the framework is often misused. For those
reasons it is important for the framework to support different sources and formats of
metadata.
As an example, in Repository presented in Listing 3, the class
ComparisonMetadataReader is directly instantiated. Additionally, the
framework does not provide an abstraction for the metadata reading class.
Consequently, it is not possible to change or extend how the metadata is obtained in a
specific framework instantiation.
76 E. Guerra, J. de Souza, and C. Fernandes

Problem
How to allow the framework to support metadata reading from different sources and
formats?

Forces
• The application could already have the metadata needed by the framework in
other sources.
• The use of external metadata definition can make it modifiable at
deployment time.
• Code annotations bring the metadata definition closer to the source code,
usually making it easier to maintain.
• The use of annotations is sometimes not possible in legacy classes, which
demand usage of other metadata definition strategies.
• Different applications may have different needs for metadata definition in the
same framework domain.
• The same application can have different needs for metadata definition for
distinct class sets.

Solution
Metadata Reader Strategy proposes abstracting the metadata reading component to
enable the exchange of its concrete implementation. By changing the implementation
of metadata reader, it is possible to change the algorithm which is used to obtain the
Metadata Container to be used by the framework. Distinct reading implementations
can access metadata form different sources and formats.
The framework also needs to allow the application to configure the concrete
Metadata Reader Strategy which should be used in a particular instantiation. That can
be made by using factories, configuration files, or Dependency Injection [14]. The use
of factories is specially advised when distinct metadata readers should be used for
distinct sets of classes.

Structure
The Metadata Reader Strategy uses a similar structure of Strategy [17] but for
metadata reading purposes, its structure is introduced in Figure 7. There, an interface
is used to abstract the metadata reading, and different classes can implement it to read
metadata from different sources. A Singleton [17] is used to retrieve the correct
metadata reader instance, but other factory implementations can be adopted as well.
Dependency Injection [14] is another alternative that can be used to set the correct
reader in framework.
The interface AbstractMetadataReader abstracts the reading of metadata
and is implemented by any ConcreteMetadataReader. The
MetadataReaderClient represents the class that needs to read metadata. If the
component uses the structure of Metadata Container the client will be
FrameworkController. Otherwise, if it uses Metadata Repository structure the
client will be Repository.
Pattern Language for the Internal Structure of Metadata-Based Frameworks 77

«singleton»
«interface» MetadataReaderProvider
AbstractMetadataReader
+getMetadataContainer() +getMetadataReader()
+getInstance()
use
get reader
instance
ConcreteMetadataReader
MetadataReaderClient

+getMetadataContainer()

Fig. 7. The structure of Metadata Reader Strategy

Participants
• AbstractMetadataReader - It represents an abstraction of a metadata
reader. It must be implemented by any ConcreteMetadataReader.
• ConcreteMetadataReader - It is responsible for reading metadata from
one specific source and implements the AbstractMetadataReader
interface.
• MetadataReaderClient - It is the class that needs to directly retrieve
metadata from a reader, which can be a Repository or a
FrameworkController depending on the component structure. It is
coupled only with AbstractMetadataReader and not with one specific
implementation.
• MetadataReaderProvider - It is responsible for providing the correct
ConcreteMetadataReader instance that the
MetadataReaderClient should use for each application class.

Dynamics
The client uses MetadataReaderProvider to retrieve the correct instance of a
ConcreteMetadataReader. This class can have some logic that returns different
readers to read metadata from different classes. It is especially useful if different sets
of classes in the application require different readers.
As an alternative implementation, the MetadataReaderProvider is not
necessary if the client set the ConcreteMetadataReader instance as a parameter
or using dependency injection. The need for the MetadataReaderProvider can
also be eliminated by the use of Dependence Injection [14] on the
MetadataReaderClient. Figure 8 shows a sequence diagram that represents
how the MetadataReaderClient retrieves the MetadataContainer by
using this solution.
78 E. Guerra, J. de Souza, and C. Fernandes

:MetadataReaderClient :MetadataReaderProvider

getMetadataReader()

create
reader:ConcreteMetadataReader
reader

getMetadataContainer()

Fig. 8. Sequence of MetadataReaderClient retrieving a Metadata Container

Consequences
• (+) The framework can provide more than one alternative for metadata
definition for an application to use.
• (+) The application can provide new approaches for metadata definition,
extending the framework metadata reading functionality.
• (+) The MetadataReaderProvider can return different readers for
different classes in the same application.
• (-) In cases in which one approach for metadata definition is enough, the use
of this pattern can over-design the component.
• (-) Additional configurations for the Metadata Reader Strategy can
complicate the first framework instantiation for beginners.

Known Uses
Early versions of the Hibernate framework support metadata definition by only using
XML. The class Configuration is used to setup the configuration files and create
the SessionFactory instance. The project Hibernate Annotations is a separate
release that gives support to annotations to the framework. Furthermore, the class
AnnotationConfiguration, which extends Configuration, creates the
same SessionFactory instance by using annotations as the metadata source.
The ACE framework supports the mapping of web functionalities to
mobile systems. It provides metadata definition by using annotations for new
applications and using XML files for legacy applications. As a result, it uses the
interface MetadataFactory to abstract the metadata reading and has
implementations to get it both from annotations and from XML files, respectively
AnnotationMetadataFactory and XmlMetadataFactory.
MentalLink maps ontology instances to objects by using annotations. Natively it
does not support other types of metadata definition, but it uses the structure of this
pattern to allow for the extension of the metadata reading mechanism by the
application. The interface AdapterFactory is used to abstract the metadata
Pattern Language for the Internal Structure of Metadata-Based Frameworks 79

reading and the class AnnotationAdapterFactory implements the annotations


reading. A new implementation of AdapterFactory can be created by the
application and configured in the AdapterFactoryManager to be used by the
framework.

Running Example
The application that uses the Comparison Component now needs to compare classes
from a legacy application whose source code the developers do not have access to
modify. One solution to this problem is to provide the Comparison Component with a
facility to define metadata by using XML files.
Before implementing the reading from XML files, the framework is refactored to
implement the Metadata Reader Strategy. Then, the
ComparisonMetadataReader class is renamed to
AnnotationComparisonMetadataReader and an interface, named
ComparisonMetadataReader, is extracted to generalize the concept of
metadata reading.
To provide the current reader implementation to the framework, the
MetadataReaderProvider class is introduced. It is a Singleton class that returns
an instance of the configured ComparisonMetadatReader. It has two static
methods that encapsulate the access to the singleton instance to set and to get the
metadata reader instance. In this case, the metadata factory instance should now be
obtained by using this new class in the Repository.
After the refactoring, the metadata reading using XML files can be implemented
and used by the Comparison Component. Listing 4 presents an example of an XML
document for the class metadata definition. For simplicity, the class metadata is
considered to be stored in an XML file with the same name of the class.

Listing 4. An example of the metadata definition in XML.


<?xml version="1.0" encoding="UTF-8"?>
<comparison>
<prop name="name"/>
<prop name="weight" tolerance="0.1" />
<prop name="address" deep="true" />
</comparison>

The XMLComparisonMetadataReader source code is presented in Listing 5. It


uses JColtrane framework [31], which is based on SAX [50] parsing, to read XML
files. JColtrane uses annotations for the SAX event management. Listing 6 exhibits
the XML handler that reads metadata and populates the ComparisonDescriptor.

Listing 5. The implementation of XMLComparisonMetatadaReader.


public class XMLComparisonMetadataReader implements ComparisonMetadataReader{
@Override
public ComparisonDescriptor createContainer(Class c) {
try {
SAXParser parser= [Link]().newSAXParser();
File file=new File([Link]()+".xml");
ComparisonXMLHandler handler = new ComparisonXMLHandler();
[Link](file,new JColtraneXMLHandler(handler));
80 E. Guerra, J. de Souza, and C. Fernandes

return [Link]();
} catch (Exception e) {
throw new RuntimeException("Can't read metadata",e);
}
}
}

Listing 6. The handler to interpret XML files using JColtrane framework.


public class ComparisonXMLHandler {

private ComparisonDescriptor descriptor = new ComparisonDescriptor();

@StartElement(tag="prop")
public void addProperty(@Attribute("name") String name,
@Attribute("tolerance") Float tolerance,
@Attribute("deep") Boolean deep){
PropertyDescriptor pd = new PropertyDescriptor();
[Link](name);
if(tolerance != null)
[Link](tolerance);
if(deep != null)
[Link](deep);
[Link](pd);
}

public ComparisonDescriptor getDescriptor() {


return descriptor;
}
}

Related Patterns
Metadata Reader Strategy provides the flexibility in the achievement of metadata
required by other patterns in this pattern language. Both Metadata Reader Chain and
Metadata Reader Adapter are patterns based on the fact that it is possible to change
the algorithm for metadata reading.
This pattern uses the same structure of Strategy [17] to help to solve the problem of
metadata reading. It is also related to Data Mapper [15] and Data Access Object [1],
also known as DAO, which are used to encapsulate data access and manipulation in
separate layers. By using one of them, it is possible to have different implementations
for retrieving data from different data sources.

4.2 Metadata Reader Chain


Also Known as
Composite Metadata Reader, Aggregate Metadata Reader

Context
The code annotations define metadata closer to the application class, making it easier
to manage and to maintain this information. The usage of XML is more indicated
when the metadata may need to be changed at deploy-time without source code
recompilation. However, if a few classes in a system need to be configured at deploy
time, that does not justify the use of XML metadata definition for all of them.
Each metadata definition strategy has its applicability and, in some applications,
the best solution is a combination of more than one. In this context, to read different
metadata sources exclusively is not enough for a framework, because the metadata
Pattern Language for the Internal Structure of Metadata-Based Frameworks 81

may need to be dispersed in more than one source. Consequently, the framework
should combine metadata from different sources in the reading process.
For instance, the implementations of ComparisonMetadataReader,
presented in listings 2 and 5, read metadata from respectively annotations and XML
files. Despite both metadata formats being supported, their combination is not.

Problem
How to allow for metadata reading to combine information from more than one
source?

Forces
• Each kind of metadata definition has its benefits and drawbacks and some
applications need to take advantage of the benefits from more than one.
• The use of more than one metadata source requires an organization of the
precedence between these sources.
• Some metadata can be retrieved partially from alternative sources, such as
metadata from other frameworks, and must be complemented with additional
information from other sources.
• An order can be defined for reading metadata from more than one source, but
some applications may need to use a different order.
• Code annotations are an easy way to define metadata and can be
complemented by an XML document that can be changed at deployment time.

Solution
Metadata Reader Chain proposes combining different metadata readers to compose
the framework metadata reading algorithm. Each reader is responsible for retrieving
metadata from one source and the metadata should be merged to create the complete
Metadata Container. The merging algorithm, which can be implemented inside or
outside the readers, should be prepared to deal with redundancy and conflicts.
The framework should provide a Metadata Reader Strategy which coordinates the
execution of other readers. During the execution of this Metadata Reader Chain, this
implementation is also responsible for passing the Metadata Container instance
among the reader implementations or to merge the information contained in the
Metadata Container instances returned by them. The precedence is defined by the
readers order and by the action taken when the Metadata Container is already
populated with some given information.

Structure
Figure 9 shows the class diagram that represents the basic structure of this Metadata
Reader Chain. The CompositeMetadataReader is a class that uses other
readers to compose the metadata reading algorithm. It has the responsibility of
coordinating the other readers and returning a MetadataContainer populated
with metadata combined from all the sources.
One alternative to implement the CompositeMetadataReader is to retrieve
the MetadataContainer from all the ConcreteMetadataReader instances
82 E. Guerra, J. de Souza, and C. Fernandes

and combine merge the metadata in only one MetadataContainer. By using this
approach, the readers implementation does not need to worry about the metadata from
the other readers, however the implementation which coordinates Metadata Reader
Chain should be responsible for the merging.
In the other option to implement this pattern, the AbstractMetadataReader
implementations should have a different approach for reading metadata. Instead of
populateMetadataContainer() returning a MetadataContainer
instance, it should receive it as a parameter and populate it. As a result, the reading
algorithm of each ConcreteMetadataReader should not assume that
MetadataContainer instance is empty and consider that another reader may have
already populated it.

Participants
• AbstractMetadataReader - It represents an abstraction of a metadata
reader. Any ConcreteMetadataReader must implement it.
• ConcreteMetadataReader - It is responsible for reading metadata
from one source and implementing the interface
AbstractMetadataReader. It should also consider that
MetadataContainer might have already been populated by another
source.
• MetadataReaderClient - It represents a Repository or a
FrameworkController, depending on the component structure. It is the
class that needs to directly retrieve metadata from a reader.
• CompositeMetadataReader - It represents the reader that uses other
AbstractMetadataReader implementations to compose the metadata
reading algorithm.
• MetadataContainer - It is responsible for representing metadata of an
application class at runtime. It is created by the
MetadataReaderClient and populated by metadata readers.

MetadataReaderClient
use
«interface»
AbstractMetadataReader
* +populateMetadataContainer()

create
MetadataContainer

1 CompositeMetadataReader ConcreteMetadataReader

+populateMetadataContainer() +populateMetadataContainer()

Fig. 9. Structure of Metadata Reader Chain


Pattern Language for the Internal Structure of Metadata-Based Frameworks 83

Dynamics
Figure 10 represents one possible implementation of how
CompositeMetadataReader can use other readers to compose the information
in MetadataContainer. The MetadataReaderClient is responsible for
creating a MetadataContainer instance, which is passed as a parameter to the
CompositeMetadataReader. It is noticeable that the
CompositeMetadataReader delegates for each reader instance the responsibility to
read metadata and populate the MetadataContainer.
Another possible implementation is for the CompositeMetadataReader to
retrieve distinct instances of MetadataContainer for each
ConcreteMetadataReader. In this scenario, the
CompositeMetadataReader should retrieve information from each
MetadataContainer and merge them in only one to be returned.

Consequences
• (+) The framework can use simultaneously more than one source of metadata.
• (+) Alternative metadata sources that contain only partial information can be
used to complement the metadata reading.
• (+) The order that the readers retrieve metadata can be set in the Metadata
Reader Chain.
• (-) The use of more than one source for metadata definition by the
framework can slow down the metadata reading.
• (-) The metadata read can be validated only at the end of the reading process,
since each source contains only partial information.
• (-) The metadata defined in one source can be inconsistent with other sources
and the readers must consider that situation, dealing with it appropriately.

:MetadataReaderClient :CompositeMetadataReader :ConcreteMetadataReader

create
container:MetadataContainer

populateMetadataContainer(container)

loop [for each metadata reader]

populateMetadataContainer(container)

set metadata

Fig. 10. Sequence diagram for a composite metadata reading


84 E. Guerra, J. de Souza, and C. Fernandes

Known Uses
The ACE framework supports the metadata definition by using annotations and
XML documents. The XML-based definition overrides the annotation-based
definition allowing for the configurations to be changed at deployment time. This
pattern is used internally by the class ChainMetadataFactory to allow for the
reading from multiple sources.
In MetadataSharing, a repository reads the metadata from many sources and then
provides an API for the frameworks to retrieve the information that they need. The
metadata reading is implemented as a Chain of Responsibility [17], where the abstract
class MetadataFactory can have an instance of another factory, which is invoked
in sequence. The configuration file [Link] defines the order of the
metadata readers.
By using Hibernate Validator, release 4.0 alpha, it is possible to override the
metadata defined in annotations by the metadata in XML files, but according to the
specification this order cannot be changed. For instance, by setting the attribute
ignore-annotations as true in the XML file, it is possible to ignore all the
validation annotations defined in the class.

Running Example
After the Comparison Component is deployed with the application, some comparison
rules might need to be changed. Based on that requirement, the definition of metadata
in XML files is the most appropriate solution, but it is easier and more productive to
configure the comparison metadata by using annotations. To solve this conflict, the
Comparison Component is refactored to support the definition of metadata by using
annotations which can be overridden by definitions conveyed by an XML document.
The first modification to be made is to change the signature of the method that
reads metadata to receive a ComparisonDescriptor instance as a parameter.
The method is also renamed from createContainer() to
populateContainer() to best describe what it does in this new version. The
new method signature is: void populateContainer(Class c,
ComparisonDescriptor descriptor).
Another modification that should be made in the existing metadata readers is to
consider that metadata information may already exist in the descriptor. The pieces of
code that insert metadata in the Metadata Container should first try to retrieve the
PropertyDescriptor to verify if it is already in the descriptor and, only if it is
not, it should create a new one. Repository also needs to be changed to create an
initial empty instance of ComparisonDescriptor to pass it to the
populateContainer() method.
With these modifications, a composite metadata reader can be implemented. The
class ChainComparisonMetadataReader is presented in Listing 7. It receives
an array of ComparisonMetadataReader as a parameter in the constructor and
invokes all of them in the same order to populate the ComparisonDescriptor
instance. It uses the “var-args” notation introduced in JDK 1.5 to facilitate the
instance creation.
Pattern Language for the Internal Structure of Metadata-Based Frameworks 85

Listing 7. Source code of ChainComparisonMetadataReader.


public class ChainComparisonMetatataReader implements ComparisonMetadataReader {

private List<ComparisonMetadataReader> readers;

public ChainComparisonMetatataReader(ComparisonMetadataReader... readers) {


[Link] = new ArrayList<ComparisonMetadataReader>();
for(ComparisonMetadataReader reader : readers){
[Link](reader);
}
}
@Override
public void populateContainer(Class c, ComparisonDescriptor descriptor) {
for(ComparisonMetadataReader reader : readers){
[Link](c, descriptor);
}
}
}

Related Patterns
Metadata Reader Chain is important to enable metadata reading from sources that
contain only a part of the needed metadata. It is important for the implementation of
Metadata Reader Adapter, which uses metadata already obtained from other
frameworks to populate the Metadata Container.
Moreover, Metadata Reader Chain uses Composite [17] as part of the solution to
enable the creation of a metadata reader composed by other readers. An alternative
implementation of this pattern could use other patterns with recursive composition,
like Chain of Responsibility [17]. In this case, each reader could represent a handler in
the processing chain, invoking the next one after its own metadata reading.
This pattern also presents a similar solution to the Hierarchical Property Loader
[58], which provides a Property Loader [58] which handles multiple property storages
in a way so that more specific storage values overwrite less specific storage values.
The greatest difference to metadata reading is that when more than one metadata
source is provided, they usually define metadata in different formats, such as XML
and annotations. Consequently, while Hierarquical Propety Loader can use the same
reading algorithm for different storages, the Metadata Reader Chain should provide
an interface for distinct implementations to be plugged in.

4.3 Metadata Reader Adapter


Also Known as
Metadata Converter, Metadata Transformer

Context
The metadata defined for a framework is additional information about a program
element. The information defined for one framework can also be useful to another one.
For example, an instance validation framework can provide metadata elements to
configure the maximum and minimum value of a numeric field. This information is
also useful for a metadata-based framework which creates graphical interfaces, since
it can be used to create a graphical component to represent that field.
86 E. Guerra, J. de Souza, and C. Fernandes

For frameworks which provide many options for metadata definition, such as using
a Metadata Reader Chain, it is not trivial to retrieve the metadata directly. For
instance, it can be spread in annotations and XML files. When the metadata is defined
in external files, another issue is to obtain the location of these files. Specially when
metadata reading is a complex process, it is not desirable for another framework to
recreate all this process.
For instance, the Comparison Component could benefit from metadata for
object-relation mapping in the Hibernate [2] framework. For instance, it can define
the deep comparisons based on which class an entity is mapped to the database.
However, Hibernate metadata can be defined in XML files or by using annotations,
and the external files can be located in several places.

Problem
How to allow for a framework to retrieve metadata already available in another one?

Forces
• The performance can degrade with two frameworks reading the same
information in the same application.
• It is easy to locate metadata of frameworks that support only one source, but
this is not true for frameworks that support more than one source.
• It is not possible to predict where the metadata are when the framework
provides an extensible metadata reading.
• Metadata defined in external files can be hard to locate when that depends on
the other framework configurations.
• The same information can be defined in the metadata formats of two
frameworks, but it can lead to inconsistencies and that may reduce
productivity.
• Some frameworks provide an API that enables the retrieval of a
representation of the metadata already read.

Solution
Metadata Reader Adapter proposes creating a Metadata Reader Strategy which
accesses the Metadata Repository from another framework to obtain its Metadata
Container. The metadata contained in the other framework container is accessed by
the Metadata Reader Adapter and properly inserted in its own Metadata Container.
This information is usually not directly applicable, needing to be interpreted to the
other framework context.
It is important for the other framework to provide an accessible Metadata
Repository which enables the access to its metadata. In cases where the repository is
not available, another possibility is to directly access the metadata reader. However,
this alternative has the drawback of repeating the metadata reading process.
Since the metadata of the other framework is usually not enough to fulfill all the
required metadata, the Metadata Reader Adapter is normally used as part of a
Metadata Reader Chain. In this context, it is important to define the metadata source
precedence for cases when there are conflicts with the metadata from the other
framework.
Pattern Language for the Internal Structure of Metadata-Based Frameworks 87

Structure
Figure 11 presents the structure of this pattern. The class
AdapterMetadataReader uses a repository from another framework,
represented by the class OtherRepository, to retrieve its metadata container,
represented by the class OtherMetadataContainer.
The AdapterMetadataReader is an implementation of the
AbstractMetadataReader. The CompositeMetadataReader, which
implements Metadata Reader Chain, is also represented in the diagram since the
Metadata Reader Adapter usually reads only a piece of metadata. Consequently, the
MetadataContainer should be complemented with information from other
sources read by other ConcreteMetadataReader.

«interface» MetadataContainer
create
AbstractMetadataReader
* +populateMetadataContainer()

CompositeMetadataReader ConcreteMetadataReader AdapterMetadataReader

+populateMetadataContainer() +populateMetadataContainer() +populateMetadataContainer()

use

«singleton»
OtherRepository OtherMetadataContainer

+getOtherContainer()

Fig. 11. Structure of Metadata Reader Adapter

Participants
• AbstractMetadataReader - It represents an abstraction of a metadata
reader.
• ConcreteMetadataReader - It is responsible for reading metadata
from one source and implementing the interface of
AbstractMetadataReader.
• CompositeMetadataReader - It represents the reader that uses other
AbstractMetadataReader to compose the metadata reading algorithm.
• AdapterMetadataReader - It represents the metadata reader that
accesses OtherRepository to retrieve instances of
OtherMetadataContainer. It also converts the information obtained to
the MetadataContainer format.
88 E. Guerra, J. de Souza, and C. Fernandes

• MetadataContainer - It is responsible for representing the application


class metadata needed by the framework.
• OtherRepository - It represents the metadata repository of another
framework.
• OtherMetadataContainer - It is responsible for representing the
application class metadata needed from another framework.

Dynamics
Figure 12 represents the sequence diagram for the method
populateMetadataContainer() of the class AdapterMetadataReader.
The AdapterMetadataReader is represented being invoked by a
CompositeMetadataReader since it usually does not provide the entire
metadata needed by the framework. After retrieving the metadata from the another
framework, the adapter interprets the information and sets it on its own metadata
container. Alternatively, the adapter can retrieve the metadata directly from a metadata
reader, when a repository is not available in the other framework.

:CompositeMetadataReader :AdapterMetadataReader :OtherRepository other:OtherMetadataContainer c:MetadataContainer

populateMetadataContainer(c)

getMetadata()

other

getMetadata()

setMetadata()

Fig. 12. AdapterMetadataReader retrieving metadata from another repository

Consequences
• (+) The possibility of inconsistencies that might occur with the definition of
the same information for the two frameworks is reduced, since the metadata
can be defined once and used by both.
• (+) The amount of metadata that should be defined for a class is reduced,
since the same metadata can be shared by more than one framework.
• (-) This solution is sensitive to changes in the Metadata Container interface
of the other component.
• (-) This solution is only viable when the other component has an API that
allows for the access to its Metadata Container.

Known Uses
MetadataSharing has a central repository, implemented in the class Repository,
used to store metadata read from the configured sources. The components must use a
Pattern Language for the Internal Structure of Metadata-Based Frameworks 89

Metadata Reader Adapter, abstracted by the class RepositoryAdapter, to get it


from the repository and convert it to the format of its Metadata Container.
Hispagnol [25] proposed a model to unify the models OLTP (Online Transaction
Processing), used for persistence, and OLAP (Online Analytical Processing), used for
data mining. In the proposed implementation, created in Object Pascal, the OLTP
metadata is retrieved and then adapted and complemented to compose the metadata
necessary for OLAP.
In Nardon and Silva [42], tips, tricks, and new design patterns are presented in the
context of a Java EE application by using the EJB 3 specification [34]. One of the
practices described is the use of object-relational metadata retrieved from Hibernate
SessionFactory for its use inside some EJB components. For instance, the id
property can be used by other components to identify an entity for auditing purposes.

Running Example
Some applications that use the Comparison Component, may also use the Hibernate
[2] in the persistence layer. When a property of a persistent class is also a persistent
class, that property is a composed object. For the comparison domain, that means that
this property must be deeply compared. In this case, to avoid duplicate configurations
and inconsistencies, a Metadata Reader Adapter is created to get this information
directly from Hibernate.
The class AdapterComparisonMetadataReader, presented in Listing 8,
receives in the constructor an instance of SessionFactory, namely a Hibernate
class with a method that allows for the application to retrieve the class metadata.
Based on class metadata, in the method populateContainer() searches for
properties that are also entities and sets the deepComparison to true in the
PropertyDescriptor.

Listing 8. The AdapterComparisonMetadataReader source code.


public class AdapterComparisonMetadataReader implements ComparisonMetadataReader {
private SessionFactory sessionFactory;

public AdapterComparisonMetadataReader(SessionFactory sessionFactory) {


[Link] = sessionFactory;
}

public void populateContainer(Class c, ComparisonDescriptor descriptor) {


ClassMetadata metadata = [Link](c);
if (metadata != null) {
for (String prop : [Link]()) {
if ([Link](prop).isEntityType()) {
PropertyDescriptor pd = descriptor.
getPropertyDescriptor(prop);
if (pd == null) {
pd = new PropertyDescriptor();
[Link](prop);
[Link](pd);
}
[Link](true);
}
}
}
}
}
90 E. Guerra, J. de Souza, and C. Fernandes

Related Patterns
Metadata Reader Adapter assumes that the framework uses Metadata Reader Chain
since the metadata from the other framework would rarely have all the needed
information. If that is not true, the Metadata Reader Chain does not need to be
implemented. The Metadata Repository also needs to be implemented but in another
framework. If it is not implemented, an alternative is to retrieve the metadata directly
from a metadata reader.
This pattern is related to the Adapter [17] since it invokes the API to access
metadata from another framework and adapts the information for the framework
context. In Metadata Reader Adapter, it is not the functionality provided that is
adapted to another API, but the information provided by the other framework that is
used and interpreted in another context.

4.4 Metadata Reader Delegate


Also Known as
Extended Metadata Reader, Metadata Piece Reader

Context
Every metadata-based framework provides a format which defines how its metadata
should be created. If metadata is defined in an XML file, this format should be
defined in an XML Schema or in a DTD. If the metadata is defined in annotations,
this format is the annotations defined by the framework. This format adopted by the
framework is called metadata schema and a piece of this information, such as an
annotation or an XML element, is called metadata piece.
Since the framework needs to be adapted to applications, sometimes new kinds of
metadata elements are necessary. For instance, if the application extends a Metadata-
based Graphical Framework [19] by adding a new component, probably extending the
metadata schema would also be necessary. As another example, metadata pieces can
also be added to express concepts in an application domain.
If the framework provides only a hotspot for the entire metadata reading algorithm
by using Metadata Reader Strategy, it is necessary to create a reader which can
handle all the metadata schema to deal with one additional metadata piece. In this
context it is important for the framework to provide more fine grained hotspots in the
metadata reading to allow for the addition of new metadata pieces.
In the Comparison Component domain, the classes can have attribute types which
should have a particular treatment by the framework. For instance, if an application
has some properties representing a weight configured with a custom annotation, it
should be possible to extend the framework to understand this new metadata piece.

Problem
How to allow for the framework to understand extensions in metadata schema?

Forces
• Sometimes the source code can become clearer if the application expresses
the metadata by using domain terms.
Pattern Language for the Internal Structure of Metadata-Based Frameworks 91

• It is possible to read metadata from different schemas by using the Metadata


Reader Strategy, but sometimes it is important to extend the reading to add a
new metadata piece.
• The frameworks provide metadata for general use, but for some specific
domains, some applications could need more specific metadata. For instance,
in instance validation domain, metadata schema should enable the extension
to allow for the creation of custom validations by the application.
• If the metadata provided by the framework do not fulfill the application
requirements, they can limit or prevent their usage.
• The framework behavior extension sometimes cannot be done without the
extension of the metadata schema.

Solution
Metadata Reader Delegate proposes delegating metadata pieces reading to other
classes. This pattern is applied in a context of a Metadata Reader Strategy and the
other existing readers do not necessarily need to implement it. Each metadata piece
should be associated to a Metadata Reader Delegate, which should be invoked in the
reading algorithm. The Metadata Reader Delegate should interpret the metadata piece
and the Metadata Container should be populated with that information.
To enable the extension of the metadata schema, it should be possible to configure
the Metadata Reader Delegate associated with a metadata piece. In XML files it can
be performed by associating class names to the element types and in annotations an
Annotation Reader [18] can be used. Consequently, if the application defines a new
metadata piece mapped to a Metadata Reader Delegate, the framework will be able to
perform its processing.

Structure
Figure 13 represents the pattern structure. The interface ReaderDelegate is an
abstraction of the classes that receive a piece of metadata. The
ConcreteMetadataReader should be able to create the correspondent
ConcreteReaderDelegate for each metadata piece received. The mapping
among the metadata piece and the Metadata Reader Delegate should be configurable
to enable the insertion of new metadata pieces.

«interface» use ConcreteMetadataReader


ReaderDelegate
+readMetadata() +populateMetadataContainer()

ConcreteReaderDelegate MetadataContainer
populate

+readMetadata()

Fig. 13. The structure of Metadata Reader Delegate


92 E. Guerra, J. de Souza, and C. Fernandes

A ConcreteReaderDelegate should receive the MetadataContainer as


a parameter and populate it based on the metadata piece received. An alternative
implementation is the method readMetadata() to return information and the
ConcreteMetadataReader is responsible for configuring the
MetadataContainer.

Participants
• ConcreteMetadataReader - It represents a class that reads metadata
and delegates part of its logic to implementations of ReaderDelegate. It
is responsible for instantiating the appropriate
ConcreteReaderDelegate for each piece of metadata.
• ReaderDelegate - It is an abstraction of classes that reads and interprets
a piece of metadata.
• ConcreteReaderDelegate - It represents a concrete class that
implements ReaderDelegate and interprets a specific piece of metadata.
• MetadataContainer - It is responsible for representing the application
class metadata needed in the framework.

Dynamics
Figure 14 presents a sequence diagram representing the reading of metadata using the
ReaderDelegate. For each piece of metadata found, it creates the respective
ConcreteReaderDelegate and delegates the reading of that piece to it. This
readMetadata() method receives the MetadataContainer as a parameter
and populates it with the metadata contained in that piece. Alternatively, the
ConcreteReaderDelegate can return information which should be used by the
ConcreteMetadataReader to populate the MetadataContainer.

:ConcreteMetadataReader :MetadataContainer

loop [for each piece of metadata]


create
:ConcreteReaderDelegate

readMetadata()

setMetadata()

Fig. 14. Metadata reading sequence using Metadata Reader Delegate


Pattern Language for the Internal Structure of Metadata-Based Frameworks 93

Consequences
• (+) The metadata schema can be extended without affecting the concrete
class responsible for reading that type of metadata definition.
• (+) The framework metadata schema can be extended by the application.
• (+) The Metadata Reader Delegate can set custom hook classes in the
framework structure allowing also for behavior extension.
• (-) Depending on the number of possible different pieces of metadata, there
will be many different Metadata Reader Delegates, which are usually small
classes.
• (-) In some frameworks, it is difficult to divide metadata into independent
pieces, which makes the implementation of this pattern unfeasible.

Known Uses
With the NHibernate Validator, new attributes can be created to validate more
specific constraints associated to an application domain. When this new attribute
contains information, it should receive in the attribute [ValidatorClass] a class
which implements the interface IInitializableValidator. This interface has
the method initialize() that is used to interpret the metadata.
JColtrane uses annotations to define conditions for each method to be executed.
New conditions can be added by creating annotations annotated with
@ConditionFactoryAnnotation. This annotation receives the class
responsible for reading that annotation, which should implement the interface
ElementConditionsFactory.
XapMap provides annotations for converting data among different types and a
mechanism for the application to define its own conversion annotations. The
mechanism is similar to the ones used in Hibernate Validator and JColtrane.

Running Example
The Comparison Component in this step is refactored to support annotations
created by the application. As a consequence, the application is able to create
annotations related to its domain, which can also be used by other frameworks and
components.
The interface AnnotationReader is introduced to abstract the reading of an
annotation. It contains a method named readAnnotation() that receives as
parameters the annotation to be interpreted and the PropertyDescriptor
associated to the property where the annotation is found. Each new annotation should
be configured with @DelegateReader by indicating the instance of
AnnotationReader which should interpret it.
The class AnnotationComparisonMetadataReader, which was the
ComparisonMetadataReader renamed presented in Listing 2, must have the
method populateContainer() refactored in order to look for annotations with
@DelegateReader. For each one that is found, it should create the configured
AnnotationReader and subsequently to invoke the readAnnotation()
method. Listing 9 presents the piece of source code that needed to be changed in this
class. The specific code to read the @Tolerance and @DeepComparison is
94 E. Guerra, J. de Souza, and C. Fernandes

removed and substituted by a loop that searches for annotations that have the
@DelegateReader annotation.

Listing 9. The class AnnotationComparisonMetadataReader.


for(Annotation an : [Link]()){
Class anType = [Link]();
if([Link]([Link])){
DelegateReader reader =
(DelegateReader) [Link]([Link]);
Class<? extends AnnotationReader> readerClass = [Link]();
try {
AnnotationReader anReader = [Link]();
[Link](an, prop);
} catch (Exception e) {
throw new RuntimeException("Cannot instantiate reader",e);
}
}
}

After the modification in the class that reads comparison metadata using annotations,
the @DelegateReader must be inserted into the current framework annotations.
Listing 10 presents this insertion into @Tolerance and the class responsible for
reading this annotation and inserting its information in the respective property
descriptor. The same must be done for @DeepComparison. With this refactoring,
new annotations can be created and interpreted by the framework by using the same
mechanism.

Listing 10. The definition of @Tolerance annotation with @DelegateReader.


@Target({[Link]})
@Retention([Link])
@DelegateReader([Link])
public @interface Tolerance {
double value();
}

public class ToleranceReader implements AnnotationReader<Tolerance>{


@Override
public void readAnnotation(Tolerance annotation, PropertyDescriptor desc){
[Link]([Link]());
}
}

Related Patterns
Metadata Reader Delegate is often used with Metadata Processor, allowing the
extension of the metadata schema with the extension of the framework logic. Both
patterns can be used independently, nevertheless it is more plausible to imagine them
being used together.
Annotation Reader [18] is an idiom for the usage of Java annotations. It proposes
the usage of an annotation in other annotations to configure the class which the
framework should use to interpret it. It can be used to configure the Metadata Reader
Delegate if annotations are used to define metadata.
An alternative to a Metadata Reader Delegate when the behavior extension is not
required is the use of Annotation Mapping [18]. It proposes the creation of application-
specific annotations that are mapped to the framework annotations. By using this
Pattern Language for the Internal Structure of Metadata-Based Frameworks 95

solution the framework configurations can be used indirectly in application


annotations. To enable this practice, the framework should implement a Metadata
Reader Strategy which search for framework annotations inside other annotations.

5 Metadata Processing Patterns

5.1 Metadata Processor


Also Known as
Metadata Executor, Metadata Piece Processor

Context
The flexibility in metadata reading is important to enable metadata schema extension
and its reading from different sources and formats. However, despite these hotspots
being important to adjust the metadata reading to the application needs, they do not
actually change the framework's main logic. An extension in the metadata schema
may be motivated by requirements for the insertion of new behavior in the framework.
The insertion of a metadata piece in a programming element usually changes the
framework behavior when it is processing this element. In some domains, it is
important for the application to extend the framework functionality in the processing
of specific elements. Consequently, a new metadata piece defined by the application
should be associated to a new behavior also defined by the application. The
nonexistence of such mechanism may prevent or limit the framework usage.
As an example, in the AnnotationComparisonMetadataReader presented
in Listing 9 the metadata reading of annotation is delegated to other classes, however
these classes cannot extend the comparison functionality already supported. For
instance, it is not possible for only a substring of a property to be considered in a
comparison, even when adding a new annotation @CompareSubstring.

Problem
How to allow framework behavior extension to process new metadata pieces?

Forces
• Some applications need some more specific behavior than those provided
only by the framework metadata configuration.
• Applications can use alternative solutions to implement functionalities not
covered by the framework, even though the architecture will have two
components with the same responsibility.
• The application developers may change the source code of an open-source
framework to change its behavior, but it might make it unfeasible to take
advantage of its future versions.
• In some framework domains, such as instance constraint validation, the
metadata extension associated to a behavior extension is important to
increase reuse.
96 E. Guerra, J. de Souza, and C. Fernandes

Solution
Metadata Processor proposes delegating part of the framework main functionality to
other classes. These class instances compose the Metadata Container and are created
during the metadata reading phase. The Metadata Reader Delegate associated with a
metadata piece is usually responsible for the respective Metadata Processor creation.
However it can also be created directly by a Metadata Reader Strategy which uses
reflection to instantiate them.
During the execution relative to a metadata piece, the framework controller should
retrieve the respective Metadata Processor instance from the Metadata Container.
Further, the framework delegates its execution for that metadata piece to the Metadata
Processor. This solution provides a hotspot which enables the insertion of new
behavior in the processing of each metadata piece.

Structure
Figure 15 shows the class diagram for this pattern. The interface
MetadataProcessor abstracts the processing of a piece of metadata. The
DefaultMetadataProcessor represents a default implementation for
processing and the ConcreteMetadataProcessor represents other
implementations. In addition, the MetadataProcessor implementations may
have instance variables to represent part of the metadata obtained during its reading.
The MetadataProcessor instances should compose the respective
MetadataContainer. This structure allows for new implementations of
MetadataProcessor to carry new attributes and new behavior. The
FrameworkController can access the MetadataProcessor through the
MetadataContainer.

«interface» 1 MetadataContainer
MetadataProcessor
+process() +getMetadataProcessor()

DefaultMetadataProcessor ConcreteMetadataProcessor FrameworkController

+process() +process() +execute()

Fig. 15. The structure of Metadata Processor

Participants
• FrameworkController - It is the framework entry point. It is
responsible for executing the main logic and also for being a controller of
other classes. Besides, it retrieves an implementation of the
Pattern Language for the Internal Structure of Metadata-Based Frameworks 97

MetadataProcessor from the MetadataContainer and executes it


as part of the framework logic.
• MetadataContainer - It is responsible for representing the application
class metadata needed by the framework. It is composed of instances of
MetadataProcessor implementations.
• MetadataProcessor - It is an abstraction of the classes that compose the
MetadataContainer and is invoked as part of the framework logic by
the FrameworkController.
• DefaultMetadataProcessor - It represents a default implementation
of the MetadataProcessor.
• ConcreteMetadataProcessor - It represents a concrete
implementation of the MetadataProcessor.

Dynamics
A sequence diagram that represents the use of the processor by the framework is
presented in Figure 16. The FrameworkController retrieves the
MetadataProcessor from the MetadataContainer and invokes its methods.
The MetadataProcessor should previously be created by the metadata reading
algorithm and inserted in the MetadataContainer. Likewise, it is possible to
have more than one kind of processor in a framework, depending on the different
tasks that it executes and the necessity to make it extensible.

:FrameworkController :MetadataContainer p:ConcreteMetadataProcessor

getMetadataProcessor()

process()

Fig. 16. Sequence diagram representing the use of Metadata Processor

An alternative implementation is to store the metadata in the


MetadataContainer in a more flexible way, for example by using attribute maps,
and then using this information in the FrameworkController to create or
retrieve the processor. This is recommended when the processor must have
98 E. Guerra, J. de Souza, and C. Fernandes

heavyweight objects or it cannot be shared between more than one framework entry
point instances.

Consequences
• (+) It is possible to extend the framework functionalities by creating more
Metadata Processor implementations.
• (+) The Metadata Container uses a more flexible structure, easily allowing
for the addition of different information.
• (+) It allows for the application to extend the metadata schema by adding
functionality relative to its domain.
• (-) The Metadata Container, whose objective is to store metadata, is
composed of instances that also contain framework logic.
• (-) To implement this pattern, the metadata must be divided into pieces that
can be processed separately and in some framework domains that is not
possible.
• (-) The use of processors in the Metadata Container structure may make it
hard for the metadata interpretation when it is retrieved by a Metadata
Reader Adapter.

Known Uses
In NHibernate Validator new annotations can be defined by using the attribute
[ValidatorClass] to reference a class that implements the interface
Ivalidator. When the attribute metadata should be interpreted, this class plays
simultaneously the roles of Metadata Reader Delegate and Metadata Processor. This
interface has the method isValid() that is invoked by the framework for the
processing of each instance variable.
In JColtrane, the method getConditions() of the interface
ConditionFactory returns a list of Condition, that is the Metadata Processor
for this framework. The Condition interface has the method verify(), which is
based on information of the parsing event returning true if that method should be
invoked.
The Oghma framework uses this pattern to create user interfaces based on type
metadata. In this context the Metadata Processor represents the graphical component
that represents one property in the user interface. Depending on the property metadata,
a distinct processor is used. ComboPanel, BoolPanel and
VirtualListPanel are examples of these processor classes.

Running Example
The Comparison Component deals with a domain that can have many application-
specific rules. Therefore, it is important for the component to allow for the application
developers to add new comparison types and associate them with new pieces of
metadata. In this section, the Comparison Component is refactored and a new kind of
comparison is added.
The interface ComparisonProcessor is introduced to abstract the logic of a
comparison. The method compare() receives the property name and the values to
Pattern Language for the Internal Structure of Metadata-Based Frameworks 99

be compared, and then returns null if they can be considered the same or the
respective Difference instance. The PropertyDescriptor class is also
refactored to contain an instance variable with the respective
ComparisonProcessor. In this case, the method getProcessor() returns an
instance of RegularProcessor, which represents the default comparison
algorithm, if the processor attribute is null.
The tolerance, which is stored as an attribute in the PropertyDescriptor,
now is an instance variable of the ToleranceProcessor, introduced in Listing 11.
The class responsible for reading the @Tolerance annotation, represented in
Listing 12, is also adapted to create the instance of ToleranceProcessor with
the correct tolerance value.
The implementation of the class ComparisonComponent should be refactored
to get benefit of this new mechanism. In the execution of the comparison of each
property, when the property deepComparison is false, the
ComparisonProcessor is retrieved from the PropertyDescriptor and is
used to compare the values.

Listing 11. The class ToleranceProcessor that processes the tolerance metadata.
public class ToleranceProcessor implements ComparisonProcessor {
private double tolerance;
public ToleranceProcessor(double tolerance) {
[Link] = tolerance;
}
@Override
public Difference compare(String prop, Object oldValue, Object newValue) {
double dif = [Link](((Double) newValue) - ((Double) oldValue));
if (dif > tolerance) {
return new Difference(prop, newValue, oldValue);
}
return null;
}
}

Listing 12. The class ToleranceReader that creates the ToleranceProcessor instance.
public class ToleranceReader implements AnnotationReader<Tolerance>{
@Override
public void readAnnotation(Tolerance annotation,
PropertyDescriptor descriptor){
double tolerance = [Link]();
ToleranceProcessor processor = new ToleranceProcessor(tolerance);
[Link](processor);
}
}

Related Patterns
Metadata Processor is often used in conjunction with Metadata Reader Delegate,
allowing for the extension of the metadata schema conveying the extension of the
framework logic. Nevertheless, this pattern can also be used with a Metadata
Container with a flexible structure, where the processors are created based on the
information contained in it.
100 E. Guerra, J. de Souza, and C. Fernandes

A Metadata Processor has a structure similar to Command [17], however it is


related to a metadata piece. It is also similar to Strategy [17], since each processor can
be considered a strategy for executing one piece of metadata.
Associative Annotation [18] proposes the creation of an annotation which receives a
class as a parameter. This solution can be used to define which Metadata Processor
should the annotation be associated to. By using this solution a more general
Metadata Reader Strategy which instantiates this class should be created. It is an
alternative to the use of Metadata Reader Delegate to create the Metadata Processor.

5.2 Metadata Processing Layers


Also Known as
Metadata Processing Chain, Metadata Execution Layers

Context
Sometimes it is not possible to divide the metadata-based framework processing into
metadata pieces, specially when they need to be related. For instance, a method
metadata may contain references for other metadata elements. However, these
functionalities which need the entire Metadata Container can usually be divided into
independent framework responsibilities.
Metadata Processor proposes a structure that provides flexibility in the processing
of different metadata pieces inside the same framework responsibility. However, in
some framework domains it is important to enable the application to add new
responsibilities that uses the entire metadata schema. These new hotspots should be
more coarsely grained than the ones proposed by Metadata Processor.
In the Comparison Component there are some responsibilities in the comparison
algorithm, such as the comparison of null values, the comparison by using the
metadata processors, and the deep comparison. In the current implementation it is not
possible to insert a new kind of comparison or to change its order.

Problem
How to allow for behavior extension that uses the entire metadata schema?

Forces
• Some metadata-based frameworks execute independent tasks based on the
same metadata.
• The Metadata Processor enables extension when it is possible to separate the
logic by metadata pieces, but when the framework has more than one
responsibility it is harder to make this separation.
• The framework may have well defined responsibilities, but the application
may need to extend them using the same metadata.
• The framework can provide some functionality which needs to be enabled or
disabled depending on the application needs.
• Distinct framework responsibilities implemented in the same class may
complicate their maintenance and evolution.
Pattern Language for the Internal Structure of Metadata-Based Frameworks 101

Solution
Metadata Processing Layers proposes dividing framework responsibilities into
independent processing layers. These layers can be easily inserted and removed,
providing a hotspot which can access and process the information of the entire
Metadata Container. Consequently, this improves the framework flexibility, allowing
for the application to add more general behaviors.
In the framework processing, part of its execution should be delegated to the
Metadata Processing Layers. It is the framework responsibility to coordinate the
layers execution. For instance, depending on the framework all the layers should be
always executed or it can execute the layers until one gives an expected answer. The
framework should also provide ways to manage the existing layers and allow for the
application to configure them.

Structure
Figure 17 demonstrates the pattern structure. The FrameworkController is
composed of many processing layers with different responsibilities. The
FrameworkController is responsible for defining when the layers should be
invoked. Moreover, each ConcreteProcessingLayer can access the
information in MetadataContainer to use the metadata as the base for its logic.
The MetadataContainer instance can be retrieved in the repository by the
FrameworkController or directly by each ConcreteProcessingLayer.

«interface» * 1 FrameworkController
ProcessingLayer
+executeLayer() +execute()

access

«singleton»
MetadataContainer ConcreteProcessingLayer Repository
use

+executeLayer() access +getInstance()


+getMetadata()

Fig. 17. Structure of Metadata Processing Layers

Participants
• FrameworkController - It is the framework entry point. It is
responsible for executing the main logic and for being a controller of the
other classes. In order to do so, it contains a list of ProcessingLayer
implementations and invokes them in the right order.
• MetadataContainer - It is responsible for representing the application
class metadata needed by the framework. Each ProcessingLayer can
use it during the logic processing.
• ProcessingLayer - It is an abstraction of the classes that represent a
framework processing layer.
102 E. Guerra, J. de Souza, and C. Fernandes

• ConcreteProcessingLayer - It represents a concrete implementation


of the ProcessingLayer. It uses the MetadataContainer to execute
a part of the framework logic.
• Repository - It is responsible for managing the metadata reading and
storing internally the instances of MetadataContainer. Likewise it is a
singleton and provides metadata for FrameworkController or for each
ConcreteProcessingLayer.

Dynamics
There are two alternatives for each layer to access the metadata. The
FrameworkController can retrieve the MetadataContainer and pass it as a
parameter in each layer, as illustrated in the sequence diagram of Figure 18. The other
solution is for each layer to access the Repository separately to retrieve the
MetadataContainer, as represented in Figure 19.

:FrameworkController :Repository :ConcreteProcessingLayer container:MetadataContainer

getMetadata()

container

loop [for each processing layer]


executeLayer()

retrieve metadata

execute specific
layer logic

Fig. 18. Sequence of Metadata Processing Layers passing Metadata Container as a parameter

The use of the Repository is not mandatory, but it is particularly important


when each layer retrieves metadata independently. On the one hand, to hold an
instance of MetadataContainer to pass through the layers can complicate the
framework flow. On the other hand, to retrieve the container for every layer can
generate an overhead for locating it many times.
As an alternative, the layers can also be implemented by using Chain of
Responsibility [17]. In this implementation, each layer would be responsible for
invoking or not the next one. As a result, the FrameworkController does not
control the layers invocation and only calls the first one.
Pattern Language for the Internal Structure of Metadata-Based Frameworks 103

:FrameworkController :ConcreteProcessingLayer :Repository container:MetadataContainer

loop [for each processing layer]


executeLayer()

getMetadata()

container

retrieve metadata

execute specific
layer logic

Fig. 19. Sequence of Metadata Processing Layers accessing Repository directly

Consequences
• (+) It is possible to extend the framework functionalities by creating more
Metadata Processing Layers.
• (+) The order of layers execution can be customized by the application.
• (+) Metadata Processing Layers can be added, substituted and removed for
each framework instantiation instance, enabling different behaviors of the
framework in the same application.
• (-) The creation of layers can over-design the framework if it has a
well-defined responsibility that rarely can be extended.
• (-) The use of Metadata Processor is more complicated with processing
layers since each layer has a different responsibility to execute.

Known Uses
JBoss Application Server supports the EJB 3 specification, which defines that an
EJB container must execute many responsibilities, such as transaction management,
access control and exception handling. These functionalities are executed based on
class metadata implemented in many aspects, using JBoss AOP. In this context, each
aspect advice can be considered a processing layer.
SwingBean implements many responsibilities such as validation, form and table
creation, and customization of each graphical component. Each responsibility is
implemented in a different class, which receives a FieldDescriptor instance
with the class metadata. In this framework it is not possible to insert new layers in the
execution.
Esfinge Framework provides a layered structure that allows layers to be easily
created and inserted. Therefore, each layer can use the entity class metadata to
customize its behavior. There are layers implemented for logging, remote access,
remote notification, and access control.
104 E. Guerra, J. de Souza, and C. Fernandes

Running Example
The Comparison Component has different responsibilities in terms of comparison.
The functionality to be delegated to the layers is the comparison of object properties.
Examples of these responsibilities are the comparison of null values, the deep
comparison, and the comparison of values by using the ComparisonProcessor.
Also, the application may need to add another comparison layer for more complex
data structures such as lists, sets, maps, and trees.
Listing 13 presents the class ComparisonLayer that abstracts a comparison
processing layer for each property. The method compare() receives the values to be
compared, the list of Difference and the respective PropertyDescriptor.
This implementation was chosen to pass the metadata as a parameter, because only a
part of the class metadata is necessary. As a result, the boolean value returned by the
compare() method indicates whether the comparison had already been performed
in that layer. Each layer also receives the reference to the own
ComparisonComponent.
The ComparisonComponent class nedded to be updated to delegate the
comparison to the existing layers. It now contains an attribute named layers that
stores the list of the configured ComparisonLayer instances, which should be
provided in the constructor. Additionally, in the compare() method, the comparison
of each property uses each layer comparison until one returns true, meaning that the
comparison is already completed.

Listing 13. The ComparisonLayer abstract class.


public abstract class ComparisonLayer {
private ComparisonComponent component;
public abstract boolean compare(Object oldValue, Object newValue,
List<Difference> difs, PropertyDescriptor descProp)
throws CompareException ;
public ComparisonComponent getComponent() {
return component;
}
public void setComponent(ComparisonComponent component) {
[Link] = component;
}
}

All the comparison logic was moved to the following layer classes:
NullComparisonLayer, DeepComparisonLayer and
ValueComparisonLayer. They present the implementation of comparison layers
whose functionalities are already included in the earlier version of the Comparison
Component. Listing 14 presents the implementation of the
ValueComparisonLayer as an example of a comparison layer.

Listing 14. ValueComparisonLayer, for comparisons using the ComparisonProcessor.


public class ValueComparisonLayer extends ComparisonLayer {
@Override
public boolean compare(Object oldValue, Object newValue,
List<Difference> difs, PropertyDescriptor descProp)
Pattern Language for the Internal Structure of Metadata-Based Frameworks 105

throws CompareException {
ComparisonProcessor processor = [Link]();
Difference dif = [Link]([Link](),
oldValue, newValue);
if(dif != null)
[Link](dif);
return true;
}
}

Related Patterns
Metadata Processing Layer can be combined with Metadata Processor to extend the
framework logic in different ways. Yet, the Metadata Processor is usually used in
only one layer. The use of this pattern in conjunction with Metadata Repository is
recommended, since the metadata can be retrieved independently in each layer.
This pattern can be implemented by using the structure of the Chain of
Responsibility [17], in which one layer is responsible for invoking the next one.
Besides, in frameworks that implement crosscutting concerns, each layer can be
implemented as a different Proxy or Decorator [17]. Additionally, in aspect-oriented
frameworks, each advice can represent a layer from the same framework.

6 Related Patterns and Pattern Languages

This section presents patterns and pattern languages related to the one presented in
this paper. The following items presents how each one complements and differ from
the proposed pattern language:

• Metadata-based Frameworks are clearly related to Reflection [3], which is an


architectural pattern that proposes a mechanism for changing structure and
behavior of software systems dynamically. The additional domain-specific or
application-specific metadata which should be defined for the framework
complements the information on the meta level. The use of this metadata is
what enables the framework behavior adaptation.
• The Architectural Patterns for Metadata-based Frameworks Usage [19]
presents a collection of patterns which identifies situations where the usage
of a metadata-based framework is appropriate. For a framework developer,
the proposed pattern language and these architectural patterns are
complementary, since they provide best practices on two distinct perspectives
necessary in this kind of development. However, the pattern language can
also be considered independent of the architectural patterns, since it focuses
on the framework internal structure, metadata reading and metadata
processing, which can be done whatever the framework domain.
• The Idioms for Code Annotations in Java Language [18] presents a
collection of patterns which propose solutions about how to structure
metadata in code annotations, considering their limitations in the Java
language. These patterns are complementary to the pattern language
presented in this paper in situations where code annotations are the strategy
chosen for metadata definition. The Metadata Reading Patterns allow for the
106 E. Guerra, J. de Souza, and C. Fernandes

framework to abstract the metadata definition from the logic processing,


decoupling it from the solutions used to structure metadata in code
annotations.
• The pattern language described for Handling Application Properties [58]
provides patterns for loading and reading application properties. Although
some of these patterns can be similar to some of the Metadata Reading
Patterns, they deal with a different context. Since application properties are
configured for each application instance, there can be metadata associated
with every programming element. Consequently, metadata are more fine-
grained than application properties. Another difference is that the patterns for
application properties provide solutions for reading these properties in
different contexts, but not for extending the reading mechanism. Since this
paper pattern language is focused on frameworks, its patterns concern more
on allowing extension of the reading mechanism than in describing more
concrete solutions.
• The Pattern Language for Adaptive Object Models [11, 57, 61, 62]
documents patterns for reading the metadata and building a flexible and
adaptive object model at runtime. In this context, the metadata are used to
create the whole object model and not only a framework behavior adaptation.
Despite all of the Pattern Language for Metadata-based Frameworks known
uses reads metadata from a static class model, these patterns could also be
used on frameworks created for an adaptive object model context. On the one
hand, both pattern languages deal with metadata, but for distinct purposes.
On the other hand, they can also be complementary since a framework for an
adaptive object model would probably be based on the objects metadata.

7 Conclusion

This paper presents a Pattern Language for Metadata-based Frameworks intended


to document design best practices for this kind of framework. Many existing
frameworks employed in the development of applications apply analogous concepts
and this work can help in the development of new frameworks and in the refactoring
of existing ones.
The following are the main contributions of this work: (a) The study and analysis
of the internal structural solutions of existing open source metadata-based frameworks;
(b) The documentation of the best practices found, in the form of a pattern language
that includes solutions for the structure, metadata reading, and logic processing of
metadata-based frameworks; (c) The creation of a detailed running example that
illustrates how to refactor a metadata-based framework to implement each pattern of
the presented pattern language.
By observing the running example, Comparison Component, that was functional
before implementing any of the patterns, it is possible to verify how it became more
flexible and extensible after having used the best practices documented in the
presented pattern language. The consolidation of metadata-based frameworks design
Pattern Language for the Internal Structure of Metadata-Based Frameworks 107

knowledge is important for generating more mature solutions as to the development


of this kind of software. The metadata sharing among different frameworks, for
instance, is a hard goal to be accomplished in an architecture based on the structure of
many existing frameworks.
In this work, the design patterns are applied to the Comparison Component through
refactoring, but in real framework development, its requirements should make some
part of the code to be implemented in the first place. A suggestion for future work is
to define a methodology for the development of metadata-based frameworks that
should include not only the framework design but also activities like metadata
modeling.

Acknowledgments. The authors would like to thank all the students who worked
in the development of several metadata-based frameworks which became examples
and sources of research for this work, like Renzo, Diego, Bruno, Leandro, Gustavo,
Jorge, and Ricardo. We also thank the support of PPGAO and LAB-C2 in this
research.
Additionally, we thank the PLoP shepherd Ademar Aguiar for the hard work of
reviewing this huge pattern language and giving us feedback to improve it. We’d also
like to thank all the friends we made at PLoP, especially those who gave us precious
feedback at the writers' workshop, like Joseph Yoder, Brian Foote, Rebecca
Wirfs-Brock, and James Siddle. Finally, we thank all TPLoP reviewers, whose
observations increased the maturity of this work.

References
1. Alur, D., Malks, D., Crupi, J.: Core J2EE patterns: best practices and design strategies, 2nd
edn. Prentice Hall, Upper Saddle River (2003)
2. Bauer, C., King, G.: Hibernate in Action. Manning Publications (2004)
3. Buschmann, F., et al.: Pattern-oriented software architecture - A system of patterns. Wiley
(1996)
4. Chen, N.: Convention over configuration, [Link]
[Link]/files/[Link] (accessed on December 2010)
5. Costa, B., Figueredo, L.: Uma Arquitetura Baseada em Metadados para Integração entre
Aplicações Web e Plataformas Móveis. Technical Report, Aeronautical Institute of
Technology (2009)
6. Damyanov, I., Holmes, N.: Metadata driven code generation using .NET framework. In:
International Conference on Computer Systems and Technologies, pp. 1–6 (2004)
7. Doucet, F., Shukla, S., Gupta, R.: Introspection in system-level language frameworks:
meta-level vs. Integrated. In: Source Design, Automation and Test in Europe, pp. 382–387
(2003)
8. Ernst, M.: Type annotations specification (JSR 308), [Link]
[Link]/jsr308/specification/[Link]
9. Esfinge Framework, [Link] (accessed on July 2011)
10. Fayad, M., Schmidt, D., Johnson, R.: Application frameworks. In: Fayad, M., Schmidt, D.,
Johnson, R. (eds.) Building Application Frameworks: Object-oriented Foundations of
Frameworks Design, ch. 1, pp. 3–27. Wiley, New York (1999)
108 E. Guerra, J. de Souza, and C. Fernandes

11. Ferreira, H.: Adaptive Object-Modeling Patterns, Tools and Applications. PhD Thesis,
University of Porto, Faculty of Engineering (2010)
12. Foote, B., Yoder, J.: Evolution, architecture, and metamorphosis. In: Pattern Languages of
Program Design 2, ch. 13, pp. 295–314. Addison-Wesley Longman, Boston (1996)
13. Forman, I., Forman, N.: Java reflection in action. Manning Publ., Greenwich (2005)
14. Fowler, M.: Inversion of Control Containers and the Dependency Injection Pattern (2004),
[Link]
(accessed on December 2010)
15. Fowler, M.: Patterns of enterprise application architecture. Addison-Wesley Professional,
Boston (2002)
16. Fowler, M.: Using metadata. IEEE Software 19(6), 13–17 (2002)
17. Gamma, E., Helm, R., Johnson, R., Vlissides, J.: Design Patterns: Elements of Reusable
Object-Oriented Software. Addison-Wesley (1994)
18. Guerra, E., Cardoso, M., Silva, J., Fernandes, C.: Idioms for Code Annotations in Java
Language. In: Proceedings of 8a Latin American Conference on Pattern Languages of
Programming, SugarLoafPLoP 2010, Salvador (2010)
19. Guerra, E., Fernandes, C., Silveira, F.: Architectural Patterns for Metadata-based
Frameworks Usage. In: Conference on Patterns Languages of Programs, Reno, vol. 17 (2010)
20. Guerra, E., Fernandes, C.: A Metadata-Based Components Model. In: Proceedings of
Doctoral Symposium at 22nd European Conference on Object Oriented Programming,
ECOOP 2008, Paphos (2008)
21. Guerra, E., Parente, J., Fernandes, C.: Mapeando Objetos para Entidades de uma Ontologia
Utilizando Metadados. In: Proceedings of SIGE - Defense Operational Applications
Symposium, São José dos Campos (2008)
22. Guerra, E., Pavão, F., Fernandes, C.: Padrões de Projeto para Frameworks e Componentes
Baseados em Metadados. In: Proceedings of 7a Latin American Conference on Pattern
Languages of Programming, SugarLoafPLoP 2008, Fortaleza (2008)
23. Guerra, E., Silva, J., Silveira, F., Fernandes, C.: Using Metadata in Aspect-Oriented Frame-
works. In: Proceedings of 2nd Workshop on Assessment of Contemporary Modularization
Techniques, AcoM 2008, Nashville (2008)
24. Hibernate Validator, [Link]
(accessed on July 2011)
25. Hispagnol, G.: Modelo multidimensional unificado: integrando domínios OLAP e OLTP.
Technical Report, Aeronautical Institute of Technology (2009)
26. Hot Comments (2011), [Link]
(accessed on July 2011)
27. Hunt, A., Thomas, D., Hargett, M.: Pragmatic Unit Testing in C# with NUnit, 2nd edn.
Pragmatic Bookshelf (2007)
28. JavaBeans(TM) specification 1.01 Final release, [Link]
technologies/desktop/javabeans/docs/[Link]
(accessed on December 2010)
29. JAX-RS: The JavaTM API for RESTful Web Services, [Link]
jsr/detail?id=311 (accessed on July 2011)
30. JBoss Application Server, [Link]
(accessed on December 2010)
31. JColtrane – Better than SAX Alone, [Link]
(accessed on December 2010)
32. Johnson, R., Foote, B.: Designing reusable classes. Journal Of Object-Oriented
Programming 1(2), 22–35 (1988)
Pattern Language for the Internal Structure of Metadata-Based Frameworks 109

33. JSR 175: A Metadata Facility for the Java Programming Language,
[Link] (accessed on December 2010)
34. JSR 220: Enterprise JavaBeans 3.0,
[Link]
35. JSR 222: Java Architecture for XML Binding (JAXB),
[Link] (accessed on December 2010)
36. JSR 299: Contexts and Dependency Injection for the JavaTM EE platform,
[Link] (accessed on July 2011)
37. JSR 303: Bean Validation, [Link]
(accessed on December 2010)
38. JSR 314: JavaServerTM Faces 2.0,
[Link] (accessed on July 2011)
39. Kuaté, P., Bauer, C., King, G., Harris, T.: NHibernate in Action. Manning Publications
(2009)
40. Massol, V., Husted, T.: JUnit in action. Manning Publ., Greenwich (2003)
41. Miller, J.: Common Language Infrastructure Annotated Standard. Addison-Wesley,
Boston (2003)
42. Nardon, F., Silva, E.: Implementing Java EE applications, using enterprise javabeans
(EJB) 3 technology: real-world tips, tricks, and new design patterns, Session TS-4721
(2007), [Link]
pdf/[Link] (accessed on December 2009)
43. Newkirk, J., Vorontsov, A.A.: How .NET’s Custom Attributes Affect Design. IEEE
Software 19, 18–20 (2002)
44. Noble, J.: Classifying Relationships between Object-Oriented Design Patterns. In:
Proceedings of the Australian Software Engineering Conference 1998, ASWEC 1998,
Adelaide, Australia, pp. 98–109 (1998)
45. Nock, C.: Data Access Patterns: Database Interactions in Object-Oriented Applications.
Addison-Wesley Professional (2003)
46. Pree, W.: Hot-spot-driven development. In: Fayad, M., Schmidt, D., Johnson, R. (eds.)
Building Application Frameworks: Object-oriented Foundations of Frameworks Design,
ch. 16, pp. 379–393. Wiley, New York (1999)
47. Project Lombok, [Link] (accessed on July 2011)
48. Quinonez, J., Tschantz, M.S., Ernst, M.D.: Inference of reference immutability. In:
Vitek, J. (ed.) ECOOP 2008. LNCS, vol. 5142, pp. 616–641. Springer, Heidelberg (2008)
49. Ruby, S., et al.: Agile Web Development with Rails. Pragmatic Bookshelf (2009)
50. SAX Project, [Link] (accessed on December 2010)
51. Schwarz, D.: Peeking inside the box: attribute-oriented programming with Java 1.5,
[Link]
[Link] (accessed on December 2010)
52. Silva, J., Okura, R.: Um Modelo para Compartilhamento de Metadados entre Frameworks.
Technical Report, Aeronautical Institute of Technology (2009)
53. SwingBean, [Link] (accessed on December 2010)
54. Tansey, W., Tilevich, E.: Annotation Refactoring: Inferring Upgrade Transformations for
Legacy Applications. In: The International Conference on Object Oriented Programming,
Systems, Languages and Applications, OOPSLA 2008, Nashville (2008)
55. Wada, H., Suzuki, J.: Modeling Turnpike Frontend System: a Model-Driven Development
Framework Leveraging UML Metamodeling and Attribute-Oriented Programming. In:
Proceedings of the 8th ACM/IEEE International Conference on Model Driven Engineering
Languages and Sytems, MoDELS/UML (2005)
110 E. Guerra, J. de Souza, and C. Fernandes

56. Walls, C., Richards, N., Oberg, R.: XDoclet in Action. Manning Publications (2003)
57. Welicki, L., Yoder, J., Wirfs-Brock, R., Johnson, R.: Towards a Pattern Language for
Adaptive Object-Models. In: Companion of the 22st ACM SIGPLAN Object Oriented
Programming Systems, Languages, and Applications, OOPSLA 2007, Montreal (2007)
58. Wellhausen, T., Wagner, M., Müller, G.: Handling Application Properties - Simplify
Application Customization in Different. In: 14th European Conference on Pattern
Languages of Programs, EuroPLoP 2009, Bavaria (2009)
59. Wirfs-Brock, R., Johnson, R.: Surveying current research in object-oriented design.
Communications Of The ACM 33(9), 104–124 (1990)
60. XapMap - Cross Application Mapping Framework, [Link]
(accessed on December 2010)
61. Yoder, J., Foote, B.: Metadata and Active Object-Models. In: Fifth Conference on Patterns
Languages of Programs, PLoP 1998, Monticello (1998)
62. Yoder, J., Johnson, R.: The Adaptive Object-Model Architectural Style. In: IEEE/IFIP
Conference on Software Architecture: System Design, Development and Maintenance,
vol. 3, pp. 3–27 (2002)

You might also like