ru.mail.sphere.java_hw5_vasilyev.container.TweetsContainerImpl.java Source code

Java tutorial

Introduction

Here is the source code for ru.mail.sphere.java_hw5_vasilyev.container.TweetsContainerImpl.java

Source

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package ru.mail.sphere.java_hw5_vasilyev.container;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import ru.mail.sphere.java_hw5_vasilyev.twitteraccessor.FavouriteCountTweetComparator;
import ru.mail.sphere.java_hw5_vasilyev.twitteraccessor.TimestampTweetComparator;
import ru.mail.sphere.java_hw5_vasilyev.twitteraccessor.Tweet;

import org.apache.lucene.analysis.standard.StandardTokenizer;
import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
import org.apache.lucene.util.AttributeSource;
import org.apache.lucene.util.Version;
import static ru.mail.sphere.java_hw5_vasilyev.Program.EXTERMINATUS;

/**
 *
 * @author ??
 * @param <T>
 */
public class TweetsContainerImpl<T extends Tweet> implements TweetsContainer<T> {
    private static final int optimusPrime = 31;
    private final List<T> tweetsList = new ArrayList<>();

    @Override
    public boolean add(T tweet) {
        if (tweet == null) {
            System.out.println("Warning! Trying to add 'null' to a TweetsContainer");
            return false;
        } else {
            int oldHashCode = hashCode();
            int hashOfElement = tweet.hashCode();
            for (Tweet existing : tweetsList) {
                if (existing.hashCode() == hashOfElement) {
                    return false;
                }
            }
            synchronized (this) {
                tweetsList.add(tweet);
            }
            return hashCode() != oldHashCode;
        }
    }

    @Override
    public boolean addAll(Collection<? extends T> tweets) {
        int oldHashCode = hashCode();
        for (T tweet : tweets) {
            add(tweet);
        }
        return hashCode() != oldHashCode;
    }

    @Override
    public boolean remove(T tweet) {
        if (tweet == null) {
            System.out.println("Warning! Trying to remove 'null' from a TweetsContainer");
            return false;
        } else {
            int oldHashCode = hashCode();
            synchronized (this) {
                tweetsList.remove(tweet);
            }
            return hashCode() != oldHashCode;
        }
    }

    @Override
    public void clear() {
        synchronized (this) {
            tweetsList.clear();
        }
    }

    @Override
    public Tweet getOldest() {
        return Collections.min(tweetsList, new TimestampTweetComparator<>());
    }

    @Override
    public Tweet getTopRated() {
        return Collections.max(tweetsList, new FavouriteCountTweetComparator<>());
    }

    @Override
    public void sort(Comparator<T> comparator) {
        synchronized (this) {
            tweetsList.sort(comparator);
        }
    }

    @Override
    public Map<String, Collection<T>> groupByLang() {
        Map<String, Collection<T>> result = new HashMap<>();
        for (T tweet : tweetsList) {
            if (result.containsKey(tweet.getLang())) {
                Collection<T> chain = result.get(tweet.getLang());
                chain.add(tweet);
            } else {
                Collection<T> chain = new ArrayList<>();
                chain.add(tweet);
                result.put(tweet.getLang(), chain);
            }
        }
        return result;
    }

    @Override
    public Map<String, Double> getTagCloud(String lang) {
        Map<String, Double> result = new HashMap<>();
        Map<String, Collection<T>> langHash = this.groupByLang();
        Collection<T> tweetsOfLanguage = langHash.get(lang);

        for (Tweet tweet : tweetsOfLanguage) {
            Map<String, Double> tweetStats = getTweetStatistics(tweet);
            for (String token : tweetStats.keySet()) {
                result.put(token, result.getOrDefault(token, 0.0) + tweetStats.get(token));
            }
        }

        for (String token : result.keySet()) {
            result.put(token, result.get(token) / tweetsOfLanguage.size());
        }
        return result;
    }

    private Map<String, Double> getTweetStatistics(Tweet tweet) {
        Map<String, Double> tweetStats = new HashMap<>();
        try {
            StandardTokenizer tokenizer = new StandardTokenizer(Version.LUCENE_36,
                    AttributeSource.AttributeFactory.DEFAULT_ATTRIBUTE_FACTORY,
                    new StringReader(tweet.getContent()));
            tokenizer.reset();
            CharTermAttribute attribute = tokenizer.addAttribute(CharTermAttribute.class);
            int countOfMeanings = 0;
            while (tokenizer.incrementToken()) {
                String currentToken = attribute.toString();
                // Check if token is not shorter than 3 characters
                if (currentToken.length() >= 3) {
                    tweetStats.put(currentToken, tweetStats.getOrDefault(currentToken, 0.0) + 1.0);
                    countOfMeanings++;
                }
            }
            // Normalization
            if (countOfMeanings > 0) {
                for (String key : tweetStats.keySet()) {
                    tweetStats.put(key, tweetStats.get(key) / countOfMeanings);
                }
            }
        } catch (IOException ex) {
            Logger.getLogger(TweetsContainerImpl.class.getName()).log(Level.SEVERE, null, ex);
        }
        return tweetStats;
    }

    @Override
    public Iterator<T> iterator() {
        return tweetsList.iterator();
    }

    @Override
    public int hashCode() {
        // Start with a non-zero constant. Prime is preferred
        int result = 17;
        for (Tweet elem : tweetsList) {
            result = TweetsContainerImpl.optimusPrime * result + elem.hashCode();
        }
        return result;
    }

    public void saveToFile(String path) {
        try {
            try (FileOutputStream fos = new FileOutputStream(path)) {
                try (ObjectOutputStream oos = new ObjectOutputStream(fos)) {
                    oos.writeObject(this);
                    oos.flush();
                    oos.close();
                }
            }
        } catch (IOException io_exc) {
            System.err.println(String.format("Error occured while serializing: ", io_exc.getMessage()));
            System.err.println(EXTERMINATUS);
        }
    }

    public void restoreFromFile(String path) {
        try {
            try (FileInputStream file_is = new FileInputStream(path)) {
                try (ObjectInputStream ois = new ObjectInputStream(file_is)) {
                    Object obj = ois.readObject();
                    if (obj instanceof TweetsContainerImpl) {
                        Object sync = new Object();
                        synchronized (sync) {
                            TweetsContainerImpl<T> restored = (TweetsContainerImpl<T>) obj;
                            this.clear();
                            this.addAll(restored.tweetsList);
                        }
                    }
                    ois.close();
                }
            }
        } catch (ClassNotFoundException | IOException exc) {
            System.err.println(String.format("Error occured while deserializing: ", exc.getMessage()));
            System.err.println(EXTERMINATUS);
        }
    }

    public int size() {
        return tweetsList.size();
    }
}