| /******************************************************************************* |
| * Copyright (c) 2010, 2017 Cloudsmith Inc. and others. |
| * |
| * This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * Cloudsmith Inc. - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.equinox.internal.p2.metadata.expression; |
| |
| import org.eclipse.equinox.internal.p2.metadata.expression.Member.DynamicMember; |
| import org.eclipse.equinox.p2.metadata.Version; |
| import org.eclipse.equinox.p2.metadata.expression.IExpressionVisitor; |
| |
| /** |
| * The abstract base class for all binary operations |
| */ |
| public abstract class Binary extends Expression { |
| public final Expression lhs; |
| |
| public final Expression rhs; |
| |
| protected Binary(Expression lhs, Expression rhs) { |
| this.lhs = lhs; |
| this.rhs = rhs; |
| } |
| |
| @Override |
| public boolean accept(IExpressionVisitor visitor) { |
| return super.accept(visitor) && lhs.accept(visitor) && rhs.accept(visitor); |
| } |
| |
| @Override |
| public int compareTo(Expression e) { |
| int cmp = super.compareTo(e); |
| if (cmp == 0) { |
| Binary be = (Binary) e; |
| cmp = lhs.compareTo(be.lhs); |
| if (cmp == 0) |
| cmp = rhs.compareTo(be.rhs); |
| } |
| return cmp; |
| } |
| |
| @Override |
| public boolean equals(Object o) { |
| if (super.equals(o)) { |
| Binary bo = (Binary) o; |
| return lhs.equals(bo.lhs) && rhs.equals(bo.rhs); |
| } |
| return false; |
| } |
| |
| @Override |
| public int getPriority() { |
| return PRIORITY_BINARY; // Default priority |
| } |
| |
| @Override |
| public int hashCode() { |
| int result = 31 + lhs.hashCode(); |
| return 31 * result + rhs.hashCode(); |
| } |
| |
| @Override |
| public void toString(StringBuffer bld, Variable rootVariable) { |
| appendOperand(bld, rootVariable, lhs, getPriority()); |
| bld.append(' '); |
| bld.append(getOperator()); |
| bld.append(' '); |
| appendOperand(bld, rootVariable, rhs, getPriority()); |
| } |
| |
| /** |
| * Appends the LDAP filter attribute name from the lhs expression if |
| * possible. |
| * @throws UnsupportedOperationException when this expression does not conform to an |
| * LDAP filter binary expression |
| */ |
| void appendLDAPAttribute(StringBuffer buf) { |
| if (lhs instanceof DynamicMember) { |
| DynamicMember attr = (DynamicMember) lhs; |
| if (attr.operand instanceof Variable) { |
| buf.append(attr.getName()); |
| return; |
| } |
| } |
| throw new UnsupportedOperationException(); |
| } |
| |
| private static char hexChar(int value) { |
| return (char) (value < 10 ? ('0' + value) : ('a' + (value - 10))); |
| } |
| |
| static void appendLDAPEscaped(StringBuffer bld, String str) { |
| appendLDAPEscaped(bld, str, true); |
| } |
| |
| static void appendLDAPEscaped(StringBuffer bld, String str, boolean escapeWild) { |
| int top = str.length(); |
| for (int idx = 0; idx < top; ++idx) { |
| char c = str.charAt(idx); |
| if (!escapeWild) { |
| if (c == '*') { |
| bld.append(c); |
| continue; |
| } else if (c == '\\' && idx + 1 < top && str.charAt(idx + 1) == '*') { |
| bld.append("\\2a"); //$NON-NLS-1$ |
| ++idx; |
| continue; |
| } |
| } |
| if (c == '(' || c == ')' || c == '*' || c == '\\' || c < ' ' || c > 127) { |
| short cs = (short) c; |
| bld.append('\\'); |
| bld.append(hexChar((cs & 0x00f0) >> 4)); |
| bld.append(hexChar(cs & 0x000f)); |
| } else |
| bld.append(c); |
| } |
| } |
| |
| /** |
| * Appends the LDAP filter value from the rhs expression if |
| * possible. |
| * @throws UnsupportedOperationException when this expression does not conform to an |
| * LDAP filter binary expression |
| */ |
| void appendLDAPValue(StringBuffer buf) { |
| if (rhs instanceof Literal) { |
| Object value = rhs.evaluate(null); |
| if (value instanceof String || value instanceof Version) { |
| appendLDAPEscaped(buf, value.toString()); |
| return; |
| } |
| } |
| throw new UnsupportedOperationException(); |
| } |
| |
| @Override |
| int countAccessToEverything() { |
| return lhs.countAccessToEverything() + rhs.countAccessToEverything(); |
| } |
| } |