com.isotrol.impe3.web20.server.CommentMap.java Source code

Java tutorial

Introduction

Here is the source code for com.isotrol.impe3.web20.server.CommentMap.java

Source

/**
 * This file is part of Port@l
 * Port@l 3.0 - Portal Engine and Management System
 * Copyright (C) 2010  Isotrol, SA.  http://www.isotrol.com
 *
 * Port@l is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Port@l is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Port@l.  If not, see <http://www.gnu.org/licenses/>.
 */
package com.isotrol.impe3.web20.server;

import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;

import com.google.common.base.Function;
import com.google.common.base.Objects;
import com.google.common.base.Supplier;
import com.google.common.collect.HashMultiset;
import com.google.common.collect.ImmutableListMultimap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Multiset;
import com.google.common.collect.Ordering;
import com.google.common.collect.Sets;
import com.google.common.collect.Multiset.Entry;
import com.isotrol.impe3.web20.api.ResourceCounterDTO;

/**
 * Map containing commented resources.
 * @author Andres Rodriguez
 */
public final class CommentMap {
    /** Count. */
    private static final Function<Entry<String>, Integer> COUNT = new Function<Entry<String>, Integer>() {
        public Integer apply(Entry<String> from) {
            return from.getCount();
        }
    };
    /** Ordering. */
    private static final Ordering<Entry<String>> ORDER = Ordering.natural().onResultOf(COUNT).reverse();
    /** Mapper. */
    private static final Function<Entry<String>, ResourceCounterDTO> DTO = new Function<Entry<String>, ResourceCounterDTO>() {
        public ResourceCounterDTO apply(Entry<String> from) {
            return new ResourceCounterDTO(from.getElement(), from.getCount());
        }
    };

    /** Map. */
    private final ImmutableListMultimap<Key, Entry<String>> map;

    public static Builder builder() {
        return new Builder();
    }

    CommentMap(Builder builder) {
        final ImmutableListMultimap.Builder<Key, Entry<String>> b = ImmutableListMultimap.builder();
        for (Map.Entry<Key, Multiset<String>> e : builder.map.entrySet()) {
            b.putAll(e.getKey(), ORDER.sortedCopy(e.getValue().entrySet()));
        }
        this.map = b.build();
    }

    /**
     * Returns the most commented resources.
     * @param communityId Community.
     * @param valid Validity filter.
     * @param moderated Moderation filter.
     * @param max Maximum number of results.
     * @return The requested resources.
     */
    public List<ResourceCounterDTO> get(UUID communityId, Boolean valid, Boolean moderated, int max) {
        if (max <= 0) {
            return Lists.newArrayListWithCapacity(0);
        }
        if (communityId == null) {
            communityId = CommunityManager.GLOBAL_ID;
        }
        List<Entry<String>> list = map.get(new Key(communityId, valid, moderated));
        if (list.isEmpty()) {
            return Lists.newArrayListWithCapacity(0);
        }
        if (list.size() > max) {
            list = list.subList(0, max);
        }
        return Lists.newArrayList(Iterables.transform(list, DTO));
    }

    /**
     * Returns the total number of hits in the map.
     * @return
     */
    public long size() {
        long size = 0;
        for (Entry<String> e : map.values()) {
            size += e.getCount();
        }
        return size;
    }

    private static final class Key {
        private final UUID communityId;
        private final Boolean valid;
        private final Boolean moderated;

        public Key(UUID communityId, Boolean valid, Boolean moderated) {
            this.communityId = communityId;
            this.valid = valid;
            this.moderated = moderated;
        }

        @Override
        public int hashCode() {
            return Objects.hashCode(communityId, valid, moderated);
        }

        @Override
        public boolean equals(Object obj) {
            if (obj instanceof Key) {
                final Key k = (Key) obj;
                return Objects.equal(communityId, k.communityId) && Objects.equal(valid, k.valid)
                        && Objects.equal(moderated, k.moderated);
            }
            return false;
        }

        @Override
        public String toString() {
            return String.format("[communityId:%s/valid:%s/moderated:%s]", communityId, valid, moderated);
        }

        Iterable<Key> others() {
            if (valid == null && moderated == null) {
                return ImmutableSet.of();
            }
            final Set<Key> set = Sets.newHashSet();
            if (valid != null && moderated != null) {
                set.add(new Key(communityId, valid, null));
                set.add(new Key(communityId, null, moderated));
            }
            set.add(new Key(communityId, null, null));
            return set;
        }
    }

    public static final class Builder implements Supplier<CommentMap> {
        private final Map<Key, Multiset<String>> map = Maps.newHashMap();

        Builder() {
        }

        private void add(Key key, String resource) {
            Multiset<String> ms = map.get(key);
            if (ms == null) {
                ms = HashMultiset.create();
                map.put(key, ms);
            }
            ms.add(resource);
        }

        /**
         * Adds a commment.
         * @param params Parameters.
         */
        public void add(Object[] params) {
            final String resource = (String) params[0];
            final UUID communityId = (UUID) params[1];
            final Boolean valid = (Boolean) params[2];
            final boolean moderated = (params[3] != null);
            final Key k = new Key(communityId, valid, moderated);
            add(k, resource);
            for (Key k2 : k.others()) {
                add(k2, resource);
            }
        }

        public CommentMap get() {
            return new CommentMap(this);
        }

    }

}