Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
No results found
Show changes
Commits on Source (2)
Showing
with 1018 additions and 119 deletions
......@@ -2,8 +2,8 @@
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">
<modelVersion>4.0.0</modelVersion>
<groupId>vsb-cs-java1</groupId>
<artifactId>lab11v1</artifactId>
<groupId>vsb-cs-java2</groupId>
<artifactId>java2lab02v1</artifactId>
<version>0.0.1-SNAPHOST</version>
<packaging>jar</packaging>
<properties>
......@@ -60,6 +60,12 @@
<version>0.10.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest</artifactId>
<version>3.0</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
......
......@@ -15,9 +15,6 @@ import javafx.stage.WindowEvent;
*/
public class App extends Application {
static {
System.out.println("aaa");
}
private GameController gameController;
public static void main(String[] args) {
launch(args);
......@@ -32,8 +29,7 @@ public class App extends Application {
GameController gameController = gameLoader.getController();
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.resizableProperty().set(false);
primaryStage.setTitle("Java 1 - 1th laboratory");
primaryStage.setTitle("Java 2 - 2nd laboratory");
primaryStage.show();
// Exit program when main window is closed
primaryStage.setOnCloseRequest(this::exitProgram);
......
......@@ -13,7 +13,7 @@ public class BulletAnimated extends Bullet {
private static final double SIZE = 40;
private final Point2D initVelocity;
private Cannon cannon;
private Image image = new Image(this.getClass().getResourceAsStream("fireball-transparent.gif"));
private static Image image = new Image(BulletAnimated.class.getResourceAsStream("fireball-transparent.gif"));
private List<HitListener> hitListeners =
new ArrayList<>();
......
package lab;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.regex.MatchResult;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
public class DataImporter {
private static final Pattern personTextPattern = Pattern.compile("\\{[^\\{\\}]*address");
private static final Pattern firstNamePattern = Pattern.compile("\"firstname\":\"([\\p{IsAlphabetic}']+)\"");
private static final Pattern lastNamePattern = Pattern.compile("\"lastname\":\"([\\p{IsAlphabetic}']+)\"");
private static final Pattern datePattern = Pattern.compile("\"birthday\":\"(\\d{4}-\\d{2}-\\d{2})\"");
private static final DateTimeFormatter czechDate = DateTimeFormatter.ofPattern("dd. MM. YYYY");
public static void main(String[] args) {
importPlayers();
}
public static void importPlayers() {
List<Person> persons = parseData(downloadText()).stream().map(DataImporter::parsePerson).toList();
for (Person person : persons) {
System.out.printf("%s %s (%s): age=%d, 50th: %s , next in: %d%n"
, person.getFirstName(), person.getLastName()
, person.getDayOfBirth().format(czechDate)
, person.getAge()
, person.get50thBirthDay().format(czechDate)
, person.getDaysToBirthday());
}
}
public static String downloadText() {
try {
URL url = new URI("https://fakerapi.it/api/v2/persons?_quantity=20").toURL();
try (InputStream is = url.openStream()) {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(is));
return bufferedReader.lines().collect(Collectors.joining("\n"));
}
} catch (URISyntaxException | IOException e) {
e.printStackTrace();
return "";
}
}
public static List<String> parseData(String data) {
Matcher matcher = personTextPattern.matcher(data);
return matcher.results().map(MatchResult::group).toList();
}
public static Person parsePerson(String personText) {
String firstName = firstNamePattern.matcher(personText).results().map(result -> result.group(1)).findAny()
.orElse("");
String lastName = lastNamePattern.matcher(personText).results().map(result -> result.group(1)).findAny()
.orElse("");
LocalDate date = datePattern.matcher(personText).results().map(result -> result.group(1)).map(text -> LocalDate.parse(text, DateTimeFormatter.ISO_DATE)).findAny()
.orElse(LocalDate.EPOCH);
return new Person(firstName, lastName, date);
}
}
......@@ -13,15 +13,15 @@ public class DbConnector {
private static final String JDBC_CONECTIN_STRING = "jdbc:h2:file:./scoreDB";
public static List<Score> getAll() {
public List<Score> getAll() {
return queryScore("select * from scores;");
}
public static List<Score> getFirstTen() {
public List<Score> getFirstTen() {
return queryScore("select * from scores order by points desc limit 10;");
}
private static List<Score> queryScore(String query) {
private List<Score> queryScore(String query) {
List<Score> result = new ArrayList<>();
try (Connection con = DriverManager.getConnection(JDBC_CONECTIN_STRING);
Statement stm = con.createStatement();
......@@ -35,7 +35,7 @@ public class DbConnector {
return result;
}
public static void createTable() {
public void init() {
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);");
......@@ -44,7 +44,7 @@ public class DbConnector {
}
}
public static void insertScore(Score score) {
public 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());
......
......@@ -71,17 +71,17 @@ public class GameController {
void btnGenerateScoreAction(ActionEvent event) {
Score score = Score.generate();
this.scores.getItems().add(score);
DbConnector.insertScore(score);
ScoreStorageFactory.getInstance().insertScore(score);
}
@FXML
void btnLoadAllAction(ActionEvent event) {
updateScoreTable(DbConnector.getAll());
updateScoreTable(ScoreStorageFactory.getInstance().getAll());
}
@FXML
void btnLoadFirstTenAction(ActionEvent event) {
updateScoreTable(DbConnector.getFirstTen());
updateScoreTable(ScoreStorageFactory.getInstance().getFirstTen());
}
private void updateScoreTable(List<Score> scores) {
......@@ -117,8 +117,8 @@ public class GameController {
private void initDB() {
//Stream.generate(Score::generate).limit(10).toList();
DbConnector.createTable();
scores.getItems().addAll(DbConnector.getAll());
ScoreStorageFactory.getInstance().init();
scores.getItems().addAll(ScoreStorageFactory.getInstance().getAll());
}
public void stop() {
......
package lab;
import java.time.Duration;
import java.time.LocalDate;
import java.time.Period;
import java.time.temporal.ChronoUnit;
public class Person {
private String firstName;
private String lastName;
private LocalDate dayOfBirth;
public Person(String firstName, String lastName, LocalDate dayOfBirth) {
super();
this.firstName = firstName;
this.lastName = lastName;
this.dayOfBirth = dayOfBirth;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getFirstName() {
return firstName;
}
public LocalDate getDayOfBirth() {
return dayOfBirth;
}
public int getAge() {
return Period.between(dayOfBirth, LocalDate.now()).getYears();
}
public static void main(String[] args) {
Person p = new Person("", "", LocalDate.now().minusDays(3700));
System.out.println(p.getAge());
System.out.println(p.getDaysToBirthday());
}
public LocalDate get50thBirthDay() {
return dayOfBirth.plusYears(50);
}
public long getDaysToBirthday() {
LocalDate nextBirthday = dayOfBirth.withYear(LocalDate.now().getYear());
if(nextBirthday.isBefore(LocalDate.now())){
nextBirthday = nextBirthday.plusYears(1);
}
return ChronoUnit.DAYS.between(LocalDate.now(), nextBirthday);
}
}
package lab;
public class ScoreStorageFactory {
private static DbConnector instance;
public static DbConnector getInstance() {
if(instance == null) {
instance = new DbConnector();
}
return instance;
}
}
......@@ -4,18 +4,18 @@
<?import javafx.scene.Cursor?>
<?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.layout.BorderPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.StackPane?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.text.Font?>
<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">
<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="388.0" prefWidth="911.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">
<HBox alignment="TOP_CENTER" prefHeight="66.0" prefWidth="866.0" BorderPane.alignment="CENTER">
<children>
<Slider fx:id="angle" majorTickUnit="15.0" max="90.0" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minorTickCount="5" showTickLabels="true" showTickMarks="true" HBox.hgrow="ALWAYS" />
<Button mnemonicParsing="false" onAction="#fire" style="-fx-background-color: RED;" text="Fire" textAlignment="CENTER">
......@@ -36,20 +36,20 @@
</children>
</HBox>
</bottom>
<center>
<Canvas fx:id="canvas" height="306.0" width="582.0" BorderPane.alignment="CENTER">
<left>
<StackPane style="-fx-border-image-width: 3px; -fx-border-style: SOLID;" BorderPane.alignment="CENTER">
<BorderPane.margin>
<Insets />
</BorderPane.margin>
</Canvas>
</center>
<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">
<Canvas fx:id="canvas" height="306.0" style="-fx-border-width: 3px; -fx-border-style: SOLID; -fx-border-color: RGB(100.0,0.0,0.0);" width="582.0" StackPane.alignment="TOP_LEFT" />
</children>
</StackPane>
</left>
<center>
<VBox maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" BorderPane.alignment="CENTER">
<children>
<TableView fx:id="scores" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="2000.0">
<columns>
<TableColumn fx:id="nickColumn" prefWidth="75.0" text="Nick" />
<TableColumn fx:id="pointsColumn" prefWidth="75.0" text="Points" />
......@@ -63,5 +63,5 @@
<Button fx:id="btnLoadFirstTen" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#btnLoadFirstTenAction" text="Load First 10 from DB" />
</children>
</VBox>
</right>
</center>
</BorderPane>
package jez04.structure.test;
import java.util.Arrays;
import java.util.List;
import org.hamcrest.BaseMatcher;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
public class AllOfContinue<T> extends BaseMatcher<T> {
private final List<Matcher<? super T>> matchers;
@SafeVarargs
public AllOfContinue(Matcher<? super T> ... matchers) {
this(Arrays.asList(matchers));
}
public AllOfContinue(List<Matcher<? super T>> matchers) {
this.matchers = matchers;
}
@Override
public boolean matches(Object o) {
for (Matcher<? super T> matcher : matchers) {
if (!matcher.matches(o)) {
// matcher.describeMismatch(o, mismatch);
return false;
}
}
return true;
}
@Override
public void describeTo(Description description) {
description.appendList("(", " " + "and" + " ", ")", matchers);
}
}
package jez04.structure.test;
import org.hamcrest.Description;
public class ClassExist extends StructureMatcher<String> {
private String className;
private boolean useRegExp;
private boolean caseSensitive;
public ClassExist(String className) {
this(className, true, false);
}
public ClassExist(String className, boolean caseSensitive, boolean useRegExp) {
this.className = className;
this.useRegExp = useRegExp;
this.caseSensitive = caseSensitive;
}
@Override
public boolean matches(Object actual) {
if (useRegExp) {
return structureHelper.getAllClasses().stream().anyMatch(
c -> caseSensitive ? c.matches(className) : c.toLowerCase().matches(className.toLowerCase()));
} else {
return structureHelper.getAllClasses().stream().anyMatch(
c -> caseSensitive ? c.endsWith(className) : c.toLowerCase().endsWith(className.toLowerCase()));
}
}
@Override
public void describeTo(Description description) {
description.appendText(String.format("class/interface with name '%s' comparsion params(%s %s) exists", className,
caseSensitive ? "" : "no case sensitive", useRegExp ? "using regexp" : ""));
}
@Override
public void describeMismatch(Object item, Description description) {
description.appendValueList("no class match from:\n ", "\n ", "", structureHelper.getAllClasses());
}
}
package jez04.structure.test;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.empty;
import static org.hamcrest.Matchers.endsWith;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.startsWith;
import static org.hamcrest.Matchers.stringContainsInOrder;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URISyntaxException;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.List;
import org.junit.jupiter.api.Test;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
class ClassStructureTest {
StructureHelper helper = new StructureHelper();
StructureHelper helper = StructureHelper.getInstance();
@Test
void gameControllerExistenceTest() {
helper.classExist("GameController");
void dataImporterTest() throws URISyntaxException, IOException, IllegalAccessException, InvocationTargetException {
assertThat("", new ClassExist(".*Data.*", false, true));
Class<?> c = helper.getClassRegexp(".*Data.*");
}
@Test
void gameControllerFxmlTest() {
helper.classExist("GameController");
Class<?> c = helper.getClass("GameController");
helper.hasPropertyWithAnnotation(c, ".*", FXML.class);
void dataImporterDownloadTest() throws URISyntaxException, IOException, IllegalAccessException, InvocationTargetException {
assertThat("", new ClassExist(".*Data.*", false, true));
Class<?> d = helper.getClassRegexp(".*Data.*");
assertThat(d, new HasMethod(".*down.*", String.class).useRegExp(true).caseSensitive(false));
Method download = helper.getMethod(d, ".*down.*", false, String.class);
String downloadedText = (String) download.invoke(null);
assertThat(downloadedText, allOf(
endsWith("}]}"),
startsWith("{\"status\":\"OK\""),
stringContainsInOrder("firstname"),
stringContainsInOrder("lastname"),
stringContainsInOrder("birthday")
));
}
@Test
void gameControllerButtonActionMethodTest() {
helper.classExist("GameController");
Class<?> c = helper.getClass("GameController");
long count = helper.countMethodRegexp(c, ".*", void.class, ActionEvent.class);
assertTrue(count > 1, "Only " + count+ " method handling button click found. Expected more then 1");
void dataImporterParseAllTest() throws URISyntaxException, IOException, IllegalAccessException, InvocationTargetException {
assertThat("", new ClassExist(".*Data.*", false, true));
Class<?> d = helper.getClassRegexp(".*Data.*");
helper.hasMethod(d, ".*parse.*", false, List.class, String.class);
Method parse = helper.getMethod(d, ".*parse.*", false, List.class, String.class);
List<String> texts = (List<String>) parse.invoke(null, "{\"id\":1,\"firstname\":\"Tatum\",\"lastname\":\"Block\",\"email\":\"lonnie.bergstrom@stoltenberg.com\",\"phone\":\"+12397191764\",\"birthday\":\"1946-11-06\",\"gender\":\"male\",\"address\":{");
assertThat(texts, not(empty()));
}
@Test
void gameControllerTableViewTest() {
helper.classExist("GameController");
Class<?> c = helper.getClass("GameController");
helper.hasProperty(c, ".*", TableView.class, false);
}
@Test
void gameControllerTableColumnTest() {
helper.classExist("GameController");
Class<?> c = helper.getClass("GameController");
helper.hasProperty(c, ".*", TableColumn.class, false);
void personTest() throws URISyntaxException, IOException, IllegalAccessException, InvocationTargetException {
assertThat("", new ClassExist("Person", false, false));
Class<?> p = helper.getClass("Person", false);
}
@Test
void dbConnectorTest() {
helper.classExistRegexp(".*[Dd][Bb][cC]on.*");
}
void dataImporterParsePersonTest() throws URISyntaxException, IOException, IllegalAccessException, InvocationTargetException {
assertThat("", new ClassExist(".*Data.*", false, true));
Class<?> d = helper.getClassRegexp(".*Data.*");
@Test
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 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);
assertThat("", new ClassExist("Person", false, false));
Class<?> p = helper.getClass("Person", false);
helper.hasMethod(d, ".*parse.*", false, p, String.class);
Method parsePerson = helper.getMethod(d, ".*parse.*", false, p, String.class);
Object person = parsePerson.invoke(null, "{\"id\":1,\"firstname\":\"Tatum\",\"lastname\":\"Block\",\"email\":\"lonnie.bergstrom@stoltenberg.com\",\"phone\":\"+12397191764\",\"birthday\":\"1946-11-06\",\"gender\":\"male\",\"address\":{");
assertThat(person, notNullValue());
}
@Test
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.");
void personAgeTest() throws URISyntaxException, IOException, IllegalAccessException, InvocationTargetException {
assertThat("", new ClassExist(".*Data.*", false, true));
Class<?> d = helper.getClassRegexp(".*Data.*");
assertThat("", new ClassExist("Person", false, false));
Class<?> p = helper.getClass("Person", false);
helper.hasMethod(d, ".*parse.*", false, p, String.class);
Method parsePerson = helper.getMethod(d, ".*parse.*", false, p, String.class);
Object person = parsePerson.invoke(null, "{\"id\":1,\"firstname\":\"Tatum\",\"lastname\":\"Block\",\"email\":\"lonnie.bergstrom@stoltenberg.com\",\"phone\":\"+12397191764\",\"birthday\":\"1946-11-06\",\"gender\":\"male\",\"address\":{");
assertThat(person, notNullValue());
Method age = helper.getMethod(p, ".*age.*", false, int.class);
int result = (int)age.invoke(person);
assertEquals(78, result , "Calculate wrong age.");
}
@Test
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.");
void person50birthdayTest() throws URISyntaxException, IOException, IllegalAccessException, InvocationTargetException {
assertThat("", new ClassExist(".*Data.*", false, true));
Class<?> d = helper.getClassRegexp(".*Data.*");
assertThat("", new ClassExist("Person", false, false));
Class<?> p = helper.getClass("Person", false);
helper.hasMethod(d, ".*parse.*", false, p, String.class);
Method parsePerson = helper.getMethod(d, ".*parse.*", false, p, String.class);
Object person = parsePerson.invoke(null, "{\"id\":1,\"firstname\":\"Tatum\",\"lastname\":\"Block\",\"email\":\"lonnie.bergstrom@stoltenberg.com\",\"phone\":\"+12397191764\",\"birthday\":\"1946-11-06\",\"gender\":\"male\",\"address\":{");
assertThat(person, notNullValue());
Method birth50 = helper.getMethod(p, ".*50.*", false, LocalDate.class);
LocalDate ldBirth50 = (LocalDate)birth50.invoke(person);
assertEquals(LocalDate.of(1996, 11, 06), ldBirth50 , "Calculate wrong 50th birthday.");
}
@Test
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.");
void personNextBirthdayTest() throws URISyntaxException, IOException, IllegalAccessException, InvocationTargetException {
assertThat("", new ClassExist(".*Data.*", false, true));
Class<?> d = helper.getClassRegexp(".*Data.*");
assertThat("", new ClassExist("Person", false, false));
Class<?> p = helper.getClass("Person", false);
helper.hasMethod(d, ".*parse.*", false, p, String.class);
Method parsePerson = helper.getMethod(d, ".*parse.*", false, p, String.class);
LocalDate bod =LocalDate.now().plusDays(338).minusYears(10);
Object person = parsePerson.invoke(null, "{\"id\":1,\"firstname\":\"Tatum\",\"lastname\":\"Block\",\"email\":\"lonnie.bergstrom@stoltenberg.com\",\"phone\":\"+12397191764\",\"birthday\":\""+ bod.format(DateTimeFormatter.ISO_DATE) +"\",\"gender\":\"male\",\"address\":{");
assertThat(person, notNullValue());
Method daysM = helper.getMethod(p, ".*days.*", false, long.class);
long days= (long)daysM.invoke(person);
assertEquals(338, days , "Calculate wrong days to next birthday.");
}
}
package jez04.structure.test;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.List;
import java.util.stream.Collectors;
import org.hamcrest.Description;
public class ContainsInnerClasses extends StructureMatcher<Class<?>> {
private String methodNameRegexp;
private boolean caseSensitive = true;
private boolean useRegExp = false;
private int count = 1;
private List<Class<?>> params;
public ContainsInnerClasses(String methodNameRegexp) {
this.methodNameRegexp = methodNameRegexp;
}
public ContainsInnerClasses caseSensitive(boolean caseSensitive) {
this.caseSensitive = caseSensitive;
return this;
}
public ContainsInnerClasses count(int count) {
this.count = count;
return this;
}
public ContainsInnerClasses useRegExp(boolean useRegExp) {
this.useRegExp = useRegExp;
return this;
}
@Override
public boolean matches(Object actual) {
if (actual instanceof Class c) {
long lamdaCount = structureHelper.countMethodRegexp(c, "lambda\\$.*");
long innerClassCount = structureHelper.countClassesRegexp(c.getCanonicalName()+"\\$.*");
long methodRefCount = 0;
try {
methodRefCount = structureHelper.countMethodReference(c);
} catch (URISyntaxException | IOException e) {
System.out.println("Cannot count method references");
e.printStackTrace();
}
return lamdaCount + innerClassCount+methodRefCount >= count;
}
return false;
}
@Override
public void describeTo(Description description) {
params.stream().map(Class::getName).collect(Collectors.joining(", "));
description.appendText(
String.format("Class should have inner classses or lambdas name (regexp) of type %s %s %s with params types %s",
methodNameRegexp, caseSensitive ? "" : "ignore case", ""));
}
@Override
public void describeMismatch(Object item, Description description) {
if (item instanceof Class c) {
description.appendValueList("no method match from:\n ", "\n ", "", c.getDeclaredMethods());
} else {
description.appendText("mismatched item is not class type");
}
}
}
package jez04.structure.test;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.hamcrest.Description;
public class HasMethod extends StructureMatcher<Class<?>> {
private String methodNameRegexp;
private Class<?> returnType;
private boolean caseSensitive = true;
private boolean useRegExp = false;
private Boolean abstractTag = null;
private Boolean finalTag = null;
private int count = 1;
private List<Class<?>> params;
public HasMethod(String methodNameRegexp, Class<?> returnType, Class<?>... params) {
this.methodNameRegexp = methodNameRegexp;
this.returnType = returnType;
this.params = List.of(params);
}
public HasMethod caseSensitive(boolean caseSensitive) {
this.caseSensitive = caseSensitive;
return this;
}
public HasMethod abstractTag(Boolean abstractTag) {
this.abstractTag = abstractTag;
return this;
}
public HasMethod finalTag(Boolean finalTag) {
this.finalTag = finalTag;
return this;
}
public HasMethod count(int count) {
this.count = count;
return this;
}
public HasMethod useRegExp(boolean useRegExp) {
this.useRegExp = useRegExp;
return this;
}
@Override
public boolean matches(Object actual) {
if (actual instanceof Class c) {
List<Method> methods = Arrays.asList(c.getDeclaredMethods());
Stream<Method> streamOfMethods;
if (useRegExp) {
streamOfMethods = methods.stream().filter(m -> caseSensitive ? m.getName().matches(methodNameRegexp)
: m.getName().toLowerCase().matches(methodNameRegexp.toLowerCase()));
} else {
streamOfMethods = methods.stream().filter(m -> caseSensitive ? m.getName().endsWith(methodNameRegexp)
: m.getName().toLowerCase().endsWith(methodNameRegexp.toLowerCase()));
}
streamOfMethods = streamOfMethods
.filter(m -> returnType != null ? returnType.equals(m.getReturnType()) : true)
.filter(m -> finalTag != null ? Modifier.isAbstract(m.getModifiers()) == abstractTag.booleanValue()
: true)
.filter(m -> abstractTag != null ? Modifier.isFinal(m.getModifiers()) == finalTag.booleanValue()
: true);
long co = streamOfMethods.count();
return co >= count;
}
return false;
}
@Override
public void describeTo(Description description) {
params.stream().map(Class::getName).collect(Collectors.joining(", "));
description.appendText(
String.format("Class should have method name (regexp) of type %s %s %s with params types %s",
returnType, methodNameRegexp, caseSensitive ? "" : "ignore case", ""));
}
@Override
public void describeMismatch(Object item, Description description) {
if (item instanceof Class c) {
description.appendValueList("no method match from:\n ", "\n ", "", c.getDeclaredMethods());
} else {
description.appendText("mismatched item is not class type");
}
}
}
package jez04.structure.test;
import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Stream;
import org.hamcrest.Description;
public class HasProperty extends StructureMatcher<Class<?>> {
private String propertyNameRegexp;
private Class<?> type;
private Predicate<Type> genericTypeFilter;
private Predicate<Class<?>> typeFilter;
private Boolean array = false;
private boolean caseSensitive;
private Class<?> annotation = null;
private int count = 1;
public HasProperty(String propertyNameRegexp, Class<?> type, Boolean array) {
this(propertyNameRegexp, type, array, true);
}
public HasProperty(String propertyNameRegexp, Class<?> type, Boolean array, boolean caseSensitive) {
this.propertyNameRegexp = propertyNameRegexp;
this.type = type;
this.array = array;
this.caseSensitive = caseSensitive;
}
public HasProperty annotation(Class<?> annotation) {
this.annotation = annotation;
return this;
}
public HasProperty typeFilter(Predicate<Class<?>> typeFilter) {
this.typeFilter = typeFilter;
return this;
}
public HasProperty genericTypeFilter(Predicate<Type> genericTypeFilter) {
this.genericTypeFilter = genericTypeFilter;
return this;
}
public HasProperty count(int count) {
this.count = count;
return this;
}
@Override
public boolean matches(Object actual) {
if (actual instanceof Class c) {
Stream<?> streamOfResults;
List<Field> fields = Arrays.asList(c.getDeclaredFields());
Stream<Field> streamOfFields = fields.stream()
.filter(f -> caseSensitive ? f.getName().matches(propertyNameRegexp)
: f.getName().toLowerCase().matches(propertyNameRegexp.toLowerCase()))
.filter(f -> type != null ? f.getType().equals(type) : true)
.filter(f -> array != null ? f.getType().isAnnotation() == array.booleanValue() : true)
.filter(f -> genericTypeFilter != null ? genericTypeFilter.test(f.getGenericType()) : true)
.filter(f -> typeFilter != null ? typeFilter.test(f.getType()) : true);
streamOfResults = streamOfFields;
if (annotation != null) {
streamOfResults = streamOfFields.flatMap(f -> Arrays.asList(f.getAnnotations()).stream())
.map(a -> a.annotationType()).filter(a -> a.equals(annotation));
}
long actualCount = streamOfResults.count();
return this.count <= actualCount;
}
return false;
}
@Override
public void describeTo(Description description) {
description.appendText(String.format("Class should have field of type %s%s with name match regexp '%s'%s", type,
array != null && array ? "[]" : "", propertyNameRegexp, caseSensitive ? "" : "ignore case"));
}
@Override
public void describeMismatch(Object item, Description description) {
if (item instanceof Class c) {
description.appendValueList("none of", ", ", "match", c.getDeclaredFields());
} else {
description.appendText("mismatched item is not class type");
}
}
}
package jez04.structure.test;
import org.hamcrest.Description;
public class IsDescendatOf extends StructureMatcher<Class<?>> {
private String className;
public IsDescendatOf(String className) {
this.className = className;
}
@Override
public boolean matches(Object actual) {
if(actual instanceof Class c) {
return structureHelper.getClass(className).isAssignableFrom(c);
}
return false;
}
@Override
public void describeTo(Description description) {
description.appendText(String.format("cass shoud be descendant of %s", className));
}
}
package jez04.structure.test;
import org.hamcrest.Description;
public class IsInterface extends StructureMatcher<Class<?>> {
public IsInterface() {
}
@Override
public boolean matches(Object actual) {
if (actual instanceof Class c) {
return c.isInterface();
}
return false;
}
@Override
public void describeTo(Description description) {
description.appendText(String.format("value should be interface"));
}
}
package jez04.structure.test;
import java.io.IOException;
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.LinkedList;
import java.util.List;
import java.util.regex.Pattern;
import org.hamcrest.Description;
public class ResourceContains extends StructureMatcher<String> {
private String regexp;
private boolean caseInsensitive;
private boolean srcFound;
private int count = 1;
public ResourceContains(String regexp, boolean caseInsensitive) {
this.regexp = regexp;
this.caseInsensitive = caseInsensitive;
}
public ResourceContains count(int count) {
this.count = count;
return this;
}
@Override
public boolean matches(Object actual) {
srcFound = true;
List<Path> foundResources = new LinkedList<>();
Pattern p;
if (caseInsensitive) {
p = Pattern.compile(regexp, Pattern.CASE_INSENSITIVE);
} else {
p = Pattern.compile(regexp);
}
try {
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 resourcesRoot = classRoot.getParent().getParent().resolve(Paths.get("src", "main", "resources"));
System.out.println("resources root: " + resourcesRoot);
Files.walkFileTree(resourcesRoot, new FileVisitor<Path>() {
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
if (p.matcher(file.getFileName().toString()).matches()) {
foundResources.add(file);
}
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
return FileVisitResult.CONTINUE;
}
});
return foundResources.size() >= count;
} catch (URISyntaxException | IOException e) {
srcFound = false;
e.printStackTrace();
return false;
}
}
@Override
public void describeTo(Description description) {
description.appendText(String.format("Source code of class shoud contains regexp '%s'%s", regexp,
caseInsensitive ? " in case insensitive mode" : ""));
}
@Override
public void describeMismatch(Object item, Description description) {
if (srcFound) {
description
.appendText(String.format("source code of class %s do not contains substring that match reg exp"));
} else {
description.appendText(String.format("source code of class %s was not found"));
}
}
}
package jez04.structure.test;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.regex.Pattern;
import org.hamcrest.Description;
public class SrcContains extends StructureMatcher<Class<?>> {
private String regexp;
private boolean caseInsensitive;
private boolean srcFound;
public SrcContains(String regexp, boolean caseInsensitive) {
this.regexp = regexp;
this.caseInsensitive = caseInsensitive;
}
@Override
public boolean matches(Object actual) {
srcFound = true;
if (actual instanceof Class c) {
Pattern p = Pattern.compile(regexp);
if (caseInsensitive) {
p = Pattern.compile(regexp, Pattern.CASE_INSENSITIVE);
}
try {
return p.matcher(structureHelper.getSourceCode(c)).find();
} catch (URISyntaxException | IOException e) {
srcFound = false;
e.printStackTrace();
return false;
}
}
return false;
}
@Override
public void describeTo(Description description) {
description.appendText(String.format("Source code of class shoud contains regexp '%s'%s", regexp,
caseInsensitive ? " in case insensitive mode" : ""));
}
@Override
public void describeMismatch(Object item, Description description) {
if (srcFound) {
description
.appendText(String.format("source code of class %s do not contains substring that match reg exp", item));
} else {
description.appendText(String.format("source code of class %s was not found"));
}
}
}
......@@ -29,7 +29,10 @@ import java.util.function.Predicate;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.hamcrest.BaseMatcher;
import org.hamcrest.Description;
import org.junit.jupiter.api.Assertions;
import org.reflections.Configuration;
import org.reflections.Reflections;
......@@ -38,18 +41,49 @@ import org.reflections.util.ConfigurationBuilder;
class StructureHelper {
private static StructureHelper singeltonInstance;
public static StructureHelper getInstance() {
if (singeltonInstance == null) {
singeltonInstance = new StructureHelper();
}
return singeltonInstance;
}
Set<String> allClasses = getNameOfAllClasses();
private StructureHelper() {
/* hide public one */
}
public Set<String> getAllClasses() {
return allClasses;
}
public void isInterface(Class<?> c) {
assertTrue(c.isInterface(), c.getName() + " have to be interface.");
}
public void classExist(String name) {
assertTrue(allClasses.stream().anyMatch(c -> c.endsWith(name)), "Class/Interface " + name + " not found");
classExist(name, true);
}
public void classExist(String name, boolean caseSensitive) {
assertTrue(
allClasses.stream()
.anyMatch(c -> caseSensitive ? c.endsWith(name) : c.toLowerCase().endsWith(name.toLowerCase())),
"Class/Interface " + name + " not found");
}
public void classExistRegexp(String name) {
assertTrue(allClasses.stream().anyMatch(c -> c.matches(name)), "Class/Interface " + name + " not found");
classExistRegexp(name, true);
}
public void classExistRegexp(String name, boolean caseSensitive) {
assertTrue(
allClasses.stream()
.anyMatch(c -> caseSensitive ? c.matches(name) : c.toLowerCase().matches(name.toLowerCase())),
"Class/Interface " + name + " not found");
}
public Class<?> getClassDirectly(String name) {
......@@ -57,7 +91,13 @@ class StructureHelper {
}
public Class<?> getClassRegexp(String name) {
String className = allClasses.stream().filter(c -> c.matches(name)).findAny().orElse(null);
return getClassRegexp(name, true);
}
public Class<?> getClassRegexp(String name, boolean caseSensitive) {
String className = allClasses.stream()
.filter(c -> caseSensitive ? c.matches(name) : c.toLowerCase().matches(name.toLowerCase())).findAny()
.orElse(null);
if (className == null) {
Assertions.fail("Class " + name + " not found.");
}
......@@ -65,7 +105,13 @@ class StructureHelper {
}
public Class<?> getClass(String name) {
String className = allClasses.stream().filter(c -> c.endsWith(name)).findAny().orElse(null);
return getClass(name, true);
}
public Class<?> getClass(String name, boolean caseSensitive) {
String className = allClasses.stream()
.filter(c -> caseSensitive ? c.endsWith(name) : c.toLowerCase().endsWith(name.toLowerCase())).findAny()
.orElse(null);
if (className == null) {
Assertions.fail("Class " + name + " not found.");
}
......@@ -88,10 +134,27 @@ class StructureHelper {
}
}
public org.hamcrest.Matcher<Class<?>> hasProperty(String propertyNameRegexp, Class<?> type, boolean array) {
return new HasProperty(propertyNameRegexp, type, array);
}
public void hasProperty(Class<?> classDef, String propertyNameRegexp, Class<?> type, boolean array) {
hasProperty(classDef, propertyNameRegexp, type, array, true);
}
public void hasProperty(Class<?> classDef, String propertyNameRegexp, Class<?> type, boolean array,
boolean caseSensitive) {
assertTrue(hasPropertyB(classDef, propertyNameRegexp, type, array, caseSensitive),
"No field " + propertyNameRegexp + " of type " + type.getName() + " (is array " + array + ") in class "
+ classDef.getName());
}
public boolean hasPropertyB(Class<?> classDef, String propertyNameRegexp, Class<?> type, boolean array,
boolean caseSensitive) {
List<Field> fields = Arrays.asList(classDef.getDeclaredFields());
assertTrue(fields.stream().anyMatch(f -> {
if (f.getName().matches(propertyNameRegexp)) {
return fields.stream().anyMatch(f -> {
if (caseSensitive ? f.getName().matches(propertyNameRegexp)
: f.getName().toLowerCase().matches(propertyNameRegexp.toLowerCase())) {
if (array) {
return f.getType().isArray() && f.getType().getComponentType().equals(type);
} else {
......@@ -99,14 +162,20 @@ class StructureHelper {
}
}
return false;
}), "No field " + propertyNameRegexp + " of type " + type.getName() + " (is array " + array + ") in class "
+ classDef.getName());
});
}
public void hasPropertyWithAnnotation(Class<?> classDef, String propertyNameRegexp, Class<?> annotation) {
hasPropertyWithAnnotation(classDef, propertyNameRegexp, annotation, true);
}
public void hasPropertyWithAnnotation(Class<?> classDef, String propertyNameRegexp, Class<?> annotation,
boolean caseSensitive) {
List<Field> fields = Arrays.asList(classDef.getDeclaredFields());
assertTrue(
fields.stream().filter(f -> f.getName().matches(propertyNameRegexp))
fields.stream()
.filter(f -> caseSensitive ? f.getName().matches(propertyNameRegexp)
: f.getName().toLowerCase().matches(propertyNameRegexp.toLowerCase()))
.flatMap(f -> Arrays.asList(f.getAnnotations()).stream()).map(a -> a.annotationType())
.anyMatch(a -> a.equals(annotation)),
"No field " + propertyNameRegexp + " with annotation " + annotation.getName() + " in class "
......@@ -114,19 +183,36 @@ class StructureHelper {
}
public void hasMethod(Class<?> interfaceDef, String methodName, Class<?> returnType) {
hasMethod(interfaceDef, methodName, returnType, true);
}
public void hasMethod(Class<?> interfaceDef, String methodName, Class<?> returnType, boolean caseSensitive) {
List<Method> methods = Arrays.asList(interfaceDef.getDeclaredMethods());
assertTrue(methods.stream().anyMatch(m -> m.getName().contains(methodName)), "No method " + methodName);
assertTrue(
methods.stream().filter(m -> m.getName().contains(methodName))
methods.stream()
.filter(m -> caseSensitive ? m.getName().matches(methodName)
: m.getName().toLowerCase().matches(methodName.toLowerCase()))
.anyMatch(m -> m.getReturnType().equals(returnType)),
"Method " + methodName + " not return " + returnType.getName());
}
public void hasMethod(Class<?> interfaceDef, String methodName, Class<?> returnType, Class<?>... params) {
hasMethod(interfaceDef, methodName, true, returnType, params);
}
public void hasMethod(Class<?> interfaceDef, String methodName, boolean caseSensitive, Class<?> returnType,
Class<?>... params) {
List<Method> methods = Arrays.asList(interfaceDef.getDeclaredMethods());
assertTrue(methods.stream().anyMatch(m -> m.getName().contains(methodName)), "No method " + methodName);
assertTrue(
methods.stream().filter(m -> m.getName().contains(methodName))
methods.stream()
.anyMatch(m -> caseSensitive ? m.getName().matches(methodName)
: m.getName().toLowerCase().matches(methodName.toLowerCase())),
"No method " + methodName);
assertTrue(
methods.stream()
.filter(m -> caseSensitive ? m.getName().matches(methodName)
: m.getName().toLowerCase().matches(methodName.toLowerCase()))
.filter(m -> m.getReturnType().equals(returnType))
.anyMatch(m -> Arrays.asList(m.getParameterTypes()).containsAll(Arrays.asList(params))),
"Method " + methodName + " has no all parrams:"
......@@ -134,8 +220,15 @@ class StructureHelper {
}
public Method getMethod(Class<?> interfaceDef, String methodName, Class<?> returnType, Class<?>... params) {
return getMethod(interfaceDef, methodName, true, returnType, params);
}
public Method getMethod(Class<?> interfaceDef, String methodName, boolean caseSensitive, Class<?> returnType,
Class<?>... params) {
List<Method> methods = Arrays.asList(interfaceDef.getDeclaredMethods());
List<Method> foundMethods = methods.stream().filter(m -> m.getName().contains(methodName))
List<Method> foundMethods = methods.stream()
.filter(m -> caseSensitive ? m.getName().matches(methodName)
: m.getName().toLowerCase().matches(methodName.toLowerCase()))
.filter(m -> m.getReturnType().equals(returnType))
.filter(m -> Arrays.asList(m.getParameterTypes()).containsAll(Arrays.asList(params))).toList();
if (foundMethods.isEmpty()) {
......@@ -148,8 +241,13 @@ class StructureHelper {
}
public long countMethodRegexp(Class<?> interfaceDef, String methodNameRegexp) {
return countMethodRegexp(interfaceDef, methodNameRegexp, true);
}
public long countMethodRegexp(Class<?> interfaceDef, String methodNameRegexp, boolean caseSensitive) {
List<Method> methods = Arrays.asList(interfaceDef.getDeclaredMethods());
return methods.stream().filter(m -> m.getName().matches(methodNameRegexp)).count();
return methods.stream().filter(m -> caseSensitive ? m.getName().matches(methodNameRegexp)
: m.getName().toLowerCase().matches(methodNameRegexp.toLowerCase())).count();
}
public long countMethodReference(Class<?> interfaceDef) throws URISyntaxException, IOException {
......@@ -170,7 +268,12 @@ class StructureHelper {
}
public long countClassesRegexp(String classNameRegexp) {
return getNameOfAllClasses().stream().filter(className -> className.matches(classNameRegexp)).count();
return countClassesRegexp(classNameRegexp, true);
}
public long countClassesRegexp(String classNameRegexp, boolean caseSensitive) {
return getNameOfAllClasses().stream().filter(className -> caseSensitive ? className.matches(classNameRegexp)
: className.toLowerCase().matches(classNameRegexp.toLowerCase())).count();
}
public void hasConstructor(Class<?> classDef, Class<?>... params) {
......@@ -195,33 +298,103 @@ class StructureHelper {
public void hasMethodRegexp(Class<?> interfaceDef, String methodNameRegexp, Class<?> returnType,
Class<?>... params) {
hasMethodRegexp(interfaceDef, methodNameRegexp, true, returnType, params);
}
public void hasMethodRegexp(Class<?> interfaceDef, String methodNameRegexp, boolean caseSensitive,
Class<?> returnType, Class<?>... params) {
List<Method> methods = Arrays.asList(interfaceDef.getDeclaredMethods());
assertTrue(methods.stream().anyMatch(m -> m.getName().matches(methodNameRegexp)),
assertTrue(
methods.stream()
.anyMatch(m -> caseSensitive ? m.getName().matches(methodNameRegexp)
: m.getName().toLowerCase().matches(methodNameRegexp.toLowerCase())),
"No method " + methodNameRegexp);
assertTrue(
methods.stream().filter(m -> m.getName().matches(methodNameRegexp))
methods.stream()
.filter(m -> caseSensitive ? m.getName().matches(methodNameRegexp)
: m.getName().toLowerCase().matches(methodNameRegexp.toLowerCase()))
.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 boolean hasMethodRegexpTest(Class<?> interfaceDef, String methodNameRegexp, boolean caseSensitive,
Class<?> returnType, Class<?>... params) {
return hasMethodRegexpTest(interfaceDef, methodNameRegexp, caseSensitive, returnType, List.of(params));
}
public boolean hasMethodRegexpTest(Class<?> interfaceDef, String methodNameRegexp, boolean caseSensitive,
Class<?> returnType, List<Class<?>> params) {
List<Method> methods = Arrays.asList(interfaceDef.getDeclaredMethods());
if (!methods.stream().anyMatch(m -> caseSensitive ? m.getName().matches(methodNameRegexp)
: m.getName().toLowerCase().matches(methodNameRegexp.toLowerCase()))) {
return false;
}
return methods.stream()
.filter(m -> caseSensitive ? m.getName().matches(methodNameRegexp)
: m.getName().toLowerCase().matches(methodNameRegexp.toLowerCase()))
.filter(m -> m.getReturnType().equals(returnType))
.anyMatch(m -> Arrays.asList(m.getParameterTypes()).containsAll(params));
}
public long countMethodRegexp(Class<?> interfaceDef, String methodNameRegexp, Class<?> returnType,
Class<?>... params) {
return countMethodRegexp(interfaceDef, methodNameRegexp, true, returnType, params);
}
public long countMethodRegexp(Class<?> interfaceDef, String methodNameRegexp, boolean caseSensitive,
Class<?> returnType, Class<?>... params) {
List<Method> methods = Arrays.asList(interfaceDef.getDeclaredMethods());
assertTrue(methods.stream().anyMatch(m -> m.getName().matches(methodNameRegexp)),
assertTrue(
methods.stream()
.anyMatch(m -> caseSensitive ? m.getName().matches(methodNameRegexp)
: m.getName().toLowerCase().matches(methodNameRegexp.toLowerCase())),
"No method " + methodNameRegexp);
return methods.stream().filter(m -> m.getName().matches(methodNameRegexp))
return methods.stream()
.filter(m -> caseSensitive ? m.getName().matches(methodNameRegexp)
: m.getName().toLowerCase().matches(methodNameRegexp.toLowerCase()))
.filter(m -> m.getReturnType().equals(returnType))
.filter(m -> Arrays.asList(m.getParameterTypes()).containsAll(Arrays.asList(params))).count();
}
public boolean hasMethodTest(Class<?> interfaceDef, boolean finalTag, boolean abstractTag, String methodName,
boolean caseSensitive, Class<?> returnType, Class<?>... params) {
return hasMethodTest(interfaceDef, finalTag, abstractTag, methodName, caseSensitive, returnType, List.of(params));
}
public boolean hasMethodTest(Class<?> interfaceDef, boolean finalTag, boolean abstractTag, String methodName,
boolean caseSensitive, Class<?> returnType, List<Class<?>> params) {
List<Method> methods = Arrays.asList(interfaceDef.getDeclaredMethods());
if (!methods.stream().anyMatch(m -> caseSensitive ? m.getName().matches(methodName)
: m.getName().toLowerCase().matches(methodName.toLowerCase()))) {
return false;
}
return methods.stream()
.filter(m -> caseSensitive ? m.getName().matches(methodName)
: m.getName().toLowerCase().matches(methodName.toLowerCase()))
.filter(m -> m.getReturnType().equals(returnType)
&& (Modifier.isAbstract(m.getModifiers()) == abstractTag)
&& (Modifier.isFinal(m.getModifiers()) == finalTag))
.anyMatch(m -> Arrays.asList(m.getParameterTypes()).containsAll(params));
}
public void hasMethod(Class<?> interfaceDef, boolean finalTag, boolean abstractTag, String methodName,
Class<?> returnType, Class<?>... params) {
hasMethod(interfaceDef, finalTag, abstractTag, methodName, true, returnType, params);
}
public void hasMethod(Class<?> interfaceDef, boolean finalTag, boolean abstractTag, String methodName,
boolean caseSensitive, Class<?> returnType, Class<?>... params) {
List<Method> methods = Arrays.asList(interfaceDef.getDeclaredMethods());
assertTrue(methods.stream().anyMatch(m -> m.getName().contains(methodName)), "No method " + methodName);
assertTrue(
methods.stream().filter(m -> m.getName().contains(methodName))
methods.stream()
.anyMatch(m -> caseSensitive ? m.getName().matches(methodName)
: m.getName().toLowerCase().matches(methodName.toLowerCase())),
"No method " + methodName);
assertTrue(
methods.stream()
.filter(m -> caseSensitive ? m.getName().matches(methodName)
: m.getName().toLowerCase().matches(methodName.toLowerCase()))
.filter(m -> m.getReturnType().equals(returnType)
&& (Modifier.isAbstract(m.getModifiers()) == abstractTag)
&& (Modifier.isFinal(m.getModifiers()) == finalTag))
......@@ -230,6 +403,10 @@ class StructureHelper {
+ Arrays.asList(params).stream().map(Class::getName).collect(Collectors.joining(", ")));
}
public boolean isDescendatOf(Class<?> clazz, String interfaceName) {
return getClass(interfaceName).isAssignableFrom(clazz);
}
public void hasImplements(Class<?> clazz, String... interfaceNames) {
List<Class<?>> interfaces = new ArrayList<>();
Arrays.asList(interfaceNames).stream().map(name -> getClass(name)).forEach(c -> interfaces.add(c));
......@@ -249,8 +426,16 @@ class StructureHelper {
}
public void hasMethod(Class<?> interfaceDef, String methodName) {
hasMethod(interfaceDef, methodName, true);
}
public void hasMethod(Class<?> interfaceDef, String methodName, boolean caseSensitive) {
List<Method> methods = Arrays.asList(interfaceDef.getMethods());
assertTrue(methods.stream().anyMatch(m -> m.getName().contains(methodName)), "No method " + methodName);
assertTrue(
methods.stream()
.anyMatch(m -> caseSensitive ? m.getName().matches(methodName)
: m.getName().toLowerCase().matches(methodName.toLowerCase())),
"No method " + methodName);
}
public String getSourceCode(Class<?> clazz) throws URISyntaxException, IOException {
......