Java tutorial
/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You 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 org.apache.usergrid.utils; import java.io.IOException; import java.io.StringReader; import java.util.AbstractMap; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.UUID; import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.analysis.TokenStream; import org.apache.lucene.analysis.standard.StandardAnalyzer; import org.apache.lucene.analysis.tokenattributes.TermAttribute; import org.apache.lucene.util.Version; import static org.apache.usergrid.utils.ClassUtils.cast; import static org.apache.usergrid.utils.ClassUtils.isBasicType; import static org.apache.usergrid.utils.JsonUtils.quoteString; import static org.apache.usergrid.utils.JsonUtils.toJsonNode; import org.codehaus.jackson.JsonNode; import org.codehaus.jackson.node.ArrayNode; import org.codehaus.jackson.node.ObjectNode; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class IndexUtils { private static final Logger LOG = LoggerFactory.getLogger(IndexUtils.class); static Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_30); private static void buildKeyValueSet(Object node, Map<String, List<Object>> keyValues, String path, boolean fulltextIndex, Object... history) { if (node == null) { return; } if (node instanceof Collection) { Object[] newHistory = Arrays.copyOf(history, history.length + 1); newHistory[history.length] = node; @SuppressWarnings("unchecked") Collection<Object> c = (Collection<Object>) node; for (Object o : c) { buildKeyValueSet(o, keyValues, path, fulltextIndex, newHistory); } } else if (node instanceof Map) { Object[] newHistory = Arrays.copyOf(history, history.length + 1); newHistory[history.length] = node; @SuppressWarnings("unchecked") Map<Object, Object> m = (Map<Object, Object>) node; for (Entry<Object, Object> e : m.entrySet()) { String newPath; String key = e.getKey().toString(); key = quoteString(key); if (key.indexOf('\\') == -1) { if (path != null) { newPath = path + "." + key; } else { newPath = "" + key; } } else { if (path != null) { newPath = path + "[\"" + key + "\"]"; } else { newPath = "" + "[\"" + key + "\"]"; } } buildKeyValueSet(e.getValue(), keyValues, newPath, fulltextIndex, newHistory); } } else if (node instanceof ArrayNode) { Object[] newHistory = Arrays.copyOf(history, history.length + 1); newHistory[history.length] = node; ArrayNode c = (ArrayNode) node; for (JsonNode o : c) { buildKeyValueSet(o, keyValues, path, fulltextIndex, newHistory); } } else if (node instanceof ObjectNode) { Object[] newHistory = Arrays.copyOf(history, history.length + 1); newHistory[history.length] = node; ObjectNode c = (ObjectNode) node; Iterator<Entry<String, JsonNode>> i = c.getFields(); while (i.hasNext()) { Entry<String, JsonNode> e = i.next(); String newPath; String key = e.getKey(); key = quoteString(key); if (key.indexOf('\\') == -1) { if (path != null) { newPath = path + "." + key; } else { newPath = "" + key; } } else { if (path != null) { newPath = path + "[\"" + key + "\"]"; } else { newPath = "" + "[\"" + key + "\"]"; } } buildKeyValueSet(e.getValue(), keyValues, newPath, fulltextIndex, newHistory); } } else if (!isBasicType(node.getClass()) && (!(node instanceof JsonNode))) { buildKeyValueSet(toJsonNode(node), keyValues, path, fulltextIndex, history); } else { if (node instanceof JsonNode) { if (((JsonNode) node).isTextual()) { node = ((JsonNode) node).getTextValue(); UUID uuid = UUIDUtils.tryGetUUID((String) node); if (uuid != null) { node = uuid; } } else if (((JsonNode) node).isNumber()) { node = ((JsonNode) node).getNumberValue(); } else { return; } } if (path == null) { path = ""; } List<Object> l = keyValues.get(path); if (l == null) { l = new ArrayList<Object>(); keyValues.put(path, l); } l.add(node); if ((node instanceof String) && fulltextIndex) { String keywordsPath = (path.length() > 0) ? path + ".keywords" : "keywords"; List<Object> keywords = cast(keywords((String) node)); if (keywords.size() > 0) { keyValues.put(keywordsPath, keywords); } } } } public static Map<String, List<Object>> getKeyValues(String path, Object obj, boolean fulltextIndex) { Map<String, List<Object>> keys = new LinkedHashMap<String, List<Object>>(); buildKeyValueSet(obj, keys, path, fulltextIndex); return keys; } public static List<Map.Entry<String, Object>> getKeyValueList(String path, Object obj, boolean fulltextIndex) { Map<String, List<Object>> map = getKeyValues(path, obj, fulltextIndex); List<Map.Entry<String, Object>> list = new ArrayList<Map.Entry<String, Object>>(); for (Entry<String, List<Object>> entry : map.entrySet()) { for (Object value : entry.getValue()) { list.add(new AbstractMap.SimpleEntry<String, Object>(entry.getKey(), value)); } } return list; } public static List<Entry<String, Object>> getKeyValueList(Object obj, boolean fulltextIndex) { return getKeyValueList(null, obj, fulltextIndex); } public static List<String> keywords(String source) { TokenStream ts = analyzer.tokenStream("keywords", new StringReader(source)); List<String> keywords = new ArrayList<String>(); try { while (ts.incrementToken()) { keywords.add(ts.getAttribute(TermAttribute.class).term()); } } catch (IOException e) { LOG.error("Error getting keywords ", e); } return keywords; } }