PageRenderTime 60ms CodeModel.GetById 41ms app.highlight 16ms RepoModel.GetById 0ms app.codeStats 0ms

/blogracy-web/src/main/java/net/blogracy/controller/MediaController.java

https://github.com/rik0/blogracy
Java | 558 lines | 371 code | 102 blank | 85 comment | 79 complexity | a2f072f807b748d2fd33d1ed26493eb6 MD5 | raw file
  1/*
  2 * Copyright (c)  2011 Enrico Franchi, Michele Tomaiuolo and University of Parma.
  3 *
  4 * Permission is hereby granted, free of charge, to any person obtaining a copy
  5 * of this software and associated documentation files (the "Software"), to deal
  6 * in the Software without restriction, including without limitation the rights
  7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8 * copies of the Software, and to permit persons to whom the Software is
  9 * furnished to do so, subject to the following conditions:
 10 *
 11 * The above copyright notice and this permission notice shall be included in
 12 * all copies or substantial portions of the Software.
 13 *
 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 20 * THE SOFTWARE.
 21 */
 22
 23package net.blogracy.controller;
 24
 25import java.io.File;
 26import java.io.FileReader;
 27import java.io.FileWriter;
 28import java.io.IOException;
 29import java.security.InvalidParameterException;
 30import java.security.MessageDigest;
 31import java.security.NoSuchAlgorithmException;
 32import java.text.DateFormat;
 33import java.text.SimpleDateFormat;
 34import java.util.TimeZone;
 35import java.util.ArrayList;
 36import java.util.Date;
 37import java.util.HashMap;
 38import java.util.Iterator;
 39import java.util.List;
 40import java.util.Map;
 41import java.util.Map.Entry;
 42
 43import javax.jms.Connection;
 44import javax.jms.ConnectionFactory;
 45import javax.jms.DeliveryMode;
 46import javax.jms.Destination;
 47import javax.jms.Message;
 48import javax.jms.MessageConsumer;
 49import javax.jms.MessageListener;
 50import javax.jms.MessageProducer;
 51import javax.jms.Session;
 52import javax.jms.TextMessage;
 53
 54import net.blogracy.config.Configurations;
 55import net.blogracy.util.FileUtils;
 56
 57import org.apache.activemq.ActiveMQConnection;
 58import org.apache.activemq.ActiveMQConnectionFactory;
 59import org.apache.commons.codec.binary.Base32;
 60import org.apache.shindig.protocol.conversion.BeanConverter;
 61import org.apache.shindig.protocol.conversion.BeanJsonConverter;
 62import org.apache.shindig.social.core.model.ActivityEntryImpl;
 63import org.apache.shindig.social.core.model.ActivityObjectImpl;
 64import org.apache.shindig.social.core.model.AlbumImpl;
 65import org.apache.shindig.social.core.model.MediaItemImpl;
 66import org.apache.shindig.social.opensocial.model.ActivityEntry;
 67import org.apache.shindig.social.opensocial.model.ActivityObject;
 68import org.apache.shindig.social.opensocial.model.Album;
 69import org.apache.shindig.social.opensocial.model.MediaItem;
 70import org.apache.shindig.social.opensocial.model.MediaItem.Type;
 71import org.json.JSONArray;
 72import org.json.JSONException;
 73import org.json.JSONObject;
 74import org.json.JSONTokener;
 75
 76import com.google.inject.Binder;
 77import com.google.inject.Guice;
 78import com.google.inject.Module;
 79import com.google.inject.name.Names;
 80
 81/**
 82 * Generic functions to manipulate feeds are defined in this class.
 83 */
 84public class MediaController {
 85
 86    static final DateFormat ISO_DATE_FORMAT = new SimpleDateFormat(
 87            "yyyy-MM-dd'T'HH:mm:ss'Z'");
 88    static final String CACHE_FOLDER = Configurations.getPathConfig()
 89            .getCachedFilesDirectoryPath();
 90
 91    private static final MediaController theInstance = new MediaController();
 92    private static final FileSharing sharing = new FileSharing();
 93    private static final ActivitiesController activities = new ActivitiesController();
 94    private static final DistributedHashTable dht = new DistributedHashTable();
 95
 96    private static BeanJsonConverter CONVERTER = new BeanJsonConverter(
 97            Guice.createInjector(new Module() {
 98                @Override
 99                public void configure(Binder b) {
100                    b.bind(BeanConverter.class)
101                            .annotatedWith(
102                                    Names.named("shindig.bean.converter.json"))
103                            .to(BeanJsonConverter.class);
104                }
105            }));
106
107    public static MediaController getSingleton() {
108        return theInstance;
109    }
110
111    public MediaController() {
112        ISO_DATE_FORMAT.setTimeZone(TimeZone.getTimeZone("UTC"));
113    }
114
115    /**
116     * Create a new Album for the user. Adds the album to the user's recordDB
117     * entry Adds the action to the ActivityStream (verb: create)
118     * 
119     * @param userId
120     * @param photoAlbumName
121     */
122    public synchronized String createPhotoAlbum(String userId,
123            String photoAlbumTitle) {
124        if (userId == null)
125            throw new InvalidParameterException("userId cannot be null");
126
127        if (photoAlbumTitle == null || photoAlbumTitle.isEmpty())
128            return null;
129
130        String albumHash = null;
131        try {
132            albumHash = sharing.hash(userId + photoAlbumTitle);
133            Album album = new AlbumImpl();
134            album.setTitle(photoAlbumTitle);
135            album.setId(albumHash);
136            album.setOwnerId(userId);
137            List<Type> types = new ArrayList<Type>();
138            types.add(Type.IMAGE);
139            album.setMediaType(types);
140            // Album is empty where created
141            album.setMediaItemCount(0);
142
143            final List<ActivityEntry> feed = activities.getFeed(userId);
144            final ActivityEntry entry = new ActivityEntryImpl();
145            entry.setVerb("create");
146            ActivityObject mediaAlbumObject = new ActivityObjectImpl();
147            mediaAlbumObject.setObjectType("collection");
148            mediaAlbumObject.setContent(photoAlbumTitle);
149            entry.setObject(mediaAlbumObject);
150
151            entry.setPublished(ISO_DATE_FORMAT.format(new Date()));
152            entry.setContent(photoAlbumTitle);
153
154            feed.add(0, entry);
155            String feedUri = activities.seedActivityStream(userId, feed);
156
157            // Append another album into the user's recordDB
158            JSONObject recordDb = DistributedHashTable.getSingleton()
159                    .getRecord(userId);
160
161            if (recordDb == null)
162                recordDb = new JSONObject();
163
164            JSONArray albums = recordDb.optJSONArray("albums");
165
166            if (albums != null) {
167                // Simply append new album
168                albums.put(new JSONObject(CONVERTER.convertToString(album)));
169            } else {
170                albums = new JSONArray();
171                albums.put(new JSONObject(CONVERTER.convertToString(album)));
172            }
173
174            DistributedHashTable.getSingleton().store(userId, feedUri,
175                    entry.getPublished(), albums,
176                    recordDb.optJSONArray("mediaItems"));
177
178        } catch (Exception e) {
179            e.printStackTrace();
180        }
181
182        return albumHash;
183    }
184
185    /**
186     * Get the photo albums from recordDb given the userId.
187     * 
188     * @param userId
189     */
190    public List<Album> getAlbums(String userId) {
191        if (userId == null)
192            throw new InvalidParameterException("userId cannot be null");
193
194        List<Album> albums = new ArrayList<Album>();
195        try {
196            JSONObject recordDb = DistributedHashTable.getSingleton()
197                    .getRecord(userId);
198
199            if (recordDb == null)
200                return albums;
201
202            JSONArray albumArray = recordDb.optJSONArray("albums");
203
204            if (albumArray != null) {
205                for (int i = 0; i < albumArray.length(); ++i) {
206                    JSONObject singleAlbumObject = albumArray.getJSONObject(i);
207                    Album entry = (Album) CONVERTER.convertToObject(
208                            singleAlbumObject, Album.class);
209                    albums.add(entry);
210                }
211            }
212        } catch (Exception e) {
213            e.printStackTrace();
214        }
215        return albums;
216    }
217
218    /**
219     * Get the images from recordDb given the userId and the associated albumId
220     * 
221     * @param userId
222     * @param albumId
223     * @return
224     */
225    public List<MediaItem> getMediaItems(String userId, String albumId) {
226        if (userId == null)
227            throw new InvalidParameterException("userId cannot be null");
228
229        if (albumId == null)
230            throw new InvalidParameterException("albumId cannot be null");
231
232        List<MediaItem> mediaItems = new ArrayList<MediaItem>();
233
234        try {
235            JSONObject recordDb = DistributedHashTable.getSingleton()
236                    .getRecord(userId);
237
238            if (recordDb == null)
239                return mediaItems;
240
241            JSONArray mediaItemsArray = recordDb.optJSONArray("mediaItems");
242
243            if (mediaItemsArray != null) {
244                for (int i = 0; i < mediaItemsArray.length(); ++i) {
245                    JSONObject singleAlbumObject = mediaItemsArray
246                            .getJSONObject(i);
247                    MediaItem entry = (MediaItem) CONVERTER.convertToObject(
248                            singleAlbumObject, MediaItem.class);
249
250                    if (entry.getAlbumId().equals(albumId))
251                        mediaItems.add(entry);
252                }
253            }
254        } catch (Exception e) {
255            e.printStackTrace();
256        }
257
258        return mediaItems;
259    }
260
261    /**
262     * Gets the images from recordDb given the userId and the associated
263     * albumId. Attempts to download the images from DHT. If successful, set's
264     * the URL with the cached image link
265     * 
266     * @param userId
267     * @param albumId
268     * @return
269     */
270    public List<MediaItem> getMediaItemsWithCachedImages(String userId,
271            String albumId) {
272
273        if (userId == null)
274            throw new InvalidParameterException("userId cannot be null");
275
276        if (albumId == null)
277            throw new InvalidParameterException("albumId cannot be null");
278
279        List<MediaItem> mediaItems = this.getMediaItems(userId, albumId);
280
281        for (MediaItem item : mediaItems) {
282            String itemMagneUri = item.getUrl();
283            sharing.download(itemMagneUri);
284            item.setUrl("cache/" + sharing.getHashFromMagnetURI(itemMagneUri));
285        }
286
287        return mediaItems;
288    }
289
290    /***
291     * Add multiple MediaItems to an album. It updates the user's recordDb and
292     * notifies the action in the user's Activity Stream (verb: add)
293     * 
294     * @param userId
295     * @param albumId
296     * @param photos
297     * @return
298     */
299    public synchronized List<String> addMediaItemsToAlbum(String userId,
300            String albumId, Map<File, String> photos) {
301        if (photos == null)
302            return null;
303
304        if (userId == null)
305            throw new InvalidParameterException("userId cannot be null");
306
307        if (albumId == null)
308            throw new InvalidParameterException("albumId cannot be null");
309
310        Album album = null;
311        for (Album a : this.getAlbums(userId)) {
312            if (a.getId().equals(albumId)) {
313                album = a;
314                break;
315            }
316        }
317
318        if (album == null)
319            throw new InvalidParameterException("AlbumId " + albumId
320                    + " does not match to a valid album for the user " + userId);
321
322        List<String> hashList = new ArrayList<String>();
323        List<MediaItem> listOfMediaItems = new ArrayList<MediaItem>();
324
325        final List<ActivityEntry> feed = activities.getFeed(userId);
326        final String publishedDate = ISO_DATE_FORMAT.format(new Date());
327
328        try {
329
330            for (Entry<File, String> mapEntry : photos.entrySet()) {
331                File photo = mapEntry.getKey();
332                String mimeType = mapEntry.getValue();
333                String fileHash = sharing.hash(photo);
334
335                final File photoCachedFile = new File(CACHE_FOLDER
336                        + File.separator + fileHash);
337
338                FileUtils.copyFile(photo, photoCachedFile);
339                photo.delete();
340
341                final String fileUrl = sharing.seed(photoCachedFile);
342
343                final ActivityEntry entry = new ActivityEntryImpl();
344                entry.setVerb("add");
345                entry.setPublished(publishedDate);
346                entry.setContent(sharing.getHashFromMagnetURI(fileUrl));
347
348                ActivityObject mediaItemObject = new ActivityObjectImpl();
349                mediaItemObject.setObjectType("image");
350                mediaItemObject.setContent(sharing
351                        .getHashFromMagnetURI(fileUrl));
352                mediaItemObject.setUrl(fileUrl);
353                entry.setObject(mediaItemObject);
354
355                ActivityObject mediaAlbumObject = new ActivityObjectImpl();
356                mediaAlbumObject.setObjectType("collection");
357                mediaAlbumObject.setContent(album.getTitle());
358                mediaAlbumObject.setId(album.getId());
359                entry.setTarget(mediaAlbumObject);
360
361                feed.add(0, entry);
362
363                MediaItem mediaItem = new MediaItemImpl();
364                mediaItem.setAlbumId(albumId);
365                mediaItem.setId(sharing.getHashFromMagnetURI(fileUrl));
366                mediaItem.setUrl(fileUrl);
367                mediaItem.setLastUpdated(publishedDate);
368                mediaItem.setMimeType(mimeType);
369
370                if (album.getMediaMimeType() == null)
371                    album.setMediaMimeType(new ArrayList<String>());
372
373                List<String> albumMimeTypes = album.getMediaMimeType();
374
375                if (!albumMimeTypes.contains(mimeType))
376                    albumMimeTypes.add(mimeType);
377
378                listOfMediaItems.add(mediaItem);
379                hashList.add(sharing.getHashFromMagnetURI(fileUrl));
380            }
381
382            album.setMediaItemCount(album.getMediaItemCount() + photos.size());
383
384            String feedUri = activities.seedActivityStream(userId, feed);
385
386            // Update the album accordingly
387            JSONObject recordDb = DistributedHashTable.getSingleton()
388                    .getRecord(userId);
389
390            if (recordDb == null)
391                recordDb = new JSONObject();
392
393            JSONArray albums = recordDb.optJSONArray("albums");
394
395            for (int i = 0; i < albums.length(); ++i) {
396                JSONObject singleAlbumObject = albums.getJSONObject(i);
397                Album entry1 = (Album) CONVERTER.convertToObject(
398                        singleAlbumObject, Album.class);
399
400                if (entry1.getId().equals(albumId)) {
401                    albums.put(i,
402                            new JSONObject(CONVERTER.convertToString(album)));
403                    break;
404                }
405            }
406
407            // Add all the newly created mediaItems
408            JSONArray mediaItems = recordDb.optJSONArray("mediaItems");
409
410            if (mediaItems == null)
411                mediaItems = new JSONArray();
412
413            for (MediaItem mediaItem : listOfMediaItems) {
414                // Simply append new album
415                mediaItems.put(new JSONObject(CONVERTER
416                        .convertToString(mediaItem)));
417            }
418
419            DistributedHashTable.getSingleton().store(userId, feedUri,
420                    publishedDate, albums, mediaItems);
421
422            return hashList;
423
424        } catch (Exception e) {
425            e.printStackTrace();
426            return null;
427        }
428    }
429
430    /***
431     * Adds a single MediaItem file to an Album. It updates the user's recordDb
432     * and notifies the action in the user's Activity Stream (verb: remove)
433     * 
434     * @param userId
435     * @param albumId
436     * @param photo
437     * @param mimeType
438     * @return
439     */
440    public synchronized String addMediaItemToAlbum(String userId,
441            String albumId, File photo, String mimeType) {
442        Map<File, String> map = new HashMap<File, String>();
443        map.put(photo, mimeType);
444        List<String> hashes = this.addMediaItemsToAlbum(userId, albumId, map);
445
446        return (hashes != null && !hashes.isEmpty()) ? hashes.get(0) : null;
447    }
448
449    /***
450     * A Media Item is removed from an album
451     * 
452     * @param userId
453     * @param albumId
454     * @param mediaId
455     */
456    public synchronized void deletePhotoFromAlbum(String userId,
457            String albumId, String mediaId) {
458        if (mediaId == null)
459            throw new InvalidParameterException("mediaId cannot be null");
460
461        if (userId == null)
462            throw new InvalidParameterException("userId cannot be null");
463
464        if (albumId == null)
465            throw new InvalidParameterException("albumId cannot be null");
466
467        Album album = null;
468        for (Album a : this.getAlbums(userId)) {
469            if (a.getId().equals(albumId)) {
470                album = a;
471                break;
472            }
473        }
474
475        if (album == null)
476            throw new InvalidParameterException("AlbumId " + albumId
477                    + " does not correspond to a valid album for the user "
478                    + userId);
479        try {
480
481            List<MediaItem> mediaItems = this.getMediaItems(userId, albumId);
482
483            for (Iterator<MediaItem> iter = mediaItems.iterator(); iter
484                    .hasNext();) {
485                MediaItem mediaItem = iter.next();
486                if (mediaId.equals(mediaItem.getId())
487                        && albumId.equals(mediaItem.getAlbumId()))
488                    iter.remove();
489            }
490
491            album.setMediaItemCount(mediaItems.size());
492
493            final List<ActivityEntry> feed = activities.getFeed(userId);
494            final ActivityEntry entry = new ActivityEntryImpl();
495            entry.setVerb("remove");
496            entry.setPublished(ISO_DATE_FORMAT.format(new Date()));
497            entry.setContent(mediaId);
498
499            ActivityObject mediaItemObject = new ActivityObjectImpl();
500            mediaItemObject.setObjectType("image");
501            mediaItemObject.setContent(mediaId);
502            entry.setObject(mediaItemObject);
503
504            ActivityObject mediaAlbumObject = new ActivityObjectImpl();
505            mediaAlbumObject.setObjectType("collection");
506            mediaAlbumObject.setContent(album.getTitle());
507            mediaAlbumObject.setId(album.getId());
508            entry.setTarget(mediaAlbumObject);
509
510            feed.add(0, entry);
511            String feedUri = activities.seedActivityStream(userId, feed);
512
513            JSONObject recordDb = DistributedHashTable.getSingleton()
514                    .getRecord(userId);
515
516            if (recordDb == null)
517                recordDb = new JSONObject();
518
519            JSONArray albums = recordDb.optJSONArray("albums");
520
521            // update albums
522            if (albums != null) {
523                for (int i = 0; i < albums.length(); ++i) {
524                    JSONObject singleAlbumObject = albums.getJSONObject(i);
525                    Album entry1 = (Album) CONVERTER.convertToObject(
526                            singleAlbumObject, Album.class);
527
528                    if (entry1.getId().equals(albumId)) {
529                        albums.put(
530                                i,
531                                new JSONObject(CONVERTER.convertToString(album)));
532                        break;
533                    }
534                }
535            }
536
537            JSONArray list = new JSONArray();
538            JSONArray mediaItemsArray = recordDb.optJSONArray("mediaItems");
539            if (mediaItemsArray != null) {
540                for (int i = 0; i < mediaItemsArray.length(); ++i) {
541                    JSONObject singleMediaItemObject = mediaItemsArray
542                            .getJSONObject(i);
543                    MediaItem entry1 = (MediaItem) CONVERTER.convertToObject(
544                            singleMediaItemObject, MediaItem.class);
545                    if (!mediaId.equals(entry1.getId())
546                            || !albumId.equals(entry1.getAlbumId()))
547                        list.put(singleMediaItemObject);
548                }
549            }
550
551            dht.store(userId, feedUri, entry.getPublished(), albums, list);
552
553        } catch (Exception e) {
554            e.printStackTrace();
555
556        }
557    }
558}