From 1b244186223171d68de2965bb0390e6d4b9de885 Mon Sep 17 00:00:00 2001 From: andreyzharkov Date: Tue, 13 Oct 2015 20:41:00 +0300 Subject: [PATCH 1/9] TwitterStream is almost ready --- .gitignore | 1 + checkstyle.xml | 4 +- projects/andreyzharkov/java | 0 projects/andreyzharkov/pom.xml | 82 +++++++ .../ru/mipt/diht/students/ArgumentsList.java | 70 ++++++ .../mipt/diht/students/LocationSearcher.java | 89 ++++++++ .../ru/mipt/diht/students/TimeDeclension.java | 50 +++++ .../diht/students/TwitterOutputEditor.java | 209 ++++++++++++++++++ .../ru/mipt/diht/students/TwitterStream.java | 86 +++++++ .../java/ru/mipt/diht/students/AppTest.java | 38 ++++ projects/checkstyle.xml | 6 +- projects/pom.xml | 1 + 12 files changed, 633 insertions(+), 3 deletions(-) create mode 100644 projects/andreyzharkov/java create mode 100644 projects/andreyzharkov/pom.xml create mode 100644 projects/andreyzharkov/src/main/java/ru/mipt/diht/students/ArgumentsList.java create mode 100644 projects/andreyzharkov/src/main/java/ru/mipt/diht/students/LocationSearcher.java create mode 100644 projects/andreyzharkov/src/main/java/ru/mipt/diht/students/TimeDeclension.java create mode 100644 projects/andreyzharkov/src/main/java/ru/mipt/diht/students/TwitterOutputEditor.java create mode 100644 projects/andreyzharkov/src/main/java/ru/mipt/diht/students/TwitterStream.java create mode 100644 projects/andreyzharkov/src/test/java/ru/mipt/diht/students/AppTest.java diff --git a/.gitignore b/.gitignore index 1e056e9..9df57d9 100644 --- a/.gitignore +++ b/.gitignore @@ -18,3 +18,4 @@ workbench.xmi *.swp .settings .checkstyle +twitter4j.properties \ No newline at end of file diff --git a/checkstyle.xml b/checkstyle.xml index b14e3ae..c26d1ec 100644 --- a/checkstyle.xml +++ b/checkstyle.xml @@ -107,7 +107,9 @@ - + + + diff --git a/projects/andreyzharkov/java b/projects/andreyzharkov/java new file mode 100644 index 0000000..e69de29 diff --git a/projects/andreyzharkov/pom.xml b/projects/andreyzharkov/pom.xml new file mode 100644 index 0000000..b57d8c2 --- /dev/null +++ b/projects/andreyzharkov/pom.xml @@ -0,0 +1,82 @@ + + 4.0.0 + + ru.mipt.diht.students + andreyzharkov + 1.0-SNAPSHOT + jar + + andreyzharkov + http://maven.apache.org + + + UTF-8 + + + + ru.mipt.diht.students + parent + 1.0-SNAPSHOT + + + + + junit + junit + 3.8.1 + test + + + org.twitter4j + twitter4j-core + [4.0,) + + + org.twitter4j + twitter4j-stream + [4.0,) + + + com.beust + jcommander + 1.48 + + + + + + + maven-compiler-plugin + 3.1 + + 1.8 + 1.8 + + + + maven-assembly-plugin + + + jar-with-dependencies + + + + ru.mipt.diht.students.TwitterStream + + + + + + package + + single + + + + + + + + + diff --git a/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/ArgumentsList.java b/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/ArgumentsList.java new file mode 100644 index 0000000..1c2b5f7 --- /dev/null +++ b/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/ArgumentsList.java @@ -0,0 +1,70 @@ +package ru.mipt.diht.students; + +import java.util.ArrayList; +import java.util.List; + +import com.beust.jcommander.Parameter; + +/** + * Created by Андрей on 09.10.2015. + */ +public class ArgumentsList { + private static final int DEFAULT_TWEETS_LIMIT = 10; + private static final String DEFAULT_QUERY = ""; + + @Parameter + private final List parameters = new ArrayList(); + + @Parameter(names = {"-q", "--query"}, description = + "Keywords for looking for, separating by whitespaces") + private String query = DEFAULT_QUERY; + + public final String getQueryString() { + return query; + } + + @Parameter(names = {"-p", "--place"}, description = + "Location of looking for") + private String place = "anywhere"; + + public final String getPlace() { + return place; + } + + public final void checkLocation() { + place = TwitterStream.checkLocation(place); + System.out.println(place); + } + + @Parameter(names = {"-s", "--stream"}, description = + "Stream mode: every second print new tweets, exit by esc") + private boolean stream = false; + + public final boolean isStream() { + return stream; + } + + @Parameter(names = {"-r", "--hideRetweets"}, description = + "Don't print any retweeted posts") + private boolean hideretweets = false; + + public final boolean isRetweetsHidden() { + return hideretweets; + } + + @Parameter(names = {"-l", "--limit"}, description = + "Maximum tweets for out. Only if --stream is disabled") + private int tweetLimit = DEFAULT_TWEETS_LIMIT; + + public final int getTweetLimit() { + return tweetLimit; + } + + @Parameter(names = {"-h", "--help"}, description = + "Print this page and exit", help = true) + private boolean help = false; + + public final boolean isHelp() { + return help; + } +} diff --git a/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/LocationSearcher.java b/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/LocationSearcher.java new file mode 100644 index 0000000..722ba78 --- /dev/null +++ b/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/LocationSearcher.java @@ -0,0 +1,89 @@ +package ru.mipt.diht.students; + +import twitter4j.GeoLocation; +import twitter4j.Place; +import twitter4j.ResponseList; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by Андрей on 11.10.2015. + */ +public class LocationSearcher { + private static final double DEGREES_TO_KM = 60 * 1.1515 * 1.609344; + + private List searchLocations = new ArrayList(); + + public LocationSearcher(ResponseList searchPlaces) throws Exception { + for (Place place : searchPlaces) { + for (int x = 0; x < place.getBoundingBoxCoordinates().length; ++x) { + for (int y = 0; y < place.getBoundingBoxCoordinates()[x].length; ++y) { + searchLocations.add(place.getBoundingBoxCoordinates()[x][y]); + } + } + } + if (searchLocations.isEmpty()) { + throw new Exception("too few places in placelist"); + } + } + + private static double getCoordinatesDistance(GeoLocation locationFrom, GeoLocation locationTo) { + double theta = locationFrom.getLongitude() - locationTo.getLongitude(); + double distance = Math.sin(Math.toRadians(locationFrom.getLatitude())) + * Math.sin(Math.toRadians(locationTo.getLatitude())) + + Math.cos(Math.toRadians(locationFrom.getLatitude())) + * Math.cos(Math.toRadians(locationTo.getLatitude())) + * Math.cos(Math.toRadians(theta)); + distance = Math.acos(distance); + return Math.toDegrees(distance) * DEGREES_TO_KM; + } + + public final GeoLocation getCenter() { + double xCenter = 0; + double yCenter = 0; + for (GeoLocation location : searchLocations) { + xCenter = xCenter + location.getLatitude(); + yCenter = yCenter + location.getLongitude(); + } + return new GeoLocation(xCenter / searchLocations.size(), yCenter / searchLocations.size()); + } + + public final double getRadius() { + double radius = 0; + GeoLocation center = getCenter(); + for (GeoLocation location : searchLocations) { + radius = radius + getCoordinatesDistance(center, location); + } + return (radius / searchLocations.size()) + 1; + } + + public final double[][] getBoundingBox() { + double minX = searchLocations.get(0).getLatitude(); + double maxX = searchLocations.get(0).getLatitude(); + double minY = searchLocations.get(0).getLongitude(); + double maxY = searchLocations.get(0).getLongitude(); + + for (GeoLocation location : searchLocations) { + if (location.getLatitude() < minX) { + minX = location.getLatitude(); + } + if (location.getLatitude() > maxX) { + maxX = location.getLatitude(); + } + if (location.getLongitude() < minY) { + minY = location.getLongitude(); + } + if (location.getLongitude() > maxY) { + maxY = location.getLongitude(); + } + } + return new double[][]{{minX, minY}, {maxX, maxY}}; + } + + public final String toString() { + return "(" + getCenter().getLatitude() + ", " + + getCenter().getLongitude() + ") with r = " + + getRadius() + "."; + } +} diff --git a/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/TimeDeclension.java b/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/TimeDeclension.java new file mode 100644 index 0000000..29d8a2e --- /dev/null +++ b/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/TimeDeclension.java @@ -0,0 +1,50 @@ +package ru.mipt.diht.students; + +/** + * Created by Андрей on 11.10.2015. + */ +public class TimeDeclension { + public static final String timeInRightForm(String timeUnion, int count) { + switch (count % 10) { + case 1: + if (count / 10 != 1) { + switch (timeUnion) { + case "DAY": + return "день"; + case "HOUR": + return "час"; + case "MINUTE": + return "минуту"; + default: + return "Wrong Arguments"; + } + } + case 2: + case 3: + case 4: + if (count / 10 != 1) { + switch (timeUnion) { + case "DAY": + return "дня"; + case "HOUR": + return "часа"; + case "MINUTE": + return "минуты"; + default: + return "Wrong Arguments"; + } + } + default: + switch (timeUnion) { + case "DAY": + return "дней"; + case "HOUR": + return "часов"; + case "MINUTE": + return "минут"; + default: + return "Wrong Arguments"; + } + } + } +} diff --git a/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/TwitterOutputEditor.java b/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/TwitterOutputEditor.java new file mode 100644 index 0000000..96bfa8e --- /dev/null +++ b/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/TwitterOutputEditor.java @@ -0,0 +1,209 @@ +package ru.mipt.diht.students; + +import java.io.IOException; +import java.time.Duration; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.util.Date; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; + +import twitter4j.*; + +/** + * Created by Андрей on 10.10.2015. + */ +public class TwitterOutputEditor { + //colors + private static final String SET_BLUE = (char) 27 + "[" + (char) 34 + "m"; + private static final String SET_STANDART = (char) 27 + "[" + (char) 37 + "m"; + //private static final String SET_BLUE = ""; + //private static final String SET_STANDART = ""; + private static final int SLEEP_TIME = 1000; + private static final int QUEUE_MAX_SIZE = 1000; + private static final char EXIT_KEY = (char) 27; + + private Twitter twitter; + private ArgumentsList programArguments; + private BlockingQueue streamQueue; + + TwitterOutputEditor(ArgumentsList prArguments) { + twitter = new TwitterFactory().getInstance(); + this.programArguments = prArguments; + } + + + public final String convertTime(Date date) { + LocalDateTime currentDateTime = LocalDateTime.now(); + LocalDateTime tweetDateTime = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime(); + Duration timeAfterTweet = Duration.between(tweetDateTime, currentDateTime); + if (timeAfterTweet.toMinutes() < 2) { + return "только что"; + } + if (timeAfterTweet.toHours() < 1) { + return (int) (timeAfterTweet.toMinutes()) + " " + + TimeDeclension.timeInRightForm("MINUTE", (int) (timeAfterTweet.toMinutes())) + " назад"; + } + if (currentDateTime.toLocalDate().equals(tweetDateTime.toLocalDate())) { + return (int) (timeAfterTweet.toHours()) + " " + + TimeDeclension.timeInRightForm("HOUR", (int) (timeAfterTweet.toHours())) + " назад"; + } + if (currentDateTime.toLocalDate().minusDays(1).equals(tweetDateTime.toLocalDate())) { + return "вчера"; + } + return (int) (timeAfterTweet.toDays()) + " " + + TimeDeclension.timeInRightForm("DAY", (int) (timeAfterTweet.toDays())) + " назад"; + } + + final String convertNick(User user) { + return SET_BLUE + "@" + user.getName() + SET_STANDART; + } + + final String convertRetweetsCount(int count) { + if (count == 0) { + return ""; + } + if (count == 1) { + return "(1 ретвит)"; + } + return "(" + count + " ретвитов)"; + } + + final void printOneTweet(Status tweet, boolean withDate) { + String result = ""; + if (withDate) { + result += "[" + convertTime(tweet.getCreatedAt()) + "] "; + } + result += (convertNick(tweet.getUser()) + " "); + if (tweet.isRetweet()) { + result += ("ретвитнул " + convertNick(tweet.getRetweetedStatus().getUser())); + } + + result += (tweet.getText() + " "); + result += convertRetweetsCount(tweet.getRetweetCount()); + System.out.println(result); + } + + public final LocationSearcher findLocation(String region) throws TwitterException { + if (region == "anywhere") { + return null; + } + GeoQuery geoQuery = new GeoQuery("1.1.1.1"); //ip need for init + geoQuery.setQuery(region); + ResponseList searchPlaces = twitter.searchPlaces(geoQuery); + LocationSearcher location; + try { + location = new LocationSearcher(searchPlaces); + } catch (Exception ex) { + location = null; + } + return location; + } + + final void simpleMode() { + while (true) { + try { + Query query = new Query(programArguments.getQueryString()); + LocationSearcher location = findLocation(programArguments.getPlace()); + if (location != null) { + //System.out.println("Search by location success!"); + query.setGeoCode(location.getCenter(), location.getRadius(), Query.Unit.km); + } + if (location == null) { + System.out.println("Search by location failed!"); + } + + QueryResult result = twitter.search(query); + int tweetsCounter = 0; + + System.out.print("Твиты по запросу \"" + + programArguments.getQueryString() + "\" для " + + programArguments.getPlace() + ":"); + if (result.getTweets().size() == 0) { + System.out.println("ничего не найдено!"); + return; + } else { + System.out.println(""); + } + do { + for (Status status : result.getTweets()) { + if (!(status.isRetweet() && programArguments.isRetweetsHidden())) { + printOneTweet(status, true); + if (++tweetsCounter == programArguments.getTweetLimit()) { + return; + } + } + } + if (result.hasNext()) { + result = twitter.search(result.nextQuery()); + } else { + break; + } + } while (tweetsCounter < programArguments.getTweetLimit()); + if (tweetsCounter == 0) { + System.out.println("ничего не найдено!"); + } + return; + } catch (TwitterException te) { + //te.printStackTrace(); + System.err.println("Failed to run twitter. I'm trying once more.. "); + } + } + } + + private StatusListener tweetListener = new StatusAdapter() { + public void onStatus(Status tweet) { + if ((!programArguments.isRetweetsHidden() || !tweet.isRetweet())) { + streamQueue.add(tweet); + } + } + }; + + final void streamMode() { + while (true) { + try { + streamQueue = new ArrayBlockingQueue(QUEUE_MAX_SIZE); + twitter4j.TwitterStream twitterStream = new TwitterStreamFactory().getInstance(); + twitterStream.addListener(tweetListener); + FilterQuery filterQuery = new FilterQuery(); + filterQuery.track(new String[]{programArguments.getQueryString()}); + LocationSearcher location = findLocation(programArguments.getPlace()); + if (location != null) { + filterQuery.locations(location.getBoundingBox()); + } + twitterStream.filter(filterQuery); + System.out.println("Stream mode on! Press 'q'&&Enter to exit!"); + + while (true) { + while (!streamQueue.isEmpty()) { + Status tweet = streamQueue.poll(); + printOneTweet(tweet, false); + } + try { + boolean needExit = false; + while (System.in.available() > 0) { + int c = System.in.read(); + if (c == 'q' || c == EXIT_KEY || c == -1) { + twitterStream.shutdown(); + needExit = true; + break; + } + } + if (needExit) { + break; + } + } catch (IOException e) { + System.err.println("cannot read from stdin: " + e.getMessage()); + } + Thread.sleep(SLEEP_TIME); + } + return; + } catch (TwitterException te) { + te.printStackTrace(); + System.err.println("Failed to run twitter. I'm trying once more.. "); + } catch (InterruptedException e) { + System.err.println("Failed to sleep!"); + } + } + } +} diff --git a/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/TwitterStream.java b/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/TwitterStream.java new file mode 100644 index 0000000..1f2feeb --- /dev/null +++ b/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/TwitterStream.java @@ -0,0 +1,86 @@ +package ru.mipt.diht.students; + +import twitter4j.*; +import com.beust.jcommander.JCommander; +import com.beust.jcommander.ParameterException; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.URL; +import java.net.URLConnection; + +/** + * Created by Андрей on 09.10.2015. + */ +public class TwitterStream { + public static void main(String[] args) { + ArgumentsList programArguments = new ArgumentsList(); + JCommander jcommander; + try { + jcommander = new JCommander(programArguments, args); + } catch (ParameterException pe) { + System.out.println(pe.getMessage()); + System.out.println("You can use --help to learn more."); + System.exit(1); + return; + } + + if (programArguments.isHelp()) { + System.out.println("This program can print in stdout some tweets," + + "searched at twitter.com and filtered by options:"); + jcommander.usage(); + return; + } + + programArguments.checkLocation(); + + TwitterOutputEditor twitterEditor = new TwitterOutputEditor(programArguments); + + if (!programArguments.isStream()) { + twitterEditor.simpleMode(); + } else { + twitterEditor.streamMode(); + } + } + + private static String getUrlSource(String url) throws IOException { + URL realURL = new URL(url); + URLConnection connection = realURL.openConnection(); + BufferedReader urlReader = new BufferedReader( + new InputStreamReader(connection.getInputStream(), "UTF-8")); + String inputLine = urlReader.readLine(); + StringBuilder sourceString = new StringBuilder(); + while (inputLine != null) { + sourceString.append(inputLine); + inputLine = urlReader.readLine(); + } + urlReader.close(); + + return sourceString.toString(); + } + + private static String getMyLocation() throws IOException { + //telize site JSON output look like "getgeoip({"parameter":"value","parameter":"value",...})" + String[] geoSiteSource = getUrlSource("http://www.telize.com/geoip?callback=getgeoip").split("[,\":]+"); + for (int i = 0; i < geoSiteSource.length; ++i) { + if (geoSiteSource[i].equals("city") && i < geoSiteSource.length - 1) { + return geoSiteSource[i + 1]; + } + } + return "anywhere"; + } + + public static String checkLocation(String queryString) { + if (queryString.equals("nearby")) { + try { + return getMyLocation(); + } catch (IOException e) { + System.err.println("Failed to calculate your location by IP, " + e.getMessage() + + ". Searching tweets from anywhere."); + return "anywhere"; + } + } + return queryString; + } +} diff --git a/projects/andreyzharkov/src/test/java/ru/mipt/diht/students/AppTest.java b/projects/andreyzharkov/src/test/java/ru/mipt/diht/students/AppTest.java new file mode 100644 index 0000000..4bb8dd4 --- /dev/null +++ b/projects/andreyzharkov/src/test/java/ru/mipt/diht/students/AppTest.java @@ -0,0 +1,38 @@ +package ru.mipt.diht.students; + +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/checkstyle.xml b/projects/checkstyle.xml index 49bf662..34d6397 100644 --- a/projects/checkstyle.xml +++ b/projects/checkstyle.xml @@ -107,7 +107,9 @@ - + + + @@ -145,7 +147,7 @@ - + diff --git a/projects/pom.xml b/projects/pom.xml index f0dd988..4d1558d 100644 --- a/projects/pom.xml +++ b/projects/pom.xml @@ -29,6 +29,7 @@ dkhurtin ale3otik + andreyzharkov From 9c7a09cea864548523e5e5e91eca697f80220c6c Mon Sep 17 00:00:00 2001 From: andreyzharkov Date: Wed, 14 Oct 2015 19:31:48 +0300 Subject: [PATCH 2/9] =?UTF-8?q?=D0=A2=D0=B5=D0=BF=D0=B5=D1=80=D1=8C=20?= =?UTF-8?q?=D0=B2=D1=81=D1=91=20=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=B0=D0=B5?= =?UTF-8?q?=D1=82.=20=D0=9D=D0=B5=D0=B4=D0=BE=D1=87=D1=91=D1=82=D1=8B=20?= =?UTF-8?q?=D0=B8=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D1=8B.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- projects/andreyzharkov/pom.xml | 5 +++++ .../java/ru/mipt/diht/students/ArgumentsList.java | 5 ++--- .../java/ru/mipt/diht/students/TimeDeclension.java | 12 +++++++----- .../ru/mipt/diht/students/TwitterOutputEditor.java | 9 +++++++-- .../java/ru/mipt/diht/students/TwitterStream.java | 1 - projects/checkstyle.xml | 4 ++-- 6 files changed, 23 insertions(+), 13 deletions(-) diff --git a/projects/andreyzharkov/pom.xml b/projects/andreyzharkov/pom.xml index b57d8c2..b2c18f9 100644 --- a/projects/andreyzharkov/pom.xml +++ b/projects/andreyzharkov/pom.xml @@ -10,6 +10,11 @@ andreyzharkov http://maven.apache.org + + Travis CI + https://travis-ci.org/KhurtinDN/fizteh-java-2015 + + UTF-8 diff --git a/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/ArgumentsList.java b/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/ArgumentsList.java index 1c2b5f7..656385b 100644 --- a/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/ArgumentsList.java +++ b/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/ArgumentsList.java @@ -10,14 +10,13 @@ */ public class ArgumentsList { private static final int DEFAULT_TWEETS_LIMIT = 10; - private static final String DEFAULT_QUERY = ""; @Parameter private final List parameters = new ArrayList(); @Parameter(names = {"-q", "--query"}, description = - "Keywords for looking for, separating by whitespaces") - private String query = DEFAULT_QUERY; + "Keywords for looking for, separating by whitespaces", required = true) + private String query; public final String getQueryString() { return query; diff --git a/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/TimeDeclension.java b/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/TimeDeclension.java index 29d8a2e..cc1cda9 100644 --- a/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/TimeDeclension.java +++ b/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/TimeDeclension.java @@ -4,10 +4,12 @@ * Created by Андрей on 11.10.2015. */ public class TimeDeclension { + private static final int TEN = 10; + public static final String timeInRightForm(String timeUnion, int count) { - switch (count % 10) { + switch (count % TEN) { case 1: - if (count / 10 != 1) { + if (count / TEN % TEN != 1) { switch (timeUnion) { case "DAY": return "день"; @@ -20,9 +22,9 @@ public static final String timeInRightForm(String timeUnion, int count) { } } case 2: - case 3: - case 4: - if (count / 10 != 1) { + case 2 + 1://Because 3 and 4 are magic numbers + case 2 + 2: + if (count / TEN % TEN != 1) { switch (timeUnion) { case "DAY": return "дня"; diff --git a/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/TwitterOutputEditor.java b/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/TwitterOutputEditor.java index 96bfa8e..8f2bdb2 100644 --- a/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/TwitterOutputEditor.java +++ b/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/TwitterOutputEditor.java @@ -22,6 +22,7 @@ public class TwitterOutputEditor { private static final int SLEEP_TIME = 1000; private static final int QUEUE_MAX_SIZE = 1000; private static final char EXIT_KEY = (char) 27; + private static final String SEARCH_BY_LOCATION_FAILED = "too few places in placelist"; private Twitter twitter; private ArgumentsList programArguments; @@ -94,10 +95,14 @@ public final LocationSearcher findLocation(String region) throws TwitterExceptio LocationSearcher location; try { location = new LocationSearcher(searchPlaces); + return location; } catch (Exception ex) { - location = null; + if (ex.getMessage() == SEARCH_BY_LOCATION_FAILED) { + System.err.println(SEARCH_BY_LOCATION_FAILED); + return null; + } } - return location; + return null; } final void simpleMode() { diff --git a/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/TwitterStream.java b/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/TwitterStream.java index 1f2feeb..c858025 100644 --- a/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/TwitterStream.java +++ b/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/TwitterStream.java @@ -1,6 +1,5 @@ package ru.mipt.diht.students; -import twitter4j.*; import com.beust.jcommander.JCommander; import com.beust.jcommander.ParameterException; diff --git a/projects/checkstyle.xml b/projects/checkstyle.xml index 34d6397..ddbde8a 100644 --- a/projects/checkstyle.xml +++ b/projects/checkstyle.xml @@ -108,7 +108,7 @@ - + @@ -147,7 +147,7 @@ - + From cbefb155ab176ce0cf1b51b9061ee8207eab9a8d Mon Sep 17 00:00:00 2001 From: andreyzharkov Date: Thu, 15 Oct 2015 01:09:13 +0300 Subject: [PATCH 3/9] Some fixes --- .../ru/mipt/diht/students/ArgumentsList.java | 5 +- .../mipt/diht/students/LocationSearcher.java | 2 +- .../ru/mipt/diht/students/Translator.java | 53 +++++++++++++++++++ .../diht/students/TwitterOutputEditor.java | 20 +++---- 4 files changed, 67 insertions(+), 13 deletions(-) create mode 100644 projects/andreyzharkov/src/main/java/ru/mipt/diht/students/Translator.java diff --git a/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/ArgumentsList.java b/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/ArgumentsList.java index 656385b..f73a864 100644 --- a/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/ArgumentsList.java +++ b/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/ArgumentsList.java @@ -9,7 +9,7 @@ * Created by Андрей on 09.10.2015. */ public class ArgumentsList { - private static final int DEFAULT_TWEETS_LIMIT = 10; + private static final int DEFAULT_TWEETS_LIMIT = 100; @Parameter private final List parameters = new ArrayList(); @@ -24,7 +24,7 @@ public final String getQueryString() { @Parameter(names = {"-p", "--place"}, description = "Location of looking for") - private String place = "anywhere"; + private String place = "nearby"; public final String getPlace() { return place; @@ -32,7 +32,6 @@ public final String getPlace() { public final void checkLocation() { place = TwitterStream.checkLocation(place); - System.out.println(place); } @Parameter(names = {"-s", "--stream"}, description = diff --git a/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/LocationSearcher.java b/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/LocationSearcher.java index 722ba78..48efd76 100644 --- a/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/LocationSearcher.java +++ b/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/LocationSearcher.java @@ -24,7 +24,7 @@ public LocationSearcher(ResponseList searchPlaces) throws Exception { } } if (searchLocations.isEmpty()) { - throw new Exception("too few places in placelist"); + throw new Exception("Too few places in placelist."); } } diff --git a/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/Translator.java b/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/Translator.java new file mode 100644 index 0000000..00f7621 --- /dev/null +++ b/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/Translator.java @@ -0,0 +1,53 @@ +package ru.mipt.diht.students; + +import javax.net.ssl.HttpsURLConnection; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; + +/** + * Created by Андрей on 14.10.2015. + */ +public class Translator { + //нормально переводит только с английского на русский, но не наоборот + //ибо какая-то проблема с кодировкой + private static int tryingTimes = 0; + + public static String translate(String lang, String input) throws IOException { + tryingTimes++; + + if (input.equals("Dolgoprudnyy")) { + return "Долгопрудный"; //костыль. yandex translated Doldoprudnyy as "Долгопрудном", что не ищется + } + + String urlStr = "https://translate.yandex.net/api/v1.5/tr.json/translate?key=" + + "trnsl.1.1.20151014T174735Z.84c9a75c05df4e5e.cb5a00eacf7657d7969a3c2a0e1421712d67bdb5"; + urlStr += "&text=" + input + "&lang=" + lang; + URL urlObj = new URL(urlStr); + HttpsURLConnection connection = (HttpsURLConnection) urlObj.openConnection(); + + InputStream response = connection.getInputStream(); + String json = new java.util.Scanner(response).nextLine(); + int start = json.indexOf("["); + int end = json.indexOf("]"); + String translated; + if (lang == "en-ru") { + String translatedIncorrect = json.substring(start + 2, end - 1); + byte[] b = translatedIncorrect.getBytes(); + translated = new String(b, "UTF-8"); + //System.out.println(translated); + } else { + translated = json.substring(start + 2, end - 1); + } + + if (translated.equals(input)) { + if (tryingTimes > 2) { + tryingTimes = 0; + return input; + } + return translate("en-ru", input); //метод из программы вызывается с lang="ru-en" + } + tryingTimes = 0; + return translated; + } +} diff --git a/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/TwitterOutputEditor.java b/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/TwitterOutputEditor.java index 8f2bdb2..24f0fed 100644 --- a/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/TwitterOutputEditor.java +++ b/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/TwitterOutputEditor.java @@ -22,7 +22,7 @@ public class TwitterOutputEditor { private static final int SLEEP_TIME = 1000; private static final int QUEUE_MAX_SIZE = 1000; private static final char EXIT_KEY = (char) 27; - private static final String SEARCH_BY_LOCATION_FAILED = "too few places in placelist"; + private static final String SEARCH_BY_LOCATION_FAILED = "Search by location failed! Show results from anywhere."; private Twitter twitter; private ArgumentsList programArguments; @@ -90,19 +90,24 @@ public final LocationSearcher findLocation(String region) throws TwitterExceptio return null; } GeoQuery geoQuery = new GeoQuery("1.1.1.1"); //ip need for init - geoQuery.setQuery(region); - ResponseList searchPlaces = twitter.searchPlaces(geoQuery); + ResponseList searchPlaces; LocationSearcher location; try { + geoQuery.setQuery(region); + searchPlaces = twitter.searchPlaces(geoQuery); location = new LocationSearcher(searchPlaces); return location; } catch (Exception ex) { - if (ex.getMessage() == SEARCH_BY_LOCATION_FAILED) { - System.err.println(SEARCH_BY_LOCATION_FAILED); + try { + geoQuery.setQuery(Translator.translate("ru-en", region)); + searchPlaces = twitter.searchPlaces(geoQuery); + location = new LocationSearcher(searchPlaces); + return location; + } catch (Exception e) { + System.out.println(SEARCH_BY_LOCATION_FAILED); return null; } } - return null; } final void simpleMode() { @@ -114,9 +119,6 @@ final void simpleMode() { //System.out.println("Search by location success!"); query.setGeoCode(location.getCenter(), location.getRadius(), Query.Unit.km); } - if (location == null) { - System.out.println("Search by location failed!"); - } QueryResult result = twitter.search(query); int tweetsCounter = 0; From a0756b9688c5dd8e73a28d98b924cd6536ee6347 Mon Sep 17 00:00:00 2001 From: andreyzharkov Date: Tue, 15 Dec 2015 19:43:49 +0300 Subject: [PATCH 4/9] deletions --- .gitignore | 3 +- projects/andreyzharkov/pom.xml | 2 +- .../ru/mipt/diht/students/ArgumentsList.java | 68 ------ .../mipt/diht/students/LocationSearcher.java | 89 -------- .../ru/mipt/diht/students/TimeDeclension.java | 52 ----- .../ru/mipt/diht/students/Translator.java | 53 ----- .../diht/students/TwitterOutputEditor.java | 216 ------------------ .../ru/mipt/diht/students/TwitterStream.java | 85 ------- .../java/ru/mipt/diht/students/AppTest.java | 38 --- 9 files changed, 3 insertions(+), 603 deletions(-) delete mode 100644 projects/andreyzharkov/src/main/java/ru/mipt/diht/students/ArgumentsList.java delete mode 100644 projects/andreyzharkov/src/main/java/ru/mipt/diht/students/LocationSearcher.java delete mode 100644 projects/andreyzharkov/src/main/java/ru/mipt/diht/students/TimeDeclension.java delete mode 100644 projects/andreyzharkov/src/main/java/ru/mipt/diht/students/Translator.java delete mode 100644 projects/andreyzharkov/src/main/java/ru/mipt/diht/students/TwitterOutputEditor.java delete mode 100644 projects/andreyzharkov/src/main/java/ru/mipt/diht/students/TwitterStream.java delete mode 100644 projects/andreyzharkov/src/test/java/ru/mipt/diht/students/AppTest.java diff --git a/.gitignore b/.gitignore index 9df57d9..8797c1c 100644 --- a/.gitignore +++ b/.gitignore @@ -18,4 +18,5 @@ workbench.xmi *.swp .settings .checkstyle -twitter4j.properties \ No newline at end of file +twitter4j.properties +key.txt \ No newline at end of file diff --git a/projects/andreyzharkov/pom.xml b/projects/andreyzharkov/pom.xml index b2c18f9..e578997 100644 --- a/projects/andreyzharkov/pom.xml +++ b/projects/andreyzharkov/pom.xml @@ -67,7 +67,7 @@ - ru.mipt.diht.students.TwitterStream + ru.mipt.diht.students.andreyzharkov.collectionquery.CollectionQuery diff --git a/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/ArgumentsList.java b/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/ArgumentsList.java deleted file mode 100644 index f73a864..0000000 --- a/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/ArgumentsList.java +++ /dev/null @@ -1,68 +0,0 @@ -package ru.mipt.diht.students; - -import java.util.ArrayList; -import java.util.List; - -import com.beust.jcommander.Parameter; - -/** - * Created by Андрей on 09.10.2015. - */ -public class ArgumentsList { - private static final int DEFAULT_TWEETS_LIMIT = 100; - - @Parameter - private final List parameters = new ArrayList(); - - @Parameter(names = {"-q", "--query"}, description = - "Keywords for looking for, separating by whitespaces", required = true) - private String query; - - public final String getQueryString() { - return query; - } - - @Parameter(names = {"-p", "--place"}, description = - "Location of looking for") - private String place = "nearby"; - - public final String getPlace() { - return place; - } - - public final void checkLocation() { - place = TwitterStream.checkLocation(place); - } - - @Parameter(names = {"-s", "--stream"}, description = - "Stream mode: every second print new tweets, exit by esc") - private boolean stream = false; - - public final boolean isStream() { - return stream; - } - - @Parameter(names = {"-r", "--hideRetweets"}, description = - "Don't print any retweeted posts") - private boolean hideretweets = false; - - public final boolean isRetweetsHidden() { - return hideretweets; - } - - @Parameter(names = {"-l", "--limit"}, description = - "Maximum tweets for out. Only if --stream is disabled") - private int tweetLimit = DEFAULT_TWEETS_LIMIT; - - public final int getTweetLimit() { - return tweetLimit; - } - - @Parameter(names = {"-h", "--help"}, description = - "Print this page and exit", help = true) - private boolean help = false; - - public final boolean isHelp() { - return help; - } -} diff --git a/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/LocationSearcher.java b/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/LocationSearcher.java deleted file mode 100644 index 48efd76..0000000 --- a/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/LocationSearcher.java +++ /dev/null @@ -1,89 +0,0 @@ -package ru.mipt.diht.students; - -import twitter4j.GeoLocation; -import twitter4j.Place; -import twitter4j.ResponseList; - -import java.util.ArrayList; -import java.util.List; - -/** - * Created by Андрей on 11.10.2015. - */ -public class LocationSearcher { - private static final double DEGREES_TO_KM = 60 * 1.1515 * 1.609344; - - private List searchLocations = new ArrayList(); - - public LocationSearcher(ResponseList searchPlaces) throws Exception { - for (Place place : searchPlaces) { - for (int x = 0; x < place.getBoundingBoxCoordinates().length; ++x) { - for (int y = 0; y < place.getBoundingBoxCoordinates()[x].length; ++y) { - searchLocations.add(place.getBoundingBoxCoordinates()[x][y]); - } - } - } - if (searchLocations.isEmpty()) { - throw new Exception("Too few places in placelist."); - } - } - - private static double getCoordinatesDistance(GeoLocation locationFrom, GeoLocation locationTo) { - double theta = locationFrom.getLongitude() - locationTo.getLongitude(); - double distance = Math.sin(Math.toRadians(locationFrom.getLatitude())) - * Math.sin(Math.toRadians(locationTo.getLatitude())) - + Math.cos(Math.toRadians(locationFrom.getLatitude())) - * Math.cos(Math.toRadians(locationTo.getLatitude())) - * Math.cos(Math.toRadians(theta)); - distance = Math.acos(distance); - return Math.toDegrees(distance) * DEGREES_TO_KM; - } - - public final GeoLocation getCenter() { - double xCenter = 0; - double yCenter = 0; - for (GeoLocation location : searchLocations) { - xCenter = xCenter + location.getLatitude(); - yCenter = yCenter + location.getLongitude(); - } - return new GeoLocation(xCenter / searchLocations.size(), yCenter / searchLocations.size()); - } - - public final double getRadius() { - double radius = 0; - GeoLocation center = getCenter(); - for (GeoLocation location : searchLocations) { - radius = radius + getCoordinatesDistance(center, location); - } - return (radius / searchLocations.size()) + 1; - } - - public final double[][] getBoundingBox() { - double minX = searchLocations.get(0).getLatitude(); - double maxX = searchLocations.get(0).getLatitude(); - double minY = searchLocations.get(0).getLongitude(); - double maxY = searchLocations.get(0).getLongitude(); - - for (GeoLocation location : searchLocations) { - if (location.getLatitude() < minX) { - minX = location.getLatitude(); - } - if (location.getLatitude() > maxX) { - maxX = location.getLatitude(); - } - if (location.getLongitude() < minY) { - minY = location.getLongitude(); - } - if (location.getLongitude() > maxY) { - maxY = location.getLongitude(); - } - } - return new double[][]{{minX, minY}, {maxX, maxY}}; - } - - public final String toString() { - return "(" + getCenter().getLatitude() + ", " - + getCenter().getLongitude() + ") with r = " - + getRadius() + "."; - } -} diff --git a/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/TimeDeclension.java b/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/TimeDeclension.java deleted file mode 100644 index cc1cda9..0000000 --- a/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/TimeDeclension.java +++ /dev/null @@ -1,52 +0,0 @@ -package ru.mipt.diht.students; - -/** - * Created by Андрей on 11.10.2015. - */ -public class TimeDeclension { - private static final int TEN = 10; - - public static final String timeInRightForm(String timeUnion, int count) { - switch (count % TEN) { - case 1: - if (count / TEN % TEN != 1) { - switch (timeUnion) { - case "DAY": - return "день"; - case "HOUR": - return "час"; - case "MINUTE": - return "минуту"; - default: - return "Wrong Arguments"; - } - } - case 2: - case 2 + 1://Because 3 and 4 are magic numbers - case 2 + 2: - if (count / TEN % TEN != 1) { - switch (timeUnion) { - case "DAY": - return "дня"; - case "HOUR": - return "часа"; - case "MINUTE": - return "минуты"; - default: - return "Wrong Arguments"; - } - } - default: - switch (timeUnion) { - case "DAY": - return "дней"; - case "HOUR": - return "часов"; - case "MINUTE": - return "минут"; - default: - return "Wrong Arguments"; - } - } - } -} diff --git a/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/Translator.java b/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/Translator.java deleted file mode 100644 index 00f7621..0000000 --- a/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/Translator.java +++ /dev/null @@ -1,53 +0,0 @@ -package ru.mipt.diht.students; - -import javax.net.ssl.HttpsURLConnection; -import java.io.IOException; -import java.io.InputStream; -import java.net.URL; - -/** - * Created by Андрей on 14.10.2015. - */ -public class Translator { - //нормально переводит только с английского на русский, но не наоборот - //ибо какая-то проблема с кодировкой - private static int tryingTimes = 0; - - public static String translate(String lang, String input) throws IOException { - tryingTimes++; - - if (input.equals("Dolgoprudnyy")) { - return "Долгопрудный"; //костыль. yandex translated Doldoprudnyy as "Долгопрудном", что не ищется - } - - String urlStr = "https://translate.yandex.net/api/v1.5/tr.json/translate?key=" - + "trnsl.1.1.20151014T174735Z.84c9a75c05df4e5e.cb5a00eacf7657d7969a3c2a0e1421712d67bdb5"; - urlStr += "&text=" + input + "&lang=" + lang; - URL urlObj = new URL(urlStr); - HttpsURLConnection connection = (HttpsURLConnection) urlObj.openConnection(); - - InputStream response = connection.getInputStream(); - String json = new java.util.Scanner(response).nextLine(); - int start = json.indexOf("["); - int end = json.indexOf("]"); - String translated; - if (lang == "en-ru") { - String translatedIncorrect = json.substring(start + 2, end - 1); - byte[] b = translatedIncorrect.getBytes(); - translated = new String(b, "UTF-8"); - //System.out.println(translated); - } else { - translated = json.substring(start + 2, end - 1); - } - - if (translated.equals(input)) { - if (tryingTimes > 2) { - tryingTimes = 0; - return input; - } - return translate("en-ru", input); //метод из программы вызывается с lang="ru-en" - } - tryingTimes = 0; - return translated; - } -} diff --git a/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/TwitterOutputEditor.java b/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/TwitterOutputEditor.java deleted file mode 100644 index 24f0fed..0000000 --- a/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/TwitterOutputEditor.java +++ /dev/null @@ -1,216 +0,0 @@ -package ru.mipt.diht.students; - -import java.io.IOException; -import java.time.Duration; -import java.time.LocalDateTime; -import java.time.ZoneId; -import java.util.Date; -import java.util.concurrent.ArrayBlockingQueue; -import java.util.concurrent.BlockingQueue; - -import twitter4j.*; - -/** - * Created by Андрей on 10.10.2015. - */ -public class TwitterOutputEditor { - //colors - private static final String SET_BLUE = (char) 27 + "[" + (char) 34 + "m"; - private static final String SET_STANDART = (char) 27 + "[" + (char) 37 + "m"; - //private static final String SET_BLUE = ""; - //private static final String SET_STANDART = ""; - private static final int SLEEP_TIME = 1000; - private static final int QUEUE_MAX_SIZE = 1000; - private static final char EXIT_KEY = (char) 27; - private static final String SEARCH_BY_LOCATION_FAILED = "Search by location failed! Show results from anywhere."; - - private Twitter twitter; - private ArgumentsList programArguments; - private BlockingQueue streamQueue; - - TwitterOutputEditor(ArgumentsList prArguments) { - twitter = new TwitterFactory().getInstance(); - this.programArguments = prArguments; - } - - - public final String convertTime(Date date) { - LocalDateTime currentDateTime = LocalDateTime.now(); - LocalDateTime tweetDateTime = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime(); - Duration timeAfterTweet = Duration.between(tweetDateTime, currentDateTime); - if (timeAfterTweet.toMinutes() < 2) { - return "только что"; - } - if (timeAfterTweet.toHours() < 1) { - return (int) (timeAfterTweet.toMinutes()) + " " - + TimeDeclension.timeInRightForm("MINUTE", (int) (timeAfterTweet.toMinutes())) + " назад"; - } - if (currentDateTime.toLocalDate().equals(tweetDateTime.toLocalDate())) { - return (int) (timeAfterTweet.toHours()) + " " - + TimeDeclension.timeInRightForm("HOUR", (int) (timeAfterTweet.toHours())) + " назад"; - } - if (currentDateTime.toLocalDate().minusDays(1).equals(tweetDateTime.toLocalDate())) { - return "вчера"; - } - return (int) (timeAfterTweet.toDays()) + " " - + TimeDeclension.timeInRightForm("DAY", (int) (timeAfterTweet.toDays())) + " назад"; - } - - final String convertNick(User user) { - return SET_BLUE + "@" + user.getName() + SET_STANDART; - } - - final String convertRetweetsCount(int count) { - if (count == 0) { - return ""; - } - if (count == 1) { - return "(1 ретвит)"; - } - return "(" + count + " ретвитов)"; - } - - final void printOneTweet(Status tweet, boolean withDate) { - String result = ""; - if (withDate) { - result += "[" + convertTime(tweet.getCreatedAt()) + "] "; - } - result += (convertNick(tweet.getUser()) + " "); - if (tweet.isRetweet()) { - result += ("ретвитнул " + convertNick(tweet.getRetweetedStatus().getUser())); - } - - result += (tweet.getText() + " "); - result += convertRetweetsCount(tweet.getRetweetCount()); - System.out.println(result); - } - - public final LocationSearcher findLocation(String region) throws TwitterException { - if (region == "anywhere") { - return null; - } - GeoQuery geoQuery = new GeoQuery("1.1.1.1"); //ip need for init - ResponseList searchPlaces; - LocationSearcher location; - try { - geoQuery.setQuery(region); - searchPlaces = twitter.searchPlaces(geoQuery); - location = new LocationSearcher(searchPlaces); - return location; - } catch (Exception ex) { - try { - geoQuery.setQuery(Translator.translate("ru-en", region)); - searchPlaces = twitter.searchPlaces(geoQuery); - location = new LocationSearcher(searchPlaces); - return location; - } catch (Exception e) { - System.out.println(SEARCH_BY_LOCATION_FAILED); - return null; - } - } - } - - final void simpleMode() { - while (true) { - try { - Query query = new Query(programArguments.getQueryString()); - LocationSearcher location = findLocation(programArguments.getPlace()); - if (location != null) { - //System.out.println("Search by location success!"); - query.setGeoCode(location.getCenter(), location.getRadius(), Query.Unit.km); - } - - QueryResult result = twitter.search(query); - int tweetsCounter = 0; - - System.out.print("Твиты по запросу \"" - + programArguments.getQueryString() + "\" для " - + programArguments.getPlace() + ":"); - if (result.getTweets().size() == 0) { - System.out.println("ничего не найдено!"); - return; - } else { - System.out.println(""); - } - do { - for (Status status : result.getTweets()) { - if (!(status.isRetweet() && programArguments.isRetweetsHidden())) { - printOneTweet(status, true); - if (++tweetsCounter == programArguments.getTweetLimit()) { - return; - } - } - } - if (result.hasNext()) { - result = twitter.search(result.nextQuery()); - } else { - break; - } - } while (tweetsCounter < programArguments.getTweetLimit()); - if (tweetsCounter == 0) { - System.out.println("ничего не найдено!"); - } - return; - } catch (TwitterException te) { - //te.printStackTrace(); - System.err.println("Failed to run twitter. I'm trying once more.. "); - } - } - } - - private StatusListener tweetListener = new StatusAdapter() { - public void onStatus(Status tweet) { - if ((!programArguments.isRetweetsHidden() || !tweet.isRetweet())) { - streamQueue.add(tweet); - } - } - }; - - final void streamMode() { - while (true) { - try { - streamQueue = new ArrayBlockingQueue(QUEUE_MAX_SIZE); - twitter4j.TwitterStream twitterStream = new TwitterStreamFactory().getInstance(); - twitterStream.addListener(tweetListener); - FilterQuery filterQuery = new FilterQuery(); - filterQuery.track(new String[]{programArguments.getQueryString()}); - LocationSearcher location = findLocation(programArguments.getPlace()); - if (location != null) { - filterQuery.locations(location.getBoundingBox()); - } - twitterStream.filter(filterQuery); - System.out.println("Stream mode on! Press 'q'&&Enter to exit!"); - - while (true) { - while (!streamQueue.isEmpty()) { - Status tweet = streamQueue.poll(); - printOneTweet(tweet, false); - } - try { - boolean needExit = false; - while (System.in.available() > 0) { - int c = System.in.read(); - if (c == 'q' || c == EXIT_KEY || c == -1) { - twitterStream.shutdown(); - needExit = true; - break; - } - } - if (needExit) { - break; - } - } catch (IOException e) { - System.err.println("cannot read from stdin: " + e.getMessage()); - } - Thread.sleep(SLEEP_TIME); - } - return; - } catch (TwitterException te) { - te.printStackTrace(); - System.err.println("Failed to run twitter. I'm trying once more.. "); - } catch (InterruptedException e) { - System.err.println("Failed to sleep!"); - } - } - } -} diff --git a/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/TwitterStream.java b/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/TwitterStream.java deleted file mode 100644 index c858025..0000000 --- a/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/TwitterStream.java +++ /dev/null @@ -1,85 +0,0 @@ -package ru.mipt.diht.students; - -import com.beust.jcommander.JCommander; -import com.beust.jcommander.ParameterException; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.net.URL; -import java.net.URLConnection; - -/** - * Created by Андрей on 09.10.2015. - */ -public class TwitterStream { - public static void main(String[] args) { - ArgumentsList programArguments = new ArgumentsList(); - JCommander jcommander; - try { - jcommander = new JCommander(programArguments, args); - } catch (ParameterException pe) { - System.out.println(pe.getMessage()); - System.out.println("You can use --help to learn more."); - System.exit(1); - return; - } - - if (programArguments.isHelp()) { - System.out.println("This program can print in stdout some tweets," - + "searched at twitter.com and filtered by options:"); - jcommander.usage(); - return; - } - - programArguments.checkLocation(); - - TwitterOutputEditor twitterEditor = new TwitterOutputEditor(programArguments); - - if (!programArguments.isStream()) { - twitterEditor.simpleMode(); - } else { - twitterEditor.streamMode(); - } - } - - private static String getUrlSource(String url) throws IOException { - URL realURL = new URL(url); - URLConnection connection = realURL.openConnection(); - BufferedReader urlReader = new BufferedReader( - new InputStreamReader(connection.getInputStream(), "UTF-8")); - String inputLine = urlReader.readLine(); - StringBuilder sourceString = new StringBuilder(); - while (inputLine != null) { - sourceString.append(inputLine); - inputLine = urlReader.readLine(); - } - urlReader.close(); - - return sourceString.toString(); - } - - private static String getMyLocation() throws IOException { - //telize site JSON output look like "getgeoip({"parameter":"value","parameter":"value",...})" - String[] geoSiteSource = getUrlSource("http://www.telize.com/geoip?callback=getgeoip").split("[,\":]+"); - for (int i = 0; i < geoSiteSource.length; ++i) { - if (geoSiteSource[i].equals("city") && i < geoSiteSource.length - 1) { - return geoSiteSource[i + 1]; - } - } - return "anywhere"; - } - - public static String checkLocation(String queryString) { - if (queryString.equals("nearby")) { - try { - return getMyLocation(); - } catch (IOException e) { - System.err.println("Failed to calculate your location by IP, " + e.getMessage() - + ". Searching tweets from anywhere."); - return "anywhere"; - } - } - return queryString; - } -} diff --git a/projects/andreyzharkov/src/test/java/ru/mipt/diht/students/AppTest.java b/projects/andreyzharkov/src/test/java/ru/mipt/diht/students/AppTest.java deleted file mode 100644 index 4bb8dd4..0000000 --- a/projects/andreyzharkov/src/test/java/ru/mipt/diht/students/AppTest.java +++ /dev/null @@ -1,38 +0,0 @@ -package ru.mipt.diht.students; - -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 ); - } -} From 49da2f5b310fbd97a8469fbbf89a191482bd1d8a Mon Sep 17 00:00:00 2001 From: andreyzharkov Date: Wed, 16 Dec 2015 18:29:55 +0300 Subject: [PATCH 5/9] linelength --- checkstyle.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/checkstyle.xml b/checkstyle.xml index c26d1ec..eae5b01 100644 --- a/checkstyle.xml +++ b/checkstyle.xml @@ -108,7 +108,7 @@ - + From e046d4a7658919820086f38da6ed00d083dd0bff Mon Sep 17 00:00:00 2001 From: andreyzharkov Date: Thu, 17 Dec 2015 14:06:15 +0300 Subject: [PATCH 6/9] orm functionality --- projects/andreyzharkov/pom.xml | 94 ++--- .../andreyzharkov/miniORM/AnnotatedField.java | 62 ++++ .../miniORM/DatabaseService.java | 328 ++++++++++++++++++ .../miniORM/DatabaseServiceException.java | 14 + .../miniORM/annotations/Column.java | 15 + .../miniORM/annotations/PrimaryKey.java | 15 + .../miniORM/annotations/Table.java | 15 + 7 files changed, 501 insertions(+), 42 deletions(-) create mode 100644 projects/andreyzharkov/src/main/java/ru/mipt/diht/students/andreyzharkov/miniORM/AnnotatedField.java create mode 100644 projects/andreyzharkov/src/main/java/ru/mipt/diht/students/andreyzharkov/miniORM/DatabaseService.java create mode 100644 projects/andreyzharkov/src/main/java/ru/mipt/diht/students/andreyzharkov/miniORM/DatabaseServiceException.java create mode 100644 projects/andreyzharkov/src/main/java/ru/mipt/diht/students/andreyzharkov/miniORM/annotations/Column.java create mode 100644 projects/andreyzharkov/src/main/java/ru/mipt/diht/students/andreyzharkov/miniORM/annotations/PrimaryKey.java create mode 100644 projects/andreyzharkov/src/main/java/ru/mipt/diht/students/andreyzharkov/miniORM/annotations/Table.java diff --git a/projects/andreyzharkov/pom.xml b/projects/andreyzharkov/pom.xml index e578997..fc2d142 100644 --- a/projects/andreyzharkov/pom.xml +++ b/projects/andreyzharkov/pom.xml @@ -1,55 +1,65 @@ - 4.0.0 + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 - ru.mipt.diht.students - andreyzharkov - 1.0-SNAPSHOT - jar + ru.mipt.diht.students + andreyzharkov + 1.0-SNAPSHOT + jar - andreyzharkov - http://maven.apache.org + andreyzharkov + http://maven.apache.org - + Travis CI https://travis-ci.org/KhurtinDN/fizteh-java-2015 - - UTF-8 - + + UTF-8 + - - ru.mipt.diht.students - parent - 1.0-SNAPSHOT - + + ru.mipt.diht.students + parent + 1.0-SNAPSHOT + - - - junit - junit - 3.8.1 - test - - - org.twitter4j - twitter4j-core - [4.0,) - - - org.twitter4j - twitter4j-stream - [4.0,) - - - com.beust - jcommander - 1.48 - - + + + junit + junit + 3.8.1 + test + + + com.h2database + h2 + 1.4.190 + + + com.google.guava + guava + 19.0 + + + org.twitter4j + twitter4j-core + [4.0,) + + + org.twitter4j + twitter4j-stream + [4.0,) + + + com.beust + jcommander + 1.48 + + - + maven-compiler-plugin @@ -67,7 +77,7 @@ - ru.mipt.diht.students.andreyzharkov.collectionquery.CollectionQuery + ru.mipt.diht.students.andreyzharkov.miniORM.DatabaseService diff --git a/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/andreyzharkov/miniORM/AnnotatedField.java b/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/andreyzharkov/miniORM/AnnotatedField.java new file mode 100644 index 0000000..762d2fd --- /dev/null +++ b/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/andreyzharkov/miniORM/AnnotatedField.java @@ -0,0 +1,62 @@ +package ru.mipt.diht.students.andreyzharkov.miniORM; + +import com.google.common.base.CaseFormat; +import ru.mipt.diht.students.andreyzharkov.miniORM.annotations.Column; + +import java.lang.reflect.Field; +import java.util.HashMap; +import java.util.Map; + +/** + * Created by Андрей on 17.12.2015. + */ +public class AnnotatedField { + private String columnName; + private Field field; + + private static final Map SQL_TYPE; + + static { + SQL_TYPE = new HashMap<>(); + SQL_TYPE.put(Integer.class, "INT"); + SQL_TYPE.put(Long.class, "INT"); + SQL_TYPE.put(Byte.class, "INT"); + SQL_TYPE.put(Short.class, "INT"); + SQL_TYPE.put(Double.class, "DOUBLE"); + SQL_TYPE.put(Float.class, "DOUBLE"); + SQL_TYPE.put(String.class, "VARCHAR(10)"); + SQL_TYPE.put(Character.class, "VARCHAR(10)"); + SQL_TYPE.put(Integer.TYPE, "INT"); + SQL_TYPE.put(Long.TYPE, "INT"); + SQL_TYPE.put(Byte.TYPE, "INT"); + SQL_TYPE.put(Short.TYPE, "INT"); + SQL_TYPE.put(Double.TYPE, "DOUBLE"); + SQL_TYPE.put(Float.TYPE, "DOUBLE"); + SQL_TYPE.put(Character.TYPE, "VARCHAR(10)"); + } + + public String getColumnName() { + return columnName; + } + + public Field getField() { + return field; + } + + public String getSqlType() throws DatabaseServiceException { + if (SQL_TYPE.get(field.getType()) == null) { + throw new DatabaseServiceException(columnName + " doesn't have good sql name!"); + } + return SQL_TYPE.get(field.getType()); + } + + public AnnotatedField(Field field) { + this.field = field; + Column column = field.getAnnotation(Column.class); + columnName = column.name(); + if (columnName.equals("")) { + columnName = field.getName(); + columnName = CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, columnName); + } + } +} diff --git a/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/andreyzharkov/miniORM/DatabaseService.java b/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/andreyzharkov/miniORM/DatabaseService.java new file mode 100644 index 0000000..229dad2 --- /dev/null +++ b/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/andreyzharkov/miniORM/DatabaseService.java @@ -0,0 +1,328 @@ +package ru.mipt.diht.students.andreyzharkov.miniORM; + +import com.google.common.base.CaseFormat; +import ru.mipt.diht.students.andreyzharkov.miniORM.annotations.Column; +import ru.mipt.diht.students.andreyzharkov.miniORM.annotations.PrimaryKey; +import ru.mipt.diht.students.andreyzharkov.miniORM.annotations.Table; + +import java.lang.reflect.Field; +import java.sql.*; +import java.util.ArrayList; +import java.util.List; + +/** + * Created by Андрей on 16.12.2015. + */ +@SuppressWarnings("Duplicates") +public class DatabaseService { + private Class typeClass; + private List columns; + private int primaryKey = -1; + private boolean hasTable = false; + private String tableName; + private static final String DATABASE_NAME = "jdbc:h2:/database"; + + public DatabaseService(Class typeClass) throws DatabaseServiceException { + columns = new ArrayList<>(); + this.typeClass = typeClass; + Table table = typeClass.getAnnotation(Table.class); + if (table == null) { + throw new DatabaseServiceException("Class must be annotated with Table"); + } + + tableName = table.name(); + if (tableName.equals("")) { + tableName = typeClass.getSimpleName(); + tableName = CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, tableName); + } + + for (Field field : typeClass.getFields()) { + if (field.getAnnotation(Column.class) != null) { + columns.add(new AnnotatedField(field)); + } + if (field.getAnnotation(PrimaryKey.class) != null) { + if (field.getAnnotation(Column.class) == null) { + throw new DatabaseServiceException("Primary key must be column"); + } + if (primaryKey != -1) { + throw new DatabaseServiceException("Primary key must be only one"); + } + primaryKey = columns.size() - 1; + } + } + + try (Connection connection = DriverManager.getConnection(DATABASE_NAME)) { + try (ResultSet resultSet = connection.getMetaData().getTables(null, null, + CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.UPPER_UNDERSCORE, tableName), null)) { + if (resultSet.next()) { + hasTable = true; + } + } + } catch (SQLException ex) { + throw new DatabaseServiceException("Connection with database failed!", ex); + } + } + + public void createTable() throws DatabaseServiceException { + if (hasTable) { + throw new DatabaseServiceException("There is table already"); + } + + StringBuilder createRequest = new StringBuilder(); + createRequest.append("CREATE TABLE ").append(tableName).append(" ("); + + for (AnnotatedField field : columns) { + createRequest.append(field.getColumnName()).append(" "); + createRequest.append(field.getSqlType()).append(" "); + if (field.getField().isAnnotationPresent(PrimaryKey.class)) { + createRequest.append("NOT NULL PRIMARY KEY "); + } + createRequest.append(" , "); + } + createRequest.deleteCharAt(createRequest.lastIndexOf(",")); + createRequest.append(")"); + + try (Connection connection = DriverManager.getConnection(DATABASE_NAME)) { + try (Statement statement = connection.createStatement()) { + statement.execute(createRequest.toString()); + hasTable = true; + } + } catch (SQLException ex) { + throw new DatabaseServiceException("Connection with database failed!", ex); + } + } + + public void dropTable() throws DatabaseServiceException { + if (!hasTable) { + throw new DatabaseServiceException("there is no database to drop"); + } + try (Connection connection = DriverManager.getConnection(DATABASE_NAME)) { + try (Statement statement = connection.createStatement()) { + statement.execute("DROP TABLE " + tableName); + hasTable = false; + } + } catch (SQLException ex) { + throw new DatabaseServiceException("Connection with database failed!", ex); + } + } + + //if element is not in table return null + public T queryById(K key) throws DatabaseServiceException { + if (!hasTable) { + throw new DatabaseServiceException("there is no table"); + } + if (primaryKey == -1) { + throw new DatabaseServiceException("primary key should exist for this operation"); + } + if (!columns.get(primaryKey).getField().getType().isInstance(key)) { + throw new IllegalArgumentException("key should have same type as primary key"); + } + + StringBuilder query = new StringBuilder(); + query.append("SELECT * FROM ").append(tableName).append(" WHERE ") + .append(columns.get(primaryKey).getColumnName()).append(" = ?"); + + List result; + try (Connection connection = DriverManager.getConnection(DATABASE_NAME)) { + try (PreparedStatement statement = connection.prepareStatement(query.toString())) { + statement.setObject(1, key); + try (ResultSet resultSet = statement.executeQuery()) { + result = convertResult(resultSet); + } + } + } catch (SQLException ex) { + throw new DatabaseServiceException("Connection with database failed!", ex); + } + if (result.size() == 0) { + return null; + } else { + return result.get(0); + } + } + + public List queryForAll() throws DatabaseServiceException { + if (!hasTable) { + throw new DatabaseServiceException("there is no table"); + } + try{ + return queryWithRequest("SELECT * FROM " + tableName); + } catch (SQLException ex) { + throw new DatabaseServiceException("Connection with database failed!", ex); + } + } + + public boolean isTableCreated() { + return hasTable; + } + + public void insert(T element) throws DatabaseServiceException { + if (!hasTable) { + throw new DatabaseServiceException("there is no table"); + } + StringBuilder insertRequest = new StringBuilder(); + insertRequest.append("INSERT INTO ").append(tableName).append(" ( "); + for (AnnotatedField field : columns) { + insertRequest.append(field.getColumnName()).append(", "); + } + insertRequest.deleteCharAt(insertRequest.lastIndexOf(",")); + insertRequest.append(") VALUES ("); + + for (AnnotatedField field : columns) { + insertRequest.append("?").append(", "); + } + insertRequest.deleteCharAt(insertRequest.lastIndexOf(",")); + insertRequest.append(")"); + + try (Connection connection = DriverManager.getConnection(DATABASE_NAME)) { + try (PreparedStatement statement = connection.prepareStatement(insertRequest.toString())) { + for (int i = 0; i < columns.size(); ++i) { + try { + statement.setObject(i + 1, columns.get(i).getField().get(element)); + } catch (IllegalAccessException e) { + throw new DatabaseServiceException("bad argument for insert"); + } + } + statement.execute(); + } + } catch (SQLException ex) { + throw new DatabaseServiceException("Connection with database failed!", ex); + } + } + + public void update(T element) throws DatabaseServiceException { + if (!hasTable) { + throw new DatabaseServiceException("there is no table"); + } + if (primaryKey == -1) { + throw new DatabaseServiceException("primary key must exist for this operation"); + } + StringBuilder updateRequest = new StringBuilder(); + updateRequest.append("UPDATE ").append(tableName).append(" SET "); + for (AnnotatedField field : columns) { + updateRequest.append(field.getColumnName()).append(" = ?, "); + } + updateRequest.deleteCharAt(updateRequest.lastIndexOf(",")); + updateRequest.append(" WHERE ") + .append(columns.get(primaryKey).getColumnName()).append(" = ?"); + try (Connection connection = DriverManager.getConnection(DATABASE_NAME)) { + try (PreparedStatement statement = connection.prepareStatement(updateRequest.toString())) { + try { + for (int i = 0; i < columns.size(); ++i) { + statement.setObject(i + 1, columns.get(i).getField().get(element)); + } + statement.setObject(columns.size() + 1, columns.get(primaryKey).getField().get(element)); + } catch (IllegalAccessException e) { + throw new DatabaseServiceException("bad element for update"); + } + statement.execute(); + } + } catch (SQLException ex) { + throw new DatabaseServiceException("Connection with database failed!", ex); + } + } + + public void deleteByKey(K key) throws DatabaseServiceException { + if (!hasTable) { + throw new DatabaseServiceException("there is no table"); + } + if (primaryKey == -1) { + throw new DatabaseServiceException("primary key must exist for this operation"); + } + if (!columns.get(primaryKey).getField().getType().isInstance(key)) { + throw new IllegalArgumentException("key should have same type as primary key"); + } + StringBuilder deleteRequest = new StringBuilder(); + deleteRequest.append("DELETE FROM ").append(tableName).append(" WHERE ") + .append(columns.get(primaryKey).getColumnName()).append(" = ?"); + + try (Connection connection = DriverManager.getConnection(DATABASE_NAME)) { + try (PreparedStatement statement = connection.prepareStatement(deleteRequest.toString())) { + statement.setObject(1, key); + statement.execute(); + } + } catch (SQLException ex) { + throw new DatabaseServiceException("Connection with database failed!", ex); + } + } + + public void delete(T line) throws DatabaseServiceException { + if (!hasTable) { + throw new DatabaseServiceException("there is no table"); + } + Object key = null; + try { + key = columns.get(primaryKey).getField().get(line); + } catch (IllegalAccessException e) { + throw new DatabaseServiceException("bad element for delete"); + } + deleteByKey(key); + } + + private List queryWithRequest(String query) throws SQLException, DatabaseServiceException { + try (Connection connection = DriverManager.getConnection(DATABASE_NAME)) { + try (Statement statement = connection.createStatement()) { + try (ResultSet resultSet = statement.executeQuery(query)) { + return convertResult(resultSet); + } + } + } + } + + private List convertResult(ResultSet resultSet) throws SQLException, DatabaseServiceException { + List result = new ArrayList<>(); + while (resultSet.next()) { + T newElement; + try { + newElement = typeClass.newInstance(); + } catch (InstantiationException | IllegalAccessException e) { + throw new DatabaseServiceException("Can not create new element"); + } + for (int i = 0; i < columns.size(); ++i) { + try { + AnnotatedField currentField = columns.get(i); + switch (currentField.getSqlType()) { + case "INT": + Long number = resultSet.getLong(i + 1); + if (currentField.getField().getType().equals(Byte.class) + || currentField.getField().getType().equals(Byte.TYPE)) { + currentField.getField().set(newElement, number.byteValue()); + } else if (currentField.getField().getType().equals(Short.class) + || currentField.getField().getType().equals(Short.TYPE)) { + currentField.getField().set(newElement, number.shortValue()); + } else if (currentField.getField().getType().equals(Integer.class) + || currentField.getField().getType().equals(Integer.TYPE)) { + currentField.getField().set(newElement, number.intValue()); + } else { + currentField.getField().set(newElement, number); + } + break; + case "DOUBLE": + Double doubleNumber = resultSet.getDouble(i + 1); + if (currentField.getField().getType().equals(Float.class) + || currentField.getField().getType().equals(Float.TYPE)) { + currentField.getField().set(newElement, doubleNumber.floatValue()); + } else { + currentField.getField().set(newElement, doubleNumber); + } + break; + case "VARCHAR(10)": + if (columns.get(i).getField().getType().equals(String.class)) { + String string = resultSet.getString(i + 1); + columns.get(i).getField().set(newElement, string); + } else { + char c = resultSet.getString(i + 1).charAt(0); + columns.get(i).getField().set(newElement, c); + } + break; + default: + throw new DatabaseServiceException("Type of field in class unsupported"); + } + } catch (IllegalAccessException e) { + throw new DatabaseServiceException("Can not initialize new element"); + } + } + result.add(newElement); + } + return result; + } +} diff --git a/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/andreyzharkov/miniORM/DatabaseServiceException.java b/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/andreyzharkov/miniORM/DatabaseServiceException.java new file mode 100644 index 0000000..de67040 --- /dev/null +++ b/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/andreyzharkov/miniORM/DatabaseServiceException.java @@ -0,0 +1,14 @@ +package ru.mipt.diht.students.andreyzharkov.miniORM; + +/** + * Created by Андрей on 17.12.2015. + */ +public class DatabaseServiceException extends Exception { + DatabaseServiceException(String message) { + super(message); + } + + DatabaseServiceException(String messahe, Throwable cause) { + super(messahe, cause); + } +} diff --git a/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/andreyzharkov/miniORM/annotations/Column.java b/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/andreyzharkov/miniORM/annotations/Column.java new file mode 100644 index 0000000..6bd6ad3 --- /dev/null +++ b/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/andreyzharkov/miniORM/annotations/Column.java @@ -0,0 +1,15 @@ +package ru.mipt.diht.students.andreyzharkov.miniORM.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Created by Андрей on 17.12.2015. + */ +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +public @interface Column { + String name() default ""; +} diff --git a/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/andreyzharkov/miniORM/annotations/PrimaryKey.java b/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/andreyzharkov/miniORM/annotations/PrimaryKey.java new file mode 100644 index 0000000..ba11ef1 --- /dev/null +++ b/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/andreyzharkov/miniORM/annotations/PrimaryKey.java @@ -0,0 +1,15 @@ +package ru.mipt.diht.students.andreyzharkov.miniORM.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Created by Андрей on 17.12.2015. + */ +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +public @interface PrimaryKey { + +} diff --git a/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/andreyzharkov/miniORM/annotations/Table.java b/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/andreyzharkov/miniORM/annotations/Table.java new file mode 100644 index 0000000..b70e244 --- /dev/null +++ b/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/andreyzharkov/miniORM/annotations/Table.java @@ -0,0 +1,15 @@ +package ru.mipt.diht.students.andreyzharkov.miniORM.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Created by Андрей on 17.12.2015. + */ +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface Table { + String name() default ""; +} From 33b1d14583d35addeaab31568ad17c6cedfa188a Mon Sep 17 00:00:00 2001 From: andreyzharkov Date: Thu, 17 Dec 2015 14:13:57 +0300 Subject: [PATCH 7/9] checkstyle --- checkstyle.xml | 172 ------------------ .../andreyzharkov/miniORM/AnnotatedField.java | 11 +- .../miniORM/DatabaseService.java | 24 +-- 3 files changed, 18 insertions(+), 189 deletions(-) delete mode 100644 checkstyle.xml diff --git a/checkstyle.xml b/checkstyle.xml deleted file mode 100644 index eae5b01..0000000 --- a/checkstyle.xml +++ /dev/null @@ -1,172 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/andreyzharkov/miniORM/AnnotatedField.java b/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/andreyzharkov/miniORM/AnnotatedField.java index 762d2fd..18b9a2f 100644 --- a/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/andreyzharkov/miniORM/AnnotatedField.java +++ b/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/andreyzharkov/miniORM/AnnotatedField.java @@ -10,6 +10,7 @@ /** * Created by Андрей on 17.12.2015. */ +@SuppressWarnings("Duplicates") public class AnnotatedField { private String columnName; private Field field; @@ -35,23 +36,23 @@ public class AnnotatedField { SQL_TYPE.put(Character.TYPE, "VARCHAR(10)"); } - public String getColumnName() { + public final String getColumnName() { return columnName; } - public Field getField() { + public final Field getField() { return field; } - public String getSqlType() throws DatabaseServiceException { + public final String getSqlType() throws DatabaseServiceException { if (SQL_TYPE.get(field.getType()) == null) { throw new DatabaseServiceException(columnName + " doesn't have good sql name!"); } return SQL_TYPE.get(field.getType()); } - public AnnotatedField(Field field) { - this.field = field; + public AnnotatedField(Field fild) { + this.field = fild; Column column = field.getAnnotation(Column.class); columnName = column.name(); if (columnName.equals("")) { diff --git a/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/andreyzharkov/miniORM/DatabaseService.java b/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/andreyzharkov/miniORM/DatabaseService.java index 229dad2..0834884 100644 --- a/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/andreyzharkov/miniORM/DatabaseService.java +++ b/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/andreyzharkov/miniORM/DatabaseService.java @@ -22,9 +22,9 @@ public class DatabaseService { private String tableName; private static final String DATABASE_NAME = "jdbc:h2:/database"; - public DatabaseService(Class typeClass) throws DatabaseServiceException { + public DatabaseService(Class typeClas) throws DatabaseServiceException { columns = new ArrayList<>(); - this.typeClass = typeClass; + this.typeClass = typeClas; Table table = typeClass.getAnnotation(Table.class); if (table == null) { throw new DatabaseServiceException("Class must be annotated with Table"); @@ -63,7 +63,7 @@ public DatabaseService(Class typeClass) throws DatabaseServiceException { } } - public void createTable() throws DatabaseServiceException { + public final void createTable() throws DatabaseServiceException { if (hasTable) { throw new DatabaseServiceException("There is table already"); } @@ -92,7 +92,7 @@ public void createTable() throws DatabaseServiceException { } } - public void dropTable() throws DatabaseServiceException { + public final void dropTable() throws DatabaseServiceException { if (!hasTable) { throw new DatabaseServiceException("there is no database to drop"); } @@ -107,7 +107,7 @@ public void dropTable() throws DatabaseServiceException { } //if element is not in table return null - public T queryById(K key) throws DatabaseServiceException { + public final T queryById(K key) throws DatabaseServiceException { if (!hasTable) { throw new DatabaseServiceException("there is no table"); } @@ -140,22 +140,22 @@ public T queryById(K key) throws DatabaseServiceException { } } - public List queryForAll() throws DatabaseServiceException { + public final List queryForAll() throws DatabaseServiceException { if (!hasTable) { throw new DatabaseServiceException("there is no table"); } - try{ + try { return queryWithRequest("SELECT * FROM " + tableName); } catch (SQLException ex) { throw new DatabaseServiceException("Connection with database failed!", ex); } } - public boolean isTableCreated() { + public final boolean isTableCreated() { return hasTable; } - public void insert(T element) throws DatabaseServiceException { + public final void insert(T element) throws DatabaseServiceException { if (!hasTable) { throw new DatabaseServiceException("there is no table"); } @@ -189,7 +189,7 @@ public void insert(T element) throws DatabaseServiceException { } } - public void update(T element) throws DatabaseServiceException { + public final void update(T element) throws DatabaseServiceException { if (!hasTable) { throw new DatabaseServiceException("there is no table"); } @@ -221,7 +221,7 @@ public void update(T element) throws DatabaseServiceException { } } - public void deleteByKey(K key) throws DatabaseServiceException { + public final void deleteByKey(K key) throws DatabaseServiceException { if (!hasTable) { throw new DatabaseServiceException("there is no table"); } @@ -245,7 +245,7 @@ public void deleteByKey(K key) throws DatabaseServiceException { } } - public void delete(T line) throws DatabaseServiceException { + public final void delete(T line) throws DatabaseServiceException { if (!hasTable) { throw new DatabaseServiceException("there is no table"); } From 09f517d1c15c61afe2d5adc52242b0fc74b9bae6 Mon Sep 17 00:00:00 2001 From: andreyzharkov Date: Thu, 17 Dec 2015 17:27:20 +0300 Subject: [PATCH 8/9] tested --- projects/andreyzharkov/pom.xml | 2 +- .../miniORM/DatabaseService.java | 10 +- .../miniORM/DatabaseServiceTest.java | 220 ++++++++++++++++++ 3 files changed, 226 insertions(+), 6 deletions(-) create mode 100644 projects/andreyzharkov/src/test/java/ru/mipt/diht/students/andreyzharkov/miniORM/DatabaseServiceTest.java diff --git a/projects/andreyzharkov/pom.xml b/projects/andreyzharkov/pom.xml index fc2d142..48c16af 100644 --- a/projects/andreyzharkov/pom.xml +++ b/projects/andreyzharkov/pom.xml @@ -29,7 +29,7 @@ junit junit - 3.8.1 + 4.12 test diff --git a/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/andreyzharkov/miniORM/DatabaseService.java b/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/andreyzharkov/miniORM/DatabaseService.java index 0834884..88bf789 100644 --- a/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/andreyzharkov/miniORM/DatabaseService.java +++ b/projects/andreyzharkov/src/main/java/ru/mipt/diht/students/andreyzharkov/miniORM/DatabaseService.java @@ -20,7 +20,7 @@ public class DatabaseService { private int primaryKey = -1; private boolean hasTable = false; private String tableName; - private static final String DATABASE_NAME = "jdbc:h2:/database"; + private static final String DATABASE_NAME = "jdbc:h2:~/azharkov"; public DatabaseService(Class typeClas) throws DatabaseServiceException { columns = new ArrayList<>(); @@ -36,7 +36,7 @@ public DatabaseService(Class typeClas) throws DatabaseServiceException { tableName = CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, tableName); } - for (Field field : typeClass.getFields()) { + for (Field field : typeClass.getDeclaredFields()) { if (field.getAnnotation(Column.class) != null) { columns.add(new AnnotatedField(field)); } @@ -73,11 +73,11 @@ public final void createTable() throws DatabaseServiceException { for (AnnotatedField field : columns) { createRequest.append(field.getColumnName()).append(" "); - createRequest.append(field.getSqlType()).append(" "); + createRequest.append(field.getSqlType()); if (field.getField().isAnnotationPresent(PrimaryKey.class)) { - createRequest.append("NOT NULL PRIMARY KEY "); + createRequest.append(" NOT NULL PRIMARY KEY"); } - createRequest.append(" , "); + createRequest.append(", "); } createRequest.deleteCharAt(createRequest.lastIndexOf(",")); createRequest.append(")"); diff --git a/projects/andreyzharkov/src/test/java/ru/mipt/diht/students/andreyzharkov/miniORM/DatabaseServiceTest.java b/projects/andreyzharkov/src/test/java/ru/mipt/diht/students/andreyzharkov/miniORM/DatabaseServiceTest.java new file mode 100644 index 0000000..c38a9e8 --- /dev/null +++ b/projects/andreyzharkov/src/test/java/ru/mipt/diht/students/andreyzharkov/miniORM/DatabaseServiceTest.java @@ -0,0 +1,220 @@ +package ru.mipt.diht.students.andreyzharkov.miniORM; + +import junit.framework.TestCase; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import ru.mipt.diht.students.andreyzharkov.miniORM.annotations.Column; +import ru.mipt.diht.students.andreyzharkov.miniORM.annotations.PrimaryKey; +import ru.mipt.diht.students.andreyzharkov.miniORM.annotations.Table; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.core.Is.is; +import static org.hamcrest.core.IsEqual.equalTo; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by Андрей on 17.12.2015. + */ +public class DatabaseServiceTest { + List input; + DatabaseService dataBaseService; + + @Before + public void setUp() throws DatabaseServiceException { + dataBaseService = new DatabaseService<>(TestedClass.class); + if (!dataBaseService.isTableCreated()) { + dataBaseService.createTable(); + } + input = new ArrayList<>(); + List baseForInput = new ArrayList<>(); + for (int i = 0; i < 10; ++i) { + baseForInput.add(i); + } + baseForInput.forEach(element -> { + input.add(new TestedClass(element)); + }); + for (TestedClass element : input) { + dataBaseService.insert(element); + } + } + + @After + public void tryToDrop() throws DatabaseServiceException { + if (dataBaseService.isTableCreated()) { + dataBaseService.dropTable(); + } + + } + + @Test(expected = DatabaseServiceException.class) + public void testDoubleInsert() throws Exception { + dataBaseService.insert(input.get(0)); + dataBaseService.insert(input.get(0)); + } + + @Test + public void testQueryById() throws Exception { + TestedClass elem = dataBaseService.queryById(1); + assertThat(elem, equalTo(input.get(1))); + } + + @Test(expected = IllegalArgumentException.class) + public void testQueryByBadKey() throws Exception { + TestedClass elem = dataBaseService.queryById(1d); + } + + @Test + public void testQueryForAll() throws Exception { + List newList = dataBaseService.queryForAll(); + assertThat(newList, equalTo(input)); + } + + @Test + public void testDrop() throws Exception { + dataBaseService.dropTable(); + assertThat(dataBaseService.isTableCreated(), is(false)); + } + + @Test + public void testDelete() throws Exception { + dataBaseService.delete(input.get(0)); + List newList = dataBaseService.queryForAll(); + assertThat(newList, equalTo(input.subList(1, 10))); + } + + @Test + public void testInsert() throws Exception { + dataBaseService.delete(input.get(0)); + dataBaseService.insert(input.get(0)); + List newList = dataBaseService.queryForAll(); + assertThat(newList, equalTo(input)); + } + + @Test + public void testUpdate() throws Exception { + input.get(0).name = "Test"; + dataBaseService.update(input.get(0)); + List newList = dataBaseService.queryForAll(); + assertThat(newList, equalTo(input)); + } + + @Table + public static class Student { + @PrimaryKey + @Column(name = "name") + public final String name; + @Column(name = "age") + public Integer age; + @Column(name = "stud_group") + public final Integer group; + + public final String getName() { + return name; + } + + public Student(String name, int age, int group) { + this.name = name; + this.age = age; + this.group = group; + } + + public Student() { + this.name = ""; + this.age = 0; + this.group = 0; + } + + public final int getAge() { + return age; + } + + public final void setAge(int newAge) { + age = newAge; + } + + public final int getGroup() { + return group; + } + + public static Student student(String name, int age, int group) { + return new Student(name, age, group); + } + + @Override + public final String toString() { + return "Student{" + name + "|" + age + "|" + group + "}"; + } + + @Override + public final boolean equals(Object obj) { + if (!(obj instanceof Student)) { + return false; + } + Student st = (Student) obj; + return (st.name.equals(name) && age == st.age && group == st.group); + } + } + + @Table + public static class TestedClass { + @Column + @PrimaryKey + public Integer id; + + @Column + public Short shortNumber; + + @Column + public Byte byteNumber; + + @Column + public String name; + + @Column + public Long longNumber; + + @Column + public Double doubleNumber; + + @Column + Float floatNumber; + + @Column + public Character c; + + public TestedClass(Integer id, Short shortNumber, Byte byteNumber, String name, Long longNumber, Character c, + Double doubleNumber, Float floatNumber) { + this.id = id; + this.shortNumber = shortNumber; + this.byteNumber = byteNumber; + this.name = name; + this.c = c; + this.longNumber = longNumber; + this.doubleNumber = doubleNumber; + this.floatNumber = floatNumber; + } + + public TestedClass(Integer i) { + this(i, i.shortValue(), i.byteValue(), i.toString(), + i.longValue(), i.toString().charAt(0), i.doubleValue(), i.floatValue()); + } + + public TestedClass() { + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof TestedClass)) { + return false; + } + TestedClass another = (TestedClass) obj; + return id.equals(another.id) && shortNumber.equals(another.shortNumber) + && byteNumber.equals(another.byteNumber) && name.equals(another.name) + && longNumber.equals(another.longNumber); + } + } + +} From ae0494330e5dc64d98e4462b99df5d13abb8ef9f Mon Sep 17 00:00:00 2001 From: andreyzharkov Date: Thu, 17 Dec 2015 17:34:29 +0300 Subject: [PATCH 9/9] more accuracy --- .../miniORM/DatabaseServiceTest.java | 69 ++----------------- 1 file changed, 6 insertions(+), 63 deletions(-) diff --git a/projects/andreyzharkov/src/test/java/ru/mipt/diht/students/andreyzharkov/miniORM/DatabaseServiceTest.java b/projects/andreyzharkov/src/test/java/ru/mipt/diht/students/andreyzharkov/miniORM/DatabaseServiceTest.java index c38a9e8..4972cf3 100644 --- a/projects/andreyzharkov/src/test/java/ru/mipt/diht/students/andreyzharkov/miniORM/DatabaseServiceTest.java +++ b/projects/andreyzharkov/src/test/java/ru/mipt/diht/students/andreyzharkov/miniORM/DatabaseServiceTest.java @@ -56,7 +56,7 @@ public void testDoubleInsert() throws Exception { } @Test - public void testQueryById() throws Exception { + public void testQueryById() throws DatabaseServiceException { TestedClass elem = dataBaseService.queryById(1); assertThat(elem, equalTo(input.get(1))); } @@ -67,26 +67,26 @@ public void testQueryByBadKey() throws Exception { } @Test - public void testQueryForAll() throws Exception { + public void testQueryForAll() throws DatabaseServiceException { List newList = dataBaseService.queryForAll(); assertThat(newList, equalTo(input)); } @Test - public void testDrop() throws Exception { + public void testDrop() throws DatabaseServiceException { dataBaseService.dropTable(); assertThat(dataBaseService.isTableCreated(), is(false)); } @Test - public void testDelete() throws Exception { + public void testDelete() throws DatabaseServiceException { dataBaseService.delete(input.get(0)); List newList = dataBaseService.queryForAll(); assertThat(newList, equalTo(input.subList(1, 10))); } @Test - public void testInsert() throws Exception { + public void testInsert() throws DatabaseServiceException { dataBaseService.delete(input.get(0)); dataBaseService.insert(input.get(0)); List newList = dataBaseService.queryForAll(); @@ -94,70 +94,13 @@ public void testInsert() throws Exception { } @Test - public void testUpdate() throws Exception { + public void testUpdate() throws DatabaseServiceException { input.get(0).name = "Test"; dataBaseService.update(input.get(0)); List newList = dataBaseService.queryForAll(); assertThat(newList, equalTo(input)); } - @Table - public static class Student { - @PrimaryKey - @Column(name = "name") - public final String name; - @Column(name = "age") - public Integer age; - @Column(name = "stud_group") - public final Integer group; - - public final String getName() { - return name; - } - - public Student(String name, int age, int group) { - this.name = name; - this.age = age; - this.group = group; - } - - public Student() { - this.name = ""; - this.age = 0; - this.group = 0; - } - - public final int getAge() { - return age; - } - - public final void setAge(int newAge) { - age = newAge; - } - - public final int getGroup() { - return group; - } - - public static Student student(String name, int age, int group) { - return new Student(name, age, group); - } - - @Override - public final String toString() { - return "Student{" + name + "|" + age + "|" + group + "}"; - } - - @Override - public final boolean equals(Object obj) { - if (!(obj instanceof Student)) { - return false; - } - Student st = (Student) obj; - return (st.name.equals(name) && age == st.age && group == st.group); - } - } - @Table public static class TestedClass { @Column