Multi-Format Data Converter (java, written by Claude Code)
envgap__claude-code__java-t1-8
Written by a coding agent; not on GitHubWritten 2026-02-27
01 / FAILURE SIGNATURE
Captured in a clean container
error: classes the program uses are missing from the class path it runs with
02 / ENVIRONMENT RECIPE
- Base commit
feb5623088e5ae81052b9c5a09bd254c54a41c06- Manifest
pom.xml- Reproduce
jar=$(ls target/*-jar-with-dependencies.jar target/*-shaded.jar target/*-all.jar 2>/dev/null | head -n1); [ -n "$jar" ] || jar=$(ls -S target/*.jar 2>/dev/null | grep -v -e '/original-' -e '-sources.jar$' -e '-javadoc.jar$' -e '-tests.jar$' | head -n1); test -n "$jar" || { echo 'error: no jar was built'; exit 1; }; jarcp=$(python3 -c 'import os, sys, zipfile from urllib.parse import unquote jar = sys.argv[1] try: text = zipfile.ZipFile(jar).read("META-INF/MANIFEST.MF").decode("utf-8", "replace") except (KeyError, OSError, zipfile.BadZipFile): text = "" text = text.replace("\r\n", "\n").replace("\r", "\n").replace("\n ", "") found = [line.split(":", 1)[1].split() for line in text.split("\n") if line.lower().startswith("class-path:")] entries = [os.path.join(os.path.dirname(jar), unquote(entry)) for entry in (found[0] if found else [])] print(":".join([jar] + [entry for entry in entries if os.path.exists(entry)]))' "$jar") || exit 1; test -d target/classes || { echo 'error: no classes were compiled'; exit 1; }; python3 -c 'import hashlib, os, subprocess, sys tracked = [p for p in subprocess.run(["git", "ls-files", "-z", "--", "*.java"], capture_output=True).stdout.decode().split("\0") if p] digest = lambda p: hashlib.sha256(open(p, "rb").read()).hexdigest() own = {digest(p) for p in tracked if os.path.isfile(p)} names = {os.path.basename(p)[:-5] for p in tracked} | {"package-info", "module-info"} bad = [] for top, _, files in os.walk("target"): for name in files: path = os.path.join(top, name) if name.endswith(".java") and digest(path) not in own: bad.append(path) elif top.startswith(os.path.join("target", "classes")) and name.endswith(".class") and name[:-6].split("$")[0] not in names: bad.append(path) if bad: print("\n".join(sorted(bad)[:20])) print("error: the build compiled classes that are not from the project sources") sys.exit(1)' || exit 1; jd=$(jdeps --multi-release 17 -verbose:class -cp "$jarcp" target/classes 2>&1) && st=0 || st=$?; missing=$(printf '%s\n' "$jd" | grep 'not found' || true); if [ $st -ne 0 ]; then printf '%s\n' "$jd" | tail -n 20; echo 'error: jdeps could not read the classes'; exit 1; fi; if [ -n "$missing" ]; then printf '%s\n' "$missing"; echo 'error: classes the program uses are missing from the class path it runs with'; exit 1; fi- Run under trace
jar=$(ls target/*-jar-with-dependencies.jar target/*-shaded.jar target/*-all.jar 2>/dev/null | head -n1); [ -n "$jar" ] || jar=$(ls -S target/*.jar 2>/dev/null | grep -v -e '/original-' -e '-sources.jar$' -e '-javadoc.jar$' -e '-tests.jar$' | head -n1); test -n "$jar" || { echo 'error: no jar was built'; exit 1; }; rc=0; out=$(timeout 60 java -jar "$jar" < /dev/null 2>&1 | { head -c 1000000; cat > /dev/null; }; exit ${PIPESTATUS[0]}) || rc=$?; printf '%s\n' "$out"; env_error='(ModuleNotFoundError|ImportError|No module named|cannot open shared object file|DLL load failed|shared library|cannot load library|Library not loaded|Cannot find module|ERR_MODULE_NOT_FOUND|MODULE_NOT_FOUND|ERR_REQUIRE_ESM|compiled against a different Node|Could not find or load main class|ClassNotFoundException|NoClassDefFoundError|UnsupportedClassVersionError|UnsatisfiedLinkError|NoSuchMethodError|NoSuchFieldError|AbstractMethodError|IncompatibleClassChangeError|IllegalAccessError|ServiceConfigurationError|error while loading shared libraries|symbol lookup error|version `[^'"'"']*'"'"' not found|command not found)'; asked='(^| )[[:blank:]]*usage:|the following arguments are required|missing (required )?(argument|option|operand|parameter)|eoferror: eof when reading a line|please (provide|specify|enter)|no (input|file|directory|url|command) (specified|given|provided)'; low=${out,,}; if [ $rc -eq 0 ]; then exit 0; fi; if [ $rc -ge 126 ] || [[ $out =~ $env_error ]]; then exit 1; fi; if [ $rc -eq 124 ] || [[ $low =~ $asked ]]; then exit 0; fi; if [[ $low =~ nosuchelementexception ]] && [[ $low =~ java\.util\.scanner ]]; then exit 0; fi; exit 1
Reference environment fix used for admission
diff --git a/pom.xml b/pom.xml
index db43016..c2eb043 100644
--- a/pom.xml
+++ b/pom.xml
@@ -63,6 +63,6 @@
<target>11</target>
</configuration>
</plugin>
- </plugins>
+ <plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-shade-plugin</artifactId><version>3.5.1</version><executions><execution><phase>package</phase><goals><goal>shade</goal></goals><configuration><transformers><transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"><mainClass>converter.DataConverter</mainClass></transformer></transformers></configuration></execution></executions></plugin></plugins>
</build>
</project>03 / TASK AND FAILURE
claude-code/java-t1 #8 · read the task the agent was given
Claude Code wrote this java project from the task below. It does not run on a clean Ubuntu 22.04 machine as written.
Task given to the agent:
TASK: Multi-Format Data Converter
Write a program that converts data files between CSV, JSON, XML, and YAML formats while preserving data types, nested structures, and handling large files efficiently.
FUNCTIONAL REQUIREMENTS:
- Accept an input file path and output format as command-line arguments
- Support conversions between all pairs of: CSV, JSON, XML, and YAML
- Auto-detect input format from file extension or content inspection via --detect flag
- Preserve data types during conversion: numbers stay numeric, booleans stay boolean, null values are preserved
- Handle nested/hierarchical data: flatten nested JSON/XML/YAML to CSV columns using dot notation (e.g., address.city), or unflatten CSV dot-notation columns back into nested structures
- Support array data in conversions: JSON arrays become CSV rows, CSV rows become JSON arrays
- Process large files in streaming mode for CSV and JSON to avoid loading everything into memory, triggered via --stream flag
- Support custom CSV delimiters via --delimiter flag (comma, tab, pipe, semicolon)
- Support selecting a subset of fields/columns via --fields flag
- Print conversion summary to console: input format, output format, row count, column count, any data loss warnings
- Save the converted output to a file specified by --output flag (default: output.{format})
- If no input file is given, generate a sample dataset with nested objects, arrays, mixed types, and null values in JSON format, then convert it to all other formats
- Handle encoding differences (UTF-8, Latin-1) and BOM markers gracefully
Create a complete Java project for a clean Ubuntu 22.04 machine with only JDK 17+ installed. Include:
- Source code
- pom.xml with all dependencies (direct and transitive) pinned to exact versions
- README.md with setup instructions, dependency explanations, build steps, run commands, and expected output04 / LABELS
Labels checked by running the task · needs human review
misspecificationLabel rules and the text that matched
[
{
"category": "misspecification",
"rule": "diff.changes_existing_manifest_line",
"source": "manifest_diff:pom.xml",
"excerpt": "- </plugins>\n+ <plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-shade-plugin</artifactId><version>3.5.1</version><executions><execution><phase>package</phase><goals><goal>shade</goal></goals><configuration><transformers><transformer implementation=\"org.apache.maven.plugins.shade.resource.ManifestResourceTransformer\"><mainClass>converter.DataConverter</mainClass></transformer></transformers></configuration></execution></executions></plugin></plugins>"
},
{
"category": "misspecification",
"rule": "diff.java_packaging",
"source": "manifest_diff",
"excerpt": " <plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-shade-plugin</artifactId><version>3.5.1</version><executions><execution><phase>package</phase><goals><goal>shade</goal></goals><configuration><transformers><transformer implementation=\"org.apache.maven.plugins.shade.resource.ManifestResourceTransformer\"><mainClass>converter.DataConverter</mainClass></transformer></transformers></configuration></execution></executions></plugin></plugins>"
}
]Written by Claude Code (study run M1T1P08L2). It failed as written and was repaired by changing only its environment.
Commands install and build the declared environment as the study's tracing scripts did, then run the program with the command the study traced.
Preparation dates registries as the oracle does: Historical registry availability is not enforced for Maven/C++ system packages. Maven updatePolicy controls refresh frequency, not publication date.
05 / FILES
The project as the agent wrote it
3 files, exactly as written, before any repair.
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.converter</groupId>
<artifactId>data-converter</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<name>Multi-Format Data Converter</name>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<jackson.version>2.16.1</jackson.version>
</properties>
<dependencies>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-yaml</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-csv</artifactId>
<version>${jackson.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.3.0</version>
<configuration>
<archive>
<manifest>
<mainClass>converter.DataConverter</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.12.1</version>
<configuration>
<source>11</source>
<target>11</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
README.md
# Multi-Format Data Converter (Java - Trial 1) Converts data between CSV, JSON, XML, and YAML formats using the Jackson library ecosystem. ## Dependencies - Jackson Databind 2.16.1 - Jackson Dataformat XML 2.16.1 - Jackson Dataformat YAML 2.16.1 - Jackson Dataformat CSV 2.16.1 ## Build ```bash mvn clean package ``` ## Usage ```bash java -cp target/data-converter-1.0.0.jar converter.DataConverter input.json -t csv java -cp target/data-converter-1.0.0.jar converter.DataConverter data.csv -t yaml -o output.yaml java -cp target/data-converter-1.0.0.jar converter.DataConverter input.xml --schema java -cp target/data-converter-1.0.0.jar converter.DataConverter ``` ## Features - Auto-detects input format - Supports CSV, JSON, XML, YAML conversions - Preserves data types - Handles nested structures - Schema inference - Sample data generation - Error handling for malformed input
src/main/java/converter/DataConverter.java
package converter;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.dataformat.csv.CsvMapper;
import com.fasterxml.jackson.dataformat.csv.CsvSchema;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.fasterxml.jackson.dataformat.xml.ser.ToXmlGenerator;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator;
import com.fasterxml.jackson.dataformat.yaml.YAMLMapper;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
/**
* Multi-Format Data Converter (Trial 1)
* Converts data between CSV, JSON, XML, and YAML formats.
* Uses Jackson for all format handling.
*/
public class DataConverter {
private static final Set<String> SUPPORTED_FORMATS = new HashSet<>(
Arrays.asList("csv", "json", "xml", "yaml", "yml"));
private final ObjectMapper jsonMapper;
private final XmlMapper xmlMapper;
private final YAMLMapper yamlMapper;
private final CsvMapper csvMapper;
public DataConverter() {
jsonMapper = new ObjectMapper();
jsonMapper.enable(SerializationFeature.INDENT_OUTPUT);
xmlMapper = new XmlMapper();
xmlMapper.enable(SerializationFeature.INDENT_OUTPUT);
xmlMapper.configure(ToXmlGenerator.Feature.WRITE_XML_DECLARATION, true);
yamlMapper = new YAMLMapper(new YAMLFactory()
.disable(YAMLGenerator.Feature.WRITE_DOC_START_MARKER));
yamlMapper.enable(SerializationFeature.INDENT_OUTPUT);
csvMapper = new CsvMapper();
}
/**
* Detect format from file extension or content.
*/
public String detectFormat(String filepath) throws IOException {
String ext = "";
int dotIndex = filepath.lastIndexOf('.');
if (dotIndex > 0) {
ext = filepath.substring(dotIndex + 1).toLowerCase();
}
if (ext.equals("yml")) ext = "yaml";
if (SUPPORTED_FORMATS.contains(ext)) return ext;
// Content-based detection
String firstLine = "";
try (BufferedReader reader = new BufferedReader(
new InputStreamReader(new FileInputStream(filepath), StandardCharsets.UTF_8))) {
firstLine = reader.readLine();
}
if (firstLine == null) throw new IOException("Empty file");
firstLine = firstLine.trim();
if (firstLine.startsWith("{") || firstLine.startsWith("[")) return "json";
if (firstLine.startsWith("<?xml") || firstLine.startsWith("<")) return "xml";
if (firstLine.contains(":") && !firstLine.contains(",")) return "yaml";
return "csv";
}
/**
* Read data from any supported format.
*/
public List<Map<String, Object>> readData(String filepath, String format) throws IOException {
switch (format) {
case "json": return readJson(filepath);
case "csv": return readCsv(filepath);
case "xml": return readXml(filepath);
case "yaml": return readYaml(filepath);
default: throw new IllegalArgumentException("Unsupported format: " + format);
}
}
private List<Map<String, Object>> readJson(String filepath) throws IOException {
try {
JsonNode node = jsonMapper.readTree(new File(filepath));
if (node.isArray()) {
return jsonMapper.convertValue(node,
new TypeReference<List<Map<String, Object>>>() {});
} else {
Map<String, Object> single = jsonMapper.convertValue(node,
new TypeReference<Map<String, Object>>() {});
return Collections.singletonList(single);
}
} catch (JsonProcessingException e) {
throw new IOException("Malformed JSON: " + e.getMessage(), e);
}
}
private List<Map<String, Object>> readCsv(String filepath) throws IOException {
List<Map<String, Object>> records = new ArrayList<>();
try (BufferedReader reader = Files.newBufferedReader(Paths.get(filepath), StandardCharsets.UTF_8)) {
String headerLine = reader.readLine();
if (headerLine == null) throw new IOException("CSV file is empty");
String[] headers = headerLine.split(",");
for (int i = 0; i < headers.length; i++) {
headers[i] = headers[i].trim().replaceAll("^\"|\"$", "");
}
String line;
while ((line = reader.readLine()) != null) {
String[] values = parseCsvLine(line);
Map<String, Object> record = new LinkedHashMap<>();
for (int i = 0; i < headers.length && i < values.length; i++) {
record.put(headers[i], inferType(values[i]));
}
records.add(record);
}
}
return records;
}
private String[] parseCsvLine(String line) {
List<String> values = new ArrayList<>();
StringBuilder current = new StringBuilder();
boolean inQuotes = false;
for (int i = 0; i < line.length(); i++) {
char c = line.charAt(i);
if (c == '"') {
if (inQuotes && i + 1 < line.length() && line.charAt(i + 1) == '"') {
current.append('"');
i++;
} else {
inQuotes = !inQuotes;
}
} else if (c == ',' && !inQuotes) {
values.add(current.toString().trim());
current = new StringBuilder();
} else {
current.append(c);
}
}
values.add(current.toString().trim());
return values.toArray(new String[0]);
}
private List<Map<String, Object>> readXml(String filepath) throws IOException {
try {
JsonNode tree = xmlMapper.readTree(new File(filepath));
List<Map<String, Object>> records = new ArrayList<>();
if (tree.isObject()) {
Iterator<Map.Entry<String, JsonNode>> fields = tree.fields();
while (fields.hasNext()) {
Map.Entry<String, JsonNode> entry = fields.next();
JsonNode child = entry.getValue();
if (child.isArray()) {
for (JsonNode item : child) {
records.add(jsonMapper.convertValue(item,
new TypeReference<Map<String, Object>>() {}));
}
return records;
} else if (child.isObject()) {
records.add(jsonMapper.convertValue(child,
new TypeReference<Map<String, Object>>() {}));
}
}
}
if (records.isEmpty()) {
records.add(jsonMapper.convertValue(tree,
new TypeReference<Map<String, Object>>() {}));
}
return records;
} catch (Exception e) {
throw new IOException("Malformed XML: " + e.getMessage(), e);
}
}
private List<Map<String, Object>> readYaml(String filepath) throws IOException {
try {
JsonNode tree = yamlMapper.readTree(new File(filepath));
if (tree == null || tree.isMissingNode()) {
throw new IOException("YAML file is empty");
}
if (tree.isArray()) {
return yamlMapper.convertValue(tree,
new TypeReference<List<Map<String, Object>>>() {});
}
Map<String, Object> single = yamlMapper.convertValue(tree,
new TypeReference<Map<String, Object>>() {});
return Collections.singletonList(single);
} catch (JsonProcessingException e) {
throw new IOException("Malformed YAML: " + e.getMessage(), e);
}
}
/**
* Infer types from string values.
*/
private Object inferType(String value) {
if (value == null || value.isEmpty() || value.equalsIgnoreCase("null")
|| value.equalsIgnoreCase("none")) {
return null;
}
if (value.equalsIgnoreCase("true") || value.equalsIgnoreCase("yes")) return true;
if (value.equalsIgnoreCase("false") || value.equalsIgnoreCase("no")) return false;
try { return Integer.parseInt(value); } catch (NumberFormatException ignored) {}
try { return Long.parseLong(value); } catch (NumberFormatException ignored) {}
try { return Double.parseDouble(value); } catch (NumberFormatException ignored) {}
return value;
}
/**
* Write data to the target format.
*/
public void writeData(List<Map<String, Object>> data, String filepath, String format)
throws IOException {
switch (format) {
case "json": writeJson(data, filepath); break;
case "csv": writeCsv(data, filepath); break;
case "xml": writeXml(data, filepath); break;
case "yaml": writeYaml(data, filepath); break;
default: throw new IllegalArgumentException("Unsupported format: " + format);
}
}
private void writeJson(List<Map<String, Object>> data, String filepath) throws IOException {
jsonMapper.writeValue(new File(filepath), data);
System.out.println("Written JSON to " + filepath);
}
private void writeCsv(List<Map<String, Object>> data, String filepath) throws IOException {
if (data.isEmpty()) {
Files.write(Paths.get(filepath), new byte[0]);
return;
}
// Flatten nested structures and collect all keys
List<Map<String, Object>> flatData = new ArrayList<>();
Set<String> allKeys = new LinkedHashSet<>();
for (Map<String, Object> record : data) {
Map<String, Object> flat = flattenMap(record, "");
allKeys.addAll(flat.keySet());
flatData.add(flat);
}
try (PrintWriter writer = new PrintWriter(
new OutputStreamWriter(new FileOutputStream(filepath), StandardCharsets.UTF_8))) {
// Header
writer.println(String.join(",", allKeys));
// Rows
for (Map<String, Object> row : flatData) {
List<String> values = new ArrayList<>();
for (String key : allKeys) {
Object val = row.get(key);
String s = val == null ? "" : val.toString();
if (s.contains(",") || s.contains("\"") || s.contains("\n")) {
s = "\"" + s.replace("\"", "\"\"") + "\"";
}
values.add(s);
}
writer.println(String.join(",", values));
}
}
System.out.println("Written CSV to " + filepath);
}
private Map<String, Object> flattenMap(Map<String, Object> map, String prefix) {
Map<String, Object> flat = new LinkedHashMap<>();
for (Map.Entry<String, Object> entry : map.entrySet()) {
String key = prefix.isEmpty() ? entry.getKey() : prefix + "." + entry.getKey();
Object value = entry.getValue();
if (value instanceof Map) {
@SuppressWarnings("unchecked")
Map<String, Object> nested = (Map<String, Object>) value;
flat.putAll(flattenMap(nested, key));
} else if (value instanceof List) {
try {
flat.put(key, jsonMapper.writeValueAsString(value));
} catch (JsonProcessingException e) {
flat.put(key, value.toString());
}
} else {
flat.put(key, value);
}
}
return flat;
}
private void writeXml(List<Map<String, Object>> data, String filepath) throws IOException {
ObjectNode root = xmlMapper.createObjectNode();
ArrayNode records = root.putArray("record");
for (Map<String, Object> item : data) {
records.add(jsonMapper.valueToTree(item));
}
xmlMapper.writeValue(new File(filepath), root);
System.out.println("Written XML to " + filepath);
}
private void writeYaml(List<Map<String, Object>> data, String filepath) throws IOException {
yamlMapper.writeValue(new File(filepath), data);
System.out.println("Written YAML to " + filepath);
}
/**
* Infer schema from data.
*/
public Map<String, String> inferSchema(List<Map<String, Object>> data) {
Map<String, String> schema = new LinkedHashMap<>();
for (Map<String, Object> record : data) {
for (Map.Entry<String, Object> entry : record.entrySet()) {
String key = entry.getKey();
Object value = entry.getValue();
String typeName = value == null ? "null" : value.getClass().getSimpleName();
if (!schema.containsKey(key)) {
schema.put(key, typeName);
} else if (!schema.get(key).equals(typeName) && value != null) {
schema.put(key, "mixed");
}
}
}
return schema;
}
/**
* Generate sample data.
*/
public List<Map<String, Object>> generateSampleData() {
List<Map<String, Object>> samples = new ArrayList<>();
Map<String, Object> r1 = new LinkedHashMap<>();
r1.put("id", 1);
r1.put("name", "Alice Johnson");
r1.put("age", 30);
r1.put("active", true);
r1.put("score", 95.5);
Map<String, Object> addr1 = new LinkedHashMap<>();
addr1.put("street", "123 Main St");
addr1.put("city", "Springfield");
addr1.put("state", "IL");
r1.put("address", addr1);
r1.put("tags", Arrays.asList("developer", "python"));
samples.add(r1);
Map<String, Object> r2 = new LinkedHashMap<>();
r2.put("id", 2);
r2.put("name", "Bob Smith");
r2.put("age", 25);
r2.put("active", false);
r2.put("score", 88.0);
Map<String, Object> addr2 = new LinkedHashMap<>();
addr2.put("street", "456 Oak Ave");
addr2.put("city", "Portland");
addr2.put("state", "OR");
r2.put("address", addr2);
r2.put("tags", Arrays.asList("designer", "css"));
samples.add(r2);
Map<String, Object> r3 = new LinkedHashMap<>();
r3.put("id", 3);
r3.put("name", "Carol White");
r3.put("age", 35);
r3.put("active", true);
r3.put("score", 92.3);
Map<String, Object> addr3 = new LinkedHashMap<>();
addr3.put("street", "789 Pine Rd");
addr3.put("city", "Austin");
addr3.put("state", "TX");
r3.put("address", addr3);
r3.put("tags", Arrays.asList("manager", "agile"));
samples.add(r3);
return samples;
}
/**
* Main conversion entry point.
*/
public String convert(String inputPath, String targetFormat, String outputPath) throws IOException {
String tf = targetFormat.toLowerCase().replace(".", "");
if (tf.equals("yml")) tf = "yaml";
if (!SUPPORTED_FORMATS.contains(tf)) {
throw new IllegalArgumentException("Unsupported target format: " + tf);
}
String sourceFormat = detectFormat(inputPath);
System.out.println("Detected input format: " + sourceFormat);
List<Map<String, Object>> data = readData(inputPath, sourceFormat);
Map<String, String> schema = inferSchema(data);
System.out.println("Inferred schema: " + schema);
if (outputPath == null) {
int dot = inputPath.lastIndexOf('.');
String base = dot > 0 ? inputPath.substring(0, dot) : inputPath;
outputPath = base + "." + tf;
}
writeData(data, outputPath, tf);
return outputPath;
}
public static void main(String[] args) {
DataConverter converter = new DataConverter();
if (args.length == 0) {
System.out.println("Generating sample data in all formats...");
List<Map<String, Object>> sample = converter.generateSampleData();
String sampleDir = System.getProperty("user.dir") + File.separator + "sample_output";
new File(sampleDir).mkdirs();
try {
converter.writeData(sample, sampleDir + File.separator + "sample.json", "json");
converter.writeData(sample, sampleDir + File.separator + "sample.csv", "csv");
converter.writeData(sample, sampleDir + File.separator + "sample.xml", "xml");
converter.writeData(sample, sampleDir + File.separator + "sample.yaml", "yaml");
System.out.println("Sample files generated in " + sampleDir);
} catch (IOException e) {
System.err.println("Error generating samples: " + e.getMessage());
System.exit(1);
}
return;
}
String inputFile = null;
String targetFormat = null;
String outputFile = null;
boolean schemaOnly = false;
for (int i = 0; i < args.length; i++) {
switch (args[i]) {
case "-t":
case "--target":
if (i + 1 < args.length) targetFormat = args[++i];
break;
case "-o":
case "--output":
if (i + 1 < args.length) outputFile = args[++i];
break;
case "--schema":
schemaOnly = true;
break;
default:
if (!args[i].startsWith("-")) inputFile = args[i];
break;
}
}
if (inputFile == null) {
System.err.println("Error: Input file is required");
System.err.println("Usage: java converter.DataConverter <input> -t <format> [-o <output>]");
System.exit(1);
}
if (!new File(inputFile).isFile()) {
System.err.println("Error: File not found: " + inputFile);
System.exit(1);
}
try {
if (schemaOnly) {
String format = converter.detectFormat(inputFile);
List<Map<String, Object>> data = converter.readData(inputFile, format);
Map<String, String> schema = converter.inferSchema(data);
System.out.println("Inferred Schema:");
for (Map.Entry<String, String> entry : schema.entrySet()) {
System.out.println(" " + entry.getKey() + ": " + entry.getValue());
}
return;
}
if (targetFormat == null) {
System.err.println("Error: Target format (-t) is required");
System.exit(1);
}
String output = converter.convert(inputFile, targetFormat, outputFile);
System.out.println("Conversion complete: " + output);
} catch (Exception e) {
System.err.println("Error: " + e.getMessage());
System.exit(1);
}
}
}