Programming Assignment 4
Generating Scalable Vector Graphics
Code Review for Jade Cheng
Build Results
No errors; no warnings
Requirements Verification
All source code should be submitted in one file, and that file should be named according to the following pattern: LastFirstX.java
, where Last
is the student’s last name, First
is the student’s first name, and X
is the assignment number.
For example, student John Doe
would submit DoeJohn3.java
for programming assignment 3.
PASS.
The first lines of the submitted file should include a comment with the following information and format:
/** * A short description of the program. * * @author Last Name, First Name * @assignment CSCI 2912 Assignment X * @date Date */
PASS.
The submitted file should be emailed to ycheng@hpu.edu.
PASS.
The subject line of the email sent to the instructor should follow the pattern: [2912] assignment number
.
For example, for assignment 3, student John Doe would write “[2912] assignment 3
” as the subject line of his submission email.
PASS.
The submission email sent to the instructor should include exactly one attachment, the Java implementation file. Students should not attach any other files to their submission email.
PASS.
The implementation file must include JavaDoc for all definitions: classes, interfaces, fields, methods, enumerations, and so on.
PASS.
You will implement a Java console application that reads drawing commands from a text file and writes Scalable Vector Graphics (SVG) to Standard Output.
PASS.
The application uses these drawing commands to build a collection of concrete classes: Line
, Rectangle
, and Circle
.
PASS.
These concrete classes derive from an abstract base class, Shape
.
PASS.
This collection of shapes
is maintained as a private field of an Svg
class.
PASS.
The Svg
class maintains the collection of shapes
and two fields of type double
representing the width and height of the graphic.
PASS.
The class provides a method, addShape
, that receives Shape objects and adds them to its private collection.
PASS.
The Svg
class also provides a second method, render
, that writes SVG elements to a specified output stream.
PASS.
The Shape
class maintains an array of styles
, which are stored as a collection of String types obtained from reading two tokens, a Key and a Value, and joining them with the ‘:’ character.
PASS.
The class also defines an abstract method, renderAttributes
, that derived classes use to write XML attributes to an output stream.
PASS.
The Line
class contains fields of type double
representing two points in Cartesian Space.
PASS.
The Rectangle
class contains fields of type double
representing a location and size in Cartesian Space.
PASS.
The Circle
class contains fields of type double
representing a center coordinate and radius in Cartesian Space.
PASS.
When all commands have been read from the text file, the application writes to Standard Output a series of SVG elements based on the commands from the input file.
PASS.
The implementation writes the SVG elements by passing System.out
to the render method of an Svg
instance.
PASS.
The application determines the name of the text file from the command-line arguments.
PASS.
If the user supplies no arguments, or if the user supplies two or more arguments, the application terminates after writing to Standard Error, “Invalid command-line arguments.”.
PASS.
If any I/O error occurs while reading the input file, the application terminates after writing to Standard Error, “Failed to read input file: XXX”, where XXX is the value returned by Exception.getMessage()
.
PASS.
The application ignores case for all comparisons of tokens read from the input file.
PASS.
If a Parsing Error, such as NumberFormatException
, occurs while reading the input file, the application terminates after writing to Standard Error “Invalid token: ‘XXX’.“, where XXX is the unsupported or invalid token read from the file.
PASS.
If the first token from the input file is not SVG, the application terminates with a Parsing Error.
PASS.
The application then reads two more tokens from the input file representing the width and then the height of the graphic, and if these two tokens cannot be parsed as double
types, the application terminates with a Parsing Error.
PASS.
If the SVG token, the width, and the height are valid, the application creates a new instance of the Svg
class and initializes it with the specified width and height.
PASS.
Then the application loops over additional tokens of the input file. For each iteration, the application first reads one Command Token, and if this Command Token is not LINE
, RECT
, or CIRCLE
, the application terminates with a Parsing Error.
PASS.
If the Command Token is LINE
, the application reads four tokens that represent x1
, y1
, x2
, and y2
values that are used to create a new instance of the Line
class; if any of these values fail to parse as double
types, the application terminates with a Parsing Error.
PASS.
If the Command Token is RECT
, the application then reads four tokens that represent x
, y
, width
, and height
values that are used to create a new instance of the Rectangle
class; if any of these values fail to parse as double
types, the application terminates with a Parsing Error.
PASS.
If the Command Token is CIRCLE
, the application then reads three tokens that represent cx
, cy
, and r
values that are used to create a new instance of the Circle
class; if any of these values fail to parse as double
types, the application terminates with a Parsing Error.
PASS.
After successfully parsing a LINE
, RECT
, or CIRCLE
command, the application enters a Style Loop that reads style information for the class derived from Shape
.
PASS.
For each iteration, the application reads a first token, and if this token is END
, the shape is added to the Svg
instance, the application exits the Style Loop, and it then continues to process new commands from the input file.
PASS.
If the first token is not END
, the application interprets it as a Key, reads a second token and interprets it as a Value, and then passes this Key-Value pair to the Shape class to add as a style.
PASS.
The application continues to read and add styles in this fashion until the END
token is encountered.
PASS.
When all tokens have been read from the input file, the application renders the Svg
instance to Standard Output.
PASS.
The Svg
class data is formatted as follows.
<svg width='WIDTH' height='HEIGHT'> : (shapes) : </svg>
PASS.
Between the opening and closing svg tags, the application renders each shape in the order they were defined in the input file.
PASS.
The format of each shape is specific to its type, but each contains a style attribute that is common to all shapes. Arrays of n
styles are formatted as follows.
STYLE := Key1:Value1;Key2:Value2;...;Keyn:Valuen;
PASS.
Line shapes are formatted as follows.
<line x1='X1' y1='Y1' x2='X2' y2='Y2' style='STYLE' />
PASS.
Rectangle shapes are formatted as follows.
<rect x='X' y='Y' width='WIDTH' height='HEIGHT' style='STYLE' />
PASS.
Circle shapes are formatted as follows.
<circle cx='CX' cy='CY' r='R' style='STYLE' />
PASS.
Sample Execution
$ java ChengJade4 input.txt
<svg width='300.0' height='300.0'> <rect x='5.0' y='5.0' width='290.0' height='290.0' style='fill:#f8f8f8;'/> <line x1='5.0' y1='5.0' x2='295.0' y2='295.0' style='stroke:#804040;stroke-width:2;stroke-dasharray:5,10;'/> <line x1='5.0' y1='295.0' x2='295.0' y2='5.0' style='stroke:#804040;stroke-width:2;stroke-dasharray:5,10;'/> <rect x='5.0' y='5.0' width='290.0' height='290.0' style='fill:none;stroke:#c0c0c0;stroke-width:2;'/> <circle cx='150.0' cy='150.0' r='75.0' style='stroke:#444;stroke-width:2;fill:#844;fill-opacity:0.25;'/> </svg>
$ java ChengJade4 mystery-one.txt
<svg width='250.0' height='250.0'> <rect x='0.0' y='0.0' width='10.0' height='10.0' style='FILL:#000;'/> <rect x='10.0' y='0.0' width='10.0' height='10.0' style='FILL:#000;'/> <rect x='20.0' y='0.0' width='10.0' height='10.0' style='FILL:#000;'/> <rect x='30.0' y='0.0' width='10.0' height='10.0' style='FILL:#000;'/> <rect x='40.0' y='0.0' width='10.0' height='10.0' style='FILL:#000;'/> <rect x='50.0' y='0.0' width='10.0' height='10.0' style='FILL:#000;'/> <rect x='60.0' y='0.0' width='10.0' height='10.0' style='FILL:#000;'/> <rect x='80.0' y='0.0' width='10.0' height='10.0' style='FILL:#000;'/> <rect x='90.0' y='0.0' width='10.0' height='10.0' style='FILL:#000;'/> <rect x='100.0' y='0.0' width='10.0' height='10.0' style='FILL:#000;'/> : <rect x='30.0' y='240.0' width='10.0' height='10.0' style='FILL:#000;'/> <rect x='40.0' y='240.0' width='10.0' height='10.0' style='FILL:#000;'/> <rect x='50.0' y='240.0' width='10.0' height='10.0' style='FILL:#000;'/> <rect x='60.0' y='240.0' width='10.0' height='10.0' style='FILL:#000;'/> <rect x='80.0' y='240.0' width='10.0' height='10.0' style='FILL:#000;'/> <rect x='120.0' y='240.0' width='10.0' height='10.0' style='FILL:#000;'/> <rect x='160.0' y='240.0' width='10.0' height='10.0' style='FILL:#000;'/> <rect x='170.0' y='240.0' width='10.0' height='10.0' style='FILL:#000;'/> <rect x='210.0' y='240.0' width='10.0' height='10.0' style='FILL:#000;'/> <rect x='240.0' y='240.0' width='10.0' height='10.0' style='FILL:#000;'/> </svg>
$ java ChengJade4 mystery-two.txt
<svg width='600.0' height='600.0'> <line x1='250.0' y1='550.0' x2='250.0' y2='450.0' style='stroke-linecap:round;stroke:#440000;stroke-width:15.00;'/> <line x1='250.0' y1='450.0' x2='224.69' y2='390.13' style='stroke-linecap:round;stroke:#440000;stroke-width:9.75;'/> <line x1='224.69' y1='390.13' x2='185.05' y2='351.64' style='stroke-linecap:round;stroke:#440000;stroke-width:8.29;'/> <line x1='185.05' y1='351.64' x2='151.58' y2='338.62' style='stroke-linecap:round;stroke:#440000;stroke-width:5.39;'/> <line x1='151.58' y1='338.62' x2='128.25' y2='339.31' style='stroke-linecap:round;stroke:#440000;stroke-width:3.50;'/> <line x1='128.25' y1='339.31' x2='110.21' y2='347.56' style='stroke-linecap:round;stroke:#440000;stroke-width:2.98;'/> <line x1='110.21' y1='347.56' x2='101.5' y2='357.07' style='stroke-linecap:round;stroke:#440000;stroke-width:1.93;'/> <line x1='101.5' y1='357.07' x2='98.69' y2='364.97' style='stroke-linecap:round;stroke:#440000;stroke-width:1.26;'/> <line x1='98.69' y1='364.97' x2='99.1' y2='372.09' style='stroke-linecap:round;stroke:#440000;stroke-width:1.07;'/> <circle cx='99.1' cy='372.09' r='5.0' style='fill:#ff99cc;fill-opacity:0.15;stroke:#ffcccc;stroke-opacity:0.5;'/> : <line x1='439.22' y1='389.3' x2='435.91' y2='396.01' style='stroke-linecap:round;stroke:#440000;stroke-width:1.12;'/> <circle cx='435.91' cy='396.01' r='5.0' style='fill:#ff99cc;fill-opacity:0.15;stroke:#ffcccc;stroke-opacity:0.5;'/> <line x1='435.91' y1='396.01' x2='431.09' y2='400.16' style='stroke-linecap:round;stroke:#440000;stroke-width:0.95;'/> <circle cx='431.09' cy='400.16' r='5.0' style='fill:#ff99cc;fill-opacity:0.15;stroke:#ffcccc;stroke-opacity:0.5;'/> <line x1='431.09' y1='400.16' x2='425.95' y2='401.83' style='stroke-linecap:round;stroke:#440000;stroke-width:0.81;'/> <circle cx='425.95' cy='401.83' r='5.0' style='fill:#ff99cc;fill-opacity:0.15;stroke:#ffcccc;stroke-opacity:0.5;'/> <circle cx='425.95' cy='401.83' r='5.0' style='fill:#ff99cc;fill-opacity:0.15;stroke:#ffcccc;stroke-opacity:0.5;'/> <line x1='439.22' y1='389.3' x2='433.77' y2='391.06' style='stroke-linecap:round;stroke:#440000;stroke-width:0.86;'/> <circle cx='433.77' cy='391.06' r='5.0' style='fill:#ff99cc;fill-opacity:0.15;stroke:#ffcccc;stroke-opacity:0.5;'/> <circle cx='433.77' cy='391.06' r='5.0' style='fill:#ff99cc;fill-opacity:0.15;stroke:#ffcccc;stroke-opacity:0.5;'/> </svg>
$ java ChengJade4 mystery-three.txt
<svg width='600.0' height='600.0'> <line x1='300.0' y1='150.0' x2='300.0' y2='450.0' style='stroke:#888;stroke-opacity:-1.4666666666666666;'/> <line x1='300.0' y1='97.5' x2='300.0' y2='202.5' style='stroke:#888;stroke-opacity:-0.16666666666666663;'/> <line x1='300.0' y1='79.13' x2='300.0' y2='115.88' style='stroke:#888;stroke-opacity:0.28833333333333333;'/> <line x1='300.0' y1='72.69' x2='300.0' y2='85.56' style='stroke:#888;stroke-opacity:0.44758333333333333;'/> <circle cx='300.0' cy='72.69' r='3.0' style='fill:#669900;fill-opacity:0.5;stroke:#669900;stroke-opacity:0.5;stroke-width:0.5;'/> <circle cx='300.0' cy='85.56' r='3.0' style='fill:#669900;fill-opacity:0.5;stroke:#669900;stroke-opacity:0.5;stroke-width:0.5;'/> <line x1='293.57' y1='79.13' x2='306.43' y2='79.13' style='stroke:#888;stroke-opacity:0.44758333333333333;'/> <circle cx='293.57' cy='79.13' r='3.0' style='fill:#669900;fill-opacity:0.5;stroke:#669900;stroke-opacity:0.5;stroke-width:0.5;'/> <circle cx='306.43' cy='79.13' r='3.0' style='fill:#669900;fill-opacity:0.5;stroke:#669900;stroke-opacity:0.5;stroke-width:0.5;'/> <line x1='295.45' y1='74.58' x2='304.55' y2='83.67' style='stroke:#888;stroke-opacity:0.44758333333333333;'/> : <circle cx='456.18' cy='150.25' r='3.0' style='fill:#669900;fill-opacity:0.5;stroke:#669900;stroke-opacity:0.5;stroke-width:0.5;'/> <line x1='449.75' y1='143.82' x2='462.61' y2='143.82' style='stroke:#888;stroke-opacity:0.44758333333333333;'/> <circle cx='449.75' cy='143.82' r='3.0' style='fill:#669900;fill-opacity:0.5;stroke:#669900;stroke-opacity:0.5;stroke-width:0.5;'/> <circle cx='462.61' cy='143.82' r='3.0' style='fill:#669900;fill-opacity:0.5;stroke:#669900;stroke-opacity:0.5;stroke-width:0.5;'/> <line x1='451.63' y1='139.27' x2='460.73' y2='148.37' style='stroke:#888;stroke-opacity:0.44758333333333333;'/> <circle cx='451.63' cy='139.27' r='3.0' style='fill:#669900;fill-opacity:0.5;stroke:#669900;stroke-opacity:0.5;stroke-width:0.5;'/> <circle cx='460.73' cy='148.37' r='3.0' style='fill:#669900;fill-opacity:0.5;stroke:#669900;stroke-opacity:0.5;stroke-width:0.5;'/> <line x1='451.63' y1='148.37' x2='460.73' y2='139.27' style='stroke:#888;stroke-opacity:0.44758333333333333;'/> <circle cx='451.63' cy='148.37' r='3.0' style='fill:#669900;fill-opacity:0.5;stroke:#669900;stroke-opacity:0.5;stroke-width:0.5;'/> <circle cx='460.73' cy='139.27' r='3.0' style='fill:#669900;fill-opacity:0.5;stroke:#669900;stroke-opacity:0.5;stroke-width:0.5;'/> </svg>
$ java ChengJade4 invalid-one.txt
Invalid token: png
$ java ChengJade4 invalid-two.txt
Invalid token: triangle
$ java ChengJade4 invalid-three.txt
Invalid token: 'three'.
$ java ChengJade4 invalid-four.txt
Invalid token: 'five'.