====== CasesJ2EE ====== ===== Autorzy ===== * Grzegorz Leśniakiewicz * Tomasz Maruszak ===== Opis projektu ===== Projekt polega na wyszukaniu aplikacji napisanej w technologii j2ee, zrealizowanej zgodnie z modelem MVC oraz na zapisaniu logiki biznesowej w postaci reguł. ===== Duke's Bank ===== Jest to case study zastosowania technologii Java EE 5 do stworzenia przykładowego systemu bankowości elektronicznej. System wyposażony jest w interfejs web, w którym klienci banku mogą zlecać przelewy oraz przeglądać historię transakcji. Pracownicy banku posiadają dostęp do systemu poprzez klienta desktop, w którym mogą zarządzać kontami i użytkownikami. ==== Architektura aplikacji ==== {{ http://java.sun.com/javaee/5/docs/tutorial/doc/figures/bank-appFlow.gif |Architektura aplikacji}} ==== Aplikacje klienckie ==== ^ Klient web ^ Klient desktop ^ | {{http://java.sun.com/javaee/5/docs/tutorial/doc/figures/dukesbank-appClientCustomer.gif?400|Klient desktop}} | {{http://java.sun.com/javaee/5/docs/tutorial/doc/figures/bank-accountHist.gif?400|Klient web}} | ==== Technologia ==== Aplikacja jest napisana w technologii Java EE 5. Warstwa prezentacji została zrealizowana zgodnie z wzorcem MVC ([[http://java.sun.com/javaee/javaserverfaces/|JavaServer Faces 1.2]]). Aplikację uruchomiliśmy na serwerze aplikacji [[https://glassfish.dev.java.net/downloads/v2.1-b60e.html|GlassFish V2]]. ==== Reguły ==== Reguły opisujące warstwę logiki EJB projektu. Rule 1: TxController.checkAccountArgs(BigDecimal amount, String description, Long accountId, Account account) if amount > 0 and !isEmpty(description) and exists(accountId) then account is selectAccount(accountId). Rule 2: TxController.withdraw(BigDecimal amount, String description, Long accountId, UserPrincipal userPrincipal) if userPrincipal = 'bankCustomer' and amount > 0 and checkAccountArgs(amount, description, accountId, account) and !isCreditAccount(account.type) and account.balance - amount > 0 then executeTx(-amount, description, account.balance - amount, account). Rule 3: TxController.deposit(BigDecimal amount, String description, Long accountId, UserPrincipal userPrincipal) if userPrincipal = 'bankCustomer' and amount > 0 and checkAccountArgs(amount, description, accountId, account) and !isCreditAccount(account.type) then executeTx(amount, description, account.balance + amount, account). Rule 4: TxController.makeCharge(BigDecimal amount, String description, Long accountId, UserPrincipal userPrincipal) if userPrincipal = 'bankCustomer' and amount > 0 and checkAccountArgs(amount, description, accountId, account) and isCreditAccount(account.type) and account.balance + amount > account.creditLine then executeTx(amount, description, account.balance + amount, account). Rule 5: TxController.makePayment(BigDecimal amount, String description, Long accountId, UserPrincipal userPrincipal) if userPrincipal = 'bankCustomer' and amount > 0 and checkAccountArgs(amount, description, accountId, account) and isCreditAccount(account.type) then executeTx(amount, description, account.balance - amount, account). Rule 6: TxController.transferFunds.rule1(BigDecimal amount, String description, Long fromAccountId, Long toAccountId, UserPrincipal userPrincipal) if userPrincipal = 'bankCustomer' and amount > 0 and checkAccountArgs(amount, description, fromAccountId, fromAccount) and checkAccountArgs(amount, description, toAccountId, toAccount) and isCreditAccount(fromAccount.type) and isCreditAccount(toAccount.type) and fromAccount.balance + amount <= fromAccount.creditLine then executeTx(amount, description, fromAccount.balance + amount, fromAccount), executeTx(-amount, description, toAccount.balance - amount, toAccount). Rule 7: TxController.transferFunds.rule2(BigDecimal amount, String description, Long fromAccountId, Long toAccountId, UserPrincipal userPrincipal) if userPrincipal = 'bankCustomer' and amount > 0 and checkAccountArgs(amount, description, fromAccountId, fromAccount) and checkAccountArgs(amount, description, toAccountId, toAccount) and isCreditAccount(fromAccount.type) and !isCreditAccount(toAccount.type) and fromAccount.balance + amount <= fromAccount.creditLine then executeTx(amount, description, fromAccount.balance + amount, fromAccount), executeTx(amount, description, toAccount.balance + amount, toAccount). Rule 8: TxController.transferFunds.rule3(BigDecimal amount, String description, Long fromAccountId, Long toAccountId, UserPrincipal userPrincipal) if userPrincipal = 'bankCustomer' and amount > 0 and checkAccountArgs(amount, description, fromAccountId, fromAccount) and checkAccountArgs(amount, description, toAccountId, toAccount) and !isCreditAccount(fromAccount.type) and isCreditAccount(toAccount.type) and fromAccount.balance - amount >= 0 then executeTx(-amount, description, fromAccount.balance - amount, fromAccount), executeTx(-amount, description, toAccount.balance - amount, toAccount). Rule 9: TxController.transferFunds.rule4(BigDecimal amount, String description, Long fromAccountId, Long toAccountId, UserPrincipal userPrincipal) if userPrincipal = 'bankCustomer' and amount > 0 and checkAccountArgs(amount, description, fromAccountId, fromAccount) and checkAccountArgs(amount, description, toAccountId, toAccount) and !isCreditAccount(fromAccount.type) and !isCreditAccount(toAccount.type) and fromAccount.balance - amount >= 0 then executeTx(-amount, description, fromAccount.balance - amount, fromAccount), executeTx(amount, description, toAccount.balance + amount, toAccount). Rule 10: TxController.executeTx(BigDecimal amount, String description, BigDecimal newBalance, Account account, UserPrincipal userPricipal) if userPrincipal = 'bankCustomer' then tx is Tx(account, TimeNow, amount, newBalance, description), persist(tx). Rule 11: AccountController.createAccount(AccountDetails details, Long customerId, UserPrincipal userPrincipal) if userPrincipal = 'bankAdmin' and !isEmpty(details.type) and !isEmpty(details.description) and !isEmpty(details.beginBalanceTimeStamp) and exists(cusomerId) then account is Account(details), persist(account), add(customerId, account). Rule 12: AccountController.removeAccount(Long accountId, UserPrincipal userPrincipal) if userPrincipal = 'bankAdmin' then remove(accountId). Rule 13: AccountController.addCustomerToAccount(Long customerId, Long accountId, UserPrincipal userPrincipal) if userPrincipal = 'bankAdmin' and exists(customerId) and exists(accountId) then add(customerId, accountId). Rule 14: AccountController.removeCustomerFromAccount(Long customerId, Long accountId, UserPrincipal userPrincipal) if userPrincipal = 'bankAdmin' and exists(customerId) and exists(accountId) then remove(customerId, accountId). Rule 15: AccountController.getAccountsOfCustomer(Long customerId, List accountDetails) if exists(customerId) then accountDetails is selectAccountByCustomer(customerId). Rule 16: AccountController.getCustomerIds(Long accountId, List customers) if exists(accountId) then customers is selectAccountCustomers(customerId). Rule 17: AccountController.getDetails(Long accountId, AccountDetails accountDetails) if exists(accountId) then accountDetails is selectAccount(accountId). Rule 18: CustomerController.createCustomer(CustomerDetails details, UserPrincipal userPrincipal) if userPrincipal = 'bankAdmin' and !isEmpty(details.firstName) and !isEmpty(details.lastName) then customer is Customer(details), persist(customer). Rule 19: CustomerController.removeCustomer(Long customerId, UserPrincipal userPrincipal) if userPrincipal = 'bankAdmin' and exists(customerId) then remove(customerId). Rule 20: CustomerController.getDetails(Long customerId, CustomerDetails customerDetails) if exists(customerId) then Customer(customerDetails) is selectCustomer(customerId). Rule 21: CustomerController.getCustomersOfAccount(Long accountId, List customerDetails) if exists(accountId) then account is selectAccount(accountId), Customer(customerDetails) is account.customers. Rule 22: CustomerController.getCustomersOfLastName(String lastName, List customerDetails, UserPrincipal userPrincipal) if userPrincipal = 'bankAdmin' and !isEmpty(lastName) then Customer(customerDetails) is selectCustomerByName(lastName). ==== Źródła i dokumentacja ==== Kod źródłowy jest do pobrania ze strony producenta [[http://java.sun.com/javaee/downloads/|Java EE Downloads]] - należy wybrać "Java EE 5 Samples". Dokumentacja dostępna jest tu [[http://java.sun.com/javaee/5/docs/tutorial/doc/bnclz.html|Java EE 5 Tutorial]]. ===== Sprint (e-Protokół) ===== Sprint jest to aplikacja stworzona na potrzeby wydziału EAIiE. Umożliwia obsługę rejestracji użytkowników, tworzenia newsów, zarządzania artykułami, zarządzania kalendarzem. Dodatkowo został stworzony moduł e-Protokół, umożliwiający automatyzację procesu obsługi protokołów w obrębie wydziału EAIiE. E-protokół, obsługuje przepływ e-protokołów od momentu stworzenia, lub importu poprzez obsługę w dziekanacie, dziekanatach katedr, przez prowadzących zajęcia do momentu zamknięcia, wydruku i eksportu e-protokołu. {{ :pl:miw:2009:sprint.jpg?800 |Sprint e-protokół na borg}} Poniżej zaprezentowany jest przepływ biznesowy e-protokołu. {{ :pl:miw:2009:eprotocol_gl_tm.jpg?550 |}} Aplikacja obecnie jest wdrożona na środowisku developerskim. Główne funkcjonalności systemu zostaną wdrożone produkcyjnie w najbliższym czasie, natomiast wdrożenie produkcyjne modułu e-Protokołu przewidziane jest na wrzesień bieżącego roku. Obecny adres serwisu na środowisku developerskim (dostępny z wewnątrz sieci AGH, bez modułu e-Protokół) * [[http://wwwdev.eaie.agh.edu.pl/]] Adres środowiska testowego (zawiera moduł e-Protokół) * [[http://borg.ia.agh.edu.pl:8080/Sprint-web/]] ==== Technologia ==== Aplikacja jest napisana w technologii Java EE 5. Wzorzec MVC został zrealizowany przy użyciu technologii [[http://java.sun.com/javaee/javaserverfaces/|JavaServer Faces 1.2]] (implementacja [[https://facelets.dev.java.net/|Facelets]]) oraz frameworku [[http://seamframework.org/|Seam]]. Aplikacja jest uruchamiana na serwerze aplikacji [[http://www.jboss.org/jbossas/downloads/|JBoss 4.2.2]]. Silnik bazy danych to [[http://www.postgresql.org/download/|PostgreSQL]]. ==== Opisanie modułu e-Protokół w postaci reguł ==== Rule 1: EProtocolEditForSecretariatBean.editEProtocol.rule1(EProtocolEditForSecretariatBean bean, Boolean isEditingEnabled) if isEditingEnabled = true then bean.cancelEditingEProtocol(). Rule 2: EProtocolEditForSecretariatBean.enableEditingEProtocol.rule1(List assignedLecturersList, Boolean isEditingEnabled) if assignedLecturersList.length > 0 then isEditingEnabled is false. Rule 3: EProtocolEditForSecretariatBean.enableEditingEProtocol.rule2(List assignedLecturersList, Boolean isEditingEnabled) if assignedLecturersList.length = 0 then isEditingEnabled is true. Rule 4: EProtocolEditForSecretariatBean.chooseTheLecturer.rule1(EProtocol selectedEProtocol) if selectedEProtocol.state = ACCEPTED then selectedEProtocol.state is NEW. Rule 5: EProtocolEditForSecretariatBean.prepareToDeleteTheAssigment.rule1(List lecturersMark, Boolean deletingEnabled) if markToDelete.length > 0 then deletingEnabled is false. Rule 6: EProtocolEditForSecretariatBean.prepareToDeleteTheAssigment.rule2(List lecturersMark, Boolean deletingEnabled) if markToDelete.length = 0 then deletingEnabled is true. Rule 7: EProtocolEditForSecretariatBean.deleteTheAssigment.rule2(List courseUserRels, EProtocol selectedEProtocol) if courseUserRel.length = 0 and if selectedEProtocol.state = ACCEPTED then selectedEProtocol.state is NEW. Rule 8: EProtocolEditForSecretariatBean.deleteTheAssigment.rule3(List courseUserRels, List courseUserRelsNotAccepted, EProtocol selectedEProtocol) if courseUserRel.length > 0 and if courseUserRelsNotAccepted.length = 0 and if selectedEProtocol.state = NEW then selectedEProtocol.state is ACCEPTED. Rule 9: EProtocolEditForSecretariatBean.isChangingEnabled.rule1(EProtocol selectedEProtocol, Boolean changing) if selectedEProtocol.state = CLOSED then changing is true. Rule 10: EProtocolEditForSecretariatBean.isChangingEnabled.rule2(EProtocol selectedEProtocol, Boolean changing) if selectedEProtocol.state != CLOSED then changing is false. Rule 11: EProtocolEditForLecturerBean.acceptEProtocol.rule1(CourseUserRel rel, Boolean isAcceptedByLecturer) if rel.state != ACCEPTED then rel.state is ACCEPTED, isAcceptedByLecturer is true. Rule 12: EProtocolEditForLecturerBean.acceptEProtocol.rule1(CourseUserRel rel, Boolean isAcceptedByLecturer) if rel.state = ACCEPTED then isAcceptedByLecturer is true. Rule 13: EProtocolEditForLecturerBean.acceptEProtocol.rule2(List courseUserRels, EProtocol selectedEProtocol) if courseUserRel = 0 then selectedEProtocol.state is ACCEPTED. Rule 14: EProtocolEditForLecturerBean.acceptEProtocol.rule3(List courseUserRels, List courseUserRelsNotAccepted, EProtocol selectedEProtocol) if courseUserRel.length > 0 and if courseUserRelsNotAccepted.length = 0 then selectedEProtocol.state is ACCEPTED. Rule 15: EProtocolEditForLecturerBean.unAcceptEProtocol.rule1(CourseUserRel rel, Boolean isAcceptedByLecturer, EProtocol selectedEProtocol) if selectedEProtocol.state = ACCEPTED then selectedEProtocol.state is NEW, rel.state is NEW, isAcceptedByLecturer is false. Rule 16: EProtocolEditForLecturerBean.addMarkDateType.rule1(Mark addingMark, Utils util) if addingMark.date.isSet() = false then addingMark.date is util.getFormattedNowDate(). Rule 17: EProtocolPrintBean.unlockEProtocol.rule1(EProtocol eProtocol, List courseUserRelsNotAccepted) if eProtocol.state = CLOSED and if courseUserRelsNotAccepted = 0 then eProtocol.state is ACCEPTED. Rule 18: EProtocolPrintBean.unlockEProtocol.rule2(EProtocol eProtocol, List courseUserRelsNotAccepted) if eProtocol.state = CLOSED and if courseUserRelsNotAccepted > 0 then eProtocol.state is NEW. Rule 19: EProtocolPrintBean.isClosed.rule1(EProtocol eProtocol, Boolean isClosed) if eProtocol.state = CLOSED then isClosed is true. Rule 20: EProtocolPrintBean.isClosed.rule2(EProtocol eProtocol, Boolean isClosed) if eProtocol.state != CLOSED then isClosed is false. Rule 21: EProtocolStudentListBean.prepareToDeleteStudent.rule1(List studentMarks, Boolean isDeleteEnabled) if studentMarks.length > 0 then isDeleteEnabled is false. Rule 22: EProtocolStudentListBean.prepareToDeleteStudent.rule2(List studentMarks, Boolean isDeleteEnabled) if studentMarks.length = 0 then isDeleteEnabled is true. Rule 23: EProtocolStudentListForCourseBean.prepareToDeleteStudent.rule1(List studentMarksForCourse, Boolean isDeleteEnabled) if studentMarksForCourse.length > 0 then isDeleteEnabled is false. Rule 24: EProtocolStudentListForCourseBean.prepareToDeleteStudent.rule2(List studentMarksForCourse, Boolean isDeleteEnabled) if studentMarksForCourse.length = 0 then isDeleteEnabled is true. ===== Źródło projektów Java Enterprise ===== W poszukiwaniu projektów korporacyjnej Javy warto zajrzeć do inkubatora projektów [[https://enterprise-incubator.dev.java.net/|java.net]].