Subversion Repositories SmartDukaan

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
7255 amit.gupta 1
package in.shop2020.serving.service;
2
 
3
 
4
import in.shop2020.serving.utils.Utils;
5
import java.io.File;
6
import java.util.ArrayList;
7
import java.util.HashMap;
8
import java.util.HashSet;
9
import java.util.List;
10
import java.util.Map;
11
import java.util.Map.Entry;
12
import java.util.Set;
13
 
14
import org.apache.commons.io.FileUtils;
15
import org.apache.log4j.Logger;
16
 
17
import com.google.gson.Gson;
18
import com.google.gson.reflect.TypeToken;
19
 
20
/**
21
 * 
22
 * @author rajveer
23
 * 
24
 * Auto suggest service will help user to search some term. This is based on turnary search tree. 
25
 */
26
public class AutoSuggestService
27
{
28
	private Node root;
29
	private static Logger log = Logger.getLogger(AutoSuggestService.class);
30
	private static AutoSuggestService autoSuggestService;
31
 
32
	static{
33
		synchronized(AutoSuggestService.class){
34
			autoSuggestService = new AutoSuggestService();
35
			autoSuggestService.initialize();
36
		}
37
	}
38
 
39
	private void initialize() {
40
		log.info("Starting instance of Autosuggest service");
41
		try {
42
			Gson g = new Gson();
43
			java.lang.reflect.Type typeOfT = new TypeToken<Map<String, List<String>>>(){}.getType();
44
			Map<String, List<String>> synonyms = g.fromJson(FileUtils.readFileToString(new File(Utils.EXPORT_JAVASCRIPT_CONTENT_PATH + "autosuggest.json")), typeOfT);
45
			if(synonyms != null){
46
				for(Entry<String, List<String>> entry : synonyms.entrySet()){
47
					for(String title : entry.getValue()){
48
						addItemName(title, entry.getKey());
49
					}
50
				}
51
			}
52
		} catch (Exception e) {
53
			log.error("", e);
54
		}
55
		log.info("Done with starting Autosuggest service");
56
	}
57
 
58
	public static AutoSuggestService getAutoSuggestServiceInstance(){
59
		return autoSuggestService;
60
	}
61
 
62
	private Node addChars(char[] s, int position, Node node, String string, String displaystring)
63
    {
64
        if (node == null) { 
65
        	node = new Node(s[position], null, null); 
66
        }
67
        if (s[position] < node.storedChar) {
68
        	node.left = addChars(s, position, node.left, string, displaystring); 
69
        }
70
        else if (s[position] > node.storedChar) {
71
        	node.right = addChars(s, position, node.right, string, displaystring); 
72
        }
73
        else {
74
        	if (position + 1 == s.length) {
75
        		node.addItem(string, displaystring);
76
        	}
77
        	else {
78
        		node.center =  addChars(s, position + 1, node.center, string, displaystring);
79
        	}
80
        }
81
        return node;
82
    }
83
 
84
    public void addStringPart(String part, String string, String displaystring)
85
    {
86
        if (part == null || part == "") return;
87
        root = addChars(part.toCharArray(), 0, root, string, displaystring);
88
    }
89
 
90
    /**
91
     * Add String to the tree
92
     * @param string
93
     */
94
    private void addItemName(String string, String displayString) {
95
        if (string == null || string == "") return;
96
        String[] parts = string.trim().toLowerCase().split("\\s+");
97
        for(String part : parts){
98
        	addStringPart(part, string, displayString);
99
        }
100
    }
101
 
102
    /**
103
     * Get list of matching product names.
104
     * @param str
105
     * @param resultCount
106
     * @return
107
     */
108
    public List<String> getMatchingQueries(String str, int resultCount){
109
    	Set<String> totalSet = new HashSet<String>();
110
    	String[] parts = str.trim().toLowerCase().split("\\s+");
111
        for(String part : parts){
112
        	Node node = getPartialMatchNode(part);
113
        	Set<String> set = new HashSet<String>();
114
        	getChildElements(node, set, part);
115
        	if(totalSet.isEmpty()){
116
        		totalSet.addAll(set);
117
        	}else{
118
        		totalSet.retainAll(set);
119
        	}
120
        }
121
        List<String> items = new ArrayList<String>(totalSet);
122
        if(items.size() > resultCount){
123
        	return items.subList(0, resultCount-1);
124
        }else{
125
        	return items;	
126
        }
127
    }
128
 
129
    /**
130
     * Return the node till which we are able to match the word.
131
     * @param str
132
     * @return
133
     */
134
    private Node getPartialMatchNode(String str){
135
	    char[] s = str.toCharArray();
136
	    int pos = 0;
137
	    Node node = root;
138
	    while (node != null)
139
	    {
140
	        if (s[pos] < node.storedChar) { node = node.left; }
141
	        else if (s[pos] > node.storedChar) { node = node.right; }
142
	        else
143
	        {
144
	            if (++pos == s.length){
145
	            	return node;
146
	            }
147
	            node = node.center;
148
	        }
149
	    }
150
	    return node;
151
    }
152
 
153
    private void getChildElements(Node node, Set<String>  set, String str){
154
    	if(node == null){
155
    		return;
156
    	}
157
    	if(node.itemMap != null && !node.itemMap.isEmpty()){
158
    		for(Entry<String, String> entry : node.itemMap.entrySet()) {
159
    			String item_name = entry.getKey();
160
    			String item_displayname = entry.getValue();
161
    			String ignore_item_name = item_name.toLowerCase();
162
    			if(ignore_item_name.indexOf(str) != -1){
163
    				set.add(item_displayname);
164
    			}
165
    		}
166
    	}
167
    	getChildElements(node.center, set, str);	
168
    	getChildElements(node.left, set, str);
169
    	getChildElements(node.right, set, str);
170
    }
171
 
172
 
173
	@Override
174
	public String toString() {
175
		return "AutoSuggest [root=" + root + "]";
176
	}
177
 
178
	public static void main(String[] args) throws Exception {
179
		AutoSuggestService as = new AutoSuggestService();
180
		as.addItemName("Nokia N8", "Nokia N");
181
		as.addItemName("Nokia C5-00", "Nokia C5");
182
		as.addItemName("Nokia C3-00", "Nokia C3");
183
		as.addItemName("Nokia X2-01", "Nokia X2");
184
		as.addItemName("Samsung Galaxy Pro", "Samsung Galaxy Pro");
185
		as.addItemName("Samsung Galaxy Pop", "Samsung Galaxy Pop");
186
		as.addItemName("Samsung Galaxy 551 I5510", "Samsung Galaxy 551");
187
		System.out.println(as.getMatchingQueries("noki", 10));
188
		System.out.println(as.getMatchingQueries("nok", 10));
189
		System.out.println(as.getMatchingQueries("Nokia", 10));
190
		System.out.println(as.getMatchingQueries("n8", 10));
191
		System.out.println(as.getMatchingQueries("po gala", 10));
192
	}
193
}
194
 
195
class Node
196
{
197
	char storedChar;
198
    Node left, center, right;
199
    Map<String, String> itemMap;
200
 
201
    public void addItem(String itemName, String itemDisplayName){
202
    	if(itemMap == null || itemMap.isEmpty()){
203
    		itemMap = new HashMap<String, String>();
204
    	}
205
    	itemMap.put(itemName, itemDisplayName);
206
    }
207
    public Node(char ch, String itemName, String itemDisplayName)
208
    {
209
        this.storedChar = ch;
210
        if(itemName != null){
211
        	itemMap = new HashMap<String, String>();
212
        	itemMap.put(itemName, itemDisplayName);
213
        }
214
    }
215
	@Override
216
	public String toString() {
217
		return "Node [storedChar=" + storedChar + ", left=" + left
218
				+ ", center=" + center + ", right=" + right + ", itemMap="
219
				+ itemMap + "]";
220
	}   
221
}