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
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
[![Review Assignment Due Date](https://classroom.github.com/assets/deadline-readme-button-22041afd0340ce965d47ae6ef1cefeee28c7c493a6346c4f15d667ab976d596c.svg)](https://classroom.github.com/a/4ISSpVK4)
**Java reflection**

Ваша задача --- написать генератор экземпляров произвольных классов.
Expand Down
5 changes: 3 additions & 2 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ repositories {

dependencies {
testImplementation(platform("org.junit:junit-bom:5.10.0"))
testImplementation("org.junit.jupiter:junit-jupiter")
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
testImplementation("org.junit.jupiter:junit-jupiter-api")
testImplementation("org.junit.jupiter:junit-jupiter-params")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine")
}

tasks.test {
Expand Down
38 changes: 33 additions & 5 deletions src/main/java/org/example/GenerateExample.java
Original file line number Diff line number Diff line change
@@ -1,17 +1,45 @@
package org.example;


import org.example.classes.Example;
import org.example.classes.*;
import org.example.generator.Generator;

public class GenerateExample {
public static void main(String[] args) {
var gen = new Generator();

try {
Object generated = gen.generateValueOfType(Example.class);
System.out.println(generated);
System.out.println("=== Testing Generator ===");

System.out.println("\n1. Generating Example:");
Object example = gen.generateValueOfType(Example.class);
System.out.println(example);

System.out.println("\n2. Generating Product:");
Object product = gen.generateValueOfType(Product.class);
System.out.println(product);

System.out.println("\n3. Generating Rectangle:");
Object rectangle = gen.generateValueOfType(Rectangle.class);
System.out.println(rectangle);

System.out.println("\n4. Generating Triangle:");
Object triangle = gen.generateValueOfType(Triangle.class);
System.out.println(triangle);

System.out.println("\n5. Generating BinaryTreeNode:");
Object node = gen.generateValueOfType(BinaryTreeNode.class);
System.out.println(node);

System.out.println("\n6. Generating Cart:");
Object cart = gen.generateValueOfType(Cart.class);
System.out.println(cart);

System.out.println("\n7. Generating Shape (interface):");
Object shape = gen.generateValueOfType(Shape.class);
System.out.println(shape);

} catch (Throwable e) {
throw new RuntimeException(e);
e.printStackTrace();
}
}
}
12 changes: 12 additions & 0 deletions src/main/java/org/example/classes/BinaryTreeNode.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package org.example.classes;

import org.example.generator.Generatable;

@Generatable
public class BinaryTreeNode {
private Integer data;
private BinaryTreeNode left;
Expand Down Expand Up @@ -30,4 +33,13 @@ public void setLeft(BinaryTreeNode left) {
public void setRight(BinaryTreeNode right) {
this.right = right;
}

@Override
public String toString() {
return "BinaryTreeNode{" +
"data=" + data +
", left=" + left +
", right=" + right +
'}';
}
}
10 changes: 10 additions & 0 deletions src/main/java/org/example/classes/Cart.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package org.example.classes;

import org.example.generator.Generatable;

import java.util.List;

@Generatable
public class Cart {
private List<Product> items;

Expand All @@ -18,4 +21,11 @@ public void setItems(List<Product> items) {
}

// Конструктор, методы добавления и удаления товаров, геттеры и другие методы

@Override
public String toString() {
return "Cart{" +
"items=" + items +
'}';
}
}
3 changes: 3 additions & 0 deletions src/main/java/org/example/classes/Example.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package org.example.classes;

import org.example.generator.Generatable;

@Generatable
public class Example {
int i;

Expand Down
10 changes: 8 additions & 2 deletions src/main/java/org/example/classes/Product.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package org.example.classes;


import org.example.generator.Generatable;

@Generatable
public class Product {
private String name;
private double price;
Expand Down Expand Up @@ -42,7 +46,9 @@ public boolean equals(Object obj) {

@Override
public String toString() {
return super.toString();
return "Product{" +
"name='" + name + '\'' +
", price=" + price +
'}';
}

}
11 changes: 11 additions & 0 deletions src/main/java/org/example/classes/Rectangle.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package org.example.classes;

import org.example.generator.Generatable;

@Generatable
public class Rectangle implements Shape {
private double length;
private double width;
Expand All @@ -18,4 +21,12 @@ public double getArea() {
public double getPerimeter() {
return 2 * (length + width);
}

@Override
public String toString() {
return "Rectangle{" +
"length=" + length +
", width=" + width +
'}';
}
}
3 changes: 3 additions & 0 deletions src/main/java/org/example/classes/Shape.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package org.example.classes;

import org.example.generator.Generatable;

@Generatable
public interface Shape {
double getArea();
double getPerimeter();
Expand Down
12 changes: 12 additions & 0 deletions src/main/java/org/example/classes/Triangle.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package org.example.classes;

import org.example.generator.Generatable;

@Generatable
public class Triangle implements Shape {
private double sideA;
private double sideB;
Expand All @@ -21,4 +24,13 @@ public double getArea() {
public double getPerimeter() {
return sideA + sideB + sideC;
}

@Override
public String toString() {
return "Triangle{" +
"sideA=" + sideA +
", sideB=" + sideB +
", sideC=" + sideC +
'}';
}
}
12 changes: 12 additions & 0 deletions src/main/java/org/example/generator/Generatable.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package org.example.generator;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Generatable {

}
116 changes: 108 additions & 8 deletions src/main/java/org/example/generator/Generator.java
Original file line number Diff line number Diff line change
@@ -1,18 +1,118 @@
package org.example.generator;

import org.example.classes.*;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Random;
import java.util.*;


public class Generator {
private final Random random = new Random();
private int currentDepth = 0;
private final int maxDepth = 1;

public Object generateValueOfType(Class<?> clazz) throws Exception {
if (!clazz.isAnnotationPresent(Generatable.class)) {
throw new Exception("Class with name '" + clazz.getSimpleName() + "' does not have annotation @Generatable");
}

if (clazz.isInterface()) {
return generateInterfaceImplementation(clazz);
}

if (clazz == BinaryTreeNode.class) {
currentDepth++;
if (currentDepth > maxDepth) {
currentDepth--;
return null;
}
}

try {
Constructor<?>[] constructors = clazz.getDeclaredConstructors();
Constructor<?> constructor = constructors[0];

Class<?>[] parameterTypes = constructor.getParameterTypes();
Object[] parameters = new Object[parameterTypes.length];

int i = 0;
for (Class<?> parameterType : parameterTypes) {
Object value = generateValueForField(parameterType);
parameters[i++] = value;
System.out.println("For field " + parameterType.getName() + " was generate random value: " + value);
}

return constructor.newInstance(parameters);
} finally {
if (clazz == BinaryTreeNode.class) {
currentDepth--;
}
}
}

private Object generateInterfaceImplementation(Class<?> clazz) throws Exception {
if (clazz == Shape.class) {
if (random.nextBoolean()) {
return generateValueOfType(Rectangle.class);
} else {
return generateValueOfType(Triangle.class);
}
}

throw new Exception("Unsupported interface: " + clazz.getSimpleName());
}

private Object generateBinaryTreeNode() throws Exception {
Integer data = random.nextInt(100);

BinaryTreeNode left = null;
BinaryTreeNode right = null;

if (currentDepth <= maxDepth) {
left = (BinaryTreeNode) generateValueOfType(BinaryTreeNode.class);
right = (BinaryTreeNode) generateValueOfType(BinaryTreeNode.class);
}

return new BinaryTreeNode(data, left, right);
}

public Object generateValueOfType(Class<?> clazz) throws InvocationTargetException, InstantiationException, IllegalAccessException {
Constructor<?>[] constructors = clazz.getDeclaredConstructors();
private Object generateValueForField(Class<?> clazz) throws Exception {
if (clazz == BinaryTreeNode.class) {
return generateBinaryTreeNode();
}

int randomConstructorIndex = new Random().nextInt(constructors.length);
Constructor<?> randomConstructor = constructors[randomConstructorIndex];
return randomConstructor.newInstance(111);
if (clazz == int.class || clazz == Integer.class) {
return random.nextInt(1000);
} else if (clazz == double.class || clazz == Double.class) {
return random.nextDouble() * 1000;
} else if (clazz == String.class) {
return generateString();
} else if (List.class.isAssignableFrom(clazz)) {
return generateList();
}

throw new Exception("Unsupported class type");
}

private Object generateList() throws Exception {
List<Object> list = new ArrayList<>();
int size = random.nextInt(3) + 1;

for (int i = 0; i < size; i++) {
Object product = generateValueOfType(Product.class);
list.add(product);
}

return list;
}

private Object generateString() {
int length = random.nextInt(10) + 1;
char[] characters = new char[length];
for (int i = 0; i < length; i++) {
characters[i] = (char) ('a' + random.nextInt(26));
}

}
return new String(characters);
}
}
Loading