diff --git a/projects/elinrin/pom.xml b/projects/elinrin/pom.xml new file mode 100644 index 0000000..2a0e80e --- /dev/null +++ b/projects/elinrin/pom.xml @@ -0,0 +1,120 @@ + + 4.0.0 + + ru.mipt.diht.students + parent + 1.0-SNAPSHOT + + + ru.mipt.diht.students + elinrin + 1.0-SNAPSHOT + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 1.8 + + + + + jar + + elinrin + http://maven.apache.org + + + UTF-8 + + + + + + com.h2database + h2 + 1.4.190 + + + + junit + junit + 3.8.1 + test + + + + com.beust + jcommander + 1.48 + + + + org.twitter4j + twitter4j-stream + 4.0.4 + + + + org.json + json + 20141113 + + + + com.google.guava + guava + 17.0 + + + + junit + junit + 4.11 + test + + + + org.mockito + mockito-all + 1.9.5 + + + + org.powermock + powermock-module-junit4 + 1.6.1 + test + true + + + junit + junit + + + + + + org.powermock + powermock-api-mockito + 1.6.1 + test + true + + + mockito-all + org.mockito + + + + + com.tngtech.java + junit-dataprovider + 1.10.1 + + + + diff --git a/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/collectionquery/Aggregates.java b/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/collectionquery/Aggregates.java new file mode 100644 index 0000000..c590518 --- /dev/null +++ b/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/collectionquery/Aggregates.java @@ -0,0 +1,27 @@ +package ru.mipt.diht.students.elinrin.collectionquery; + +import ru.mipt.diht.students.elinrin.collectionquery.aggregatesImpl.Avg; +import ru.mipt.diht.students.elinrin.collectionquery.aggregatesImpl.Count; +import ru.mipt.diht.students.elinrin.collectionquery.aggregatesImpl.Max; +import ru.mipt.diht.students.elinrin.collectionquery.aggregatesImpl.Min; + +import java.util.function.Function; + +public class Aggregates { + public static Function max(final Function expression) { + return new Max<>(expression); + } + + public static > Function min(final Function expression) { + return new Min<>(expression); + } + + public static Function count(final Function expression) { + return new Count<>(expression); + } + + public static Function avg(final Function expression) { + return new Avg<>(expression); + } + +} diff --git a/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/collectionquery/CollectionQuery.java b/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/collectionquery/CollectionQuery.java new file mode 100644 index 0000000..6c7d32d --- /dev/null +++ b/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/collectionquery/CollectionQuery.java @@ -0,0 +1,217 @@ +package ru.mipt.diht.students.elinrin.collectionquery; + +import ru.mipt.diht.students.elinrin.collectionquery.impl.Tuple; + +import java.lang.reflect.InvocationTargetException; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.temporal.ChronoUnit; +import java.util.Objects; + +import static ru.mipt.diht.students.elinrin.collectionquery.Aggregates.avg; +import static ru.mipt.diht.students.elinrin.collectionquery.Aggregates.count; +import static ru.mipt.diht.students.elinrin.collectionquery.CollectionQuery.Student.student; +import static ru.mipt.diht.students.elinrin.collectionquery.Conditions.rlike; +import static ru.mipt.diht.students.elinrin.collectionquery.OrderByConditions.asc; +import static ru.mipt.diht.students.elinrin.collectionquery.OrderByConditions.desc; +import static ru.mipt.diht.students.elinrin.collectionquery.Sources.list; +import static ru.mipt.diht.students.elinrin.collectionquery.impl.FromStmt.from; + +/*nnn*/ + +public class CollectionQuery { + static final int TWENTY = 20; + static final int HUNDRED = 100; + /** + * Make this code work! + * + * @param args + */ + public static void main(final String[] args) throws InvocationTargetException, NoSuchMethodException, + InstantiationException, IllegalAccessException { + Iterable statistics = + from(list( + student("ivanov", LocalDate.parse("1986-08-06"), "496"), + student("ivanov", LocalDate.parse("1986-08-06"), "496"))) + .select(Statistics.class, Student::getGroup, count(Student::getGroup), avg(Student::age)) + .where(rlike(Student::getName, ".*ov").and(s -> s.age() > TWENTY)) + .groupBy(Student::getName) + .having(s -> s.getCount() > 0) + .orderBy(asc(Statistics::getGroup), desc(count(Statistics::getGroup))) + .limit(HUNDRED) + .union() + .from(list(student("ivanov", LocalDate.parse("1985-08-06"), "496"))) + .selectDistinct(Statistics.class, s -> "all", + count(Student::getDateOfBith), avg(Student::age)) + .groupBy(Student::getGroup) + .execute(); + statistics.forEach(System.out::print); + + + Iterable> mentorsByStudent = + from(list(student("ivanov", LocalDate.parse("1985-08-06"), "496"), + student("sidorov", LocalDate.parse("1986-08-06"), "497"), + student("vasilev", LocalDate.parse("1986-08-06"), "496"), + student("petrov", LocalDate.parse("1986-08-06"), "497"))) + .join(list(Group.group("497", "mr.solovev"))) + .on((s, g) -> Objects.equals(s.getGroup(), g.getGroup())) + .select(sg -> sg.getFirst().getName(), sg -> sg.getSecond().getMentor()) + .where(s -> Objects.equals(s.getFirst().getName(), "sidorov")) + .union() + .from(list(student("ivanov", LocalDate.parse("1985-08-06"), "496"), + student("sidorov", LocalDate.parse("1986-08-06"), "497"), + student("vasilev", LocalDate.parse("1986-08-06"), "496"), + student("petrov", LocalDate.parse("1986-08-06"), "497"))) + .join(list(Group.group("496", "mr.ilanov"))) + .on(s -> s.getGroup(), f -> f.getGroup()) + .select(sg -> sg.getFirst().getName(), sg -> sg.getSecond().getMentor()) + .execute(); + mentorsByStudent.forEach(System.out::print); + } + + public static class Student { + private final String name; + + private final LocalDate dateOfBith; + + private final String group; + + public final String getName() { + return name; + } + + public Student(final String gottenName, final LocalDate gottenDateOfBith, final String gottenGroup) { + name = gottenName; + dateOfBith = gottenDateOfBith; + group = gottenGroup; + } + + public Student(final String gottenName, final String gottenGroup) { + name = gottenName; + dateOfBith = null; + group = gottenGroup; + } + + public final LocalDate getDateOfBith() { + return dateOfBith; + } + + public final String getGroup() { + return group; + } + + public final Double age() { + return (double) ChronoUnit.YEARS.between(getDateOfBith(), LocalDateTime.now()); + } + + public static Student student(final String name, final LocalDate dateOfBith, final String group) { + return new Student(name, dateOfBith, group); + } + + @Override + public final String toString() { + StringBuilder result = new StringBuilder().append("Student{"); + if (group != null) { + result.append("group='").append(group).append('\''); + } + if (name != null) { + result.append(", name=").append(name); + } + if (dateOfBith != null) { + result.append(", age=").append(dateOfBith); + } + result.append("}\n"); + return result.toString(); + } + } + + public static class Group { + private final String group; + private final String mentor; + + public Group(final String gottenGroup, final String gottenMentor) { + group = gottenGroup; + mentor = gottenMentor; + } + + public final String getGroup() { + return group; + } + + public final String getMentor() { + return mentor; + } + + public static Group group(final String ggroup, final String mmentor) { + return new Group(ggroup, mmentor); + } + + @Override + public final String toString() { + StringBuilder result = new StringBuilder().append("Student{"); + if (group != null) { + result.append("group='").append(group).append('\''); + } + if (mentor != null) { + result.append(", name=").append(mentor); + } + result.append("}\n"); + return result.toString(); + } + } + + + public static class Statistics { + + private final String group; + private final Integer count; + private final Double age; + + public final String getGroup() { + return group; + } + + public final Integer getCount() { + return count; + } + + public final Double getAge() { + return age; + } + + public Statistics(final String gottenGroup, final Integer gottenCount) { + group = gottenGroup; + count = gottenCount; + age = null; + } + + public Statistics(final String gottenGroup, final Integer gottenCount, final Double gottenAge) { + group = gottenGroup; + count = gottenCount; + age = gottenAge; + } + + public Statistics(final String gottenGroup) { + group = gottenGroup; + count = null; + age = null; + } + + @Override + public final String toString() { + StringBuilder result = new StringBuilder().append("Statistics{"); + if (group != null) { + result.append("group='").append(group).append('\''); + } + if (count != null) { + result.append(", count=").append(count); + } + if (age != null) { + result.append(", age=").append(age); + } + result.append("}\n"); + return result.toString(); + } + } + +} diff --git a/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/collectionquery/Conditions.java b/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/collectionquery/Conditions.java new file mode 100644 index 0000000..53b0b54 --- /dev/null +++ b/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/collectionquery/Conditions.java @@ -0,0 +1,14 @@ +package ru.mipt.diht.students.elinrin.collectionquery; + +import java.util.function.Function; +import java.util.function.Predicate; + +public class Conditions { + public static Predicate rlike(final Function expression, final String regexp) { + return element -> expression.apply(element).matches(regexp); + } + + public static Predicate like(final Function expression, final String pattern) { + throw new UnsupportedOperationException(); + } +} diff --git a/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/collectionquery/OrderByConditions.java b/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/collectionquery/OrderByConditions.java new file mode 100644 index 0000000..0b61963 --- /dev/null +++ b/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/collectionquery/OrderByConditions.java @@ -0,0 +1,16 @@ +package ru.mipt.diht.students.elinrin.collectionquery; + +import java.util.Comparator; +import java.util.function.Function; + +public final class OrderByConditions { + + public static > Comparator asc(final Function expression) { + return (o1, o2) -> expression.apply(o1).compareTo(expression.apply(o2)); + } + + public static > Comparator desc(final Function expression) { + return (o1, o2) -> expression.apply(o2).compareTo(expression.apply(o1)); + } + +} diff --git a/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/collectionquery/Sources.java b/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/collectionquery/Sources.java new file mode 100644 index 0000000..9f740d9 --- /dev/null +++ b/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/collectionquery/Sources.java @@ -0,0 +1,12 @@ +package ru.mipt.diht.students.elinrin.collectionquery; + +import java.util.Arrays; +import java.util.List; + +public class Sources { + + @SafeVarargs + public static List list(final T... items) { + return Arrays.asList(items); + } +} diff --git a/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/collectionquery/aggregatesImpl/Aggregator.java b/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/collectionquery/aggregatesImpl/Aggregator.java new file mode 100644 index 0000000..c5fc669 --- /dev/null +++ b/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/collectionquery/aggregatesImpl/Aggregator.java @@ -0,0 +1,9 @@ +package ru.mipt.diht.students.elinrin.collectionquery.aggregatesImpl; + +import java.util.List; +import java.util.function.Function; + + +public interface Aggregator extends Function { + C apply(List elements); +} diff --git a/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/collectionquery/aggregatesImpl/Avg.java b/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/collectionquery/aggregatesImpl/Avg.java new file mode 100644 index 0000000..d5d63ca --- /dev/null +++ b/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/collectionquery/aggregatesImpl/Avg.java @@ -0,0 +1,26 @@ +package ru.mipt.diht.students.elinrin.collectionquery.aggregatesImpl; + +import java.util.List; +import java.util.function.Function; + +public class Avg implements Aggregator { + + private Function function; + public Avg(final Function expression) { + function = expression; + } + + @Override + public final Double apply(final List elements) { + Double result = 0.0; + for (T element : elements) { + result += (Double) function.apply(element); + } + return result / elements.size(); + } + + @Override + public final Double apply(final T t) { + return null; + } +} diff --git a/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/collectionquery/aggregatesImpl/Count.java b/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/collectionquery/aggregatesImpl/Count.java new file mode 100644 index 0000000..1053414 --- /dev/null +++ b/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/collectionquery/aggregatesImpl/Count.java @@ -0,0 +1,29 @@ +package ru.mipt.diht.students.elinrin.collectionquery.aggregatesImpl; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.function.Function; + +public class Count implements Aggregator { + + private Function function; + public Count(final Function expression) { + function = expression; + } + + @Override + public final Integer apply(final List elements) { + Set distincted = new HashSet<>(); + for (T element : elements) { + if (!distincted.contains(function.apply(element))) { + distincted.add(function.apply(element)); + } + } + return distincted.size(); + } + @Override + public final Integer apply(final T t) { + return null; + } +} diff --git a/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/collectionquery/aggregatesImpl/Max.java b/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/collectionquery/aggregatesImpl/Max.java new file mode 100644 index 0000000..0f40bb5 --- /dev/null +++ b/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/collectionquery/aggregatesImpl/Max.java @@ -0,0 +1,31 @@ +package ru.mipt.diht.students.elinrin.collectionquery.aggregatesImpl; + +import java.util.List; +import java.util.function.Function; + +public class Max> implements Aggregator { + + private Function function; + public Max(final Function expression) { + function = expression; + } + + @Override + public final R apply(final List elements) { + if (elements.isEmpty()) { + return null; + } + T result = elements.get(0); + for (T element : elements) { + if (function.apply(result).compareTo(function.apply(element)) < 0) { + result = element; + } + } + return function.apply(result); + } + + @Override + public final R apply(final T t) { + return null; + } +} diff --git a/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/collectionquery/aggregatesImpl/Min.java b/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/collectionquery/aggregatesImpl/Min.java new file mode 100644 index 0000000..fa95a98 --- /dev/null +++ b/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/collectionquery/aggregatesImpl/Min.java @@ -0,0 +1,31 @@ +package ru.mipt.diht.students.elinrin.collectionquery.aggregatesImpl; + +import java.util.List; +import java.util.function.Function; + +public class Min> implements Aggregator { + + private Function function; + public Min(final Function expression) { + function = expression; + } + + @Override + public final R apply(final List elements) { + if (elements.isEmpty()) { + return null; + } + T result = elements.get(0); + for (T element : elements) { + if (function.apply(result).compareTo(function.apply(element)) > 0) { + result = element; + } + } + return function.apply(result); + } + + @Override + public final R apply(final T t) { + return null; + } +} diff --git a/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/collectionquery/impl/FromStmt.java b/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/collectionquery/impl/FromStmt.java new file mode 100644 index 0000000..cd2b65e --- /dev/null +++ b/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/collectionquery/impl/FromStmt.java @@ -0,0 +1,92 @@ +package ru.mipt.diht.students.elinrin.collectionquery.impl; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.function.BiPredicate; +import java.util.function.Function; +import java.util.stream.Collectors; + +public class FromStmt { + private List elements = new ArrayList<>(); + + public final List getElements() { + return elements; + } + + public FromStmt(final Iterable iterable) { + for (T curr : iterable) { + elements.add(curr); + } + } + + public static FromStmt from(final Iterable iterable) { + return new FromStmt<>(iterable); + } + + @SafeVarargs + public final SelectStmt select(final Class returnClass, final Function... functions) { + return new SelectStmt<>(elements, returnClass, false, functions); + } + + @SafeVarargs + public final SelectStmt selectDistinct(final Class returnClass, + final Function... functions) { + return new SelectStmt<>(elements, returnClass, true, functions); + } + + public final SelectStmt> select(final Function first, + final Function second) { + return new SelectStmt<>(elements, false, first, second); + } + + public final JoinClause join(final Iterable iterable) { + return new JoinClause<>(elements, iterable); + } + + public class JoinClause { + + private List firstElements = new ArrayList<>(); + private List secondElements = new ArrayList<>(); + private List> elements = new ArrayList<>(); + + public JoinClause(final List gottenFirstElements, final Iterable gottenSecondElements) { + firstElements.addAll(gottenFirstElements.stream().collect(Collectors.toList())); + for (J curr : gottenSecondElements) { + secondElements.add(curr); + } + } + + public final FromStmt> on(final BiPredicate condition) { + for (S first : firstElements) { + for (J second : secondElements) { + if (condition.test(first, second)) { + elements.add(new Tuple<>(first, second)); + } + } + } + return new FromStmt<>(elements); + } + + public final > FromStmt> on( + final Function leftKey, + final Function rightKey) { + HashMap> map = new HashMap<>(); + for (J element : secondElements) { + K key = rightKey.apply(element); + if (!map.containsKey(key)) { + map.put(key, new ArrayList<>()); + } + map.get(key).add(element); + } + for (S first : firstElements) { + K key = leftKey.apply(first); + if (map.containsKey(key)) { + List second = map.get(key); + second.forEach(s -> elements.add(new Tuple<>(first, s))); + } + } + return new FromStmt<>(elements); + } + } +} diff --git a/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/collectionquery/impl/SelectStmt.java b/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/collectionquery/impl/SelectStmt.java new file mode 100644 index 0000000..65104af --- /dev/null +++ b/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/collectionquery/impl/SelectStmt.java @@ -0,0 +1,284 @@ +package ru.mipt.diht.students.elinrin.collectionquery.impl; + +import javafx.util.Pair; +import ru.mipt.diht.students.elinrin.collectionquery.aggregatesImpl.Aggregator; + +import java.lang.reflect.InvocationTargetException; +import java.util.*; +import java.util.function.Function; +import java.util.function.Predicate; + +public class SelectStmt { + + public final boolean isDistinct() { + return isDistinct; + } + + public final Function[] getFunctions() { + return functions; + } + + public final Class getReturnClass() { + return returnClass; + } + + public final int getNumberOfObjects() { + return numberOfObjects; + } + + public final boolean isUnion() { + return isUnion; + } + + public final List getElements() { + return elements; + } + + private boolean isDistinct; + private Class returnClass; + private Function[] functions; + private List elements; + + private List pastElements; + + private Predicate whereCondition; + private Comparator[] comparators; + private Predicate havingCondition; + private int numberOfObjects; + private Function[] groupByConditions; + + private CQLComparator cqlComparator; + private boolean isUnion; + private boolean isJoin; + + @SafeVarargs + public SelectStmt(final List gottenElements, final Class gottenReturnClass, final boolean gottenIsDistinct, + final Function... gottenFunctions) { + elements = new ArrayList<>(); + for (T element : gottenElements) { + //System.out.println(element.toString()); + elements.add(element); + } + returnClass = gottenReturnClass; + isDistinct = gottenIsDistinct; + functions = gottenFunctions; + numberOfObjects = -1; + isUnion = false; + isJoin = false; + } + + public SelectStmt(final List gottenElements, final boolean gottenIsDistinct, final Function first, + final Function second) { + elements = new ArrayList<>(); + for (T element : gottenElements) { + //System.out.println(gottenElement.toString()); + elements.add(element); + } + returnClass = gottenElements.get(0).getClass(); + isDistinct = gottenIsDistinct; + functions = new Function[]{first, second}; + numberOfObjects = -1; + isUnion = false; + isJoin = true; + } + + @SafeVarargs + public SelectStmt(final List gottenPastElements, final List gottenElements, final Class gottenReturnClass, + final boolean gottenIsDistinct, final Function... gottenFunctions) { + elements = new ArrayList<>(); + for (T element : gottenElements) { + elements.add(element); + } + returnClass = gottenReturnClass; + isDistinct = gottenIsDistinct; + functions = gottenFunctions; + numberOfObjects = -1; + isUnion = true; + pastElements = gottenPastElements; + } + + public SelectStmt(final List gottenPastElements, final List gottenElements, final boolean gottenIsDistinct, + final Function first, final Function second) { + elements = new ArrayList<>(); + for (T element : gottenElements) { + //System.out.println(element.toString()); + elements.add(element); + } + returnClass = gottenElements.get(0).getClass(); + isDistinct = gottenIsDistinct; + functions = new Function[]{first, second}; + numberOfObjects = -1; + isUnion = true; + isJoin = true; + pastElements = gottenPastElements; + } + + public final SelectStmt where(final Predicate predicate) { + whereCondition = predicate; + return this; + } + + @SafeVarargs + public final SelectStmt groupBy(final Function... expressions) { + groupByConditions = expressions; + return this; + } + + @SafeVarargs + public final SelectStmt orderBy(final Comparator... gottenComparators) { + comparators = gottenComparators; + cqlComparator = new CQLComparator(comparators); + return this; + } + + public final SelectStmt having(final Predicate condition) { + havingCondition = condition; + return this; + } + + public final SelectStmt limit(final int amount) { + numberOfObjects = amount; + return this; + } + + public final Iterable execute() throws NoSuchMethodException, IllegalAccessException, + InvocationTargetException, InstantiationException { + List result = new ArrayList<>(); + Object[] arguments = new Object[functions.length]; + Class[] returnClasses = new Class[functions.length]; + if (whereCondition != null) { + List filtered = new ArrayList<>(); + elements.stream().filter(whereCondition::test).forEach(filtered::add); + elements = filtered; + } + if (groupByConditions != null) { + Map mapped = new HashMap<>(); + String[] results = new String[groupByConditions.length]; + List> grouped = new ArrayList<>(); + elements.stream().forEach( + element -> { + for (int i = 0; i < groupByConditions.length; i++) { + results[i] = (String) groupByConditions[i].apply(element); + } + if (!mapped.containsKey(Objects.hash(results))) { + mapped.put(Objects.hash(results), mapped.size()); + } + grouped.add(new Pair(element, mapped.get(Objects.hash(results)))); + } + ); + List> groupedElements = new ArrayList<>(); + for (int i = 0; i < mapped.size(); i++) { + groupedElements.add(new ArrayList()); + } + + for (Pair element : grouped) { + groupedElements.get(element.getValue()).add(element.getKey()); + } + for (List group : groupedElements) { + for (int i = 0; i < functions.length; i++) { + if (functions[i] instanceof Aggregator) { + arguments[i] = ((Aggregator) functions[i]).apply(group); + } else { + arguments[i] = functions[i].apply(group.get(0)); + } + returnClasses[i] = arguments[i].getClass(); + } + if (isJoin) { + Tuple newElement = new Tuple(arguments[0], arguments[1]); + result.add((R) newElement); + } else { + R newElement = (R) returnClass.getConstructor(returnClasses).newInstance(arguments); + result.add(newElement); + } + } + } else { + for (T element : this.elements) { + for (int i = 0; i < functions.length; i++) { + arguments[i] = functions[i].apply(element); + if (functions[i] instanceof Aggregator) { + List currArg = new ArrayList<>(); + currArg.add(element); + arguments[i] = ((Aggregator) functions[i]).apply(currArg); + } else { + arguments[i] = functions[i].apply(element); + } + returnClasses[i] = arguments[i].getClass(); + } + if (isJoin) { + Tuple newElement = new Tuple(arguments[0], arguments[1]); + result.add((R) newElement); + } else { + R newElement = (R) returnClass.getConstructor(returnClasses).newInstance(arguments); + result.add(newElement); + } + } + } + if (havingCondition != null) { + List filtered = new ArrayList<>(); + result.stream().filter(havingCondition::test).forEach(filtered::add); + result = filtered; + } + if (isDistinct) { + Set hashes = new HashSet<>(); + List flags = new ArrayList<>(); + for (R element : result) { + if (!hashes.contains(element.toString().hashCode())) { + flags.add(1); + hashes.add(element.toString().hashCode()); + } else { + flags.add(0); + } + } + List distincted = new ArrayList<>(); + for (int i = 0; i < result.size(); i++) { + if (flags.get(i) == 1) { + distincted.add(result.get(i)); + } + } + result = distincted; + } + if (comparators != null) { + result.sort(cqlComparator); + } + if (numberOfObjects != -1) { + while (result.size() > numberOfObjects) { + result.remove(result.size() - 1); + } + } + if (isUnion) { + pastElements.addAll(result); + result = pastElements; + } + //System.out.println("Hello!"); + return result; + } + + public final UnionStmt union() throws InvocationTargetException, NoSuchMethodException, + InstantiationException, IllegalAccessException { + List result = (List) this.execute(); + if (isJoin) { + return new UnionStmt<>(result, true); + } else { + return new UnionStmt<>(result); + } + } + + public class CQLComparator implements Comparator { + private Comparator[] comparators; + @SafeVarargs + public CQLComparator(final Comparator... gottenComparators) { + comparators = gottenComparators; + } + + @Override + public final int compare(final K first, final K second) { + for (Comparator comparator : comparators) { + if (comparator.compare(first, second) != 0) { + return comparator.compare(first, second); + } + } + return 0; + } + } + +} diff --git a/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/collectionquery/impl/Tuple.java b/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/collectionquery/impl/Tuple.java new file mode 100644 index 0000000..56e9c08 --- /dev/null +++ b/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/collectionquery/impl/Tuple.java @@ -0,0 +1,30 @@ +package ru.mipt.diht.students.elinrin.collectionquery.impl; + + +public class Tuple { + + private final F first; + private final S second; + + public Tuple(final F first1, final S second2) { + first = first1; + second = second2; + } + + public final F getFirst() { + return first; + } + + public final S getSecond() { + return second; + } + + @Override + public final String toString() { + return "Tuple{" + + "first=" + first + + ", second=" + second + + "}\n"; + } +} + diff --git a/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/collectionquery/impl/UnionStmt.java b/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/collectionquery/impl/UnionStmt.java new file mode 100644 index 0000000..018f185 --- /dev/null +++ b/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/collectionquery/impl/UnionStmt.java @@ -0,0 +1,123 @@ +package ru.mipt.diht.students.elinrin.collectionquery.impl; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.function.BiPredicate; +import java.util.function.Function; +import java.util.stream.Collectors; + +public class UnionStmt { + + private List pastElements = new ArrayList<>(); + + private boolean isTuple; + + public UnionStmt(final Iterable iterable) { + for (R curr : iterable) { + pastElements.add(curr); + } + isTuple = false; + } + + public UnionStmt(final Iterable iterable, final boolean gottenIsTuple) { + for (R curr : iterable) { + pastElements.add(curr); + } + isTuple = true; + } + + public final FromClause from(final Iterable elements) { + if (isTuple) { + return new FromClause<>(pastElements, elements); + } else { + return new FromClause<>(pastElements, elements); + } + } + + + public class FromClause { + private List pastElements = new ArrayList<>(); + + private List elements = new ArrayList<>(); + + public FromClause(final Iterable gottenPastElements, final Iterable gottenElements) { + for (Q curr : gottenPastElements) { + pastElements.add(curr); + } + for (S curr : gottenElements) { + elements.add(curr); + } + } + @SafeVarargs + public final SelectStmt select(final Class returnClass, final Function... functions) { + return new SelectStmt<>(pastElements, elements, returnClass, false, functions); + } + + public final SelectStmt> select(final Function first, final Function second) { + return new SelectStmt<>((List>) pastElements, elements, false, first, second); + } + + @SafeVarargs + public final SelectStmt selectDistinct(final Class returnClass, final Function... functions) { + return new SelectStmt<>(pastElements, elements, returnClass, true, functions); + } + + public final JoinClause join(final Iterable iterable) { + return new JoinClause<>(pastElements, elements, iterable); + } + } + + + public class JoinClause { + + private List firstElements = new ArrayList<>(); + private List secondElements = new ArrayList<>(); + private List pastElements = new ArrayList<>(); + private List> elements = new ArrayList<>(); + + public JoinClause(final List gottenPastElements, final List gottenFirstElements, + final Iterable gottenSecondElements) { + pastElements.addAll(gottenPastElements.stream().collect(Collectors.toList())); + firstElements.addAll(gottenFirstElements.stream().collect(Collectors.toList())); + for (J curr : gottenSecondElements) { + secondElements.add(curr); + } + //secondElements.forEach(System.out::print); + } + + public final FromClause, W> on(final BiPredicate condition) { + for (F first : firstElements) { + for (J second : secondElements) { + if (condition.test(first, second)) { + elements.add(new Tuple<>(first, second)); + } + } + } + //System.out.println(secondElements.get(0)); + //System.out.println(elements.get(0)); + return new FromClause<>(pastElements, elements); + } + + public final > FromClause, W> on( + final Function leftKey, + final Function rightKey) { + HashMap> map = new HashMap<>(); + for (J element : secondElements) { + K key = rightKey.apply(element); + if (!map.containsKey(key)) { + map.put(key, new ArrayList<>()); + } + map.get(key).add(element); + } + for (F first : firstElements) { + K key = leftKey.apply(first); + if (map.containsKey(key)) { + List second = map.get(key); + second.forEach(s -> elements.add(new Tuple<>(first, s))); + } + } + return new FromClause<>(pastElements, elements); + } + } +} diff --git a/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/miniorm/ClassConverter.java b/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/miniorm/ClassConverter.java new file mode 100644 index 0000000..52b0777 --- /dev/null +++ b/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/miniorm/ClassConverter.java @@ -0,0 +1,38 @@ +package ru.mipt.diht.students.elinrin.miniorm; + +import java.sql.Time; +import java.sql.Timestamp; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + + +public class +ClassConverter { + private static Map classes; + static { + classes = new HashMap<>(); + classes.put(Integer.class, "INTEGER"); + classes.put(Boolean.class, "BOOLEAN"); + classes.put(Byte.class, "TINYINT"); + classes.put(Short.class, "SMALLINT"); + classes.put(Long.class, "BIGINT"); + classes.put(Double.class, "DOUBLE"); + classes.put(Float.class, "FLOAT"); + classes.put(Time.class, "TIME"); + classes.put(Date.class, "DATE"); + classes.put(Timestamp.class, "TIMESTAMP"); + classes.put(Character.class, "CHAR"); + classes.put(String.class, "CLOB"); + classes.put(UUID.class, "UUID"); + } + + public static String convert(final Class currClass) { + if (classes.containsKey(currClass)) { + return classes.get(currClass); + } + return "OTHER"; + } + +} diff --git a/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/miniorm/DatabaseService.java b/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/miniorm/DatabaseService.java new file mode 100644 index 0000000..6151400 --- /dev/null +++ b/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/miniorm/DatabaseService.java @@ -0,0 +1,255 @@ +package ru.mipt.diht.students.elinrin.miniorm; +import com.google.common.base.CaseFormat; +import ru.mipt.diht.students.elinrin.miniorm.annotations.Column; +import ru.mipt.diht.students.elinrin.miniorm.annotations.PrimaryKey; +import ru.mipt.diht.students.elinrin.miniorm.annotations.Table; +import ru.mipt.diht.students.elinrin.miniorm.exception.HandlerOfException; + +import javax.management.OperationsException; +import java.lang.reflect.Field; +import java.sql.*; +import java.util.ArrayList; +import java.util.List; + +/* + +T queryById(K) - возвращает запись по первичному ключу +T queryForAll() - возвращает все записи из таблицы +void insert(T) - добавляет запись +void update(T) - редактирует запись по первичному ключу +void delete(T) - удаляет запись по первичному ключу +void createTable() - создаёт таблицу по метаданным класса T. См. аннотации ниже. +void dropTable() - удаляет таблицу, соответствующую T. Класс нужно покрыть модульными тестами. +*/ +public class DatabaseService { + //Классы JDSC + private Connection connection = null; + private Statement statement = null; + private ResultSet resultSet = null; + private Field primaryKey = null; + private List columns = null; + private Field[] fields; + private String[] namesOfColumns; + private Class tableClass = null; + private String tableName = ""; + private int primaryKeyFieldNumber = -1; + + private boolean hasTableYet = false; + + + /*protected void finalize ( ) throws SQLException { + resultSet.close(); + statement.close(); + connection.close(); + }*/ + + // DatabaseService(Class) - коструктор, принимает тип объекта, с которым хотим работать + DatabaseService(final Class elementClass) throws ClassNotFoundException, + SQLException, InstantiationException, IllegalAccessException { + + Class.forName("org.h2.Driver").newInstance(); + //путь к файлу с БД, соединение с драйверами БД + connection = DriverManager.getConnection("jdbc:h2:~/test", "test", "test"); + statement = connection.createStatement(); + + columns = new ArrayList<>(); + tableClass = elementClass; + Table table = tableClass.getAnnotation(Table.class); + if (table == null) { + throw new IllegalArgumentException("Class should be annotated with Table"); + } + tableName = table.name(); + if (tableName.equals("")) { + tableName = "MY_TABLE"; + } + int i = 0; + for (Field elem : tableClass.getDeclaredFields()) { + if (elem.getAnnotation(Column.class) != null) { + columns.add(elem); + } + if (elem.getAnnotation(PrimaryKey.class) != null) { + if (elem.getAnnotation(Column.class) == null) { + throw new IllegalArgumentException("Not all fields are columns"); + } + if (primaryKey != null) { + throw new IllegalArgumentException("Not one primary Key"); + } + primaryKey = elem; + primaryKeyFieldNumber = i; + } + ++i; + } + + resultSet = connection.getMetaData().getTables(null, null, + CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.UPPER_UNDERSCORE, tableName), null); + resultSet.next(); + } + public final T queryById(final K id) throws OperationsException, + SQLException, IllegalAccessException, InstantiationException { + if (!hasTableYet) { + throw new OperationsException("Для данного запроа необходимо создать таблицу"); + } + if (primaryKey == null) { + throw new OperationsException("Должен суущестовать первичный ключ"); + } + /*if (!id.getClass().isInstance(primaryKey.getType())){ + throw new IllegalArgumentException("Ключ должен иметь тот же тип, что и первичные ключи таблицы"); + }*/ + StringBuilder newRequest = new StringBuilder(); + newRequest.append("SELECT * FROM ").append(tableName).append(" WHERE ") + .append(columns.get(primaryKeyFieldNumber).getAnnotation(Column.class) + .name()).append(" = ").append(id.toString()); + resultSet = statement.executeQuery(newRequest.toString()); + List list = new ArrayList<>(); + while (resultSet.next()) { + T item = tableClass.newInstance(); + for (Field field: columns) { + if (field.getType().equals(Integer.class)) { + field.set(item, resultSet.getInt(field.getAnnotation(Column.class).name())); + } + if (field.getType().equals(String.class)) { + field.set(item, resultSet.getString(field.getAnnotation(Column.class).name())); + } + } + list.add(item); + } + if (list.size() == 0) { + return null; + } + if (list.size() > 1) { + throw new OperationsException("Ошибка получения результата"); + } + return list.get(0); + } + + final List queryForAll() throws OperationsException, SQLException, IllegalAccessException, + InstantiationException { + + if (!hasTableYet) { + throw new OperationsException("Для данного запроа необходимо создать таблицу"); + } + if (primaryKey == null) { + throw new OperationsException("Должен суущестовать первичный ключ"); + } + StringBuilder newRequest = new StringBuilder(); + newRequest.append("SELECT * FROM ").append(tableName); + resultSet = statement.executeQuery(newRequest.toString()); + List list = new ArrayList<>(); + while (resultSet.next()) { + T item = tableClass.newInstance(); + for (Field field: columns) { + if (field.getType().equals(Integer.class)) { + field.set(item, resultSet.getInt(field.getAnnotation(Column.class).name())); + } + if (field.getType().equals(String.class)) { + field.set(item, resultSet.getString(field.getAnnotation(Column.class).name())); + } + } + list.add(item); + } + return list; + } + + final void insert(final T key) throws SQLException { + StringBuilder newRequest = new StringBuilder(); + newRequest.append("INSERT INTO ").append(tableName).append(" VALUES("); + boolean first = true; + for (Field field:columns) { + if (!first) { + newRequest.append(", "); + } else { + first = false; + } + newRequest.append("?"); + } + newRequest.append(")"); + //System.out.println(newRequest); + PreparedStatement preparedStatement = connection.prepareStatement(newRequest.toString()); + + for (int i = 0; i < columns.size(); i++) { + try { + preparedStatement.setObject(i + 1, columns.get(i).get(key)); + } catch (IllegalAccessException e) { + HandlerOfException.handler(e); + } + } + //System.out.println(preparedStatement.toString()); + preparedStatement.execute(); + + } + + final void update(final T key) throws SQLException { + StringBuilder newRequest = new StringBuilder().append("UPDATE ").append(tableName).append(" SET "); + for (int i = 0; i < columns.size(); ++i) { + if (i != 0) { + newRequest.append(", "); + } + newRequest.append(columns.get(i).getAnnotation(Column.class).name()).append(" = ?"); + } + + newRequest.append(" WHERE ").append(columns.get(primaryKeyFieldNumber).getAnnotation(Column.class).name()) + .append(" = ?"); + PreparedStatement prepareStatement = connection.prepareStatement(newRequest.toString()); + for (int i = 0; i < columns.size(); i++) { + try { + prepareStatement.setObject(1, columns.get(i).get(key)); + prepareStatement.setObject(2, columns.get(primaryKeyFieldNumber).get(key)); + } catch (IllegalAccessException e) { + HandlerOfException.handler(e); + } + prepareStatement.execute(); + } + + + + } + + + final void delete(final T key) throws SQLException { + StringBuilder newRequest = new StringBuilder(); + newRequest.append("DELETE FROM ").append(tableName).append(columns.get(primaryKeyFieldNumber) + .getAnnotation(Column.class).name()).append(" = ").append("?"); + PreparedStatement preparedStatement = connection.prepareStatement(newRequest.toString()); + try { + preparedStatement.setObject(1, columns.get(primaryKeyFieldNumber).get(key)); + preparedStatement.execute(); + } catch (IllegalAccessException e) { + HandlerOfException.handler(e); + } + } + + final void createTable() throws OperationsException, SQLException { + if (hasTableYet) { + throw new OperationsException("Невозможно повторно создать таблицу"); + } + hasTableYet = true; + StringBuilder newRequest = new StringBuilder(); + newRequest.append("CREATE TABLE IF NOT EXISTS ").append(tableName).append(" ("); + int i = 0; + for (Field field : columns) { + //System.out.println(field.getType().toString()); + if (i != 0) { + newRequest.append(", "); + } + newRequest.append(field.getAnnotation(Column.class).name()).append(" "); + newRequest.append(ClassConverter.convert(columns.get(i).getType())).append(" "); + if (field.isAnnotationPresent(PrimaryKey.class)) { + newRequest.append("PRIMARY KEY"); + primaryKeyFieldNumber = i; + } + i++; + } + newRequest.append(") "); + //System.out.println(newRequest); + statement.execute(newRequest.toString()); + } + + final void dropTable() { + try { + statement.execute("DROP TABLE IF EXISTS " + tableName); + hasTableYet = false; + } catch (SQLException e) { + HandlerOfException.handler(e); + } + } +} diff --git a/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/miniorm/User.java b/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/miniorm/User.java new file mode 100644 index 0000000..8101341 --- /dev/null +++ b/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/miniorm/User.java @@ -0,0 +1,80 @@ +package ru.mipt.diht.students.elinrin.miniorm; + +/* +import ru.mipt.diht.students.elinrin.miniorm.annotations.Column; +import ru.mipt.diht.students.elinrin.miniorm.annotations.PrimaryKey; +import ru.mipt.diht.students.elinrin.miniorm.annotations.Table; +import ru.mipt.diht.students.elinrin.miniorm.exception.HandlerOfException; + +import javax.management.OperationsException; +import java.sql.SQLException; +import java.util.List; +import java.util.Objects; +*/ + + +public class User { + /*@Table(name = "TESTTABLE") + static class Tab { + @PrimaryKey + @Column(name = "ID") + Integer a; + + @Column(name = "STRING") + String s; + + @Override + public boolean equals(Object obj) { + if (obj instanceof Tab) { + return ((Objects.equals(this.a, ((Tab) obj).a)) && (Objects.equals(this.s, ((Tab) obj).s))); + } + return false; + } + + Tab(Object a, Object s) { + this.a = (Integer) a; + this.s = (String) s; + } + + Tab() { + this.a = 0; + this.s = ""; + } + + @Override + public String toString() { + StringBuilder result = new StringBuilder().append("Id = ").append(a).append(", String = ").append(s); + return result.toString(); + } + } + + public static void main(String[] argv) { + DatabaseService bd = null; + try { + bd = new DatabaseService(Tab.class); + } catch (ClassNotFoundException | IllegalAccessException | InstantiationException | SQLException e) { + HandlerOfException.handler(e); + } + + try { + bd.createTable(); + bd.insert(new Tab(1, "one")); + List all = bd.queryForAll(); + all.forEach(System.out::println); + + bd.insert(new Tab(2, "two")); + bd.insert(new Tab(3, "three")); + bd.insert(new Tab(4, "four")); + + Tab elem = bd.queryById(3); + System.out.println(elem); + + all = bd.queryForAll(); + all.forEach(System.out::println); + } catch (IllegalAccessException | InstantiationException | OperationsException | SQLException e) { + HandlerOfException.handler(e); + } finally { + bd.dropTable(); + } + }*/ +} diff --git a/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/miniorm/annotations/Column.java b/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/miniorm/annotations/Column.java new file mode 100644 index 0000000..cbb2322 --- /dev/null +++ b/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/miniorm/annotations/Column.java @@ -0,0 +1,13 @@ +package ru.mipt.diht.students.elinrin.miniorm.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(value = ElementType.FIELD) +@Retention(value = RetentionPolicy.RUNTIME) +public @interface Column { + String name() default ""; +} + diff --git a/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/miniorm/annotations/PrimaryKey.java b/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/miniorm/annotations/PrimaryKey.java new file mode 100644 index 0000000..6234828 --- /dev/null +++ b/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/miniorm/annotations/PrimaryKey.java @@ -0,0 +1,11 @@ +package ru.mipt.diht.students.elinrin.miniorm.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(value = ElementType.FIELD) +@Retention(value = RetentionPolicy.RUNTIME) +public @interface PrimaryKey { +} diff --git a/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/miniorm/annotations/Table.java b/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/miniorm/annotations/Table.java new file mode 100644 index 0000000..bc3a545 --- /dev/null +++ b/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/miniorm/annotations/Table.java @@ -0,0 +1,12 @@ +package ru.mipt.diht.students.elinrin.miniorm.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(value = ElementType.TYPE) +@Retention(value = RetentionPolicy.RUNTIME) +public @interface Table { + String name() default ""; +} diff --git a/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/miniorm/exception/HandlerOfException.java b/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/miniorm/exception/HandlerOfException.java new file mode 100644 index 0000000..57f24a1 --- /dev/null +++ b/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/miniorm/exception/HandlerOfException.java @@ -0,0 +1,23 @@ +package ru.mipt.diht.students.elinrin.miniorm.exception; + +public class HandlerOfException { + static final String USER_MOD = "user"; + + public static void handler(final String message, final Throwable cause) { + System.err.println(message + ". " + cause.getMessage()); + System.exit(1); + } + public static void handler(final Throwable cause) { + System.err.println(cause.getMessage()); + System.exit(1); + } + + public static void handler(final Throwable cause, final String mod) { + if (mod.equals(USER_MOD)) { + System.err.println(cause.getMessage()); + } else { + System.err.println(cause.getMessage()); + System.exit(1); + } + } +} diff --git a/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/threads/BlockingQueue.java b/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/threads/BlockingQueue.java new file mode 100644 index 0000000..2d9b413 --- /dev/null +++ b/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/threads/BlockingQueue.java @@ -0,0 +1,89 @@ +package ru.mipt.diht.students.elinrin.threads; + +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.List; +import java.util.Queue; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +public class BlockingQueue { + private int maxQueueSize; + private Queue queue; + private Lock queueLock = new ReentrantLock(); + private Lock offerLock = new ReentrantLock(); + private Lock takeLock = new ReentrantLock(); + private Object pushWait = new Object(); + private Object popWait = new Object(); + + public final void offer(final List list) { + offerLock.lock(); + try { + Integer last = 0; + while (last != list.size()) { + synchronized (popWait) { + while (queue.size() == maxQueueSize) { + try { + popWait.wait(); + } catch (InterruptedException e) { + System.err.println(e.getMessage()); + System.exit(1); + } + } + try { + queueLock.lock(); + while (last < Integer.min(last + maxQueueSize - queue.size(), list.size())) { + queue.add(list.get(last)); + last++; + } + } finally { + queueLock.unlock(); + } + } + } + } finally { + synchronized (pushWait) { + pushWait.notifyAll(); + } + offerLock.unlock(); + } + } + + public final List take(final int n) { + takeLock.lock(); + try { + List elements = new ArrayList<>(); + while (elements.size() != n) { + synchronized (pushWait) { + while (queue.size() == 0) { + try { + pushWait.wait(); + } catch (InterruptedException e) { + System.err.println(e.getMessage()); + System.exit(1); + } + } + try { + queueLock.lock(); + while (queue.size() > 0 && elements.size() != n) { + elements.add(queue.poll()); + } + } finally { + queueLock.unlock(); + } + } + } + return elements; + } finally { + synchronized (popWait) { + popWait.notifyAll(); + } + takeLock.unlock(); + } + } + + public BlockingQueue(final int maxSize) { + maxQueueSize = maxSize; + queue = new ArrayDeque<>(); + } +} diff --git a/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/threads/Counter.java b/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/threads/Counter.java new file mode 100644 index 0000000..8ae7c85 --- /dev/null +++ b/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/threads/Counter.java @@ -0,0 +1,49 @@ +package ru.mipt.diht.students.elinrin.threads; + +import ru.mipt.diht.students.elinrin.threads.exception.HandlerOfException; + + +public class Counter { + + private static volatile int printId; + + public static void main(final String[] args) { + int number; + number = Parse.parse(args); + + for (int id = 0; id < number; id++) { + CounterThread thread = new CounterThread(id, (id + 1) % number); + thread.start(); + } + } + + + private static Object working = new Object(); + + private static class CounterThread extends Thread { + private int threadId, nextThreadId; + + CounterThread(final int id1, final int id2) { + threadId = id1; + nextThreadId = id2; + } + + @Override + public void run() { + while (true) { + synchronized (working) { + while (threadId != printId) { + try { + working.wait(); + } catch (InterruptedException e) { + HandlerOfException.handler(e); + } + } + System.out.println("Thread-" + (threadId + 1)); + printId = nextThreadId; + working.notifyAll(); + } + } + } + } +} diff --git a/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/threads/Parse.java b/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/threads/Parse.java new file mode 100644 index 0000000..6ecfb93 --- /dev/null +++ b/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/threads/Parse.java @@ -0,0 +1,61 @@ +package ru.mipt.diht.students.elinrin.threads; + + +import ru.mipt.diht.students.elinrin.threads.exception.HandlerOfException; +import ru.mipt.diht.students.elinrin.threads.exception.UserException; + +import java.util.Scanner; + +import static java.lang.Thread.sleep; + +public class Parse { + + static final String USER_MOD = "user"; + static final int SLEEP_TIME = 500; + + private static int checkArgument(final String arguments) throws UserException { + int number; + try { + number = Integer.valueOf(arguments); + if (number <= 0) { + throw new UserException("Expected positive number"); + } else { + return number; + } + } catch (NumberFormatException e) { + throw new UserException("Expected integer number"); + } + } + + public static int parse(final String[] args) { + int number = 0; + if (args.length != 1) { + try (Scanner in = new Scanner(System.in)) { + while (true) { + System.out.print("$ Counter "); + String arguments = in.nextLine().trim(); + try { + number = checkArgument(arguments); + break; + } catch (UserException e) { + HandlerOfException.handler(e, USER_MOD); + try { + sleep(SLEEP_TIME); + } catch (InterruptedException e1) { + HandlerOfException.handler(e1); + } + } + } + } + } else { + try { + number = checkArgument(args[0]); + } catch (UserException e) { + HandlerOfException.handler(e); + } + } + return number; + } + + +} diff --git a/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/threads/Rollcall.java b/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/threads/Rollcall.java new file mode 100644 index 0000000..9260787 --- /dev/null +++ b/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/threads/Rollcall.java @@ -0,0 +1,78 @@ +package ru.mipt.diht.students.elinrin.threads; + +import ru.mipt.diht.students.elinrin.threads.exception.HandlerOfException; + +import java.util.Random; +import java.util.concurrent.BrokenBarrierException; +import java.util.concurrent.CyclicBarrier; + +public class Rollcall { + static final int NUMBER_EVENTS = 10; + + private static volatile boolean allSaidYes = false; + private static CyclicBarrier allReady, allAnswered; + + public static void main(final String[] args) { + int number; + number = Parse.parse(args); + + allReady = new CyclicBarrier(number + 1); + allAnswered = new CyclicBarrier(number + 1); + + for (int i = 0; i < number; i++) { + RollcallThread thread = new RollcallThread(); + thread.start(); + } + + while (!allSaidYes) { + System.out.println("Are you ready?"); + allSaidYes = true; + try { + allReady.await(); + } catch (InterruptedException | BrokenBarrierException e) { + HandlerOfException.handler(e); + } + allReady.reset(); + try { + allAnswered.await(); + } catch (InterruptedException | BrokenBarrierException e) { + HandlerOfException.handler(e); + } + allAnswered.reset(); + + if (allSaidYes) { + System.exit(0); + } + } + } + + private static class RollcallThread extends Thread { + private Boolean answer; + private Random rand = new Random(); + + @Override + public void run() { + while (true) { + try { + allReady.await(); + } catch (InterruptedException | BrokenBarrierException e) { + HandlerOfException.handler(e); + } + answer = rand.nextInt(NUMBER_EVENTS) != 0; + if (answer) { + System.out.println("Yes"); + } else { + System.out.println("No"); + } + if (!answer) { + allSaidYes = false; + } + try { + allAnswered.await(); + } catch (InterruptedException | BrokenBarrierException e) { + HandlerOfException.handler(e); + } + } + } + } +} diff --git a/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/threads/exception/HandlerOfException.java b/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/threads/exception/HandlerOfException.java new file mode 100644 index 0000000..4967b09 --- /dev/null +++ b/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/threads/exception/HandlerOfException.java @@ -0,0 +1,23 @@ +package ru.mipt.diht.students.elinrin.threads.exception; + +public class HandlerOfException { + static final String USER_MOD = "user"; + + public static void handler(final String message, final Throwable cause) { + System.err.println(message + ". " + cause.getMessage()); + System.exit(1); + } + public static void handler(final Throwable cause) { + System.err.println(cause.getMessage()); + System.exit(1); + } + + public static void handler(final Throwable cause, final String mod) { + if (mod.equals(USER_MOD)) { + System.err.println(cause.getMessage()); + } else { + System.err.println(cause.getMessage()); + System.exit(1); + } + } +} diff --git a/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/threads/exception/UserException.java b/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/threads/exception/UserException.java new file mode 100644 index 0000000..da07f59 --- /dev/null +++ b/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/threads/exception/UserException.java @@ -0,0 +1,9 @@ +package ru.mipt.diht.students.elinrin.threads.exception; + +public class UserException extends Exception { + + public UserException(final String message) { + super(message); + } +} + diff --git a/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/twitterstream/InteractiveParse.java b/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/twitterstream/InteractiveParse.java new file mode 100644 index 0000000..bb3238a --- /dev/null +++ b/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/twitterstream/InteractiveParse.java @@ -0,0 +1,47 @@ +package ru.mipt.diht.students.elinrin.twitterstream; + +import ru.mipt.diht.students.elinrin.twitterstream.exception.HandlerOfException; +import ru.mipt.diht.students.elinrin.twitterstream.commands.Commands; + +import java.util.NoSuchElementException; +import java.util.Scanner; + +public class InteractiveParse { + static final String USER_MOD = "user"; + + public static void parse(final TwitterProvider twitterPr) { + Scanner in = new Scanner(System.in); + try { + while (true) { + System.out.print("$ "); + String arguments; + arguments = in.nextLine(); + arguments = arguments.trim(); + String[] current = arguments.split("\\s+"); + for (String argument : current) { + argument.trim(); + } + try { + Commands command = Commands.fromString(current); + command.execute(twitterPr); + } catch (NoSuchElementException e) { + HandlerOfException.handler(e, USER_MOD); + } + } + } catch (IllegalMonitorStateException e) { + if (e.getMessage().equals("Exit")) { + in.close(); + System.out.println("Goodbye"); + System.exit(0); + } else { + HandlerOfException.handler(e); + } + } catch (NoSuchElementException e) { + HandlerOfException.handler(e); + } catch (Exception e) { + in.close(); + HandlerOfException.handler(e); + } + in.close(); + } +} diff --git a/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/twitterstream/PackageParse.java b/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/twitterstream/PackageParse.java new file mode 100644 index 0000000..a4c0bf1 --- /dev/null +++ b/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/twitterstream/PackageParse.java @@ -0,0 +1,50 @@ +package ru.mipt.diht.students.elinrin.twitterstream; + + +import ru.mipt.diht.students.elinrin.twitterstream.exception.HandlerOfException; +import ru.mipt.diht.students.elinrin.twitterstream.commands.Commands; + +import java.util.ArrayList; +import java.util.NoSuchElementException; + +public class PackageParse { + static final String USER_MOD = "user"; + + public static void parse(final TwitterProvider twitterPr, final String[] args) { + + + try { + ArrayList current = new ArrayList<>(); + for (int i = 0; i < args.length; ++i) { + current.clear(); + while (i < args.length) { + if (!(args[i].contains(";"))) { + current.add(args[i]); + i++; + } else { + current.add(args[i].substring(0, args[i].indexOf(";"))); + break; + } + } + if (current.isEmpty()) { + return; + } + String[] com = new String[current.size()]; + com = current.toArray(com); + try { + Commands command = Commands.fromString(com); + command.execute(twitterPr); + } catch (NoSuchElementException e) { + HandlerOfException.handler(e, USER_MOD); + } + } + } catch (IllegalMonitorStateException e) { + System.out.println("Goodbye"); + System.exit(0); + } catch (IllegalArgumentException e) { + HandlerOfException.handler("Wrong arguments", e); + } catch (Exception e) { + HandlerOfException.handler(e); + } + } +} diff --git a/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/twitterstream/PrintTweet.java b/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/twitterstream/PrintTweet.java new file mode 100644 index 0000000..3139321 --- /dev/null +++ b/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/twitterstream/PrintTweet.java @@ -0,0 +1,115 @@ +package ru.mipt.diht.students.elinrin.twitterstream; + +import twitter4j.Status; + +import java.time.Duration; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.util.Date; + +import static java.lang.Math.abs; + +public class PrintTweet { + + static final int LENGTH = 170; + static final int MIN_MOD = 1; + static final int HOUR_MOD = 2; + static final int DAY_MOD = 3; + static final int RETWEET_MOD = 0; + + static final int NOUN_FORM_1 = 0; + static final int NOUN_FORM_2 = 1; + static final int NOUN_FORM_3 = 2; + + static final int ONE = 1; + static final int FIVE = 5; + static final int TEN = 10; + static final int TWENTY = 20; + static final int HUNDRED = 100; + + + static final String BLUE = "\033[34m"; + static final String BLACK = "\033[0m"; + + + static final String[][] NOUN_FORM = { + {"ретвит", "ретвита", "ретвитов" }, + {"минута", "минуты", "минут" }, + {"час", "часа", "часов" }, + {"день", "дня", "дней"} + }; + + public static int pluralForm(final long num) { + long numeral = abs(num) % HUNDRED; + if (numeral > TEN && numeral < TWENTY) { + return NOUN_FORM_3; + } + if ((numeral % TEN) > ONE && (numeral % TEN) < FIVE) { + return NOUN_FORM_2; + } + if ((numeral % TEN) == ONE) { + return NOUN_FORM_1; + } + return NOUN_FORM_3; + } + + public static String tweetDate(final Date givenDate) { + + StringBuilder result = new StringBuilder().append("[ "); + + LocalDateTime givenTime = LocalDateTime.ofInstant(givenDate.toInstant(), ZoneId.systemDefault()); + LocalDateTime nowTime = LocalDateTime.now(); + Duration goneTime = Duration.between(givenTime, nowTime); + + if (goneTime.toMinutes() < 2) { + result.append("Только что"); + } else if (goneTime.toHours() <= 0) { + result.append(goneTime.toMinutes()).append(" ") + .append(NOUN_FORM[MIN_MOD][pluralForm(goneTime.toMinutes())]).append(" назад"); + } else if (goneTime.toDays() <= 0) { + result.append(goneTime.toHours()).append(" ") + .append(NOUN_FORM[HOUR_MOD][pluralForm(goneTime.toHours())]).append(" назад"); + } else if (goneTime.toDays() == 1) { + result.append("Вчера"); + } else { + result.append(goneTime.toDays()).append(" ") + .append(NOUN_FORM[DAY_MOD][pluralForm(goneTime.toDays())]).append(" назад"); + } + return result.append(" ] ").toString(); + } + + public static String print(final Status tweet, final boolean stream) { + StringBuilder result = new StringBuilder(); + + if (!stream) { + result.append(tweetDate(tweet.getCreatedAt())); + } + + result.append(printUserName(tweet)); + + if (tweet.isRetweet()) { + result.append("ретвитнул ").append(printUserName(tweet.getRetweetedStatus())) + .append(tweet.getRetweetedStatus().getText()); + } else { + result.append(tweet.getText()); + } + if (!tweet.isRetweet() && tweet.getRetweetCount() != 0) { + result.append(" (").append(tweet.getRetweetCount()).append(" ") + .append(NOUN_FORM[RETWEET_MOD][pluralForm(tweet.getRetweetCount())]).append(")"); + } + + result.append("\n"); + for (int i = 0; i < LENGTH; i++) { + result.append("-"); + } + + return result.toString(); + } + + public static String printUserName(final Status tweet) { + String result = "@" + BLUE + tweet.getUser().getScreenName() + + BLACK + ": "; + return result; + } + +} diff --git a/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/twitterstream/RunTwitter.java b/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/twitterstream/RunTwitter.java new file mode 100644 index 0000000..6e9dc03 --- /dev/null +++ b/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/twitterstream/RunTwitter.java @@ -0,0 +1,24 @@ +package ru.mipt.diht.students.elinrin.twitterstream; + +import ru.mipt.diht.students.elinrin.twitterstream.exception.HandlerOfException; +import twitter4j.Twitter; +import twitter4j.TwitterFactory; + +public class RunTwitter { + public static void main(final String[] args) { + + + + try { + Twitter twitter = new TwitterFactory().getInstance(); + TwitterProvider twitterPr = new TwitterProvider(twitter); + if (args.length == 0) { + InteractiveParse.parse(twitterPr); + } else { + PackageParse.parse(twitterPr, args); + } + } catch (IllegalArgumentException e) { + HandlerOfException.handler(e); + } + } +} diff --git a/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/twitterstream/TwitterProvider.java b/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/twitterstream/TwitterProvider.java new file mode 100644 index 0000000..1572be6 --- /dev/null +++ b/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/twitterstream/TwitterProvider.java @@ -0,0 +1,40 @@ +package ru.mipt.diht.students.elinrin.twitterstream; + + +import twitter4j.Twitter; + +public class TwitterProvider { + private Twitter twitter; + private boolean hideRetweets; + private String place; + + public TwitterProvider(final Twitter twitterUser) { + + twitter = twitterUser; + hideRetweets = false; + place = " "; + } + + public final void changeParameterRetweets(final boolean parameter) { + hideRetweets = parameter; + } + + public final void changeParameterPlase(final String parameter) { + place = parameter; + } + + + public final Twitter twitter() { + return twitter; + } + + public final boolean isHideRetweets() { + return hideRetweets; + } + + public final String getPlace() { + return place; + } + + +} diff --git a/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/twitterstream/commands/Commands.java b/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/twitterstream/commands/Commands.java new file mode 100644 index 0000000..2b598e6 --- /dev/null +++ b/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/twitterstream/commands/Commands.java @@ -0,0 +1,54 @@ +package ru.mipt.diht.students.elinrin.twitterstream.commands; + + +import ru.mipt.diht.students.elinrin.twitterstream.TwitterProvider; + +import java.util.HashMap; +import java.util.NoSuchElementException; + +public abstract class Commands { + private static final HashMap COMMANDS; + static { + COMMANDS = new HashMap<>(); + COMMANDS.put("--query", new QueryCommand()); + COMMANDS.put("-q", new QueryCommand()); + COMMANDS.put("--place", new PlaceCommand()); + COMMANDS.put("-p", new PlaceCommand()); + COMMANDS.put("--stream", new StreamCommand()); + COMMANDS.put("-s", new StreamCommand()); + COMMANDS.put("--hideRetweets", new HideCommand()); + COMMANDS.put("-hRtws", new HideCommand()); + COMMANDS.put("--limit", new LimitCommand()); + COMMANDS.put("-l", new LimitCommand()); + COMMANDS.put("--help", new HelpCommand()); + COMMANDS.put("-h", new HelpCommand()); + COMMANDS.put("-e", new ExitCommand()); + COMMANDS.put("-exit", new ExitCommand()); + } + + public static Commands fromString(final String[] arguments) { + if (arguments[0].equals("")) { + throw new NoSuchElementException(""); + } + + if (COMMANDS.containsKey(arguments[0])) { + Commands command = COMMANDS.get(arguments[0]); + if (arguments.length - 1 != command.numberOfArguments()) { + throw new NoSuchElementException("Unexpected number of arguments: " + + command.numberOfArguments() + " required"); + } + + command.putArguments(arguments); + return command; + } else { + throw new NoSuchElementException(arguments[0] + " is unknown command"); + } + } + + public abstract void execute(TwitterProvider twitter); + + protected void putArguments(final String[] args) { + } + + protected abstract int numberOfArguments(); +} diff --git a/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/twitterstream/commands/ExitCommand.java b/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/twitterstream/commands/ExitCommand.java new file mode 100644 index 0000000..c2d029e --- /dev/null +++ b/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/twitterstream/commands/ExitCommand.java @@ -0,0 +1,16 @@ +package ru.mipt.diht.students.elinrin.twitterstream.commands; + +import ru.mipt.diht.students.elinrin.twitterstream.TwitterProvider; + +public class ExitCommand extends Commands { + + @Override + public final void execute(final TwitterProvider twitter) { + throw new IllegalMonitorStateException("Exit"); + } + + @Override + protected final int numberOfArguments() { + return 0; + } +} diff --git a/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/twitterstream/commands/HelpCommand.java b/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/twitterstream/commands/HelpCommand.java new file mode 100644 index 0000000..3b39442 --- /dev/null +++ b/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/twitterstream/commands/HelpCommand.java @@ -0,0 +1,39 @@ +package ru.mipt.diht.students.elinrin.twitterstream.commands; + +import ru.mipt.diht.students.elinrin.twitterstream.TwitterProvider; + +public class HelpCommand extends Commands { + static final String LIGHT_BLUE = "\033[36m"; + static final String PURPLE = "\033[35m"; + static final String BLACK = "\033[0m"; + + @Override + public final void execute(final TwitterProvider twitter) { + + System.out.println(PURPLE + "Параметры\n" + + LIGHT_BLUE + "stream " + BLACK + + "- равномерно и непрерывно с задержкой в 1 секунду печатает твиты на экран. [--stream|-s]\n" + + LIGHT_BLUE + "limit " + BLACK + + "- n твитов. [--limit|-l ]\n" + + LIGHT_BLUE + "query " + BLACK + + " - поиск по заданному запросу. [--query|-q )]\n" + + LIGHT_BLUE + "place " + BLACK + + "- поиск по заданному региону. [--place|-p ]\n" + + LIGHT_BLUE + "allPlace " + BLACK + + "- отменить place режим. [--place|-p 0]\n" + + LIGHT_BLUE + "hideRetweets " + BLACK + + "- филтр ретвитов. [--hideRetweets|-hRtws +]\n" + + LIGHT_BLUE + "Retweets " + BLACK + + "- отменить hideRetweets режим. [--hideRetweets|-hRtws -]\n" + + LIGHT_BLUE + "help " + BLACK + + "- печатает справку. [--help|-h]\n" + + LIGHT_BLUE + "exit " + BLACK + + "- выход. [--exit|-e]\n"); + + } + + @Override + protected final int numberOfArguments() { + return 0; + } +} diff --git a/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/twitterstream/commands/HideCommand.java b/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/twitterstream/commands/HideCommand.java new file mode 100644 index 0000000..c86a1c6 --- /dev/null +++ b/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/twitterstream/commands/HideCommand.java @@ -0,0 +1,32 @@ +package ru.mipt.diht.students.elinrin.twitterstream.commands; + + +import ru.mipt.diht.students.elinrin.twitterstream.TwitterProvider; + +import java.util.NoSuchElementException; + +public class HideCommand extends Commands { + private String parameter; + @Override + public final void execute(final TwitterProvider twitterPr) { + if (parameter.equals("+")) { + twitterPr.changeParameterRetweets(true); + } else { + twitterPr.changeParameterRetweets(false); + } + } + + @Override + protected final int numberOfArguments() { + return 1; + } + + @Override + protected final void putArguments(final String[] args) { + if (!((args[1].equals("+")) || (args[1].equals("-")))) { + throw new NoSuchElementException("Wrong second arguments. Expected + or -. "); + } + parameter = args[1]; + } + +} diff --git a/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/twitterstream/commands/LimitCommand.java b/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/twitterstream/commands/LimitCommand.java new file mode 100644 index 0000000..1aea04b --- /dev/null +++ b/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/twitterstream/commands/LimitCommand.java @@ -0,0 +1,46 @@ +package ru.mipt.diht.students.elinrin.twitterstream.commands; + +import ru.mipt.diht.students.elinrin.twitterstream.TwitterProvider; +import ru.mipt.diht.students.elinrin.twitterstream.exception.HandlerOfException; +import ru.mipt.diht.students.elinrin.twitterstream.PrintTweet; +import twitter4j.Status; +import twitter4j.TwitterException; + +import java.util.List; + +public class LimitCommand extends Commands { + private int number; + + @Override + public final void execute(final TwitterProvider twitterPr) { + + + List statusList = null; + try { + statusList = twitterPr.twitter().getHomeTimeline(); + + } catch (TwitterException e) { + HandlerOfException.handler(e); + } + for (Status status: statusList) { + if ((!twitterPr.isHideRetweets()) || !(status.isRetweet())) { + System.out.println(new PrintTweet().print(status, false)); + } + number -= 1; + if (number == 0) { + break; + } + } + + } + + @Override + protected final int numberOfArguments() { + return 1; + } + + @Override + protected final void putArguments(final String[] args) { + number = Integer.parseInt(args[1]); + } +} diff --git a/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/twitterstream/commands/PlaceCommand.java b/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/twitterstream/commands/PlaceCommand.java new file mode 100644 index 0000000..1bf62b2 --- /dev/null +++ b/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/twitterstream/commands/PlaceCommand.java @@ -0,0 +1,26 @@ +package ru.mipt.diht.students.elinrin.twitterstream.commands; + + +import ru.mipt.diht.students.elinrin.twitterstream.TwitterProvider; + +public class PlaceCommand extends Commands { + + private String searchPlace; + + @Override + public final void execute(final TwitterProvider twitterPr) { + + twitterPr.changeParameterPlase(searchPlace); + + } + + @Override + protected final int numberOfArguments() { + return 1; + } + + @Override + protected final void putArguments(final String[] args) { + searchPlace = args[1]; + } +} diff --git a/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/twitterstream/commands/QueryCommand.java b/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/twitterstream/commands/QueryCommand.java new file mode 100644 index 0000000..99f7c86 --- /dev/null +++ b/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/twitterstream/commands/QueryCommand.java @@ -0,0 +1,43 @@ +package ru.mipt.diht.students.elinrin.twitterstream.commands; + +import ru.mipt.diht.students.elinrin.twitterstream.TwitterProvider; +import ru.mipt.diht.students.elinrin.twitterstream.exception.HandlerOfException; +import ru.mipt.diht.students.elinrin.twitterstream.PrintTweet; +import twitter4j.Query; +import twitter4j.QueryResult; +import twitter4j.Status; +import twitter4j.TwitterException; + +public class QueryCommand extends Commands { + + private String searchString; + + @Override + public final void execute(final TwitterProvider twitterPr) { + + Query query = new Query(searchString); + QueryResult result = null; + try { + result = twitterPr.twitter().search(query); + } catch (TwitterException e) { + HandlerOfException.handler(e); + } + for (Status status : result.getTweets()) { + if ((!twitterPr.isHideRetweets()) || !(status.isRetweet())) { + System.out.println(new PrintTweet().print(status, false)); + + } + } + + } + + @Override + protected final int numberOfArguments() { + return 1; + } + + @Override + protected final void putArguments(final String[] args) { + searchString = args[1]; + } +} diff --git a/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/twitterstream/commands/StreamCommand.java b/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/twitterstream/commands/StreamCommand.java new file mode 100644 index 0000000..9e77163 --- /dev/null +++ b/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/twitterstream/commands/StreamCommand.java @@ -0,0 +1,43 @@ +package ru.mipt.diht.students.elinrin.twitterstream.commands; + +import ru.mipt.diht.students.elinrin.twitterstream.PrintTweet; +import ru.mipt.diht.students.elinrin.twitterstream.TwitterProvider; +import ru.mipt.diht.students.elinrin.twitterstream.exception.HandlerOfException; +import twitter4j.Status; +import twitter4j.TwitterException; + +import java.util.List; + +import static java.lang.Thread.sleep; + +public class StreamCommand extends Commands { + + static final int SLEEP_TIME = 1000; + @Override + public final void execute(final TwitterProvider twitterPr) { + + List statusList = null; + try { + statusList = twitterPr.twitter().getHomeTimeline(); + } catch (TwitterException e) { + HandlerOfException.handler(e); + } + for (Status status: statusList) { + if ((!twitterPr.isHideRetweets()) || !(status.isRetweet())) { + System.out.println(new PrintTweet().print(status, false)); + } + + try { + sleep(SLEEP_TIME); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + + @Override + protected final int numberOfArguments() { + return 0; + } + +} diff --git a/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/twitterstream/exception/HandlerOfException.java b/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/twitterstream/exception/HandlerOfException.java new file mode 100644 index 0000000..a057f1a --- /dev/null +++ b/projects/elinrin/src/main/java/ru/mipt/diht/students/elinrin/twitterstream/exception/HandlerOfException.java @@ -0,0 +1,23 @@ +package ru.mipt.diht.students.elinrin.twitterstream.exception; + +public class HandlerOfException { + static final String USER_MOD = "user"; + + public static void handler(final String message, final Throwable cause) { + System.err.println(message + ". " + cause.getMessage()); + System.exit(1); + } + public static void handler(final Throwable cause) { + System.err.println(cause.getMessage()); + System.exit(1); + } + + public static void handler(final Throwable cause, final String mod) { + if (mod.equals(USER_MOD)) { + System.err.println(cause.getMessage()); + } else { + System.err.println(cause.getMessage()); + System.exit(1); + } + } +} diff --git a/projects/elinrin/src/main/resources/yandexAnswer b/projects/elinrin/src/main/resources/yandexAnswer new file mode 100644 index 0000000..2544611 --- /dev/null +++ b/projects/elinrin/src/main/resources/yandexAnswer @@ -0,0 +1 @@ +{"response":{"GeoObjectCollection":{"metaDataProperty":{"GeocoderResponseMetaData":{"request":"Москва","found":"54","results":"10"}},"featureMember":[{"GeoObject":{"metaDataProperty":{"GeocoderMetaData":{"kind":"locality","text":"Россия, Москва","precision":"other","AddressDetails":{"Country":{"AddressLine":"Москва","CountryNameCode":"RU","CountryName":"Россия","AdministrativeArea":{"AdministrativeAreaName":"Центральный федеральный округ","SubAdministrativeArea":{"SubAdministrativeAreaName":"Москва","Locality":{"LocalityName":"Москва"}}}}}}},"description":"Россия","name":"Москва","boundedBy":{"Envelope":{"lowerCorner":"37.32624 55.491126","upperCorner":"37.967682 55.957565"}},"Point":{"pos":"37.620393 55.753960"}}},{"GeoObject":{"metaDataProperty":{"GeocoderMetaData":{"kind":"hydro","text":"Россия, река Москва","precision":"other","AddressDetails":{"Country":{"AddressLine":"река Москва","CountryNameCode":"RU","CountryName":"Россия","AdministrativeArea":{"AdministrativeAreaName":"Центральный федеральный округ","Locality":{"Premise":{"PremiseName":"река Москва"}}}}}}},"description":"Россия","name":"река Москва","boundedBy":{"Envelope":{"lowerCorner":"35.27093 55.073809","upperCorner":"38.847968 55.83022"}},"Point":{"pos":"37.049280 55.709449"}}},{"GeoObject":{"metaDataProperty":{"GeocoderMetaData":{"kind":"hydro","text":"Узбекистан, Канал Москва","precision":"other","AddressDetails":{"Country":{"AddressLine":"Канал Москва","CountryNameCode":"UZ","CountryName":"Узбекистан","Locality":{"Premise":{"PremiseName":"Канал Москва"}}}}}},"description":"Узбекистан","name":"Канал Москва","boundedBy":{"Envelope":{"lowerCorner":"66.359835 39.121034","upperCorner":"66.552838 39.588246"}},"Point":{"pos":"66.385751 39.335933"}}},{"GeoObject":{"metaDataProperty":{"GeocoderMetaData":{"kind":"street","text":"Россия, Саратовская область, Романовский район, село Усть-Щербедино, улица Москва","precision":"street","AddressDetails":{"Country":{"AddressLine":"Саратовская область, Романовский район, село Усть-Щербедино, улица Москва","CountryNameCode":"RU","CountryName":"Россия","AdministrativeArea":{"AdministrativeAreaName":"Саратовская область","SubAdministrativeArea":{"SubAdministrativeAreaName":"Романовский район","Locality":{"LocalityName":"село Усть-Щербедино","Thoroughfare":{"ThoroughfareName":"улица Москва"}}}}}}}},"description":"село Усть-Щербедино, Романовский район, Саратовская область, Россия","name":"улица Москва","boundedBy":{"Envelope":{"lowerCorner":"42.870552 51.849693","upperCorner":"42.871019 51.86548"}},"Point":{"pos":"42.870830 51.857587"}}},{"GeoObject":{"metaDataProperty":{"GeocoderMetaData":{"kind":"street","text":"Россия, М-11","precision":"street","AddressDetails":{"Country":{"AddressLine":"М-11","CountryNameCode":"RU","CountryName":"Россия","Thoroughfare":{"ThoroughfareName":"М-11"}}}}},"description":"Россия","name":"М-11","boundedBy":{"Envelope":{"lowerCorner":"30.327744 55.886902","upperCorner":"37.486535 59.809473"}},"Point":{"pos":"33.945933 57.922779"}}},{"GeoObject":{"metaDataProperty":{"GeocoderMetaData":{"kind":"street","text":"Россия, М-10 Россия","precision":"street","AddressDetails":{"Country":{"AddressLine":"М-10 Россия","CountryNameCode":"RU","CountryName":"Россия","Thoroughfare":{"ThoroughfareName":"М-10 Россия"}}}}},"description":"Россия","name":"М-10 Россия","boundedBy":{"Envelope":{"lowerCorner":"30.371348 55.881662","upperCorner":"37.445069 59.816197"}},"Point":{"pos":"33.882530 57.793519"}}},{"GeoObject":{"metaDataProperty":{"GeocoderMetaData":{"kind":"street","text":"Россия, М-4 Дон","precision":"street","AddressDetails":{"Country":{"AddressLine":"М-4 Дон","CountryNameCode":"RU","CountryName":"Россия","Thoroughfare":{"ThoroughfareName":"М-4 Дон"}}}}},"description":"Россия","name":"М-4 Дон","boundedBy":{"Envelope":{"lowerCorner":"37.682485 44.353395","upperCorner":"40.638095 55.576391"}},"Point":{"pos":"40.138820 50.367517"}}},{"GeoObject":{"metaDataProperty":{"GeocoderMetaData":{"kind":"street","text":"Россия, М-9 Балтия","precision":"street","AddressDetails":{"Country":{"AddressLine":"М-9 Балтия","CountryNameCode":"RU","CountryName":"Россия","Thoroughfare":{"ThoroughfareName":"М-9 Балтия"}}}}},"description":"Россия","name":"М-9 Балтия","boundedBy":{"Envelope":{"lowerCorner":"28.193796 55.774431","upperCorner":"37.37271 56.381779"}},"Point":{"pos":"32.810076 56.266207"}}},{"GeoObject":{"metaDataProperty":{"GeocoderMetaData":{"kind":"street","text":"Россия, Новосибирская область, Краснозерский район, село Лобино, улица Москва","precision":"street","AddressDetails":{"Country":{"AddressLine":"Новосибирская область, Краснозерский район, село Лобино, улица Москва","CountryNameCode":"RU","CountryName":"Россия","AdministrativeArea":{"AdministrativeAreaName":"Новосибирская область","SubAdministrativeArea":{"SubAdministrativeAreaName":"Краснозерский район","Locality":{"LocalityName":"село Лобино","Thoroughfare":{"ThoroughfareName":"улица Москва"}}}}}}}},"description":"село Лобино, Краснозерский район, Новосибирская область, Россия","name":"улица Москва","boundedBy":{"Envelope":{"lowerCorner":"79.025397 53.853407","upperCorner":"79.032072 53.863057"}},"Point":{"pos":"79.028694 53.858203"}}},{"GeoObject":{"metaDataProperty":{"GeocoderMetaData":{"kind":"street","text":"Россия, Тамбовская область, Тамбовский район, село Куксово, улица Москва","precision":"street","AddressDetails":{"Country":{"AddressLine":"Тамбовская область, Тамбовский район, село Куксово, улица Москва","CountryNameCode":"RU","CountryName":"Россия","AdministrativeArea":{"AdministrativeAreaName":"Тамбовская область","SubAdministrativeArea":{"SubAdministrativeAreaName":"Тамбовский район","Locality":{"LocalityName":"село Куксово","Thoroughfare":{"ThoroughfareName":"улица Москва"}}}}}}}},"description":"село Куксово, Тамбовский район, Тамбовская область, Россия","name":"улица Москва","boundedBy":{"Envelope":{"lowerCorner":"41.48588 52.856247","upperCorner":"41.499831 52.860401"}},"Point":{"pos":"41.492635 52.857726"}}}]}}} diff --git a/projects/elinrin/src/main/resources/yandexkey b/projects/elinrin/src/main/resources/yandexkey new file mode 100644 index 0000000..3eff4f3 --- /dev/null +++ b/projects/elinrin/src/main/resources/yandexkey @@ -0,0 +1 @@ +AEpbCFYBAAAASOuPOQIBg8DHj8Ntfn_0Mwo5S6UjS7my7xYAAAAAAAAAAABMWqQjMsyiftYfJdRc_-QaNBUXUw== diff --git a/projects/elinrin/src/main/resourses/db.properties b/projects/elinrin/src/main/resourses/db.properties new file mode 100644 index 0000000..8a47781 --- /dev/null +++ b/projects/elinrin/src/main/resourses/db.properties @@ -0,0 +1,3 @@ +connection_name=jdbc:h2:~/test +username=test +password=test \ No newline at end of file diff --git a/projects/elinrin/src/test/java/ru/mipt/diht/students/elinrin/collectionquery/AggregatesTest.java b/projects/elinrin/src/test/java/ru/mipt/diht/students/elinrin/collectionquery/AggregatesTest.java new file mode 100644 index 0000000..e519cea --- /dev/null +++ b/projects/elinrin/src/test/java/ru/mipt/diht/students/elinrin/collectionquery/AggregatesTest.java @@ -0,0 +1,72 @@ +package ru.mipt.diht.students.elinrin.collectionquery; + +import junit.framework.TestCase; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.runners.MockitoJUnitRunner; +import ru.mipt.diht.students.elinrin.collectionquery.aggregatesImpl.Aggregator; + +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.List; +import java.util.function.Function; + +@SuppressWarnings("unchecked") +@RunWith(MockitoJUnitRunner.class) +public class AggregatesTest extends TestCase { + + List exampleList, emptyExampleList; + Function functionAge; + Function functionName, functionGroup; + CollectionQuery.Student student; + + @Before + public void setUp() throws Exception { + exampleList = new ArrayList<>(); + emptyExampleList = new ArrayList<>(); + exampleList.add(new CollectionQuery.Student("ivanov", LocalDate.parse("1996-08-06"), "494")); + exampleList.add(new CollectionQuery.Student("petrov", LocalDate.parse("1997-02-20"), "495")); + exampleList.add(new CollectionQuery.Student("sidorov", LocalDate.parse("1996-10-29"), "495")); + functionAge = CollectionQuery.Student::age; + functionName = CollectionQuery.Student::getName; + functionGroup = CollectionQuery.Student::getGroup; + student = new CollectionQuery.Student("sidorov", LocalDate.parse("1996-10-29"), "495"); + } + + @Test + public void testMax() throws Exception { + assertEquals(((Aggregator) Aggregates.max(functionGroup)).apply(exampleList), "495"); + assertEquals(((Aggregator) Aggregates.max(functionName)).apply(exampleList), "sidorov"); + assertEquals(((Aggregator) Aggregates.max(functionAge)).apply(exampleList), 19.0); + + assertEquals(((Aggregator) Aggregates.max(functionAge)).apply(student), null); + assertEquals(((Aggregator) Aggregates.max(functionAge)).apply(emptyExampleList), null); + } + + @Test + public void testMin() throws Exception { + assertEquals(((Aggregator) Aggregates.min(functionGroup)).apply(exampleList), "494"); + assertEquals(((Aggregator) Aggregates.min(functionName)).apply(exampleList), "ivanov"); + assertEquals(((Aggregator) Aggregates.min(functionAge)).apply(exampleList), 18.0); + + assertEquals(((Aggregator) Aggregates.min(functionAge)).apply(student), null); + assertEquals(((Aggregator) Aggregates.min(functionAge)).apply(emptyExampleList), null); + } + + @Test + public void testCount() throws Exception { + assertEquals(((Aggregator) Aggregates.count(functionGroup)).apply(exampleList), 2); + assertEquals(((Aggregator) Aggregates.count(functionName)).apply(exampleList), 3); + assertEquals(((Aggregator) Aggregates.count(functionAge)).apply(exampleList), 2); + + assertEquals(((Aggregator) Aggregates.count(functionAge)).apply(student), null); + } + + @Test + public void testAvg() throws Exception { + assertEquals((Double)((Aggregator) Aggregates.avg(functionAge)).apply(exampleList), 18.666, 0.1); + + assertEquals(((Aggregator) Aggregates.avg(functionAge)).apply(student), null); + } +} diff --git a/projects/elinrin/src/test/java/ru/mipt/diht/students/elinrin/collectionquery/ConditionsTest.java b/projects/elinrin/src/test/java/ru/mipt/diht/students/elinrin/collectionquery/ConditionsTest.java new file mode 100644 index 0000000..acd4bce --- /dev/null +++ b/projects/elinrin/src/test/java/ru/mipt/diht/students/elinrin/collectionquery/ConditionsTest.java @@ -0,0 +1,36 @@ +package ru.mipt.diht.students.elinrin.collectionquery; + +import junit.framework.TestCase; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.runners.MockitoJUnitRunner; + +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.List; +import java.util.function.Function; + +import static ru.mipt.diht.students.elinrin.collectionquery.CollectionQuery.Student.student; +import static ru.mipt.diht.students.elinrin.collectionquery.Conditions.rlike; + +@RunWith(MockitoJUnitRunner.class) +public class ConditionsTest extends TestCase { + Function function = CollectionQuery.Student::getName; + + @Test + public void testRlike() throws Exception { + List exampleList = new ArrayList<>(); + exampleList.add(student("ivanov", LocalDate.parse("1986-08-06"), "494")); + exampleList.add(student("petrov", LocalDate.parse("1986-08-06"), "495")); + exampleList.add(student("mogilev", LocalDate.parse("1986-08-06"), "495")); + + assertEquals(rlike(function, ".*ev").test(exampleList.get(0)), false); + assertEquals(rlike(function, ".*ev").test(exampleList.get(1)), false); + assertEquals(rlike(function, ".*ev").test(exampleList.get(2)), true); + } + + @Test(expected = UnsupportedOperationException.class) + public void testLike() throws Exception { + Conditions.like(function, "aaa"); + } +} diff --git a/projects/elinrin/src/test/java/ru/mipt/diht/students/elinrin/collectionquery/OrderByConditionsTest.java b/projects/elinrin/src/test/java/ru/mipt/diht/students/elinrin/collectionquery/OrderByConditionsTest.java new file mode 100644 index 0000000..19b43e5 --- /dev/null +++ b/projects/elinrin/src/test/java/ru/mipt/diht/students/elinrin/collectionquery/OrderByConditionsTest.java @@ -0,0 +1,40 @@ +package ru.mipt.diht.students.elinrin.collectionquery; + +import junit.framework.TestCase; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.runners.MockitoJUnitRunner; + +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.List; +import java.util.function.Function; + +import static ru.mipt.diht.students.elinrin.collectionquery.CollectionQuery.Student.student; + +@RunWith(MockitoJUnitRunner.class) +public class OrderByConditionsTest extends TestCase { + Function function = CollectionQuery.Student::getName; + + @Test + public void testAsc() throws Exception { + List exampleList = new ArrayList<>(); + exampleList.add(student("ivanov", LocalDate.parse("1986-08-06"), "496")); + exampleList.add(student("petrov", LocalDate.parse("1986-08-06"), "497")); + exampleList.add(student("vasilev", LocalDate.parse("1986-08-06"), "496")); + assertTrue(OrderByConditions.asc(function).compare(exampleList.get(0), exampleList.get(2)) < 0); + assertTrue(OrderByConditions.asc(function).compare(exampleList.get(1), exampleList.get(0)) > 0); + assertTrue(OrderByConditions.asc(function).compare(exampleList.get(0), exampleList.get(0)) == 0); + } + + @Test + public void testDesc() throws Exception { + List exampleList = new ArrayList<>(); + exampleList.add(student("ivanov", LocalDate.parse("1986-08-06"), "494")); + exampleList.add(student("petrov", LocalDate.parse("1986-08-06"), "495")); + exampleList.add(student("sidorov", LocalDate.parse("1986-08-06"), "495")); + assertTrue(OrderByConditions.desc(function).compare(exampleList.get(0), exampleList.get(2)) > 0); + assertTrue(OrderByConditions.desc(function).compare(exampleList.get(1), exampleList.get(0)) < 0); + assertTrue(OrderByConditions.desc(function).compare(exampleList.get(0), exampleList.get(0)) == 0); + } +} diff --git a/projects/elinrin/src/test/java/ru/mipt/diht/students/elinrin/collectionquery/SourcesTest.java b/projects/elinrin/src/test/java/ru/mipt/diht/students/elinrin/collectionquery/SourcesTest.java new file mode 100644 index 0000000..af5822e --- /dev/null +++ b/projects/elinrin/src/test/java/ru/mipt/diht/students/elinrin/collectionquery/SourcesTest.java @@ -0,0 +1,33 @@ +package ru.mipt.diht.students.elinrin.collectionquery; + +import junit.framework.TestCase; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.runners.MockitoJUnitRunner; + +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.List; + +import static ru.mipt.diht.students.elinrin.collectionquery.CollectionQuery.Student.student; + +@RunWith(MockitoJUnitRunner.class) +public class SourcesTest extends TestCase { + + @Test + public void testList() throws Exception { + List exampleList = new ArrayList<>(); + exampleList.add(student("ivanov", LocalDate.parse("1986-08-06"), "496")); + exampleList.add(student("petrov", LocalDate.parse("1986-08-06"), "495")); + exampleList.add(student("sidorov", LocalDate.parse("1986-08-06"), "495")); + + List resultList = Sources.list( + student("ivanov", LocalDate.parse("1986-08-06"), "496"), + student("petrov", LocalDate.parse("1986-08-06"), "495"), + student("sidorov", LocalDate.parse("1986-08-06"), "495")); + assertEquals(exampleList.size(), resultList.size()); + for (int i = 0; i < exampleList.size(); i++) { + assertEquals(exampleList.get(i).toString(), resultList.get(i).toString()); + } + } +} diff --git a/projects/elinrin/src/test/java/ru/mipt/diht/students/elinrin/collectionquery/impl/FromStmtTest.java b/projects/elinrin/src/test/java/ru/mipt/diht/students/elinrin/collectionquery/impl/FromStmtTest.java new file mode 100644 index 0000000..16c73d1 --- /dev/null +++ b/projects/elinrin/src/test/java/ru/mipt/diht/students/elinrin/collectionquery/impl/FromStmtTest.java @@ -0,0 +1,95 @@ +package ru.mipt.diht.students.elinrin.collectionquery.impl; + +import junit.framework.TestCase; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.runners.MockitoJUnitRunner; +import ru.mipt.diht.students.elinrin.collectionquery.CollectionQuery; + +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.List; +import java.util.function.Function; + +@SuppressWarnings("unchecked") +@RunWith(MockitoJUnitRunner.class) +public class FromStmtTest extends TestCase { + + List exampleList, emptyExampleList; + Function functionAge; + Function functionName, functionGroup; + CollectionQuery.Student student; + + @Before + public void setUp() throws Exception { + exampleList = new ArrayList<>(); + emptyExampleList = new ArrayList<>(); + exampleList.add(new CollectionQuery.Student("ivanov", LocalDate.parse("1996-08-06"), "494")); + exampleList.add(new CollectionQuery.Student("petrov", LocalDate.parse("1997-02-20"), "495")); + exampleList.add(new CollectionQuery.Student("sidorov", LocalDate.parse("1996-10-29"), "495")); + functionAge = CollectionQuery.Student::age; + functionName = CollectionQuery.Student::getName; + functionGroup = CollectionQuery.Student::getGroup; + student = new CollectionQuery.Student("sidorov", LocalDate.parse("1996-10-29"), "495"); + } + + @Test + public void testFrom() throws Exception { + FromStmt fromStmt = FromStmt.from(exampleList); + assertEquals(fromStmt.getElements().size(), exampleList.size()); + for (int i = 0; i < exampleList.size(); i++) { + assertEquals(fromStmt.getElements().get(i), exampleList.get(i)); + } + } + + @Test + public void testSelect() throws Exception { + SelectStmt select = FromStmt.from(exampleList) + .select(CollectionQuery.Student.class, CollectionQuery.Student::getName, + CollectionQuery.Student::getGroup); + assertEquals(select.getNumberOfObjects(), -1); + assertEquals(select.getReturnClass(), CollectionQuery.Student.class); + assertEquals(select.isDistinct(), false); + assertEquals(select.isUnion(), false); + Function[] functions = new Function[2]; + functions[0] = CollectionQuery.Student::getName; + functions[1] = CollectionQuery.Student::getGroup; + assertEquals(select.getFunctions().length, functions.length); + for (int i = 0; i < functions.length; i++) { + for (CollectionQuery.Student element : exampleList) { + assertEquals(functions[i].apply(element), + select.getFunctions()[i].apply(element)); + } + } + assertEquals(exampleList.size(), select.getElements().size()); + for (int i = 0; i < exampleList.size(); i++) { + assertEquals(exampleList.get(i), select.getElements().get(i)); + } + } + + @Test + public void testSelectDistinct() throws Exception { + SelectStmt select = FromStmt.from(exampleList) + .selectDistinct(CollectionQuery.Student.class, CollectionQuery.Student::getName, + CollectionQuery.Student::getGroup); + assertEquals(select.getNumberOfObjects(), -1); + assertEquals(select.getReturnClass(), CollectionQuery.Student.class); + assertEquals(select.isDistinct(), true); + assertEquals(select.isUnion(), false); + Function[] functions = new Function[2]; + functions[0] = CollectionQuery.Student::getName; + functions[1] = CollectionQuery.Student::getGroup; + assertEquals(select.getFunctions().length, functions.length); + for (int i = 0; i < functions.length; i++) { + for (CollectionQuery.Student element : exampleList) { + assertEquals(functions[i].apply(element), + select.getFunctions()[i].apply(element)); + } + } + assertEquals(exampleList.size(), select.getElements().size()); + for (int i = 0; i < exampleList.size(); i++) { + assertEquals(exampleList.get(i), select.getElements().get(i)); + } + } +} diff --git a/projects/elinrin/src/test/java/ru/mipt/diht/students/elinrin/collectionquery/impl/SelectStmtTest.java b/projects/elinrin/src/test/java/ru/mipt/diht/students/elinrin/collectionquery/impl/SelectStmtTest.java new file mode 100644 index 0000000..85fd304 --- /dev/null +++ b/projects/elinrin/src/test/java/ru/mipt/diht/students/elinrin/collectionquery/impl/SelectStmtTest.java @@ -0,0 +1,195 @@ +package ru.mipt.diht.students.elinrin.collectionquery.impl; + +import junit.framework.TestCase; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.runners.MockitoJUnitRunner; +import ru.mipt.diht.students.elinrin.collectionquery.Aggregates; +import ru.mipt.diht.students.elinrin.collectionquery.CollectionQuery; +import ru.mipt.diht.students.elinrin.collectionquery.OrderByConditions; + +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.function.Function; + +@RunWith(MockitoJUnitRunner.class) +public class SelectStmtTest extends TestCase { + + List exampleList, emptyExampleList, distinctExampleList; + Function functionAge; + Function functionName, functionGroup; + CollectionQuery.Student student; + SelectStmt select, distinctSelect; + SelectStmt groupSelect; + + @Before + public void setUp() throws Exception { + exampleList = new ArrayList<>(); + emptyExampleList = new ArrayList<>(); + distinctExampleList = new ArrayList<>(); + exampleList.add(new CollectionQuery.Student("garkaviy", LocalDate.parse("1997-02-20"), "495")); + exampleList.add(new CollectionQuery.Student("ivanov", LocalDate.parse("1996-08-06"), "494")); + exampleList.add(new CollectionQuery.Student("petrov", LocalDate.parse("1997-02-20"), "495")); + exampleList.add(new CollectionQuery.Student("sidorov", LocalDate.parse("1996-10-29"), "495")); + distinctExampleList.add(new CollectionQuery.Student("garkaviy", LocalDate.parse("1997-02-20"), "495")); + distinctExampleList.add(new CollectionQuery.Student("ivanov", LocalDate.parse("1996-08-06"), "494")); + distinctExampleList.add(new CollectionQuery.Student("garkaviy", LocalDate.parse("1997-02-20"), "495")); + distinctExampleList.add(new CollectionQuery.Student("ivanov", LocalDate.parse("1996-08-06"), "494")); + functionAge = CollectionQuery.Student::age; + functionName = CollectionQuery.Student::getName; + functionGroup = CollectionQuery.Student::getGroup; + student = new CollectionQuery.Student("sidorov", LocalDate.parse("1996-10-29"), "495"); + select = FromStmt.from(exampleList).select(CollectionQuery.Student.class, CollectionQuery.Student::getName, + CollectionQuery.Student::getGroup); + distinctSelect = FromStmt.from(distinctExampleList).selectDistinct(CollectionQuery.Student.class, + CollectionQuery.Student::getName, CollectionQuery.Student::getGroup); + groupSelect = FromStmt.from(exampleList).select(CollectionQuery.Statistics.class, + CollectionQuery.Student::getGroup, Aggregates.count(CollectionQuery.Student::getName)); + } + + @Test + public void testWhere() throws Exception { + List result = (List) select + .where(s -> Objects.equals(s.getGroup(), "494")) + .execute(); + List resultList = new ArrayList<>(); + resultList.add(new CollectionQuery.Student("ivanov", "494")); + assertEquals(resultList.size(), result.size()); + for (int i = 0; i < resultList.size(); i++) { + assertEquals(resultList.get(i).toString(), result.get(i).toString()); + } + } + + @Test + public void testGroupBy() throws Exception { + List result = (List) groupSelect + .groupBy(CollectionQuery.Student::getGroup) + .execute(); + List resultList = new ArrayList<>(); + resultList.add(new CollectionQuery.Statistics("495", 3)); + resultList.add(new CollectionQuery.Statistics("494", 1)); + assertEquals(resultList.size(), result.size()); + for (int i = 0; i < resultList.size(); i++) { + assertEquals(resultList.get(i).toString(), result.get(i).toString()); + } + } + + @Test + public void testOrderBy() throws Exception { + List result = (List) select + .orderBy(OrderByConditions.desc(CollectionQuery.Student::getGroup)) + .execute(); + List resultList = new ArrayList<>(); + resultList.add(new CollectionQuery.Student("garkaviy", "495")); + resultList.add(new CollectionQuery.Student("petrov", "495")); + resultList.add(new CollectionQuery.Student("sidorov", "495")); + resultList.add(new CollectionQuery.Student("ivanov", "494")); + assertEquals(resultList.size(), result.size()); + for (int i = 0; i < resultList.size(); i++) { + assertEquals(resultList.get(i).toString(), result.get(i).toString()); + } + } + + @Test + public void testHaving() throws Exception { + List result = (List) groupSelect + .groupBy(CollectionQuery.Student::getGroup) + .having(s -> Objects.equals(s.getGroup(), "494")) + .execute(); + List resultList = new ArrayList<>(); + resultList.add(new CollectionQuery.Statistics("494", 1)); + assertEquals(resultList.size(), result.size()); + for (int i = 0; i < resultList.size(); i++) { + assertEquals(resultList.get(i).toString(), result.get(i).toString()); + } + } + + @Test + public void testLimit() throws Exception { + List result = (List) select + .limit(2) + .execute(); + List resultList = new ArrayList<>(); + resultList.add(new CollectionQuery.Student("garkaviy", "495")); + resultList.add(new CollectionQuery.Student("ivanov", "494")); + assertEquals(resultList.size(), result.size()); + for (int i = 0; i < resultList.size(); i++) { + assertEquals(resultList.get(i).toString(), result.get(i).toString()); + } + + result = (List) select + .limit(5) + .execute(); + resultList.clear(); + resultList.add(new CollectionQuery.Student("garkaviy", "495")); + resultList.add(new CollectionQuery.Student("ivanov", "494")); + resultList.add(new CollectionQuery.Student("petrov", "495")); + resultList.add(new CollectionQuery.Student("sidorov", "495")); + assertEquals(resultList.size(), result.size()); + for (int i = 0; i < resultList.size(); i++) { + assertEquals(resultList.get(i).toString(), result.get(i).toString()); + } + } + + @Test + public void testExecute() throws Exception { + List result = (List) select.execute(); + List resultList = new ArrayList<>(); + resultList.add(new CollectionQuery.Student("garkaviy", "495")); + resultList.add(new CollectionQuery.Student("ivanov", "494")); + resultList.add(new CollectionQuery.Student("petrov", "495")); + resultList.add(new CollectionQuery.Student("sidorov", "495")); + assertEquals(resultList.size(), result.size()); + for (int i = 0; i < resultList.size(); i++) { + assertEquals(resultList.get(i).toString(), result.get(i).toString()); + } + + List resultWithAggr = (List) groupSelect.execute(); + List resultListWithAggr = new ArrayList<>(); + resultListWithAggr.add(new CollectionQuery.Statistics("495", 1)); + resultListWithAggr.add(new CollectionQuery.Statistics("494", 1)); + resultListWithAggr.add(new CollectionQuery.Statistics("495", 1)); + resultListWithAggr.add(new CollectionQuery.Statistics("495", 1)); + assertEquals(resultWithAggr.size(), resultListWithAggr.size()); + for (int i = 0; i < resultWithAggr.size(); i++) { + assertEquals(resultListWithAggr.get(i).toString(), resultWithAggr.get(i).toString()); + } + } + + @Test + public void testUnion() throws Exception { + List result = (List) select.union(). + from(exampleList). + select(CollectionQuery.Student.class, CollectionQuery.Student::getName, + CollectionQuery.Student::getGroup). + execute(); + List resultList = new ArrayList<>(); + resultList.add(new CollectionQuery.Student("garkaviy", "495")); + resultList.add(new CollectionQuery.Student("ivanov", "494")); + resultList.add(new CollectionQuery.Student("petrov", "495")); + resultList.add(new CollectionQuery.Student("sidorov", "495")); + resultList.add(new CollectionQuery.Student("garkaviy", "495")); + resultList.add(new CollectionQuery.Student("ivanov", "494")); + resultList.add(new CollectionQuery.Student("petrov", "495")); + resultList.add(new CollectionQuery.Student("sidorov", "495")); + assertEquals(resultList.size(), result.size()); + for (int i = 0; i < resultList.size(); i++) { + assertEquals(resultList.get(i).toString(), result.get(i).toString()); + } + } + + @Test + public void testIsDistinct() throws Exception { + List result = (List) distinctSelect.execute(); + List resultList = new ArrayList<>(); + resultList.add(new CollectionQuery.Student("garkaviy", "495")); + resultList.add(new CollectionQuery.Student("ivanov", "494")); + assertEquals(resultList.size(), result.size()); + for (int i = 0; i < resultList.size(); i++) { + assertEquals(resultList.get(i).toString(), result.get(i).toString()); + } + } +} diff --git a/projects/elinrin/src/test/java/ru/mipt/diht/students/elinrin/miniorm/AppTest.java b/projects/elinrin/src/test/java/ru/mipt/diht/students/elinrin/miniorm/AppTest.java new file mode 100644 index 0000000..3593c8d --- /dev/null +++ b/projects/elinrin/src/test/java/ru/mipt/diht/students/elinrin/miniorm/AppTest.java @@ -0,0 +1,38 @@ +package ru.mipt.diht.students.elinrin.miniorm; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +/** + * Unit test for simple App. + */ +public class AppTest + extends TestCase +{ + /** + * Create the test case + * + * @param testName name of the test case + */ + public AppTest( String testName ) + { + super( testName ); + } + + /** + * @return the suite of tests being tested + */ + public static Test suite() + { + return new TestSuite( AppTest.class ); + } + + /** + * Rigourous Test :-) + */ + public void testApp() + { + assertTrue( true ); + } +} diff --git a/projects/elinrin/src/test/java/ru/mipt/diht/students/elinrin/threads/AppTest.java b/projects/elinrin/src/test/java/ru/mipt/diht/students/elinrin/threads/AppTest.java new file mode 100644 index 0000000..931b809 --- /dev/null +++ b/projects/elinrin/src/test/java/ru/mipt/diht/students/elinrin/threads/AppTest.java @@ -0,0 +1,38 @@ +package ru.mipt.diht.students.elinrin.threads; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +/** + * Unit test for simple App. + */ +public class AppTest + extends TestCase +{ + /** + * Create the test case + * + * @param testName name of the test case + */ + public AppTest( String testName ) + { + super( testName ); + } + + /** + * @return the suite of tests being tested + */ + public static Test suite() + { + return new TestSuite( AppTest.class ); + } + + /** + * Rigourous Test :-) + */ + public void testApp() + { + assertTrue( true ); + } +} diff --git a/projects/pom.xml b/projects/pom.xml index 5d14966..a7a8bc2 100644 --- a/projects/pom.xml +++ b/projects/pom.xml @@ -30,6 +30,7 @@ dkhurtin ale3otik Pitovsky + elinrin