task: MVVM design pattern using zkoss framework. (#1678)

* MVVM design pattern using zkoss framework.

* MVVM Design pattern updates for issues reported by SonarCloud.

* MVVM Design pattern updates for coverage issues reported by SonarCloud.

* MVVM Design pattern updates for coverage issues (removing lombok @Data)
reported by SonarCloud.

* MVVM Design pattern updates for coverage issues reported by Sonar - TEST
cases added for Equals and ToString

* MVVM Design Pattern - updating missing/todo details.

* MVVM Design Pattern - adding lombok.config

* MVVM Design Pattern - Removing xml, updating pom.xml and README as per
suggested changes in code review

* Update model-view-viewmodel/README.md

* Update model-view-viewmodel/README.md

* Update model-view-viewmodel/README.md

* Update model-view-viewmodel/README.md

* MVVM Design Pattern - Updated pom.xml and Readme based on Suggested
changes

* added type as xml

* MVVM Design Patterm - root pom.xml and module pom.xml updated

* Update pom.xml

Co-authored-by: Subhrodip Mohanta <hello@subho.xyz>
Co-authored-by: Ilkka Seppälä <iluwatar@users.noreply.github.com>
This commit is contained in:
jinishavora
2021-03-22 02:13:34 -04:00
committed by GitHub
parent 2b7d181ac4
commit 794795acf5
15 changed files with 730 additions and 2 deletions

View File

@ -0,0 +1,25 @@
<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
<id>webapp</id>
<formats>
<format>zip</format>
</formats>
<fileSets>
<fileSet>
<directory>${project.basedir}/src/main/java</directory>
<outputDirectory>/${project.artifactId}/src</outputDirectory>
</fileSet>
<fileSet>
<directory>${project.basedir}/src/main/webapp</directory>
<outputDirectory>/${project.artifactId}/WebContent</outputDirectory>
</fileSet>
</fileSets>
<files>
<file>
<source>${project.build.directory}/${project.artifactId}.war</source>
<outputDirectory>/</outputDirectory>
</file>
</files>
</assembly>

View File

@ -0,0 +1,37 @@
/*
* The MIT License
* Copyright © 2014-2021 Ilkka Seppälä
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.model.view.viewmodel;
import lombok.AllArgsConstructor;
import lombok.Data;
@AllArgsConstructor
@Data
public class Book {
private String name;
private String author;
private String description;
}

View File

@ -0,0 +1,10 @@
package com.iluwatar.model.view.viewmodel;
import java.util.List;
public interface BookService {
/* List all books
* @return all books
*/
public List<Book> load();
}

View File

@ -0,0 +1,38 @@
package com.iluwatar.model.view.viewmodel;
import java.util.ArrayList;
import java.util.List;
public class BookServiceImpl implements BookService {
private List<Book> designPatternBooks = new ArrayList<>();
/** Initializes Book Data.
* To be used and passed along in load method
* In this case, list design pattern books are initialized to be loaded.
*/
public BookServiceImpl() {
designPatternBooks.add(new Book(
"Head First Design Patterns: A Brain-Friendly Guide",
"Eric Freeman, Bert Bates, Kathy Sierra, Elisabeth Robson",
"Head First Design Patterns Description"));
designPatternBooks.add(new Book(
"Design Patterns: Elements of Reusable Object-Oriented Software",
"Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides",
"Design Patterns Description"));
designPatternBooks.add(new Book(
"Patterns of Enterprise Application Architecture", "Martin Fowler",
"Patterns of Enterprise Application Architecture Description"));
designPatternBooks.add(new Book(
"Design Patterns Explained", "Alan Shalloway, James Trott",
"Design Patterns Explained Description"));
designPatternBooks.add(new Book(
"Applying UML and Patterns: An Introduction to "
+ "Object-Oriented Analysis and Design and Iterative Development",
"Craig Larman", "Applying UML and Patterns Description"));
}
public List<Book> load() {
return designPatternBooks;
}
}

View File

@ -0,0 +1,43 @@
package com.iluwatar.model.view.viewmodel;
import java.util.List;
import org.zkoss.bind.annotation.Command;
import org.zkoss.bind.annotation.NotifyChange;
import org.zkoss.zk.ui.select.annotation.WireVariable;
public class BookViewModel {
@WireVariable
private List<Book> bookList;
private Book selectedBook;
private BookService bookService = new BookServiceImpl();
public Book getSelectedBook() {
return selectedBook;
}
@NotifyChange("selectedBook")
public void setSelectedBook(Book selectedBook) {
this.selectedBook = selectedBook;
}
public List<Book> getBookList() {
return bookService.load();
}
/** Deleting a book.
* When event is triggered on click of Delete button,
* this method will be notified with the selected entry that will be referenced
* and used to delete the selected book from the list of books.
*/
@Command
@NotifyChange({"selectedBook","bookList"})
public void deleteBook() {
if (selectedBook != null) {
getBookList().remove(selectedBook);
selectedBook = null;
}
}
}

View File

@ -0,0 +1,8 @@
Manifest-Version: 1.0
Specification-Title: ZK Application
Specification-Version: 1.0
Specification-Vendor:
Implementation-Title:
Implementation-URL: http://your-website/
Implementation-Version: 1.0
Implementation-Vendor:

View File

@ -0,0 +1,114 @@
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<description><![CDATA[My ZK Application]]></description>
<display-name>model-view-viewmodel</display-name>
<!-- ZK -->
<listener>
<description>ZK listener for session cleanup</description>
<listener-class>org.zkoss.zk.ui.http.HttpSessionListener</listener-class>
</listener>
<servlet>
<description>ZK loader for ZUML pages</description>
<servlet-name>zkLoader</servlet-name>
<servlet-class>org.zkoss.zk.ui.http.DHtmlLayoutServlet</servlet-class>
<!-- Must. Specifies URI of the update engine (DHtmlUpdateServlet).
It must be the same as <url-pattern> for the update engine.
-->
<init-param>
<param-name>update-uri</param-name>
<param-value>/zkau</param-value>
</init-param>
<load-on-startup>1</load-on-startup><!-- Must -->
</servlet>
<servlet-mapping>
<servlet-name>zkLoader</servlet-name>
<url-pattern>*.zul</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>zkLoader</servlet-name>
<url-pattern>*.zhtml</url-pattern>
</servlet-mapping>
<servlet>
<description>The asynchronous update engine for ZK</description>
<servlet-name>auEngine</servlet-name>
<servlet-class>org.zkoss.zk.au.http.DHtmlUpdateServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>auEngine</servlet-name>
<url-pattern>/zkau/*</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>60</session-timeout>
</session-config>
<!-- [Optional] MIME mapping -->
<mime-mapping>
<extension>doc</extension>
<mime-type>application/vnd.ms-word</mime-type>
</mime-mapping>
<mime-mapping>
<extension>gif</extension>
<mime-type>image/gif</mime-type>
</mime-mapping>
<mime-mapping>
<extension>htm</extension>
<mime-type>text/html</mime-type>
</mime-mapping>
<mime-mapping>
<extension>html</extension>
<mime-type>text/html</mime-type>
</mime-mapping>
<mime-mapping>
<extension>jpeg</extension>
<mime-type>image/jpeg</mime-type>
</mime-mapping>
<mime-mapping>
<extension>jpg</extension>
<mime-type>image/jpeg</mime-type>
</mime-mapping>
<mime-mapping>
<extension>js</extension>
<mime-type>text/javascript</mime-type>
</mime-mapping>
<mime-mapping>
<extension>pdf</extension>
<mime-type>application/pdf</mime-type>
</mime-mapping>
<mime-mapping>
<extension>png</extension>
<mime-type>image/png</mime-type>
</mime-mapping>
<mime-mapping>
<extension>txt</extension>
<mime-type>text/plain</mime-type>
</mime-mapping>
<mime-mapping>
<extension>xls</extension>
<mime-type>application/vnd.ms-excel</mime-type>
</mime-mapping>
<mime-mapping>
<extension>xml</extension>
<mime-type>text/xml</mime-type>
</mime-mapping>
<mime-mapping>
<extension>zhtml</extension>
<mime-type>text/html</mime-type>
</mime-mapping>
<mime-mapping>
<extension>zul</extension>
<mime-type>text/html</mime-type>
</mime-mapping>
<welcome-file-list>
<welcome-file>index.zul</welcome-file>
<welcome-file>index.zhtml</welcome-file>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
</welcome-file-list>
</web-app>

View File

@ -0,0 +1,34 @@
<zk>
<window title="List of Books" border="normal" width="600px" apply="org.zkoss.bind.BindComposer" viewModel="@id('vm') @init('com.iluwatar.model.view.viewmodel.BookViewModel')">
<vbox hflex="true">
<listbox model="@bind(vm.bookList)" selectedItem="@bind(vm.selectedBook)" height="400px" mold="paging">
<listhead>
<listheader label="Book Name"/>
<listheader label="Author"/>
</listhead>
<template name="model" var="book">
<listitem >
<listcell label="@bind(book.name)"/>
<listcell label="@bind(book.author)"/>
</listitem>
</template>
</listbox>
</vbox>
<toolbar>
        <button label="Delete" onClick="@command('deleteBook')" disabled="@load(empty vm.selectedBook)" />
    </toolbar>
<hbox style="margin-top:20px" visible="@bind(not empty vm.selectedBook)">
<vbox>
<hlayout>
Book Name : <label value="@bind(vm.selectedBook.name)" style="font-weight:bold"/>
</hlayout>
<hlayout>
Book Author : <label value="@bind(vm.selectedBook.author)" style="font-weight:bold"/>
</hlayout>
<hlayout>
Book Description : <label value="@bind(vm.selectedBook.description)" style="font-weight:bold"/>
</hlayout>
</vbox>
</hbox>
</window>
</zk>

View File

@ -0,0 +1,108 @@
/*
* The MIT License
* Copyright © 2014-2021 Ilkka Seppälä
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.model.view.viewmodel;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.not;
import static org.junit.Assert.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.util.List;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import com.google.common.testing.EqualsTester;
class BookTest {
BookViewModel bvm;
Book testBook;
List<Book> testBookList;
Book testBookTwo;
Book testBookThree;
@BeforeEach
void setUp() {
bvm = new BookViewModel();
testBook = new Book("Head First Design Patterns: A Brain-Friendly Guide",
"Eric Freeman, Bert Bates, Kathy Sierra, Elisabeth Robson",
"Head First Design Patterns Description");
testBookList = bvm.getBookList();
testBookTwo = new Book("Head First Design Patterns: A Brain-Friendly Guide",
"Eric Freeman, Bert Bates, Kathy Sierra, Elisabeth Robson",
"Head First Design Patterns Description");
testBookThree = new Book("Design Patterns: Elements of Reusable Object-Oriented Software",
"Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides",
"Design Patterns Description");
}
@Test
void testBookModel() {
assertNotNull(testBook);
}
@Test
void testEquals() {
new EqualsTester().addEqualityGroup(testBook, testBookTwo).testEquals();
}
@Test
void testToString() {
assertThat(testBook.toString(), is(testBookTwo.toString()));
assertThat(testBook.toString(), is(not(testBookThree.toString())));
}
@Test
void testHashCode() {
assertTrue(testBook.equals(testBookTwo) && testBookTwo.equals(testBook));
assertEquals(testBook.hashCode(), testBookTwo.hashCode());
}
@Test
void testLoadData() {
assertNotNull(testBookList);
assertTrue(testBookList.get(0).toString().contains("Head First Design Patterns"));
}
@Test
void testSelectedData() {
bvm.setSelectedBook(testBook);
assertNotNull(bvm.getSelectedBook());
assertEquals(testBook.toString(), bvm.getSelectedBook().toString());
assertTrue(true, bvm.getSelectedBook().toString());
}
@Test
void testDeleteData() {
bvm.setSelectedBook(testBook);
assertNotNull(bvm.getSelectedBook());
assertTrue(testBookList.get(0).toString().contains("Head First Design Patterns"));
bvm.deleteBook();
assertNull(bvm.getSelectedBook());
assertFalse(testBookList.get(0).toString().contains("Head First Design Patterns"));
}
}