net.blogracy.controller.FileSharing.java Source code

Java tutorial

Introduction

Here is the source code for net.blogracy.controller.FileSharing.java

Source

/*
 * Copyright (c)  2011 Enrico Franchi, Michele Tomaiuolo and University of Parma.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

package net.blogracy.controller;

import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.DeliveryMode;
import javax.jms.Destination;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;

import net.blogracy.config.Configurations;

import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.commons.codec.binary.Base32;
import org.apache.shindig.protocol.conversion.BeanConverter;
import org.apache.shindig.protocol.conversion.BeanJsonConverter;
import org.apache.shindig.social.core.model.ActivityEntryImpl;
import org.apache.shindig.social.core.model.ActivityObjectImpl;
import org.apache.shindig.social.opensocial.model.ActivityEntry;
import org.apache.shindig.social.opensocial.model.ActivityObject;
import org.json.JSONArray;
import org.json.JSONObject;
import org.json.JSONTokener;

import com.google.inject.Binder;
import com.google.inject.Guice;
import com.google.inject.Module;
import com.google.inject.name.Names;

/**
 * Generic functions to manipulate feeds are defined in this class.
 */
public class FileSharing {

    private ConnectionFactory connectionFactory;
    private Connection connection;
    private Session session;
    private Destination seedQueue;
    private Destination downloadQueue;
    private MessageProducer producer;
    private MessageConsumer consumer;

    static final DateFormat ISO_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
    static final String CACHE_FOLDER = Configurations.getPathConfig().getCachedFilesDirectoryPath();

    private static final FileSharing THE_INSTANCE = new FileSharing();

    private static BeanJsonConverter CONVERTER = new BeanJsonConverter(Guice.createInjector(new Module() {
        @Override
        public void configure(Binder b) {
            b.bind(BeanConverter.class).annotatedWith(Names.named("shindig.bean.converter.json"))
                    .to(BeanJsonConverter.class);
        }
    }));

    public static FileSharing getSingleton() {
        return THE_INSTANCE;
    }

    public static String hash(String text) {
        String result = null;
        try {
            MessageDigest digester = MessageDigest.getInstance("SHA-1");
            Base32 encoder = new Base32();
            byte[] digest = digester.digest(text.getBytes());
            result = encoder.encodeAsString(digest);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return result;
    }

    public FileSharing() {
        try {
            connectionFactory = new ActiveMQConnectionFactory(ActiveMQConnection.DEFAULT_BROKER_URL);
            connection = connectionFactory.createConnection();
            connection.start();
            session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
            producer = session.createProducer(null);
            producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
            seedQueue = session.createQueue("seed");
            downloadQueue = session.createQueue("download");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public String seed(File file) {
        String uri = null;
        try {
            Destination tempDest = session.createTemporaryQueue();
            MessageConsumer responseConsumer = session.createConsumer(tempDest);

            JSONObject requestObj = new JSONObject();
            requestObj.put("file", file.getAbsolutePath());

            TextMessage request = session.createTextMessage();
            request.setText(requestObj.toString());
            request.setJMSReplyTo(tempDest);
            producer.send(seedQueue, request);

            TextMessage response = (TextMessage) responseConsumer.receive();
            String msgText = ((TextMessage) response).getText();
            JSONObject responseObj = new JSONObject(msgText);
            uri = responseObj.getString("uri");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return uri;
    }

    static public List<ActivityEntry> getFeed(String user) {
        List<ActivityEntry> result = new ArrayList<ActivityEntry>();
        System.out.println("Getting feed: " + user);
        JSONObject record = DistributedHashTable.getSingleton().getRecord(user);
        if (record != null) {
            try {
                String latestHash = FileSharing.getHashFromMagnetURI(record.getString("uri"));
                File dbFile = new File(CACHE_FOLDER + File.separator + latestHash + ".json");
                System.out.println("Getting feed: " + dbFile.getAbsolutePath());
                JSONObject db = new JSONObject(new JSONTokener(new FileReader(dbFile)));

                JSONArray items = db.getJSONArray("items");
                for (int i = 0; i < items.length(); ++i) {
                    JSONObject item = items.getJSONObject(i);
                    ActivityEntry entry = (ActivityEntry) CONVERTER.convertToObject(item, ActivityEntry.class);
                    result.add(entry);
                }
                System.out.println("Feed loaded");
            } catch (Exception e) {
                e.printStackTrace();
                System.out.println("Feed created");
            }
        }
        return result;
    }

    public void addFeedEntry(String id, String text, File attachment) {
        try {
            String hash = hash(text);
            File textFile = new File(CACHE_FOLDER + File.separator + hash + ".txt");

            FileWriter w = new FileWriter(textFile);
            w.write(text);
            w.close();

            String textUri = seed(textFile);
            String attachmentUri = null;
            if (attachment != null) {
                attachmentUri = seed(attachment);
            }

            final List<ActivityEntry> feed = getFeed(id);
            final ActivityEntry entry = new ActivityEntryImpl();
            entry.setVerb("post");
            entry.setUrl(textUri);
            entry.setPublished(ISO_DATE_FORMAT.format(new Date()));
            entry.setContent(text);
            if (attachment != null) {
                ActivityObject enclosure = new ActivityObjectImpl();
                enclosure.setUrl(attachmentUri);
                entry.setObject(enclosure);
            }
            feed.add(0, entry);
            final File feedFile = new File(CACHE_FOLDER + File.separator + id + ".json");

            JSONArray items = new JSONArray();
            for (int i = 0; i < feed.size(); ++i) {
                JSONObject item = new JSONObject(feed.get(i));
                items.put(item);
            }
            JSONObject db = new JSONObject();
            db.put("items", items);

            FileWriter writer = new FileWriter(feedFile);
            db.write(writer);
            writer.close();

            String feedUri = seed(feedFile);
            DistributedHashTable.getSingleton().store(id, feedUri, entry.getPublished());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    static String getHashFromMagnetURI(String uri) {
        String hash = null;
        int btih = uri.indexOf("xt=urn:btih:");
        if (btih >= 0) {
            hash = uri.substring(btih + "xt=urn:btih:".length());
            int amp = hash.indexOf('&');
            if (amp >= 0)
                hash = hash.substring(0, amp);
        }
        return hash;
    }

    public void download(final String uri) {
        String hash = getHashFromMagnetURI(uri);
        downloadByHash(hash);
    }

    public void downloadByHash(final String hash) {
        try {
            JSONObject sharedFile = new JSONObject();
            sharedFile.put("uri", "magnet:?xt=urn:btih:" + hash);
            sharedFile.put("file", CACHE_FOLDER + File.separator + hash);

            TextMessage message = session.createTextMessage();
            message.setText(sharedFile.toString());
            producer.send(downloadQueue, message);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

}