PageRenderTime 68ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/projects/eclipse_SDK-3.7.1/plugins/org.eclipse.equinox.p2.metadata.source_2.1.0.v20110510/org/eclipse/equinox/internal/p2/metadata/index/Index.java

https://gitlab.com/essere.lab.public/qualitas.class-corpus
Java | 149 lines | 109 code | 16 blank | 24 comment | 35 complexity | 1702a551e4e5e9ba83579750c9c9c8cd MD5 | raw file
  1. /*******************************************************************************
  2. * Copyright (c) 2010 Cloudsmith Inc. and others.
  3. * All rights reserved. This program and the accompanying materials
  4. * are made available under the terms of the Eclipse Public License v1.0
  5. * which accompanies this distribution, and is available at
  6. * http://www.eclipse.org/legal/epl-v10.html
  7. *
  8. * Contributors:
  9. * Cloudsmith Inc. - initial API and implementation
  10. *******************************************************************************/
  11. package org.eclipse.equinox.internal.p2.metadata.index;
  12. import java.util.ArrayList;
  13. import java.util.Iterator;
  14. import org.eclipse.equinox.internal.p2.metadata.expression.*;
  15. import org.eclipse.equinox.p2.metadata.expression.*;
  16. import org.eclipse.equinox.p2.metadata.index.IIndex;
  17. public abstract class Index<T> implements IIndex<T> {
  18. protected static boolean isIndexedMember(IExpression expr, IExpression variable, String memberName) {
  19. if (expr instanceof Member) {
  20. Member member = (Member) expr;
  21. return member.getOperand() == variable && member.getName().equals(memberName);
  22. }
  23. return false;
  24. }
  25. protected static Object concatenateUnique(Object previous, Object toAdd) {
  26. if (previous == null || toAdd == null || toAdd == Boolean.FALSE)
  27. return toAdd;
  28. if (previous instanceof ArrayList<?>) {
  29. @SuppressWarnings("unchecked")
  30. ArrayList<Object> prevArr = (ArrayList<Object>) previous;
  31. if (!prevArr.contains(toAdd))
  32. prevArr.add(toAdd);
  33. return previous;
  34. }
  35. if (previous.equals(toAdd))
  36. return previous;
  37. ArrayList<Object> arr = new ArrayList<Object>();
  38. arr.add(previous);
  39. arr.add(toAdd);
  40. return arr;
  41. }
  42. protected Object getQueriedIDs(IEvaluationContext ctx, IExpression variable, String memberName, IExpression booleanExpr, Object queriedKeys) {
  43. IExpression targetExpr = booleanExpr;
  44. if (booleanExpr instanceof IMatchExpression<?>) {
  45. targetExpr = ((Unary) targetExpr).operand;
  46. ctx = ((IMatchExpression<?>) booleanExpr).createContext();
  47. }
  48. int type = targetExpr.getExpressionType();
  49. switch (type) {
  50. case IExpression.TYPE_EQUALS :
  51. Binary eqExpr = (Binary) targetExpr;
  52. IExpression lhs = eqExpr.lhs;
  53. IExpression rhs = eqExpr.rhs;
  54. if (isIndexedMember(lhs, variable, memberName)) {
  55. Object val = safeEvaluate(ctx, rhs);
  56. if (val == null)
  57. return null;
  58. return concatenateUnique(queriedKeys, val);
  59. }
  60. if (isIndexedMember(rhs, variable, memberName)) {
  61. Object val = safeEvaluate(ctx, lhs);
  62. if (val == null)
  63. return null;
  64. return concatenateUnique(queriedKeys, val);
  65. }
  66. // Not applicable for indexing
  67. return null;
  68. case IExpression.TYPE_AND :
  69. // AND is OK if at least one of the branches require the queried key
  70. for (IExpression expr : ExpressionUtil.getOperands(targetExpr)) {
  71. Object test = getQueriedIDs(ctx, variable, memberName, expr, queriedKeys);
  72. if (test != null) {
  73. if (test == Boolean.FALSE)
  74. // Failing exists so the AND will fail altogether
  75. return test;
  76. // It's safe to break here since an and'ing several queries
  77. // for different keys and the same input will yield false anyway.
  78. return test;
  79. }
  80. }
  81. return null;
  82. case IExpression.TYPE_OR :
  83. // OR is OK if all the branches require the queried key
  84. for (IExpression expr : ExpressionUtil.getOperands(targetExpr)) {
  85. Object test = getQueriedIDs(ctx, variable, memberName, expr, queriedKeys);
  86. if (test == null)
  87. // This branch did not require the key so index cannot be used
  88. return null;
  89. if (test == Boolean.FALSE)
  90. // Branch will always fail regardless of input, so just ignore
  91. continue;
  92. queriedKeys = test;
  93. }
  94. return queriedKeys;
  95. case IExpression.TYPE_EXISTS :
  96. case IExpression.TYPE_ALL :
  97. // We must evaluate the lhs to find the referenced keys
  98. //
  99. CollectionFilter cf = (CollectionFilter) targetExpr;
  100. Iterator<?> values;
  101. try {
  102. values = cf.getOperand().evaluateAsIterator(ctx);
  103. } catch (IllegalArgumentException e) {
  104. return null;
  105. }
  106. if (!values.hasNext())
  107. // No keys are requested but we know that an exists must
  108. // fail at this point. An all will however succeed regardless
  109. // of what is used as input.
  110. return type == IExpression.TYPE_ALL ? null : Boolean.FALSE;
  111. LambdaExpression lambda = cf.lambda;
  112. IEvaluationContext lambdaCtx = lambda.prolog(ctx);
  113. Variable lambdaVar = lambda.getItemVariable();
  114. IExpression filterExpr = lambda.getOperand();
  115. do {
  116. lambdaVar.setValue(lambdaCtx, values.next());
  117. queriedKeys = getQueriedIDs(lambdaCtx, variable, memberName, filterExpr, queriedKeys);
  118. if (queriedKeys == null)
  119. // No use continuing. The expression does not require the key
  120. return null;
  121. } while (values.hasNext());
  122. return queriedKeys;
  123. }
  124. return null;
  125. }
  126. private static Object safeEvaluate(IEvaluationContext ctx, IExpression expr) {
  127. try {
  128. return expr.evaluate(ctx);
  129. } catch (IllegalArgumentException e) {
  130. return null;
  131. }
  132. }
  133. }