if (isLeaf()) { return this; this.children = new ArrayList<TraceNode>(); for (TraceNode child : tmp) { child.compact(); if (child.isEmpty()) { } else if (child.isLeaf()) { addChild(child); } else if (strict == child.strict) { addChildren(child.children); } else if (child.getNumChildren() == 1) { TraceNode grandChild = child.getChild(0); if (grandChild.isEmpty()) { } else if (grandChild.isLeaf() || strict != grandChild.strict) { addChild(grandChild); } else { addChildren(grandChild.children); addChild(child);
/** * Normalize this tree. This will transform all equivalent trees into the same form. Note that this will also * perform an implicit compaction of the tree. * * @return This, to allow chaining. */ public TraceNode normalize() { compact(); sort(); if (note != null || !strict) { TraceNode child = new TraceNode(); child.swap(this); addChild(child); strict = true; } return this; }
@Override public int compareTo(TraceNode rhs) { if (isLeaf() || rhs.isLeaf()) { if (isLeaf() && rhs.isLeaf()) { return note.compareTo(rhs.getNote()); } else { return isLeaf() ? -1 : 1; } } if (children.size() != rhs.children.size()) { return children.size() < rhs.children.size() ? -1 : 1; } for (int i = 0; i < children.size(); ++i) { int cmp = children.get(i).compareTo(rhs.children.get(i)); if (cmp != 0) { return cmp; } } return -1; }
return new TraceNode(); TraceNode proxy = new TraceNode(); TraceNode node = proxy; StringBuilder note = null; inEscape = true; } else if (c == ']') { node.addChild(note.toString()); note = null; } else { note = new StringBuilder(); } else if (c == '(' || c == '{') { node.addChild(new TraceNode()); node = node.getChild(node.getNumChildren() - 1); node.setStrict(c == '('); } else if (c == ')' || c == '}') { if (node == null) { log.log(LogLevel.WARNING, "Unexpected closing brace in trace '" + str + "' at position " + i + "."); return new TraceNode(); if (node.isStrict() != (c == ')')) { log.log(LogLevel.WARNING, "Mismatched closing brace in trace '" + str + "' at position " + i + "."); return new TraceNode(); return new TraceNode(); return new TraceNode();
/** * Adds a list of child nodes to this. * * @param children The children to add. * @return This, to allow chaining. */ public TraceNode addChildren(List<TraceNode> children) { for (TraceNode child : children) { addChild(child); } return this; }
@Override public void run() { Reply reply = decode(envelope.reply.getProtocol(), payload, Reply.class); reply.setRetryDelay(envelope.reply.getRetryDelay()); reply.getTrace().getRoot().addChild(TraceNode.decode(envelope.reply.getTrace().getRoot().encode())); for (int i = 0, len = envelope.reply.getNumErrors(); i < len; ++i) { Error error = envelope.reply.getError(i); reply.addError(new Error(error.getCode(), error.getMessage(), error.getService() != null ? error.getService() : envelope.sender.hostId)); } owner.deliverReply(reply, envelope.parent.recipient); } });
/** * Returns a parseable (using {@link #decode(String)}) string representation of this trace node. * * @return A string representation of this tree. */ public String encode() { StringBuilder ret = new StringBuilder(); encode(ret); return ret.toString(); }
/** * Remove all trace information and set the trace level to 0. * * @return This, to allow chaining. */ public Trace clear() { level = 0; root = new TraceNode(); return this; }
/** * Create a trace tree which is a copy of another. * * @param rhs The tree to copy. */ TraceNode(TraceNode rhs) { strict = rhs.strict; note = rhs.note; addChildren(rhs.children); }
/** * Writes a parseable string representation of this trace node to the given string builder. * * @param ret The string builder to write to. */ private void encode(StringBuilder ret) { if (note != null) { ret.append("["); for (int i = 0, len = note.length(); i < len; ++i) { char c = note.charAt(i); if (c == '\\' || c == ']') { ret.append('\\'); } ret.append(note.charAt(i)); } ret.append("]"); } else { ret.append(strict ? "(" : "{"); for (TraceNode child : children) { child.encode(ret); } ret.append(strict ? ")" : "}"); } }
/** * Adds a child node to this. * * @param child The child to add. * @return This, to allow chaining. */ public TraceNode addChild(TraceNode child) { if (note != null) { throw new IllegalStateException("Nodes with notes are leaf nodes, you can not add children to it."); } TraceNode node = new TraceNode(child); node.parent = this; children.add(node); return this; }
@Override public ContentChannel handleResponse(Response response) { synchronized (this) { if (response instanceof MbusResponse) { Reply reply = ((MbusResponse)response).getReply(); requestTrace.addChild(reply.getTrace().getRoot()); replies.add(reply); } if (--numPending != 0) { return null; } } requestMsg.getTrace().getRoot().addChild(requestTrace); Reply reply = DocumentProtocol.merge(replies); Response mbusResponse = new MbusResponse(StatusCodes.fromMbusReply(reply), reply); ResponseDispatch.newInstance(mbusResponse).dispatch(responseHandler); return null; }
@Override protected void createResponse(Values ret, Reply reply, Version version, byte [] payload) { int[] eCodes = new int[reply.getNumErrors()]; String[] eMessages = new String[reply.getNumErrors()]; String[] eServices = new String[reply.getNumErrors()]; for (int i = 0; i < reply.getNumErrors(); ++i) { Error error = reply.getError(i); eCodes[i] = error.getCode(); eMessages[i] = error.getMessage(); eServices[i] = error.getService() != null ? error.getService() : ""; } ret.add(new StringValue(version.toString())); ret.add(new DoubleValue(reply.getRetryDelay())); ret.add(new Int32Array(eCodes)); ret.add(new StringArray(eMessages)); ret.add(new StringArray(eServices)); ret.add(new StringValue(reply.getProtocol())); ret.add(new DataValue(payload)); ret.add(new StringValue(reply.getTrace().getRoot() != null ? reply.getTrace().getRoot().encode() : "")); }
/** * Sets the reply of this routing node. This method also updates the internal state of this node; it is tagged for * resending if the reply has only transient errors, and the reply's {@link Trace} is copied. This method <u>does * not</u> call the parent node's {@link #notifyMerge()}. * * @param reply The reply to set. */ public void setReply(Reply reply) { if (reply != null) { shouldRetry = resender != null && resender.shouldRetry(reply); trace.getRoot().addChild(reply.getTrace().getRoot()); reply.getTrace().clear(); } this.reply = reply; }