@Override public List<String> completionCandidates(String partOfLine, Session session) { String lastWord = TextUtil.lastWordOrQuoteOf(partOfLine, false); if (lastWord.startsWith("-")) { return super.completionCandidates(partOfLine, session); } try { TreeSet<String> result = new TreeSet<String>(); NodeOrRelationship current = getCurrent(session); if (current.isNode()) { // TODO Check if -r is supplied Node node = current.asNode(); for (Node otherNode : RelationshipToNodeIterable.wrap(node.getRelationships(), node)) { long otherNodeId = otherNode.getId(); String title = findTitle(getServer(), session, otherNode); if (title != null) { if (!result.contains(title)) { maybeAddCompletionCandidate(result, title + "," + otherNodeId, lastWord); } } maybeAddCompletionCandidate(result, "" + otherNodeId, lastWord); } } else { maybeAddCompletionCandidate(result, START_ALIAS, lastWord); maybeAddCompletionCandidate(result, END_ALIAS, lastWord); Relationship rel = current.asRelationship(); maybeAddCompletionCandidate(result, "" + rel.getStartNode().getId(), lastWord); maybeAddCompletionCandidate(result, "" + rel.getEndNode().getId(), lastWord); } return new ArrayList<String>(result); } catch (ShellException e) { e.printStackTrace(); return super.completionCandidates(partOfLine, session); } }
private boolean isConnected(NodeOrRelationship current, TypedId newId) throws ShellException { if (current.isNode()) { Node currentNode = current.asNode(); for (Relationship rel : currentNode.getRelationships()) { if (newId.isNode()) { if (rel.getOtherNode(currentNode).getId() == newId.getId()) { return true; } } else { if (rel.getId() == newId.getId()) { return true; } } } } else { if (newId.isRelationship()) { return false; } Relationship relationship = current.asRelationship(); if (relationship.getStartNode().getId() == newId.getId() || relationship.getEndNode().getId() == newId.getId()) { return true; } } return false; }
/** * @param server the {@link GraphDatabaseShellServer} to run at. * @param session the {@link Session} used by the client. * @param thing the thing to get the name-representation for. * @return the display name for a {@link Node}. */ public static String getDisplayName( GraphDatabaseShellServer server, Session session, NodeOrRelationship thing, boolean checkForMe) throws ShellException { if (thing.isNode()) { return getDisplayName(server, session, thing.asNode(), checkForMe); } else { return getDisplayName(server, session, thing.asRelationship(), true, checkForMe); } }
private TypedId getStartOrEnd(NodeOrRelationship current, String arg) throws ShellException { if (!current.isRelationship()) { throw new ShellException("Only allowed on relationships"); } Node newNode = null; if (arg.equals(START_ALIAS)) { newNode = current.asRelationship().getStartNode(); } else if (arg.equals(END_ALIAS)) { newNode = current.asRelationship().getEndNode(); } else { throw new ShellException("Unknown alias '" + arg + "'"); } return NodeOrRelationship.wrap(newNode).getTypedId(); }
protected static void printAndInterpretTemplateLines( Collection<String> templateLines, boolean forcePrintHitHeader, boolean newLineBetweenHits, NodeOrRelationship entity, GraphDatabaseShellServer server, Session session, Output out) throws ShellException, RemoteException { if (templateLines.isEmpty() || forcePrintHitHeader) { out.println(getDisplayName(server, session, entity, true)); } if (!templateLines.isEmpty()) { Map<String, Object> data = new HashMap<String, Object>(); data.put("i", entity.getId()); for (String command : templateLines) { String line = TextUtil.templateString(command, data); server.interpretLine(session.getId(), line, out); } } if (newLineBetweenHits) { out.println(); } }
protected static NodeOrRelationship getThingById(GraphDatabaseShellServer server, TypedId typedId) throws ShellException { NodeOrRelationship result = null; if (typedId.isNode()) { try { result = NodeOrRelationship.wrap(server.getDb().getNodeById(typedId.getId())); } catch (NotFoundException e) { throw new ShellException("Node " + typedId.getId() + " not found"); } } else { try { result = NodeOrRelationship.wrap(server.getDb().getRelationshipById(typedId.getId())); } catch (NotFoundException e) { throw new ShellException("Relationship " + typedId.getId() + " not found"); } } return result; }
protected void cdTo(Session session, Node node) throws RemoteException, ShellException { List<TypedId> wd = readCurrentWorkingDir(session); try { NodeOrRelationship current = getCurrent(session); wd.add(getCurrent(session).getTypedId()); } catch (ShellException e) { // OK not found then } writeCurrentWorkingDir(wd, session); setCurrent(session, NodeOrRelationship.wrap(node)); }
@Override protected String exec(AppCommandParser parser, Session session, Output out) throws ShellException { if (parser.arguments().size() < 2) { throw new ShellException( "Must supply <from-key> <to-key> " + "arguments, like: mv name \"given_name\""); } String fromKey = parser.arguments().get(0); String toKey = parser.arguments().get(1); boolean mayOverwrite = parser.options().containsKey("o"); NodeOrRelationship thing = getCurrent(session); if (!thing.hasProperty(fromKey)) { throw new ShellException("Property '" + fromKey + "' doesn't exist"); } if (thing.hasProperty(toKey)) { if (!mayOverwrite) { throw new ShellException( "Property '" + toKey + "' already exists, supply -o flag to overwrite"); } else { thing.removeProperty(toKey); } } Object value = thing.removeProperty(fromKey); thing.setProperty(toKey, value); return null; }
@Override protected String exec(AppCommandParser parser, Session session, Output out) throws ShellException, RemoteException { List<TypedId> paths = readCurrentWorkingDir(session); NodeOrRelationship current = getCurrent(session); NodeOrRelationship newThing = null; if (parser.arguments().isEmpty()) { newThing = NodeOrRelationship.wrap(getServer().getDb().getReferenceNode()); paths.clear(); } else { String arg = parser.arguments().get(0); TypedId newId = current.getTypedId(); if (arg.equals("..")) { if (paths.size() > 0) { newId = paths.remove(paths.size() - 1); } } else if (arg.equals(".")) { } else if (arg.equals(START_ALIAS) || arg.equals(END_ALIAS)) { newId = getStartOrEnd(current, arg); paths.add(current.getTypedId()); } else { long suppliedId = -1; try { suppliedId = Long.parseLong(arg); } catch (NumberFormatException e) { suppliedId = findNodeWithTitle(current.asNode(), arg, session); if (suppliedId == -1) { throw new ShellException("No connected node with title '" + arg + "'"); } } newId = parser.options().containsKey("r") ? new TypedId(NodeOrRelationship.TYPE_RELATIONSHIP, suppliedId) : new TypedId(NodeOrRelationship.TYPE_NODE, suppliedId); if (newId.equals(current.getTypedId())) { throw new ShellException("Can't cd to where you stand"); } boolean absolute = parser.options().containsKey("a"); if (!absolute && !this.isConnected(current, newId)) { throw new ShellException( getDisplayName(getServer(), session, newId, false) + " isn't connected to the current primitive," + " use -a to force it to go there anyway"); } paths.add(current.getTypedId()); } newThing = this.getThingById(newId); } setCurrent(session, newThing); writeCurrentWorkingDir(paths, session); return null; }
/** * @param server the {@link GraphDatabaseShellServer} to run at. * @param session the {@link Session} used by the client. * @param node the {@link Node} to get a display string for. * @return a display string for {@code node}. */ public static String getDisplayName( GraphDatabaseShellServer server, Session session, Node node, boolean checkForMe) throws ShellException { if (checkForMe && isCurrent(session, NodeOrRelationship.wrap(node))) { return getDisplayNameForCurrent(server, session); } String title = findTitle(server, session, node); StringBuilder result = new StringBuilder("("); result.append((title != null ? title + "," : "")); result.append(node.getId()); result.append(")"); return result.toString(); }
/** * @param server the {@link GraphDatabaseShellServer} to get the current node/relationship from. * @param session the {@link Session} used by the client. * @return the current node/relationship the client stands on at the moment. * @throws ShellException if some error occured. */ public static NodeOrRelationship getCurrent(GraphDatabaseShellServer server, Session session) throws ShellException { String currentThing = (String) session.get(CURRENT_KEY); NodeOrRelationship result = null; if (currentThing == null) { try { result = NodeOrRelationship.wrap(server.getDb().getReferenceNode()); } catch (NotFoundException e) { throw new ShellException("Reference node not found"); } setCurrent(session, result); } else { TypedId typedId = new TypedId(currentThing); result = getThingById(server, typedId); } return result; }
/** * @param server the {@link GraphDatabaseShellServer} to run at. * @param session the {@link Session} used by the client. * @param relationship the {@link Relationship} to get a display name for. * @param verbose whether or not to include the relationship id as well. * @return a display string for the {@code relationship}. */ public static String getDisplayName( GraphDatabaseShellServer server, Session session, Relationship relationship, boolean verbose, boolean checkForMe) throws ShellException { if (checkForMe && isCurrent(session, NodeOrRelationship.wrap(relationship))) { return getDisplayNameForCurrent(server, session); } StringBuilder result = new StringBuilder("["); result.append(":" + relationship.getType().name()); result.append(verbose ? "," + relationship.getId() : ""); result.append("]"); return result.toString(); }
@Override protected Continuation exec(AppCommandParser parser, Session session, Output out) throws ShellException, RemoteException { assertCurrentIsNode(session); Node node = this.getCurrent(session).asNode(); boolean caseInsensitiveFilters = parser.options().containsKey("i"); boolean looseFilters = parser.options().containsKey("l"); boolean quiet = parser.options().containsKey("q"); // Order TraversalDescription description = Traversal.description(); String order = parser.options().get("o"); if (order != null) { description = description.order(parseOrder(order)); } // Relationship types / expander String relationshipTypes = parser.options().get("r"); if (relationshipTypes != null) { Map<String, Object> types = parseFilter(relationshipTypes, out); description = description.expand( toExpander(getServer().getDb(), null, types, caseInsensitiveFilters, looseFilters)); } // Uniqueness String uniqueness = parser.options().get("u"); if (uniqueness != null) { description = description.uniqueness(parseUniqueness(uniqueness)); } // Depth limit String depthLimit = parser.options().get("d"); if (depthLimit != null) { description = description.evaluator(toDepth(parseInt(depthLimit))); } String filterString = parser.options().get("f"); Map<String, Object> filterMap = filterString != null ? parseFilter(filterString, out) : null; String commandToRun = parser.options().get("c"); Collection<String> commandsToRun = new ArrayList<String>(); if (commandToRun != null) { commandsToRun.addAll(Arrays.asList(commandToRun.split(Pattern.quote("&&")))); } for (Path path : description.traverse(node)) { boolean hit = false; if (filterMap == null) { hit = true; } else { Node endNode = path.endNode(); Map<String, Boolean> matchPerFilterKey = new HashMap<String, Boolean>(); for (String key : endNode.getPropertyKeys()) { for (Map.Entry<String, Object> filterEntry : filterMap.entrySet()) { String filterKey = filterEntry.getKey(); if (matchPerFilterKey.containsKey(filterKey)) { continue; } if (matches( newPattern(filterKey, caseInsensitiveFilters), key, caseInsensitiveFilters, looseFilters)) { Object value = endNode.getProperty(key); String filterPattern = filterEntry.getValue() != null ? filterEntry.getValue().toString() : null; if (matches( newPattern(filterPattern, caseInsensitiveFilters), value.toString(), caseInsensitiveFilters, looseFilters)) { matchPerFilterKey.put(filterKey, true); } } } } if (matchPerFilterKey.size() == filterMap.size()) { hit = true; } } if (hit) { if (commandsToRun.isEmpty()) { printPath(path, quiet, session, out); } else { printAndInterpretTemplateLines( commandsToRun, false, true, NodeOrRelationship.wrap(path.endNode()), getServer(), session, out); } } } return Continuation.INPUT_COMPLETE; }
public static boolean isCurrent(Session session, NodeOrRelationship thing) { String currentThing = (String) session.get(CURRENT_KEY); return currentThing != null && currentThing.equals(thing.getTypedId().toString()); }
protected static void setCurrent(Session session, NodeOrRelationship current) { session.set(CURRENT_KEY, current.getTypedId().toString()); }
private static String getDisplayNameForCurrent(GraphDatabaseShellServer server, Session session) throws ShellException { NodeOrRelationship current = getCurrent(server, session); return current.isNode() ? "(me)" : "<me>"; }
protected void assertCurrentIsNode(Session session) throws ShellException { NodeOrRelationship current = getCurrent(session); if (!current.isNode()) { throw new ShellException("You must stand on a node to be able to do this"); } }