-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
f6b2231
commit adb6775
Showing
23 changed files
with
432 additions
and
176 deletions.
There are no files selected for viewing
This file contains 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
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,103 +1,32 @@ | ||
package hexlet.code; | ||
|
||
import java.io.IOException; | ||
import java.nio.file.Path; | ||
import java.util.Map; | ||
import java.util.Set; | ||
import java.util.TreeSet; | ||
|
||
public class Differ { | ||
public static String generate(String filePath1, String filePath2, String format) throws Exception { | ||
// Чтение содержимого файлов | ||
String fileContent1 = ReadFile.readFile(Path.of(filePath1)); | ||
String fileContent2 = ReadFile.readFile(Path.of(filePath2)); | ||
import java.util.Map; | ||
import java.util.List; | ||
|
||
// Получение расширения файлов для парсинга | ||
String extension1 = ReadFile.getFileExtension(Path.of(filePath1)); | ||
String extension2 = ReadFile.getFileExtension(Path.of(filePath2)); | ||
public final class Differ { | ||
|
||
// Парсинг содержимого файлов в Map | ||
Map<String, Object> map1 = Parser.parseString(fileContent1, extension1); | ||
Map<String, Object> map2 = Parser.parseString(fileContent2, extension2); | ||
public static String generate(String filePath1, String filePath2, String format) throws IOException { | ||
Path path1 = Reader.getPath(filePath1); | ||
Path path2 = Reader.getPath(filePath2); | ||
|
||
// Создание отсортированного набора ключей | ||
Set<String> allKeys = new TreeSet<>(); | ||
allKeys.addAll(map1.keySet()); | ||
allKeys.addAll(map2.keySet()); | ||
Map<String, Object> data1 = Parser.parseString( | ||
Reader.readFile(path1), | ||
Reader.getFileExtension(path1) | ||
); | ||
Map<String, Object> data2 = Parser.parseString( | ||
Reader.readFile(path2), | ||
Reader.getFileExtension(path2) | ||
); | ||
|
||
// Формирование результата в зависимости от формата | ||
return switch (format) { | ||
case "plain" -> formatPlain(allKeys, map1, map2); | ||
case "json" -> formatJson(allKeys, map1, map2); | ||
default -> formatStylish(allKeys, map1, map2); // формат по умолчанию | ||
}; | ||
List<Map<String, Object>> differDifferNodeList = DifferListComposer.composeList(data1, data2); | ||
return Formatter.formatString(differDifferNodeList, format); | ||
} | ||
|
||
private static String formatStylish(Set<String> allKeys, Map<String, Object> map1, Map<String, Object> map2) { | ||
StringBuilder result = new StringBuilder("{\n"); | ||
|
||
for (String key : allKeys) { | ||
Object value1 = map1.get(key); | ||
Object value2 = map2.get(key); | ||
|
||
if (value1 == null && value2 != null) { | ||
result.append(" + ").append(key).append(": ").append(value2).append("\n"); | ||
} else if (value1 != null && value2 == null) { | ||
result.append(" - ").append(key).append(": ").append(value1).append("\n"); | ||
} else if (value1 != null && value2 != null && !value1.equals(value2)) { | ||
result.append(" - ").append(key).append(": ").append(value1).append("\n"); | ||
result.append(" + ").append(key).append(": ").append(value2).append("\n"); | ||
} else if (value1 != null && value2 != null && value1.equals(value2)) { | ||
result.append(" ").append(key).append(": ").append(value1).append("\n"); | ||
} | ||
} | ||
|
||
result.append("}"); | ||
return result.toString(); | ||
public static String generate(String filePath1, String filePath2) throws IOException { | ||
return generate(filePath1, filePath2, "stylish"); | ||
} | ||
|
||
private static String formatPlain(Set<String> allKeys, Map<String, Object> map1, Map<String, Object> map2) { | ||
StringBuilder result = new StringBuilder(); | ||
|
||
for (String key : allKeys) { | ||
Object value1 = map1.get(key); | ||
Object value2 = map2.get(key); | ||
|
||
if (value1 == null) { | ||
result.append("Property '").append(key).append("' was added with value: ").append(value2).append("\n"); | ||
} else if (value2 == null) { | ||
result.append("Property '").append(key).append("' was removed").append("\n"); | ||
} else if (!value1.equals(value2)) { | ||
result.append("Property '").append(key).append("' was updated. From ").append(value1).append(" to ").append(value2).append("\n"); | ||
} | ||
} | ||
|
||
return result.toString().trim(); | ||
} | ||
|
||
private static String formatJson(Set<String> allKeys, Map<String, Object> map1, Map<String, Object> map2) { | ||
StringBuilder result = new StringBuilder("{"); | ||
|
||
for (String key : allKeys) { | ||
Object value1 = map1.get(key); | ||
Object value2 = map2.get(key); | ||
|
||
if (value1 == null) { | ||
result.append("\"").append(key).append("\": ").append(value2).append(", "); | ||
} else if (value2 == null) { | ||
result.append("\"").append(key).append("\": ").append(value1).append(", "); | ||
} else if (!value1.equals(value2)) { | ||
result.append("\"").append(key).append("\": ").append(value2).append(", "); | ||
} else { | ||
result.append("\"").append(key).append("\": ").append(value1).append(", "); | ||
} | ||
} | ||
|
||
// Удаляем последнюю запятую и пробел, если они есть | ||
if (result.length() > 1) { | ||
result.setLength(result.length() - 2); | ||
} | ||
|
||
result.append("}"); | ||
return result.toString(); | ||
} | ||
} | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
package hexlet.code; | ||
|
||
import java.util.Optional; | ||
import java.util.List; | ||
import java.util.ArrayList; | ||
import java.util.Map; | ||
import java.util.LinkedHashMap; | ||
import java.util.Set; | ||
import java.util.TreeSet; | ||
|
||
public final class DifferListComposer { | ||
|
||
public static List<Map<String, Object>> composeList( | ||
Map<String, Object> data1, | ||
Map<String, Object> data2 | ||
) { | ||
List<Map<String, Object>> differNodeList = new ArrayList<>(); | ||
|
||
Set<String> keys = new TreeSet<>(data1.keySet()); | ||
keys.addAll(data2.keySet()); | ||
for (String key : keys) { | ||
differNodeList.add(makeDifferNode(key, data1, data2)); | ||
} | ||
|
||
return differNodeList; | ||
} | ||
|
||
private static Map<String, Object> makeDifferNode( | ||
String key, | ||
Map<String, Object> data1, | ||
Map<String, Object> data2 | ||
) { | ||
Map<String, Object> differNode = new LinkedHashMap<>(); | ||
Optional<Object> value1 = Optional.ofNullable(data1.get(key)); | ||
Optional<Object> value2 = Optional.ofNullable(data2.get(key)); | ||
|
||
differNode.put("key", key); | ||
if (!data1.containsKey(key)) { | ||
differNode.put("condition", "ADDED"); | ||
differNode.put("value", value2.orElse(null)); | ||
} else if (!data2.containsKey(key)) { | ||
differNode.put("condition", "DELETED"); | ||
differNode.put("value", value1.orElse(null)); | ||
} else if (value1.equals(value2)) { | ||
differNode.put("condition", "UNCHANGED"); | ||
differNode.put("value", value1.orElse(null)); | ||
} else { | ||
differNode.put("condition", "CHANGED"); | ||
differNode.put("value1", value1.orElse(null)); | ||
differNode.put("value2", value2.orElse(null)); | ||
} | ||
return differNode; | ||
} | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
package hexlet.code; | ||
|
||
import hexlet.code.formatters.Json; | ||
import hexlet.code.formatters.StringFormatter; | ||
import hexlet.code.formatters.Stylish; | ||
import hexlet.code.formatters.Plain; | ||
|
||
import java.io.IOException; | ||
import java.util.List; | ||
import java.util.Map; | ||
|
||
public final class Formatter { | ||
|
||
public static String formatString(List<Map<String, Object>> differEntryList, String format) throws IOException { | ||
StringFormatter formatter = getFormatter(format); | ||
return formatter.format(differEntryList); | ||
} | ||
|
||
private static StringFormatter getFormatter(String format) throws IOException { | ||
return switch (format) { | ||
case "stylish" -> new Stylish(); | ||
case "plain" -> new Plain(); | ||
case "json" -> new Json(); | ||
default -> | ||
throw new IOException("File should have 'stylish', 'plain' or 'json' format! (was '%s')" | ||
.formatted(format)); | ||
}; | ||
} | ||
} |
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package hexlet.code.formatters; | ||
|
||
import com.fasterxml.jackson.databind.ObjectMapper; | ||
import java.io.IOException; | ||
|
||
import java.util.List; | ||
import java.util.Map; | ||
|
||
public final class Json implements StringFormatter { | ||
|
||
@Override | ||
public String format(List<Map<String, Object>> differNodeList) throws IOException { | ||
ObjectMapper objectMapper = new ObjectMapper(); | ||
return objectMapper.writeValueAsString(differNodeList); | ||
} | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
package hexlet.code.formatters; | ||
|
||
import java.util.List; | ||
import java.util.Map; | ||
|
||
public final class Plain implements StringFormatter { | ||
|
||
@Override | ||
public String format(List<Map<String, Object>> differNodeList) { | ||
List<Map<String, Object>> filteredList = differNodeList.stream() | ||
.filter(node -> !node.get("condition").equals("UNCHANGED")) | ||
.toList(); | ||
|
||
StringBuilder sb = new StringBuilder(); | ||
|
||
for (Map<String, Object> node : filteredList) { | ||
String condition = (String) node.get("condition"); | ||
switch (condition) { | ||
case "ADDED" -> { | ||
String value = formatComplexValue(node.get("value")); | ||
sb.append("Property '%s' was added with value: %s%n" | ||
.formatted(node.get("key"), value)); | ||
} | ||
case "DELETED" -> sb.append("Property '%s' was removed%n" | ||
.formatted(node.get("key"))); | ||
case "CHANGED" -> { | ||
String value1 = formatComplexValue(node.get("value1")); | ||
String value2 = formatComplexValue(node.get("value2")); | ||
sb.append("Property '%s' was updated. From %s to %s%n" | ||
.formatted(node.get("key"), value1, value2)); | ||
} | ||
default -> throw new IllegalStateException("Unexpected value: " + condition); | ||
} | ||
} | ||
|
||
return sb.deleteCharAt(sb.length() - 1).toString(); | ||
} | ||
|
||
private static String formatComplexValue(Object value) { | ||
if (value == null) { | ||
return null; | ||
} | ||
if (value instanceof List<?> || value instanceof Map<?, ?>) { | ||
return "[complex value]"; | ||
} | ||
if (value instanceof String) { | ||
return String.format("'%s'", value); | ||
} | ||
return value.toString(); | ||
} | ||
} |
9 changes: 9 additions & 0 deletions
9
app/src/main/java/hexlet/code/formatters/StringFormatter.java
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package hexlet.code.formatters; | ||
|
||
import java.io.IOException; | ||
import java.util.List; | ||
import java.util.Map; | ||
|
||
public interface StringFormatter { | ||
String format(List<Map<String, Object>> differEntryList) throws IOException; | ||
} |
Oops, something went wrong.