Skip to content

Latest commit

 

History

History
407 lines (263 loc) · 16.8 KB

DeveloperGuide.adoc

File metadata and controls

407 lines (263 loc) · 16.8 KB

AddressBook Level 4 - Developer Guide

1. Setting up

1.1. Prerequisites

  1. JDK 1.8.0_60 or later

    ℹ️
    Having any Java 8 version is not enough.
    This app will not work with earlier versions of Java 8.
  2. Eclipse IDE

  3. e(fx)clipse plugin for Eclipse (Do the steps 2 onwards given in this page)

  4. Buildship Gradle Integration plugin from the Eclipse Marketplace

  5. Checkstyle Plug-in plugin from the Eclipse Marketplace

1.2. Importing the project into Eclipse

  1. Fork this repo, and clone the fork to your computer

  2. Open Eclipse (Note: Ensure you have installed the e(fx)clipse and buildship plugins as given in the prerequisites above)

  3. Click File > Import

  4. Click Gradle > Gradle Project > Next > Next

  5. Click Browse, then locate the project’s directory

  6. Click Finish

ℹ️
  • If you are asked whether to 'keep' or 'overwrite' config files, choose to 'keep'.

  • Depending on your connection speed and server load, it can even take up to 30 minutes for the set up to finish (This is because Gradle downloads library files from servers during the project set up process).

  • If Eclipse auto-changed any settings files during the import process, you can discard those changes.

1.3. Configuring Checkstyle

  1. Click ProjectPropertiesCheckstyleLocal Check ConfigurationsNew…​

  2. Choose External Configuration File under Type

  3. Enter an arbitrary configuration name e.g. addressbook

  4. Import checkstyle configuration file found at config/checkstyle/checkstyle.xml

  5. Click OK once, go to the Main tab, use the newly imported check configuration.

  6. Tick and select files from packages, click Change…​, and select the resources package

  7. Click OK twice. Rebuild project if prompted

ℹ️
Click on the files from packages text after ticking in order to enable the Change…​ button

1.4. Troubleshooting project setup

Problem: Eclipse reports compile errors after new commits are pulled from Git

  • Reason: Eclipse fails to recognize new files that appeared due to the Git pull.

  • Solution: Refresh the project in Eclipse: Right click on the project (in Eclipse package explorer), choose GradleRefresh Gradle Project.

Problem: Eclipse reports some required libraries missing

  • Reason: Required libraries may not have been downloaded during the project import.

  • Solution: Run tests using Gradle once (to refresh the libraries).

1.5. Updating documentation

After forking the repo, links in the documentation will link to the wrong repo. You should replace the URL in the variable repoURL in DeveloperGuide.adoc with the URL of your fork.

1.6. Coding style

2. Design

2.1. Architecture

Architecture

Figure 2.1.1 : Architecture Diagram

The Architecture Diagram given above explains the high-level design of the App. Given below is a quick overview of each component.

💡
The .pptx files used to create diagrams in this document can be found in the diagrams folder. To update a diagram, modify the diagram in the pptx file, select the objects of the diagram, and choose Save as picture.

Main has only one class called MainApp. It is responsible for,

  • At app launch: Initializes the components in the correct sequence, and connects them up with each other.

  • At shut down: Shuts down the components and invokes cleanup method where necessary.

Commons represents a collection of classes used by multiple other components. Two of those classes play important roles at the architecture level.

  • EventsCenter : This class (written using Google’s Event Bus library) is used by components to communicate with other components using events (i.e. a form of Event Driven design)

  • LogsCenter : Used by many classes to write log messages to the App’s log file.

The rest of the App consists of four components.

  • UI : The UI of the App.

  • Logic : The command executor.

  • Model : Holds the data of the App in-memory.

  • Storage : Reads data from, and writes data to, the hard disk.

Each of the four components

  • Defines its API in an interface with the same name as the Component.

  • Exposes its functionality using a {Component Name}Manager class.

For example, the Logic component (see the class diagram given below) defines it’s API in the Logic.java interface and exposes its functionality using the LogicManager.java class.

LogicClassDiagram

Figure 2.1.2 : Class Diagram of the Logic Component

Events-Driven nature of the design

The Sequence Diagram below shows how the components interact for the scenario where the user issues the command delete 1.

SDforDeletePerson

Figure 2.1.3a : Component interactions for delete 1 command (part 1)

ℹ️
Note how the Model simply raises a AddressBookChangedEvent when the Address Book data are changed, instead of asking the Storage to save the updates to the hard disk.

The diagram below shows how the EventsCenter reacts to that event, which eventually results in the updates being saved to the hard disk and the status bar of the UI being updated to reflect the 'Last Updated' time.

SDforDeletePersonEventHandling

Figure 2.1.3b : Component interactions for delete 1 command (part 2)

ℹ️
Note how the event is propagated through the EventsCenter to the Storage and UI without Model having to be coupled to either of them. This is an example of how this Event Driven approach helps us reduce direct coupling between components.

The sections below give more details of each component.

2.2. UI component

Author: Alice Bee

UiClassDiagram

Figure 2.2.1 : Structure of the UI Component

API : Ui.java

The UI consists of a MainWindow that is made up of parts e.g.CommandBox, ResultDisplay, PersonListPanel, StatusBarFooter, BrowserPanel etc. All these, including the MainWindow, inherit from the abstract UiPart class.

The UI component uses JavaFx UI framework. The layout of these UI parts are defined in matching .fxml files that are in the src/main/resources/view folder. For example, the layout of the MainWindow is specified in MainWindow.fxml

The UI component,

  • Executes user commands using the Logic component.

  • Binds itself to some data in the Model so that the UI can auto-update when data in the Model change.

  • Responds to events raised from various parts of the App and updates the UI accordingly.

2.3. Logic component

Author: Bernard Choo

LogicClassDiagram

Figure 2.3.1 : Structure of the Logic Component

API : Logic.java

  1. Logic uses the Parser class to parse the user command.

  2. This results in a Command object which is executed by the LogicManager.

  3. The command execution can affect the Model (e.g. adding a person) and/or raise events.

  4. The result of the command execution is encapsulated as a CommandResult object which is passed back to the Ui.

Given below is the Sequence Diagram for interactions within the Logic component for the execute("delete 1") API call.

DeletePersonSdForLogic

Figure 2.3.1 : Interactions Inside the Logic Component for the delete 1 Command

2.4. Model component

Author: Cynthia Dharman

ModelClassDiagram

Figure 2.4.1 : Structure of the Model Component

API : Model.java

The Model,

  • stores a UserPref object that represents the user’s preferences.

  • stores the Address Book data.

  • exposes a UnmodifiableObservableList<ReadOnlyPerson> that can be 'observed' e.g. the UI can be bound to this list so that the UI automatically updates when the data in the list change.

  • does not depend on any of the other three components.

2.5. Storage component

Author: Darius Foong

StorageClassDiagram

Figure 2.5.1 : Structure of the Storage Component

API : Storage.java

The Storage component,

  • can save UserPref objects in json format and read it back.

  • can save the Address Book data in xml format and read it back.

2.6. Common classes

Classes used by multiple components are in the seedu.addressbook.commons package.

3. Implementation

3.1. Logging

We are using java.util.logging package for logging. The LogsCenter class is used to manage the logging levels and logging destinations.

  • The logging level can be controlled using the logLevel setting in the configuration file (See Configuration)

  • The Logger for a class can be obtained using LogsCenter.getLogger(Class) which will log messages according to the specified logging level

  • Currently log messages are output through: Console and to a .log file.

Logging Levels

  • SEVERE : Critical problem detected which may possibly cause the termination of the application

  • WARNING : Can continue, but with caution

  • INFO : Information showing the noteworthy actions by the App

  • FINE : Details that is not usually noteworthy but may be useful in debugging e.g. print the actual list instead of just its size

3.2. Configuration

Certain properties of the application can be controlled (e.g App name, logging level) through the configuration file (default: config.json).

4. Testing

Tests can be found in the ./src/test/java folder.

In Eclipse:

  • To run all tests, right-click on the src/test/java folder and choose Run as > JUnit Test

  • To run a subset of tests, you can right-click on a test package, test class, or a test and choose to run as a JUnit test.

Using Gradle:

We have two types of tests:

  1. GUI Tests - These are System Tests that test the entire App by simulating user actions on the GUI. These are in the guitests package.

  2. Non-GUI Tests - These are tests not involving the GUI. They include,

    1. Unit tests targeting the lowest level methods/classes.
      e.g. seedu.address.commons.StringUtilTest

    2. Integration tests that are checking the integration of multiple code units (those code units are assumed to be working).
      e.g. seedu.address.storage.StorageManagerTest

    3. Hybrids of unit and integration tests. These test are checking multiple code units as well as how the are connected together.
      e.g. seedu.address.logic.LogicManagerTest

4.1. Headless GUI Testing

Thanks to the TestFX library we use, our GUI tests can be run in the headless mode. In the headless mode, GUI tests do not show up on the screen. That means the developer can do other things on the Computer while the tests are running. See UsingGradle.adoc to learn how to run tests in headless mode.

4.2. Troubleshooting tests

Problem: Tests fail because NullPointException when AssertionError is expected

  • Reason: Assertions are not enabled for JUnit tests. This can happen if you are not using a recent Eclipse version (i.e. Neon or later)

  • Solution: Enable assertions in JUnit tests as described here. Delete run configurations created when you ran tests earlier.

5. Dev Ops

5.1. Build Automation

See UsingGradle.adoc to learn how to use Gradle for build automation.

5.2. Continuous Integration

We use Travis CI and AppVeyor to perform Continuous Integration on our projects. See UsingTravis.adoc and UsingAppVeyor.adoc for more details.

5.3. Publishing Documentation

See UsingGithubPages.adoc to learn how to use GitHub Pages to publish documentation to the project site.

5.4. Making a Release

Here are the steps to create a new release.

  1. Generate a JAR file using Gradle.

  2. Tag the repo with the version number. e.g. v0.1

  3. Create a new release using GitHub and upload the JAR file you created.

5.5. Converting Documentation to PDF format

We use Google Chrome for converting documentation to PDF format, as Chrome’s PDF engine preserves hyperlinks used in webpages.

Here are the steps to convert the project documentation files to PDF format.

  1. Make sure you have set up GitHub Pages as described in UsingGithubPages.adoc.

  2. Using Chrome, go to the GitHub Pages version of the documentation file. e.g. For UserGuide.adoc, the URL will be https://<your-username-or-organization-name>.github.io/addressbook-level4/docs/UserGuide.html.

  3. Click on the Print option in Chrome’s menu.

  4. Set the destination to Save as PDF, then click Save to save a copy of the file in PDF format. For best results, use the settings indicated in the screenshot below.

chrome save as pdf

Figure 5.4.1 : Saving documentation as PDF files in Chrome

5.6. Managing Dependencies

A project often depends on third-party libraries. For example, Address Book depends on the Jackson library for XML parsing. Managing these dependencies can be automated using Gradle. For example, Gradle can download the dependencies automatically, which is better than these alternatives.
a. Include those libraries in the repo (this bloats the repo size)
b. Require developers to download those libraries manually (this creates extra work for developers)

Appendix A: User Stories

Priorities: High (must have) - * * *, Medium (nice to have) - * *, Low (unlikely to have) - *

Priority As a …​ I want to …​ So that I can…​

* * *

new user

see usage instructions

refer to instructions when I forget how to use the App

* * *

user

add a new person

* * *

user

delete a person

remove entries that I no longer need

* * *

user

find a person by name

locate details of persons without having to go through the entire list

* *

user

hide private contact details by default

minimize chance of someone else seeing them by accident

*

user with many persons in the address book

sort persons by name

locate a person easily

{More to be added}

Appendix B: Use Cases

(For all use cases below, the System is the AddressBook and the Actor is the user, unless specified otherwise)

Use case: Delete person

MSS

  1. User requests to list persons

  2. AddressBook shows a list of persons

  3. User requests to delete a specific person in the list

  4. AddressBook deletes the person Use case ends.

Extensions

2a. The list is empty

Use case ends

3a. The given index is invalid

3a1. AddressBook shows an error message
Use case resumes at step 2

{More to be added}

Appendix C: Non Functional Requirements

  1. Should work on any mainstream OS as long as it has Java 1.8.0_60 or higher installed.

  2. Should be able to hold up to 1000 persons without a noticeable sluggishness in performance for typical usage.

  3. A user with above average typing speed for regular English text (i.e. not code, not system admin commands) should be able to accomplish most of the tasks faster using commands than using the mouse.

{More to be added}

Appendix D: Glossary

Mainstream OS

Windows, Linux, Unix, OS-X

Private contact detail

A contact detail that is not meant to be shared with others

Appendix E: Product Survey

Product Name

Author: …​

Pros:

  • …​

  • …​

Cons:

  • …​

  • …​