Skip to content

Instantly share code, notes, and snippets.

@comp500
Last active October 4, 2019 01:45
Show Gist options
  • Save comp500/1f0b9b4f5cf9c8e52e2aef53ab6945eb to your computer and use it in GitHub Desktop.
Save comp500/1f0b9b4f5cf9c8e52e2aef53ab6945eb to your computer and use it in GitHub Desktop.
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