Package com.trsst.server

Source Code of com.trsst.server.HomeAdapter

/*
* Copyright 2013 mpowers
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*    http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.trsst.server;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.TreeMap;

import org.apache.abdera.Abdera;
import org.apache.abdera.model.Document;
import org.apache.abdera.model.Entry;
import org.apache.abdera.model.Feed;
import org.apache.abdera.parser.ParseException;
import org.apache.abdera.protocol.server.RequestContext;
import org.apache.abdera.protocol.server.RequestContext.Scope;
import org.apache.abdera.protocol.server.context.RequestContextWrapper;

import com.trsst.Common;

/**
* Customized adapter used to serve aggregate feeds containing global search
* results.
*
* @author mpowers
*/

public class HomeAdapter extends TrsstAdapter {

    public HomeAdapter(String feedId, Storage storage)
            throws FileNotFoundException, IOException {
        super(feedId, storage);
    }

    /**
     * Returns the current feed to service this request, fetching from the
     * current request, from local storage, or from remote peers as needed.
     */
    protected Feed currentFeed(RequestContext request) throws ParseException,
            FileNotFoundException, IOException {
        Feed feed = null;
        RequestContextWrapper wrapper = new RequestContextWrapper(request);
        // System.err.println(new Date().toString() + " "
        // + wrapper.getTargetPath());

        // fetch from request context
        feed = (Feed) wrapper.getAttribute(Scope.REQUEST, "com.trsst.Feed");
        if (feed != null) {
            // shortcut for very common case
            return feed;
        }

        feed = Abdera.getInstance().newFeed();
        feed.setId(canonicalFeedIdForQuery(request));

        // build a title string from query params
        List<String> values;
        String title = "";
        values = request.getParameters("tag");
        if (values != null) {
            for (String value : values) {
                title = title + '#' + value + ' ';
            }
        }
        values = request.getParameters("mention");
        if (values != null) {
            for (String value : values) {
                title = title + '@' + value + ' ';
            }
        }
        String query = request.getParameter("q");
        if (query != null) {
            title = title + query;
        }
        title = title.trim();
        if (title.length() == 0) {
            title = "Search Results";
        }
        feed.setTitle(title);

        // default to one month ago in case of zero results
        feed.setUpdated(new Date(System.currentTimeMillis() - 1000 * 60 * 60
                * 24 * 30));

        if (feed != null) {
            if (feed.getEntries().size() == 0
                    || wrapper.getParameter("sync") != null) {
                // no local results: check the relays now
                pullFromRelay(feedId, request);
            } else {
                // we have some results: return these and check relays later
                pullLaterFromRelay(feedId, request);
            }
        }

        // store in request context
        wrapper.setAttribute(Scope.REQUEST, "com.trsst.Feed", feed);
        return feed;
    }

    /**
     * Eliminates paging parameters and sorts remaining query parameters to
     * construct a feed id string of the form "?key=value&key=value"
     *
     * @param requestment
     * @return
     */
    public static String canonicalFeedIdForQuery(RequestContext request) {
        // collate and sort query parameters
        TreeMap<String, List<String>> map = new TreeMap<String, List<String>>();
        String[] params = request.getParameterNames();
        for (String param : params) {
            map.put(param, request.getParameters(param));
        }

        // remove params used for paging
        map.remove("page");
        map.remove("count");
        map.remove("before");
        map.remove("after");

        // reassemble ordered query string
        StringBuffer buf = new StringBuffer("urn:feed:?");
        String param;
        List<String> values;
        Iterator<String> iterator = map.keySet().iterator();
        while (iterator.hasNext()) {
            param = iterator.next();
            values = map.get(param);
            for (String value : values) {
                buf.append(Common.encodeURL(param));
                buf.append('=');
                buf.append(Common.encodeURL(value));
                buf.append('&');
            }
        }
        // remove trailing ampersand
        return buf.substring(0, buf.length() - 1);
    }

    /**
     * Overridden to populate aggregate feed with global query results.
     *
     * @return the total number of entries matching the query.
     */
    @Override
    protected int addEntriesFromStorage(Feed feed, int start, int length,
            Date after, Date before, String query, String[] mentions,
            String[] tags, String verb) {
        String[] entryIds = persistence.getEntryIds(0, length, after, before,
                query, mentions, tags, verb);
        Document<Entry> entryDoc;
        String feedId;
        Feed parentFeed;
        long entryId;
        String urn;
        Entry entry;
        Date updated = null;
        int end = Math.min(entryIds.length, start + length);
        for (int i = start; i < end; i++) {
            urn = entryIds[i];
            feedId = urn.substring(0, urn.lastIndexOf(':'));
            entryId = Common.toEntryId(urn);
            parentFeed = fetchFeedFromStorage(feedId, persistence);
            entryDoc = getEntry(persistence, feedId, entryId);
            if (entryDoc != null) {
                entry = (Entry) entryDoc.getRoot().clone();
                if (updated == null || updated.before(entry.getUpdated())) {
                    updated = entry.getUpdated();
                }
                if (parentFeed != null) {
                    // specify xmlbase if known
                    entry.setBaseUri(parentFeed.getBaseUri());
                    // NOTE: clients should not persist
                    // xmlbase on aggregate feeds
                }
                feed.addEntry(entry);
            } else {
                log.error("Could not find entry for id: " + feedId + " : "
                        + Long.toHexString(entryId));
            }
        }
        if (updated != null) {
            // set to date of most recent entry
            feed.setUpdated(updated);
        }
        return entryIds.length;
    }

    /**
     * Counts entries specified search parameters.
     *
     * @return the total number of entries matching the query.
     */
    @Override
    protected int countEntriesFromStorage(Date after, Date before,
            String query, String[] mentions, String[] tags, String verb) {
        return persistence.getEntryCount(after, before, query, mentions, tags,
                verb);
    }

    private static final org.slf4j.Logger log = org.slf4j.LoggerFactory
            .getLogger(HomeAdapter.class);

}
TOP

Related Classes of com.trsst.server.HomeAdapter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.