private @NonNull JsonEntity getNodeIdJson( final @NonNull NodesTransaction txn, final @NonNull NodeId nodeId, final @NonNull Set<NodeId> seen) { if (seen.contains(nodeId)) return new JsonString("seen"); seen.add(nodeId); final NodeIdJsonTranslatorRegistry nitjr = nitjrReactor.getInstance(); final NodeIdJsonTranslator nitj = nitjr.get(nodeId.getType()); if (nitj == null) return new JsonString("error"); final JsonEntity je = nitj.translate(nodeId); if (!(je instanceof JsonObject)) return je; final JsonObject jo = (JsonObject) je; final JsonObjectEditor joe = jo.createEditor(); { final JsonArrayEditor jae = new JsonArrayEditor(); final Set<NodeId> natureNodeIds = txn.getDeclaredNatureNodeIds(nodeId); for (final NodeId natureNodeId : natureNodeIds) { if (natureNodeId != null) { jae.add(getNodeIdJson(txn, natureNodeId)); } } joe.set("natures", jae); } { final JsonArrayEditor jae = new JsonArrayEditor(); Cursor<NodeKey> cursor = null; try { cursor = txn.fetchKeys(nodeId); for (final NodeKey nodeKey : cursor) { if (nodeKey != null) { jae.add(nodeKey.toString()); } } } finally { if (cursor != null) cursor.close(); } joe.set("keys", jae); } return joe.create(); }
@Override public void updateIndex( final @NonNull NodesTransaction txn, final @NonNull NodeId nodeId, final boolean deferred) { final ValidatingKernel kernel = k1Reactor.getInstance(); final Queue queue = queueReactor.getInstance(); final WordMeaning wordMeaning = wordMeaningReactor.getInstance(); final WordParentMeaning wordParentMeaning = wordParentMeaningReactor.getInstance(); final MimeTypeMeaning mimeTypeMeaning = mimeTypeMeaningReactor.getInstance(); final LocaleMeaning localeMeaning = localeMeaningReactor.getInstance(); final Coordinator coordinator = coordReactor.getInstance(); final Reservation reservation = coordinator.reserve( CoordinatorUtil.makeSetOfRules(new BaseNodeRule(nodeId)), CoordinatorUtil.makeSetOfIntents(new BaseNodeIntent(nodeId))); try { final Datum datum = txn.getDatum(nodeId); final MimeType mimeType = mimeTypeMeaning.getMimeType(txn, nodeId); final Locale locale = localeMeaning.getLocale(txn, nodeId); final List<Stemmer> stemmers = StemmerUtil.getStemmers(bundleContext, locale); WordParser parser; if (mimeType != null) { parser = getParser(mimeType.toString()); } else if (datum instanceof StringDatum) { parser = getParser("text/plain"); } else { parser = null; } if (parser == null) return; Cursor<NodeId> cursor = null; final Map<String, NodeId> oldIndexEntries = new HashMap<String, NodeId>(); final Set<NodeId> oldNodesToDelete = new HashSet<NodeId>(); try { cursor = txn.fetchSourceNodes(nodeId, wordParentMeaning.getNodeId()); for (final NodeId linkNodeId : cursor) { if (linkNodeId != null) { final NodeId wordNodeId = txn.getTarget(linkNodeId, wordMeaning.getNodeId()); if (wordNodeId != null) { final Datum wordDatum = txn.getDatum(wordNodeId); if (wordDatum instanceof StringDatum) { final String indexEntry = ((StringDatum) wordDatum).getValue(); final NodeId oldLinkNodeId = oldIndexEntries.get(indexEntry); if (oldLinkNodeId != null) { // get rid of redundant link oldNodesToDelete.add(linkNodeId); } else { oldIndexEntries.put(indexEntry, linkNodeId); } } } } } } finally { if (cursor != null) cursor.close(); } // enqueue deletes for all redundant links for (final NodeId linkNodeId : oldNodesToDelete) { if (linkNodeId != null) { final QueueOperation op = new DeleteIndexLinkOperation( kernel, nodeId, linkNodeId, wordParentMeaning.getNodeId(), wordMeaning.getNodeId()); if (deferred) { queue.add(op, 0); queue.start(); } else op.execute(); } } Reader reader; try { reader = new InputStreamReader(datum.getInputStream()); } catch (final IOException e) { // TODO log something reader = null; } if (reader == null) return; final Set<String> newStemmedWords = new HashSet<String>(); Set<String> words = new HashSet<String>(); for (final String word : parser.parse(reader)) { if (word != null) { words.add(word); } } for (final Stemmer stemmer : stemmers) { if (stemmer != null) { words = stemmer.stem(words); } } newStemmedWords.addAll(words); for (final String word : newStemmedWords) { if (word != null) { final NodeId oldLinkNodeId = oldIndexEntries.get(word); if (oldLinkNodeId != null) { oldIndexEntries.remove(word); } else { final QueueOperation op = new IndexOperation( kernel, wicpReactor, coordReactor, word, nodeId, wordParentMeaning.getNodeId(), wordMeaning.getNodeId()); queue.add(op, 0); } } } // enqueue deletes for all old word links that no longer apply for (final NodeId linkNodeId : oldIndexEntries.values()) { if (linkNodeId != null) { final QueueOperation op = new DeleteIndexLinkOperation( kernel, nodeId, linkNodeId, wordParentMeaning.getNodeId(), wordMeaning.getNodeId()); if (deferred) queue.add(op, 0); else op.execute(); } } } finally { reservation.release(); } }