private void processOpenParan(Stack<ExpressionNode> expStack, String expS, int index) throws ParseException { if (!expStack.isEmpty()) { ExpressionNode top = expStack.peek(); // Top can not be a Label Node. a(.. is not valid. but ((a.. is fine. if (top instanceof LeafExpressionNode && top != LeafExpressionNode.OPEN_PARAN_NODE) { throw new ParseException("Error parsing expression " + expS + " at column : " + index); } else if (top instanceof NonLeafExpressionNode) { // Top is non leaf. // It can be ! node but with out any child nodes. !a(.. is invalid // Other NonLeafExpressionNode , then there should be exactly 1 child. // a&b( is not valid. // a&( is valid though. Also !( is valid NonLeafExpressionNode nlTop = (NonLeafExpressionNode) top; if ((nlTop.getOperator() == Operator.NOT && nlTop.getChildExps().size() != 0) || (nlTop.getOperator() != Operator.NOT && nlTop.getChildExps().size() != 1)) { throw new ParseException("Error parsing expression " + expS + " at column : " + index); } } } expStack.push(LeafExpressionNode.OPEN_PARAN_NODE); }
private void processLabelExpNode(LeafExpressionNode node, Stack<ExpressionNode> expStack, String expS, int index) throws ParseException { if (expStack.isEmpty()) { expStack.push(node); } else { ExpressionNode top = expStack.peek(); if (top == LeafExpressionNode.OPEN_PARAN_NODE) { expStack.push(node); } else if (top instanceof NonLeafExpressionNode) { NonLeafExpressionNode nlTop = (NonLeafExpressionNode) expStack.pop(); nlTop.addChildExp(node); if (nlTop.getOperator() == Operator.NOT && !expStack.isEmpty()) { ExpressionNode secondTop = expStack.peek(); if (secondTop == LeafExpressionNode.OPEN_PARAN_NODE) { expStack.push(nlTop); } else if (secondTop instanceof NonLeafExpressionNode) { ((NonLeafExpressionNode) secondTop).addChildExp(nlTop); } } else { expStack.push(nlTop); } } else { throw new ParseException("Error parsing expression " + expS + " at column : " + index); } } }
private void processANDorOROp(Operator op, Stack<ExpressionNode> expStack, String expS, int index) throws ParseException { if (expStack.isEmpty()) { throw new ParseException("Error parsing expression " + expS + " at column : " + index); } ExpressionNode top = expStack.pop(); if (top.isSingleNode()) { if (top == LeafExpressionNode.OPEN_PARAN_NODE) { throw new ParseException("Error parsing expression " + expS + " at column : " + index); } expStack.push(new NonLeafExpressionNode(op, top)); } else { NonLeafExpressionNode nlTop = (NonLeafExpressionNode) top; if (nlTop.getChildExps().size() != 2) { throw new ParseException("Error parsing expression " + expS + " at column : " + index); } expStack.push(new NonLeafExpressionNode(op, nlTop)); } }
private void processNOTOp(Stack<ExpressionNode> expStack, String expS, int index) throws ParseException { // When ! comes, the stack can be empty or top ( or top can be some exp like // a& // !!.., a!, a&b!, !a! are invalid if (!expStack.isEmpty()) { ExpressionNode top = expStack.peek(); if (top.isSingleNode() && top != LeafExpressionNode.OPEN_PARAN_NODE) { throw new ParseException("Error parsing expression " + expS + " at column : " + index); } if (!top.isSingleNode() && ((NonLeafExpressionNode) top).getChildExps().size() != 1) { throw new ParseException("Error parsing expression " + expS + " at column : " + index); } } expStack.push(new NonLeafExpressionNode(Operator.NOT)); }
private ExpressionNode negate(NonLeafExpressionNode nlExp) { ExpressionNode notChild = nlExp.getChildExps().get(0); if (notChild instanceof LeafExpressionNode) { return nlExp; } NonLeafExpressionNode nlNotChild = (NonLeafExpressionNode) notChild; if (nlNotChild.getOperator() == Operator.NOT) { // negate the negate return nlNotChild.getChildExps().get(0); } Operator negateOp = nlNotChild.getOperator() == Operator.AND ? Operator.OR : Operator.AND; NonLeafExpressionNode newNode = new NonLeafExpressionNode(negateOp); for (ExpressionNode expNode : nlNotChild.getChildExps()) { NonLeafExpressionNode negateNode = new NonLeafExpressionNode(Operator.NOT); negateNode.addChildExp(expNode.deepClone()); newNode.addChildExp(expand(negateNode)); } return newNode; }
private static void getLabelOrdinals(ExpressionNode node, List<Integer> labelOrdinals, Set<Integer> auths, boolean checkAuths, VisibilityLabelOrdinalProvider ordinalProvider) throws IOException, InvalidLabelException { if (node.isSingleNode()) { String identifier = null; int labelOrdinal = 0; if (node instanceof LeafExpressionNode) { identifier = ((LeafExpressionNode) node).getIdentifier(); if (LOG.isTraceEnabled()) { LOG.trace("The identifier is " + identifier); } labelOrdinal = ordinalProvider.getLabelOrdinal(identifier); checkAuths(auths, labelOrdinal, identifier, checkAuths); } else { // This is a NOT node. LeafExpressionNode lNode = (LeafExpressionNode) ((NonLeafExpressionNode) node) .getChildExps().get(0); identifier = lNode.getIdentifier(); labelOrdinal = ordinalProvider.getLabelOrdinal(identifier); checkAuths(auths, labelOrdinal, identifier, checkAuths); labelOrdinal = -1 * labelOrdinal; // Store NOT node as -ve ordinal. } if (labelOrdinal == 0) { throw new InvalidLabelException("Invalid visibility label " + identifier); } labelOrdinals.add(labelOrdinal); } else { List<ExpressionNode> childExps = ((NonLeafExpressionNode) node).getChildExps(); for (ExpressionNode child : childExps) { getLabelOrdinals(child, labelOrdinals, auths, checkAuths, ordinalProvider); } } }
private void writeLabelOrdinalsToStream(ExpressionNode node, DataOutputStream dos) throws IOException, InvalidLabelException { if (node.isSingleNode()) { String identifier = null; int labelOrdinal = 0; if (node instanceof LeafExpressionNode) { identifier = ((LeafExpressionNode) node) .getIdentifier(); if (LOG.isTraceEnabled()) { LOG.trace("The identifier is "+identifier); } labelOrdinal = this.visibilityManager.getLabelOrdinal(identifier); } else { // This is a NOT node. LeafExpressionNode lNode = (LeafExpressionNode) ((NonLeafExpressionNode) node) .getChildExps().get(0); identifier = lNode.getIdentifier(); labelOrdinal = this.visibilityManager.getLabelOrdinal(identifier); labelOrdinal = -1 * labelOrdinal; // Store NOT node as -ve ordinal. } if (labelOrdinal == 0) { throw new InvalidLabelException("Invalid visibility label " + identifier); } StreamUtils.writeRawVInt32(dos, labelOrdinal); } else { List<ExpressionNode> childExps = ((NonLeafExpressionNode) node).getChildExps(); for (ExpressionNode child : childExps) { writeLabelOrdinalsToStream(child, dos); } } }
private void writeLabelOrdinalsToStream(ExpressionNode node, DataOutputStream dos) throws IOException, BadTsvLineException { if (node.isSingleNode()) { String identifier = null; int labelOrdinal = 0; if (node instanceof LeafExpressionNode) { identifier = ((LeafExpressionNode) node).getIdentifier(); if (this.labels.get(identifier) != null) { labelOrdinal = this.labels.get(identifier); } } else { // This is a NOT node. LeafExpressionNode lNode = (LeafExpressionNode) ((NonLeafExpressionNode) node) .getChildExps().get(0); identifier = lNode.getIdentifier(); if (this.labels.get(identifier) != null) { labelOrdinal = this.labels.get(identifier); labelOrdinal = -1 * labelOrdinal; // Store NOT node as -ve ordinal. } } if (labelOrdinal == 0) { throw new BadTsvLineException("Invalid visibility label " + identifier); } WritableUtils.writeVInt(dos, labelOrdinal); } else { List<ExpressionNode> childExps = ((NonLeafExpressionNode) node).getChildExps(); for (ExpressionNode child : childExps) { writeLabelOrdinalsToStream(child, dos); } } }
public ExpressionNode parse(String expS) throws ParseException { expS = expS.trim(); Stack<ExpressionNode> expStack = new Stack<ExpressionNode>(); int index = 0; int endPos = expS.length(); byte[] exp = Bytes.toBytes(expS); while (index < endPos) { byte b = exp[index]; switch (b) { case OPEN_PARAN: processOpenParan(expStack, expS, index); index = skipSpaces(exp, index); break; case CLOSE_PARAN: processCloseParan(expStack, expS, index); index = skipSpaces(exp, index); break; case AND: case OR: processANDorOROp(getOperator(b), expStack, expS, index); index = skipSpaces(exp, index); break; case NOT: processNOTOp(expStack, expS, index); break; default: int labelOffset = index; do { if (!VisibilityLabelsValidator.isValidAuthChar(exp[index])) { throw new ParseException("Error parsing expression " + expS + " at column : " + index); } index++; } while (index < endPos && !isEndOfLabel(exp[index])); String leafExp = new String(exp, labelOffset, index - labelOffset).trim(); if (leafExp.isEmpty()) { throw new ParseException("Error parsing expression " + expS + " at column : " + index); } processLabelExpNode(new LeafExpressionNode(leafExp), expStack, expS, index); // We already crossed the label node index. So need to reduce 1 here. index--; index = skipSpaces(exp, index); } index++; } if (expStack.size() != 1) { throw new ParseException("Error parsing expression " + expS); } ExpressionNode top = expStack.pop(); if (top == LeafExpressionNode.OPEN_PARAN_NODE) { throw new ParseException("Error parsing expression " + expS); } if (top instanceof NonLeafExpressionNode) { NonLeafExpressionNode nlTop = (NonLeafExpressionNode) top; if (nlTop.getOperator() == Operator.NOT) { if (nlTop.getChildExps().size() != 1) { throw new ParseException("Error parsing expression " + expS); } } else if (nlTop.getChildExps().size() != 2) { throw new ParseException("Error parsing expression " + expS); } } return top; }