Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
rlanning2
OpenWeather REST and file connector
Commits
830eafd2
Commit
830eafd2
authored
Nov 12, 2021
by
Christopher Bohn
🤔
Browse files
Reformatted to SOFT160 formatting specification
parent
77a56416
Changes
13
Expand all
Hide whitespace changes
Inline
Side-by-side
pom.xml
View file @
830eafd2
<project
xmlns=
"http://maven.apache.org/POM/4.0.0"
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=
"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"
>
<modelVersion>
4.0.0
</modelVersion>
<groupId>
edu.unl.cse.soft160.rest_connector
</groupId>
<artifactId>
rest_and_file_connector
</artifactId>
<packaging>
jar
</packaging>
<version>
1.0-SNAPSHOT
</version>
<name>
rest_connector
</name>
<url>
http://maven.apache.org
</url>
<project
xmlns=
"http://maven.apache.org/POM/4.0.0"
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=
"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"
>
<modelVersion>
4.0.0
</modelVersion>
<groupId>
edu.unl.cse.soft160.rest_connector
</groupId>
<artifactId>
rest_and_file_connector
</artifactId>
<packaging>
jar
</packaging>
<version>
1.0-SNAPSHOT
</version>
<name>
rest_connector
</name>
<url>
http://maven.apache.org
</url>
<properties>
<project.build.sourceEncoding>
UTF-8
</project.build.sourceEncoding>
</properties>
<properties>
<project.build.sourceEncoding>
UTF-8
</project.build.sourceEncoding>
</properties>
<build>
<plugins>
<plugin>
<artifactId>
maven-compiler-plugin
</artifactId>
<version>
3.8.1
</version>
<configuration>
<source>
11
</source>
<target>
11
</target>
</configuration>
</plugin>
<plugin>
<groupId>
org.apache.maven.plugins
</groupId>
<artifactId>
maven-javadoc-plugin
</artifactId>
<version>
3.3.1
</version>
<configuration>
<show>
public
</show>
<source>
11
</source>
</configuration>
</plugin>
</plugins>
</build>
<build>
<plugins>
<plugin>
<artifactId>
maven-compiler-plugin
</artifactId>
<version>
3.8.1
</version>
<configuration>
<source>
11
</source>
<target>
11
</target>
</configuration>
</plugin>
<plugin>
<groupId>
org.apache.maven.plugins
</groupId>
<artifactId>
maven-javadoc-plugin
</artifactId>
<version>
3.3.1
</version>
<configuration>
<show>
public
</show>
<source>
11
</source>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>
com.googlecode.json-simple
</groupId>
<artifactId>
json-simple
</artifactId>
<version>
1.1.1
</version>
</dependency>
<dependency>
<groupId>
junit
</groupId>
<artifactId>
junit
</artifactId>
<version>
4.13
</version>
<scope>
test
</scope>
</dependency>
</dependencies>
<dependencies>
<dependency>
<groupId>
com.googlecode.json-simple
</groupId>
<artifactId>
json-simple
</artifactId>
<version>
1.1.1
</version>
</dependency>
<dependency>
<groupId>
junit
</groupId>
<artifactId>
junit
</artifactId>
<version>
4.13
</version>
<scope>
test
</scope>
</dependency>
</dependencies>
</project>
src/main/java/edu/unl/cse/soft160/json_connections/Demonstration.java
View file @
830eafd2
This diff is collapsed.
Click to expand it.
src/main/java/edu/unl/cse/soft160/json_connections/connection/Connection.java
View file @
830eafd2
...
...
@@ -9,14 +9,14 @@ import java.io.IOException;
* Interface for connections to JSON data sources.
*/
public
interface
Connection
{
/**
* Retrieves data in JSON format.
*
* @param dataSpecification identifies the data to be retrieved; the nature of
this String depends on the
* implementing class
* @return requested data
* @throws IOException if the data cannot be requested or delivered
* @throws ParseException if the data is not a properly-formatted JSON string
*/
JSONObject
get
(
String
dataSpecification
)
throws
IOException
,
ParseException
;
/**
* Retrieves data in JSON format.
*
* @param dataSpecification identifies the data to be retrieved; the nature of
*
this String depends on the
implementing class
* @return requested data
* @throws IOException if the data cannot be requested or delivered
* @throws ParseException if the data is not a properly-formatted JSON string
*/
JSONObject
get
(
String
dataSpecification
)
throws
IOException
,
ParseException
;
}
src/main/java/edu/unl/cse/soft160/json_connections/connection/FileConnection.java
View file @
830eafd2
...
...
@@ -13,54 +13,55 @@ import java.util.Objects;
* Connection to JSON files stored locally.
*/
public
class
FileConnection
implements
Connection
{
protected
String
directory
;
protected
String
directory
;
/**
* Initiates connection to files at the top-level directory.
*/
public
FileConnection
()
{
directory
=
""
;
}
/**
* Initiates connection to files at the top-level directory.
*/
public
FileConnection
()
{
directory
=
""
;
}
/**
* Initiates connection to files in a particular directory.
*
* @param directory location of files that will be accessed
*/
public
FileConnection
(
String
directory
)
{
this
.
directory
=
directory
+
"/"
;
}
/**
* Initiates connection to files in a particular directory.
*
* @param directory location of files that will be accessed
*/
public
FileConnection
(
String
directory
)
{
this
.
directory
=
directory
+
"/"
;
}
/**
* Retrieves data from a JSON file.
*
* @param filename name of the file containing data
* @return requested data
* @throws IOException if the data cannot be requested or delivered; probably the most-common reason is that
* the requested file is not in the directory
* @throws ParseException if the data is not a properly-formatted JSON string
*/
public
JSONObject
get
(
String
filename
)
throws
IOException
,
ParseException
{
JSONObject
data
;
try
(
InputStreamReader
inputStreamReader
=
new
InputStreamReader
(
Objects
.
requireNonNull
(
FileConnection
.
class
.
getClassLoader
().
getResourceAsStream
(
directory
+
filename
))))
{
data
=
(
JSONObject
)
new
JSONParser
().
parse
(
inputStreamReader
);
}
catch
(
NullPointerException
originalException
)
{
throw
new
IOException
(
"Could not find "
+
directory
+
filename
+
"."
,
originalException
);
}
return
data
;
}
/**
* Retrieves data from a JSON file.
*
* @param filename name of the file containing data
* @return requested data
* @throws IOException if the data cannot be requested or delivered; probably
* the most-common reason is that the requested file is
* not in the directory
* @throws ParseException if the data is not a properly-formatted JSON string
*/
public
JSONObject
get
(
String
filename
)
throws
IOException
,
ParseException
{
JSONObject
data
;
try
(
InputStreamReader
inputStreamReader
=
new
InputStreamReader
(
Objects
.
requireNonNull
(
FileConnection
.
class
.
getClassLoader
().
getResourceAsStream
(
directory
+
filename
))))
{
data
=
(
JSONObject
)
new
JSONParser
().
parse
(
inputStreamReader
);
}
catch
(
NullPointerException
originalException
)
{
throw
new
IOException
(
"Could not find "
+
directory
+
filename
+
"."
,
originalException
);
}
return
data
;
}
/**
* Saves data to a JSON file.
*
* @param filename name of the file that will hold the data
* @param data data to be saved
* @throws IOException if the data cannot be written to the file
*/
public
void
save
(
String
filename
,
JSONObject
data
)
throws
IOException
{
FileWriter
fileWriter
=
new
FileWriter
(
filename
);
data
.
writeJSONString
(
fileWriter
);
fileWriter
.
close
();
}
/**
* Saves data to a JSON file.
*
* @param filename name of the file that will hold the data
* @param data data to be saved
* @throws IOException if the data cannot be written to the file
*/
public
void
save
(
String
filename
,
JSONObject
data
)
throws
IOException
{
FileWriter
fileWriter
=
new
FileWriter
(
filename
);
data
.
writeJSONString
(
fileWriter
);
fileWriter
.
close
();
}
}
src/main/java/edu/unl/cse/soft160/json_connections/connection/RestConnection.java
View file @
830eafd2
...
...
@@ -19,79 +19,79 @@ import java.util.Objects;
*/
public
class
RestConnection
implements
Connection
{
private
static
final
String
FILENAME
=
"apikeys.json"
;
private
static
final
String
FILENAME
=
"apikeys.json"
;
/**
* Retrieves the specified API key from the {@code apikeys.json} file.
* @param apiKeyName name of the key to be retrieved
* @return the API key
* @throws IOException if no data stored in {@code apikeys.json} could be retrieved
*/
public
static
String
getApiKey
(
String
apiKeyName
)
throws
IOException
{
JSONObject
apiKeyJson
;
try
(
InputStreamReader
inputStreamReader
=
new
InputStreamReader
(
Objects
.
requireNonNull
(
Demonstration
.
class
.
getClassLoader
().
getResourceAsStream
(
FILENAME
))))
{
apiKeyJson
=
(
JSONObject
)
new
JSONParser
().
parse
(
inputStreamReader
);
}
catch
(
NullPointerException
nullPointerException
)
{
FileNotFoundException
newException
=
new
FileNotFoundException
(
"File "
+
FILENAME
+
" not found."
);
newException
.
initCause
(
nullPointerException
);
throw
newException
;
}
catch
(
ParseException
parseException
)
{
throw
new
IOException
(
"Error while parsing file "
+
FILENAME
+
"."
,
parseException
);
}
if
(!
apiKeyJson
.
containsKey
(
apiKeyName
))
{
System
.
err
.
println
(
"WARNING! Could not locate API key named "
+
apiKeyName
+
" in file "
+
FILENAME
+
"."
);
}
String
apiKey
=
apiKeyJson
.
get
(
apiKeyName
).
toString
();
if
(
apiKey
.
equals
(
""
))
{
System
.
err
.
println
(
"WARNING! API key named "
+
apiKeyName
+
" in file "
+
FILENAME
+
" is blank."
);
}
return
apiKey
;
}
/**
* Retrieves the specified API key from the {@code apikeys.json} file.
*
* @param apiKeyName name of the key to be retrieved
* @return the API key
* @throws IOException if no data stored in {@code apikeys.json} could be
* retrieved
*/
public
static
String
getApiKey
(
String
apiKeyName
)
throws
IOException
{
JSONObject
apiKeyJson
;
try
(
InputStreamReader
inputStreamReader
=
new
InputStreamReader
(
Objects
.
requireNonNull
(
Demonstration
.
class
.
getClassLoader
().
getResourceAsStream
(
FILENAME
))))
{
apiKeyJson
=
(
JSONObject
)
new
JSONParser
().
parse
(
inputStreamReader
);
}
catch
(
NullPointerException
nullPointerException
)
{
FileNotFoundException
newException
=
new
FileNotFoundException
(
"File "
+
FILENAME
+
" not found."
);
newException
.
initCause
(
nullPointerException
);
throw
newException
;
}
catch
(
ParseException
parseException
)
{
throw
new
IOException
(
"Error while parsing file "
+
FILENAME
+
"."
,
parseException
);
}
if
(!
apiKeyJson
.
containsKey
(
apiKeyName
))
{
System
.
err
.
println
(
"WARNING! Could not locate API key named "
+
apiKeyName
+
" in file "
+
FILENAME
+
"."
);
}
String
apiKey
=
apiKeyJson
.
get
(
apiKeyName
).
toString
();
if
(
apiKey
.
equals
(
""
))
{
System
.
err
.
println
(
"WARNING! API key named "
+
apiKeyName
+
" in file "
+
FILENAME
+
" is blank."
);
}
return
apiKey
;
}
protected
final
String
protocol
;
protected
final
String
authority
;
protected
final
String
path
;
protected
final
String
apiKey
;
protected
final
String
protocol
;
protected
final
String
authority
;
protected
final
String
path
;
protected
final
String
apiKey
;
/**
* Initializes connection to REST API service.
*
* @param protocol transfer protocol to be used, typically as "http"
* @param authority service provider, typically the server's fully-resolved name
* @param path filepath on the authority to the REST service
* @param apiKey token provided by service owner to authenticate requester and grant appropriate privileges
*/
public
RestConnection
(
String
protocol
,
String
authority
,
String
path
,
String
apiKey
)
{
this
.
protocol
=
protocol
;
this
.
authority
=
authority
;
this
.
path
=
path
;
this
.
apiKey
=
apiKey
;
}
/**
* Initializes connection to REST API service.
*
* @param protocol transfer protocol to be used, typically as "http"
* @param authority service provider, typically the server's fully-resolved name
* @param path filepath on the authority to the REST service
* @param apiKey token provided by service owner to authenticate requester
* and grant appropriate privileges
*/
public
RestConnection
(
String
protocol
,
String
authority
,
String
path
,
String
apiKey
)
{
this
.
protocol
=
protocol
;
this
.
authority
=
authority
;
this
.
path
=
path
;
this
.
apiKey
=
apiKey
;
}
/**
* Retrieves data from REST service.
*
* @param query the REST query specifying the requested data
* @return requested data
* @throws IOException if the data cannot be requested or delivered, such as an incorrect URL or network problems
* @throws ParseException if the data is not a properly-formatted JSON string
*/
public
JSONObject
get
(
String
query
)
throws
IOException
,
ParseException
{
JSONObject
data
;
try
{
URLConnection
connection
=
new
URI
(
protocol
,
authority
,
path
,
query
+
"&appid="
+
apiKey
,
null
).
toURL
().
openConnection
();
connection
.
setRequestProperty
(
"Accept"
,
"application/json"
);
InputStreamReader
inputStreamReader
=
new
InputStreamReader
(
connection
.
getInputStream
());
data
=
(
JSONObject
)
new
JSONParser
().
parse
(
inputStreamReader
);
}
catch
(
URISyntaxException
|
MalformedURLException
originalException
)
{
throw
new
IOException
(
"Could not retrieve usable data from "
+
authority
+
"."
,
originalException
);
}
return
data
;
}
/**
* Retrieves data from REST service.
*
* @param query the REST query specifying the requested data
* @return requested data
* @throws IOException if the data cannot be requested or delivered, such as
* an incorrect URL or network problems
* @throws ParseException if the data is not a properly-formatted JSON string
*/
public
JSONObject
get
(
String
query
)
throws
IOException
,
ParseException
{
JSONObject
data
;
try
{
URLConnection
connection
=
new
URI
(
protocol
,
authority
,
path
,
query
+
"&appid="
+
apiKey
,
null
).
toURL
()
.
openConnection
();
connection
.
setRequestProperty
(
"Accept"
,
"application/json"
);
InputStreamReader
inputStreamReader
=
new
InputStreamReader
(
connection
.
getInputStream
());
data
=
(
JSONObject
)
new
JSONParser
().
parse
(
inputStreamReader
);
}
catch
(
URISyntaxException
|
MalformedURLException
originalException
)
{
throw
new
IOException
(
"Could not retrieve usable data from "
+
authority
+
"."
,
originalException
);
}
return
data
;
}
}
src/main/java/edu/unl/cse/soft160/json_connections/connector/OpenWeatherConnector.java
View file @
830eafd2
This diff is collapsed.
Click to expand it.
src/test/java/edu/unl/cse/soft160/json_connections/AirPollution_UnlNov24ToNov27Test.java
View file @
830eafd2
...
...
@@ -11,88 +11,89 @@ import java.util.List;
import
static
org
.
junit
.
Assert
.
assertEquals
;
public
class
AirPollution_UnlNov24ToNov27Test
{
private
OpenWeatherConnector
connector
;
private
List
<
Date
>
timestamps
;
private
OpenWeatherConnector
connector
;
private
List
<
Date
>
timestamps
;
@Before
public
void
setup
()
throws
IOException
{
connector
=
new
OpenWeatherConnector
(
"air_pollution/history"
);
connector
.
retrieveData
(
"air_pollution-unl-historical.json"
);
timestamps
=
connector
.
getTimestamps
();
}
@Before
public
void
setup
()
throws
IOException
{
connector
=
new
OpenWeatherConnector
(
"air_pollution/history"
);
connector
.
retrieveData
(
"air_pollution-unl-historical.json"
);
timestamps
=
connector
.
getTimestamps
();
}
@Test
public
void
testLocation
()
{
double
expectedLatitude
=
40.8151
;
double
expectedLongitude
=
-
96.7049
;
double
actualLatitude
=
connector
.
getLatitude
();
double
actualLongitude
=
connector
.
getLongitude
();
assertEquals
(
expectedLatitude
,
actualLatitude
,
0.0001
);
assertEquals
(
expectedLongitude
,
actualLongitude
,
0.0001
);
}
@Test
public
void
testLocation
()
{
double
expectedLatitude
=
40.8151
;
double
expectedLongitude
=
-
96.7049
;
double
actualLatitude
=
connector
.
getLatitude
();
double
actualLongitude
=
connector
.
getLongitude
();
assertEquals
(
expectedLatitude
,
actualLatitude
,
0.0001
);
assertEquals
(
expectedLongitude
,
actualLongitude
,
0.0001
);
}
@Test
public
void
testAirQualityIndex
()
{
// We'll pick one of the hours that has AQI==2
OpenWeatherConnector
.
AirQuality
expectedValue
=
OpenWeatherConnector
.
AirQuality
.
LOW
;
OpenWeatherConnector
.
AirQuality
actualValue
=
connector
.
getAirQualityIndex
(
timestamps
.
get
(
25
));
assertEquals
(
expectedValue
,
actualValue
);
}
@Test
public
void
testAirQualityIndex
()
{
// We'll pick one of the hours that has AQI==2
OpenWeatherConnector
.
AirQuality
expectedValue
=
OpenWeatherConnector
.
AirQuality
.
LOW
;
OpenWeatherConnector
.
AirQuality
actualValue
=
connector
.
getAirQualityIndex
(
timestamps
.
get
(
25
));
assertEquals
(
expectedValue
,
actualValue
);
}
@Test
public
void
testCO
()
{
double
expectedValue
=
240.33
;
double
actualValue
=
connector
.
getCarbonMonoxide
(
timestamps
.
get
(
0
));
assertEquals
(
expectedValue
,
actualValue
,
0.0001
);
}
@Test
public
void
testCO
()
{
double
expectedValue
=
240.33
;
double
actualValue
=
connector
.
getCarbonMonoxide
(
timestamps
.
get
(
0
));
assertEquals
(
expectedValue
,
actualValue
,
0.0001
);
}
@Test
public
void
testNO
()
{
// This is interesting. Normally a double, this report has NO as 0 instead of 0.0.
double
expectedValue
=
0.0
;
double
actualValue
=
connector
.
getNitrogenMonoxide
(
timestamps
.
get
(
1
));
assertEquals
(
expectedValue
,
actualValue
,
0.0001
);
}
@Test
public
void
testNO
()
{
// This is interesting. Normally a double, this report has NO as 0 instead of
// 0.0.
double
expectedValue
=
0.0
;
double
actualValue
=
connector
.
getNitrogenMonoxide
(
timestamps
.
get
(
1
));
assertEquals
(
expectedValue
,
actualValue
,
0.0001
);
}
@Test
public
void
testNO2
()
{
double
expectedValue
=
3.64
;
double
actualValue
=
connector
.
getNitrogenDioxide
(
timestamps
.
get
(
2
));
assertEquals
(
expectedValue
,
actualValue
,
0.0001
);
}
@Test
public
void
testNO2
()
{
double
expectedValue
=
3.64
;
double
actualValue
=
connector
.
getNitrogenDioxide
(
timestamps
.
get
(
2
));
assertEquals
(
expectedValue
,
actualValue
,
0.0001
);
}
@Test
public
void
testO3
()
{
double
expectedValue
=
55.08
;
double
actualValue
=
connector
.
getOzone
(
timestamps
.
get
(
3
));
assertEquals
(
expectedValue
,
actualValue
,
0.0001
);
}
@Test
public
void
testO3
()
{
double
expectedValue
=
55.08
;
double
actualValue
=
connector
.
getOzone
(
timestamps
.
get
(
3
));
assertEquals
(
expectedValue
,
actualValue
,
0.0001
);
}
@Test
public
void
testSO2
()
{
double
expectedValue
=
0.08
;
double
actualValue
=
connector
.
getSulfurDioxide
(
timestamps
.
get
(
60
));
assertEquals
(
expectedValue
,
actualValue
,
0.0001
);
}
@Test
public
void
testSO2
()
{
double
expectedValue
=
0.08
;
double
actualValue
=
connector
.
getSulfurDioxide
(
timestamps
.
get
(
60
));
assertEquals
(
expectedValue
,
actualValue
,
0.0001
);
}
@Test
public
void
testPM2_5
()
{
double
expectedValue
=
1.32
;
double
actualValue
=
connector
.
getFineParticulateMatter
(
timestamps
.
get
(
59
));
assertEquals
(
expectedValue
,
actualValue
,
0.0001
);
}
@Test
public
void
testPM2_5
()
{
double
expectedValue
=
1.32
;
double
actualValue
=
connector
.
getFineParticulateMatter
(
timestamps
.
get
(
59
));
assertEquals
(
expectedValue
,
actualValue
,
0.0001
);
}
@Test
public
void
testPM10
()
{
double
expectedValue
=
1.78
;
double
actualValue
=
connector
.
getCoarseParticulateMatter
(
timestamps
.
get
(
58
));
assertEquals
(
expectedValue
,
actualValue
,
0.0001
);
}
@Test
public
void
testPM10
()
{
double
expectedValue
=
1.78
;
double
actualValue
=
connector
.
getCoarseParticulateMatter
(
timestamps
.
get
(
58
));
assertEquals
(
expectedValue
,
actualValue
,
0.0001
);
}
@Test
public
void
testNH3
()
{
double
expectedValue
=
1.85
;
double
actualValue
=
connector
.
getAmmonia
(
timestamps
.
get
(
57
));
assertEquals
(
expectedValue
,
actualValue
,
0.0001
);
}
@Test
public
void
testNH3
()
{
double
expectedValue
=
1.85
;
double
actualValue
=
connector
.
getAmmonia
(
timestamps
.
get
(
57
));
assertEquals
(
expectedValue
,
actualValue
,
0.0001
);
}
}
src/test/java/edu/unl/cse/soft160/json_connections/AirPollution_WebsiteExampleTest.java
View file @
830eafd2
...
...
@@ -10,92 +10,92 @@ import java.util.Date;
import
static
org
.
junit
.
Assert
.
assertEquals
;
public
class
AirPollution_WebsiteExampleTest
{
private
OpenWeatherConnector
connector
;
@Before
public
void
setup
()
throws
IOException
{
connector
=
new
OpenWeatherConnector
(
"air_pollution"
);
connector
.
retrieveData
(
"website-example.json"
);
}
@Test
public
void
testLocation
()
{
double
expectedLatitude
=
50.0
;
double
expectedLongitude
=
50.0
;
double
actualLatitude
=
connector
.
getLatitude
();
double
actualLongitude
=
connector
.
getLongitude
();
assertEquals
(
expectedLatitude
,
actualLatitude
,
0.0001
);
assertEquals
(
expectedLongitude
,
actualLongitude
,
0.0001
);
}
@Test