# App Sample
Version: 1.0 | Release Date: 30/6/2018
# Things to know
Our app example is a simple book borrowing program that contains two main objects: Book
and Member
- The member's profile stores his borrowing history
- The
Available
Property of Book decided whether it can be borrowed or not - Each book has an ISBN number that checks its validity each time it is saved.
- Users can also manually check the ISBN before saving.
- Add a Printing Report to the
Member
- Add a EBI Report to the
Member
You can download the runable code of the entire app from github (opens new window)
# Define App in App.xml
p-share\src\main\resources\META-INF\app.xml
<?xml version="1.0"?>
<app xmlns="http://www.multiable.com/app">
<name>opcq</name>
<version>1.0</version>
<description>Opcq App</description>
<dependences>
<dependence id="caw" versions="1.0" />
</dependences>
<ear>caw_ear</ear>
<ejb>p-ejb</ejb>
</app>
See App.xml for other available setting parameters.
# Define Table Structure in datadict.xml
p-share\src\main\resources\META-INF\datadict.xml
<?xml version="1.0"?>
<dd xmlns="http://www.multiable.com/datadict">
<table name="opcqbookcat" mess="opcq.bookCat" pk="id">
<inherit name="module_fm" />
<column name="code" type="varchar" mess="core.code" length="20" defPattern="fmCode" required="true" batchUpdate="false"/>
<column name="desc" type="varchar" mess="core.description" length="100" defPattern="charDesc" i18nField="true" batchUpdate="true"/>
<index name="module_code" columns="code" />
</table>
<table name="opcqbook" mess="opcq.book" pk="id" >
<inherit name="module_fm" />
<column name="code" type="varchar" mess="opcq.bookCode" length="40" defPattern="fmCode" required="true" batchUpdate="false"/>
<column name="isbn" type="varchar" mess="opcq.isbn" length="40" defPattern="char20" required="true" batchUpdate="false"/>
<column name="desc" type="varchar" mess="opcq.title" length="200" defPattern="charDesc" i18nField="true" batchUpdate="true"/>
<column name="author" type="varchar" mess="opcq.author" length="100" defPattern="char60" i18nField="true" batchUpdate="true"/>
<column name="publisher" type="varchar" mess="opcq.publisher" length="100" defPattern="char100" i18nField="true" batchUpdate="true"/>
<column name="pDate" type="datetime" mess="opcq.pDate" defValue="NOW()" defPattern="date"/>
<column name="photoCode" type="varchar" mess="opcq.coverImg" length="60" defPattern="imgCode" />
<column name="bookCatId" type="int_unsigned" mess="opcq.bookCat" defValue="0" defPattern="opcqBookCat" batchUpdate="false"/>
<column name="avail" type="bit" mess="opcq.avail" defValue="0" defPattern="check"/>
<index name="module_isbn" columns="isbn" unique="true"/>
</table>
<table name="opcqmem" mess="opcq.mem" pk="id" >
<inherit name="module_fm" />
<column name="code" type="varchar" mess="opcq.memNo" length="60" defPattern="fmCode" required="true" batchUpdate="false"/>
<column name="desc" type="varchar" mess="opcq.name" length="200" defPattern="char50" i18nField="true" required="true" batchUpdate="true"/>
<column name="card" type="varchar" mess="opcq.cardNum" length="60" defPattern="char30" required="true" batchUpdate="false"/>
<column name="email" type="varchar" mess="opcq.email" length="200" defPattern="char100" batchUpdate="true"/>
<column name="addr" type="varchar" mess="opcq.address" length="-1" defPattern="char2000" i18nField="true"/>
<index name="module_code" columns="code"/>
</table>
<table name="opcqmemt" mess="opcq.memt" pk="id">
<inherit name="id_irev" />
<column name="hId" type="int_unsigned" mess="opcq.mem" defValue="0" defPattern="opcqMem" dataImport="false" dataExport="false" buildin="true"/>
<column name="itemNo" type="varchar" mess="core.itemNo" length="12" defPattern="char6" dataEasy="true" dataImport="false" dataExport="false"/>
<column name="bookId" type="int_unsigned" mess="opcq.bookCode" defValue="0" defPattern="opcqBook" required="true"/>
<column name="bDate" type="datetime" mess="opcq.bDate" defValue="NOW()" defPattern="date"/>
<column name="rDate" type="datetime" mess="opcq.rDate" defValue="NOW()" defPattern="date"/>
<fk name="book" columns="bookId" refTable="opcqbook" refColumns="id" />
</table>
</dd>
See Datadict.xml for other available setting parameters.
For reuse purposes, the properties of the field can be defined by Pattern.xml
<?xml version="1.0"?>
<pattern xmlns="http://www.multiable.com/pattern">
<record code="opcqBookCat" type="lookup">
<lookup searchType="opcqBookCat"/>
</record>
<record code="opcqBook" type="lookup">
<lookup searchType="opcqBook"/>
</record>
<record code="opcqMem" type="lookup">
<lookup searchType="opcqMem"/>
</record>
</pattern>
# Define Module in module.xml
This app has a total of three modules, they are:
Book Category
Book
Member
p-share\src\main\resources\META-INF\module.xml
<?xml version="1.0"?>
<md xmlns="http://www.multiable.com/module" app="opcq">
<module name="opcqBookCat" mess="opcq.bookCat" extend="false" mainTable="opcqbookcat" recType="" useAccess="true" useAttach="true" useBeShare="true" useApv="true" useChangenote="true" fmShare="Y" genCode_Type="BC">
<table name="opcqbookcat" key="id" c="true" r="true" d="true" u="true" initRow="1" hpk="" fKey="" order=""/>
</module>
<module name="opcqBook" mess="opcq.book" extend="false" mainTable="opcqbook" recType="" useAccess="true" useAttach="true" useBeShare="true" useApv="true" useChangenote="true" fmShare="Y" genCode_Type="BK">
<table name="opcqbook" key="id" c="true" r="true" d="true" u="true" initRow="1" hpk="" fKey="" order=""/>
<checker class="com.multiable.opcq.ejb.checker.OpcqBookChecker"/>
</module>
<module name="opcqMem" mess="opcq.mem" extend="false" mainTable="opcqmem" recType="" useAccess="true" useAttach="true" useBeShare="true" useApv="true" useChangenote="true" fmShare="Y" importThreadMode="false" genCode_Type="MEM">
<table name="opcqmem" key="id" c="true" r="true" d="true" u="true" initRow="1" hpk="" fKey="" order=""/>
<table name="opcqmemt" key="id" c="true" r="true" d="true" u="true" initRow="0" hpk="hId" fKey="" order="" cpnType="table"/>
</module>
</md>
See Module.xml for other available setting parameters.
# Define Menu in navmenu.xml
This app has a total of four menus, they are:
Book Category
Book
Member
- EBI for
Member
p-share\src\main\resources\META-INF\navmenu.xml
<?xml version="1.0"?>
<nm xmlns="http://www.multiable.com/navmenu" app="opcq">
<folder code="m18Opcq" messCode="opcq.opcqApp">
<menu code="opcqBookCat" messCode="opcq.bookCat" src="view/opcq/module/opcqBookCat" module="opcqBookCat" mType="FM" order="1000">
<inherit name ="module_fc" />
</menu>
<menu code="opcqBook" messCode="opcq.book" src="view/opcq/module/opcqBook" module="opcqBook" mType="FM" order="2000">
<inherit name ="module_fc" />
</menu>
<menu code="opcqMem" messCode="opcq.mem" src="view/opcq/module/opcqMem" module="opcqMem" mType="FM" order="3000">
<inherit name ="module_fc" />
</menu>
<folder code="biOpcq" messCode="opcq.ebi" order="4000">
<icon name="cicon-ebi" library="font/cawIcon"/>
<menu code="M18_EBI_OPCQMEM" messCode="opcq.memRep" src="view/module/ebi/ebi" mType="EBI" order="1000">
<icon name="cicon-ebi-report" library="font/cawIcon"/>
<inherit name="module_ebi"/>
</menu>
</folder>
</folder>
</nm>
See NavMenu.xml for other available setting parameters.
# i18N Support
In order to avoid conflicts with other apps, the Key of each translation item is prefixed with Appname.
p-share\src\main\resources\META-INF\lang\Message_en.properties
p-share\src\main\resources\META-INF\lang\Message_zh-CN.properties
p-share\src\main\resources\META-INF\lang\Message_zh-TW.properties
# App Screenshot
Book Category
Book
Add books to Member