* Remove jpacontainer section from the docs.tags/8.0.0.beta1
@@ -42,13 +42,6 @@ domain layer, offering the domain logic as a service, which can be used by the | |||
user interface layer, as well as for other uses. In Java EE development, | |||
Enterprise JavaBeans (EJBs) are typically used for building this layer. | |||
An __infrastructure layer__ (or __data access layer__) is often distinguished | |||
from the data store layer, with a purpose to abstract the data store. For | |||
example, it could involve a persistence solution such as JPA and an EJB | |||
container. This layer becomes relevant with Vaadin when binding Vaadin | |||
components to data with the JPAContainer, as described in | |||
<<dummy/../../../framework/jpacontainer/jpacontainer-overview.asciidoc#jpacontainer.overview,"Vaadin | |||
JPAContainer">>. | |||
[[advanced.architecture.mvp]] |
@@ -7,6 +7,8 @@ layout: page | |||
[[components.calendar]] | |||
= [classname]#Calendar# | |||
*_This section has not yet been updated for Vaadin Framework 8._* | |||
ifdef::web[] | |||
[.sampler] | |||
image:{live-demo-image}[alt="Live Demo", link="http://demo.vaadin.com/sampler/#ui/data-input/dates/dates-calendar"] |
@@ -1,25 +0,0 @@ | |||
[[jpacontainer]] | |||
== Vaadin JPAContainer | |||
((("JPAContainer", id="term.jpacontainer", range="startofrange"))) | |||
This chapter describes the use of the Vaadin JPAContainer add-on. | |||
include::jpacontainer-overview.asciidoc[leveloffset=+2] | |||
include::jpacontainer-installation.asciidoc[leveloffset=+2] | |||
include::jpacontainer-domain-model.asciidoc[leveloffset=+2] | |||
include::jpacontainer-usage.asciidoc[leveloffset=+2] | |||
include::jpacontainer-entityprovider.asciidoc[leveloffset=+2] | |||
include::jpacontainer-filtering.asciidoc[leveloffset=+2] | |||
include::jpacontainer-filtering-criteria-api.asciidoc[leveloffset=+2] | |||
include::jpacontainer-fieldfactory.asciidoc[leveloffset=+2] | |||
include::jpacontainer-hibernate.asciidoc[leveloffset=+2] | |||
(((range="endofrange", startref="term.jpacontainer"))) |
@@ -1,265 +0,0 @@ | |||
--- | |||
title: Defining a Domain Model | |||
order: 3 | |||
layout: page | |||
--- | |||
[[jpacontainer.domain-model]] | |||
= Defining a Domain Model | |||
Developing a persistent application begins with defining a domain model. A | |||
domain model consists of a number of entities (classes) and relationships | |||
between them. | |||
<<figure.jpacontainer.domain-model>> illustrates a simple domain model as a UML | |||
class diagram. It has two entities: [classname]#Country# and | |||
[classname]#Person#. They have a "country has persons" relationship. This is a | |||
__one-to-many relationship__ with one country having many persons, each of which | |||
belongs to just one country. | |||
[[figure.jpacontainer.domain-model]] | |||
.A Domain Model | |||
image::img/domain-model-hi.png[] | |||
Realized in Java, the classes are as follows: | |||
---- | |||
public class Country { | |||
private Long id; | |||
private String name; | |||
private Set<Person> persons; | |||
... setters and getters ... | |||
} | |||
public class Person { | |||
private Long id; | |||
private String name; | |||
private Integer age; | |||
private Country country; | |||
... setters and getters ... | |||
} | |||
---- | |||
You should make the classes proper beans by defining a default constructor and | |||
implementing the [interfacename]#Serializable# interface. A default constructor | |||
is required by the JPA entity manager for instantiating entities. Having the | |||
classes serializable is not required but often useful for other reasons. | |||
After you have a basic domain model, you need to define the entity relationship | |||
metadata by annotating the classes. | |||
[[jpacontainer.domain-model.annotation]] | |||
== Persistence Metadata | |||
The entity relationships are defined with metadata. The metadata can be defined | |||
in an XML metadata file or with Java annotations defined in the | |||
[package]#javax.persistence# package. With Vaadin JPAContainer, you need to | |||
provide the metadata as annotations. | |||
For example, if we look at the Person class in the JPAContainer AddressBook | |||
Demo, we define various database-related metadata for the member variables of a | |||
class: | |||
---- | |||
@Entity | |||
public class Person { | |||
@Id | |||
@GeneratedValue(strategy = GenerationType.AUTO) | |||
private Long id; | |||
private String name; | |||
private Integer age; | |||
@ManyToOne | |||
private Country country; | |||
---- | |||
The JPA implementation uses reflection to read the annotations and defines a | |||
database model automatically from the class definitions. | |||
Let us look at some of the basic JPA metadata annotations. The annotations are | |||
defined in the [package]#javax.persistence# package. Please refer to JPA | |||
reference documentation for the complete list of possible annotations. | |||
[[jpacontainer.domain-model.metadata.entity]] | |||
=== Annotation: [literal]#++@Entity++# | |||
Each class that is enabled as a persistent entity must have the | |||
[literal]#++@Entity++# annotation. | |||
---- | |||
@Entity | |||
public class Country { | |||
---- | |||
[[jpacontainer.domain-model.annotation.id]] | |||
=== Annotation: [literal]#++@Id++# | |||
Entities must have an identifier that is used as the primary key for the table. | |||
It is used for various purposes in database queries, most commonly for joining | |||
tables. | |||
---- | |||
@Id | |||
@GeneratedValue(strategy = GenerationType.AUTO) | |||
private Long id; | |||
---- | |||
The identifier is generated automatically in the database. The strategy for | |||
generating the identifier is defined with the [literal]#++@GeneratedValue++# | |||
annotation. Any generation type should work. | |||
[[jpacontainer.domain-model.annotation.onetoone]] | |||
=== Annotation: [literal]#++@OneToOne++# | |||
The [literal]#++@OneToOne++# annotation describes a one-to-one relationship | |||
where each entity of one type is associated with exactly one entity of another | |||
type. For example, the postal address of a person could be given as such. | |||
---- | |||
@OneToOne | |||
private Address address; | |||
---- | |||
When using the JPAContainer [classname]#FieldFactory# to automatically create | |||
fields for a form, the [literal]#++@OneToOne++# relationship generates a nested | |||
[classname]#Form# to edit the data. See | |||
<<dummy/../../../framework/jpacontainer/jpacontainer-fieldfactory#jpacontainer.fieldfactory,"Automatic | |||
Form Generation">> for more details. | |||
[[jpacontainer.domain-model.annotation.embedded]] | |||
=== Annotation: [literal]#++@Embedded++# | |||
Just as with the [literal]#++@OneToOne++# annotation, [literal]#++@Embedded++# | |||
describes a one-to-one relationship, but says that the referenced entity should | |||
be stored as columns in the same table as the referencing entity. | |||
---- | |||
@Embedded | |||
private Address address; | |||
---- | |||
The referenced entity class must have [literal]#++@Embeddable++# annotation. | |||
The JPAContainer [classname]#FieldFactory# generates a nested [classname]#Form# | |||
for [literal]#++@Embedded++#, just as with [literal]#++@OneToOne++#. | |||
[[jpacontainer.domain-model.annotation.onetomany]] | |||
=== Annotation: [literal]#++@OneToMany++# | |||
The [classname]#Country# entity in the domain model has a __one-to-many__ | |||
relationship with the [classname]#Person# entity ("country has persons"). This | |||
relationship is represented with the [literal]#++@OneToMany++# annotation. The | |||
[parameter]#mappedBy# parameter names the corresponding back-reference in the | |||
[classname]#Person# entity. | |||
---- | |||
@OneToMany(mappedBy = "country") | |||
private Set<Person> persons; | |||
---- | |||
When using the JPAContainer [classname]#FieldFactory# to automatically create | |||
fields for a form, the [literal]#++@OneToMany++# relationship generates a | |||
[classname]#MasterDetailEditor# for editing the items. See | |||
<<dummy/../../../framework/jpacontainer/jpacontainer-fieldfactory#jpacontainer.fieldfactory,"Automatic | |||
Form Generation">> for more details. | |||
[[jpacontainer.domain-model.annotation.elementcollection]] | |||
=== Annotation: [literal]#++@ElementCollection++# | |||
The [literal]#++@ElementCollection++# annotation can be used for one-to-many | |||
relationships to a collection of basic values such as [classname]#String# or | |||
[classname]#Integer#, or to entities annotated as [literal]#++@Embeddable++#. | |||
The referenced entities are stored in a separate table defined with a | |||
[literal]#++@CollectionTable++# annotation. | |||
---- | |||
@ElementCollection | |||
@CollectionTable( | |||
name="OLDPEOPLE", | |||
joinColumns=@JoinColumn(name="COUNTRY_ID")) | |||
private Set<Person> persons; | |||
---- | |||
JPAContainer [classname]#FieldFactory# generates a | |||
[classname]#MasterDetailEditor# for the [literal]#++@ElementCollection++# | |||
relationship, just as with [literal]#++@OneToMany++#. | |||
[[jpacontainer.domain-model.annotation.manytoone]] | |||
=== Annotation: [literal]#++@ManyToOne++# | |||
Many people can live in the same country. This would be represented with the | |||
[literal]#++@ManyToOne++# annotation in the [classname]#Person# class. | |||
---- | |||
@ManyToOne | |||
private Country country; | |||
---- | |||
JPAContainer [classname]#FieldFactory# generates a [classname]#NativeSelect# for | |||
selecting an item from the collection. You can do so yourself as well in a | |||
custom field factory. Doing so you need to pay notice not to confuse the | |||
container between the referenced entity and its ID, which could even result in | |||
insertion of false entities in the database in some cases. You can handle | |||
conversion between an entity and the entity ID using the | |||
[classname]#SingleSelectConverter# as follows: | |||
---- | |||
@Override | |||
public <T extends Field> T createField(Class<?> dataType, | |||
Class<T> fieldType) { | |||
if (dataType == Country.class) { | |||
JPAContainer<Country> countries = | |||
JPAContainerFactory.make(Country.class, "mypunit"); | |||
ComboBox cb = new ComboBox(null, countries); | |||
cb.setConverter(new SingleSelectConverter<Country>(cb)); | |||
return (T) cb; | |||
} | |||
return super.createField(dataType, fieldType); | |||
} | |||
---- | |||
The JPAContainer [classname]#FieldFactory# uses the translator internally, so | |||
using it also avoids the problem. | |||
[[jpacontainer.domain-model.annotation.transient]] | |||
=== Annotation: [literal]#++@Transient++# | |||
JPA assumes that all entity properties are persisted. Properties that should not | |||
be persisted should be marked as transient with the [literal]#++@Transient++# | |||
annotation. | |||
---- | |||
@Transient | |||
private Boolean superDepartment; | |||
... | |||
@Transient | |||
public String getHierarchicalName() { | |||
... | |||
---- | |||
@@ -1,225 +0,0 @@ | |||
--- | |||
title: Entity Providers | |||
order: 5 | |||
layout: page | |||
--- | |||
[[jpacontainer.entityprovider]] | |||
= Entity Providers | |||
Entity providers provide access to entities persisted in a data store. They are | |||
essentially wrappers over a JPA entity manager, adding optimizations and other | |||
features important when binding persistent data to a user interface. | |||
The choice and use of entity providers is largely invisible if you create your | |||
[classname]#JPAContainer# instances with the [classname]#JPAContainerFactory#, | |||
which hides such details. | |||
JPAContainer entity providers can be customized, which is necessary for some | |||
purposes. Entity providers can be Enterprise JavaBeans (EJBs), which is useful | |||
when you use them in a Java EE application server. | |||
[[jpacontainer.entityprovider.built-in]] | |||
== Built-In Entity Providers | |||
JPAContainer includes various kinds of built-in entity providers: caching and | |||
non-caching, read-write and read-only, and batchable. | |||
__Caching__ is useful for performance, but takes some memory for the cache and | |||
makes the provider stateful. __Batching__, that is, running updates in larger | |||
batches, can also enhance performance and be used together with caching. It is | |||
stateless, but doing updates is a bit more complex than otherwise. | |||
Using a __read-only__ container is preferable if read-write capability is not | |||
needed. | |||
All built-in providers are __local__ in the sense that they provide access to | |||
entities using a local JPA entity manager. | |||
The [classname]#CachingMutableLocalEntityProvider# is usually recommended as the | |||
first choise for read-write access and [classname]#CachingLocalEntityProvider# | |||
for read-only access. | |||
=== [classname]#LocalEntityProvider# | |||
A read-only, lazy loading entity provider that does not perform caching and | |||
reads its data directly from an entity manager. | |||
You can create the provider with [methodname]#makeNonCachedReadOnly()# method in | |||
[classname]#JPAContainerFactory#. | |||
=== [classname]#MutableLocalEntityProvider# | |||
Extends [classname]#LocalEntityProvider# with write support. All changes are | |||
directly sent to the entity manager. | |||
Transactions can be handled either internally by the provider, which is the | |||
default, or by the container. In the latter case, you can extend the class and | |||
annotate it, for example, as described in | |||
<<jpacontainer.entityprovider.built-in>>. | |||
The provider can notify about updates to entities through the | |||
[interfacename]#EntityProviderChangeNotifier# interface. | |||
=== [classname]#BatchableLocalEntityProvider# | |||
A simple non-caching implementation of the | |||
[interfacename]#BatchableEntityProvider# interface. It extends | |||
[classname]#MutableLocalEntityProvider# and simply passes itself to the | |||
[methodname]#batchUpdate()# callback method. This will work properly if the | |||
entities do not contain any references to other entities that are managed by the | |||
same container. | |||
=== [classname]#CachingLocalEntityProvider# | |||
A read-only, lazy loading entity provider that caches both entities and query | |||
results for different filter/sortBy combinations. When the cache gets full, the | |||
oldest entries in the cache are removed. The maximum number of entities and | |||
entity IDs to cache for each filter/sortBy combination can be configured in the | |||
provider. The cache can also be manually flushed. When the cache grows full, the | |||
oldest items are removed. | |||
You can create the provider with [methodname]#makeReadOnly()# method in | |||
[classname]#JPAContainerFactory#. | |||
=== [classname]#CachingMutableLocalEntityProvider# | |||
Just like [classname]#CachingLocalEntityProvider#, but with read-write access. | |||
For read access, caching works just like in the read-only provider. When an | |||
entity is added or updated, the cache is flushed in order to make sure the added | |||
or updated entity shows up correctly when using filters and/or sorting. When an | |||
entity is removed, only the filter/sortBy-caches that actually contain the item | |||
are flushed. | |||
This is perhaps the most commonly entity provider that you should consider using | |||
for most tasks. You can create it with the [methodname]#make()# method in | |||
[classname]#JPAContainerFactory#. | |||
=== [classname]#CachingBatchableLocalEntityProvider# | |||
This provider supports making updates in __batches__. You need to implement a | |||
[interfacename]#BatchUpdateCallback# that does all the updates and execute the | |||
batch by calling [methodname]#batchUpdate()# on the provider. | |||
The provider is an extension of the | |||
[classname]#CachingMutableLocalEntityProvider# that implements the | |||
[interfacename]#BatchableEntityProvider# interface. This will work properly if | |||
the entities do not contain any references to other entities that are managed by | |||
the same container. | |||
You can create the provider with [methodname]#makeBatchable()# method in | |||
[classname]#JPAContainerFactory#. | |||
[[jpacontainer.entityprovider.jndi]] | |||
== Using JNDI Entity Providers in JEE6 Environment | |||
JPAContainer 2.0 introduced a new set of entity providers specifically for | |||
working in a [literal]#++JEE6++# environment. In a JEE environment, you should | |||
use an entity manager provided by the application server and, usually, | |||
[literal]#++JTA++# transactions instead of transactions provided by JPA. Entity | |||
providers in [package]#com.vaadin.addon.jpacontainer.provider.jndijta# package | |||
work mostly the same way as the normal providers discussed earlier, but use JNDI | |||
lookups to get reference to an [interfacename]#EntityManager# and to a JTA | |||
transaction. | |||
The JNDI providers work with almost no special configuration at all. The | |||
[classname]#JPAContainerFactory# has factory methods for creating various JNDI | |||
provider types. The only thing that you commonly need to do is to expose the | |||
[interfacename]#EntityManager# to a JNDI address. By default, the JNDI providers | |||
look for the [interfacename]#EntityManager# from " | |||
java:comp/env/persistence/em". This can be done with the following snippet in | |||
[filename]#web.xml# or with similar configuration with annotations. | |||
---- | |||
<persistence-context-ref> | |||
<persistence-context-ref-name> | |||
persistence/em | |||
</persistence-context-ref-name> | |||
<persistence-unit-name>MYPU</persistence-unit-name> | |||
</persistence-context-ref> | |||
---- | |||
The " [literal]#++MYPU++#" is the identifier of your persistence unit defined in | |||
your [filename]#persistence.xml# file. | |||
If you choose to annotate your servlets (instead of using the | |||
[filename]#web.xml# file as described above), you can simply add the following | |||
annotation to your servlet. | |||
---- | |||
@PersistenceContext(name="persistence/em",unitName="MYPU") | |||
---- | |||
If you wish to use another address for the persistence context, you can define | |||
them with the [methodname]#setJndiAddresses()# method. You can also define the | |||
location for the JTA [classname]#UserTransaction#, but that should be always | |||
accessible from " java:comp/UserTransaction" by the JEE6 specification. | |||
[[jpacontainer.entityprovider.ejb]] | |||
== Entity Providers as Enterprise Beans | |||
Entity providers can be Enterprise JavaBeans (EJB). This may be useful if you | |||
use JPAContainer in a Java EE application server. In such case, you need to | |||
implement a custom entity provider that allows the server to inject the entity | |||
manager. | |||
For example, if you need to use Java Transaction API (JTA) for JPA transactions, | |||
you can implement such entity provider as follows. Just extend a built-in entity | |||
provider of your choise and annotate the entity manager member as | |||
[literal]#++@PersistenceContext++#. Entity providers can be either stateless or | |||
stateful session beans. If you extend a caching entity provider, it has to be | |||
stateful. | |||
---- | |||
@Stateless | |||
@TransactionManagement | |||
public class MyEntityProviderBean extends | |||
MutableLocalEntityProvider<MyEntity> { | |||
@PersistenceContext | |||
private EntityManager em; | |||
protected LocalEntityProviderBean() { | |||
super(MyEntity.class); | |||
setTransactionsHandledByProvider(false); | |||
} | |||
@Override | |||
@TransactionAttribute(TransactionAttributeType.REQUIRED) | |||
protected void runInTransaction(Runnable operation) { | |||
super.runInTransaction(operation); | |||
} | |||
@PostConstruct | |||
public void init() { | |||
setEntityManager(em); | |||
/* | |||
* The entity manager is transaction-scoped, which means | |||
* that the entities will be automatically detached when | |||
* the transaction is closed. Therefore, we do not need | |||
* to explicitly detach them. | |||
*/ | |||
setEntitiesDetached(false); | |||
} | |||
} | |||
---- | |||
If you have more than one EJB provider, you might want to create an abstract | |||
super class of the above and only define the entity type in implementations. You | |||
can implement an entity provider as a managed bean in Spring Framefork the same | |||
way. | |||
@@ -1,151 +0,0 @@ | |||
--- | |||
title: Automatic Form Generation | |||
order: 8 | |||
layout: page | |||
--- | |||
[[jpacontainer.fieldfactory]] | |||
= Automatic Form Generation | |||
The JPAContainer [classname]#FieldFactory# is an implementation of the | |||
[interfacename]#FormFieldFactory# and [interfacename]#TableFieldFactory# | |||
interfaces that can generate fields based on JPA annotations in a POJO. It goes | |||
further than the [classname]#DefaultFieldFactory#, which only creates simple | |||
fields for the basic data types. This way, you can easily create forms to input | |||
entities or enable editing in tables. | |||
The generated defaults are as follows: | |||
[options="header"] | |||
|=============== | |||
|Annotation|Class Mapping | |||
|[literal]#++@ManyToOne++#|[classname]#NativeSelect# | |||
|[literal]#++@OneToOne++#, [literal]#++@Embedded++#|Nested [classname]#Form# | |||
|[literal]#++@OneToMany++#, [literal]#++@ElementCollection++#|[classname]#MasterDetailEditor# (see below) | |||
|[literal]#++@ManyToMany++#|Selectable [classname]#Table# | |||
|=============== | |||
The field factory is recursive, so that you can edit a complex object tree with one form. | |||
[[jpacontainer.fieldfactory.configuring]] | |||
== Configuring the Field Factory | |||
The [classname]#FieldFactory# is highly configurable with various configuration settings and by extending. | |||
// You need to make the configuration before ... | |||
The [methodname]#setMultiSelectType()# and [methodname]#setSingleSelectType()# | |||
allow you to specify a selection component that is used instead of the default | |||
for a field with [literal]#++@ManyToMany++# and [literal]#++@ManyToOne++# | |||
annotation, respectively. The first parameter is the class type of the field, | |||
and the second parameter is the class type of a selection component. It must be | |||
a sub-class of [classname]#AbstractSelect#. | |||
The [methodname]#setVisibleProperties()# controls which properties (fields) are | |||
visible in generated forms, subforms, and tables. The first paramater is the | |||
class type for which the setting should be made, followed by the IDs of the | |||
visible properties. | |||
The configuration should be done before binding the form to a data source as | |||
that is when the field generation is done. | |||
Further configuration must be done by extending the many protected methods. | |||
Please see the API documentation for the complete list. | |||
[[jpacontainer.fieldfactory.using]] | |||
== Using the Field Factory | |||
The most basic use case for the JPAContainer [classname]#FieldFactory# is with a | |||
[classname]#Form# bound to a container item: | |||
---- | |||
// Have a persistent container | |||
final JPAContainer<Country> countries = | |||
JPAContainerFactory.make(Country.class, "book-examples"); | |||
// For selecting an item to edit | |||
final ComboBox countrySelect = | |||
new ComboBox("Select a Country", countries); | |||
countrySelect.setItemCaptionMode(Select.ITEM_CAPTION_MODE_PROPERTY); | |||
countrySelect.setItemCaptionPropertyId("name"); | |||
// Country Editor | |||
final Form countryForm = new Form(); | |||
countryForm.setCaption("Country Editor"); | |||
countryForm.addStyleName("bordered"); // Custom style | |||
countryForm.setWidth("420px"); | |||
countryForm.setBuffered(true); | |||
countryForm.setEnabled(false); | |||
// When an item is selected from the list... | |||
countrySelect.addValueChangeListener(new ValueChangeListener(){ | |||
@Override | |||
public void valueChange(ValueChangeEvent event) { | |||
// Get the item to edit in the form | |||
Item countryItem = | |||
countries.getItem(event.getProperty().getValue()); | |||
// Use a JPAContainer field factory | |||
// - no configuration is needed here | |||
final FieldFactory fieldFactory = new FieldFactory(); | |||
countryForm.setFormFieldFactory(fieldFactory); | |||
// Edit the item in the form | |||
countryForm.setItemDataSource(countryItem); | |||
countryForm.setEnabled(true); | |||
// Handle saves on the form | |||
final Button save = new Button("Save"); | |||
countryForm.getFooter().removeAllComponents(); | |||
countryForm.getFooter().addComponent(save); | |||
save.addClickListener(new ClickListener() { | |||
@Override | |||
public void buttonClick(ClickEvent event) { | |||
try { | |||
countryForm.commit(); | |||
countryForm.setEnabled(false); | |||
} catch (InvalidValueException e) { | |||
} | |||
} | |||
}); | |||
} | |||
}); | |||
countrySelect.setImmediate(true); | |||
countrySelect.setNullSelectionAllowed(false); | |||
---- | |||
See the http://demo.vaadin.com/book-examples-vaadin7/book#jpacontainer.fieldfactory.formonetoone[on-line example, window="_blank"]. | |||
This would create a form shown in <<figure.jpacontainer.fieldfactory.using>>. | |||
[[figure.jpacontainer.fieldfactory.using]] | |||
.Using FieldFactory with One-to-Many Relationship | |||
image::img/fieldfactory-form.png[] | |||
If you use Hibernate, you also need to pass an | |||
[classname]#EntityManagerPerRequestHelper#, either for the constructor or with | |||
[methodname]#setEntityManagerPerRequestHelper()# | |||
ifdef::web[] | |||
, as described in | |||
<<dummy/../../../framework/jpacontainer/jpacontainer-hibernate#jpacontainer.hibernate.em-per-request,"The | |||
EntityManager-Per-Request | |||
pattern">> | |||
endif::web[] | |||
. | |||
[[jpacontainer.fieldfactory.masterdetaileditor]] | |||
== Master-Detail Editor | |||
The [classname]#MasterDetailEditor# is a field component that allows editing an | |||
item property that has one-to-many relationship. The item can be a row in a | |||
table or bound to a form. It displays the referenced collection as an editable | |||
[classname]#Table# and allows adding and removing items in it. | |||
You can use the [classname]#MasterDetailEditor# manually, or perhaps more | |||
commonly use a JPAContainer [classname]#FieldFactory# to create it | |||
automatically. As shown in the example in | |||
<<figure.jpacontainer.fieldfactory.using>>, the factory creates a | |||
[classname]#MasterDetailEditor# for all properties with a | |||
[literal]#++@OneToMany++# or an [literal]#++@ElementCollection++# annotation. |
@@ -1,95 +0,0 @@ | |||
--- | |||
title: Querying with the Criteria API | |||
order: 7 | |||
layout: page | |||
--- | |||
[[jpacontainer.filtering.criteria-api]] | |||
= Querying with the Criteria API | |||
When the [interfacename]#Filterable# API is not enough and you need to have more | |||
control, you can make queries directly with the JPA Criteria API. You may also | |||
need to customize sorting or joins, or otherwise modify the query in some way. | |||
To do so, you need to implement a [interfacename]#QueryModifierDelegate# that | |||
the JPAContainer entity provider calls when making a query. The easiest way to | |||
do this is to extend [classname]#DefaultQueryModifierDelegate#, which has empty | |||
implementations of all the methods so that you can only override the ones you | |||
need. | |||
The entity provider calls specific [interfacename]#QueryModifierDelegate# | |||
methods at different stages while making a query. The stages are: | |||
. Start building a query | |||
. Add " [literal]#++ORDER BY++#" expression | |||
. Add " [literal]#++WHERE++#" expression (filter) | |||
. Finish building a query | |||
Methods where you can modify the query are called before and after each stage as | |||
listed in the following table: | |||
[[table.jpacontainer.filtering.criteria-api.methods]] | |||
.[classname]#QueryModifierDelegate# Methods | |||
|=============== | |||
|[methodname]#queryWillBeBuilt()# | |||
|[methodname]#orderByWillBeAdded()# | |||
|[methodname]#orderByWasAdded()# | |||
|[methodname]#filtersWillBeAdded()# | |||
|[methodname]#filtersWereAdded()# | |||
|[methodname]#queryHasBeenBuilt()# | |||
|=============== | |||
All the methods get two parameters. The [interfacename]#CriteriaBuilder# is a | |||
builder that you can use to build queries. The [interfacename]#CriteriaQuery# is | |||
the query being built. | |||
You can use the [methodname]#getRoots().iterator().next()# in | |||
[interfacename]#CriteriaQuery# to get the "root" that is queried, for example, | |||
the [literal]#++PERSON++# table, etc. | |||
[[jpacontainer.filtering.criteria-api.filters]] | |||
== Filtering the Query | |||
Let us consider a case where we modify the query for a [classname]#Person# | |||
container so that it includes only people over 116. This trivial example is | |||
identical to the one given earlier using the [classname]#Filterable# interface. | |||
---- | |||
persons.getEntityProvider().setQueryModifierDelegate( | |||
new DefaultQueryModifierDelegate () { | |||
@Override | |||
public void filtersWillBeAdded( | |||
CriteriaBuilder criteriaBuilder, | |||
CriteriaQuery<?> query, | |||
List<Predicate> predicates) { | |||
Root<?> fromPerson = query.getRoots().iterator().next(); | |||
// Add a "WHERE age > 116" expression | |||
Path<Integer> age = fromPerson.<Integer>get("age"); | |||
predicates.add(criteriaBuilder.gt(age, 116)); | |||
} | |||
}); | |||
---- | |||
See the http://demo.vaadin.com/book-examples-vaadin7/book#jpacontainer.criteria.querymodification[on-line example, window="_blank"]. | |||
[[jpacontainer.filtering.criteria-api.compatibility]] | |||
== Compatibility | |||
When building queries, you should consider the capabilities of the different JPA | |||
implementations. Regarding Hibernate, see | |||
<<dummy/../../../framework/jpacontainer/jpacontainer-hibernate#jpacontainer.hibernate.joins,"Joins | |||
in Hibernate vs EclipseLink">>. | |||
@@ -1,45 +0,0 @@ | |||
--- | |||
title: Filtering JPAContainer | |||
order: 6 | |||
layout: page | |||
--- | |||
[[jpacontainer.filtering]] | |||
= Filtering [classname]#JPAContainer# | |||
Normally, a [classname]#JPAContainer# contains all instances of a particular | |||
entity type in the persistence context. Hence, it is equivalent to a database | |||
table or query. Just like with database queries, you often want to narrow the | |||
results down. [classname]#JPAContainer# implements the | |||
[interfacename]#Filterable# interface in Vaadin containers, described in | |||
<<dummy/../../../framework/datamodel/datamodel-container#datamodel.container.filtered,"Filterable | |||
Containers">>. All filtering is done at the database level with queries, not in | |||
the container. | |||
For example, let us filter all the people older than 117: | |||
---- | |||
Filter filter = new Compare.Greater("age", 117); | |||
persons.addContainerFilter(filter); | |||
---- | |||
See the http://demo.vaadin.com/book-examples-vaadin7/book#jpacontainer.filtering.basic[on-line example, window="_blank"]. | |||
This would create a JPQL query somewhat as follows: | |||
---- | |||
SELECT id FROM Person WHERE (AGE > 117) | |||
---- | |||
See the http://demo.vaadin.com/book-examples-vaadin7/book#jpacontainer.filtering.basic[on-line example, window="_blank"]. | |||
The filtering implementation uses the JPA 2.0 Criteria API transparently. As the | |||
filtering is done at the database-level, custom filters that use the | |||
[interfacename]#Filterable# API do not work. | |||
When using Hibernate, note that it does not support implicit joins. See | |||
<<dummy/../../../framework/jpacontainer/jpacontainer-hibernate#jpacontainer.hibernate.joins,"Joins | |||
in Hibernate vs EclipseLink">> for more details. | |||
@@ -1,180 +0,0 @@ | |||
--- | |||
title: Using JPAContainer with Hibernate | |||
order: 9 | |||
layout: page | |||
--- | |||
[[jpacontainer.hibernate]] | |||
= Using JPAContainer with Hibernate | |||
Hibernate needs special handling in some cases. | |||
[[jpacontainer.hibernate.lazyloading]] | |||
== Lazy loading | |||
In order for lazy loading to work automatically, an entity must be attached to | |||
an entity manager. Unfortunately, Hibernate can not keep entity managers for | |||
long without problems. To work around the problem, you need to use a special | |||
lazy loading delegate for Hibernate. | |||
JPAContainer entity providers handle lazy loading in delegates defined by the | |||
[interfacename]#LazyLoadingDelegate# interface. The default implementation for | |||
Hibernate is defined in [classname]#HibernateLazyLoadingDelegate#. You can | |||
instantiate one and use it in an entity provider with | |||
[methodname]#setLazyLoadingDelegate()#. | |||
The default implementation works so that whenever a lazy property is accessed | |||
through the Vaadin Property interface, the value is retrieved with a separate | |||
(JPA Criteria API) query using the currently active entity manager. The value is | |||
then manually attached to the entity instance, which is detached from the entity | |||
manager. If this default implementation is not good enough, you may need to make | |||
your own implementation. | |||
ifdef::web[] | |||
[[jpacontainer.hibernate.em-per-request]] | |||
== The EntityManager-Per-Request pattern | |||
One issue with Hibernate is that it is designed for short-lived sessions, but | |||
the lifetime of an entity manager is normally roughly that of a user session. | |||
The problem is that if an error occurs in a session or an entity manager, the | |||
manager becomes unuseable. This causes big problems with long-lived sessions | |||
that would work fine with EclipseLink. | |||
The recommended solution is to use the __EntityManager-per-Request__ pattern. It | |||
is highly recommended always when using Hibernate. | |||
An entity manager can only be open during the request-response cycle of the | |||
Vaadin servlet, so that one is created at the beginning of the request and | |||
closed at the end. | |||
[[jpacontainer.hibernate.em-per-request.provider]] | |||
=== Storing an Entity Manager | |||
You first need to implement an [interfacename]#EntityManagerProvider# that | |||
returns a stored [interfacename]#EntityManager# with | |||
[methodname]#getEntityManager()#. The entity manager must be stored in a | |||
[classname]#ThreadLocal# variable. | |||
---- | |||
public class LazyHibernateEntityManagerProvider | |||
implements EntityManagerProvider { | |||
private static ThreadLocal<EntityManager> | |||
entityManagerThreadLocal = | |||
new ThreadLocal<EntityManager>(); | |||
@Override | |||
public EntityManager getEntityManager() { | |||
return entityManagerThreadLocal.get(); | |||
} | |||
public static void setCurrentEntityManager( | |||
EntityManager em) { | |||
entityManagerThreadLocal.set(em); | |||
} | |||
} | |||
---- | |||
You need to create and store the per-request instance at the beginning of each | |||
request with [methodname]#setCurrentEntityManager()# and clear it at the end by | |||
setting it as [literal]#++null++#. | |||
[[jpacontainer.hibernate.em-per-request.provider]] | |||
=== Creating Entity Managers in a Servlet Filter | |||
You can create the entity managers for each request either by extending | |||
[classname]#VaadinServlet# and overriding the [methodname]#service()# method or | |||
by implementing a servlet filter. In the following, we describe how to implement | |||
a servlet filter to do the task, but overriding the servlet could be even | |||
easier. | |||
---- | |||
public class LazyHibernateServletFilter | |||
implements Filter { | |||
private EntityManagerFactory entityManagerFactory; | |||
@Override | |||
public void init(FilterConfig filterConfig) | |||
throws ServletException { | |||
entityManagerFactory = Persistence | |||
.createEntityManagerFactory("lazyhibernate"); | |||
} | |||
@Override | |||
public void doFilter(ServletRequest servletRequest, | |||
ServletResponse servletResponse, | |||
FilterChain filterChain) | |||
throws IOException, ServletException { | |||
try { | |||
// Create and set the entity manager | |||
LazyHibernateEntityManagerProvider | |||
.setCurrentEntityManager( | |||
entityManagerFactory | |||
.createEntityManager()); | |||
// Handle the request | |||
filterChain.doFilter(servletRequest, | |||
servletResponse); | |||
} finally { | |||
// Reset the entity manager | |||
LazyHibernateEntityManagerProvider | |||
.setCurrentEntityManager(null); | |||
} | |||
} | |||
@Override | |||
public void destroy() { | |||
entityManagerFactory = null; | |||
} | |||
} | |||
---- | |||
You need to define the servlet filter in the [filename]#web.xml# deployment | |||
descriptor as follows: | |||
[subs="normal"] | |||
---- | |||
<filter> | |||
<filter-name>**LazyHibernateServletFilter**</filter-name> | |||
<filter-class>**com.example.LazyHibernateServletFilter**</filter-class> | |||
</filter> | |||
<filter-mapping> | |||
<filter-name>**LazyHibernateServletFilter**</filter-name> | |||
<url-pattern>**/++*++**</url-pattern> | |||
</filter-mapping> | |||
---- | |||
The [literal]#++url-pattern++# must match the pattern for your Vaadin servlet. | |||
endif::web[] | |||
[[jpacontainer.hibernate.joins]] | |||
== Joins in Hibernate vs EclipseLink | |||
EclipseLink supports implicit joins, while Hibernate requires explicit joins. In | |||
SQL terms, an explicit join is a " [literal]#++FROM a INNER JOIN b ON a.bid = | |||
b.id++#" expression, while an implicit join is done in a WHERE clause, such as: | |||
" [literal]#++FROM a,b WHERE a.bid = b.id++#". | |||
In a JPAContainer filter with EclipseLink, an implicit join would have form: | |||
---- | |||
new Equal("skills.skill", s) | |||
---- | |||
In Hibernate you would need to use [classname]#JoinFilter# for the explicit | |||
join: | |||
---- | |||
new JoinFilter("skills", new Equal("skill", s)) | |||
---- | |||
@@ -1,305 +0,0 @@ | |||
--- | |||
title: Installing | |||
order: 2 | |||
layout: page | |||
--- | |||
[[jpacontainer.installation]] | |||
= Installing | |||
Vaadin JPAContainer can be installed either as an installation package, | |||
downloaded from the Vaadin Directory, or as a Maven dependency. You can also | |||
create a new JPAContainer-enabled Vaadin project using a Maven archetype. | |||
[[jpacontainer.installation.download]] | |||
== Downloading the Package | |||
Vaadin JPAContainer is available for download from the | |||
link:http://vaadin.com/directory[Vaadin Directory]. Please see | |||
<<dummy/../../../framework/addons/addons-downloading#addons.downloading,"Downloading | |||
Add-ons from Vaadin Directory">> for basic instructions for downloading from | |||
Directory. The download page also gives the dependency declaration needed for | |||
retrieving the library with Maven. | |||
JPAContainer is a purely server-side component, so it does not include a widget | |||
set that you would need to compile. | |||
[[jpacontainer.installation.package]] | |||
== Installation Package Content | |||
Once extracted to a local folder, the contents of the installation directory are | |||
as follows: | |||
[filename]#README#:: A readme file describing the package contents. | |||
[filename]#LICENSE#:: The full license text for the library. | |||
[filename]#vaadin-jpacontainer-3.x.x.jar#:: The actual Vaadin JPAContainer library. | |||
[filename]#vaadin-jpacontainer-3.x.x-sources.jar#:: Source JAR for the library. You can use it for example in Eclipse by associating | |||
the JavaDoc JAR with the JPAContainer JAR in the build path settings of your | |||
project. | |||
[filename]#jpacontainer-tutorial.pdf#:: The tutorial in PDF format. | |||
[filename]#jpacontainer-tutorial-html#:: The tutorial in HTML format. | |||
[filename]#jpacontainer-addressbook-demo#:: The JPAContainer AddressBook Demo project covered in this tutorial. You can | |||
compile and package the application as a WAR with " [command]#mvn# | |||
[parameter]#package#" or launch it in the Jetty web browser with " | |||
[command]#mvn# [parameter]#jetty:run#". You can also import the demo project in | |||
Eclipse. | |||
[[jpacontainer.installation.maven]] | |||
== Downloading with Maven | |||
The link:http://vaadin.com/directory[download page in Vaadin Directory] gives | |||
the dependency declaration needed for retrieving the Vaadin JPAContainer library | |||
with Maven. | |||
[subs="normal"] | |||
---- | |||
<dependency> | |||
<groupId>com.vaadin.addon</groupId> | |||
<artifactId>jpacontainer</artifactId> | |||
<version>[replaceable]##3.2.0##</version> | |||
</dependency> | |||
---- | |||
Use the [literal]#++LATEST++# version tag to automatically download the latest | |||
stable release or use a specific version number as done above. | |||
See <<dummy/../../../framework/addons/addons-maven#addons.maven,"Using Add-ons | |||
in a Maven Project">> for detailed instructions for using a Vaadin add-on with | |||
Maven. | |||
[[jpacontainer.installation.maven.archetype]] | |||
=== Using the Maven Archetype | |||
If you wish to create a new JPAContainer-enabled Vaadin project with Maven, you | |||
can use the [literal]#++vaadin-archetype-jpacontainer++# archetype. Please see | |||
<<dummy/../../../framework/getting-started/getting-started-maven#getting-started.maven,"Using | |||
Vaadin with Maven">> for details on creating a Vaadin project with a Maven | |||
archetype. | |||
[[jpacontainer.installation.libraries]] | |||
== Including Libraries in Your Project | |||
The Vaadin JPAContainer JAR must be included in the library folder of the web | |||
application. It is located in [filename]#WEB-INF/lib# path in a web application. | |||
In a normal Eclipse web projects the path is [filename]#WebContent/WEB-INF/lib#. | |||
In Maven projects the JARs are automatically included in the folder, as long as | |||
the dependencies are defined correctly. | |||
You will need the following JARs: | |||
* Vaadin Framework Library | |||
* Vaadin JPAContainer | |||
* Java Persistence API 2.0 (javax.persistence package) | |||
* JPA implementation (EclipseLink, Hibernate, ...) | |||
* Database driver or embedded engine (H2, HSQLDB, MySQL, PostgreSQL, ...) | |||
If you use Eclipse, the Vaadin Framework library is automatically downloaded and | |||
updated by the Vaadin Plugin for Eclipse. | |||
To use bean validation, you need an implementation of the Bean Validation, such | |||
as Hibernate Validator.//TODO | |||
elaborate | |||
[[jpacontainer.installation.configuration]] | |||
== Persistence Configuration | |||
Persistence configuration is done in a [filename]#persistence.xml# file. In a | |||
regular Eclipse project, it should be located in | |||
[filename]#WebContent/WEB-INF/classes/META-INF#. In a Maven project, it should | |||
be in [filename]#src/main/resources/META-INF#. The configuration includes the | |||
following: | |||
* The persistence unit | |||
* The persistence provider | |||
* The database driver and connection | |||
* Logging | |||
The [filename]#persistence.xml# file is packaged as | |||
[filename]#WEB-INF/classes/META-INF/persistence.xml# in the WAR. This is done | |||
automatically in a Maven build at the package phase. | |||
[[jpacontainer.installation.configuration.schema]] | |||
=== Persistence XML Schema | |||
The beginning of a [filename]#persistence.xml# file defines the used schema and | |||
namespaces: | |||
---- | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<persistence | |||
xmlns="http://java.sun.com/xml/ns/persistence" | |||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |||
xsi:schemaLocation=" | |||
http://java.sun.com/xml/ns/persistence | |||
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd" | |||
version="2.0"> | |||
---- | |||
[[jpacontainer.installation.configuration.unit]] | |||
=== Defining the Persistence Unit | |||
The root element of the persistence definition is persistence-unit. The name of | |||
the persistence unit is needed for creating [classname]#JPAContainer# instances | |||
from a [classname]#JPAContainerFactory#, as described in | |||
<<dummy/../../../framework/jpacontainer/jpacontainer-usage#jpacontainer.usage.jpacontainerfactory,"Creating | |||
JPAContainer with JPAContainerFactory">> or when creating a JPA entity manager. | |||
---- | |||
<persistence-unit name="addressbook"> | |||
---- | |||
Persistence provider is the JPA provider implementation used. For example, the | |||
JPAContainer AddressBook demo uses the EclipseLink JPA, which is defined as | |||
follows: | |||
---- | |||
<provider> | |||
org.eclipse.persistence.jpa.PersistenceProvider | |||
</provider> | |||
---- | |||
The persistent classes need to be listed with a [literal]#++<class>++# element. | |||
Alternatively, you can allow including unlisted classes for persistence by | |||
overriding the [literal]#++exclude-unlisted-classes++# default as follows: | |||
---- | |||
<exclude-unlisted-classes>false</exclude-unlisted-classes> | |||
---- | |||
JPA provider specific parameters are given under the [literal]#++properties++# | |||
element. | |||
---- | |||
<properties> | |||
... | |||
---- | |||
In the following section we give parameters for the EclipseLink JPA and H2 | |||
database used in the JPAContainer AddressBook Demo. Please refer to the | |||
documentation of the JPA provider you use for a complete reference of | |||
parameters. | |||
[[jpacontainer.installation.configuration.database]] | |||
=== Database Connection | |||
EclipseLink allows using JDBC for database connection. For example, if we use | |||
the the H2 database, we define its driver here as follows: | |||
---- | |||
<property name="eclipselink.jdbc.platform" | |||
value="org.eclipse.persistence.platform.database.H2Platform"/> | |||
<property name="eclipselink.jdbc.driver" | |||
value="org.h2.Driver" /> | |||
---- | |||
Database connection is specified with a URL. For example, using an embedded H2 | |||
database stored in the home directory it would be as follows: | |||
---- | |||
<property name="eclipselink.jdbc.url" | |||
value="jdbc:h2:~/my-app-h2db"/> | |||
---- | |||
A hint: when using an embedded H2 database while developing a Vaadin application | |||
in Eclipse, you may want to add [literal]#++;FILE_LOCK=NO++# to the URL to avoid | |||
locking issues when redeploying. | |||
We can just use the default user name and password for the H2 database: | |||
---- | |||
<property name="eclipselink.jdbc.user" value="sa"/> | |||
<property name="eclipselink.jdbc.password" value="sa"/> | |||
---- | |||
[[jpacontainer.installation.configuration.logging]] | |||
=== Logging Configuration | |||
JPA implementations as well as database engines like to produce logs and they | |||
should be configured in the persistence configuration. For example, if using | |||
EclipseLink JPA, you can get log that includes all SQL statements with the | |||
[literal]#++FINE++# logging level: | |||
---- | |||
<property name="eclipselink.logging.level" | |||
value="FINE" /> | |||
---- | |||
[[jpacontainer.installation.configuration.other]] | |||
=== Other Settings | |||
The rest is some Data Definition Language settings for EclipseLink. During | |||
development, when we use generated example data, we want EclipseLink to drop | |||
tables before trying to create them. In production environments, you should use | |||
[literal]#++create-tables++#. | |||
---- | |||
<property name="eclipselink.ddl-generation" | |||
value="drop-and-create-tables" /> | |||
---- | |||
And there is no need to generate SQL files, just execute them directly to the | |||
database. | |||
---- | |||
<property name="eclipselink.ddl-generation.output-mode" | |||
value="database"/> | |||
</properties> | |||
</persistence-unit> | |||
</persistence> | |||
---- | |||
[[jpacontainer.installation.troubleshooting]] | |||
== Troubleshooting | |||
Below are some typical errors that you might get when using JPA. These are not | |||
specific to JPAContainer. | |||
[classname]#javax.persistence.PersistenceException#: No Persistence provider for EntityManager:: The most typical cases for this error are that the persistence unit name is | |||
wrong in the source code or in the [filename]#persistence.xml# file, or that the | |||
[filename]#persistence.xml# is at a wrong place or has some other problem. Make | |||
sure that the persistence unit name matches and the [filename]#persistence.xml# | |||
is in [filename]#WEB-INF/classes/META-INF# folder in the deployment. | |||
[classname]#java.lang.IllegalArgumentException#: The class is not an entity:: The class is missing from the set of persistent entities. If the | |||
[filename]#persistence.xml# does not have [parameter]#exclude-unlisted-classes# | |||
defined as [literal]#++false++#, the persistent entity classes should be listed | |||
with [literal]#++<class>++# elements. |
@@ -1,124 +0,0 @@ | |||
--- | |||
title: Overview | |||
order: 1 | |||
layout: page | |||
--- | |||
[[jpacontainer.overview]] | |||
= Overview | |||
NOTE: Using JPAContainer is no longer recommended. | |||
While it works for simple data models, it is not as easy to use as it should be. | |||
It also has architectural weaknesses and performance issues that cause problems in building more complex applications. | |||
Instead, we recommend using JPA directly, while hiding it from your UI logic behind a DAO or service class. | |||
In UI code, you should mainly handle beans and collections of beans, bound to a [classname]#BeanItemContainer#. You should also note the https://vaadin.com/directory#!addon/viritin[Viritin] add-on, which provides data binding features that help with JPA. | |||
Vaadin JPAContainer add-on makes it possible to bind user interface components | |||
to a database easily using the Java Persistence API (JPA). It is an | |||
implementation of the [interfacename]#Container# interface described in | |||
<<dummy/../../../framework/datamodel/datamodel-container#datamodel.container,"Collecting | |||
Items in Containers">>. It supports a typical three-layer application | |||
architecture with an intermediate __domain model__ between the user interface | |||
and the data access layer. | |||
[[figure.jpacontainer.overview.architecture]] | |||
.Three-Layer Architecture Using JPAContainer And JPA | |||
image::img/three-layer-architecture-hi.png[] | |||
The role of Java Persistence API is to handle persisting the domain model in the | |||
database. The database is typically a relational database. Vaadin JPAContainer | |||
binds the user interface components to the domain model and handles database | |||
access with JPA transparently. | |||
JPA is really just an API definition and has many alternative implementations. | |||
Vaadin JPAContainer supports especially EclipseLink, which is the reference | |||
implementation of JPA, and Hibernate. Any other compliant implementation should | |||
work just as well. The architecture of an application using JPAContainer is | |||
shown in <<figure.jpacontainer.overview.detailed-architecture>>. | |||
[[figure.jpacontainer.overview.detailed-architecture]] | |||
.JPAContainer Architecture | |||
image::img/detailed-architecture-hi.png[] | |||
Vaadin JPAContainer also plays together with the Vaadin support for Java Bean | |||
Validation (JSR 303). | |||
[[jpacontainer.overview.jpa]] | |||
== Java Persistence API | |||
Java Persistence API (JPA) is an API for object-relational mapping (ORM) of Java | |||
objects to a relational database. In JPA and entity-relationship modeling in | |||
general, a Java class is considered an __entity__. Class (or entity) instances | |||
correspond with a row in a database table and member variables of a class with | |||
columns. Entities can also have relationships with other entities. | |||
The object-relational mapping is illustrated in | |||
<<figure.jpacontainer.overview.jpa.orm>> with two entities with a one-to-many | |||
relationship. | |||
[[figure.jpacontainer.overview.jpa.orm]] | |||
.Object-Relational Mapping | |||
image::img/jpa-mapping-graphic-hi.png[] | |||
The entity relationships are declared with metadata. With Vaadin JPAContainer, | |||
you provide the metadata with annotations in the entity classes. The JPA | |||
implementation uses reflection to read the annotations and defines a database | |||
model automatically from the class definitions. Definition of the domain model | |||
and the annotations are described in | |||
<<dummy/../../../framework/jpacontainer/jpacontainer-domain-model#jpacontainer.domain-model.annotation,"Persistence | |||
Metadata">>. | |||
The main interface in JPA is the [interfacename]#EntityManager#, which allows | |||
making different kinds of queries either with the Java Persistence Query | |||
Language (JPQL), native SQL, or the Criteria API in JPA 2.0. You can always use | |||
the interface directly as well, using Vaadin JPAContainer only for binding the | |||
data to the user interface. | |||
Vaadin JPAContainer supports JPA 2.0 (JSR 317). It is available under the Apache | |||
License 2.0. | |||
[[jpacontainer.overview.concepts]] | |||
== JPAContainer Concepts | |||
The [classname]#JPAContainer# is an implementation of the Vaadin | |||
[interfacename]#Container# interface that you can bind to user interface | |||
components such as [classname]#Table#, [classname]#ComboBox#, etc. | |||
The data access to the persistent entities is handled with a __entity | |||
provider__, as defined in the [interfacename]#EntityProvider# interface. | |||
JPAContainer provides a number of different entity providers for different use | |||
cases and optimizations. The built-in providers are described in | |||
<<dummy/../../../framework/jpacontainer/jpacontainer-entityprovider#jpacontainer.entityprovider,"Entity | |||
Providers">>. | |||
[classname]#JPAContainer# is by default __unbuffered__, so that any entity | |||
property changes are written immediately to the database when you call | |||
[methodname]#setValue()# for a property, or when a user edits a bound field. A | |||
container can be set as __buffered__, so that changes are written on calling | |||
[methodname]#commit()#. Buffering can be done both at item level, such as when | |||
updating item property values, or at container level, such as when adding or | |||
deleting items. Only __batchable__ containers, that is, containers with a | |||
batchable entity provider, can be buffered. Note that buffering is recommended | |||
for situations where two users could update the same entity simultaneously, and | |||
when this would be a problem. In an unbuffered container, the entity is | |||
refreshed before writing an update, so the last write wins and a conflicting | |||
simultaneous update written before it is lost. A buffered container throws an | |||
[classname]#OptimisticLockException# when two users edit the same item (an | |||
unbuffered container never throws it), thereby allowing to handle the situation | |||
with application logic. | |||
[[jpacontainer.overview.documentation]] | |||
== Documentation and Support | |||
In addition to this chapter in the book, the installation package includes the | |||
following documentation about JPAContainer: | |||
* API Documentation | |||
* JPAContainer Tutorial | |||
* JPAContainer AddressBook Demo | |||
* JPAContainer Demo |
@@ -1,386 +0,0 @@ | |||
--- | |||
title: Basic Use of JPAContainer | |||
order: 4 | |||
layout: page | |||
--- | |||
[[jpacontainer.usage]] | |||
= Basic Use of JPAContainer | |||
Vaadin JPAContainer offers a highly flexible API that makes things easy in | |||
simple cases while allowing extensive flexibility in demanding cases. To begin | |||
with, it is a [classname]#Container#, as described in | |||
<<dummy/../../../framework/datamodel/datamodel-container#datamodel.container,"Collecting | |||
Items in Containers">>. | |||
In this section, we look how to create and use [classname]#JPAContainer# | |||
instances. We assume that you have defined a domain model with JPA annotations, | |||
as described in the previous section. | |||
[[jpacontainer.usage.jpacontainerfactory]] | |||
== Creating [classname]#JPAContainer# with [classname]#JPAContainerFactory# | |||
The [classname]#JPAContainerFactory# is the easy way to create | |||
[classname]#JPAContainer#s. It provides a set of __make...()__ factory methods | |||
for most cases that you will likely meet. Each factory method uses a different | |||
type of entity provider, which are described in | |||
<<dummy/../../../framework/jpacontainer/jpacontainer-entityprovider#jpacontainer.entityprovider,"Entity | |||
Providers">>. | |||
The factory methods take the class type of the entity class as the first | |||
parameter. The second parameter is either a persistence unit name (persistence | |||
context) or an [classname]#EntityManager# instance. | |||
---- | |||
// Create a persistent person container | |||
JPAContainer<Person> persons = | |||
JPAContainerFactory.make(Person.class, "book-examples"); | |||
// You can add entities to the container as well | |||
persons.addEntity(new Person("Marie-Louise Meilleur", 117)); | |||
// Set up sorting if the natural order is not appropriate | |||
persons.sort(new String[]{"age", "name"}, | |||
new boolean[]{false, false}); | |||
// Bind it to a component | |||
Table personTable = new Table("The Persistent People", persons); | |||
personTable.setVisibleColumns("id","name","age"); | |||
layout.addComponent(personTable); | |||
---- | |||
See the http://demo.vaadin.com/book-examples-vaadin7/book#jpacontainer.basic[on-line example, window="_blank"]. | |||
It's that easy. In fact, if you run the above code multiple times, you'll be | |||
annoyed by getting a new set of persons for each run - that's how persistent the | |||
container is. The basic [methodname]#make()# uses a | |||
[classname]#CachedMutableLocalEntityProvider#, which allows modifying the | |||
container and its entities, as we do above by adding new entities. | |||
When using just the persistence unit name, the factory creates an instance of | |||
[classname]#EntityManagerFactory# for the persistence unit and uses it to build | |||
entity managers. You can also create the entity managers yourself, as described | |||
later. | |||
The entity providers associated with the different factory methods are as | |||
follows: | |||
[[table.jpacontainer.usage.jpacontainerfactory]] | |||
.[classname]#JPAContainerFactory# Methods | |||
|=============== | |||
|[methodname]#make()#|[classname]#CachingMutableLocalEntityProvider# | |||
|[methodname]#makeReadOnly()#|[classname]#CachingLocalEntityProvider# | |||
|[methodname]#makeBatchable()#|[classname]#BatchableLocalEntityProvider# | |||
|[methodname]#makeNonCached()#|[classname]#MutableLocalEntityProvider# | |||
|[methodname]#makeNonCachedReadOnly()#|[classname]#LocalEntityProvider# | |||
|=============== | |||
[classname]#JPAContainerFactory# holds a cache of entity manager factories for | |||
the different persistence units, making sure that any entity manager factory is | |||
created only once, as it is a heavy operation. You can access the cache to get a | |||
new entity manager with the | |||
[methodname]#createEntityManagerForPersistenceUnit()# method. | |||
---- | |||
// Get an entity manager | |||
EntityManager em = JPAContainerFactory. | |||
createEntityManagerForPersistenceUnit("book-examples"); | |||
// Do a query | |||
em.getTransaction().begin(); | |||
em.createQuery("DELETE FROM Person p").executeUpdate(); | |||
em.persist(new Person("Jeanne Calment", 122)); | |||
em.persist(new Person("Sarah Knauss", 119)); | |||
em.persist(new Person("Lucy Hannah", 117)); | |||
em.getTransaction().commit(); | |||
... | |||
---- | |||
See the http://demo.vaadin.com/book-examples-vaadin7/book#jpacontainer.basic[on-line example, window="_blank"]. | |||
Notice that if you use update the persistent data with an entity manager outside | |||
a [classname]#JPAContainer# bound to the data, you need to refresh the container | |||
as described in <<jpacontainer.usage.entitites>>. | |||
[[jpacontainer.usage.jpacontainerfactory.thehardway]] | |||
=== Creating [classname]#JPAContainer# Manually | |||
While it is normally easiest to use a [classname]#JPAContainerFactory# to create | |||
[classname]#JPAContainer# instances, you may need to create them manually. It is | |||
necessary, for example, when you need to use a custom entity provider or extend | |||
[classname]#JPAContainer#. | |||
First, we need to create an entity manager and then the entity provider, which | |||
we bind to a [classname]#JPAContainer#. | |||
---- | |||
// We need a factory to create entity manager | |||
EntityManagerFactory emf = | |||
Persistence.createEntityManagerFactory("book-examples"); | |||
// We need an entity manager to create entity provider | |||
EntityManager em = emf.createEntityManager(); | |||
// We need an entity provider to create a container | |||
CachingMutableLocalEntityProvider<Person> entityProvider = | |||
new CachingMutableLocalEntityProvider<Person>(Person.class, | |||
em); | |||
// And there we have it | |||
JPAContainer<Person> persons = | |||
new JPAContainer<Person> (Person.class); | |||
persons.setEntityProvider(entityProvider); | |||
---- | |||
See the http://demo.vaadin.com/book-examples-vaadin7/book#jpacontainer.thehardway[on-line example, window="_blank"]. | |||
You could save the first step by asking the entity manager from the | |||
[classname]#JPAContainerFactory#. | |||
[[jpacontainer.usage.entitites]] | |||
== Creating and Accessing Entities | |||
JPAContainer integrates with the JPA entity manager, which you would normally | |||
use to create and access entities with JPA. You can use the entity manager for | |||
any purposes you may have, and then [classname]#JPAContainer# to bind entities | |||
to user interface components such as [classname]#Table#, [classname]#Tree#, any | |||
selection components, or a [classname]#Form#. | |||
You can add new entities to a [classname]#JPAContainer# with the | |||
[methodname]#addEntity()# method. It returns the item ID of the new entity. | |||
---- | |||
Country france = new Country("France"); | |||
Object itemId = countries.addEntity(france); | |||
---- | |||
The item ID used by [classname]#JPAContainer# is the value of the ID property | |||
(column) defined with the [literal]#++@Id++# annotation. In our | |||
[classname]#Country# entity, it would have [classname]#Long# type. It is | |||
generated by the entity manager when the entity is persisted and set with the | |||
setter for the ID proeprty. | |||
Notice that the [methodname]#addEntity()# method does __not__ attach the entity | |||
instance given as the parameter. Instead, it creates a new instance. If you need | |||
to use the entity for some purpose, you need to get the actual managed entity | |||
from the container. You can get it with the item ID returned by | |||
[methodname]#addEntity()#. | |||
---- | |||
// Create a new entity and add it to a container | |||
Country france = new Country("France"); | |||
Object itemId = countries.addEntity(france); | |||
// Get the managed entity | |||
france = countries.getItem(itemId).getEntity(); | |||
// Use the managed entity in entity references | |||
persons.addEntity(new Person("Jeanne Calment", 122, france)); | |||
---- | |||
[[jpacontainer.usage.entitites.items]] | |||
=== Entity Items | |||
The [methodname]#getItem()# method is defined in the normal Vaadin | |||
[interfacename]#Container# interface. It returns an [classname]#EntityItem#, | |||
which is a wrapper over the actual entity object. You can get the entity object | |||
with [methodname]#getEntity()#. | |||
An [classname]#EntityItem# can have a number of states: persistent, modified, | |||
dirty, and deleted. The dirty and deleted states are meaningful when using | |||
__container buffering__, while the modified state is meaningful when using | |||
__item buffering__. Both levels of buffering can be used together - user input | |||
is first written to the item buffer, then to the entity instance, and finally to | |||
the database. | |||
The [methodname]#isPersistent()# method tells if the item is actually | |||
persistent, that is, fetched from a persistent storage, or if it is just a | |||
transient entity created and buffered by the container. | |||
The [methodname]#isModified()# method checks whether the [classname]#EntityItem# | |||
has changes that are not yet committed to the entity instance. It is only | |||
relevant if the item buffering is enabled with [methodname]#setBuffered(true)# | |||
for the item. | |||
The [methodname]#isDirty()# method checks whether the entity object has been | |||
modified after it was fetched from the entity provider. The dirty state is | |||
possible only when buffering is enabled for the container. | |||
The [methodname]#isDeleted()# method checks whether the item has been marked for | |||
deletion with [methodname]#removeItem()# in a buffered container. | |||
[[jpacontainer.usage.entitites.refreshing]] | |||
=== Refreshing JPAContainer | |||
In cases where you change [classname]#JPAContainer# items outside the container, | |||
for example by through an [interfacename]#EntityManager#, or when they change in | |||
the database, you need to refresh the container. | |||
The [interfacename]#EntityContainer# interface implemented by | |||
[classname]#JPAContainer# provides two methods to refresh a container. The | |||
[methodname]#refresh()# discards all container caches and buffers and refreshes | |||
all loaded items in the container. All changes made to items provided by the | |||
container are discarded. The [methodname]#refreshItem()# refreshes a single | |||
item. | |||
[[jpacontainer.usage.nested-properties]] | |||
== Nested Properties | |||
If you have a one-to-one or many-to-one relationship, you can define the | |||
properties of the referenced entity as __nested__ in a | |||
[classname]#JPAContainer#. This way, you can access the properties directly | |||
through the container of the first entity type as if they were its properties. | |||
The interface is the same as with [classname]#BeanContainer# described in | |||
<<dummy/../../../framework/datamodel/datamodel-container#datamodel.container.beancontainer,"BeanContainer">>. | |||
You just need to add each nested property with | |||
[methodname]#addNestedContainerProperty()# using dot-separated path to the | |||
property. | |||
---- | |||
// Have a persistent container | |||
JPAContainer<Person> persons = | |||
JPAContainerFactory.make(Person.class, "book-examples"); | |||
// Add a nested property to a many-to-one property | |||
persons.addNestedContainerProperty("country.name"); | |||
// Show the persons in a table, except the "country" column, | |||
// which is an object - show the nested property instead | |||
Table personTable = new Table("The Persistent People", persons); | |||
personTable.setVisibleColumns("name", "age", "country.name"); | |||
// Have a nicer caption for the country.name column | |||
personTable.setColumnHeader("country.name", "Nationality"); | |||
---- | |||
See the http://demo.vaadin.com/book-examples-vaadin7/book#jpacontainer.nested[on-line example, window="_blank"]. | |||
The result is shown in <<figure.jpacontainer.usage.nested-properties>>. Notice | |||
that the [literal]#++country++# property in the container remains after adding | |||
the nested property, so we had to make that column invisible. Alternatively, we | |||
could have redefined the [methodname]#toString()# method in the country object | |||
to show the name instead of an object reference. | |||
[[figure.jpacontainer.usage.nested-properties]] | |||
.Nested Properties | |||
image::img/nested-properties.png[] | |||
You can use the [literal]#++*++# wildcard to add all properties in a nested | |||
item, for example, " [literal]#++country.*++#". | |||
[[jpacontainer.usage.hierarchical]] | |||
== Hierarchical Container | |||
[classname]#JPAContainer# implements the [interfacename]#Container.Hierarchical# | |||
interface and can be bound to hierarchical components such as a | |||
[classname]#Tree# or [classname]#TreeTable#. The feature requires that the | |||
hierarchy is represented with a __parent__ property that refers to the parent | |||
item. At database level, this would be a column with IDs. | |||
The representation would be as follows: | |||
---- | |||
@Entity | |||
public class CelestialBody implements Serializable { | |||
@Id | |||
@GeneratedValue(strategy = GenerationType.IDENTITY) | |||
private Long id; | |||
private String name; | |||
@ManyToOne | |||
private CelestialBody parent; | |||
... | |||
} ... | |||
// Create some entities | |||
CelestialBody sun = new CelestialBody("The Sun", null); | |||
CelestialBody mercury = new CelestialBody("Mercury", sun); | |||
CelestialBody venus = new CelestialBody("Venus", sun); | |||
CelestialBody earth = new CelestialBody("Earth", sun); | |||
CelestialBody moon = new CelestialBody("The Moon", earth); | |||
CelestialBody mars = new CelestialBody("Mars", sun); | |||
... | |||
---- | |||
See the http://demo.vaadin.com/book-examples-vaadin7/book#jpacontainer.hierarchical[on-line example, window="_blank"]. | |||
You set up a [classname]#JPAContainer# to have hierarchy by calling | |||
[methodname]#setParentProperty()# with the name of the property that refers to | |||
the parent. Coincidentally, it is named " [literal]#++parent++#" in the example: | |||
---- | |||
// Create the container | |||
JPAContainer<CelestialBody> bodies = | |||
JPAContainerFactory.make(CelestialBody.class, "my-unit"); | |||
// Set it up for hierarchical representation | |||
bodies.setParentProperty("parent"); | |||
// Bind it to a hierarhical component | |||
Tree tree = new Tree("Celestial Bodies", bodies); | |||
tree.setItemCaptionMode(Tree.ITEM_CAPTION_MODE_PROPERTY); | |||
tree.setItemCaptionPropertyId("name"); | |||
---- | |||
See the http://demo.vaadin.com/book-examples-vaadin7/book#jpacontainer.hierarchical[on-line example, window="_blank"]. | |||
You can use the [methodname]#rootItemIds()# to acquire the item IDs of the root | |||
elements with no parent. | |||
---- | |||
// Expand the tree | |||
for (Object rootId: bodies.rootItemIds()) | |||
tree.expandItemsRecursively(rootId); | |||
---- | |||
See the http://demo.vaadin.com/book-examples-vaadin7/book#jpacontainer.hierarchical[on-line example, window="_blank"]. | |||
[[jpacontainer.usage.hierarchical.unsupported]] | |||
=== Unsupported Hierarchical Features | |||
Using [methodname]#setParent()# in the container to define parenthood is not | |||
supported. | |||
Also, the current implementation does not support __setChildrenAllowed()__, | |||
which controls whether the user can expand a node by clicking a toggle. The | |||
toggle is by default visible for all nodes, even if they have no children. The | |||
method is not supported because it would require storing the information outside | |||
the entities. You can override [methodname]#areChildrenAllowed()# to implement | |||
the functionality using a custom logic. | |||
---- | |||
// Customize JPAContainer to define the logic for | |||
// displaying the node expansion indicator | |||
JPAContainer<CelestialBody> bodies = | |||
new JPAContainer<CelestialBody>(CelestialBody.class) { | |||
@Override | |||
public boolean areChildrenAllowed(Object itemId) { | |||
// Some simple logic | |||
return getChildren(itemId).size() > 0; | |||
} | |||
}; | |||
bodies.setEntityProvider( | |||
new CachingLocalEntityProvider<CelestialBody>( | |||
CelestialBody.class, em)); | |||
---- | |||
See the http://demo.vaadin.com/book-examples-vaadin7/book#jpacontainer.hierarchical[on-line example, window="_blank"]. | |||
@@ -1,938 +0,0 @@ | |||
<?xml version="1.0" encoding="UTF-8" standalone="no"?> | |||
<!-- Created with Inkscape (http://www.inkscape.org/) --> | |||
<svg | |||
xmlns:dc="http://purl.org/dc/elements/1.1/" | |||
xmlns:cc="http://creativecommons.org/ns#" | |||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | |||
xmlns:svg="http://www.w3.org/2000/svg" | |||
xmlns="http://www.w3.org/2000/svg" | |||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | |||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | |||
width="744.09448" | |||
height="1052.3622" | |||
id="svg2475" | |||
sodipodi:version="0.32" | |||
inkscape:version="0.48.2 r9819" | |||
sodipodi:docname="domain-model.svg" | |||
inkscape:output_extension="org.inkscape.output.svg.inkscape" | |||
inkscape:export-filename="/home/magi/itmill/doc/cheatsheet/vaadin-cheatsheet.png" | |||
inkscape:export-xdpi="300.01001" | |||
inkscape:export-ydpi="300.01001" | |||
version="1.0"> | |||
<sodipodi:namedview | |||
id="base" | |||
pagecolor="#ffffff" | |||
bordercolor="#666666" | |||
borderopacity="1.0" | |||
gridtolerance="10000" | |||
guidetolerance="10" | |||
objecttolerance="10" | |||
inkscape:pageopacity="0.0" | |||
inkscape:pageshadow="2" | |||
inkscape:zoom="3.3941125" | |||
inkscape:cx="447.08547" | |||
inkscape:cy="609.40826" | |||
inkscape:document-units="mm" | |||
inkscape:current-layer="layer1" | |||
showgrid="true" | |||
inkscape:window-width="1920" | |||
inkscape:window-height="1060" | |||
inkscape:window-x="-4" | |||
inkscape:window-y="-3" | |||
inkscape:snap-nodes="true" | |||
inkscape:snap-bbox="true" | |||
units="mm" | |||
inkscape:snap-global="true" | |||
inkscape:window-maximized="1"> | |||
<inkscape:grid | |||
spacingy="1mm" | |||
spacingx="1mm" | |||
empspacing="5" | |||
units="mm" | |||
enabled="true" | |||
visible="true" | |||
id="grid4674" | |||
type="xygrid" | |||
dotted="false" /> | |||
</sodipodi:namedview> | |||
<defs | |||
id="defs2477"> | |||
<marker | |||
inkscape:stockid="Arrow1Lstart" | |||
orient="auto" | |||
refY="0" | |||
refX="0" | |||
id="Arrow1Lstart" | |||
style="overflow:visible"> | |||
<path | |||
id="path5210" | |||
d="M 0,0 L 5,-5 L -12.5,0 L 5,5 L 0,0 z" | |||
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none" | |||
transform="matrix(0.8,0,0,0.8,10,0)" /> | |||
</marker> | |||
<marker | |||
style="overflow:visible" | |||
id="DotS" | |||
refX="0" | |||
refY="0" | |||
orient="auto" | |||
inkscape:stockid="DotS"> | |||
<path | |||
transform="matrix(0.2,0,0,0.2,1.48,0.2)" | |||
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none;marker-end:none" | |||
d="M -2.5,-1 C -2.5,1.76 -4.74,4 -7.5,4 C -10.26,4 -12.5,1.76 -12.5,-1 C -12.5,-3.76 -10.26,-6 -7.5,-6 C -4.74,-6 -2.5,-3.76 -2.5,-1 z" | |||
id="path3636" /> | |||
</marker> | |||
<marker | |||
inkscape:stockid="TriangleOutS" | |||
orient="auto" | |||
refY="0" | |||
refX="0" | |||
id="TriangleOutS" | |||
style="overflow:visible"> | |||
<path | |||
id="path3717" | |||
d="M 5.77,0 L -2.88,5 L -2.88,-5 L 5.77,0 z" | |||
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none" | |||
transform="scale(0.2,0.2)" /> | |||
</marker> | |||
<inkscape:path-effect | |||
copytype="single_stretched" | |||
pattern="M 349.202,225.086 L 405.895,331.386 L 370.462,338.472 " | |||
prop_scale="1" | |||
id="path-effect2503" | |||
effect="skeletal" /> | |||
<inkscape:path-effect | |||
prop_scale="1" | |||
id="path-effect2499" | |||
effect="skeletal" /> | |||
<inkscape:path-effect | |||
pattern-nodetypes="cc" | |||
pattern="M 432.28346,272.83462 L 403.93701,216.14171" | |||
prop_scale="1" | |||
id="path-effect2497" | |||
effect="skeletal" /> | |||
<marker | |||
style="overflow:visible" | |||
id="Arrow1Send" | |||
refX="0" | |||
refY="0" | |||
orient="auto" | |||
inkscape:stockid="Arrow1Send"> | |||
<path | |||
transform="matrix(-0.2,0,0,-0.2,-1.2,0)" | |||
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none" | |||
d="M 0,0 L 5,-5 L -12.5,0 L 5,5 L 0,0 z" | |||
id="path3641" /> | |||
</marker> | |||
<marker | |||
style="overflow:visible" | |||
id="Arrow1Lend" | |||
refX="0" | |||
refY="0" | |||
orient="auto" | |||
inkscape:stockid="Arrow1Lend"> | |||
<path | |||
transform="matrix(-0.8,0,0,-0.8,-10,0)" | |||
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none" | |||
d="M 0,0 L 5,-5 L -12.5,0 L 5,5 L 0,0 z" | |||
id="path3629" /> | |||
</marker> | |||
<inkscape:perspective | |||
sodipodi:type="inkscape:persp3d" | |||
inkscape:vp_x="0 : 526.18109 : 1" | |||
inkscape:vp_y="0 : 1000 : 0" | |||
inkscape:vp_z="744.09448 : 526.18109 : 1" | |||
inkscape:persp3d-origin="372.04724 : 350.78739 : 1" | |||
id="perspective3487" /> | |||
<marker | |||
style="overflow:visible" | |||
id="Arrow2Sendp" | |||
refX="0" | |||
refY="0" | |||
orient="auto" | |||
inkscape:stockid="Arrow2Sendp"> | |||
<path | |||
transform="matrix(-0.3,0,0,-0.3,0.69,0)" | |||
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.97309,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z" | |||
style="font-size:12px;fill:#f39300;fill-rule:evenodd;stroke:#f39300;stroke-width:0.625;stroke-linejoin:round" | |||
id="path28139" /> | |||
</marker> | |||
<marker | |||
style="overflow:visible" | |||
id="TriangleOutSK" | |||
refX="0" | |||
refY="0" | |||
orient="auto" | |||
inkscape:stockid="TriangleOutSK"> | |||
<path | |||
transform="scale(0.2,0.2)" | |||
style="fill:#49c2f1;fill-rule:evenodd;stroke:#49c2f1;stroke-width:1pt;marker-start:none" | |||
d="M 5.77,0 L -2.88,5 L -2.88,-5 L 5.77,0 z" | |||
id="path36611" /> | |||
</marker> | |||
<marker | |||
style="overflow:visible" | |||
id="TriangleOutSH" | |||
refX="0" | |||
refY="0" | |||
orient="auto" | |||
inkscape:stockid="TriangleOutSH"> | |||
<path | |||
transform="scale(0.2,0.2)" | |||
style="fill:#49c2f1;fill-rule:evenodd;stroke:#49c2f1;stroke-width:1pt;marker-start:none" | |||
d="M 5.77,0 L -2.88,5 L -2.88,-5 L 5.77,0 z" | |||
id="path36614" /> | |||
</marker> | |||
<marker | |||
style="overflow:visible" | |||
id="TriangleOutSA" | |||
refX="0" | |||
refY="0" | |||
orient="auto" | |||
inkscape:stockid="TriangleOutSA"> | |||
<path | |||
transform="scale(0.2,0.2)" | |||
style="fill:#49c2f1;fill-rule:evenodd;stroke:#49c2f1;stroke-width:1pt;marker-start:none" | |||
d="M 5.77,0 L -2.88,5 L -2.88,-5 L 5.77,0 z" | |||
id="path36617" /> | |||
</marker> | |||
<marker | |||
style="overflow:visible" | |||
id="TriangleOutSKF" | |||
refX="0" | |||
refY="0" | |||
orient="auto" | |||
inkscape:stockid="TriangleOutSKF"> | |||
<path | |||
transform="scale(0.2,0.2)" | |||
style="fill:#49c2f1;fill-rule:evenodd;stroke:#49c2f1;stroke-width:1pt;marker-start:none" | |||
d="M 5.77,0 L -2.88,5 L -2.88,-5 L 5.77,0 z" | |||
id="path36620" /> | |||
</marker> | |||
<marker | |||
style="overflow:visible" | |||
id="TriangleOutS9" | |||
refX="0" | |||
refY="0" | |||
orient="auto" | |||
inkscape:stockid="TriangleOutS9"> | |||
<path | |||
transform="scale(0.2,0.2)" | |||
style="fill:#49c2f1;fill-rule:evenodd;stroke:#49c2f1;stroke-width:1pt;marker-start:none" | |||
d="M 5.77,0 L -2.88,5 L -2.88,-5 L 5.77,0 z" | |||
id="path36623" /> | |||
</marker> | |||
<marker | |||
style="overflow:visible" | |||
id="Arrow2SendpA" | |||
refX="0" | |||
refY="0" | |||
orient="auto" | |||
inkscape:stockid="Arrow2SendpA"> | |||
<path | |||
transform="matrix(-0.3,0,0,-0.3,0.69,0)" | |||
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.97309,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z" | |||
style="font-size:12px;fill:#d9d9cd;fill-rule:evenodd;stroke:#d9d9cd;stroke-width:0.625;stroke-linejoin:round" | |||
id="path3396" /> | |||
</marker> | |||
<marker | |||
style="overflow:visible" | |||
id="Arrow2Sendpg" | |||
refX="0" | |||
refY="0" | |||
orient="auto" | |||
inkscape:stockid="Arrow2Sendpg"> | |||
<path | |||
transform="matrix(-0.3,0,0,-0.3,0.69,0)" | |||
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.97309,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z" | |||
style="font-size:12px;fill:#fcc988;fill-rule:evenodd;stroke:#fcc988;stroke-width:0.625;stroke-linejoin:round" | |||
id="path3360" /> | |||
</marker> | |||
<filter | |||
id="filter2780" | |||
inkscape:label="White Halo" | |||
width="1.1" | |||
height="1.1"> | |||
<feMorphology | |||
id="feMorphology2782" | |||
operator="dilate" | |||
radius="3" | |||
result="result0" /> | |||
<feFlood | |||
id="feFlood2786" | |||
flood-color="rgb(255,255,255)" | |||
flood-opacity="1" | |||
in="result0" | |||
result="result3" /> | |||
<feComposite | |||
id="feComposite2623" | |||
in="result3" | |||
in2="result0" | |||
operator="in" | |||
result="result4" /> | |||
<feMerge | |||
id="feMerge2629"> | |||
<feMergeNode | |||
inkscape:collect="always" | |||
id="feMergeNode2631" | |||
in="result4" /> | |||
<feMergeNode | |||
inkscape:collect="always" | |||
id="feMergeNode2633" | |||
in="SourceGraphic" /> | |||
</feMerge> | |||
</filter> | |||
<marker | |||
inkscape:stockid="TriangleOutSn" | |||
orient="auto" | |||
refY="0" | |||
refX="0" | |||
id="TriangleOutSn" | |||
style="overflow:visible"> | |||
<path | |||
id="path4441" | |||
d="M 5.77,0 L -2.88,5 L -2.88,-5 L 5.77,0 z" | |||
style="fill:#d9d9cd;fill-rule:evenodd;stroke:#d9d9cd;stroke-width:1pt;marker-start:none" | |||
transform="scale(0.2,0.2)" /> | |||
</marker> | |||
<marker | |||
inkscape:stockid="TriangleOutS9F" | |||
orient="auto" | |||
refY="0" | |||
refX="0" | |||
id="TriangleOutS9F" | |||
style="overflow:visible"> | |||
<path | |||
id="path4444" | |||
d="M 5.77,0 L -2.88,5 L -2.88,-5 L 5.77,0 z" | |||
style="fill:#d9d9cd;fill-rule:evenodd;stroke:#d9d9cd;stroke-width:1pt;marker-start:none" | |||
transform="scale(0.2,0.2)" /> | |||
</marker> | |||
<marker | |||
inkscape:stockid="TriangleOutSI" | |||
orient="auto" | |||
refY="0" | |||
refX="0" | |||
id="TriangleOutSI" | |||
style="overflow:visible"> | |||
<path | |||
id="path4447" | |||
d="M 5.77,0 L -2.88,5 L -2.88,-5 L 5.77,0 z" | |||
style="fill:#d9d9cd;fill-rule:evenodd;stroke:#d9d9cd;stroke-width:1pt;marker-start:none" | |||
transform="scale(0.2,0.2)" /> | |||
</marker> | |||
<marker | |||
inkscape:stockid="TriangleOutSO" | |||
orient="auto" | |||
refY="0" | |||
refX="0" | |||
id="TriangleOutSO" | |||
style="overflow:visible"> | |||
<path | |||
id="path4450" | |||
d="M 5.77,0 L -2.88,5 L -2.88,-5 L 5.77,0 z" | |||
style="fill:#d9d9cd;fill-rule:evenodd;stroke:#d9d9cd;stroke-width:1pt;marker-start:none" | |||
transform="scale(0.2,0.2)" /> | |||
</marker> | |||
<marker | |||
inkscape:stockid="TriangleOutSW" | |||
orient="auto" | |||
refY="0" | |||
refX="0" | |||
id="TriangleOutSW" | |||
style="overflow:visible"> | |||
<path | |||
id="path4453" | |||
d="M 5.77,0 L -2.88,5 L -2.88,-5 L 5.77,0 z" | |||
style="fill:#d9d9cd;fill-rule:evenodd;stroke:#d9d9cd;stroke-width:1pt;marker-start:none" | |||
transform="scale(0.2,0.2)" /> | |||
</marker> | |||
<marker | |||
inkscape:stockid="TriangleOutSB" | |||
orient="auto" | |||
refY="0" | |||
refX="0" | |||
id="TriangleOutSB" | |||
style="overflow:visible"> | |||
<path | |||
id="path4456" | |||
d="M 5.77,0 L -2.88,5 L -2.88,-5 L 5.77,0 z" | |||
style="fill:#d9d9cd;fill-rule:evenodd;stroke:#d9d9cd;stroke-width:1pt;marker-start:none" | |||
transform="scale(0.2,0.2)" /> | |||
</marker> | |||
<marker | |||
inkscape:stockid="TriangleOutSZ" | |||
orient="auto" | |||
refY="0" | |||
refX="0" | |||
id="TriangleOutSZ" | |||
style="overflow:visible"> | |||
<path | |||
id="path4459" | |||
d="M 5.77,0 L -2.88,5 L -2.88,-5 L 5.77,0 z" | |||
style="fill:#d9d9cd;fill-rule:evenodd;stroke:#d9d9cd;stroke-width:1pt;marker-start:none" | |||
transform="scale(0.2,0.2)" /> | |||
</marker> | |||
<marker | |||
style="overflow:visible" | |||
id="DotSq" | |||
refX="0" | |||
refY="0" | |||
orient="auto" | |||
inkscape:stockid="DotSq"> | |||
<path | |||
transform="matrix(0.2,0,0,0.2,1.48,0.2)" | |||
style="fill:#d9d9cd;fill-rule:evenodd;stroke:#d9d9cd;stroke-width:1pt;marker-start:none;marker-end:none" | |||
d="M -2.5,-1 C -2.5,1.76 -4.74,4 -7.5,4 C -10.26,4 -12.5,1.76 -12.5,-1 C -12.5,-3.76 -10.26,-6 -7.5,-6 C -4.74,-6 -2.5,-3.76 -2.5,-1 z" | |||
id="path5853" /> | |||
</marker> | |||
<marker | |||
inkscape:stockid="TriangleOutSBO" | |||
orient="auto" | |||
refY="0" | |||
refX="0" | |||
id="TriangleOutSBO" | |||
style="overflow:visible"> | |||
<path | |||
id="path7501" | |||
d="M 5.77,0 L -2.88,5 L -2.88,-5 L 5.77,0 z" | |||
style="fill:#49c2f1;fill-rule:evenodd;stroke:#49c2f1;stroke-width:1pt;marker-start:none" | |||
transform="scale(0.2,0.2)" /> | |||
</marker> | |||
<marker | |||
style="overflow:visible" | |||
id="DotSu" | |||
refX="0" | |||
refY="0" | |||
orient="auto" | |||
inkscape:stockid="DotSu"> | |||
<path | |||
transform="matrix(0.2,0,0,0.2,1.48,0.2)" | |||
style="fill:#49c2f1;fill-rule:evenodd;stroke:#49c2f1;stroke-width:1pt;marker-start:none;marker-end:none" | |||
d="M -2.5,-1 C -2.5,1.76 -4.74,4 -7.5,4 C -10.26,4 -12.5,1.76 -12.5,-1 C -12.5,-3.76 -10.26,-6 -7.5,-6 C -4.74,-6 -2.5,-3.76 -2.5,-1 z" | |||
id="path9463" /> | |||
</marker> | |||
<filter | |||
height="1.1" | |||
width="1.1" | |||
inkscape:label="Black Halo" | |||
id="filter10694"> | |||
<feMorphology | |||
result="result0" | |||
radius="3" | |||
operator="dilate" | |||
id="feMorphology10696" /> | |||
<feFlood | |||
result="result3" | |||
in="result0" | |||
flood-opacity="1" | |||
flood-color="rgb(0,0,0)" | |||
id="feFlood10698" /> | |||
<feComposite | |||
result="result4" | |||
operator="in" | |||
in2="result0" | |||
in="result3" | |||
id="feComposite10700" /> | |||
<feMerge | |||
id="feMerge10702"> | |||
<feMergeNode | |||
in="result4" | |||
id="feMergeNode10704" | |||
inkscape:collect="always" /> | |||
<feMergeNode | |||
in="SourceGraphic" | |||
id="feMergeNode10706" | |||
inkscape:collect="always" /> | |||
</feMerge> | |||
</filter> | |||
<marker | |||
inkscape:stockid="TriangleOutSu" | |||
orient="auto" | |||
refY="0" | |||
refX="0" | |||
id="TriangleOutSu" | |||
style="overflow:visible"> | |||
<path | |||
id="path8127" | |||
d="M 5.77,0 L -2.88,5 L -2.88,-5 L 5.77,0 z" | |||
style="fill:#49c2f1;fill-rule:evenodd;stroke:#49c2f1;stroke-width:1pt;marker-start:none" | |||
transform="scale(0.2,0.2)" /> | |||
</marker> | |||
<marker | |||
inkscape:stockid="TriangleOutSI8" | |||
orient="auto" | |||
refY="0" | |||
refX="0" | |||
id="TriangleOutSI8" | |||
style="overflow:visible"> | |||
<path | |||
id="path8130" | |||
d="M 5.77,0 L -2.88,5 L -2.88,-5 L 5.77,0 z" | |||
style="fill:#49c2f1;fill-rule:evenodd;stroke:#49c2f1;stroke-width:1pt;marker-start:none" | |||
transform="scale(0.2,0.2)" /> | |||
</marker> | |||
<marker | |||
inkscape:stockid="TriangleOutSr" | |||
orient="auto" | |||
refY="0" | |||
refX="0" | |||
id="TriangleOutSr" | |||
style="overflow:visible"> | |||
<path | |||
id="path8133" | |||
d="M 5.77,0 L -2.88,5 L -2.88,-5 L 5.77,0 z" | |||
style="fill:#49c2f1;fill-rule:evenodd;stroke:#49c2f1;stroke-width:1pt;marker-start:none" | |||
transform="scale(0.2,0.2)" /> | |||
</marker> | |||
<marker | |||
inkscape:stockid="TriangleOutSM" | |||
orient="auto" | |||
refY="0" | |||
refX="0" | |||
id="TriangleOutSM" | |||
style="overflow:visible"> | |||
<path | |||
id="path8136" | |||
d="M 5.77,0 L -2.88,5 L -2.88,-5 L 5.77,0 z" | |||
style="fill:#49c2f1;fill-rule:evenodd;stroke:#49c2f1;stroke-width:1pt;marker-start:none" | |||
transform="scale(0.2,0.2)" /> | |||
</marker> | |||
<marker | |||
inkscape:stockid="TriangleOutSb" | |||
orient="auto" | |||
refY="0" | |||
refX="0" | |||
id="TriangleOutSb" | |||
style="overflow:visible"> | |||
<path | |||
id="path8139" | |||
d="M 5.77,0 L -2.88,5 L -2.88,-5 L 5.77,0 z" | |||
style="fill:#49c2f1;fill-rule:evenodd;stroke:#49c2f1;stroke-width:1pt;marker-start:none" | |||
transform="scale(0.2,0.2)" /> | |||
</marker> | |||
<marker | |||
id="marker18095" | |||
orient="auto" | |||
markerHeight="5.7450776" | |||
markerWidth="4.6297302"> | |||
<g | |||
id="g11064" | |||
transform="matrix(0.5,0,0,0.5,-185.64298,-257.19655)"> | |||
<path | |||
sodipodi:nodetypes="csccccccsccssssssssssssssccc" | |||
id="path11050" | |||
d="M 370,508.65625 C 369.13933,508.715 368.39056,509.27755 368.09375,510.09375 C 367.82399,510.83551 368.03605,511.62868 368.53125,512.21875 L 366.78125,512.21875 C 366.73884,512.21408 366.69882,512.22093 366.65625,512.21875 L 366.65625,516.59375 L 366.78125,516.59375 L 368.53125,516.59375 C 367.85229,517.45345 367.83424,518.70924 368.625,519.5 C 369.47591,520.35091 370.89909,520.35091 371.75,519.5 L 375.09375,516.125 C 375.12672,516.09552 375.15802,516.06422 375.1875,516.03125 C 375.21972,516.01191 375.25101,515.99105 375.28125,515.96875 C 375.28162,515.96839 375.49976,515.68796 375.5,515.6875 C 375.50005,515.68741 375.49338,515.64282 375.5,515.625 C 375.5011,515.62203 375.53002,515.62832 375.53125,515.625 C 375.57039,515.57293 375.58228,515.57321 375.625,515.5 C 375.76199,515.26524 375.79184,515.12809 375.78125,515.15625 C 375.81807,515.06473 375.79977,515.04374 375.8125,515 C 375.82311,514.98978 375.83353,514.97936 375.84375,514.96875 C 375.90379,514.74477 375.93181,514.45186 375.90625,514.1875 C 375.89266,513.98387 375.84739,513.88985 375.84375,513.875 C 375.84389,513.86458 375.84389,513.85417 375.84375,513.84375 C 375.86975,513.94071 375.85901,513.85978 375.75,513.59375 C 375.69753,513.46336 375.66014,513.37439 375.625,513.3125 C 375.57262,513.22275 375.49154,513.05015 375.28125,512.84375 L 371.75,509.3125 C 371.29355,508.82579 370.66491,508.60087 370,508.65625 z" | |||
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1" /> | |||
<path | |||
sodipodi:nodetypes="cccscccsssssssscccsccc" | |||
id="path11035" | |||
d="M 366.65625,515.40625 L 371.28125,515.40625 L 369.46875,517.21875 C 369.0718,517.6157 369.0718,518.2593 369.46875,518.65625 C 369.8657,519.0532 370.5093,519.0532 370.90625,518.65625 L 374.34375,515.1875 L 374.4375,515.125 C 374.44343,515.11918 374.43171,515.09972 374.4375,515.09375 C 374.49291,515.03659 374.5526,514.97676 374.59375,514.90625 C 374.62239,514.85717 374.63663,514.80216 374.65625,514.75 C 374.66861,514.71928 374.67831,514.68783 374.6875,514.65625 C 374.71862,514.54015 374.73024,514.43132 374.71875,514.3125 C 374.71489,514.25466 374.70138,514.21285 374.6875,514.15625 C 374.6766,514.1156 374.67237,514.07059 374.65625,514.03125 C 374.63982,513.99042 374.61578,513.94505 374.59375,513.90625 C 374.5483,513.82838 374.50015,513.74899 374.4375,513.6875 L 370.90625,510.15625 C 370.69734,509.93349 370.39809,509.8184 370.09375,509.84375 C 369.69897,509.8707 369.35398,510.12813 369.21875,510.5 C 369.08351,510.87187 369.18349,511.28826 369.46875,511.5625 L 371.34375,513.40625 L 366.65625,513.40625" | |||
style="fill:#49c2f1;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> | |||
</g> | |||
</marker> | |||
<marker | |||
id="marker44971" | |||
orient="auto" | |||
markerHeight="5.7450781" | |||
markerWidth="4.6297355"> | |||
<g | |||
id="g18059" | |||
transform="matrix(0.5,0,0,0.5,-185.64299,-257.19655)"> | |||
<path | |||
sodipodi:nodetypes="csccccccsccssssssssssssssccc" | |||
id="path18061" | |||
d="M 370,508.65625 C 369.13933,508.715 368.39056,509.27755 368.09375,510.09375 C 367.82399,510.83551 368.03605,511.62868 368.53125,512.21875 L 366.78125,512.21875 C 366.73884,512.21408 366.69882,512.22093 366.65625,512.21875 L 366.65625,516.59375 L 366.78125,516.59375 L 368.53125,516.59375 C 367.85229,517.45345 367.83424,518.70924 368.625,519.5 C 369.47591,520.35091 370.89909,520.35091 371.75,519.5 L 375.09375,516.125 C 375.12672,516.09552 375.15802,516.06422 375.1875,516.03125 C 375.21972,516.01191 375.25101,515.99105 375.28125,515.96875 C 375.28162,515.96839 375.49976,515.68796 375.5,515.6875 C 375.50005,515.68741 375.49338,515.64282 375.5,515.625 C 375.5011,515.62203 375.53002,515.62832 375.53125,515.625 C 375.57039,515.57293 375.58228,515.57321 375.625,515.5 C 375.76199,515.26524 375.79184,515.12809 375.78125,515.15625 C 375.81807,515.06473 375.79977,515.04374 375.8125,515 C 375.82311,514.98978 375.83353,514.97936 375.84375,514.96875 C 375.90379,514.74477 375.93181,514.45186 375.90625,514.1875 C 375.89266,513.98387 375.84739,513.88985 375.84375,513.875 C 375.84389,513.86458 375.84389,513.85417 375.84375,513.84375 C 375.86975,513.94071 375.85901,513.85978 375.75,513.59375 C 375.69753,513.46336 375.66014,513.37439 375.625,513.3125 C 375.57262,513.22275 375.49154,513.05015 375.28125,512.84375 L 371.75,509.3125 C 371.29355,508.82579 370.66491,508.60087 370,508.65625 z" | |||
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1" /> | |||
<path | |||
sodipodi:nodetypes="cccscccsssssssscccsccc" | |||
id="path18063" | |||
d="M 366.65625,515.40625 L 371.28125,515.40625 L 369.46875,517.21875 C 369.0718,517.6157 369.0718,518.2593 369.46875,518.65625 C 369.8657,519.0532 370.5093,519.0532 370.90625,518.65625 L 374.34375,515.1875 L 374.4375,515.125 C 374.44343,515.11918 374.43171,515.09972 374.4375,515.09375 C 374.49291,515.03659 374.5526,514.97676 374.59375,514.90625 C 374.62239,514.85717 374.63663,514.80216 374.65625,514.75 C 374.66861,514.71928 374.67831,514.68783 374.6875,514.65625 C 374.71862,514.54015 374.73024,514.43132 374.71875,514.3125 C 374.71489,514.25466 374.70138,514.21285 374.6875,514.15625 C 374.6766,514.1156 374.67237,514.07059 374.65625,514.03125 C 374.63982,513.99042 374.61578,513.94505 374.59375,513.90625 C 374.5483,513.82838 374.50015,513.74899 374.4375,513.6875 L 370.90625,510.15625 C 370.69734,509.93349 370.39809,509.8184 370.09375,509.84375 C 369.69897,509.8707 369.35398,510.12813 369.21875,510.5 C 369.08351,510.87187 369.18349,511.28826 369.46875,511.5625 L 371.34375,513.40625 L 366.65625,513.40625" | |||
style="fill:#d9d9cd;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> | |||
</g> | |||
</marker> | |||
<marker | |||
id="marker52016" | |||
orient="auto" | |||
markerHeight="5.7450786" | |||
markerWidth="4.6297302"> | |||
<g | |||
id="g52010" | |||
transform="matrix(0.5,0,0,0.5,-185.64299,-257.19655)"> | |||
<path | |||
sodipodi:nodetypes="csccccccsccssssssssssssssccc" | |||
id="path52012" | |||
d="M 370,508.65625 C 369.13933,508.715 368.39056,509.27755 368.09375,510.09375 C 367.82399,510.83551 368.03605,511.62868 368.53125,512.21875 L 366.78125,512.21875 C 366.73884,512.21408 366.69882,512.22093 366.65625,512.21875 L 366.65625,516.59375 L 366.78125,516.59375 L 368.53125,516.59375 C 367.85229,517.45345 367.83424,518.70924 368.625,519.5 C 369.47591,520.35091 370.89909,520.35091 371.75,519.5 L 375.09375,516.125 C 375.12672,516.09552 375.15802,516.06422 375.1875,516.03125 C 375.21972,516.01191 375.25101,515.99105 375.28125,515.96875 C 375.28162,515.96839 375.49976,515.68796 375.5,515.6875 C 375.50005,515.68741 375.49338,515.64282 375.5,515.625 C 375.5011,515.62203 375.53002,515.62832 375.53125,515.625 C 375.57039,515.57293 375.58228,515.57321 375.625,515.5 C 375.76199,515.26524 375.79184,515.12809 375.78125,515.15625 C 375.81807,515.06473 375.79977,515.04374 375.8125,515 C 375.82311,514.98978 375.83353,514.97936 375.84375,514.96875 C 375.90379,514.74477 375.93181,514.45186 375.90625,514.1875 C 375.89266,513.98387 375.84739,513.88985 375.84375,513.875 C 375.84389,513.86458 375.84389,513.85417 375.84375,513.84375 C 375.86975,513.94071 375.85901,513.85978 375.75,513.59375 C 375.69753,513.46336 375.66014,513.37439 375.625,513.3125 C 375.57262,513.22275 375.49154,513.05015 375.28125,512.84375 L 371.75,509.3125 C 371.29355,508.82579 370.66491,508.60087 370,508.65625 z" | |||
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1" /> | |||
<path | |||
sodipodi:nodetypes="cccscccsssssssscccsccc" | |||
id="path52014" | |||
d="M 366.65625,515.40625 L 371.28125,515.40625 L 369.46875,517.21875 C 369.0718,517.6157 369.0718,518.2593 369.46875,518.65625 C 369.8657,519.0532 370.5093,519.0532 370.90625,518.65625 L 374.34375,515.1875 L 374.4375,515.125 C 374.44343,515.11918 374.43171,515.09972 374.4375,515.09375 C 374.49291,515.03659 374.5526,514.97676 374.59375,514.90625 C 374.62239,514.85717 374.63663,514.80216 374.65625,514.75 C 374.66861,514.71928 374.67831,514.68783 374.6875,514.65625 C 374.71862,514.54015 374.73024,514.43132 374.71875,514.3125 C 374.71489,514.25466 374.70138,514.21285 374.6875,514.15625 C 374.6766,514.1156 374.67237,514.07059 374.65625,514.03125 C 374.63982,513.99042 374.61578,513.94505 374.59375,513.90625 C 374.5483,513.82838 374.50015,513.74899 374.4375,513.6875 L 370.90625,510.15625 C 370.69734,509.93349 370.39809,509.8184 370.09375,509.84375 C 369.69897,509.8707 369.35398,510.12813 369.21875,510.5 C 369.08351,510.87187 369.18349,511.28826 369.46875,511.5625 L 371.34375,513.40625 L 366.65625,513.40625" | |||
style="fill:#f39300;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> | |||
</g> | |||
</marker> | |||
<marker | |||
id="marker64887" | |||
orient="auto" | |||
markerHeight="5.745079" | |||
markerWidth="4.6297255"> | |||
<g | |||
id="g64855" | |||
transform="matrix(0.5,0,0,0.5,-185.64299,-257.19655)"> | |||
<path | |||
sodipodi:nodetypes="csccccccsccssssssssssssssccc" | |||
id="path64857" | |||
d="M 370,508.65625 C 369.13933,508.715 368.39056,509.27755 368.09375,510.09375 C 367.82399,510.83551 368.03605,511.62868 368.53125,512.21875 L 366.78125,512.21875 C 366.73884,512.21408 366.69882,512.22093 366.65625,512.21875 L 366.65625,516.59375 L 366.78125,516.59375 L 368.53125,516.59375 C 367.85229,517.45345 367.83424,518.70924 368.625,519.5 C 369.47591,520.35091 370.89909,520.35091 371.75,519.5 L 375.09375,516.125 C 375.12672,516.09552 375.15802,516.06422 375.1875,516.03125 C 375.21972,516.01191 375.25101,515.99105 375.28125,515.96875 C 375.28162,515.96839 375.49976,515.68796 375.5,515.6875 C 375.50005,515.68741 375.49338,515.64282 375.5,515.625 C 375.5011,515.62203 375.53002,515.62832 375.53125,515.625 C 375.57039,515.57293 375.58228,515.57321 375.625,515.5 C 375.76199,515.26524 375.79184,515.12809 375.78125,515.15625 C 375.81807,515.06473 375.79977,515.04374 375.8125,515 C 375.82311,514.98978 375.83353,514.97936 375.84375,514.96875 C 375.90379,514.74477 375.93181,514.45186 375.90625,514.1875 C 375.89266,513.98387 375.84739,513.88985 375.84375,513.875 C 375.84389,513.86458 375.84389,513.85417 375.84375,513.84375 C 375.86975,513.94071 375.85901,513.85978 375.75,513.59375 C 375.69753,513.46336 375.66014,513.37439 375.625,513.3125 C 375.57262,513.22275 375.49154,513.05015 375.28125,512.84375 L 371.75,509.3125 C 371.29355,508.82579 370.66491,508.60087 370,508.65625 z" | |||
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1" /> | |||
<path | |||
sodipodi:nodetypes="cccscccsssssssscccsccc" | |||
id="path64859" | |||
d="M 366.65625,515.40625 L 371.28125,515.40625 L 369.46875,517.21875 C 369.0718,517.6157 369.0718,518.2593 369.46875,518.65625 C 369.8657,519.0532 370.5093,519.0532 370.90625,518.65625 L 374.34375,515.1875 L 374.4375,515.125 C 374.44343,515.11918 374.43171,515.09972 374.4375,515.09375 C 374.49291,515.03659 374.5526,514.97676 374.59375,514.90625 C 374.62239,514.85717 374.63663,514.80216 374.65625,514.75 C 374.66861,514.71928 374.67831,514.68783 374.6875,514.65625 C 374.71862,514.54015 374.73024,514.43132 374.71875,514.3125 C 374.71489,514.25466 374.70138,514.21285 374.6875,514.15625 C 374.6766,514.1156 374.67237,514.07059 374.65625,514.03125 C 374.63982,513.99042 374.61578,513.94505 374.59375,513.90625 C 374.5483,513.82838 374.50015,513.74899 374.4375,513.6875 L 370.90625,510.15625 C 370.69734,509.93349 370.39809,509.8184 370.09375,509.84375 C 369.69897,509.8707 369.35398,510.12813 369.21875,510.5 C 369.08351,510.87187 369.18349,511.28826 369.46875,511.5625 L 371.34375,513.40625 L 366.65625,513.40625" | |||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> | |||
</g> | |||
</marker> | |||
<marker | |||
id="marker4057" | |||
orient="auto" | |||
markerHeight="5.745079" | |||
markerWidth="4.6297302"> | |||
<g | |||
id="g51986" | |||
transform="matrix(0.5,0,0,0.5,-185.64299,-257.19655)"> | |||
<path | |||
sodipodi:nodetypes="csccccccsccssssssssssssssccc" | |||
id="path51988" | |||
d="M 370,508.65625 C 369.13933,508.715 368.39056,509.27755 368.09375,510.09375 C 367.82399,510.83551 368.03605,511.62868 368.53125,512.21875 L 366.78125,512.21875 C 366.73884,512.21408 366.69882,512.22093 366.65625,512.21875 L 366.65625,516.59375 L 366.78125,516.59375 L 368.53125,516.59375 C 367.85229,517.45345 367.83424,518.70924 368.625,519.5 C 369.47591,520.35091 370.89909,520.35091 371.75,519.5 L 375.09375,516.125 C 375.12672,516.09552 375.15802,516.06422 375.1875,516.03125 C 375.21972,516.01191 375.25101,515.99105 375.28125,515.96875 C 375.28162,515.96839 375.49976,515.68796 375.5,515.6875 C 375.50005,515.68741 375.49338,515.64282 375.5,515.625 C 375.5011,515.62203 375.53002,515.62832 375.53125,515.625 C 375.57039,515.57293 375.58228,515.57321 375.625,515.5 C 375.76199,515.26524 375.79184,515.12809 375.78125,515.15625 C 375.81807,515.06473 375.79977,515.04374 375.8125,515 C 375.82311,514.98978 375.83353,514.97936 375.84375,514.96875 C 375.90379,514.74477 375.93181,514.45186 375.90625,514.1875 C 375.89266,513.98387 375.84739,513.88985 375.84375,513.875 C 375.84389,513.86458 375.84389,513.85417 375.84375,513.84375 C 375.86975,513.94071 375.85901,513.85978 375.75,513.59375 C 375.69753,513.46336 375.66014,513.37439 375.625,513.3125 C 375.57262,513.22275 375.49154,513.05015 375.28125,512.84375 L 371.75,509.3125 C 371.29355,508.82579 370.66491,508.60087 370,508.65625 z" | |||
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1" /> | |||
<path | |||
sodipodi:nodetypes="cccscccsssssssscccsccc" | |||
id="path51990" | |||
d="M 366.65625,515.40625 L 371.28125,515.40625 L 369.46875,517.21875 C 369.0718,517.6157 369.0718,518.2593 369.46875,518.65625 C 369.8657,519.0532 370.5093,519.0532 370.90625,518.65625 L 374.34375,515.1875 L 374.4375,515.125 C 374.44343,515.11918 374.43171,515.09972 374.4375,515.09375 C 374.49291,515.03659 374.5526,514.97676 374.59375,514.90625 C 374.62239,514.85717 374.63663,514.80216 374.65625,514.75 C 374.66861,514.71928 374.67831,514.68783 374.6875,514.65625 C 374.71862,514.54015 374.73024,514.43132 374.71875,514.3125 C 374.71489,514.25466 374.70138,514.21285 374.6875,514.15625 C 374.6766,514.1156 374.67237,514.07059 374.65625,514.03125 C 374.63982,513.99042 374.61578,513.94505 374.59375,513.90625 C 374.5483,513.82838 374.50015,513.74899 374.4375,513.6875 L 370.90625,510.15625 C 370.69734,509.93349 370.39809,509.8184 370.09375,509.84375 C 369.69897,509.8707 369.35398,510.12813 369.21875,510.5 C 369.08351,510.87187 369.18349,511.28826 369.46875,511.5625 L 371.34375,513.40625 L 366.65625,513.40625" | |||
style="fill:#49c2f1;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> | |||
</g> | |||
</marker> | |||
<marker | |||
id="marker72805" | |||
orient="auto" | |||
markerHeight="4.5568175" | |||
markerWidth="4.0334239"> | |||
<path | |||
sodipodi:nodetypes="cccscccsssssssscccsccc" | |||
id="path18057" | |||
d="M -2.0167119,0.50456824 L 0.29578813,0.50456824 L -0.61046187,1.4108182 C -0.80893187,1.6092982 -0.80893187,1.9310982 -0.61046187,2.1295682 C -0.41198187,2.3280482 -0.090181874,2.3280482 0.10828813,2.1295682 L 1.8270381,0.39519824 L 1.8739181,0.36394824 C 1.8768781,0.36103824 1.8710181,0.35130824 1.8739181,0.34831824 C 1.9016181,0.31973824 1.9314681,0.28982824 1.9520381,0.25456824 C 1.9663581,0.23002824 1.9734781,0.20252824 1.9832881,0.17644824 C 1.9894681,0.16108824 1.9943181,0.14535824 1.9989181,0.12956824 C 2.0144781,0.07151824 2.0202881,0.01710824 2.0145381,-0.04230176 C 2.0126081,-0.07122176 2.0058581,-0.09213176 1.9989181,-0.12043176 C 1.9934681,-0.14075176 1.9913481,-0.16326176 1.9832881,-0.18293176 C 1.9750781,-0.20334176 1.9630581,-0.22603176 1.9520381,-0.24543176 C 1.9293181,-0.28436176 1.9052381,-0.32406176 1.8739181,-0.35480176 L 0.10828813,-2.1204318 C 0.003838126,-2.2318118 -0.14579187,-2.2893518 -0.29796187,-2.2766818 C -0.49535187,-2.2632018 -0.66784187,-2.1344918 -0.73546187,-1.9485518 C -0.80308187,-1.7626218 -0.75309187,-1.5544218 -0.61046187,-1.4173018 L 0.32703813,-0.49543176 L -2.0167119,-0.49543176" | |||
style="fill:#f39300;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> | |||
</marker> | |||
<marker | |||
id="marker72808" | |||
orient="auto" | |||
markerHeight="4.5568123" | |||
markerWidth="4.0334177"> | |||
<path | |||
sodipodi:nodetypes="cccscccsssssssscccsccc" | |||
id="path72801" | |||
d="M -2.016709,0.50457301 L 0.29579105,0.50457301 L -0.61045895,1.410823 C -0.80893895,1.609293 -0.80893895,1.931093 -0.61045895,2.129573 C -0.41198895,2.328043 -0.090188953,2.328043 0.10829105,2.129573 L 1.827041,0.39519301 L 1.873911,0.36394301 C 1.876881,0.36103301 1.871021,0.35130301 1.873911,0.34832301 C 1.901621,0.31974301 1.931461,0.28982301 1.952041,0.25457301 C 1.966361,0.23003301 1.973481,0.20252301 1.983291,0.17644301 C 1.989471,0.16108301 1.994321,0.14536301 1.998911,0.12957301 C 2.014471,0.071523013 2.020281,0.017103013 2.014541,-0.042306987 C 2.012611,-0.071226987 2.005851,-0.092126987 1.998911,-0.12042699 C 1.993461,-0.14075699 1.991351,-0.16325699 1.983291,-0.18292699 C 1.975071,-0.20334699 1.963051,-0.22602699 1.952041,-0.24542699 C 1.929311,-0.28436699 1.905241,-0.32405699 1.873911,-0.35480699 L 0.10829105,-2.120427 C 0.003831047,-2.231807 -0.14578895,-2.289357 -0.29795895,-2.276677 C -0.49534895,-2.263207 -0.66784895,-2.134487 -0.73545895,-1.948557 C -0.80307895,-1.762617 -0.75308895,-1.554427 -0.61045895,-1.417307 L 0.32704105,-0.49542699 L -2.016709,-0.49542699" | |||
style="fill:#d9d9cd;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> | |||
</marker> | |||
<marker | |||
style="overflow:visible" | |||
id="DotSuN" | |||
refX="0" | |||
refY="0" | |||
orient="auto" | |||
inkscape:stockid="DotSuN"> | |||
<path | |||
transform="matrix(0.2,0,0,0.2,1.48,0.2)" | |||
style="fill:#f39300;fill-rule:evenodd;stroke:#f39300;stroke-width:1pt;marker-start:none;marker-end:none" | |||
d="M -2.5,-1 C -2.5,1.76 -4.74,4 -7.5,4 C -10.26,4 -12.5,1.76 -12.5,-1 C -12.5,-3.76 -10.26,-6 -7.5,-6 C -4.74,-6 -2.5,-3.76 -2.5,-1 z" | |||
id="path81580" /> | |||
</marker> | |||
<marker | |||
style="overflow:visible" | |||
id="DotSuNS" | |||
refX="0" | |||
refY="0" | |||
orient="auto" | |||
inkscape:stockid="DotSuNS"> | |||
<path | |||
transform="matrix(0.2,0,0,0.2,1.48,0.2)" | |||
style="marker-end:none;fill-rule:evenodd;marker-start:none;stroke:#49c2f1;stroke-width:1pt;fill:#49c2f1" | |||
d="M -2.5,-1 C -2.5,1.76 -4.74,4 -7.5,4 C -10.26,4 -12.5,1.76 -12.5,-1 C -12.5,-3.76 -10.26,-6 -7.5,-6 C -4.74,-6 -2.5,-3.76 -2.5,-1 z" | |||
id="path5020" /> | |||
</marker> | |||
<marker | |||
style="overflow:visible" | |||
id="DotSuNSX" | |||
refX="0" | |||
refY="0" | |||
orient="auto" | |||
inkscape:stockid="DotSuNSX"> | |||
<path | |||
transform="matrix(0.2,0,0,0.2,1.48,0.2)" | |||
style="marker-end:none;fill-rule:evenodd;marker-start:none;stroke:#49c2f1;stroke-width:1pt;fill:#49c2f1" | |||
d="M -2.5,-1 C -2.5,1.76 -4.74,4 -7.5,4 C -10.26,4 -12.5,1.76 -12.5,-1 C -12.5,-3.76 -10.26,-6 -7.5,-6 C -4.74,-6 -2.5,-3.76 -2.5,-1 z" | |||
id="path5565" /> | |||
</marker> | |||
<marker | |||
style="overflow:visible" | |||
id="DotSuN4" | |||
refX="0" | |||
refY="0" | |||
orient="auto" | |||
inkscape:stockid="DotSuN4"> | |||
<path | |||
transform="matrix(0.2,0,0,0.2,1.48,0.2)" | |||
style="marker-end:none;fill-rule:evenodd;marker-start:none;stroke:#49c2f1;stroke-width:1pt;fill:#49c2f1" | |||
d="M -2.5,-1 C -2.5,1.76 -4.74,4 -7.5,4 C -10.26,4 -12.5,1.76 -12.5,-1 C -12.5,-3.76 -10.26,-6 -7.5,-6 C -4.74,-6 -2.5,-3.76 -2.5,-1 z" | |||
id="path5568" /> | |||
</marker> | |||
<marker | |||
style="overflow:visible" | |||
id="DotSuNSX-5" | |||
refX="0" | |||
refY="0" | |||
orient="auto" | |||
inkscape:stockid="DotSuNSX"> | |||
<path | |||
inkscape:connector-curvature="0" | |||
transform="matrix(0.2,0,0,0.2,1.48,0.2)" | |||
style="fill:#49c2f1;fill-rule:evenodd;stroke:#49c2f1;stroke-width:1pt;marker-start:none;marker-end:none" | |||
d="m -2.5,-1 c 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z" | |||
id="path5565-5" /> | |||
</marker> | |||
<marker | |||
style="overflow:visible" | |||
id="DotSuN4-0" | |||
refX="0" | |||
refY="0" | |||
orient="auto" | |||
inkscape:stockid="DotSuN4"> | |||
<path | |||
inkscape:connector-curvature="0" | |||
transform="matrix(0.2,0,0,0.2,1.48,0.2)" | |||
style="fill:#49c2f1;fill-rule:evenodd;stroke:#49c2f1;stroke-width:1pt;marker-start:none;marker-end:none" | |||
d="m -2.5,-1 c 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z" | |||
id="path5568-1" /> | |||
</marker> | |||
</defs> | |||
<metadata | |||
id="metadata2480"> | |||
<rdf:RDF> | |||
<cc:Work | |||
rdf:about=""> | |||
<dc:format>image/svg+xml</dc:format> | |||
<dc:type | |||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> | |||
</cc:Work> | |||
</rdf:RDF> | |||
</metadata> | |||
<g | |||
id="layer1" | |||
inkscape:groupmode="layer" | |||
inkscape:label="Layer 1"> | |||
<flowRoot | |||
style="font-size:12px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Helvetica Rounded LT Std;-inkscape-font-specification:Helvetica Rounded LT Std Bold" | |||
id="flowRoot2485" | |||
xml:space="preserve"><flowRegion | |||
id="flowRegion2487"><rect | |||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:Helvetica Rounded LT Std;-inkscape-font-specification:Helvetica Rounded LT Std Bold" | |||
y="238.07646" | |||
x="262.85715" | |||
height="120" | |||
width="184.28572" | |||
id="rect2489" /></flowRegion><flowPara | |||
id="flowPara2491" /></flowRoot> <g | |||
transform="translate(-3.5714286,23.214286)" | |||
id="g3178" /> | |||
<g | |||
transform="translate(287.00786,159.44882)" | |||
id="g3820"> | |||
<rect | |||
style="fill:#49c2f1;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" | |||
id="rect3822" | |||
width="99.212593" | |||
height="56.692913" | |||
x="14.173247" | |||
y="237.40155" | |||
ry="3.7880721" /> | |||
<flowRoot | |||
xml:space="preserve" | |||
style="font-size:12px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Helvetica Rounded LT Std;-inkscape-font-specification:Helvetica Rounded LT Std Bold" | |||
id="flowRoot3824" | |||
transform="translate(20.586428,253.63916)"><flowRegion | |||
id="flowRegion3826" /><flowPara | |||
id="flowPara3830">Country</flowPara></flowRoot> <text | |||
xml:space="preserve" | |||
style="font-size:10px;font-style:normal;font-variant:normal;font-weight:300;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Helvetica LT Std;-inkscape-font-specification:Helvetica LT Std Light" | |||
x="21.095966" | |||
y="269.65045" | |||
id="text84151" | |||
sodipodi:linespacing="125%" | |||
inkscape:transform-center-x="7.0447343" | |||
inkscape:transform-center-y="1.4910516"><tspan | |||
sodipodi:role="line" | |||
id="tspan84153" | |||
x="21.095966" | |||
y="269.65045">id : Long</tspan><tspan | |||
sodipodi:role="line" | |||
x="21.095966" | |||
y="282.15045" | |||
id="tspan3271">name : String</tspan></text> | |||
</g> | |||
<flowRoot | |||
style="font-size:12px;font-style:normal;font-variant:normal;font-weight:300;font-stretch:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Helvetica LT Std;-inkscape-font-specification:Helvetica LT Std Light" | |||
id="flowRoot8724" | |||
xml:space="preserve"><flowRegion | |||
id="flowRegion8726"><rect | |||
style="font-style:normal;font-variant:normal;font-weight:300;font-stretch:normal;font-family:Helvetica LT Std;-inkscape-font-specification:Helvetica LT Std Light" | |||
y="752.14441" | |||
x="39.286312" | |||
height="22.868153" | |||
width="29.904507" | |||
id="rect8728" /></flowRegion><flowPara | |||
id="flowPara8730" /></flowRoot> <g | |||
transform="matrix(0.5,0,0,0.5,103.34299,0.7940752)" | |||
id="g18053" /> | |||
<g | |||
transform="translate(464.17321,159.44882)" | |||
id="g3820-6"> | |||
<rect | |||
style="fill:#49c2f1;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" | |||
id="rect3822-3" | |||
width="95.669289" | |||
height="67.322838" | |||
x="14.173247" | |||
y="237.40155" | |||
ry="3.7880721" /> | |||
<flowRoot | |||
xml:space="preserve" | |||
style="font-size:12px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Helvetica Rounded LT Std;-inkscape-font-specification:Helvetica Rounded LT Std Bold" | |||
id="flowRoot3824-6" | |||
transform="translate(20.586428,253.57675)"><flowRegion | |||
id="flowRegion3826-8" /><flowPara | |||
id="flowPara3830-4">Person</flowPara></flowRoot> <text | |||
xml:space="preserve" | |||
style="font-size:10px;font-style:normal;font-variant:normal;font-weight:300;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Helvetica LT Std;-inkscape-font-specification:Helvetica LT Std Light" | |||
x="24.803171" | |||
y="269.29132" | |||
id="text84151-6" | |||
sodipodi:linespacing="125%" | |||
inkscape:transform-center-x="7.0447348" | |||
inkscape:transform-center-y="1.4910597"><tspan | |||
sodipodi:role="line" | |||
id="tspan84153-6" | |||
x="24.803171" | |||
y="269.29132">id : Long</tspan><tspan | |||
sodipodi:role="line" | |||
x="24.803171" | |||
y="281.79132" | |||
id="tspan3316">name : String</tspan><tspan | |||
sodipodi:role="line" | |||
x="24.803171" | |||
y="294.29132" | |||
id="tspan3328">age : Integer</tspan></text> | |||
</g> | |||
<g | |||
id="g5797" | |||
transform="translate(0,1.7716289)"> | |||
<path | |||
transform="matrix(1.2499999,0,0,1.2499999,-108.95668,-114.27159)" | |||
sodipodi:open="true" | |||
sodipodi:end="6.2827149" | |||
sodipodi:start="0" | |||
d="m 414.56693,428.74014 c 0,3.91383 -3.17278,7.08662 -7.08661,7.08662 -3.91383,0 -7.08662,-3.17279 -7.08662,-7.08662 0,-3.91383 3.17279,-7.08661 7.08662,-7.08661 3.91252,0 7.08477,3.17075 7.08661,7.08328" | |||
sodipodi:ry="7.0866141" | |||
sodipodi:rx="7.0866141" | |||
sodipodi:cy="428.74014" | |||
sodipodi:cx="407.48032" | |||
id="path5752" | |||
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" | |||
sodipodi:type="arc" /> | |||
<path | |||
transform="matrix(1.2499999,0,0,1.2499999,-31.003898,-114.27159)" | |||
sodipodi:open="true" | |||
sodipodi:end="6.2827149" | |||
sodipodi:start="0" | |||
d="m 414.56693,428.74014 c 0,3.91383 -3.17278,7.08662 -7.08661,7.08662 -3.91383,0 -7.08662,-3.17279 -7.08662,-7.08662 0,-3.91383 3.17279,-7.08661 7.08662,-7.08661 3.91252,0 7.08477,3.17075 7.08661,7.08328" | |||
sodipodi:ry="7.0866141" | |||
sodipodi:rx="7.0866141" | |||
sodipodi:cy="428.74014" | |||
sodipodi:cx="407.48032" | |||
id="path5752-0" | |||
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" | |||
sodipodi:type="arc" /> | |||
<path | |||
inkscape:connector-curvature="0" | |||
id="path3375" | |||
d="m 478.34646,421.65352 -77.95276,0" | |||
style="fill:none;stroke:#49c2f1;stroke-width:5.31496048;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-start:url(#DotSuNSX);marker-end:url(#DotSuN4)" | |||
sodipodi:nodetypes="cc" /> | |||
</g> | |||
<text | |||
xml:space="preserve" | |||
style="font-size:14px;font-style:normal;font-variant:normal;font-weight:300;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#49c2f1;fill-opacity:1;fill-rule:nonzero;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Helvetica LT Std;-inkscape-font-specification:Helvetica LT Std Light" | |||
x="402.35632" | |||
y="414.56689" | |||
id="text84151-4" | |||
sodipodi:linespacing="125%" | |||
inkscape:transform-center-x="7.0447431" | |||
inkscape:transform-center-y="1.4910516"><tspan | |||
sodipodi:role="line" | |||
x="402.35632" | |||
y="414.56689" | |||
id="tspan3271-2">1</tspan></text> | |||
<text | |||
xml:space="preserve" | |||
style="font-size:14px;font-style:normal;font-variant:normal;font-weight:300;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#49c2f1;fill-opacity:1;fill-rule:nonzero;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Helvetica LT Std;-inkscape-font-specification:Helvetica LT Std Light" | |||
x="468.04114" | |||
y="414.56689" | |||
id="text84151-4-0" | |||
sodipodi:linespacing="125%" | |||
inkscape:transform-center-x="7.0447343" | |||
inkscape:transform-center-y="1.4910516"><tspan | |||
sodipodi:role="line" | |||
x="468.04114" | |||
y="414.56689" | |||
id="tspan3271-2-4">n</tspan></text> | |||
<text | |||
xml:space="preserve" | |||
style="font-size:10px;font-style:normal;font-variant:normal;font-weight:300;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#49c2f1;fill-opacity:1;fill-rule:nonzero;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Helvetica LT Std;-inkscape-font-specification:Helvetica LT Std Light" | |||
x="432.50925" | |||
y="437.64047" | |||
id="text84151-4-4-7-2" | |||
sodipodi:linespacing="125%" | |||
inkscape:transform-center-x="7.0447343" | |||
inkscape:transform-center-y="1.4910516"><tspan | |||
sodipodi:role="line" | |||
x="432.50925" | |||
y="437.64047" | |||
id="tspan3271-2-9-1-2">+persons</tspan></text> | |||
<text | |||
xml:space="preserve" | |||
style="font-size:10px;font-style:normal;font-variant:normal;font-weight:300;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#49c2f1;fill-opacity:1;fill-rule:nonzero;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Helvetica LT Std;-inkscape-font-specification:Helvetica LT Std Light" | |||
x="402.54776" | |||
y="400.80167" | |||
id="text84151-4-4-7-2-7" | |||
sodipodi:linespacing="125%" | |||
inkscape:transform-center-x="7.0447343" | |||
inkscape:transform-center-y="1.4910516"><tspan | |||
sodipodi:role="line" | |||
x="402.54776" | |||
y="400.80167" | |||
id="tspan3271-2-9-1-2-7">+country</tspan></text> | |||
<text | |||
xml:space="preserve" | |||
style="font-size:10px;font-style:normal;font-variant:normal;font-weight:300;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#49c2f1;fill-opacity:1;fill-rule:nonzero;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Helvetica LT Std;-inkscape-font-specification:Helvetica LT Std Light" | |||
x="426.82224" | |||
y="416.52689" | |||
id="text84151-4-4-7-2-7-9" | |||
sodipodi:linespacing="125%" | |||
inkscape:transform-center-x="7.0447343" | |||
inkscape:transform-center-y="1.4910516"><tspan | |||
sodipodi:role="line" | |||
x="426.82224" | |||
y="416.52689" | |||
id="tspan3271-2-9-1-2-7-1">«has»</tspan></text> | |||
</g> | |||
</svg> |