com.sfs.whichdoctor.search.TagSearchDAOImpl.java Source code

Java tutorial

Introduction

Here is the source code for com.sfs.whichdoctor.search.TagSearchDAOImpl.java

Source

/*******************************************************************************
 * Copyright (c) 2009 David Harrison.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Public License v3.0
 * which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/gpl-3.0.html
 *
 * Contributors:
 *     David Harrison - initial API and implementation
 ******************************************************************************/
package com.sfs.whichdoctor.search;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.dao.IncorrectResultSizeDataAccessException;
import org.springframework.jdbc.core.RowMapper;

import com.sfs.DataFilter;

import com.sfs.beans.UserBean;

import com.sfs.whichdoctor.beans.TagBean;

/**
 * The Class TagSearchDAOImpl.
 */
public class TagSearchDAOImpl extends com.sfs.whichdoctor.dao.BaseDAOImpl implements TagSearchDAO {

    /** The data logger. */
    private static Logger dataLogger = Logger.getLogger(TagSearchDAOImpl.class);

    /**
     * Search.
     *
     * @param objecttype the objecttype
     * @param user the user
     *
     * @return the map< string, collection< tag bean>>
     *
     * @throws WhichDoctorSearchDaoException the which doctor search dao
     *             exception
     */
    public final Map<String, Collection<TagBean>> search(final String objecttype, final UserBean user)
            throws WhichDoctorSearchDaoException {
        return search(objecttype, null, user);
    }

    /**
     * Perform a search for tags.
     *
     * @param objecttype the objecttype
     * @param order Order options are: alpha (alphabetical), count (tag count)
     * @param user the user
     *
     * @return the map< string, collection< tag bean>>
     *
     * @throws WhichDoctorSearchDaoException the which doctor search dao
     *             exception
     */
    @SuppressWarnings("unchecked")
    public final Map<String, Collection<TagBean>> search(final String objecttype, final String order,
            final UserBean user) throws WhichDoctorSearchDaoException {

        if (objecttype == null) {
            throw new WhichDoctorSearchDaoException("An object type must be " + "specified for a tag search");
        }

        Map<String, Collection<TagBean>> results = new HashMap<String, Collection<TagBean>>();

        // Holds a running total of the maximum tag count for each tag type
        HashMap<String, Integer> maxTagCount = new HashMap<String, Integer>();

        String searchSQL = this.getSQL().getValue("tag/search");

        /* Default order is alphabetical */
        if (StringUtils.equalsIgnoreCase(order, "count")) {
            searchSQL += " ORDER BY TagCount DESC";
        } else {
            searchSQL += " ORDER BY TagName ASC";
        }

        dataLogger.info("Performing tag search");

        Collection<TagBean> tagResults = new ArrayList<TagBean>();

        try {
            tagResults = this.getJdbcTemplateReader().query(searchSQL,
                    new Object[] { objecttype, "Private", "Private", user.getDN() }, new RowMapper() {
                        public Object mapRow(final ResultSet rs, final int rowNum) throws SQLException {
                            TagBean tag = new TagBean();
                            tag.setTagName(rs.getString("TagName"));
                            tag.setTagType(rs.getString("TagType"));
                            tag.setTagCount(rs.getInt("TagCount"));

                            return tag;
                        }
                    });
        } catch (IncorrectResultSizeDataAccessException ie) {
            dataLogger.debug("No results found for search: " + ie.getMessage());
        }

        for (TagBean tag : tagResults) {
            Collection<TagBean> tags = new ArrayList<TagBean>();
            if (results.containsKey(tag.getTagType())) {
                // Get existing array from
                tags = results.get(tag.getTagType());
            }

            if (maxTagCount.containsKey(tag.getTagType())) {
                Integer maxCount = maxTagCount.get(tag.getTagType());
                if (tag.getTagCount() > maxCount) {
                    maxTagCount.put(tag.getTagType(), tag.getTagCount());
                }
            } else {
                maxTagCount.put(tag.getTagType(), new Integer(tag.getTagCount()));
            }
            tags.add(tag);

            results.put(tag.getTagType(), tags);
        }

        /* Iterate through results setting max tag count */
        for (String key : results.keySet()) {
            Integer maxCount = maxTagCount.get(key);

            Collection<TagBean> tempTags = results.get(key);
            Collection<TagBean> tags = new ArrayList<TagBean>();

            for (TagBean tag : tempTags) {
                tag.setMaxCount(maxCount);
                tags.add(tag);
            }
            results.put(key, tags);
        }

        /* Load all tags */
        String searchAllSQL = getSQL().getValue("tag/searchAll");

        if (order.compareToIgnoreCase("count") == 0) {
            searchAllSQL += " ORDER BY TagCount DESC";
        } else {
            searchAllSQL += " ORDER BY TagName ASC";
        }

        Collection<TagBean> allTagResults = new ArrayList<TagBean>();
        try {
            allTagResults = this.getJdbcTemplateReader().query(searchAllSQL,
                    new Object[] { objecttype, "Private", "Private", user.getDN() }, new RowMapper() {
                        public Object mapRow(final ResultSet rs, final int rowNum) throws SQLException {
                            TagBean tag = new TagBean();
                            tag.setTagName(rs.getString("TagName"));
                            tag.setTagType("All");
                            tag.setTagCount(rs.getInt("TagCount"));

                            return tag;
                        }
                    });
        } catch (IncorrectResultSizeDataAccessException ie) {
            dataLogger.debug("No results found for search: " + ie.getMessage());
        }

        int maxAllTagCount = 0;
        for (TagBean tag : allTagResults) {
            if (tag.getTagCount() > maxAllTagCount) {
                maxAllTagCount = tag.getTagCount();
            }
        }

        Collection<TagBean> allTags = new ArrayList<TagBean>();

        for (TagBean tag : allTagResults) {
            tag.setMaxCount(maxAllTagCount);
            allTags.add(tag);
        }

        if (allTags.size() > 0) {
            // At least one tag has been found, add it to results
            results.put("All", allTags);
        }
        return results;
    }

    /**
     * Construct.
     *
     * @param objCriteria the obj criteria
     * @param objConstraints the obj constraints
     *
     * @return the map< string[], collection< object>>
     *
     * @throws IllegalArgumentException the illegal argument exception
     */
    public final Map<String[], Collection<Object>> construct(final Object objCriteria, final Object objConstraints)
            throws IllegalArgumentException {

        TagBean searchCriteria = null;

        if (objCriteria instanceof TagBean) {
            searchCriteria = (TagBean) objCriteria;
        }

        if (objCriteria == null || objConstraints == null) {
            throw new IllegalArgumentException(
                    "The search criteria and " + "constraints must be valid TagBean classes");
        }

        StringBuffer sqlWHERE = new StringBuffer();
        StringBuffer description = new StringBuffer();
        Collection<Object> parameters = new ArrayList<Object>();

        boolean tagSearch = false;

        if (searchCriteria.getTagName() != null) {
            if (searchCriteria.getTagName().compareTo("") != 0) {
                sqlWHERE.append(" AND tags.TagName = ?");
                description.append(" and tagged with '" + searchCriteria.getTagName() + "'");
                parameters.add(searchCriteria.getTagName());
                tagSearch = true;
            }
        }
        if (tagSearch) {
            boolean allTags = true;

            if (!StringUtils.equalsIgnoreCase(searchCriteria.getTagType(), "All")) {
                allTags = false;
                if (StringUtils.equalsIgnoreCase(searchCriteria.getTagType(), "Private")) {
                    if (searchCriteria.getCreatedBy() != null) {
                        // A private search - set type and username
                        sqlWHERE.append(" AND tagtype.Class = ? " + "AND tags.CreatedBy = ?");
                        description.append(" - a private tag");
                        parameters.add(searchCriteria.getTagType());
                        parameters.add(searchCriteria.getCreatedBy());
                    }
                } else {
                    // A standard type search
                    sqlWHERE.append(" AND tagtype.Class = ?");
                    description.append(" - a " + searchCriteria.getTagType() + " tag");
                    parameters.add(searchCriteria.getTagType());
                }
            }

            if (allTags) {
                // Perform a search for all relevant tag types
                if (searchCriteria.getCreatedBy() != null) {
                    // User DN set
                    sqlWHERE.append(" AND (tagtype.Class != ? OR " + "(tagtype.Class = ? AND tags.CreatedBy = ?))");
                    parameters.add("Private");
                    parameters.add("Private");
                    parameters.add(searchCriteria.getCreatedBy());
                } else {
                    // No user DN set
                    sqlWHERE.append(" AND tagtype.Class != ?");
                    parameters.add("Private");
                }
            }
        }

        String sqlStatement = sqlWHERE.toString();
        if (sqlStatement.length() > 0) {
            // Remove the first AND statement
            final int substring = 5;
            sqlStatement = sqlStatement.substring(substring, sqlStatement.length());
        }

        String[] index = new String[] { sqlStatement, DataFilter.getHtml(description.toString()) };

        Map<String[], Collection<Object>> results = new HashMap<String[], Collection<Object>>();

        results.put(index, parameters);

        return results;
    }
}