integrating java beans with emf in order to build ... · internationalized models building...

21
Integrating Java Beans with EMF in order to build internationalized models Building model-centric applications with a modeling framework gives a lot of advantages. Separating the business domain model from the rest of the code makes domain objects easier to identify. It allows to write generic code that does not change when the model changes, which gives more flexible software. It facilitates code generation, which lowers development costs. Because writing model-independent software is easier, a modeling framework can integrate transactions, validations, persistence, query component. It is exactly what EMF has to offer. Building software for an international market implies specific challenges, because people speaking different languages and having different cultures will use the software. Model elements have different names according the language, the country, or even the community, that we call a locale. Model elements may be important for a particular locale, and irrelevant from another one. The standard Java library includes the java.beans package, which gives solutions for localization problems. Bean descriptors render display names, which change according the current locale. Giving user-dependent information is exactly what Java Beans has to offer. Unfortunately, the EMF framework and the Java Beans technology are two separate worlds. EMF does not include software component to access Java Beans functions. This article explains how to integrate the Java Beans library to the EMF framework in order to build EMF-based applications that take advantage of Java Beans features. Section 1: EMF metadata and internationalization The EMF model represents the data of an application. Each element of the model (an EObject instance) stores data. Also, each EObject instance contains data about the data, which is call metadata. The EObject's default value, the possibility of each of its attributes to be changed, the lower and upper bounds of each of its references to other EObjects are all metadata. It's interesting to notice that several of these metadata may depend of the user's locale. An obvious case is the default value of an EObject's attribute. If the attribute is an enumeration representing a list of countries, American users may want UNITED_STATES as the default value for country. If the attribute represents temperature units, they may want FARENHEIT instead of CELCIUS as the default value. Of course, users from other countries may have their own preferred default values. The problem is EMF is not locale-sensitive. For an EAttribute instance, EMF defines an attr.getDefaultValue(), but not an attr.getDefaultValue(Locale l). There is no way to tell EMF that people from a given locale would prefer having a specific default value. It's here that JavaBeans may fill a lack in EMF. If we consider each EObject as a bean, then we can get its descriptors (that are locale-dependant metadata). Making Java Beans working with EMF would allow us to create really internationalized EMF applications.

Upload: others

Post on 11-Aug-2020

0 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Integrating Java Beans with EMF in order to build ... · internationalized models Building model-centric applications with a modeling framework gives a lot of advantages. Separating

Integrating Java Beans with EMF in order to build internationalized models

Building model-centric applications with a modeling framework gives a lot of advantages. Separating the business domain model from the rest of the code makes domain objects easier to identify. It allows to write generic code that does not change when the model changes, which gives more flexible software. It facilitates code generation, which lowers development costs. Because writing model-independent software is easier, a modeling framework can integrate transactions, validations, persistence, query component. It is exactly what EMF has to offer.

Building software for an international market implies specific challenges, because people speaking different languages and having different cultures will use the software. Model elements have different names according the language, the country, or even the community, that we call a locale. Model elements may be important for a particular locale, and irrelevant from another one.

The standard Java library includes the java.beans package, which gives solutions for localization problems. Bean descriptors render display names, which change according the current locale. Giving user-dependent information is exactly what Java Beans has to offer.

Unfortunately, the EMF framework and the Java Beans technology are two separate worlds. EMF does not include software component to access Java Beans functions. This article explains how to integrate the Java Beans library to the EMF framework in order to build EMF-based applications that take advantage of Java Beans features.

Section 1: EMF metadata and internationalization The EMF model represents the data of an application. Each element of the model (an EObject instance) stores data. Also, each EObject instance contains data about the data, which is call metadata. The EObject's default value, the possibility of each of its attributes to be changed, the lower and upper bounds of each of its references to other EObjects are all metadata.

It's interesting to notice that several of these metadata may depend of the user's locale. An obvious case is the default value of an EObject's attribute. If the attribute is an enumeration representing a list of countries, American users may want UNITED_STATES as the default value for country. If the attribute represents temperature units, they may want FARENHEIT instead of CELCIUS as the default value. Of course, users from other countries may have their own preferred default values.

The problem is EMF is not locale-sensitive. For an EAttribute instance, EMF defines an attr.getDefaultValue(), but not an attr.getDefaultValue(Locale l). There is no way to tell EMF that people from a given locale would prefer having a specific default value.

It's here that JavaBeans may fill a lack in EMF. If we consider each EObject as a bean, then we can get its descriptors (that are locale-dependant metadata). Making Java Beans working with EMF would allow us to create really internationalized EMF applications.

Page 2: Integrating Java Beans with EMF in order to build ... · internationalized models Building model-centric applications with a modeling framework gives a lot of advantages. Separating

Section 2: Overview of the Java Beans Package Java Beans is a component architecture which is part of the standard library. Following Java Beans naming and design patterns allows a newcomer to quickly comprehend the functionality provided by a beans-based package; it also enables automated tools to introspect code and extract data about classes, called metadata. Some of these metadata are related to how to visualize class instances; they are called GUI metadata. Automated tools can extract GUI metadata and learn how to present class instances in a visually appealing way. Various methods in the beans library are locale-dependent.

The following figure shows the inheritance between the most important classes of the beans package. The Instrospector class is the link between a bean class and its information class (BeanInfo). BeanInfo is used to get descriptors, which describes how to visually present bean instances.

Figure 1: Main classes of the java.beans.package

The Introspector class is the entry point of the package. The getBeanClass() returns the informational class of a bean class. For instance, if I have a PurchaseOrder class that is compliant to beans convention, this method searches for a PurchaseOrderBeanInfo class. If this class in not found, it will return a GenericBeanInfo object. The searchPath methods are use to localize the BeanInfo class, in the case the Info is in a different package from the bean class.

Figure 2: Introspector class

Page 3: Integrating Java Beans with EMF in order to build ... · internationalized models Building model-centric applications with a modeling framework gives a lot of advantages. Separating

The BeanInfo class gives information about a bean class. These is generally one BeanInfo class for each bean class.

The getIcon() returns the 16x16 or 32x32 icon image associated with its underlying class. Note that the image returned is an instance of java.awt.Image. This is unfortunate, since it makes the client code AWT/Swing-dependent, and we would like to use bean mechanisms in Eclipse, which runs in a SWT environment. We will explain later how to circumvent this problem.

The getBeanDescriptor() method returns descriptors about the bean class, while getPropertyDescriptors() returns descriptors about each property of the bean class.

It is also possible to get descriptors on the bean methods, and the events associated with the beans.

Figure 3: BeanInfo classes

Page 4: Integrating Java Beans with EMF in order to build ... · internationalized models Building model-centric applications with a modeling framework gives a lot of advantages. Separating

Figure 4: FeatureDescriptor and its subclasses

The FeatureDescriptor class is the superclass of all kinds of descriptors. Descriptors are data that describes how to visually render bean class detail:

displayName The name intended to be shown to the end-user, contrary to the programmatic name of the bean class. The display name varies according the current locale, while the programmatic name is only dependent of the developers' language.

description Additional information targeted to the end-user. It can be shown using tooltips, or any similar way.

hidden Tells if a given class or property is intended to be hidden in the user interface, altougt it actually exists "under the hood".

expert Tells if a given class or property is intended to be shown for the layman, or only to expert end-users.

preferred Tells if a given class or property is particularly important to human users.

Page 5: Integrating Java Beans with EMF in order to build ... · internationalized models Building model-centric applications with a modeling framework gives a lot of advantages. Separating

Section 3: Define an EMF model (purchasing) Let's define a sample EMF model. We will start from the well-known model used in the EMF documentation1. In my case, I have used the Open ModelSphere UML tool2, because it's a free tool, it supports class duplicates and has EMF-generation capabilities. Class duplicates are identified with a fractional number (the 1/3 number in the right-upper corner of the Address class box indicates that it is the first class figure out of the three duplicated in the diagram). Class duplicates allows to make clear diagrams and get rid of overcrowded inter-crossing association and inheritance links.

Of course, there are many ways to define a EMF model. You can use Rational Rose instead, and generate the .ecore. You can define a EMF model by adding annotations in already-existing Java code. The question of which of these methods is the best one is really a question of preference.

Figure 4: Purchase Order and neighbor classes

1 Eclipse Modeling Framework, The eclipse series, Erich Gamma and others, Addison-Wesley, August 2003.2 See www.modelsphere.org

Page 6: Integrating Java Beans with EMF in order to build ... · internationalized models Building model-centric applications with a modeling framework gives a lot of advantages. Separating

Figure 5: Item and neighbor classes

Figure 6: Inheritance structure

Notice the class Company, Address, which have irregular plurals (companies, addresses). Also pay attention the Organisation class, and to center, color attribute, which differ in US/UK spelling. We will use these classes to validate UK localization.

Page 7: Integrating Java Beans with EMF in order to build ... · internationalized models Building model-centric applications with a modeling framework gives a lot of advantages. Separating

Figure 7: Data types and enumerations

Section 4: Generate the .ecoreThe ecore format is the textual representation of the model previously defined with the UML tool. The way to generate the .ecore file depends of the UML tool you have chosen, and it is out of the scope of this article. Opening the .ecore file in Eclipse should give the following.

Figure 8: the model in the Eclipse .ecore editor

Page 8: Integrating Java Beans with EMF in order to build ... · internationalized models Building model-centric applications with a modeling framework gives a lot of advantages. Separating

Section 5: Execute the genmodel commandThe UML tool I used to generate the .ecore file had also generated a .genmodel file and a .emf file. The genmodel file is a XML-formatted script that reads the .ecore and generate the EMF classes. The .emf file is the model defined using the Emfatic programming language, instanceof of being XML formatted. The Emfatic file is not essential for the subsequent operations, but is useful for model examination, in the case you prefer textually examine your model rather than using the .ecore editor. The .genbeans is a text file written by hand that is used to generate bean classes.

The following figure shows the file structure before and after executing the .genmodel script.

The original file structure. The file structure after running the genmodel script.

Figure 9: Generating the EMF model

Section 6: Structure of bean descriptor filesContrary to the .genmodel which is part of the standard EMF framework, the .genbeans is a proposed file format. It is so simple that you can write it by hand with the Eclipse built-in text editor. It consists only of three parameters: the first one defined the input .ecore, the second one the base package of generated file, and the last one the default package prefix.

We will discuss how to generate bean descriptor files (.java files in the .beans package) from this .genbeans script in the next section, but for now let's just examine the structure of descriptors files.

Page 9: Integrating Java Beans with EMF in order to build ... · internationalized models Building model-centric applications with a modeling framework gives a lot of advantages. Separating

Figure 10: The .genbeans file, opened with the Eclipse text editor.

The file structure before running the .genbeans script.

The file structure after running the genbeans script.

Figure 11: Generating the beans

The .beans folder contains informational classes. The .beans.properties folder contains icons and property files. BeanInfo classes read their properties from these files. Thus, running .genbeans internationalizes our EMF classes. Localization consists of adding property fields (one for each locale) in the .beans.properties folder.

Page 10: Integrating Java Beans with EMF in order to build ... · internationalized models Building model-centric applications with a modeling framework gives a lot of advantages. Separating

Let's expand the .purchasing and .purchasing.beans folders. The .purchasing package contains classes created by the .genmodel script. These files depend on java.beans classes, but do not depend of any external library.

The .purchasing.beans package contains the Introspector class, and a BeanInfo class for each EMF class present in the purchasing package.

If you open the AddressBeanInfo.java file (or any other file), you will notice that this class only depends on standard java.beans classes. The .genbeans script tool doesn't tie your classes with any proprietary library.

Also, the contents is quite simple. You could have created AddressBeanInfo.java by yourself. The .genbeans script just take avantage of the generic aspect of EMF to automate a process that would be long and repetitive otherwise.

Figure 12: Examining the generated bean info classes

The BeanInfo classes return descriptors about modeled classes. These descriptors are locale-dependant, consequently their values are not hard-coded in the .java classes. Instead, locale-dependent strings are placed in .properties files.

By default, .genbeans generates metadata in the English locale (assuming English is the language of the developer). The file is named metadata.properties. If would like to translate your application in other language such as French or Spanish, you have to create metadata_fr.properties and metadata_es.properties files from metadata.properties, and then translate each property of the file. Because the .properties file is a text file, the translation doesn't have to be done by a person who has programming skills. Refers to properties tutorial for more details about localization in Java3.

3 http://java.sun.com/developer/technicalArticles/Intl/ResourceBundles/

Page 11: Integrating Java Beans with EMF in order to build ... · internationalized models Building model-centric applications with a modeling framework gives a lot of advantages. Separating

Let's expand the .beans.properties package to examine its content.

Besides metadata.properties, you have one image file (called source image) per each modelized class. The image size is 32x32 pixels.

AdressBeanInfo defines four constants: ● ICON_COLOR_16x16 ● ICON_COLOR_32x32 ● ICON_MONO_16x60 ● ICON_MONO_32x32

AddressBeanInfo getIcon(kind) returns the source image if kind is ICON_COLOR_32x32. Otherwise, it will manipulate the image to return monochrome or 16x16 images.

The metadata.properties file defines the following property, which links the icon property with the actual image file.

Address.icon=Address.gif

Figure 12: Generated properties

When you translate the application, you can provide a locale-specific image for each target locale. This is necessary because icons may vary according the user's locale. For instance, an interface named Running may be illustrated in English by a person who is running, but it may doesn't make sense in other locale. Also, in an enumeration, NEXT and PREVIOUS icons may differ in the case of Arabic or Hebrew locale.

By default, .genbeans creates a blue bullet icon ( ) for each leaf concept (such as Address, Company, Product) and three small blue bullets ( ) for each composite concept (Purchase Order). A composite concept is a class that hold at least one component class.

Page 12: Integrating Java Beans with EMF in order to build ... · internationalized models Building model-centric applications with a modeling framework gives a lot of advantages. Separating

Section 7: Execute the genbeans command

In the previous section, we have discussed of the .genbeans script and the resulting bean descriptor files. But how to generate the resulting Java files from the .genbeans script (shown below).

Figure 13: The .genbeans file, opened with the Eclipse text editor.

There are three ways to create bean descriptor files from the .genbeans file:• Write bean descriptors manually• Execute an ANT script to do it automatically• Installing an Eclipse plug-in that would have generate code automatically

The first and less elaborated way is simply to write them manually. Because the content of bean descriptor files is very simple, it is not as difficult as it could appear at the first glance.

public interface Address extends EObject { //code generated by .genmodel

}

public class AddressBeanInfo extends EBeanInfo { public AddressBeanInfo() { super( PurchasingPackage.eINSTANCE. getAddress()); }}

An EObject generated by .genmodel Its corresponding BeanInfo file, created manually or automatically.

The problem with this method is each time you create a new kind of EObject, it's your responsibility to maintain the bean descriptor files. Although it possible to write bean classes without using the script, running the script allows to get rid of tedious manual operations.

The second method is to create an ANT script that would make the code generation job for us.

<project default="genbeans"> <target name="genbeans"> <java classname="com.neosapiens.dmf.core.genbeans.plugin.command.GenBeans"> <arg value="Purchasing.genbeans"/> <classpath> <pathelement location=".../com.neosapiens.dmf.core.genbeans.plugin/bin/"/> <pathelement location="...org.eclipse.emf.common_2.5.0.v....jar"/>

Page 13: Integrating Java Beans with EMF in order to build ... · internationalized models Building model-centric applications with a modeling framework gives a lot of advantages. Separating

<pathelement location=".../org.eclipse.emf.ecore_2.5.0.v....jar"/> <pathelement location=".../lib/velocity-1.6.2/velocity-1.6.2.jar"/> </classpath> </java> <echo message="Beans desciptors successfully generated"/> </target> </project>

Figure: Building the ANT script

Figure: The result after executing the script

The third way to generate is to install the genbeans plug-in. It the most user-friendly approach, but we have an extra step: installing a special genbeans plug-in. The genbean functionality is similar the the genmodel function of the EMF plug-in.

domain.genmodel file

EMF plug-indomaindomain.impldomain.util

domain.genbeans file

GenBeans plug-indomain.beansdomain.beans.properties

Source files Eclipse Plug-ins Generated Java files

Page 14: Integrating Java Beans with EMF in order to build ... · internationalized models Building model-centric applications with a modeling framework gives a lot of advantages. Separating

Figure : Generate bean from contextual menu on .genbeans files (requires Eclipse plug-in)

Section 8: Create a new localeThe first step after running the .genbeans script would be to verify if the strings contained in the generated metadata.properties file are compliant with English language rules (assuming English is the developer's language).

CanadianAddress.displayName.gender=defaultCanadianAddress.displayName.plural=Canadian AddressesCanadianAddress.displayName.singular=Canadian AddressCanadianAddress.feature.displayName.civicNumber=Civic NumberCanadianAddress.feature.displayName.designation=DesignationCanadianAddress.feature.displayName.postalCode=Postal CodeCanadianAddress.feature.displayName.province=ProvinceCanadianAddress.feature.displayName.street=Street

In the case illustrated above, .genbeans has correctly converted the camel-case programmatic name (CanadianAddress) into English locale (Canadian Address). The plural name of Address (Addresses) and Company (Companies) have also be correctly generated.

Because English (as most other languages) has irregular rules, it is expected that .genbeans won't correctly translate all the strings correctly. You can assume that the Pareto rule would apply here: .genbeans would correctly translate 80% of the strings, the remaining 20% requires human intervention.

If errors are found, it is recommended to place the corrected strings into a file named metadata_en.properties that you create from scratch. The file does not contain all the strings of metadata.properties, only corrected strings. If current locale is English, strings defined in metadata_en.properties will override those in metadata.properties. Also, the next time you will execute again .genbeans, the metadata.properties file will be overwritten, but your metadata_en.properties will be left intact.

Translating in French implies creating a metadata_fr.properties and translate all its values (right side oif the equal sign). The keys (left side of the equal sign) must be kept untouched, otherwise BeanInfo classes won't be able to retrieve localized strings.

Page 15: Integrating Java Beans with EMF in order to build ... · internationalized models Building model-centric applications with a modeling framework gives a lot of advantages. Separating

CanadianAddress.displayName.gender=feminineCanadianAddress.displayName.plural=Adresses canadiennesCanadianAddress.displayName.singular=Adresse canadienneCanadianAddress.feature.displayName.civicNumber=Numéro civiqueCanadianAddress.feature.displayName.designation=AppellationCanadianAddress.feature.displayName.postalCode=Code postalCanadianAddress.feature.displayName.province=ProvinceCanadianAddress.feature.displayName.street=Rue

Strings may differ according the country. For instance, French spoken in France may differ from French spoken in Canada:

Address.feature.displayName.emailAddress=Adresse emailmetadata_fr_FR.properties

Address.feature.displayName.emailAddress=Adresse courrielmetadata_fr_CA.properties

In addition of language and country, it is possible to specify variant for community-specific strings. Variants may include regional settings, professional communities, styles and notations, etc.

Section 9: Extended descriptorsIn addition of standard Java beans description fields (displayName, hidden, expert, etc.) discussed in section 2, EFeatureDescriptor supports these extra fields:

scrambled A Boolean that tells if a given property is intended to be scrambled in the user interface. Password is a typical scrambled property.

sensitive A Boolean that tells if a given class or property contains sensitive information. Sensitive information are not expected to be exported to an external applications.

rank An integer that indicates the rank in which a given feature (attribute or reference) is expected to be rendered. Each feature (attribute and reference) has a sequential rank (1, 2, 3...). Features are listed according their rank. Ranks differ according the locale (for instance, months are displayed before days in the US English locale).

regex A regular expression to which string attributes must comply. For instance, [a-zA-Z0-9_.]+@[a-zA-Z0-9_.]+ validates email address.

pattern Same as regex, but pattern is used in error messages for end-users. For instance, [email protected] is the email address' pattern.

multiline For string values, specify the number of lines used for text capture.

Page 16: Integrating Java Beans with EMF in order to build ... · internationalized models Building model-centric applications with a modeling framework gives a lot of advantages. Separating

Section 10: Client Programming

Snippet 1//List the name of the classespublic class Snippet01 { public static void main(String[] args) { PurchasingPackage pack = PurchasingPackage.eINSTANCE; List<EClass> classes = getClasses(pack); String msg = MessageFormat.format("Package {0} has {1} classes:", pack.getName(), classes.size()); System.out.println(msg); for (EClass claz : classes) { String name = claz.getName(); msg = MessageFormat.format(" -{0}", name); System.out.println(msg); } } //end main()

private static List<EClass> getClasses(PurchasingPackage pack) { List<EClass> classes = new ArrayList<EClass>(); List<EClassifier> classifiers = pack.getEClassifiers(); for (EClassifier classifier : classifiers) { if (classifier instanceof EClass) { classes.add((EClass)classifier); } } return classes; }

OutputPackage purchasing has 10 classes: -Address -Item -PurchaseOrder -CanadianAddress -USAddress -Product -DistributionCenter -Company -Organization -InternationalAddress

Page 17: Integrating Java Beans with EMF in order to build ... · internationalized models Building model-centric applications with a modeling framework gives a lot of advantages. Separating

Snippet 2

//List the display name of the classespublic class Snippet02 { public static void main(String[] args) { PurchasingPackage pack = PurchasingPackage.eINSTANCE; List<EClass> classes = getClasses(pack); String msg = MessageFormat.format("Package {0} has {1} classes:", pack.getName(), classes.size()); System.out.println(msg); for (EClass claz : classes) {| Class c = claz.getInstanceClass();| BeanInfo info = Introspector.getBeanInfo(c);| BeanDescriptor desc = info.getBeanDescriptor();| String name = desc.getDisplayName(); msg = MessageFormat.format(" -{0}", name); System.out.println(msg); } } //end main()

OutputPackage purchasing has 10 classes: -Address -Item -Purchase Order -Canadian Address -US Address -Product -Distribution Center -Company -Organization -International Address

Page 18: Integrating Java Beans with EMF in order to build ... · internationalized models Building model-centric applications with a modeling framework gives a lot of advantages. Separating

Snippet 3

//List the singular and plural name of the classespublic class Snippet03 { public static void main(String[] args) { PurchasingPackage pack = PurchasingPackage.eINSTANCE; List<EClass> classes = getClasses(pack); String msg = MessageFormat.format("Package {0} has {1} classes:", pack.getName(), classes.size()); System.out.println(msg); for (EClass claz : classes) { Class c = claz.getInstanceClass(); EBeanInfo info = (EBeanInfo)Introspector.getBeanInfo(c); EBeanDescriptor desc = (EBeanDescriptor)info.getBeanDescriptor();| String singular = desc.getDisplayName(); | String plural = desc.getDisplayName(true); | msg = MessageFormat.format(" -{0} (plural: {1})", singular, plural); System.out.println(msg); } } //end main()

OutputPackage purchasing has 10 classes: -Address (plural: Addresses) -Item (plural: Items) -Purchase Order (plural: Purchase Orders) -Canadian Address (plural: Canadian Addresses) -US Address (plural: US Addresss) -Product (plural: Products) -Distribution Center (plural: Distribution Centers) -Company (plural: Companies) -Organization (plural: Organizations) -International Address (plural: International Addresses)

Page 19: Integrating Java Beans with EMF in order to build ... · internationalized models Building model-centric applications with a modeling framework gives a lot of advantages. Separating

Snippet 4

//list the display name of classes and their attributespublic class Snippet04 { public static void main(String[] args) { PurchasingPackage pack = PurchasingPackage.eINSTANCE; List<EClass> classes = getClasses(pack); String msg = MessageFormat.format("Package {0} has {1} classes:", pack.getName(), classes.size()); System.out.println(msg); for (EClass claz : classes) { Class c = claz.getInstanceClass(); EBeanInfo info = (EBeanInfo)Introspector.getBeanInfo(c); EBeanDescriptor desc = (EBeanDescriptor)info.getBeanDescriptor(); String singular = desc.getDisplayName(); | String attributeList = getAttributeList(claz, info);| msg = MessageFormat.format(" -{0} ({1})", singular, attributeList); System.out.println(msg); } } //end main()

Page 20: Integrating Java Beans with EMF in order to build ... · internationalized models Building model-centric applications with a modeling framework gives a lot of advantages. Separating

private static String getAttributeList(EClass claz, EBeanInfo info) { String attributeList = ""; List<EAttribute> attributes = claz.getEAllAttributes(); Iterator<EAttribute> iter = attributes.iterator(); boolean added = false; while (iter.hasNext()) { EAttribute attribute = iter.next(); PropertyDescriptor desc = info.getPropertyDescriptor(attribute); if (! desc.isExpert()) { String attributeName = desc.getDisplayName(); attributeList += attributeName; added = true; } if (added && iter.hasNext()) { attributeList += ", "; } } return attributeList; }

OutputPackage purchasing has 10 classes: -Address (Civic Number, Street) -Item (Quantity) -Purchase Order (Order Date, Status, Shipping Date, Finalized) -Canadian Address (Civic Number, Street, Province, Postal Code) -US Address (Civic Number, Street, State, Zip Code) -Product (Name, Sku, US price, Color, Weight, Labeled) -Distribution Center (Champ, Name) -Company (Name) -Organization (Name) -International Address (Civic Number, Street, Country, Postal Code)

Page 21: Integrating Java Beans with EMF in order to build ... · internationalized models Building model-centric applications with a modeling framework gives a lot of advantages. Separating

Snippet 5

//list the display name of classes and their attributes, in UK localepublic class Snippet05 { public static void main(String[] args) {| Locale.setDefault(Locale.UK); PurchasingPackage pack = PurchasingPackage.eINSTANCE; List<EClass> classes = getClasses(pack); String msg = MessageFormat.format("Package {0} has {1} classes:", pack.getName(), classes.size()); System.out.println(msg); for (EClass claz : classes) { Class c = claz.getInstanceClass(); EBeanInfo info = (EBeanInfo)Introspector.getBeanInfo(c); EBeanDescriptor desc = (EBeanDescriptor)info.getBeanDescriptor(); String singular = desc.getDisplayName(); String attributeList = getAttributeList(claz, info); msg = MessageFormat.format(" -{0} ({1})", singular, attributeList); System.out.println(msg); } } //end main()

OutputPackage purchasing has 10 classes: -Address (Civic Number, Street) -Item (Quantity) -Purchase Order (Order Date, Status, Shipping Date, Finalised) -Canadian Address (Civic Number, Street, Province, Postal Code) -US Address (Civic Number, Street, State, Zip Code) -Product (Name, Sku, US price, Colour, Weight, Labelled) -Distribution Centre (Champ, Name) -Company (Name) -Organisation (Name) -International Address (Civic Number, Street, Country, Postal Code)