fr.gael.dhus.service.job.SearchesJob.java Source code

Java tutorial

Introduction

Here is the source code for fr.gael.dhus.service.job.SearchesJob.java

Source

/*
 * Data Hub Service (DHuS) - For Space data distribution.
 * Copyright (C) 2013,2014,2015 GAEL Systems
 *
 * This file is part of DHuS software sources.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
package fr.gael.dhus.service.job;

import java.io.File;
import java.util.ArrayList;
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 fr.gael.dhus.service.ProductService;
import org.apache.commons.mail.EmailException;
import org.apache.commons.mail.HtmlEmail;
import org.apache.log4j.Logger;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import fr.gael.dhus.DHuS;
import fr.gael.dhus.database.dao.UserDao;
import fr.gael.dhus.database.object.MetadataIndex;
import fr.gael.dhus.database.object.Product;
import fr.gael.dhus.database.object.Role;
import fr.gael.dhus.database.object.Search;
import fr.gael.dhus.database.object.User;
import fr.gael.dhus.messaging.mail.MailServer;
import fr.gael.dhus.service.SearchService;
import fr.gael.dhus.system.config.ConfigurationManager;

/**
 * Autowired by {@link AutowiringJobFactory}
 */
@Component
public class SearchesJob extends AbstractJob {
    private static Logger logger = Logger.getLogger(SearchesJob.class);

    @Autowired
    private UserDao userDao;

    @Autowired
    private ProductService productService;

    @Autowired
    private MailServer mailServer;

    @Autowired
    private SearchService searchService;

    @Autowired
    private ConfigurationManager configurationManager;

    @Override
    public String getCronExpression() {
        return configurationManager.getSearchesCronConfiguration().getSchedule();
    }

    @Override
    protected void executeInternal(JobExecutionContext arg0) throws JobExecutionException {
        if (!configurationManager.getSearchesCronConfiguration().isActive())
            return;
        long time_start = System.currentTimeMillis();
        logger.info("SCHEDULER : User searches mailings.");
        if (!DHuS.isStarted()) {
            logger.warn("SCHEDULER : Not run while system not fully initialized.");
            return;
        }
        Map<String, String> cids = new HashMap<String, String>();
        for (User user : userDao.readNotDeleted()) {
            List<Search> searches = userDao.getUserSearches(user);
            if (searches == null || (searches.size() == 0)) {
                logger.debug("No saved search for user \"" + user.getUsername() + "\".");
                continue;
            }

            if (user.getEmail() == null) {
                logger.error(
                        "User \"" + user.getUsername() + "\" email not configured to send search notifications.");
                continue;
            }

            HtmlEmail he = new HtmlEmail();
            cids.clear();

            int maxResult = searches.size() >= 10 ? 5 : 10;
            String message = "<html><style>" + "a { font-weight: bold; color: #205887; "
                    + "text-decoration: none; }\n" + "a:hover { font-weight:bold; color: #FF790B"
                    + "; text-decoration: none; }\na img { border-style: none; }\n"
                    + "</style><body style=\"font-family: Trebuchet MS, Helvetica, "
                    + "sans-serif; font-size: 14px;\">Dear " + getUserWelcome(user) + ",<p/>\n\n";
            message += "You requested periodic notification for the following " + "searches. Here are the top "
                    + maxResult + " results for " + "each search:<p/>";
            message += "<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" "
                    + "style=\"width: 100%;font-family: Trebuchet MS, Helvetica, "
                    + "sans-serif; font-size: 14px;\"><tbody>";

            boolean atLeastOneResult = false;
            for (Search search : searches) {
                if (search.isNotify()) {
                    message += "<tr><td colspan=\"3\" style=\"font-size: 13px; "
                            + "font-weight: bold; color: white; background-color: "
                            + "#205887; text-align: center;\"><b>";
                    message += search.getValue();
                    message += "</b></td></tr>\n";

                    Map<String, String> advanceds = search.getAdvanced();
                    if (advanceds != null && !advanceds.isEmpty()) {
                        message += "<tr><td style=\"font-size: 13px; padding:0px; "
                                + "margin:0px; font-weight:normal; background-color: "
                                + "#799BB7; text-align: center; border-left: 1px solid "
                                + "#205887; border-right: 1px solid #205887; "
                                + "border-bottom: 1px solid #205887;\">";
                        boolean first = true;
                        List<String> keys = new ArrayList<String>(advanceds.keySet());
                        Collections.sort(keys);
                        String lastKey = "";
                        for (String key : keys) {
                            if ((lastKey + "End").equals(key)) {
                                message += " to " + advanceds.get(key);
                            } else {
                                if (key.endsWith("End")) {
                                    message += (first ? "" : ", ") + key.substring(0, key.length() - 3) + ": * to "
                                            + advanceds.get(key);
                                } else {
                                    message += (first ? "" : ", ") + key + ": " + advanceds.get(key);
                                }
                            }
                            first = false;
                            lastKey = key;
                        }
                        message += "</td></tr>";
                    }

                    Iterator<Product> results;
                    try {
                        results = searchService.search(search.getComplete());
                    } catch (Exception e) {
                        message += "<tr><td colspan=\"3\" style=\""
                                + "text-align: center; border-left: 1px solid #205887; "
                                + "border-right: 1px solid #205887;\">" + "No result found</td></tr>";
                        logger.debug("There was an error when executing query : \"" + e.getMessage() + "\"");
                        continue;
                    }

                    if (!results.hasNext()) {
                        message += "<tr><td colspan=\"3\" style=\""
                                + "text-align: center; border-left: 1px solid #205887; "
                                + "border-right: 1px solid #205887;\">" + "No result found</td></tr>";
                        logger.debug("No result matches query : \"" + search.getComplete() + "\"");
                    }

                    boolean first = true;
                    int searchIndex = 0;
                    while (results.hasNext() && searchIndex < maxResult) {

                        if (!first) {
                            message += "<tr><td colspan=\"3\" style=\""
                                    + "background-color: #205887; height:1px;\" /></tr>";
                        }
                        first = false;

                        Product product = results.next();
                        // WARNING : must implement to schedule fix of this issue...
                        if (product == null)
                            continue;

                        atLeastOneResult = true;
                        searchIndex++;

                        logger.debug("Result found: " + product.getIdentifier());

                        String purl = configurationManager.getServerConfiguration().getExternalUrl()
                                + "odata/v1/Products('" + product.getUuid() + "')";

                        // EMBEDED THUMBNAIL
                        String cid = null;
                        if (product.getThumbnailFlag()) {
                            File thumbnail = new File(product.getThumbnailPath());
                            String thumbname = thumbnail.getName();
                            if (cids.containsKey(thumbname)) {
                                cid = cids.get(thumbname);
                            } else {
                                try {
                                    cid = he.embed(thumbnail);
                                    cids.put(thumbname, cid);
                                } catch (Exception e) {
                                    logger.warn("Cannot embed image \"" + purl + "/Products('Quicklook')/$value\" :"
                                            + e.getMessage());
                                    cid = null;
                                }
                            }
                        }
                        boolean downloadRight = user.getRoles().contains(Role.DOWNLOAD);
                        String link = downloadRight
                                ? "(<a target=\"_blank\" href=\"" + purl + "/$value\">download</a>)"
                                : "";
                        message += "   <tr><td colspan=\"3\" style=\"" + "font-size: 14px; text-align: center; "
                                + "border-left: 1px solid #205887; border-right: 1px "
                                + "solid #205887;\"><a target=\"_blank\" href=\"" + purl + "/$value\">"
                                + product.getIdentifier() + "</a> " + link + "</td>\n</tr>\n";
                        if (cid != null) {
                            message += "   <tr><td rowspan=\"8\" style=\""
                                    + "text-align: center; vertical-align: middle;"
                                    + " border-left: 1px solid #205887;\">" + "<a target=\"_blank\" href=\"" + purl
                                    + "/Products('Quicklook')/$value\"><img src=cid:" + cid
                                    + " style=\"max-height: 64px; max-width:" + " 64px;\"></a></td>\n";
                        }

                        // Displays metadata
                        List<MetadataIndex> indexes = new ArrayList<>(productService.getIndexes(product.getId()));
                        Collections.sort(indexes, new Comparator<MetadataIndex>() {
                            @Override
                            public int compare(MetadataIndex o1, MetadataIndex o2) {
                                if ((o1.getCategory() == null) || o1.getCategory().equals(o2.getCategory()))
                                    return o1.getName().compareTo(o2.getName());
                                return o1.getCategory().compareTo(o2.getCategory());
                            }
                        });
                        int i = 0;
                        for (MetadataIndex index : indexes) {
                            String queryable = index.getQueryable();
                            String name = index.getName();
                            String value = index.getValue();

                            if (value.length() > 50)
                                continue;

                            if (queryable != null)
                                name += "(" + queryable + ")";

                            if (i != 0) {
                                message += "<tr>";
                            }
                            String start = "<td";
                            if (cid == null || i >= 8) {
                                start += " style=\"width: 120px;" + " border-left: 1px solid #205887;\"><td";
                            }
                            i++;
                            message += start + ">" + name + "</td>"
                                    + "<td style=\"border-right: 1px solid #205887;\">" + value + "</td>";
                            message += "</tr>";
                        }
                        if (indexes == null || indexes.size() == 0) {
                            message += "</tr>";
                        }
                    }
                }
            }
            // No result: next user, no mail.
            if (!atLeastOneResult)
                continue;
            message += "<tr><td colspan=\"3\" style=\"background-color: #205887;" + " height:1px;\" /></tr>";
            message += "</tbody></table><p/>\n";
            message += "You can configure which searches are sent by mail in the " + "<i>saved searches</i> tab in "
                    + configurationManager.getNameConfiguration().getShortName()
                    + " system at <a target=\"_blank\" href=\""
                    + configurationManager.getServerConfiguration().getExternalUrl() + "\">"
                    + configurationManager.getServerConfiguration().getExternalUrl()
                    + "</a><br/>To stop receiving this message, just disable " + "all searches.<p/>";

            message += "Thanks for using " + configurationManager.getNameConfiguration().getShortName() + ",<br/>"
                    + configurationManager.getSupportConfiguration().getName();
            message += "</body></html>";

            logger.info("Sending search results to " + user.getEmail());
            logger.debug(message);

            try {
                he.setHtmlMsg(message);
                mailServer.send(he, user.getEmail(), null, null, "Saved searches notifications");
            } catch (EmailException e) {
                logger.error("Cannot send mail to \"" + user.getEmail() + "\" :" + e.getMessage());
            }
        }
        logger.info(
                "SCHEDULER : User searches mailings done - " + (System.currentTimeMillis() - time_start) + "ms");
    }

    private String getUserWelcome(User u) {
        String firstname = u.getUsername();
        String lastname = "";
        if (u.getFirstname() != null && !u.getFirstname().trim().isEmpty()) {
            firstname = u.getFirstname();
            if (u.getLastname() != null && !u.getLastname().trim().isEmpty())
                lastname = " " + u.getLastname();
        }
        return firstname + lastname;
    }
}