diff --git a/mamaevads/pom.xml b/mamaevads/pom.xml
index bdbeb7f5..b28bc69e 100644
--- a/mamaevads/pom.xml
+++ b/mamaevads/pom.xml
@@ -21,6 +21,19 @@
junit
3.8.1
+
+ com.beust
+ jcommander
+ 1.48
+
+
+
+ junit
+ junit
+ 4.12
+ test
+
+
org.twitter4j
twitter4j-stream
@@ -31,5 +44,10 @@
jcommander
1.48
+
+ com.h2database
+ h2
+ 1.4.190
+
diff --git a/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/collectionquery/Aggregates.java b/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/collectionquery/Aggregates.java
new file mode 100644
index 00000000..dd35207c
--- /dev/null
+++ b/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/collectionquery/Aggregates.java
@@ -0,0 +1,102 @@
+package ru.fizteh.fivt.students.mamaevads.collectionquery;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.NoSuchElementException;
+import java.util.Set;
+import java.util.function.Function;
+
+
+public class Aggregates {
+
+ public interface Aggregate extends Function {
+ T forGroup(Set set);
+ }
+
+ private static Collection getValues(Collection set, Function expression) {
+ Set values = new HashSet<>();
+ for (C element : set) {
+ values.add(expression.apply(element));
+ }
+ return values;
+ }
+
+ public static > Aggregate max(Function expression) {
+ return new Aggregate() {
+
+ @Override
+ public T apply(C element) {
+ return (T) expression.apply(element);
+ }
+
+ @Override
+ public T forGroup(Set set) throws ClassCastException, NoSuchElementException {
+ return Collections.max(getValues(set, expression));
+ }
+ };
+ }
+
+ public static > Aggregate min(Function expression) {
+ return new Aggregate() {
+
+ @Override
+ public T apply(C element) {
+ return (T) expression.apply(element);
+ }
+
+ @Override
+ public T forGroup(Set set) throws ClassCastException, NoSuchElementException {
+ return Collections.min(getValues(set, expression));
+ }
+ };
+ }
+
+ public static > Aggregate count(Function expression) {
+ return new Aggregate() {
+
+ @Override
+ public Long apply(C element) {
+ return Long.valueOf(1);
+ }
+
+ @Override
+ public Long forGroup(Set set) {
+ return (long) set.size();
+ }
+ };
+ }
+
+ public static > Aggregate avg(Function expression) {
+ return new Aggregate() {
+
+ @Override
+ public T apply(C element) {
+ return expression.apply(element);
+ }
+
+ @Override
+ public T forGroup(Set set) throws ClassCastException, NoSuchElementException {
+ if (set.isEmpty()) {
+ throw new NoSuchElementException("set is empty");
+ }
+ T sample = expression.apply(set.iterator().next());
+ if (sample instanceof Long || sample instanceof Integer || sample instanceof Short) {
+ long average = 0;
+ for (C element : set) {
+ average += (Long) (expression.apply(element));
+ }
+ return (T) Long.valueOf(average / set.size());
+ } else if (sample instanceof Float || sample instanceof Double) {
+ double average = 0;
+ for (C element : set) {
+ average += (Double) (expression.apply(element));
+ }
+ return (T) Double.valueOf(average / set.size());
+ }
+ throw new ClassCastException("wrong type");
+ }
+ };
+ }
+
+}
diff --git a/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/collectionquery/Conditions.java b/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/collectionquery/Conditions.java
new file mode 100644
index 00000000..ecbfe184
--- /dev/null
+++ b/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/collectionquery/Conditions.java
@@ -0,0 +1,22 @@
+package ru.fizteh.fivt.students.mamaevads.collectionquery;
+
+import java.util.function.Function;
+import java.util.function.Predicate;
+
+public class Conditions {
+
+ public static Predicate rlike(Function expression, String regexp) {
+ return new Predicate() {
+
+ @Override
+ public boolean test(T element) {
+ return expression.apply(element).matches(regexp);
+ }
+ };
+ }
+
+ public static Predicate like(Function expression, String pattern) {
+ throw new UnsupportedOperationException();
+ }
+
+}
diff --git a/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/collectionquery/OrderByConditions.java b/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/collectionquery/OrderByConditions.java
new file mode 100644
index 00000000..23755d67
--- /dev/null
+++ b/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/collectionquery/OrderByConditions.java
@@ -0,0 +1,17 @@
+package ru.fizteh.fivt.students.mamaevads.collectionquery;
+
+import java.util.Comparator;
+import java.util.function.Function;
+
+public class OrderByConditions {
+
+
+ public static > Comparator asc(Function expression) {
+ return (o1, o2) -> expression.apply(o1).compareTo(expression.apply(o2));
+ }
+
+ public static > Comparator desc(Function expression) {
+ return (o1, o2) -> expression.apply(o2).compareTo(expression.apply(o1));
+ }
+
+}
diff --git a/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/collectionquery/Sources.java b/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/collectionquery/Sources.java
new file mode 100644
index 00000000..bc502a03
--- /dev/null
+++ b/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/collectionquery/Sources.java
@@ -0,0 +1,54 @@
+package ru.fizteh.fivt.students.mamaevads.collectionquery;
+
+ import java.io.FileInputStream;
+ import java.io.IOException;
+ import java.io.InputStream;
+ import java.nio.file.Path;
+ import java.util.Arrays;
+ import java.util.HashSet;
+ import java.util.List;
+ import java.util.Set;
+ import java.util.stream.Stream;
+
+public class Sources {
+
+ @SafeVarargs
+ public static List list(T... items) {
+ return Arrays.asList(items);
+ }
+
+ @SafeVarargs
+ public static Set set(T... items) {
+ Set result = new HashSet<>();
+ for (T element : items) {
+ result.add(element);
+ }
+ return result;
+ }
+
+ static final int READ_BLOCK_SIZE = 100;
+
+
+ public static Stream lines(InputStream inputStream) throws IOException, ClassCastException {
+ StringBuilder builder = new StringBuilder();
+ byte[] data = new byte[READ_BLOCK_SIZE];
+ int readed = inputStream.read(data);
+ while (readed > 0) {
+ builder.append(data);
+ readed = inputStream.read(data);
+ }
+ inputStream.close();
+ String[] lines = builder.toString().split("[\n]");
+ Stream.Builder stream = Stream.builder();
+ for (String line : lines) {
+ stream.add((T) line);
+ }
+ return stream.build();
+ }
+
+ public static Stream lines(Path file) throws ClassCastException, IOException {
+ InputStream input = new FileInputStream(file.toFile());
+ return lines(input);
+ }
+
+}
diff --git a/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/collectionquery/impl/CollectionQueryExecuteException.java b/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/collectionquery/impl/CollectionQueryExecuteException.java
new file mode 100644
index 00000000..7d9b3097
--- /dev/null
+++ b/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/collectionquery/impl/CollectionQueryExecuteException.java
@@ -0,0 +1,9 @@
+package ru.fizteh.fivt.students.mamaevads.collectionquery.impl;
+
+public class CollectionQueryExecuteException extends Exception {
+
+ CollectionQueryExecuteException(String message, Throwable cause) {
+ super(message, cause);
+ }
+}
+
diff --git a/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/collectionquery/impl/CollectionQuerySyntaxException.java b/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/collectionquery/impl/CollectionQuerySyntaxException.java
new file mode 100644
index 00000000..77949b75
--- /dev/null
+++ b/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/collectionquery/impl/CollectionQuerySyntaxException.java
@@ -0,0 +1,13 @@
+package ru.fizteh.fivt.students.mamaevads.collectionquery.impl;
+
+public class CollectionQuerySyntaxException extends Exception {
+
+ CollectionQuerySyntaxException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ CollectionQuerySyntaxException(String message) {
+ super(message);
+ }
+}
+
diff --git a/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/collectionquery/impl/FinalRow.java b/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/collectionquery/impl/FinalRow.java
new file mode 100644
index 00000000..e8e8fbbb
--- /dev/null
+++ b/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/collectionquery/impl/FinalRow.java
@@ -0,0 +1,33 @@
+package ru.fizteh.fivt.students.mamaevads.collectionquery.impl;
+
+import java.util.HashSet;
+import java.util.Set;
+
+class FinalRow {
+ private R row;
+ private Set from;
+
+ FinalRow(R newRow, T elementFrom) {
+ from = new HashSet();
+ from.add(elementFrom);
+ row = newRow;
+ }
+
+ public R get() {
+ return row;
+ }
+
+ public Set getFrom() {
+ return from;
+ }
+
+ public T getAnyFrom() {
+ return from.iterator().next();
+ }
+
+ public void updateRow(R newRow) {
+ row = newRow;
+ }
+}
+
+
diff --git a/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/collectionquery/impl/FromStmt.java b/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/collectionquery/impl/FromStmt.java
new file mode 100644
index 00000000..bf5ffe97
--- /dev/null
+++ b/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/collectionquery/impl/FromStmt.java
@@ -0,0 +1,162 @@
+package ru.fizteh.fivt.students.mamaevads.collectionquery.impl;
+import java.util.function.Function;
+import java.util.stream.Stream;
+
+/**
+ * Created by Даша on 01.11.2015.
+ */
+
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.function.Predicate;
+
+public final class FromStmt {
+ private Iterable base;
+ private ExecutedTable> previousTable = null;
+
+ private FromStmt() { }
+
+ private static final class ExecutedTable {
+ private final Iterable outputTable;
+ private final Class outputClass;
+
+ private ExecutedTable(Class clazz, Iterable table) {
+ outputTable = table;
+ outputClass = clazz;
+ }
+ }
+
+ public static FromStmt from(Iterable iterable) {
+ FromStmt stmt = new FromStmt<>();
+ stmt.base = iterable;
+ return stmt;
+ }
+
+ public static FromStmt from(Stream stream) {
+ FromStmt stmt = new FromStmt<>();
+ List list = new ArrayList<>();
+ stream.forEach(s -> list.add(s));
+ stmt.base = list;
+ return stmt;
+ }
+
+ public static FromStmt from(WhereStmt, T> subStmt) throws CollectionQueryExecuteException {
+ Iterable subQueryResult = subStmt.execute();
+ return from(subQueryResult);
+ }
+
+ void setPreviousPart(Class clazz, Iterable table) {
+ previousTable = new ExecutedTable(clazz, table);
+ }
+
+ private SelectStmt innerSelect(Class clazz, Function[] s, boolean isDistinct)
+ throws CollectionQuerySyntaxException {
+ if (previousTable == null) {
+ return new SelectStmt(base, null, clazz, isDistinct, s);
+ } else {
+ if (!previousTable.outputClass.equals(clazz)) {
+ throw new CollectionQuerySyntaxException("parts of union has different types");
+ }
+ return new SelectStmt(base, (Iterable) previousTable.outputTable, clazz, isDistinct, s);
+ }
+ }
+
+ @SafeVarargs
+ public final SelectStmt select(Class clazz, Function... s)
+ throws CollectionQuerySyntaxException {
+ return innerSelect(clazz, s, false);
+ }
+
+ @SafeVarargs
+ public final SelectStmt selectDistinct(Class clazz, Function... s)
+ throws CollectionQuerySyntaxException {
+ return innerSelect(clazz, s, true);
+ }
+
+ public static final class Tuple {
+ private F firstPart;
+ private S secondPart;
+
+ private Tuple(F first, S second) {
+ firstPart = first;
+ secondPart = second;
+ }
+
+ public F first() {
+ return firstPart;
+ }
+
+ public S second() {
+ return secondPart;
+ }
+ }
+
+
+ public final class JoinStmt {
+ private Iterable secondTable;
+
+ private JoinStmt(Iterable tableOnJoin) {
+ secondTable = tableOnJoin;
+ }
+
+ public FromStmt> on(Predicate> joiningPredicate) {
+ Collection> joinedCollection = new ArrayList<>();
+ for (T first : base) {
+ for (S second : secondTable) {
+ Tuple joinedRow = new Tuple(first, second);
+ if (joiningPredicate.test(joinedRow)) {
+ joinedCollection.add(joinedRow);
+ }
+ }
+ }
+ FromStmt> stmt = new FromStmt<>();
+ stmt.base = joinedCollection;
+ stmt.previousTable = previousTable;
+ return stmt;
+ }
+
+ public FromStmt> on(Function leftKey, Function rightKey) {
+ Map, Set>> possibleValues = new HashMap<>();
+ for (T row : base) {
+ R value = leftKey.apply(row);
+ if (value != null) {
+ if (!possibleValues.containsKey(value)) {
+ possibleValues.put(value, new Tuple<>(new HashSet<>(), new HashSet<>()));
+ }
+ possibleValues.get(value).firstPart.add(row);
+ }
+ }
+ for (S row : secondTable) {
+ R value = rightKey.apply(row);
+ if (value != null) {
+ if (!possibleValues.containsKey(value)) {
+ continue;
+ }
+ possibleValues.get(value).secondPart.add(row);
+ }
+ }
+
+ Collection> joinedCollection = new ArrayList<>();
+
+ possibleValues.forEach((v, tuple) -> {
+ for (T firstRow : tuple.first()) {
+ for (S secondRow : tuple.second()) {
+ joinedCollection.add(new Tuple(firstRow, secondRow));
+ }
+ }
+ });
+ return from(joinedCollection);
+ }
+ }
+
+ public JoinStmt join(Iterable secondTable) {
+ return new JoinStmt<>(secondTable);
+ }
+}
+
diff --git a/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/collectionquery/impl/SelectStmt.java b/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/collectionquery/impl/SelectStmt.java
new file mode 100644
index 00000000..d731762d
--- /dev/null
+++ b/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/collectionquery/impl/SelectStmt.java
@@ -0,0 +1,260 @@
+package ru.fizteh.fivt.students.mamaevads.collectionquery.impl;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Predicate;
+import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
+
+import java.util.Comparator;
+
+/**
+ * Created by Даша on 01.11.2015.
+ */
+
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+
+
+import ru.fizteh.fivt.students.mamaevads.collectionquery.Aggregates.Aggregate;
+
+public class SelectStmt {
+
+ private Stream stream;
+ private Iterable baseCollection;
+ private Class outputClass;
+ private Iterable previousPart;
+ private Function[] convertFunctions;
+
+ private Function>[] groupingFunctions;
+ private Predicate groupingCondition = null;
+ private Comparator finalComparator = null;
+ private int finalLimit = -1;
+
+ private boolean isDistinct;
+
+ @SafeVarargs
+ SelectStmt(Iterable newBaseCollection, Iterable previousTable,
+ Class clazz, boolean distinct, Function... s) {
+ baseCollection = newBaseCollection;
+ previousPart = previousTable;
+ stream = StreamSupport.stream(newBaseCollection.spliterator(), false);
+ outputClass = clazz;
+ convertFunctions = s;
+ isDistinct = distinct;
+ groupingFunctions = null;
+ }
+
+ final Class getOutputClass() {
+ return outputClass;
+ }
+
+ private static Comparator getCombinedComparator(Iterable> comparators) {
+ return new Comparator() {
+ @Override
+ public int compare(T first, T second) {
+ for (Comparator comparator : comparators) {
+ int result = comparator.compare(first, second);
+ if (result != 0) {
+ return result;
+ }
+ }
+ return 0;
+ }
+ };
+ }
+
+ public final WhereStmt where(Predicate predicate) {
+ stream = stream.filter(predicate);
+ return new WhereStmt<>(this);
+ }
+
+ @SafeVarargs
+ public final void groupBy(Function>... expressions) throws CollectionQuerySyntaxException {
+ if (groupingFunctions != null) {
+ throw new CollectionQuerySyntaxException("group table in the query");
+ }
+ groupingFunctions = expressions;
+ }
+
+ public final void having(Predicate condition) throws CollectionQuerySyntaxException {
+ if (groupingCondition != null) {
+ throw new CollectionQuerySyntaxException("set grouping conditions");
+ }
+ groupingCondition = condition;
+ }
+
+ private class Applier implements Consumer {
+ private Collection> output;
+ private Constructor constructor;
+
+ Applier(Collection> outputCollection, Constructor resultConstructor) {
+ output = outputCollection;
+ constructor = resultConstructor;
+ }
+
+ @Override
+ public void accept(T element) {
+ Object[] parametrs = new Object[convertFunctions.length];
+ for (int i = 0; i < convertFunctions.length; ++i) {
+ parametrs[i] = convertFunctions[i].apply(element);
+ }
+ try {
+ output.add(new FinalRow(constructor.newInstance(parametrs), element));
+ } catch (InstantiationException | IllegalAccessException
+ | IllegalArgumentException | InvocationTargetException e) {
+ throw new RuntimeException("construct", e);
+ }
+ }
+
+ }
+
+ private Constructor getAskedConstructor() throws CollectionQueryExecuteException {
+ Class>[] outputParametrsTypes = new Class>[convertFunctions.length];
+ for (int i = 0; i < convertFunctions.length; ++i) {
+ outputParametrsTypes[i] = convertFunctions[i].apply(baseCollection.iterator().next()).getClass();
+ }
+ try {
+ return outputClass.getConstructor(outputParametrsTypes);
+ } catch (NoSuchMethodException | SecurityException e) {
+ throw new CollectionQueryExecuteException("Can not found constructor", e);
+ }
+ }
+
+ private Collection> goodGroups(Collection> table) {
+ List> output = new ArrayList<>();
+ for (FinalRow row : table) {
+ if (groupingCondition == null || groupingCondition.test(row.get())) {
+ output.add(row);
+ }
+ }
+ return output;
+ }
+
+ private void aggregatingGroups(Collection> table) throws CollectionQueryExecuteException {
+ Constructor constructor = getAskedConstructor();
+ Object[] parametrs = new Object[convertFunctions.length];
+ for (FinalRow row : table) {
+ for (int i = 0; i < convertFunctions.length; ++i) {
+ if (convertFunctions[i] instanceof Aggregate) {
+ parametrs[i] = ((Aggregate) convertFunctions[i]).forGroup(row.getFrom());
+ } else {
+ parametrs[i] = convertFunctions[i].apply(row.getAnyFrom());
+ }
+ }
+ try {
+ row.updateRow(constructor.newInstance(parametrs));
+ } catch (InstantiationException | IllegalAccessException
+ | IllegalArgumentException | InvocationTargetException e) {
+ throw new CollectionQueryExecuteException("output class not instantiated", e);
+ }
+ }
+ }
+
+ private Collection convertToFinal(Collection> table) {
+ List output = new ArrayList<>();
+ if (previousPart != null) {
+ for (R row : previousPart) {
+ output.add(row);
+ }
+ }
+ for (FinalRow row : table) {
+ output.add(row.get());
+ }
+ return output;
+ }
+
+ public final Collection execute() throws CollectionQueryExecuteException {
+ Collection> output = null;
+ output = new ArrayList<>();
+
+ try {
+ stream.forEach(new Applier(output, getAskedConstructor()));
+ } catch (RuntimeException e) {
+ if (e.getMessage().equals("constructor")) {
+ throw new CollectionQueryExecuteException("constructor", e.getCause());
+ } else {
+ throw e;
+ }
+ }
+
+ if (groupingFunctions != null) {
+ List> preCalcSortedTable = new ArrayList<>();
+ for (FinalRow element : output) {
+ preCalcSortedTable.add(element);
+ }
+ List>> resultComparators = new ArrayList<>();
+ for (Function> function : groupingFunctions) {
+ resultComparators.add((r1, r2) -> {
+ Comparable result1 = function.apply(r1.getAnyFrom());
+ return result1.compareTo(function.apply(r2.getAnyFrom()));
+ });
+ }
+ Comparator> groupsComparator = getCombinedComparator(resultComparators);
+ preCalcSortedTable.sort(groupsComparator);
+ Collection> groupedTable = new ArrayList<>();
+
+ FinalRow currentGroup = null;
+ for (FinalRow row : preCalcSortedTable) {
+ if (currentGroup != null && groupsComparator.compare(row, currentGroup) == 0) {
+ currentGroup.getFrom().add(row.getAnyFrom());
+ } else {
+ if (currentGroup != null) {
+ groupedTable.add(currentGroup);
+ }
+ currentGroup = row;
+ }
+ }
+ groupedTable.add(currentGroup);
+
+ aggregatingGroups(output);
+ output = goodGroups(groupedTable);
+ }
+ Stream finalOutput = convertToFinal(output).stream();
+ if (finalLimit >= 0) {
+ finalOutput = finalOutput.limit(finalLimit);
+ }
+ if (finalComparator != null) {
+ finalOutput = finalOutput.sorted(finalComparator);
+ }
+ if (isDistinct) {
+ finalOutput = finalOutput.distinct();
+ }
+ return finalOutput.collect(() -> new ArrayList(), (l, e) -> l.add(e), (l1, l2) -> l1.addAll(l2));
+ }
+
+ public final void limit(int limit) throws CollectionQuerySyntaxException {
+ if (limit >= 0) {
+ throw new CollectionQuerySyntaxException("limitation");
+ }
+ finalLimit = limit;
+ }
+
+ @SafeVarargs
+ public final void orderBy(Comparator... comparators) throws CollectionQuerySyntaxException {
+ if (finalComparator != null) {
+ throw new CollectionQuerySyntaxException("ordering functions");
+ }
+ finalComparator = getCombinedComparator(Arrays.asList(comparators));
+ }
+
+ public final Stream stream() throws CollectionQueryExecuteException {
+ return execute().stream();
+ }
+
+ final Stream currentStream() {
+ return stream;
+ }
+
+
+ public final UnionStmt union() throws CollectionQueryExecuteException {
+ return new UnionStmt(this);
+ }
+
+}
+
diff --git a/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/collectionquery/impl/UnionStmt.java b/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/collectionquery/impl/UnionStmt.java
new file mode 100644
index 00000000..2ae2379a
--- /dev/null
+++ b/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/collectionquery/impl/UnionStmt.java
@@ -0,0 +1,24 @@
+package ru.fizteh.fivt.students.mamaevads.collectionquery.impl;
+
+/**
+ * Created by Даша on 01.11.2015.
+ */
+
+import java.util.Collection;
+
+public class UnionStmt {
+ private Collection previousPart;
+ private Class previousOutputClass;
+
+ UnionStmt(SelectStmt, R> previousStmt) throws CollectionQueryExecuteException {
+ previousOutputClass = previousStmt.getOutputClass();
+ previousPart = previousStmt.execute();
+ }
+
+ public final FromStmt from(Iterable list) {
+ FromStmt stmt = FromStmt.from(list);
+ stmt.setPreviousPart(previousOutputClass, previousPart);
+ return stmt;
+ }
+}
+
diff --git a/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/collectionquery/impl/WhereStmt.java b/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/collectionquery/impl/WhereStmt.java
new file mode 100644
index 00000000..f705b729
--- /dev/null
+++ b/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/collectionquery/impl/WhereStmt.java
@@ -0,0 +1,46 @@
+package ru.fizteh.fivt.students.mamaevads.collectionquery.impl;
+
+
+import java.util.Comparator;
+import java.util.function.Function;
+import java.util.function.Predicate;
+
+public class WhereStmt {
+ private SelectStmt baseStmt;
+
+ WhereStmt(SelectStmt selectStmt) {
+ baseStmt = selectStmt;
+ }
+
+ @SafeVarargs
+ public final WhereStmt groupBy(Function>... expressions)
+ throws CollectionQuerySyntaxException {
+ baseStmt.groupBy(expressions);
+ return this;
+ }
+
+ @SafeVarargs
+ public final WhereStmt orderBy(Comparator... comparators) throws CollectionQuerySyntaxException {
+ baseStmt.orderBy(comparators);
+ return this;
+ }
+
+ public final WhereStmt having(Predicate condition) throws CollectionQuerySyntaxException {
+ baseStmt.having(condition);
+ return this;
+ }
+
+ public final WhereStmt limit(int amount) throws CollectionQuerySyntaxException {
+ baseStmt.limit(amount);
+ return this;
+ }
+
+ public final Iterable execute() throws CollectionQueryExecuteException {
+ return baseStmt.execute();
+ }
+
+ public final UnionStmt union() throws CollectionQueryExecuteException {
+ return baseStmt.union();
+ }
+}
+
diff --git a/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/miniorm/Column.java b/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/miniorm/Column.java
new file mode 100644
index 00000000..0fe41d8c
--- /dev/null
+++ b/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/miniorm/Column.java
@@ -0,0 +1,14 @@
+package ru.fizteh.fivt.students.mamaevads.miniorm;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.FIELD)
+public @interface Column {
+ String name() default "";
+}
+
diff --git a/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/miniorm/DatabaseService.java b/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/miniorm/DatabaseService.java
new file mode 100644
index 00000000..0f06dccc
--- /dev/null
+++ b/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/miniorm/DatabaseService.java
@@ -0,0 +1,285 @@
+package ru.fizteh.fivt.students.mamaevads.miniorm;
+
+/**
+ * Created by Даша on 17.12.2015.
+ */
+
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.Function;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+//import org.h2.jdbcx.JdbcConnectionPool;
+
+public class DatabaseService {
+ private Class tableClass;
+ private String tableName;
+ private Connection dbConnection;
+ private List columns;
+ private TypedColumn primaryKeyColumn;
+
+ private static final String STANDARD_DATABASE_PATH = "./mamaevadb";
+
+ private enum DataType {
+ INTEGER("INT", Boolean.class, Byte.class, Short.class, Integer.class, Long.class),
+ DOUBLE("DOUBLE", Float.class, Double.class),
+ TEXT("VARCHAR(255)", String.class);
+
+ private final String nameSQL;
+ private final Class>[] examples;
+
+ DataType(String sqllikeName, Class>... variety) {
+ nameSQL = sqllikeName;
+ examples = variety;
+ }
+
+ private static DataType valueOf(Class> typeClass) throws DatabaseServiceException {
+ for (DataType type : values()) {
+ for (Class> testClass : type.examples) {
+ if (typeClass.equals(testClass)) {
+ return type;
+ }
+ }
+ }
+ throw new DatabaseServiceException("This type is not supported"
+ + typeClass.getSimpleName());
+ }
+ }
+
+ private final class TypedColumn {
+ private DataType type;
+ private String name;
+ private Field field;
+
+ private TypedColumn(Field realField) throws DatabaseServiceException {
+ field = realField;
+ field.setAccessible(true);
+ Column columnAnnotation = field.getAnnotation(Column.class);
+ if (columnAnnotation == null) {
+ throw new DatabaseServiceException("annotate the field");
+ }
+ name = columnAnnotation.name();
+ if (name.equals("")) {
+ name = toSnakeCase(field.getName());
+ }
+ type = DataType.valueOf(field.getType());
+ }
+ }
+
+ private static String toSnakeCase(String camelCase) {
+ StringBuilder nameBuilder = new StringBuilder();
+ for (int i = 0; i < camelCase.length(); ++i) {
+ if (camelCase.charAt(i) >= 'A' && camelCase.charAt(i) <= 'Z') {
+ if (i > 0 && camelCase.charAt(i - 1) >= 'a' && camelCase.charAt(i - 1) <= 'z') {
+ nameBuilder.append('_');
+ }
+ nameBuilder.append((char) (camelCase.charAt(i) - 'A' + 'a'));
+ } else {
+ nameBuilder.append(camelCase.charAt(i));
+ }
+ }
+ return nameBuilder.toString();
+ }
+
+ private String createColumnsPattern(Function convert) {
+ StringBuilder values = new StringBuilder();
+ for (TypedColumn column : columns) {
+ values.append(convert.apply(column))
+ .append(',');
+ }
+ values.deleteCharAt(values.length() - 1);
+ return values.toString();
+ }
+
+ private void initDatabaseTable(Class annotatedTableClass) throws DatabaseServiceException {
+ tableClass = annotatedTableClass;
+ Table tableAnnotation = tableClass.getAnnotation(Table.class);
+ if (tableAnnotation == null) {
+ throw new DatabaseServiceException("annotate the table class");
+ }
+ tableName = tableAnnotation.name();
+ if (tableName.equals("")) {
+ tableName = toSnakeCase(tableClass.getSimpleName());
+ }
+ Field[] allFields = tableClass.getDeclaredFields();
+ columns = new ArrayList<>();
+ for (Field field : allFields) {
+ if (field.isAnnotationPresent(Column.class)) {
+ columns.add(new TypedColumn(field));
+ if (field.isAnnotationPresent(PrimaryKey.class)) {
+ if (primaryKeyColumn != null) {
+ throw new DatabaseServiceException("please enter one prim key");
+ }
+ primaryKeyColumn = columns.get(columns.size() - 1);
+ }
+ }
+ }
+ }
+
+ private void initConnection(String databasePath) throws DatabaseServiceException {
+ try {
+ dbConnection = DriverManager.getConnection("jdbc:h2:" + databasePath, "sa", "");
+ } catch (SQLException e) {
+ throw new DatabaseServiceException("Connection not found: " + e.getMessage(), e);
+ }
+ }
+
+ public DatabaseService(Class annotatedTableClass) throws DatabaseServiceException {
+ initDatabaseTable(annotatedTableClass);
+ initConnection(STANDARD_DATABASE_PATH);
+ }
+
+ public final void createTable() throws DatabaseServiceException {
+ StringBuilder columnsString = new StringBuilder();
+ for (TypedColumn column : columns) {
+ columnsString.append(column.name)
+ .append(' ')
+ .append(column.type.nameSQL);
+ if (column.field.isAnnotationPresent(PrimaryKey.class)) {
+ columnsString.append(" PRIMARY KEY CAN'T BE NULL");
+ }
+ columnsString.append(',');
+ }
+ columnsString.deleteCharAt(columnsString.length() - 1);
+ try {
+ dbConnection.createStatement().execute("CREATE TABLE " + tableName
+ + "(" + columnsString.toString() + ")");
+ } catch (SQLException e) {
+ throw new DatabaseServiceException("can't create: " + e.getMessage(), e);
+ }
+ }
+
+
+ public final void dropTable() throws DatabaseServiceException {
+ try {
+ dbConnection.createStatement().execute("DROP TABLE " + tableName);
+ } catch (SQLException e) {
+ throw new DatabaseServiceException("can't drop table: " + e.getMessage(), e);
+ }
+ }
+
+
+ public final void insert(T row) throws DatabaseServiceException {
+ try {
+ PreparedStatement statement = dbConnection.prepareStatement("INSERT INTO " + tableName
+ + " VALUES (" + createColumnsPattern(c -> "?") + ")");
+ for (int i = 0; i < columns.size(); ++i) {
+ statement.setString(i + 1, String.valueOf(columns.get(i).field.get(row)));
+ }
+ statement.execute();
+ } catch (SQLException | IllegalArgumentException | IllegalAccessException e) {
+ throw new DatabaseServiceException("can't insert: " + e.getMessage());
+ }
+ }
+
+
+ public final void update(T row) throws DatabaseServiceException {
+ if (primaryKeyColumn == null) {
+ throw new DatabaseServiceException("no prim key");
+ }
+ try {
+ PreparedStatement statement = dbConnection.prepareStatement("UPDATE " + tableName
+ + " SET " + createColumnsPattern(c -> c.name + "=?") + " WHERE " + primaryKeyColumn.name + "=?");
+ for (int i = 0; i < columns.size(); ++i) {
+ statement.setString(i + 1, String.valueOf(columns.get(i).field.get(row)));
+ }
+ statement.setString(columns.size() + 1, primaryKeyColumn.field.get(row).toString());
+ statement.execute();
+ } catch (SQLException | IllegalArgumentException | IllegalAccessException e) {
+ throw new DatabaseServiceException("Can't update: " + e.getMessage());
+ }
+ }
+
+
+ public final void deleteByKey(K key) throws DatabaseServiceException {
+ if (primaryKeyColumn == null) {
+ throw new DatabaseServiceException("no prim key");
+ }
+ try {
+ PreparedStatement statement = dbConnection.prepareStatement("DELETE FROM " + tableName
+ + " WHERE " + primaryKeyColumn.name + "=?");
+ statement.setString(1, key.toString());
+ statement.execute();
+ } catch (SQLException | IllegalArgumentException e) {
+ throw new DatabaseServiceException("Can't delete" + e.getMessage());
+ }
+ }
+
+
+ public final void delete(T row) throws DatabaseServiceException {
+ try {
+ deleteByKey(primaryKeyColumn.field.get(row).toString());
+ } catch (IllegalAccessException e) {
+ throw new DatabaseServiceException("Can't delete: " + e.getMessage());
+ }
+ }
+
+ private List getRealClasses(ResultSet result) throws IllegalArgumentException, IllegalAccessException,
+ SQLException, InstantiationException, InvocationTargetException, NoSuchMethodException, SecurityException {
+ List output = new ArrayList<>();
+ while (result.next()) {
+ T row = tableClass.newInstance();
+ for (int i = 0; i < columns.size(); ++i) {
+ String value = result.getString(i + 1);
+ if (columns.get(i).field.getType().equals(String.class)) {
+ columns.get(i).field.set(row, value);
+ } else {
+ columns.get(i).field.set(row, columns.get(i).field.getType().getMethod("valueOf", String.class)
+ .invoke(null, value));
+ }
+ }
+ output.add(row);
+ }
+ result.close();
+ return output;
+ }
+
+ public final T queryById(K key) throws DatabaseServiceException {
+ if (primaryKeyColumn == null) {
+ throw new DatabaseServiceException("need prim key");
+ }
+ if (!primaryKeyColumn.field.getType().isInstance(key)) {
+ throw new DatabaseServiceException("key type is not type of primary key");
+ }
+
+ try {
+ PreparedStatement statement = dbConnection.prepareStatement("SELECT " + createColumnsPattern(c -> c.name)
+ + " FROM " + tableName + " WHERE " + primaryKeyColumn.name + "=?");
+ statement.setString(1, key.toString());
+ List result = getRealClasses(statement.executeQuery());
+ if (result.isEmpty()) {
+ return null;
+ }
+ return result.get(0);
+ } catch (SQLException | IllegalArgumentException | IllegalAccessException | InstantiationException
+ | InvocationTargetException | NoSuchMethodException | SecurityException e) {
+ throw new DatabaseServiceException("Can't get the instantiate the row: " + e.getMessage(), e);
+ }
+ }
+
+
+ public final List queryForAll() throws DatabaseServiceException {
+ try {
+ return getRealClasses(dbConnection.prepareStatement("SELECT " + createColumnsPattern(c -> c.name)
+ + " FROM " + tableName).executeQuery());
+ } catch (SQLException | IllegalArgumentException | IllegalAccessException
+ | InstantiationException | InvocationTargetException | NoSuchMethodException | SecurityException e) {
+ throw new DatabaseServiceException("Can't get or instantiate the row: " + e.getMessage(), e);
+ }
+ }
+
+ @Override
+ protected final void finalize() {
+ try {
+ dbConnection.close();
+ } catch (SQLException e) {
+ System.err.println("can not close connection: " + e.getMessage());
+ }
+ }
+}
+
diff --git a/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/miniorm/DatabaseServiceException.java b/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/miniorm/DatabaseServiceException.java
new file mode 100644
index 00000000..3864471e
--- /dev/null
+++ b/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/miniorm/DatabaseServiceException.java
@@ -0,0 +1,14 @@
+package ru.fizteh.fivt.students.mamaevads.miniorm;
+
+public class DatabaseServiceException extends Exception {
+
+ public DatabaseServiceException(String message) {
+ super(message);
+ }
+
+ public DatabaseServiceException(String message, Throwable cause) {
+ super(message, cause);
+ }
+}
+
+
diff --git a/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/miniorm/PrimaryKey.java b/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/miniorm/PrimaryKey.java
new file mode 100644
index 00000000..248d33b9
--- /dev/null
+++ b/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/miniorm/PrimaryKey.java
@@ -0,0 +1,12 @@
+package ru.fizteh.fivt.students.mamaevads.miniorm;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.FIELD)
+public @interface PrimaryKey {
+}
+
diff --git a/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/miniorm/Table.java b/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/miniorm/Table.java
new file mode 100644
index 00000000..85520df0
--- /dev/null
+++ b/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/miniorm/Table.java
@@ -0,0 +1,14 @@
+package ru.fizteh.fivt.students.mamaevads.miniorm;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+public @interface Table {
+ String name() default "";
+}
+
+
diff --git a/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/moduletests/library/Arguments.java b/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/moduletests/library/Arguments.java
new file mode 100644
index 00000000..3710b217
--- /dev/null
+++ b/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/moduletests/library/Arguments.java
@@ -0,0 +1,50 @@
+package ru.fizteh.fivt.students.mamaevads.moduletests.library;
+import com.beust.jcommander.Parameter;
+
+public class Arguments {
+ private final int maxLimit = 100;
+ @Parameter(names = { "-q", "--query" },
+ description = "ключевые слова для поиска")
+ private String query = "";
+ @Parameter(names = { "-p", "--place" },
+ description = "поиск твитов в некотором регионе")
+ private String place = "";
+ @Parameter(names = { "-l", "--limit" },
+ description = "количество твитов")
+ private Integer limit = maxLimit;
+ @Parameter(names = { "-s", "--stream" },
+ description = "вывод твитов в стриминге")
+ private boolean stream = false;
+ @Parameter(names = { "--hideRetweets" },
+ description = "скрывать ретвиты")
+ private boolean hideRetweets = false;
+ @Parameter(names = { "-h", "--help" },
+ description = "помошь")
+ private boolean help = false;
+
+
+ public final String getQuery() {
+ return query;
+ }
+
+ public final String getPlace() {
+ return place;
+ }
+
+ public final Integer getLimit() {
+ return limit;
+ }
+
+ public final boolean isStream() {
+ return stream;
+ }
+
+ public final boolean isHideRetweets() {
+ return hideRetweets;
+ }
+
+ public final boolean isHelp() {
+ return help;
+ }
+}
+
diff --git a/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/moduletests/library/ArgumentsInput.java b/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/moduletests/library/ArgumentsInput.java
new file mode 100644
index 00000000..b985b3ae
--- /dev/null
+++ b/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/moduletests/library/ArgumentsInput.java
@@ -0,0 +1,21 @@
+package ru.fizteh.fivt.students.mamaevads.moduletests.library;
+import com.beust.jcommander.JCommander;
+
+
+public class ArgumentsInput {
+ public static Arguments inputArguments(String[] args) throws InvalidArgumentsException {
+ Arguments arguments = new Arguments();
+ try {
+ JCommander commander = new JCommander(arguments, args);
+ if (arguments.isHelp()) {
+ commander.usage();
+ System.exit(0);
+ }
+ } catch (Exception ex) {
+ System.err.print("Invalid arguments exception");
+ }
+ return arguments;
+ }
+}
+
+
diff --git a/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/moduletests/library/FakeTwitter.java b/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/moduletests/library/FakeTwitter.java
new file mode 100644
index 00000000..78f985c2
--- /dev/null
+++ b/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/moduletests/library/FakeTwitter.java
@@ -0,0 +1,7 @@
+package ru.fizteh.fivt.students.mamaevads.moduletests.library;
+
+/**
+ * Created by Даша on 02.12.2015.
+ */
+public class FakeTwitter {
+}
diff --git a/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/moduletests/library/GeoFeatures.java b/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/moduletests/library/GeoFeatures.java
new file mode 100644
index 00000000..9a7c2676
--- /dev/null
+++ b/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/moduletests/library/GeoFeatures.java
@@ -0,0 +1,80 @@
+package ru.fizteh.fivt.students.mamaevads.moduletests.library;
+
+import twitter4j.*;
+import java.util.List;
+
+public class GeoFeatures {
+
+ private static final double[][] MOSCOW = {{55.489926, 37.31932}, {56.009657, 37.9456611}};
+ private static final double HALF_CIRCLE = 180.0;
+ private static final double ONE = 60;
+ private static final double TWO = 1.1515;
+ private static final double KILOMETERS = 0.8684;
+ public static double getBetween(double[][] square) {
+ double lat1 = square[0][1];
+ double lat2 = square[1][1];
+ double lon1 = square[0][0];
+ double lon2 = square[1][0];
+ double theta = lon1 - lon2;
+ double dist = Math.sin(deg2rad(lat1)) * Math.sin(deg2rad(lat2))
+ + Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) * Math.cos(deg2rad(theta));
+ dist = Math.acos(dist);
+ dist = rad2deg(dist);
+ dist = dist * ONE * TWO;
+ dist = dist * KILOMETERS;
+
+ return (dist);
+ }
+
+ private static double deg2rad(double deg) {
+ return (deg * Math.PI / HALF_CIRCLE);
+ }
+
+ private static double rad2deg(double rad) {
+ return (rad * HALF_CIRCLE / Math.PI);
+ }
+
+ public static double[] getLocation(String place, Twitter twitter) {
+ double[][] square = getFilter(place);
+ double minimumLatitude = square[0][1];
+ double minimumLongitude = square[0][0];
+ double maximumLatitude = square[1][1];
+ double maximumLongitude = square[1][0];
+ return new double[]{
+ (minimumLatitude + maximumLatitude) / 2,
+ (minimumLongitude + maximumLongitude) / 2,
+ getBetween(square) / 2
+ };
+ }
+
+ public static double[][] getFilter(String place) {
+ Twitter twitter = new TwitterFactory().getInstance();
+ try {
+ GeoQuery geoQuery = new GeoQuery((String) null);
+ geoQuery.setQuery(place);
+ List placeResponseList = twitter.searchPlaces(geoQuery);
+ double minimumLatitude = Double.MAX_VALUE,
+ maximumLatitude = -Double.MAX_VALUE,
+ minimumLongitude = Double.MAX_VALUE,
+ maximumLongitude = -Double.MAX_VALUE;
+ for (GeoLocation location : placeResponseList.get(0).getBoundingBoxCoordinates()[0]) {
+ minimumLongitude = Math.min(minimumLongitude, location.getLongitude());
+ maximumLongitude = Math.max(maximumLongitude, location.getLongitude());
+ minimumLatitude = Math.min(minimumLatitude, location.getLatitude());
+ maximumLatitude = Math.max(maximumLatitude, location.getLatitude());
+
+ }
+
+ double[][] coordinates = new double[2][2];
+ coordinates[0][0] = minimumLongitude;
+ coordinates[0][1] = minimumLatitude;
+ coordinates[1][0] = maximumLongitude;
+ coordinates[1][1] = maximumLatitude;
+ return coordinates;
+ } catch (Exception e) {
+ System.err.println("Error, while trying to get location.");
+ }
+ return MOSCOW;
+ }
+}
+
diff --git a/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/moduletests/library/InvalidArgumentsException.java b/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/moduletests/library/InvalidArgumentsException.java
new file mode 100644
index 00000000..fcd994cb
--- /dev/null
+++ b/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/moduletests/library/InvalidArgumentsException.java
@@ -0,0 +1,10 @@
+package ru.fizteh.fivt.students.mamaevads.moduletests.library;
+
+/**
+ * Created by Даша on 05.10.2015.
+ */
+public class InvalidArgumentsException extends Exception {
+ public InvalidArgumentsException(String message) {
+ super(message);
+ }
+}
diff --git a/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/moduletests/library/LostInformationException.java b/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/moduletests/library/LostInformationException.java
new file mode 100644
index 00000000..551bbdf7
--- /dev/null
+++ b/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/moduletests/library/LostInformationException.java
@@ -0,0 +1,10 @@
+package ru.fizteh.fivt.students.mamaevads.moduletests.library;
+
+/**
+ * Created by Даша on 05.10.2015.
+ */
+public class LostInformationException extends Exception {
+ public LostInformationException(String message) {
+ super(message);
+ }
+}
diff --git a/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/moduletests/library/MakeMassage.java b/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/moduletests/library/MakeMassage.java
new file mode 100644
index 00000000..2496dec5
--- /dev/null
+++ b/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/moduletests/library/MakeMassage.java
@@ -0,0 +1,39 @@
+package ru.fizteh.fivt.students.mamaevads.moduletests.library;
+import twitter4j.*;
+
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+
+public class MakeMassage {
+
+ static String getName(Status st) {
+ return "@" + st.getUser().getName() + " : ";
+ }
+ static String getRetweets(Status st) {
+ int retweet = st.getRetweetCount();
+ if (retweet == 0) {
+ return "";
+ } else {
+ return "(" + retweet + WordForms.getForm(retweet, WordForms.RE_FORMS) + ")";
+ }
+ }
+ static String getMessage(Status st) {
+ String text = st.getText();
+ if (st.isRetweet()) {
+ text = " ретвитнул " + st.getRetweetedStatus().getUser().getScreenName() + " : ";
+ }
+ return text;
+ }
+
+ static String getTime(Status st) {
+ LocalDateTime tweetDate = st.getCreatedAt().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
+ LocalDateTime curDate = LocalDateTime.now();
+ return TimeHandler.getType(tweetDate, curDate);
+ }
+
+ static String info(Status st) throws LostInformationException {
+ String message = getTime(st) + " " + getName(st) + getMessage(st) + " " + getRetweets(st) + "\n";
+ message += "-----------------------------------------------------------------------------------";
+ return message;
+ }
+}
diff --git a/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/moduletests/library/TimeHandler.java b/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/moduletests/library/TimeHandler.java
new file mode 100644
index 00000000..ee7923ce
--- /dev/null
+++ b/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/moduletests/library/TimeHandler.java
@@ -0,0 +1,35 @@
+package ru.fizteh.fivt.students.mamaevads.moduletests.library;
+
+import java.time.LocalDateTime;
+import java.time.temporal.ChronoUnit;
+
+//dontreadme
+//tweet.getCreatedAt().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime(
+// LocalDateTime curDate = LocalDateTime.now();
+
+public class TimeHandler {
+ public static final int TWO_MINUTES = 120;
+
+ static String getType(LocalDateTime myDayTime, LocalDateTime nowDayTime) {
+ LocalDateTime tweetDate = myDayTime;
+ LocalDateTime curDate = nowDayTime;
+ if (ChronoUnit.SECONDS.between(tweetDate, curDate) < TWO_MINUTES) {
+ return "только что";
+ } else if (ChronoUnit.HOURS.between(tweetDate, curDate) == 0) {
+ long between = ChronoUnit.MINUTES.between(tweetDate, curDate);
+ return between + " " + WordForms.getForm(between, WordForms.MINUTES_FORMS) + " назад";
+ } else if (ChronoUnit.DAYS.between(tweetDate, curDate) <= 1) {
+ if (tweetDate.getDayOfMonth() == nowDayTime.getDayOfMonth()) {
+ long between = ChronoUnit.HOURS.between(tweetDate, curDate);
+ return between + " " + WordForms.getForm(between, WordForms.HOUR_FORMS) + " назад";
+ } else {
+ return "вчера";
+ }
+ } else {
+ long between = ChronoUnit.DAYS.between(tweetDate, curDate);
+ return between + " " + WordForms.getForm(between, WordForms.DAYS_FORMS) + " назад";
+ }
+ }
+}
+
+
diff --git a/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/moduletests/library/TweetSearch.java b/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/moduletests/library/TweetSearch.java
new file mode 100644
index 00000000..fd09871f
--- /dev/null
+++ b/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/moduletests/library/TweetSearch.java
@@ -0,0 +1,72 @@
+package ru.fizteh.fivt.students.mamaevads.moduletests.library;
+import twitter4j.*;
+import java.util.List;
+
+public class TweetSearch {
+ public static void noStreamSearch(Arguments arguments) throws TweetSearchException {
+ Twitter twitter = new TwitterFactory().getInstance();
+ Query query = new Query(arguments.getQuery());
+ int lim = arguments.getLimit();
+ if (arguments.getPlace() != "") {
+ double[] location = GeoFeatures.getLocation(arguments.getPlace(), twitter);
+ query.geoCode(new GeoLocation(location[0], location[1]), location[2], "km");
+ }
+ QueryResult queryresult;
+ boolean any = false;
+ try {
+ while (true) {
+ queryresult = twitter.search(query);
+ List tweets = queryresult.getTweets();
+ for (Status status : tweets) {
+ if (!arguments.isHideRetweets() || !status.isRetweet()) {
+ try {
+ System.out.print(MakeMassage.info(status) + "\n");
+ any = true;
+ lim--;
+ if (lim == 0) {
+ return;
+ }
+ } catch (LostInformationException ex) {
+ System.out.print("Message part was lost.");
+ }
+ }
+ }
+ query = queryresult.nextQuery();
+ if (query == null) {
+ if (!any) {
+ System.out.print("No tweets found.");
+ }
+ return;
+ }
+ }
+ } catch (TwitterException e) {
+ System.err.println(e.getMessage());
+ }
+ }
+
+ public static void twitterStream(Arguments arguments)throws TweetSearchException {
+ TwitterStream twitterStream = new TwitterStreamFactory().getInstance();
+ StatusListener listener = new StatusAdapter() {
+ @Override
+ public void onStatus(Status status) {
+ if (!arguments.isHideRetweets() || !status.isRetweet()) {
+ try {
+ System.out.print(MakeMassage.info(status) + "\n");
+ } catch (LostInformationException ex) {
+ System.err.print("Message part was lost.");
+ }
+ }
+ }
+ };
+ String[] query = {arguments.getQuery()};
+ double[][]location = GeoFeatures.getFilter(arguments.getPlace());
+ FilterQuery filter = new FilterQuery();
+ filter.track(query);
+ if (arguments.getPlace() != "") {
+ filter.locations(location);
+ }
+ twitterStream.addListener(listener);
+ twitterStream.filter(filter);
+ }
+
+}
diff --git a/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/moduletests/library/TweetSearchException.java b/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/moduletests/library/TweetSearchException.java
new file mode 100644
index 00000000..d0c8de48
--- /dev/null
+++ b/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/moduletests/library/TweetSearchException.java
@@ -0,0 +1,11 @@
+package ru.fizteh.fivt.students.mamaevads.moduletests.library;
+
+/**
+ * Created by Даша on 05.10.2015.
+ */
+public class TweetSearchException extends Exception {
+ public TweetSearchException(String message) {
+ super(message);
+ }
+}
+
diff --git a/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/moduletests/library/TwitterStreamer.java b/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/moduletests/library/TwitterStreamer.java
new file mode 100644
index 00000000..c1c16831
--- /dev/null
+++ b/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/moduletests/library/TwitterStreamer.java
@@ -0,0 +1,32 @@
+package ru.fizteh.fivt.students.mamaevads.moduletests.library;
+import twitter4j.*;
+
+public class TwitterStreamer {
+ public static void main(String[] args) throws TwitterException {
+ Arguments arguments;
+ try {
+ arguments = ArgumentsInput.inputArguments(args);
+ } catch (InvalidArgumentsException e) {
+ arguments = new Arguments();
+ System.exit(1);
+ }
+
+ if (!arguments.isStream()) {
+ try {
+ TweetSearch.noStreamSearch(arguments);
+ } catch (TweetSearchException ex) {
+ System.err.print(ex.getMessage());
+ System.exit(1);
+ }
+ } else {
+ try {
+ TweetSearch.twitterStream(arguments);
+ } catch (TweetSearchException ex) {
+ System.err.print(ex.getMessage());
+ System.exit(1);
+ }
+ }
+ }
+}
+
+
diff --git a/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/moduletests/library/WordForms.java b/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/moduletests/library/WordForms.java
new file mode 100644
index 00000000..2325525a
--- /dev/null
+++ b/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/moduletests/library/WordForms.java
@@ -0,0 +1,27 @@
+package ru.fizteh.fivt.students.mamaevads.moduletests.library;
+
+public class WordForms {
+ public static final String[] HOUR_FORMS = {"час", "часа", "часов"};
+ public static final String[] MINUTES_FORMS = {"минуту", "минуты", "минут"};
+ public static final String[] DAYS_FORMS = {"день", "дня", "дней"};
+ public static final String[] RE_FORMS = {"ретвит", "ретвита", "ретвитов"};
+
+ public static final int ONE = 1;
+ public static final int TEN = 10;
+ public static final int TWO_TEN = 20;
+ public static final int TEN_ONE = 11;
+ public static final int TWO = 2;
+ public static final int TEN_TEN = 100;
+ public static final int TWO_TWO = 4;
+
+ static String getForm(long number, String[] words) {
+ if (number == ONE || (number > TWO_TEN && number % TEN == ONE && number % TEN_TEN != TEN_ONE)) {
+ return words[0];
+ } else if ((number % TEN_TEN < TEN || number % TEN_TEN > TWO_TEN)
+ && number % TEN >= TWO && number % TEN <= TWO_TWO) {
+ return words[1];
+ } else {
+ return words[2];
+ }
+ }
+}
diff --git a/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/supertests/Arguments.java b/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/supertests/Arguments.java
new file mode 100644
index 00000000..28bec4c3
--- /dev/null
+++ b/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/supertests/Arguments.java
@@ -0,0 +1,50 @@
+package ru.fizteh.fivt.students.mamaevads.supertests;
+import com.beust.jcommander.Parameter;
+
+public class Arguments {
+ private final int maxLimit = 100;
+ @Parameter(names = { "-q", "--query" },
+ description = "ключевые слова для поиска")
+ private String query = "";
+ @Parameter(names = { "-p", "--place" },
+ description = "поиск твитов в некотором регионе")
+ private String place = "";
+ @Parameter(names = { "-l", "--limit" },
+ description = "количество твитов")
+ private Integer limit = maxLimit;
+ @Parameter(names = { "-s", "--stream" },
+ description = "вывод твитов в стриминге")
+ private boolean stream = false;
+ @Parameter(names = { "--hideRetweets" },
+ description = "скрывать ретвиты")
+ private boolean hideRetweets = false;
+ @Parameter(names = { "-h", "--help" },
+ description = "помошь")
+ private boolean help = false;
+
+
+ public final String getQuery() {
+ return query;
+ }
+
+ public final String getPlace() {
+ return place;
+ }
+
+ public final Integer getLimit() {
+ return limit;
+ }
+
+ public final boolean isStream() {
+ return stream;
+ }
+
+ public final boolean isHideRetweets() {
+ return hideRetweets;
+ }
+
+ public final boolean isHelp() {
+ return help;
+ }
+}
+
diff --git a/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/supertests/ArgumentsInput.java b/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/supertests/ArgumentsInput.java
new file mode 100644
index 00000000..c162476b
--- /dev/null
+++ b/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/supertests/ArgumentsInput.java
@@ -0,0 +1,21 @@
+package ru.fizteh.fivt.students.mamaevads.supertests;
+import com.beust.jcommander.JCommander;
+
+
+public class ArgumentsInput {
+ public static Arguments inputArguments(String[] args) throws InvalidArgumentsException {
+ Arguments arguments = new Arguments();
+ try {
+ JCommander commander = new JCommander(arguments, args);
+ if (arguments.isHelp()) {
+ commander.usage();
+ System.exit(0);
+ }
+ } catch (Exception ex) {
+ System.err.print("Invalid arguments exception");
+ }
+ return arguments;
+ }
+}
+
+
diff --git a/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/supertests/GeoFeatures.java b/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/supertests/GeoFeatures.java
new file mode 100644
index 00000000..d0a2506f
--- /dev/null
+++ b/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/supertests/GeoFeatures.java
@@ -0,0 +1,79 @@
+package ru.fizteh.fivt.students.mamaevads.supertests;
+import twitter4j.*;
+import java.util.List;
+
+public class GeoFeatures {
+
+ private static final double[][] MOSCOW = {{55.489926, 37.31932}, {56.009657, 37.9456611}};
+ private static final double HALF_CIRCLE = 180.0;
+ private static final double ONE = 60;
+ private static final double TWO = 1.1515;
+ private static final double KILOMETERS = 0.8684;
+ public static double getBetween(double[][] square) {
+ double lat1 = square[0][1];
+ double lat2 = square[1][1];
+ double lon1 = square[0][0];
+ double lon2 = square[1][0];
+ double theta = lon1 - lon2;
+ double dist = Math.sin(deg2rad(lat1)) * Math.sin(deg2rad(lat2))
+ + Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) * Math.cos(deg2rad(theta));
+ dist = Math.acos(dist);
+ dist = rad2deg(dist);
+ dist = dist * ONE * TWO;
+ dist = dist * KILOMETERS;
+
+ return (dist);
+ }
+
+ private static double deg2rad(double deg) {
+ return (deg * Math.PI / HALF_CIRCLE);
+ }
+
+ private static double rad2deg(double rad) {
+ return (rad * HALF_CIRCLE / Math.PI);
+ }
+
+ public static double[] getLocation(String place, Twitter twitter) {
+ double[][] square = getFilter(place);
+ double minimumLatitude = square[0][1];
+ double minimumLongitude = square[0][0];
+ double maximumLatitude = square[1][1];
+ double maximumLongitude = square[1][0];
+ return new double[]{
+ (minimumLatitude + maximumLatitude) / 2,
+ (minimumLongitude + maximumLongitude) / 2,
+ getBetween(square) / 2
+ };
+ }
+
+ public static double[][] getFilter(String place) {
+ Twitter twitter = new TwitterFactory().getInstance();
+ try {
+ GeoQuery geoQuery = new GeoQuery((String) null);
+ geoQuery.setQuery(place);
+ List placeResponseList = twitter.searchPlaces(geoQuery);
+ double minimumLatitude = Double.MAX_VALUE,
+ maximumLatitude = -Double.MAX_VALUE,
+ minimumLongitude = Double.MAX_VALUE,
+ maximumLongitude = -Double.MAX_VALUE;
+ for (GeoLocation location : placeResponseList.get(0).getBoundingBoxCoordinates()[0]) {
+ minimumLongitude = Math.min(minimumLongitude, location.getLongitude());
+ maximumLongitude = Math.max(maximumLongitude, location.getLongitude());
+ minimumLatitude = Math.min(minimumLatitude, location.getLatitude());
+ maximumLatitude = Math.max(maximumLatitude, location.getLatitude());
+
+ }
+
+ double[][] coordinates = new double[2][2];
+ coordinates[0][0] = minimumLongitude;
+ coordinates[0][1] = minimumLatitude;
+ coordinates[1][0] = maximumLongitude;
+ coordinates[1][1] = maximumLatitude;
+ return coordinates;
+ } catch (Exception e) {
+ System.err.println("Error, while trying to get location.");
+ }
+ return MOSCOW;
+ }
+}
+
diff --git a/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/supertests/InvalidArgumentsException.java b/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/supertests/InvalidArgumentsException.java
new file mode 100644
index 00000000..66146941
--- /dev/null
+++ b/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/supertests/InvalidArgumentsException.java
@@ -0,0 +1,10 @@
+package ru.fizteh.fivt.students.mamaevads.supertests;
+
+/**
+ * Created by Даша on 05.10.2015.
+ */
+public class InvalidArgumentsException extends Exception {
+ public InvalidArgumentsException(String message) {
+ super(message);
+ }
+}
diff --git a/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/supertests/LostInformationException.java b/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/supertests/LostInformationException.java
new file mode 100644
index 00000000..8129d137
--- /dev/null
+++ b/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/supertests/LostInformationException.java
@@ -0,0 +1,10 @@
+package ru.fizteh.fivt.students.mamaevads.supertests;
+
+/**
+ * Created by Даша on 05.10.2015.
+ */
+public class LostInformationException extends Exception {
+ public LostInformationException(String message) {
+ super(message);
+ }
+}
diff --git a/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/supertests/MakeMassage.java b/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/supertests/MakeMassage.java
new file mode 100644
index 00000000..228b4a0c
--- /dev/null
+++ b/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/supertests/MakeMassage.java
@@ -0,0 +1,40 @@
+package ru.fizteh.fivt.students.mamaevads.supertests;
+import twitter4j.*;
+
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+
+public class MakeMassage {
+
+ static String getName(Status st) {
+ return "@" + st.getUser().getName() + " : ";
+ }
+ static String getRetweets(Status st) {
+ int retweet = st.getRetweetCount();
+ if (retweet == 0) {
+ return "";
+ } else {
+ return "(" + retweet + WordForms.getForm(retweet, WordForms.RE_FORMS) + ")";
+ }
+ }
+ static String getMessage(Status st) {
+ String text = st.getText();
+ if (st.isRetweet()) {
+ text = " ретвитнул " + st.getRetweetedStatus().getUser().getScreenName() + " : ";
+ }
+ return text;
+ }
+
+ static String getTime(Status st) {
+ LocalDateTime tweetDate = st.getCreatedAt().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
+ LocalDateTime curDate = LocalDateTime.now();
+ return TimeHandler.getType(tweetDate, curDate);
+ }
+
+ static String info(Status st) throws LostInformationException {
+ String message = getTime(st) + " " + getName(st) + getMessage(st) + " " + getRetweets(st) + "\n";
+ message += "-----------------------------------------------------------------------------------";
+ return message;
+ }
+}
+
diff --git a/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/supertests/TimeHandler.java b/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/supertests/TimeHandler.java
new file mode 100644
index 00000000..9bb97dd8
--- /dev/null
+++ b/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/supertests/TimeHandler.java
@@ -0,0 +1,34 @@
+package ru.fizteh.fivt.students.mamaevads.supertests;
+import java.time.LocalDateTime;
+import java.time.temporal.ChronoUnit;
+
+//dontreadme
+//tweet.getCreatedAt().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime(
+// LocalDateTime curDate = LocalDateTime.now();
+
+public class TimeHandler {
+ public static final int TWO_MINUTES = 120;
+
+ static String getType(LocalDateTime myDayTime, LocalDateTime nowDayTime) {
+ LocalDateTime tweetDate = myDayTime;
+ LocalDateTime curDate = nowDayTime;
+ if (ChronoUnit.SECONDS.between(tweetDate, curDate) < TWO_MINUTES) {
+ return "только что";
+ } else if (ChronoUnit.HOURS.between(tweetDate, curDate) == 0) {
+ long between = ChronoUnit.MINUTES.between(tweetDate, curDate);
+ return between + " " + WordForms.getForm(between, WordForms.MINUTES_FORMS) + " назад";
+ } else if (ChronoUnit.DAYS.between(tweetDate, curDate) <= 1) {
+ if (tweetDate.getDayOfMonth() == nowDayTime.getDayOfMonth()) {
+ long between = ChronoUnit.HOURS.between(tweetDate, curDate);
+ return between + " " + WordForms.getForm(between, WordForms.HOUR_FORMS) + " назад";
+ } else {
+ return "вчера";
+ }
+ } else {
+ long between = ChronoUnit.DAYS.between(tweetDate, curDate);
+ return between + " " + WordForms.getForm(between, WordForms.DAYS_FORMS) + " назад";
+ }
+ }
+}
+
+
diff --git a/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/supertests/TweetSearch.java b/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/supertests/TweetSearch.java
new file mode 100644
index 00000000..5a2ce1bc
--- /dev/null
+++ b/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/supertests/TweetSearch.java
@@ -0,0 +1,72 @@
+package ru.fizteh.fivt.students.mamaevads.supertests;
+import twitter4j.*;
+import java.util.List;
+
+public class TweetSearch {
+ public static void noStreamSearch(Arguments arguments) throws TweetSearchException {
+ Twitter twitter = new TwitterFactory().getInstance();
+ Query query = new Query(arguments.getQuery());
+ int lim = arguments.getLimit();
+ if (arguments.getPlace() != "") {
+ double[] location = GeoFeatures.getLocation(arguments.getPlace(), twitter);
+ query.geoCode(new GeoLocation(location[0], location[1]), location[2], "km");
+ }
+ QueryResult queryresult;
+ boolean any = false;
+ try {
+ while (true) {
+ queryresult = twitter.search(query);
+ List tweets = queryresult.getTweets();
+ for (Status status : tweets) {
+ if (!arguments.isHideRetweets() || !status.isRetweet()) {
+ try {
+ System.out.print(MakeMassage.info(status) + "\n");
+ any = true;
+ lim--;
+ if (lim == 0) {
+ return;
+ }
+ } catch (LostInformationException ex) {
+ System.out.print("Message part was lost.");
+ }
+ }
+ }
+ query = queryresult.nextQuery();
+ if (query == null) {
+ if (!any) {
+ System.out.print("No tweets found.");
+ }
+ return;
+ }
+ }
+ } catch (TwitterException e) {
+ System.err.println(e.getMessage());
+ }
+ }
+
+ public static void twitterStream(Arguments arguments)throws TweetSearchException {
+ TwitterStream twitterStream = new TwitterStreamFactory().getInstance();
+ StatusListener listener = new StatusAdapter() {
+ @Override
+ public void onStatus(Status status) {
+ if (!arguments.isHideRetweets() || !status.isRetweet()) {
+ try {
+ System.out.print(MakeMassage.info(status) + "\n");
+ } catch (LostInformationException ex) {
+ System.err.print("Message part was lost.");
+ }
+ }
+ }
+ };
+ String[] query = {arguments.getQuery()};
+ double[][]location = GeoFeatures.getFilter(arguments.getPlace());
+ FilterQuery filter = new FilterQuery();
+ filter.track(query);
+ if (arguments.getPlace() != "") {
+ filter.locations(location);
+ }
+ twitterStream.addListener(listener);
+ twitterStream.filter(filter);
+ }
+
+}
diff --git a/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/supertests/TweetSearchException.java b/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/supertests/TweetSearchException.java
new file mode 100644
index 00000000..632aed83
--- /dev/null
+++ b/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/supertests/TweetSearchException.java
@@ -0,0 +1,11 @@
+package ru.fizteh.fivt.students.mamaevads.supertests;
+
+/**
+ * Created by Даша on 05.10.2015.
+ */
+public class TweetSearchException extends Exception {
+ public TweetSearchException(String message) {
+ super(message);
+ }
+}
+
diff --git a/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/supertests/TwitterStreamer.java b/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/supertests/TwitterStreamer.java
new file mode 100644
index 00000000..e5dafc5b
--- /dev/null
+++ b/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/supertests/TwitterStreamer.java
@@ -0,0 +1,32 @@
+package ru.fizteh.fivt.students.mamaevads.supertests;
+import twitter4j.*;
+
+public class TwitterStreamer {
+ public static void main(String[] args) throws TwitterException {
+ Arguments arguments;
+ try {
+ arguments = ArgumentsInput.inputArguments(args);
+ } catch (InvalidArgumentsException e) {
+ arguments = new Arguments();
+ System.exit(1);
+ }
+
+ if (!arguments.isStream()) {
+ try {
+ TweetSearch.noStreamSearch(arguments);
+ } catch (TweetSearchException ex) {
+ System.err.print(ex.getMessage());
+ System.exit(1);
+ }
+ } else {
+ try {
+ TweetSearch.twitterStream(arguments);
+ } catch (TweetSearchException ex) {
+ System.err.print(ex.getMessage());
+ System.exit(1);
+ }
+ }
+ }
+}
+
+
diff --git a/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/supertests/WordForms.java b/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/supertests/WordForms.java
new file mode 100644
index 00000000..47ad7ffe
--- /dev/null
+++ b/mamaevads/src/main/java/ru/fizteh/fivt/students/mamaevads/supertests/WordForms.java
@@ -0,0 +1,26 @@
+package ru.fizteh.fivt.students.mamaevads.supertests;
+public class WordForms {
+ public static final String[] HOUR_FORMS = {"час", "часа", "часов"};
+ public static final String[] MINUTES_FORMS = {"минуту", "минуты", "минут"};
+ public static final String[] DAYS_FORMS = {"день", "дня", "дней"};
+ public static final String[] RE_FORMS = {"ретвит", "ретвита", "ретвитов"};
+
+ public static final int ONE = 1;
+ public static final int TEN = 10;
+ public static final int TWO_TEN = 20;
+ public static final int TEN_ONE = 11;
+ public static final int TWO = 2;
+ public static final int TEN_TEN = 100;
+ public static final int TWO_TWO = 4;
+
+ static String getForm(long number, String[] words) {
+ if (number == ONE || (number > TWO_TEN && number % TEN == ONE && number % TEN_TEN != TEN_ONE)) {
+ return words[0];
+ } else if ((number % TEN_TEN < TEN || number % TEN_TEN > TWO_TEN)
+ && number % TEN >= TWO && number % TEN <= TWO_TWO) {
+ return words[1];
+ } else {
+ return words[2];
+ }
+ }
+}
diff --git a/mamaevads/src/test/java/ru/fizteh/fivt/students/mamaevads/miniorm/DatabaseServiceTest.java b/mamaevads/src/test/java/ru/fizteh/fivt/students/mamaevads/miniorm/DatabaseServiceTest.java
new file mode 100644
index 00000000..34d91026
--- /dev/null
+++ b/mamaevads/src/test/java/ru/fizteh/fivt/students/mamaevads/miniorm/DatabaseServiceTest.java
@@ -0,0 +1,75 @@
+package ru.fizteh.fivt.students.mamaevads.miniorm;
+/*import java.util.List;
+
+
+import junit.framework.TestCase;
+import org.junit.Test;
+import ru.fizteh.fivt.students.mamaevads.miniorm.Column;
+import ru.fizteh.fivt.students.mamaevads.miniorm.DatabaseService;
+import ru.fizteh.fivt.students.mamaevads.miniorm.PrimaryKey;
+import ru.fizteh.fivt.students.mamaevads.miniorm.Table;
+
+public class DatabaseServiceTest extends TestCase {
+
+ @Table
+ public static class Student {
+ @Column
+ @PrimaryKey
+ private String name;
+ @Column(name="roomnum")
+ private String room;
+ @Column
+ private Integer age;
+
+ public Student() {}
+
+ private Student(String name, String room, int age) {
+ this.name = name;
+ this.room = room;
+ this.age = age;
+ }
+
+ @Override
+ public String toString() {
+ return "Student{" + name + "|" + room + "|" + age + "}";
+ }
+ }
+
+ @Test
+ public void testTableCreation() {
+ try {
+ DatabaseService service = new DatabaseService<>(Student.class);
+ service.createTable();
+ service.dropTable();
+ } catch (Exception e) {
+ e.printStackTrace();
+ fail("failed: " + e.getMessage());
+ }
+ }
+
+ @Test
+ public void testRowOperations() {
+ try {
+ DatabaseService service = new DatabaseService<>(Student.class);
+ service.createTable();
+ service.insert(new Student("ivanov", "305", 18));
+ service.insert(new Student("petrov", "305", 18));
+ service.insert(new Student("sidorov", "306", 19));
+ service.insert(new Student("nobody", "306", 17));
+ service.update(new Student("petrov", "308", 18));
+ service.deleteByKey("sidorov");
+ service.delete(new Student("nobody", "308", 30));
+
+ assertNull(service.queryById("sidorov"));
+ assertEquals("[Student{ivanov|305|18}, Student{petrov|308|18}]", service.queryForAll().toString());
+ service.dropTable();
+ } catch (Exception e) {
+ e.printStackTrace();
+ fail("failed: " + e.getMessage());
+ }
+ }
+
+
+}
+
+*/
\ No newline at end of file
diff --git a/mamaevads/src/test/java/ru/fizteh/fivt/students/mamaevads/moduletests/library/TimeHandlerTest.java b/mamaevads/src/test/java/ru/fizteh/fivt/students/mamaevads/moduletests/library/TimeHandlerTest.java
new file mode 100644
index 00000000..fad64f7c
--- /dev/null
+++ b/mamaevads/src/test/java/ru/fizteh/fivt/students/mamaevads/moduletests/library/TimeHandlerTest.java
@@ -0,0 +1,52 @@
+package ru.fizteh.fivt.students.mamaevads.moduletests.library;
+
+import junit.framework.TestCase;
+import org.junit.Test;
+import junit.framework.Assert;
+
+import java.time.LocalDateTime;
+import java.time.Month;
+
+
+public class TimeHandlerTest extends TestCase {
+
+ @Test
+ public void testGetType() throws Exception {
+ LocalDateTime timeOne = LocalDateTime.of(2010, Month.JANUARY, 20, 15, 0, 4);
+ LocalDateTime timeTwo = LocalDateTime.of(2010, Month.JANUARY, 20, 15, 2, 3);
+ assertEquals("только что", TimeHandler.getType(timeOne,timeTwo));
+ timeOne = LocalDateTime.of(2010, Month.JANUARY, 20, 23, 59, 25);
+ timeTwo = LocalDateTime.of(2010, Month.JANUARY, 21, 00, 00, 30);
+ assertEquals("только что", TimeHandler.getType(timeOne,timeTwo));
+ timeOne = LocalDateTime.of(2010, Month.JANUARY, 20, 15, 1, 1);
+ timeTwo = LocalDateTime.of(2010, Month.JANUARY, 20, 15, 3, 3);
+ assertEquals("2 минуты назад", TimeHandler.getType(timeOne,timeTwo));
+ timeOne = LocalDateTime.of(2010, Month.JANUARY, 20, 15, 1, 1);
+ timeTwo = LocalDateTime.of(2010, Month.JANUARY, 20, 16, 1, 0);
+ assertEquals("59 минут назад", TimeHandler.getType(timeOne,timeTwo));
+ timeOne = LocalDateTime.of(2010, Month.JANUARY, 20, 13, 1, 1);
+ timeTwo = LocalDateTime.of(2010, Month.JANUARY, 20, 16, 1, 0);
+ assertEquals("2 часа назад", TimeHandler.getType(timeOne,timeTwo));
+ timeOne = LocalDateTime.of(2010, Month.JANUARY, 20, 23, 1, 1);
+ timeTwo = LocalDateTime.of(2010, Month.JANUARY, 21, 02, 1, 0);
+ assertEquals("вчера", TimeHandler.getType(timeOne,timeTwo));
+ timeOne = LocalDateTime.of(2012, Month.FEBRUARY, 26, 00, 1, 1);
+ timeTwo = LocalDateTime.of(2012, Month.FEBRUARY, 27, 23, 59, 59);
+ assertEquals("вчера", TimeHandler.getType(timeOne,timeTwo));
+ timeOne = LocalDateTime.of(2012, Month.FEBRUARY, 25, 00, 1, 1);
+ timeTwo = LocalDateTime.of(2012, Month.FEBRUARY, 27, 23, 59, 59);
+ assertEquals("2 дня назад", TimeHandler.getType(timeOne, timeTwo));
+ timeOne = LocalDateTime.of(2012, Month.FEBRUARY, 28, 00, 1, 1); //Leap year
+ timeTwo = LocalDateTime.of(2012, Month.MARCH, 01, 23, 59, 59);
+ assertEquals("2 дня назад", TimeHandler.getType(timeOne, timeTwo));
+ timeOne = LocalDateTime.of(2012, Month.FEBRUARY, 29, 1, 1, 1);
+ timeTwo = LocalDateTime.of(2012, Month.MARCH, 01, 22, 59, 59);
+ assertEquals("вчера", TimeHandler.getType(timeOne, timeTwo));
+ timeOne = LocalDateTime.of(2012, Month.FEBRUARY, 28, 1, 1, 1);
+ timeTwo = LocalDateTime.of(2012, Month.MARCH, 06, 22, 59, 59);
+ assertEquals("7 дней назад", TimeHandler.getType(timeOne, timeTwo));
+ timeOne = LocalDateTime.of(2011, Month.FEBRUARY, 28, 1, 1, 1);
+ timeTwo = LocalDateTime.of(2011, Month.MARCH, 06, 22, 59, 59);
+ assertEquals("6 дней назад", TimeHandler.getType(timeOne, timeTwo));
+ }
+}
\ No newline at end of file
diff --git a/mamaevads/src/test/java/ru/fizteh/fivt/students/mamaevads/moduletests/library/WordFormsTest.java b/mamaevads/src/test/java/ru/fizteh/fivt/students/mamaevads/moduletests/library/WordFormsTest.java
new file mode 100644
index 00000000..6dfd9785
--- /dev/null
+++ b/mamaevads/src/test/java/ru/fizteh/fivt/students/mamaevads/moduletests/library/WordFormsTest.java
@@ -0,0 +1,45 @@
+package ru.fizteh.fivt.students.mamaevads.moduletests.library;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+import org.junit.Test;
+
+public class WordFormsTest extends TestCase {
+
+ @Test
+ public void testGetForm() throws Exception {
+ Assert.assertEquals("день", WordForms.getForm(1, WordForms.DAYS_FORMS));
+ Assert.assertEquals("минуту", WordForms.getForm(1, WordForms.MINUTES_FORMS));
+ Assert.assertEquals("час", WordForms.getForm(1, WordForms.HOUR_FORMS));
+ Assert.assertEquals("дня", WordForms.getForm(2, WordForms.DAYS_FORMS));
+ Assert.assertEquals("минуты", WordForms.getForm(2, WordForms.MINUTES_FORMS));
+ Assert.assertEquals("часа", WordForms.getForm(2, WordForms.HOUR_FORMS));
+ Assert.assertEquals("дня", WordForms.getForm(4, WordForms.DAYS_FORMS));
+ Assert.assertEquals("минуты", WordForms.getForm(4, WordForms.MINUTES_FORMS));
+ Assert.assertEquals("часа", WordForms.getForm(4, WordForms.HOUR_FORMS));
+ Assert.assertEquals("дней", WordForms.getForm(12, WordForms.DAYS_FORMS));
+ Assert.assertEquals("минут", WordForms.getForm(12, WordForms.MINUTES_FORMS));
+ Assert.assertEquals("часов", WordForms.getForm(12, WordForms.HOUR_FORMS));
+ Assert.assertEquals("дней", WordForms.getForm(14, WordForms.DAYS_FORMS));
+ Assert.assertEquals("минут", WordForms.getForm(14, WordForms.MINUTES_FORMS));
+ Assert.assertEquals("часов", WordForms.getForm(14, WordForms.HOUR_FORMS));
+ Assert.assertEquals("дня", WordForms.getForm(22, WordForms.DAYS_FORMS));
+ Assert.assertEquals("минуты", WordForms.getForm(22, WordForms.MINUTES_FORMS));
+ Assert.assertEquals("часа", WordForms.getForm(22, WordForms.HOUR_FORMS));
+ Assert.assertEquals("дня", WordForms.getForm(24, WordForms.DAYS_FORMS));
+ Assert.assertEquals("минуты", WordForms.getForm(24, WordForms.MINUTES_FORMS));
+ Assert.assertEquals("часа", WordForms.getForm(24, WordForms.HOUR_FORMS));
+ Assert.assertEquals("дней", WordForms.getForm(11, WordForms.DAYS_FORMS));
+ Assert.assertEquals("минут", WordForms.getForm(11, WordForms.MINUTES_FORMS));
+ Assert.assertEquals("часов", WordForms.getForm(11, WordForms.HOUR_FORMS));
+ Assert.assertEquals("дней", WordForms.getForm(111, WordForms.DAYS_FORMS));
+ Assert.assertEquals("минут", WordForms.getForm(111, WordForms.MINUTES_FORMS));
+ Assert.assertEquals("часов", WordForms.getForm(111, WordForms.HOUR_FORMS));
+ Assert.assertEquals("день", WordForms.getForm(131, WordForms.DAYS_FORMS));
+ Assert.assertEquals("минуту", WordForms.getForm(131, WordForms.MINUTES_FORMS));
+ Assert.assertEquals("час", WordForms.getForm(131, WordForms.HOUR_FORMS));
+ Assert.assertEquals("дней", WordForms.getForm(113, WordForms.DAYS_FORMS));
+ Assert.assertEquals("минут", WordForms.getForm(113, WordForms.MINUTES_FORMS));
+ Assert.assertEquals("часов", WordForms.getForm(113, WordForms.HOUR_FORMS));
+ }
+}
\ No newline at end of file
diff --git a/mamaevads/src/test/java/ru/fizteh/fivt/students/mamaevads/supertests/TimeHandlerTest.java b/mamaevads/src/test/java/ru/fizteh/fivt/students/mamaevads/supertests/TimeHandlerTest.java
new file mode 100644
index 00000000..af0ec718
--- /dev/null
+++ b/mamaevads/src/test/java/ru/fizteh/fivt/students/mamaevads/supertests/TimeHandlerTest.java
@@ -0,0 +1,53 @@
+package ru.fizteh.fivt.students.mamaevads.supertests;
+
+
+import junit.framework.TestCase;
+import org.junit.Test;
+import junit.framework.Assert;
+
+import java.time.LocalDateTime;
+import java.time.Month;
+
+
+public class TimeHandlerTest extends TestCase {
+
+ @Test
+ public void testGetType() throws Exception {
+ LocalDateTime timeOne = LocalDateTime.of(2010, Month.JANUARY, 20, 15, 0, 4);
+ LocalDateTime timeTwo = LocalDateTime.of(2010, Month.JANUARY, 20, 15, 2, 3);
+ assertEquals("только что", TimeHandler.getType(timeOne,timeTwo));
+ timeOne = LocalDateTime.of(2010, Month.JANUARY, 20, 23, 59, 25);
+ timeTwo = LocalDateTime.of(2010, Month.JANUARY, 21, 00, 00, 30);
+ assertEquals("только что", TimeHandler.getType(timeOne,timeTwo));
+ timeOne = LocalDateTime.of(2010, Month.JANUARY, 20, 15, 1, 1);
+ timeTwo = LocalDateTime.of(2010, Month.JANUARY, 20, 15, 3, 3);
+ assertEquals("2 минуты назад", TimeHandler.getType(timeOne,timeTwo));
+ timeOne = LocalDateTime.of(2010, Month.JANUARY, 20, 15, 1, 1);
+ timeTwo = LocalDateTime.of(2010, Month.JANUARY, 20, 16, 1, 0);
+ assertEquals("59 минут назад", TimeHandler.getType(timeOne,timeTwo));
+ timeOne = LocalDateTime.of(2010, Month.JANUARY, 20, 13, 1, 1);
+ timeTwo = LocalDateTime.of(2010, Month.JANUARY, 20, 16, 1, 0);
+ assertEquals("2 часа назад", TimeHandler.getType(timeOne,timeTwo));
+ timeOne = LocalDateTime.of(2010, Month.JANUARY, 20, 23, 1, 1);
+ timeTwo = LocalDateTime.of(2010, Month.JANUARY, 21, 02, 1, 0);
+ assertEquals("вчера", TimeHandler.getType(timeOne,timeTwo));
+ timeOne = LocalDateTime.of(2012, Month.FEBRUARY, 26, 00, 1, 1);
+ timeTwo = LocalDateTime.of(2012, Month.FEBRUARY, 27, 23, 59, 59);
+ assertEquals("вчера", TimeHandler.getType(timeOne,timeTwo));
+ timeOne = LocalDateTime.of(2012, Month.FEBRUARY, 25, 00, 1, 1);
+ timeTwo = LocalDateTime.of(2012, Month.FEBRUARY, 27, 23, 59, 59);
+ assertEquals("2 дня назад", TimeHandler.getType(timeOne, timeTwo));
+ timeOne = LocalDateTime.of(2012, Month.FEBRUARY, 28, 00, 1, 1); //Leap year
+ timeTwo = LocalDateTime.of(2012, Month.MARCH, 01, 23, 59, 59);
+ assertEquals("2 дня назад", TimeHandler.getType(timeOne, timeTwo));
+ timeOne = LocalDateTime.of(2012, Month.FEBRUARY, 29, 1, 1, 1);
+ timeTwo = LocalDateTime.of(2012, Month.MARCH, 01, 22, 59, 59);
+ assertEquals("вчера", TimeHandler.getType(timeOne, timeTwo));
+ timeOne = LocalDateTime.of(2012, Month.FEBRUARY, 28, 1, 1, 1);
+ timeTwo = LocalDateTime.of(2012, Month.MARCH, 06, 22, 59, 59);
+ assertEquals("7 дней назад", TimeHandler.getType(timeOne, timeTwo));
+ timeOne = LocalDateTime.of(2011, Month.FEBRUARY, 28, 1, 1, 1);
+ timeTwo = LocalDateTime.of(2011, Month.MARCH, 06, 22, 59, 59);
+ assertEquals("6 дней назад", TimeHandler.getType(timeOne, timeTwo));
+ }
+}
\ No newline at end of file
diff --git a/mamaevads/src/test/java/ru/fizteh/fivt/students/mamaevads/supertests/WordFormsTest.java b/mamaevads/src/test/java/ru/fizteh/fivt/students/mamaevads/supertests/WordFormsTest.java
new file mode 100644
index 00000000..d28a2601
--- /dev/null
+++ b/mamaevads/src/test/java/ru/fizteh/fivt/students/mamaevads/supertests/WordFormsTest.java
@@ -0,0 +1,45 @@
+package ru.fizteh.fivt.students.mamaevads.supertests;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+import org.junit.Test;
+
+public class WordFormsTest extends TestCase {
+
+ @Test
+ public void testGetForm() throws Exception {
+ Assert.assertEquals("день", WordForms.getForm(1, WordForms.DAYS_FORMS));
+ Assert.assertEquals("минуту", WordForms.getForm(1, WordForms.MINUTES_FORMS));
+ Assert.assertEquals("час", WordForms.getForm(1, WordForms.HOUR_FORMS));
+ Assert.assertEquals("дня", WordForms.getForm(2, WordForms.DAYS_FORMS));
+ Assert.assertEquals("минуты", WordForms.getForm(2, WordForms.MINUTES_FORMS));
+ Assert.assertEquals("часа", WordForms.getForm(2, WordForms.HOUR_FORMS));
+ Assert.assertEquals("дня", WordForms.getForm(4, WordForms.DAYS_FORMS));
+ Assert.assertEquals("минуты", WordForms.getForm(4, WordForms.MINUTES_FORMS));
+ Assert.assertEquals("часа", WordForms.getForm(4, WordForms.HOUR_FORMS));
+ Assert.assertEquals("дней", WordForms.getForm(12, WordForms.DAYS_FORMS));
+ Assert.assertEquals("минут", WordForms.getForm(12, WordForms.MINUTES_FORMS));
+ Assert.assertEquals("часов", WordForms.getForm(12, WordForms.HOUR_FORMS));
+ Assert.assertEquals("дней", WordForms.getForm(14, WordForms.DAYS_FORMS));
+ Assert.assertEquals("минут", WordForms.getForm(14, WordForms.MINUTES_FORMS));
+ Assert.assertEquals("часов", WordForms.getForm(14, WordForms.HOUR_FORMS));
+ Assert.assertEquals("дня", WordForms.getForm(22, WordForms.DAYS_FORMS));
+ Assert.assertEquals("минуты", WordForms.getForm(22, WordForms.MINUTES_FORMS));
+ Assert.assertEquals("часа", WordForms.getForm(22, WordForms.HOUR_FORMS));
+ Assert.assertEquals("дня", WordForms.getForm(24, WordForms.DAYS_FORMS));
+ Assert.assertEquals("минуты", WordForms.getForm(24, WordForms.MINUTES_FORMS));
+ Assert.assertEquals("часа", WordForms.getForm(24, WordForms.HOUR_FORMS));
+ Assert.assertEquals("дней", WordForms.getForm(11, WordForms.DAYS_FORMS));
+ Assert.assertEquals("минут", WordForms.getForm(11, WordForms.MINUTES_FORMS));
+ Assert.assertEquals("часов", WordForms.getForm(11, WordForms.HOUR_FORMS));
+ Assert.assertEquals("дней", WordForms.getForm(111, WordForms.DAYS_FORMS));
+ Assert.assertEquals("минут", WordForms.getForm(111, WordForms.MINUTES_FORMS));
+ Assert.assertEquals("часов", WordForms.getForm(111, WordForms.HOUR_FORMS));
+ Assert.assertEquals("день", WordForms.getForm(131, WordForms.DAYS_FORMS));
+ Assert.assertEquals("минуту", WordForms.getForm(131, WordForms.MINUTES_FORMS));
+ Assert.assertEquals("час", WordForms.getForm(131, WordForms.HOUR_FORMS));
+ Assert.assertEquals("дней", WordForms.getForm(113, WordForms.DAYS_FORMS));
+ Assert.assertEquals("минут", WordForms.getForm(113, WordForms.MINUTES_FORMS));
+ Assert.assertEquals("часов", WordForms.getForm(113, WordForms.HOUR_FORMS));
+ }
+}
\ No newline at end of file