Last active
October 4, 2019 01:45
-
-
Save comp500/1f0b9b4f5cf9c8e52e2aef53ab6945eb to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.io.BufferedReader; | |
import java.io.IOException; | |
import java.io.InputStreamReader; | |
import java.net.URL; | |
import java.net.URLConnection; | |
import java.util.Scanner; | |
import java.util.function.Consumer; | |
import java.util.function.Function; | |
import java.util.regex.Matcher; | |
import java.util.regex.Pattern; | |
import java.util.stream.Stream; | |
public class SCChallengeEmail { | |
// Create a Pattern (Regular Expression) that matches the name in the HTML page | |
private static final Pattern nameMatcher = Pattern.compile("property=\"name\"\\s*>([\\w ]+)<"); | |
public static void main(String[] args) throws IOException { | |
// Initialise the System.in scanner | |
Scanner sc = new Scanner(System.in); | |
// Generate an infinite stream from the user's input | |
Stream.generate(() -> { | |
System.out.print("Enter a username: "); | |
return sc.nextLine(); | |
}) | |
// Sanitise each input string | |
.map(s -> s.replaceAll("[^\\w]", "")) | |
// Filter each input string, to check if it is a valid input | |
.filter(i -> { | |
if (i.isEmpty()) { | |
// Tell the user the username isn't valid | |
System.out.println("Username is not valid!"); | |
return false; | |
} | |
return true; | |
}) | |
// Create a URL from each input string | |
.map(catchWrapper(i -> new URL("https://www.ecs.soton.ac.uk/people/" + i))) | |
// Open a connection to the URL | |
.map(catchWrapper(URL::openConnection)) | |
.peek(catchWrapperConsumer(URLConnection::connect)) | |
// Create a BufferedReader to read the InputStream of the connection | |
.map(catchWrapper(c -> new BufferedReader(new InputStreamReader(c.getInputStream())))) | |
// Get a Stream containing the lines of the page source | |
.map(BufferedReader::lines) | |
// For this Stream, do the following: | |
.map(s -> s | |
// Match the Regular Expression against each line of the page source | |
// Filter the lines for lines that match | |
.filter(nameMatcher.asPredicate()) | |
.flatMap(l -> { | |
Matcher m = nameMatcher.matcher(l); | |
if (m.find()) { | |
// Get the 1st group of the match | |
return Stream.of(m.group(1)); | |
} | |
return Stream.empty(); | |
}).findFirst() // Find the first line that matches the Regular Expression | |
) | |
// Check the Optional<String> | |
.flatMap(l -> { | |
// If the Optional<String> is present, resolve it | |
if (l.isPresent()) { | |
return Stream.of(l.get()); | |
} | |
// Tell the user the name wasn't found | |
System.out.println("Name not found!"); | |
return Stream.empty(); | |
}) | |
// Print the result | |
.forEach(System.out::println); | |
// Close the input stream (this probably won't ever be called!!) | |
sc.close(); | |
} | |
// The Function interface, but it throws an Exception | |
@FunctionalInterface | |
public interface CheckedFunction<T, R> { | |
R apply(T t) throws Exception; | |
} | |
// Turn exceptions into runtime exceptions, so they are accepted in map/filter/peek | |
private static <T, R> Function<T, R> catchWrapper(CheckedFunction<T, R> f) { | |
return i -> { | |
try { | |
return f.apply(i); | |
} catch (Exception e) { | |
throw new RuntimeException(e); | |
} | |
}; | |
} | |
// The Consumer interface, but it throws an Exception | |
@FunctionalInterface | |
public interface CheckedConsumer<T> { | |
void apply(T t) throws Exception; | |
} | |
// Turn exceptions into runtime exceptions, so they are accepted in map/filter/peek | |
private static <T> Consumer<T> catchWrapperConsumer(CheckedConsumer<T> f) { | |
return i -> { | |
try { | |
f.apply(i); | |
} catch (Exception e) { | |
throw new RuntimeException(e); | |
} | |
}; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment