Skip to content
Snippets Groups Projects
Commit edfa98ab authored by jez04's avatar jez04
Browse files

feat: :tada: solution

parent ecefcdef
Branches
No related merge requests found
......@@ -2,3 +2,5 @@
.settings/
.project
.classpath
*.mv.db
*.trace.db
......@@ -12,6 +12,13 @@
<maven.compiler.target>21</maven.compiler.target>
</properties>
<dependencies>
<!-- https://mvnrepository.com/artifact/com.h2database/h2 -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>2.3.232</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
......
package lab;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
public class DbConnector {
private static final String JDBC_CONECTIN_STRING = "jdbc:h2:file:./scoreDB";
public static List<Score> getAll() {
return queryScore("select * from scores;");
}
public static List<Score> getFirstTen() {
return queryScore("select * from scores order by points desc limit 10;");
}
private static List<Score> queryScore(String query) {
List<Score> result = new ArrayList<>();
try (Connection con = DriverManager.getConnection(JDBC_CONECTIN_STRING);
Statement stm = con.createStatement();
ResultSet rs = stm.executeQuery(query);) {
while (rs.next()) {
result.add(new Score(rs.getString("nick"), rs.getInt("points")));
}
} catch (SQLException e) {
e.printStackTrace();
}
return result;
}
public static void createTable() {
try (Connection con = DriverManager.getConnection(JDBC_CONECTIN_STRING);
Statement stm = con.createStatement();) {
stm.executeUpdate("CREATE TABLE if not exists scores (nick VARCHAR(50) NOT NULL, points INT NOT NULL);");
} catch (SQLException e) {
e.printStackTrace();
}
}
public static void insertScore(Score score) {
try (Connection con = DriverManager.getConnection(JDBC_CONECTIN_STRING);
PreparedStatement stm = con.prepareStatement("INSERT INTO scores VALUES (?, ?)");) {
stm.setString(1, score.getName());
stm.setInt(2, score.getPoints());
stm.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
package lab;
import java.util.List;
import java.util.stream.Stream;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.geometry.Point2D;
import javafx.scene.canvas.Canvas;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.Slider;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
public class GameController {
@FXML
private Button btnGenerateScore;
@FXML
private Button btnLoadAll;
@FXML
private Button btnLoadFirstTen;
@FXML
private Slider angle;
......@@ -18,6 +34,15 @@ public class GameController {
@FXML
private Canvas canvas;
@FXML
private TableView<Score> scores;
@FXML
private TableColumn<Score, String> nickColumn;
@FXML
private TableColumn<Score, Integer> pointsColumn;
private DrawingThread timer;
@FXML
......@@ -42,6 +67,28 @@ public class GameController {
() -> System.out.println("au!!!!"));
}
@FXML
void btnGenerateScoreAction(ActionEvent event) {
Score score = Score.generate();
this.scores.getItems().add(score);
DbConnector.insertScore(score);
}
@FXML
void btnLoadAllAction(ActionEvent event) {
updateScoreTable(DbConnector.getAll());
}
@FXML
void btnLoadFirstTenAction(ActionEvent event) {
updateScoreTable(DbConnector.getFirstTen());
}
private void updateScoreTable(List<Score> scores) {
this.scores.getItems().clear();
this.scores.getItems().addAll(scores);
}
private void updateHits() {
hits.setText(String.format("Hit count: %03d", hitcount));
}
......@@ -61,6 +108,20 @@ public class GameController {
angle.valueProperty().addListener(
(observable, oldValue, newValue) ->
timer.getWorld().getCannon().setAngle(newValue.doubleValue()));
nickColumn.setCellValueFactory(new PropertyValueFactory<>("name"));
pointsColumn.setCellValueFactory(new PropertyValueFactory<>("points"));
initDB();
}
private void initDB() {
scores.getItems().addAll(Stream.generate(Score::generate).limit(10).toList());
DbConnector.createTable();
DbConnector.getAll();
}
public void stop() {
......
package lab;
import java.util.Random;
public class Score {
private static final Random RANDOM = new Random();
private String name;
private int points;
public Score(String name, int points) {
this.name = name;
this.points = points;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPoints() {
return points;
}
public void setPoints(int points) {
this.points = points;
}
@Override
public String toString() {
return "Score [name=" + name + ", points=" + points + "]";
}
public static Score generate() {
return new Score(getRandomNick(), RANDOM.nextInt(50, 300));
}
public static final String[] nicks = { "CyberSurfer", "PixelPioneer", "SocialSavvy", "DigitalDynamo", "ByteBuddy", "InstaGuru",
"TikTokTornado", "SnapMaster", "TweetTrendsetter", "ChatChampion", "HashtagHero", "EmojiEnthusiast",
"StoryStylist", "SelfieStar", "FilterFanatic", "VlogVirtuoso", "Memelord", "InfluencerInsider",
"StreamSupreme", "GeekyGizmo", "CodeCommander", "JavaJuggernaut", "ByteNinja", "SyntaxSamurai",
"ClassyCoder", "ObjectOmnipotent", "LoopLegend", "VariableVirtuoso", "DebugDemon", "CompilerCrusader",
"PixelProdigy", "VirtualVoyager", "AlgorithmAce", "DataDynamo", "ExceptionExpert", "BugBuster",
"SyntaxSorcerer", "CodeCrusader", "JavaJester", "NerdyNavigator", "CryptoCaptain", "SocialButterfly",
"AppArchitect", "WebWizard", "FunctionFreak", "PixelArtist", "CyberPhantom", "HackHero", "CacheChampion",
"ScreenSage", "WebWeaver", "LogicLover", "BitBlazer", "NetworkNomad", "ProtocolPioneer", "BinaryBoss",
"StackSultan", "SocialScribe", "RenderRuler", "ScriptSorcerer", "HTMLHero", "PixelProwler", "FrameFreak",
"DataDreamer", "BotBuilder", "ByteBishop", "KeyboardKnight", "DesignDaredevil", "JavaJuggler",
"SyntaxStrategist", "TechTactician", "ProgramProdigy", "BinaryBard", "PixelPoet", "GigabyteGuru",
"TechTrekker", "NetworkNinja", "DataDetective", "MatrixMaster", "CodeConductor", "AppAlchemist",
"ServerSage", "ClusterChampion", "ScriptSensei", "KeyboardKicker", "CacheCrafter", "SocialSpark",
"BinaryBeast", "CodeConnoisseur", "BitBrain", "VirtualVanguard", "SystemSculptor", "RenderRogue",
"CryptoConqueror", "MachineMonarch", "PixelPal", "CompilerCaptain", "BitBuilder", "TechTitan",
"CloudConqueror", "EchoExplorer", "FunctionFanatic", "RobotRanger" };
public static String getRandomNick() {
return nicks[RANDOM.nextInt(nicks.length)];
}
}
......@@ -10,7 +10,7 @@ import javafx.scene.image.Image;
public class Ufo extends WorldEntity implements Collisionable {
private static final Random RANDOM = new Random();
private Image image = new Image(this.getClass().getResourceAsStream("ufo-small.gif"));
private Image image;
private Point2D velocity;
public Ufo(World world) {
......@@ -23,9 +23,17 @@ public class Ufo extends WorldEntity implements Collisionable {
this.velocity = velocity;
}
private Image getImage() {
if (image == null) {
image = new Image(Ufo.class.getResourceAsStream("ufo-small.gif"));
}
return image;
}
@Override
public void drawInternal(GraphicsContext gc) {
gc.drawImage(image, getPosition().getX(), getPosition().getY());
gc.drawImage(getImage(), getPosition().getX(), getPosition().getY());
}
public void changeDirection() {
......@@ -36,14 +44,14 @@ public class Ufo extends WorldEntity implements Collisionable {
public void simulate(double deltaT) {
position = position.add(velocity.multiply(deltaT));
position = new Point2D(position.getX() % world.getWidth(), position.getY());
if(position.getX() < -image.getWidth()) {
if (position.getX() < -getImage().getWidth()) {
position = new Point2D(world.getWidth(), position.getY());
}
}
@Override
public Rectangle2D getBoundingBox() {
return new Rectangle2D(position.getX(), position.getY(), image.getWidth(), image.getHeight());
return new Rectangle2D(position.getX(), position.getY(), getImage().getWidth(), getImage().getHeight());
}
@Override
......@@ -53,7 +61,7 @@ public class Ufo extends WorldEntity implements Collisionable {
@Override
public void hitBy(Collisionable another) {
if(another instanceof BulletAnimated || another instanceof Bullet) {
if (another instanceof BulletAnimated || another instanceof Bullet) {
world.remove(this);
}
}
......
......@@ -2,6 +2,7 @@ module lab01 {
requires transitive javafx.controls;
requires javafx.fxml;
requires javafx.base;
requires java.sql;
opens lab to javafx.fxml;
exports lab;
}
\ No newline at end of file
......@@ -6,11 +6,14 @@
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.Slider?>
<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.text.Font?>
<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/21" xmlns:fx="http://javafx.com/fxml/1" fx:controller="lab.GameController">
<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="471.0" prefWidth="901.0" xmlns="http://javafx.com/javafx/21" xmlns:fx="http://javafx.com/fxml/1" fx:controller="lab.GameController">
<bottom>
<HBox alignment="TOP_CENTER" prefHeight="100.0" prefWidth="200.0" BorderPane.alignment="CENTER">
<children>
......@@ -43,4 +46,22 @@
<top>
<Label fx:id="hits" text="Hit count: 0" textAlignment="CENTER" BorderPane.alignment="CENTER" />
</top>
<right>
<VBox maxHeight="1.7976931348623157E308" maxWidth="-Infinity" BorderPane.alignment="CENTER">
<children>
<TableView fx:id="scores" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308">
<columns>
<TableColumn fx:id="nickColumn" prefWidth="75.0" text="Nick" />
<TableColumn fx:id="pointsColumn" prefWidth="75.0" text="Points" />
</columns>
<columnResizePolicy>
<TableView fx:constant="CONSTRAINED_RESIZE_POLICY" />
</columnResizePolicy>
</TableView>
<Button fx:id="btnGenerateScore" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#btnGenerateScoreAction" text="Generate new score" />
<Button fx:id="btnLoadAll" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#btnLoadAllAction" text="Load all from DB" />
<Button fx:id="btnLoadFirstTen" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#btnLoadFirstTenAction" text="Load First 10 from DB" />
</children>
</VBox>
</right>
</BorderPane>
......@@ -2,38 +2,16 @@ package jez04.structure.test;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.FileVisitResult;
import java.nio.file.FileVisitor;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.reflections.Configuration;
import org.reflections.Reflections;
import org.reflections.scanners.Scanners;
import org.reflections.util.ConfigurationBuilder;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
class ClassStructureTest {
......@@ -52,82 +30,72 @@ class ClassStructureTest {
}
@Test
void gameControllerActionMethodTest() {
void gameControllerButtonActionMethodTest() {
helper.classExist("GameController");
Class<?> c = helper.getClass("GameController");
helper.hasMethodRegexp(c, ".*", void.class, ActionEvent.class);
long count = helper.countMethodRegexp(c, ".*", void.class, ActionEvent.class);
assertTrue(count > 1, "Only " + count+ " method handling button click found. Expected more then 1");
}
@Test
void gameControllerLambdasTest() {
void gameControllerTableViewTest() {
helper.classExist("GameController");
Class<?> c = helper.getClass("GameController");
long lamdaCount = helper.countMethodRegexp(c, "lambda\\$.*");
long innerClasscount = helper.countClassesRegexp(".*GameController\\$.*");
assertTrue(lamdaCount + innerClasscount >= 2,
"At least 2 inner classes or lamdas required for GameController but only "
+ (lamdaCount + innerClasscount) + " found.");
helper.hasProperty(c, ".*", TableView.class, false);
}
@Test
void hitListenerExistenceTest() {
helper.classExist("HitListener");
}
@Test
void hitListenerEventMethodTest() {
helper.classExist("HitListener");
Class<?> c = helper.getClass("HitListener");
helper.hasMethod(c, "ufoDestroyed");
void gameControllerTableColumnTest() {
helper.classExist("GameController");
Class<?> c = helper.getClass("GameController");
helper.hasProperty(c, ".*", TableColumn.class, false);
}
@Test
void sceneCollectionTest() {
helper.classExist("World");
Class<?> c = helper.getClass("World");
long collectionCount = Arrays.asList(c.getDeclaredFields()).stream()
.filter(f -> Collection.class.isAssignableFrom(f.getType())).count();
assertTrue(collectionCount >= 3, "lab.Scene require atleast 3 filed of type/subtype Collection, but only "
+ collectionCount + " found.");
void dbConnectorTest() {
helper.classExistRegexp(".*[Dd][Bb][cC]on.*");
}
@Test
void worldMethodAddTest() {
helper.classExist("World");
Class<?> c = helper.getClass("World");
helper.hasMethodRegexp(c, "add.*", void.class, helper.getClass("DrawableSimulable"));
;
void dbConnectorGetAllTest() {
helper.classExistRegexp(".*[Dd][Bb][cC]on.*");
Class<?> scoreClass = helper.getClassRegexp(".*[sS]core.*");
Class<?> c = helper.getClassRegexp(".*[Dd][Bb][cC]on.*");
helper.hasMethodRegexp(c, ".*[aA]ll.*", List.class);
helper.hasMethodRegexp(c, ".*[iI]nsert.*", void.class, scoreClass);
}
@Test
void worldMethodRemoveTest() {
helper.classExist("World");
Class<?> c = helper.getClass("World");
helper.hasMethodRegexp(c, "remove.*", void.class, helper.getClass("DrawableSimulable"));
;
void dbConnectorInsertTest() {
helper.classExistRegexp(".*[Dd][Bb][cC]on.*");
Class<?> scoreClass = helper.getClassRegexp(".*[sS]core.*");
Class<?> c = helper.getClassRegexp(".*[Dd][Bb][cC]on.*");
helper.hasMethodRegexp(c, ".*[iI]nsert.*", void.class, scoreClass);
}
@Test
void bulletAnimatedMethodAddTest() {
helper.classExist("BulletAnimated");
Class<?> c = helper.getClass("BulletAnimated");
Class<?> l = helper.getClass("HitListener");
helper.hasMethodRegexp(c, "add.*", List.of(void.class, boolean.class), l);
void dbConnectorContainsJdbcTest() throws URISyntaxException, IOException {
helper.classExistRegexp(".*[Dd][Bb][cC]on.*");
Class<?> c = helper.getClassRegexp(".*[Dd][Bb][cC]on.*");
String src = helper.getSourceCode(c);
assertTrue(src.contains("jdbc:"), "No usage of jdbc detect.");
}
@Test
void bulletAnimatedMethodRemoveTest() {
helper.classExist("Ufo");
Class<?> c = helper.getClass("BulletAnimated");
Class<?> l = helper.getClass("HitListener");
helper.hasMethodRegexp(c, "remove.*", List.of(void.class, boolean.class), l);
void dbConnectorContainsDriverManagerTest() throws URISyntaxException, IOException {
helper.classExistRegexp(".*[Dd][Bb][cC]on.*");
Class<?> c = helper.getClassRegexp(".*[Dd][Bb][cC]on.*");
String src = helper.getSourceCode(c);
assertTrue(src.contains("DriverManager"), "No usage of DriverManager detect.");
}
@Test
void bulletAnimatedMethodFireTest() {
helper.classExist("BulletAnimated");
Class<?> c = helper.getClass("BulletAnimated");
assertTrue(helper.countMethodRegexp(c, "fire.*") > 0, "Method fire.* in LochNess not found.");
void dbConnectorContainsSqlTest() throws URISyntaxException, IOException {
helper.classExistRegexp(".*[Dd][Bb][cC]on.*");
Class<?> c = helper.getClassRegexp(".*[Dd][Bb][cC]on.*");
String src = helper.getSourceCode(c).toLowerCase();
assertTrue(src.contains("create "), "No usage of SQL create.");
assertTrue(src.contains("select "), "No usage of SQL select.");
assertTrue(src.contains("insert "), "No usage of SQL table.");
assertTrue(src.contains(" from "), "No usage of SQL from.");
assertTrue(src.contains(" table"), "No usage of SQL table.");
}
}
package jez04.structure.test;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Parameter;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.FileVisitResult;
......@@ -19,10 +22,12 @@ import java.nio.file.Paths;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import java.util.function.Predicate;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import org.junit.jupiter.api.Assertions;
......@@ -43,11 +48,31 @@ class StructureHelper {
assertTrue(allClasses.stream().anyMatch(c -> c.endsWith(name)), "Class/Interface " + name + " not found");
}
public void classExistRegexp(String name) {
assertTrue(allClasses.stream().anyMatch(c -> c.matches(name)), "Class/Interface " + name + " not found");
}
public Class<?> getClassDirectly(String name) {
return loadClass(name, name);
}
public Class<?> getClassRegexp(String name) {
String className = allClasses.stream().filter(c -> c.matches(name)).findAny().orElse(null);
if (className == null) {
Assertions.fail("Class " + name + " not found.");
}
return loadClass(name, className);
}
public Class<?> getClass(String name) {
String className = allClasses.stream().filter(c -> c.endsWith(name)).findAny().orElse(null);
if (className == null) {
Assertions.fail("Class " + name + " not found.");
}
return loadClass(name, className);
}
private Class<?> loadClass(String name, String className) {
try {
return Class.forName(className);
} catch (ClassNotFoundException e) {
......@@ -108,48 +133,87 @@ class StructureHelper {
+ Arrays.asList(params).stream().map(Class::getName).collect(Collectors.joining(", ")));
}
public Method getMethod(Class<?> interfaceDef, String methodName, Class<?> returnType, Class<?>... params) {
List<Method> methods = Arrays.asList(interfaceDef.getDeclaredMethods());
List<Method> foundMethods = methods.stream().filter(m -> m.getName().contains(methodName))
.filter(m -> m.getReturnType().equals(returnType))
.filter(m -> Arrays.asList(m.getParameterTypes()).containsAll(Arrays.asList(params))).toList();
if (foundMethods.isEmpty()) {
fail("No method " + methodName + " found");
}
if (foundMethods.size() > 1) {
fail("More then one method " + methodName + " found");
}
return foundMethods.get(0);
}
public long countMethodRegexp(Class<?> interfaceDef, String methodNameRegexp) {
List<Method> methods = Arrays.asList(interfaceDef.getDeclaredMethods());
return methods.stream().filter(m -> m.getName().matches(methodNameRegexp)).count();
}
public long countMethodReference(Class<?> interfaceDef) throws URISyntaxException, IOException {
Pattern p = Pattern.compile("::");
Matcher m = p.matcher(getSourceCode(interfaceDef));
return m.results().count();
}
public long countMethodReferenceOn(Class<?> interfaceDef, String to) {
try {
Pattern p = Pattern.compile(to + "::");
Matcher m = p.matcher(getSourceCode(interfaceDef));
return m.results().count();
} catch (URISyntaxException | IOException e) {
e.printStackTrace();
return 0;
}
}
public long countClassesRegexp(String classNameRegexp) {
return getNameOfAllClasses().stream().filter(className -> className.matches(classNameRegexp)).count();
}
public void hasConstructor(Class<?> classDef, Class<?>... params) {
getConstructor(classDef, params);
}
public Constructor<?> getConstructor(Class<?> classDef, Class<?>... params) {
List<Constructor<?>> constructors = Arrays.asList(classDef.getConstructors());
List<Constructor<?>> foundConstructors = constructors.stream()
.filter(m -> m.getParameterCount() == params.length)
.filter(m -> Arrays.asList(m.getParameterTypes()).containsAll(Arrays.asList(params))).toList();
if (foundConstructors.isEmpty()) {
fail("No constructor found with parameters: "
+ Arrays.asList(params).stream().map(Class::getName).collect(Collectors.joining(", ")));
}
if (foundConstructors.size() > 1) {
fail("More then one constructor found with parameters: "
+ Arrays.asList(params).stream().map(Class::getName).collect(Collectors.joining(", ")));
}
return foundConstructors.get(0);
}
public void hasMethodRegexp(Class<?> interfaceDef, String methodNameRegexp, Class<?> returnType,
Class<?>... params) {
List<Method> methods = Arrays.asList(interfaceDef.getDeclaredMethods());
assertTrue(methods.stream().anyMatch(m -> m.getName().matches(methodNameRegexp)),
"No method " + methodNameRegexp);
assertTrue(
methods.stream().filter(
m ->
m.getName().matches(methodNameRegexp))
.filter(
m ->
m.getReturnType().equals(returnType))
.anyMatch(m ->
Arrays.asList(m.getParameterTypes()).containsAll(Arrays.asList(params))),
methods.stream().filter(m -> m.getName().matches(methodNameRegexp))
.filter(m -> m.getReturnType().equals(returnType))
.anyMatch(m -> Arrays.asList(m.getParameterTypes()).containsAll(Arrays.asList(params))),
"Method " + methodNameRegexp + " has no all parrams:"
+ Arrays.asList(params).stream().map(Class::getName).collect(Collectors.joining(", ")));
}
public void hasMethodRegexp(Class<?> interfaceDef, String methodNameRegexp, Collection<Class<?>> returnTypeOnOf,
public long countMethodRegexp(Class<?> interfaceDef, String methodNameRegexp, Class<?> returnType,
Class<?>... params) {
List<Method> methods = Arrays.asList(interfaceDef.getDeclaredMethods());
assertTrue(methods.stream().anyMatch(m -> m.getName().matches(methodNameRegexp)),
"No method " + methodNameRegexp);
assertTrue(
methods.stream().filter(
m ->
m.getName().matches(methodNameRegexp))
.filter(
m ->
returnTypeOnOf.contains(m.getReturnType()))
.anyMatch(m ->
Arrays.asList(m.getParameterTypes()).containsAll(Arrays.asList(params))),
"Method " + methodNameRegexp + " has no all parrams:"
+ Arrays.asList(params).stream().map(Class::getName).collect(Collectors.joining(", ")));
return methods.stream().filter(m -> m.getName().matches(methodNameRegexp))
.filter(m -> m.getReturnType().equals(returnType))
.filter(m -> Arrays.asList(m.getParameterTypes()).containsAll(Arrays.asList(params))).count();
}
public void hasMethod(Class<?> interfaceDef, boolean finalTag, boolean abstractTag, String methodName,
......@@ -179,16 +243,34 @@ class StructureHelper {
"Class " + clazz.getName() + " not extends class " + parentName);
}
public void hasExtends(Class<?> clazz, Class<?> parent) {
assertTrue(clazz.getSuperclass().equals(parent),
"Class " + clazz.getName() + " not extends class " + parent.getCanonicalName());
}
public void hasMethod(Class<?> interfaceDef, String methodName) {
List<Method> methods = Arrays.asList(interfaceDef.getMethods());
assertTrue(methods.stream().anyMatch(m -> m.getName().contains(methodName)), "No method " + methodName);
}
public String getSourceCode(Class<?> clazz) throws URISyntaxException, IOException {
URL myClassUrl = StructureHelper.class.getResource(this.getClass().getSimpleName() + ".class");
Path classRoot = Paths.get(myClassUrl.toURI());
while (!"test-classes".equals(classRoot.getFileName().toString())
&& !"classes".equals(classRoot.getFileName().toString())) {
classRoot = classRoot.getParent();
}
Path srcRoot = classRoot.getParent().getParent().resolve(Paths.get("src", "main", "java"));
System.out.println("class root: " + classRoot);
Path srcPath = srcRoot.resolve(clazz.getCanonicalName().replace(".", File.separator) + ".java");
return Files.readString(srcPath);
}
public Set<String> getNameOfAllClasses() {
List<String> initClassesName = new ArrayList<>();
dynamicaliFoundSomeClass(initClassesName);
initClassesName.addAll(List.of("lab.Routines", "lab.App", "lab.DrawingThread"));
for (String className : initClassesName) {
Set<String> allClassesName = new TreeSet<>();
dynamicalyFoundSomeClass(allClassesName);
// allClassesName.addAll(List.of("cz.vsb.fei.lab.App", "lab.Routines", "lab.App", "lab.DrawingThread"));
for (String className : allClassesName) {
try {
Class.forName(className);
break;
......@@ -196,7 +278,6 @@ class StructureHelper {
System.out.println(String.format("Class '%s' cannot be loaded: %s", className, e.getMessage()));
}
}
Set<String> allClasses = new HashSet<>();
for (Package p : Package.getPackages()) {
if (p.getName().startsWith("java.") || p.getName().startsWith("com.") || p.getName().startsWith("jdk.")
|| p.getName().startsWith("javafx.") || p.getName().startsWith("org.")
......@@ -204,36 +285,39 @@ class StructureHelper {
|| p.getName().startsWith("javassist")) {
continue;
}
System.out.println(p.getName());
// System.out.println(p.getName());
Configuration conf = new ConfigurationBuilder().addScanners(Scanners.SubTypes.filterResultsBy(pc -> true))
.forPackages(p.getName());
Reflections reflections = new Reflections(conf);
allClasses.addAll(reflections.getAll(Scanners.SubTypes.filterResultsBy(c -> {
System.out.println(c);
allClassesName.addAll(reflections.getAll(Scanners.SubTypes.filterResultsBy(c -> {
// System.out.println(">>> " + c);
return true;
})));
}
for (String string : allClasses) {
System.out.println(string);
}
return allClasses;
return allClassesName;
}
public void dynamicaliFoundSomeClass(List<String> initClassesName) {
URL myClassUrl = StructureHelper.class.getResource("ClassStructureTest.class");
myClassUrl.getFile();
private static final List<String> dirsToSkip = List.of("jez04", "META-INF");
private static final List<String> filesToSkip = List.of("module-info.class");
public void dynamicalyFoundSomeClass(Set<String> allClassesName) {
URL myClassUrl = StructureHelper.class.getResource(this.getClass().getSimpleName() + ".class");
try {
Path classRoot = Paths.get(myClassUrl.toURI()).getParent().getParent().getParent().getParent();
Path classRoot = Paths.get(myClassUrl.toURI());
while (!"test-classes".equals(classRoot.getFileName().toString())
&& !"classes".equals(classRoot.getFileName().toString())) {
classRoot = classRoot.getParent();
}
if ("test-classes".equals(classRoot.getFileName().toString())) {
classRoot = classRoot.getParent().resolve("classes");
}
System.out.println("class root: " + classRoot);
// System.out.println("class root: " + classRoot);
final Path classRootFinal = classRoot;
Files.walkFileTree(classRoot, new FileVisitor<Path>() {
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
if (List.of("jez04", "META-INF").contains(dir.getFileName().toString())) {
if (dirsToSkip.contains(dir.getFileName().toString())) {
return FileVisitResult.SKIP_SUBTREE;
}
return FileVisitResult.CONTINUE;
......@@ -241,18 +325,20 @@ class StructureHelper {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
System.out.println("VISIT: " + file);
if ("module-info.class".equals(file.getFileName().toString())) {
if (filesToSkip.contains(file.getFileName().toString())) {
return FileVisitResult.CONTINUE;
}
if (!file.getFileName().toString().endsWith(".class")) {
return FileVisitResult.CONTINUE;
}
if (file.getFileName().toString().contains("$")) {
return FileVisitResult.CONTINUE;
}
String foundClassName = classRootFinal.relativize(file).toString();
foundClassName = foundClassName.substring(0, foundClassName.length() - 6)
.replace(File.separatorChar, '.');
initClassesName.add(foundClassName);
return FileVisitResult.TERMINATE;
addClassAndAllRef(allClassesName, foundClassName);
return FileVisitResult.CONTINUE;
}
@Override
......@@ -269,4 +355,34 @@ class StructureHelper {
e.printStackTrace();
}
}
private void addClassAndAllRef(Set<String> allClassesName, String foundClassName) {
allClassesName.add(foundClassName);
try {
Class<?> foundClass = Class.forName(foundClassName);
List.of(foundClass.getInterfaces()).stream().map(Class::getCanonicalName).forEach(allClassesName::add);
List.of(foundClass.getDeclaredClasses()).stream().map(Class::getCanonicalName).forEach(allClassesName::add);
List.of(foundClass.getDeclaredFields()).stream().map(Field::getType)
.map(clazz -> clazz.isArray() ? clazz.componentType() : clazz)
.filter(Predicate.not(Class::isPrimitive)).map(Class::getCanonicalName)
.forEach(allClassesName::add);
List.of(foundClass.getDeclaredMethods()).stream().map(Method::getReturnType)
.map(clazz -> clazz.isArray() ? clazz.componentType() : clazz)
.filter(Predicate.not(Class::isPrimitive)).map(Class::getCanonicalName)
.forEach(allClassesName::add);
List.of(foundClass.getDeclaredMethods()).stream().flatMap(m -> List.of(m.getParameters()).stream())
.map(Parameter::getType).map(clazz -> clazz.isArray() ? clazz.componentType() : clazz)
.filter(Predicate.not(Class::isPrimitive)).map(Class::getCanonicalName)
.forEach(allClassesName::add);
List.of(foundClass.getDeclaredMethods()).stream().flatMap(m -> List.of(m.getExceptionTypes()).stream())
.map(clazz -> clazz.isArray() ? clazz.componentType() : clazz)
.filter(Predicate.not(Class::isPrimitive)).map(Class::getCanonicalName)
.forEach(allClassesName::add);
if (foundClass.getSuperclass() != null) {
allClassesName.add(foundClass.getSuperclass().getCanonicalName());
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment