Contents:

Introduction

In Homework 8, UW Marketing commissioned you to write a route finder tool. Marketing is pleased with your initial results, but now they've asked for a graphical user interface (GUI) that visually draws routes on a map.

You will build your GUI using React and Spring Boot just like Homework 9. However, this time you are building both the frontend and the backend! You will get practice using these tools, event-driven programming, and the model-view-controller (MVC) design pattern. You should write approximately 100 lines of Java code and about 250 lines of JavaScript to complete the basic requirements. You are required to use React for this assignment.

You are expected to fix any bugs from Homework 8 (and previous homeworks) that affect the correctness or performance of your application in Homework 10. You are also required to fix code quality/organization issues in your Homework 8 code. When doing so, it might be wise for you to refactor your code into the style of a typical Spring Boot Application.

When you're done, you can show off your awesome looking campus-map-route-finding application to your frends and family!

Setting up the Java Spring Application

A main class called CampusPathsApplication.java has been provided to you. You need to use Spring Boot's annotations to setup a backend API. We have created a simple Spring Boot Application and have explained all Annotations that you may find relevant. We strongly recommend using it to make sure you understand the usage of each of the annotations.

Here is a potentially helpful way to approach developing your Spring Application:
  1. What server functionality does the UI need to call? Make the spec for your backend API.
  2. Since your API should be a thin layer, create an initial spec for your Model (generally a combination of the Repository(ies) and Service(s)).
  3. Now that you have basic specs for your Service(s) and/or Repository(ies), implement these methods by calling to your Model from HW8.

You may not need to create new classes to add the @Service and @Repository annotations. You should be able to do these on your pre-existing classes.

You will be graded on the correct usage of Spring annotations such as @Autowired, @Bean, @Service, and @RestController. This isn't an encompassing list of all the annotations you may use. Use the Spring Demo mentioned above to see the usage of the same. Should you have questions about the usage of an annotation and cannot find the answer via a web search, we strongly encourage you to search Piazza as another student may have the answer, or may have already asked your question. This will allow you to find answers quickly.

Another annotation that might be helpful to you would be @Value. An example of the usage of this is visible in SubscriberRepository in the no-mysql branch of the Spring Demo.

All methods in your classes should be tested extensively through unit tests. Spring provides several annotations that support writing unit tests of most methods. This includes methods in your Service(s) and in your API. You will be graded on correct testing strategies. For example, testing a class with a @Service annotation by creating a new Object of that type and calling the method in a test defeats the purpose of using Spring and will result in a deduction. Spring encourages the use of "Mocking" in Unit Tests and we expect you to use the same. The Spring Demo also uses Mocking and you may use that as an example.

You can run your application by running campuspaths/CampusPathsApplication.java from IntelliJ, or by running ./gradlew bootRun from the terminal.

How to proceed

Write @Service and @Repository annotations on your existing code. That's pretty much all you need!

Now you need to change your tests too, to make them Spring-compliant.

GUI Requirements

This GUI should utilize similar techniques as Homework 9, but the exact appearance and functionality of your GUI are up to you. The only requirements are documented below.

For the most part, we are not grading on aesthetics: it doesn't matter whether your GUI looks pretty as long as it implements the required features. Nevertheless, a design that is genuinely confusing or hard to use (at our discretion) will not receive full credit. For example, we will deduct points if we can't easily figure out how to select the two buildings, if it's hard to see the selected path, or if we can only see the whole GUI on your 27-inch monitor. In addition, your program should be generally responsive: for instance, the GUI should not take an unusually long time to find and display paths.

Your GUI is a new View and Controller for your CampusPaths application. Ideally, you should not have to make any changes to your Homework 8 model classes — they already implement all the Model functionality that you need. If you have to make any small changes (for instance, if your design in Homework 8 was poor and some model methods were too closely tied to your text view), then you may do so. As always, all tests from previous homeworks must continue to pass, so you may also need to change your Homework 8 View and Controller in that case. In file src/main/java/campuspaths/answers.txt, list any changes you made to the model. For each, write a 1-2 sentence explanation of why the change was necessary and what you could have done differently on Homework 8 to create a more general and reusable Model. If you make no changes this file should just contain “None”.

Window size

At startup, your GUI must fit and be usable on a full-screen browser on a computer with a minimum of 1024 x 768 screen resolution.

Required features

At a minimum, your GUI must provide the following features:

Testing

Writing automated tests for GUIs is important, but it is difficult and usually involves special frameworks that are beyond the scope of this course. For this reason, you are not required to write unit tests or a test driver. We will test your solution by running your main program.

Getting started with your UI

To get started with your UI, you may choose to think of the problem as follows:
  1. Create a class that "loads" your UI by making the initial set of requests
  2. Once the initial set of requests has loaded, you should render a new class that has your basic set of interactions
  3. You may want to add a Toolbar that has most of the interactions to make it easier to manage call backs

Using the pattern stated above is not required, and will not impact your score in any way.

Hint for drawing the map and paths on the map

There are several ways to create a drawing space, often called a canvas, in React. Perhaps the simplest way is to use HTML5 canvases. A context can be retrieved from a reference to a canvas by calling getContext("2d") on it. The context can then be used to draw images and lines on it.

As is often the case in React, it is difficult to obtain a reference to the canvas in the first place. This can be done in a similar way to HTML ids and using document.getElementById by setting a ref field on the canvas that will identify that canvas, and looking up that canvas later in parentComponent.refs. A more concrete example is found below.

class Parent extends Component {
  componentDidUpdate() {
    var can = this.refs.canvas;
    var ctx = can.getContext("2d");

    ctx.drawImage(...);
    ctx.beginPath(...);
    // etc...
  }

  render() {
    return (<canvas ref="canvas"></canvas>);
  }
}

This example does the drawing in componentDidUpdate, which may be a natural place to do drawing (after every state update of the component); however, be careful about what resources need to be available to your drawing routine when it is called. In your case it may need to be moved into a different callback.

React Style

You are expected to follow good React Style. This includes not using `ReactDOM` (especially to use `ReactDOM.render`), not bypassing the ReactDOM by using `document.getElementById` or similar, and using the state and properties correctly.

The only exception for this is in index.js. The presence of ReactDOM.render in this situation is expected and justified.

Optional Extra Features

We encourage you to get creative with both the appearance and functionality of your application! If you do, make sure to get a basic application working and commit it to your repository before experimenting.

Here are a few ideas for additional features:

List any additional features you implemented, if any, in src/main/java/campuspaths/answers.txt. Additional features must not mask or replace any of the required features.

With this assignment, we are removing the restriction on editing build.gradle. You may make changes to build.gradle as far as they do not interfere with the functionality provided by the staff.

Extra Credit may be awarded for interesting or useful functionality that shows considerable effort. Extra credit will not be awarded for pure “eye candy,” such as changing the font and color of buttons or adding a border. Extra credit will either allow you to get back points you have lost on this assignment, or will be used when final grades are being decided; thus, it will not lower your grade if you choose not to work on optional features, but may raise your grade slightly if you do.

We would like to demonstrate some of the more interesting projects and GUIs on the last day of class. If you would like to let us show your project, please fill out this Canvas Survey by 5pm on Thursday, November 6th (the non-late-day deadline). We may not have time to show all of the projects submitted, but we would like to have as many as possible to choose from.

You do not need to fill out this Canvas Survey if you DO NOT want your project demonstrated.

Written Answers

Answer the following questions in src/main/java/campuspaths/answers.txt. You might need to make the file yourself.

  1. How has the View and Controller been split in your code? Think about how React splits up the same.
  2. What decisions did you make when you refactored your code to work with Spring?
  3. What decisions did you make when designing your API?
  4. What additional functionality did you add that you would like us to consider for Extra Credit?

Hints

Abstraction functions, representation invariants, and checkRep() are not required for GUI classes because they generally do not represent ADTs.

User testing is a great way to verify that your interface is as easy to use as you think it is. Show your GUI to your friend/roommate/sibling. Can they figure out how to use it without directions from you?

In industry, your UI and your Server will be running on the same port. However, to reduce the amount of potential issues this HW may cause, we will be running the UI and Server on separate ports.

API (that is, @RestController) methods should be thin wrappers (just like in the demo code).

When you run ./gradlew bootRun, the build won't end and will be "stuck" at some point. This is expected. Remember that this command runs a server and due to this the build can't end. Once it's "stuck", you can visit http://localhost:8080 or http://localhost:8080/subscribers and make your first GET request for the assignment.

Collaboration

Please answer the following questions in a file named src/main/java/campuspaths/collaboration.txt. The standard collaboration policy applies to this assignment. State whether or not you collaborated with other students. If you did collaborate with other students, state their names and a brief description of how you collaborated.

Feedback on the assignment

Complete the Canvas Quiz associated with this assignment. You will receive full credit for this section if you complete the quiz. Your answers will be anonymous to the instructors. This quiz is due 24 hours after the assignment due date. You cannot use late days for this quiz.

What to Turn In

You should add, commit, and push the following files to your GitLab repository:

The staff strongly urges you to test your application and UI on any of the following:

To test your submission, make a clean clone of your repository, checkout your tag and run the application and UI. If you are unable to perform any of the tasks required to test the application and/or UI on one of the environments above, at the very least test a clean clone of your code on your own machine.

Your server must compile and run without errors as a result of the command ./gradlew bootRun and your UI should build and run without errors with the command cd src/main/resources && npm install && npm start.

Refer to the assignment submission handout for complete turnin instructions.