Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 42 additions & 41 deletions pom.xml
Original file line number Diff line number Diff line change
@@ -1,46 +1,47 @@
<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">
<groupId>ru.hh.school</groupId>
<modelVersion>4.0.0</modelVersion>
<artifactId>java-stdlib</artifactId>
<packaging>jar</packaging>
<name>Homework exercise for 'Java Standard Library' lecture</name>
<version>1.0-SNAPSHOT</version>
<groupId>ru.hh.school</groupId>
<modelVersion>4.0.0</modelVersion>
<artifactId>java-stdlib</artifactId>
<packaging>jar</packaging>
<name>Homework exercise for 'Java Standard Library' lecture</name>
<version>1.0-SNAPSHOT</version>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>1.4</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<finalName>${project.artifactId}</finalName>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<manifestEntries>
<Main-Class>ru.hh.school.stdlib.Launcher</Main-Class>
</manifestEntries>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>1.4</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<finalName>${project.artifactId}</finalName>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<manifestEntries>
<Main-Class>ru.hh.school.stdlib.Launcher</Main-Class>
</manifestEntries>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>

<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.7</version>
<scope>test</scope>
</dependency>
</dependencies>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.7</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
65 changes: 65 additions & 0 deletions src/main/java/ru/hh/school/stdlib/ClientHandler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package ru.hh.school.stdlib;

import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;
import java.util.concurrent.TimeUnit;

public class ClientHandler implements Runnable {
private Socket incoming;
private final Substitutor3000 sbst;
private final Server server;


public ClientHandler(Socket i, Server srv, Substitutor3000 sb) {
incoming = i;
server = srv;
sbst = sb;
}

@Override
public void run() {
try {
try {
Scanner in = new Scanner(incoming.getInputStream());
PrintWriter out = new PrintWriter(incoming.getOutputStream());
String line = in.nextLine().trim();
String[] req = line.split(" ", 3);
int len = req.length;
if (req[0].equals("GET")) {
TimeUnit.MILLISECONDS.sleep(server.getSleepTime());
if (len >= 2) {
try {
String temp;
temp = sbst.get(req[1], null);
out.println("VALUE");
out.println(temp);
} catch (InfiniteRecursionException e) {
out.println("ERROR " + e.getMessage());
}
} else out.println("ERROR GET syntax: GET key");
} else if ((req[0].equals("SET")) && (req[1].equals("SLEEP"))) {
if (len == 3) {
server.setSleepTime(Long.valueOf(req[2]));
} else out.println("ERROR SET syntax: SET SLEEP sleeptime");
} else if (req[0].equals("PUT")) {
TimeUnit.MILLISECONDS.sleep(server.getSleepTime());
if (len == 3) {
sbst.put(req[1], req[2]);
out.println("OK");
} else out.println("ERROR PUT syntax: PUT key value");
} else out.println("ERROR Unsupported request! We accept GET, PUT or SET SLEEP here!");
out.flush();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
incoming.close();
}
} catch (IOException e) {
e.printStackTrace();
}

}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package ru.hh.school.stdlib;

public class InfiniteRecursionException extends Exception {
public InfiniteRecursionException(String s) {
super(s);
}
}
43 changes: 22 additions & 21 deletions src/main/java/ru/hh/school/stdlib/Launcher.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,27 @@
import java.net.InetSocketAddress;

public class Launcher {
public static void main(String[] args) throws IOException {
String host;
int port;
try {
if (args.length == 0) {
host = "127.0.0.1";
port = 9129;
} else if (args.length == 3) {
host = args[1];
port = Integer.parseInt(args[2]);
} else {
throw new IllegalArgumentException();
}
} catch (Exception e) {
System.err.printf("Usage: %s [host port]%n", args[0]);
System.exit(1);
return; // попробуйте закомментировать этот return
public static void main(String[] args) throws IOException {
String host;
int port;
try {
if (args.length == 0) {
host = "127.0.0.1";
port = 9129;
} else if (args.length == 2) {
host = args[0];
port = Integer.parseInt(args[1]);
} else {
throw new IllegalArgumentException();
}
} catch (Exception e) {
System.err.printf("Usage: %s [host port]%n", args[0]);
for (String s : args) System.out.println(s);
e.printStackTrace();
System.exit(1);
return; // попробуйте закомментировать этот return
}
InetSocketAddress addr = InetSocketAddress.createUnresolved(host, port);
new Server(addr).run();
}
InetSocketAddress addr = InetSocketAddress.createUnresolved(host, port);

new Server(addr).run();
}
}
47 changes: 38 additions & 9 deletions src/main/java/ru/hh/school/stdlib/Server.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,46 @@

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Server {
public Server(InetSocketAddress addr) {
throw new UnsupportedOperationException();
}
private ServerSocket s;
private Substitutor3000 sbst;
private Long sleepTime;

public void run() throws IOException {
throw new UnsupportedOperationException();
}
public Server(InetSocketAddress addr) {
try {
s = new ServerSocket(addr.getPort());
sbst = new Substitutor3000();
sleepTime = 0L;
} catch (Exception e) {
System.err.print("ERROR ");
e.printStackTrace();
System.exit(1);
}
}

public int getPort() {
throw new UnsupportedOperationException();
}
public void run() throws IOException {
System.out.printf("Server started on port %d%n", this.getPort());
ExecutorService exec = Executors.newCachedThreadPool();
while (true) {
Socket incoming = s.accept();
exec.execute(new ClientHandler(incoming, this, sbst));
}
}

public int getPort() {
return s.getLocalPort();
}

public synchronized Long getSleepTime() {
return sleepTime;
}

public synchronized void setSleepTime(Long sleepTime) {
this.sleepTime = sleepTime;
}
}
40 changes: 34 additions & 6 deletions src/main/java/ru/hh/school/stdlib/Substitutor3000.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,39 @@
package ru.hh.school.stdlib;

import java.util.HashMap;
import java.util.HashSet;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Substitutor3000 {
public void put(String key, String value) {
throw new UnsupportedOperationException();
}

public String get(String key) {
throw new UnsupportedOperationException();
}
private HashMap<String, String> storage;

public Substitutor3000() {
storage = new HashMap<String, String>();
}

public synchronized void put(String key, String value) {
storage.put(key, value);
}

public synchronized String get(String key, HashSet<String> inProgress) throws InfiniteRecursionException {
if (inProgress == null)
inProgress = new HashSet<String>();
else if (inProgress.contains(key))
throw new InfiniteRecursionException("Infinite recursion.");
String out = storage.get(key);
if (out == null) return "";
inProgress.add(key);
Pattern pattern = Pattern.compile("\\p{Sc}\\{(\\S+)\\}");
Matcher matcher = pattern.matcher(out);
while (matcher.find()) {
String part = get(matcher.group(1), inProgress);
if (part == null)
part = "";
out = out.replace(matcher.group(0), part);
}
inProgress.remove(key);
return out;
}
}
52 changes: 26 additions & 26 deletions src/test/java/ru/hh/school/stdlib/BaseFunctionalTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,36 +5,36 @@
import java.net.Socket;

public class BaseFunctionalTest {
private static Server server;
private static Server server;

protected BaseFunctionalTest() {
synchronized (BaseFunctionalTest.class) {
try {
if (server == null) {
server = new Server(new InetSocketAddress("127.0.0.1", 0));
new Thread(new Runnable() {
public void run() {
try {
server.run();
} catch (IOException e) {
protected BaseFunctionalTest() {
synchronized (BaseFunctionalTest.class) {
try {
if (server == null) {
server = new Server(new InetSocketAddress("127.0.0.1", 0));
new Thread(new Runnable() {
public void run() {
try {
server.run();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}).start();
Thread.sleep(100);
System.out.printf("Server started on port %d%n", server.getPort());
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}).start();
Thread.sleep(100);
System.out.printf("Server started on port %d%n", server.getPort());
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}

protected Socket connect() {
try {
return new Socket("127.0.0.1", server.getPort());
} catch (IOException e) {
throw new RuntimeException(e);

protected Socket connect() {
try {
return new Socket("127.0.0.1", server.getPort());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
Loading