text:
package org.apache.hadoop.hive.ql.optimizer.lineage;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Stack;

import org.apache.hadoop.hive.metastore.api.FieldSchema;
import org.apache.hadoop.hive.metastore.api.Table;
import org.apache.hadoop.hive.ql.exec.ColumnInfo;
import org.apache.hadoop.hive.ql.exec.FileSinkOperator;
import org.apache.hadoop.hive.ql.exec.FilterOperator;
import org.apache.hadoop.hive.ql.exec.ForwardOperator;
import org.apache.hadoop.hive.ql.exec.GroupByOperator;
import org.apache.hadoop.hive.ql.exec.JoinOperator;
import org.apache.hadoop.hive.ql.exec.LateralViewJoinOperator;
import org.apache.hadoop.hive.ql.exec.LimitOperator;
import org.apache.hadoop.hive.ql.exec.Operator;
import org.apache.hadoop.hive.ql.exec.ReduceSinkOperator;
import org.apache.hadoop.hive.ql.exec.RowSchema;
import org.apache.hadoop.hive.ql.exec.ScriptOperator;
import org.apache.hadoop.hive.ql.exec.SelectOperator;
import org.apache.hadoop.hive.ql.exec.TableScanOperator;
import org.apache.hadoop.hive.ql.exec.Utilities;
import org.apache.hadoop.hive.ql.hooks.LineageInfo;
import org.apache.hadoop.hive.ql.hooks.LineageInfo.BaseColumnInfo;
import org.apache.hadoop.hive.ql.hooks.LineageInfo.Dependency;
import org.apache.hadoop.hive.ql.hooks.LineageInfo.DependencyType;
import org.apache.hadoop.hive.ql.hooks.LineageInfo.Predicate;
import org.apache.hadoop.hive.ql.hooks.LineageInfo.TableAliasInfo;
import org.apache.hadoop.hive.ql.lib.Node;
import org.apache.hadoop.hive.ql.lib.NodeProcessor;
import org.apache.hadoop.hive.ql.lib.NodeProcessorCtx;
import org.apache.hadoop.hive.ql.lib.Utils;
import org.apache.hadoop.hive.ql.metadata.VirtualColumn;
import org.apache.hadoop.hive.ql.parse.ParseContext;
import org.apache.hadoop.hive.ql.parse.SemanticException;
import org.apache.hadoop.hive.ql.plan.AggregationDesc;
import org.apache.hadoop.hive.ql.plan.ExprNodeDesc;
import org.apache.hadoop.hive.ql.plan.FilterDesc;
import org.apache.hadoop.hive.ql.plan.JoinCondDesc;
import org.apache.hadoop.hive.ql.plan.JoinDesc;
import org.apache.hadoop.hive.ql.plan.OperatorDesc;
import org.apache.hadoop.hive.ql.plan.ReduceSinkDesc;

/**
 * Operator factory for the rule processors for lineage.
 */
public class OpProcFactory {

  /**
   * Returns the parent operator in the walk path to the current operator.
   *
   * @param stack The stack encoding the path.
   *
   * @return Operator The parent operator in the current path.
   */
  @SuppressWarnings("unchecked")
  protected static Operator<? extends OperatorDesc> getParent(Stack<Node> stack) {
    return (Operator<? extends OperatorDesc>)Utils.getNthAncestor(stack, 1);
  }

  /**
   * Processor for Script and UDTF Operators.
   */
  public static class TransformLineage extends DefaultLineage implements NodeProcessor {

    @Override
    public Object process(Node nd, Stack<Node> stack, NodeProcessorCtx procCtx,
        Object... nodeOutputs) throws SemanticException {

      // LineageCTx
      LineageCtx lCtx = (LineageCtx) procCtx;

      // The operators
      @SuppressWarnings("unchecked")
      Operator<? extends OperatorDesc> op = (Operator<? extends OperatorDesc>)nd;
      Operator<? extends OperatorDesc> inpOp = getParent(stack);
      lCtx.getIndex().copyPredicates(inpOp, op);

      // Create a single dependency list by concatenating the dependencies of all
      // the cols
      Dependency dep = new Dependency();
      DependencyType new_type = LineageInfo.DependencyType.SCRIPT;
      dep.setType(LineageInfo.DependencyType.SCRIPT);
      // TODO: Fix this to a non null value.
      dep.setExpr(null);

      LinkedHashSet<BaseColumnInfo> col_set = new LinkedHashSet<BaseColumnInfo>();
      for(ColumnInfo ci : inpOp.getSchema().getSignature()) {
        Dependency d = lCtx.getIndex().getDependency(inpOp, ci);
        if (d != null) {
          new_type = LineageCtx.getNewDependencyType(d.getType(), new_type);
          if (!ci.isHiddenVirtualCol()) {
            col_set.addAll(d.getBaseCols());
          }
        }
      }

      dep.setType(new_type);
      dep.setBaseCols(col_set);

      boolean isScript = op instanceof ScriptOperator;

      // This dependency is then set for all the colinfos of the script operator
      for(ColumnInfo ci : op.getSchema().getSignature()) {
        Dependency d = dep;
        if (!isScript) {
          Dependency dep_ci = lCtx.getIndex().getDependency(inpOp, ci);
          if (dep_ci != null) {
            d = dep_ci;
          }
        }
        lCtx.getIndex().putDependency(op, ci, d);
      }

      return null;
    }

  }

  /**
   * Processor for TableScan Operator. This actually creates the base column mappings.
   */
  public static class TableScanLineage extends DefaultLineage implements NodeProcessor {

    @Override
    public Object process(Node nd, Stack<Node> stack, NodeProcessorCtx procCtx,
        Object... nodeOutputs) throws SemanticException {

      // LineageCtx
      LineageCtx lCtx = (LineageCtx) procCtx;
      ParseContext pctx = lCtx.getParseCtx();

      // Table scan operator.
      TableScanOperator top = (TableScanOperator)nd;
      org.apache.hadoop.hive.ql.metadata.Table t = top.getConf().getTableMetadata();
      Table tab = t.getTTable();

      // Generate the mappings
      RowSchema rs = top.getSchema();
      List<FieldSchema> cols = t.getAllCols();
      Map<String, FieldSchema> fieldSchemaMap = new HashMap<String, FieldSchema>();
      for(FieldSchema col : cols) {
        fieldSchemaMap.put(col.getName(), col);
      }

      Iterator<VirtualColumn> vcs = VirtualColumn.getRegistry(pctx.getConf()).iterator();
      while (vcs.hasNext()) {
        VirtualColumn vc = vcs.next();
        fieldSchemaMap.put(vc.getName(), new FieldSchema(vc.getName(),
            vc.getTypeInfo().getTypeName(), ""));
      }

      TableAliasInfo tai = new TableAliasInfo();
      tai.setAlias(top.getConf().getAlias());
      tai.setTable(tab);
      for(ColumnInfo ci : rs.getSignature()) {
        // Create a dependency
        Dependency dep = new Dependency();
        BaseColumnInfo bci = new BaseColumnInfo();
        bci.setTabAlias(tai);
        bci.setColumn(fieldSchemaMap.get(ci.getInternalName()));

        // Populate the dependency
        dep.setType(LineageInfo.DependencyType.SIMPLE);
        dep.setBaseCols(new LinkedHashSet<BaseColumnInfo>());
        dep.getBaseCols().add(bci);

        // Put the dependency in the map
        lCtx.getIndex().putDependency(top, ci, dep);
      }

      return null;
    }

  }

  /**
   * Processor for Join Operator.
   */
  public static class JoinLineage extends DefaultLineage implements NodeProcessor {
    @Override
    public Object process(Node nd, Stack<Node> stack, NodeProcessorCtx procCtx,
        Object... nodeOutputs) throws SemanticException {

      // Assert that there is at least one item in the stack. This should never
      // be called for leafs.
      assert(!stack.isEmpty());

      // LineageCtx
      LineageCtx lCtx = (LineageCtx) procCtx;
      JoinOperator op = (JoinOperator)nd;
      JoinDesc jd = op.getConf();

      // The input operator to the join is always a reduce sink operator
      ReduceSinkOperator inpOp = (ReduceSinkOperator)getParent(stack);
      lCtx.getIndex().copyPredicates(inpOp, op);
      Predicate cond = getPredicate(op, lCtx);
      if (cond != null) {
        lCtx.getIndex().addPredicate(op, cond);
      }

      ReduceSinkDesc rd = inpOp.getConf();
      int tag = rd.getTag();

      // Iterate over the outputs of the join operator and merge the
      // dependencies of the columns that corresponding to the tag.
      int cnt = 0;
      List<ExprNodeDesc> exprs = jd.getExprs().get((byte)tag);
      for(ColumnInfo ci : op.getSchema().getSignature()) {
        if (jd.getReversedExprs().get(ci.getInternalName()) != tag) {
          continue;
        }

        // Otherwise look up the expression corresponding to this ci
        ExprNodeDesc expr = exprs.get(cnt++);
        Dependency dependency = ExprProcFactory.getExprDependency(lCtx, inpOp, expr);
        lCtx.getIndex().mergeDependency(op, ci, dependency);
      }

      return null;
    }

    private Predicate getPredicate(JoinOperator jop, LineageCtx lctx) {
      List<Operator<? extends OperatorDesc>> parentOperators = jop.getParentOperators();
      JoinDesc jd = jop.getConf();
      ExprNodeDesc [][] joinKeys = jd.getJoinKeys();
      if (joinKeys == null || parentOperators == null || parentOperators.size() < 2) {
        return null;
      }
      LineageCtx.Index index = lctx.getIndex();
      for (Operator<? extends OperatorDesc> op: parentOperators) {
        if (index.getDependencies(op) == null) {
          return null;
        }
      }
      Predicate cond = new Predicate();
      JoinCondDesc[] conds = jd.getConds();
      int parents = parentOperators.size();
      StringBuilder sb = new StringBuilder("(");
      for (int i = 0; i < conds.length; i++) {
        if (i != 0) {
          sb.append(" AND ");
        }
        int left = conds[i].getLeft();
        int right = conds[i].getRight();
        if (joinKeys.length < left
            || joinKeys[left].length == 0
            || joinKeys.length < right
            || joinKeys[right].length == 0
            || parents < left
            || parents < right) {
          return null;
        }
        ExprNodeDesc expr = joinKeys[left][0];
        Operator<? extends OperatorDesc> op = parentOperators.get(left);
        List<Operator<? extends OperatorDesc>> p = op.getParentOperators();
        if (p == null || p.isEmpty()) {
          return null;
        }
        sb.append(ExprProcFactory.getExprString(op.getSchema(),
          expr, lctx, p.get(0), cond));
        sb.append(" = ");
        expr = joinKeys[right][0];
        op = parentOperators.get(right);
        p = op.getParentOperators();
        if (p == null || p.isEmpty()) {
          return null;
        }
        sb.append(ExprProcFactory.getExprString(op.getSchema(),
          expr, lctx, p.get(0), cond));
      }
      sb.append(")");
      cond.setExpr(sb.toString());
      return cond;
    }
  }

  /**
   * Processor for Join Operator.
   */
  public static class LateralViewJoinLineage extends DefaultLineage implements NodeProcessor {
    @Override
    public Object process(Node nd, Stack<Node> stack, NodeProcessorCtx procCtx,
        Object... nodeOutputs) throws SemanticException {

      // Assert that there is at least one item in the stack. This should never
      // be called for leafs.
      assert(!stack.isEmpty());

      // LineageCtx
      LineageCtx lCtx = (LineageCtx) procCtx;
      LateralViewJoinOperator op = (LateralViewJoinOperator)nd;
      boolean isUdtfPath = true;
      Operator<? extends OperatorDesc> inpOp = getParent(stack);
      ArrayList<ColumnInfo> cols = inpOp.getSchema().getSignature();
      lCtx.getIndex().copyPredicates(inpOp, op);

      if (inpOp instanceof SelectOperator) {
        isUdtfPath = false;
      }

      // Dirty hack!!
      // For the select path the columns are the ones at the beginning of the
      // current operators schema and for the udtf path the columns are
      // at the end of the operator schema.
      ArrayList<ColumnInfo> out_cols = op.getSchema().getSignature();
      int out_cols_size = out_cols.size();
      int cols_size = cols.size();
      int outColOffset = isUdtfPath ? out_cols_size - cols_size : 0;
      for (int cnt = 0; cnt < cols_size; cnt++) {
        ColumnInfo outCol = out_cols.get(outColOffset + cnt);
        if (!outCol.isHiddenVirtualCol()) {
          ColumnInfo col = cols.get(cnt);
          lCtx.getIndex().mergeDependency(op, outCol,
            lCtx.getIndex().getDependency(inpOp, col));
        }
      }
      return null;
    }

  }

  /**
   * Processor for Select operator.
   */
  public static class SelectLineage extends DefaultLineage implements NodeProcessor {
    @Override
    public Object process(Node nd, Stack<Node> stack, NodeProcessorCtx procCtx,
        Object... nodeOutputs) throws SemanticException {

      LineageCtx lctx = (LineageCtx)procCtx;
      SelectOperator sop = (SelectOperator)nd;

      // if this is a selStarNoCompute then this select operator
      // is treated like a default operator, so just call the super classes
      // process method.
      if (sop.getConf().isSelStarNoCompute()) {
        return super.process(nd, stack, procCtx, nodeOutputs);
      }

      // Otherwise we treat this as a normal select operator and look at
      // the expressions.

      Operator<? extends OperatorDesc> inpOp = getParent(stack);
      lctx.getIndex().copyPredicates(inpOp, sop);

      RowSchema rs = sop.getSchema();
      ArrayList<ColumnInfo> col_infos = rs.getSignature();
      int cnt = 0;
      for(ExprNodeDesc expr : sop.getConf().getColList()) {
        Dependency dep = ExprProcFactory.getExprDependency(lctx, inpOp, expr);
        if (dep != null && dep.getExpr() == null && (dep.getBaseCols().isEmpty()
            || dep.getType() != LineageInfo.DependencyType.SIMPLE)) {
          dep.setExpr(ExprProcFactory.getExprString(rs, expr, lctx, inpOp, null));
        }
        lctx.getIndex().putDependency(sop, col_infos.get(cnt++), dep);
      }

      Operator<? extends OperatorDesc> op = null;
      if (!sop.getChildOperators().isEmpty()) {
        op = sop.getChildOperators().get(0);
        if (!op.getChildOperators().isEmpty() && op instanceof LimitOperator) {
          op = op.getChildOperators().get(0);
        }
      }
      if (op == null || (op.getChildOperators().isEmpty()
          && op instanceof FileSinkOperator)) {
        lctx.getIndex().addFinalSelectOp(sop, op);
      }

      return null;
    }

  }

  /**
   * Processor for GroupBy operator.
   */
  public static class GroupByLineage extends DefaultLineage implements NodeProcessor {
    @Override
    public Object process(Node nd, Stack<Node> stack, NodeProcessorCtx procCtx,
        Object... nodeOutputs) throws SemanticException {

      LineageCtx lctx = (LineageCtx)procCtx;
      GroupByOperator gop = (GroupByOperator)nd;
      ArrayList<ColumnInfo> col_infos = gop.getSchema().getSignature();
      Operator<? extends OperatorDesc> inpOp = getParent(stack);
      lctx.getIndex().copyPredicates(inpOp, gop);
      int cnt = 0;

      for(ExprNodeDesc expr : gop.getConf().getKeys()) {
        lctx.getIndex().putDependency(gop, col_infos.get(cnt++),
            ExprProcFactory.getExprDependency(lctx, inpOp, expr));
      }

      // If this is a reduce side GroupBy operator, check if there is
      // a corresponding map side one. If so, some expression could have
      // already been resolved in the map side.
      boolean reduceSideGop = (inpOp instanceof ReduceSinkOperator)
        && (Utils.getNthAncestor(stack, 2) instanceof GroupByOperator);

      RowSchema rs = gop.getSchema();
      for(AggregationDesc agg : gop.getConf().getAggregators()) {
        // Concatenate the dependencies of all the parameters to
        // create the new dependency
        Dependency dep = new Dependency();
        DependencyType new_type = LineageInfo.DependencyType.EXPRESSION;
        StringBuilder sb = new StringBuilder();
        boolean first = true;
        LinkedHashSet<BaseColumnInfo> bci_set = new LinkedHashSet<BaseColumnInfo>();
        for(ExprNodeDesc expr : agg.getParameters()) {
          if (first) {
            first = false;
          } else {
            sb.append(", ");
          }
          Dependency expr_dep = ExprProcFactory.getExprDependency(lctx, inpOp, expr);
          if (expr_dep != null && !expr_dep.getBaseCols().isEmpty()) {
            new_type = LineageCtx.getNewDependencyType(expr_dep.getType(), new_type);
            bci_set.addAll(expr_dep.getBaseCols());
            if (expr_dep.getType() == LineageInfo.DependencyType.SIMPLE) {
              BaseColumnInfo col = expr_dep.getBaseCols().iterator().next();
              Table t = col.getTabAlias().getTable();
              if (t != null) {
                sb.append(t.getDbName()).append(".").append(t.getTableName()).append(".");
              }
              sb.append(col.getColumn().getName());
            }
          }
          if (expr_dep == null || expr_dep.getBaseCols().isEmpty()
              || expr_dep.getType() != LineageInfo.DependencyType.SIMPLE) {
            sb.append(expr_dep != null && expr_dep.getExpr() != null ? expr_dep.getExpr() :
              ExprProcFactory.getExprString(rs, expr, lctx, inpOp, null));
          }
        }
        String expr = sb.toString();
        String udafName = agg.getGenericUDAFName();
        if (!(reduceSideGop && expr.startsWith(udafName))) {
          sb.setLength(0); // reset the buffer
          sb.append(udafName);
          sb.append("(");
          if (agg.getDistinct()) {
            sb.append("DISTINCT ");
          }
          sb.append(expr);
          if (first) {
            // No parameter, count(*)
            sb.append("*");
          }
          sb.append(")");
          expr = sb.toString();
        }
        dep.setExpr(expr);

        // If the bci_set is empty, this means that the inputs to this
        // aggregate function were all constants (e.g. count(1)). In this case
        // the aggregate function is just dependent on all the tables that are in
        // the dependency list of the input operator.
        if (bci_set.isEmpty()) {
          Set<TableAliasInfo> tai_set = new LinkedHashSet<TableAliasInfo>();
          if (inpOp.getSchema() != null && inpOp.getSchema().getSignature() != null ) {
            for(ColumnInfo ci : inpOp.getSchema().getSignature()) {
              Dependency inp_dep = lctx.getIndex().getDependency(inpOp, ci);
              // The dependency can be null as some of the input cis may not have
              // been set in case of joins.
              if (inp_dep != null) {
                for(BaseColumnInfo bci : inp_dep.getBaseCols()) {
                  new_type = LineageCtx.getNewDependencyType(inp_dep.getType(), new_type);
                  tai_set.add(bci.getTabAlias());
                }
              }
            }
          }

          // Create the BaseColumnInfos and set them in the bci_set
          for(TableAliasInfo tai : tai_set) {
            BaseColumnInfo bci = new BaseColumnInfo();
            bci.setTabAlias(tai);
            // This is set to null to reflect that the dependency is not on any
            // particular column of the table.
            bci.setColumn(null);
            bci_set.add(bci);
          }
        }

        dep.setBaseCols(bci_set);
        dep.setType(new_type);
        lctx.getIndex().putDependency(gop, col_infos.get(cnt++), dep);
      }

      return null;
    }

  }

  /**
   * Union processor.
   * In this case we call mergeDependency as opposed to putDependency
   * in order to account for visits from different parents.
   */
  public static class UnionLineage extends DefaultLineage implements NodeProcessor {

    @SuppressWarnings("unchecked")
    @Override
    public Object process(Node nd, Stack<Node> stack, NodeProcessorCtx procCtx,
        Object... nodeOutputs) throws SemanticException {
      // Assert that there is at least one item in the stack. This should never
      // be called for leafs.
      assert(!stack.isEmpty());

      // LineageCtx
      LineageCtx lCtx = (LineageCtx) procCtx;
      Operator<? extends OperatorDesc> op = (Operator<? extends OperatorDesc>)nd;

      // Get the row schema of the input operator.
      // The row schema of the parent operator
      Operator<? extends OperatorDesc> inpOp = getParent(stack);
      lCtx.getIndex().copyPredicates(inpOp, op);
      RowSchema rs = op.getSchema();
      ArrayList<ColumnInfo> inp_cols = inpOp.getSchema().getSignature();
      int cnt = 0;
      for(ColumnInfo ci : rs.getSignature()) {
        Dependency inp_dep = lCtx.getIndex().getDependency(inpOp, inp_cols.get(cnt++));
        if (inp_dep != null) {
          lCtx.getIndex().mergeDependency(op, ci, inp_dep);
        }
      }
      return null;
    }
  }

  /**
   * ReduceSink processor.
   */
  public static class ReduceSinkLineage implements NodeProcessor {

    @Override
    public Object process(Node nd, Stack<Node> stack, NodeProcessorCtx procCtx,
        Object... nodeOutputs) throws SemanticException {
      // Assert that there is at least one item in the stack. This should never
      // be called for leafs.
      assert(!stack.isEmpty());

      // LineageCtx
      LineageCtx lCtx = (LineageCtx) procCtx;
      ReduceSinkOperator rop = (ReduceSinkOperator)nd;

      Operator<? extends OperatorDesc> inpOp = getParent(stack);
      lCtx.getIndex().copyPredicates(inpOp, rop);
      int cnt = 0;

      // The keys are included only in case the reduce sink feeds into
      // a group by operator through a chain of forward operators
      Operator<? extends OperatorDesc> op = rop.getChildOperators().get(0);
      while (op instanceof ForwardOperator) {
        op = op.getChildOperators().get(0);
      }

      if (op instanceof GroupByOperator) {
        ArrayList<ColumnInfo> col_infos = rop.getSchema().getSignature();
        for(ExprNodeDesc expr : rop.getConf().getKeyCols()) {
          lCtx.getIndex().putDependency(rop, col_infos.get(cnt++),
              ExprProcFactory.getExprDependency(lCtx, inpOp, expr));
        }
        for(ExprNodeDesc expr : rop.getConf().getValueCols()) {
          lCtx.getIndex().putDependency(rop, col_infos.get(cnt++),
              ExprProcFactory.getExprDependency(lCtx, inpOp, expr));
        }
      } else {
        RowSchema schema = rop.getSchema();
        ReduceSinkDesc desc = rop.getConf();
        List<ExprNodeDesc> keyCols = desc.getKeyCols();
        ArrayList<String> keyColNames = desc.getOutputKeyColumnNames();
        for (int i = 0; i < keyCols.size(); i++) {
          // order-bys, joins
          ColumnInfo column = schema.getColumnInfo(Utilities.ReduceField.KEY + "." + keyColNames.get(i));
          if (column == null) {
            continue;   // key in values
          }
          lCtx.getIndex().putDependency(rop, column,
              ExprProcFactory.getExprDependency(lCtx, inpOp, keyCols.get(i)));
        }
        List<ExprNodeDesc> valCols = desc.getValueCols();
        ArrayList<String> valColNames = desc.getOutputValueColumnNames();
        for (int i = 0; i < valCols.size(); i++) {
          // todo: currently, bucketing,etc. makes RS differently with those for order-bys or joins
          ColumnInfo column = schema.getColumnInfo(valColNames.get(i));
          if (column == null) {
            // order-bys, joins
            column = schema.getColumnInfo(Utilities.ReduceField.VALUE + "." + valColNames.get(i));
          }
          lCtx.getIndex().putDependency(rop, column,
              ExprProcFactory.getExprDependency(lCtx, inpOp, valCols.get(i)));
        }
      }

      return null;
    }
  }

  /**
   * Filter processor.
   */
  public static class FilterLineage implements NodeProcessor {

    @Override
    public Object process(Node nd, Stack<Node> stack, NodeProcessorCtx procCtx,
        Object... nodeOutputs) throws SemanticException {
      // Assert that there is at least one item in the stack. This should never
      // be called for leafs.
      assert(!stack.isEmpty());

      // LineageCtx
      LineageCtx lCtx = (LineageCtx) procCtx;
      FilterOperator fop = (FilterOperator)nd;

      // Get the row schema of the input operator.
      // The row schema of the parent operator
      Operator<? extends OperatorDesc> inpOp = getParent(stack);
      lCtx.getIndex().copyPredicates(inpOp, fop);
      FilterDesc filterDesc = fop.getConf();
      RowSchema rs = fop.getSchema();
      if (!filterDesc.isGenerated()) {
        Predicate cond = new Predicate();
        cond.setExpr(ExprProcFactory.getExprString(
          rs, filterDesc.getPredicate(), lCtx, inpOp, cond));
        lCtx.getIndex().addPredicate(fop, cond);
      }

      ArrayList<ColumnInfo> inp_cols = inpOp.getSchema().getSignature();
      int cnt = 0;
      for(ColumnInfo ci : rs.getSignature()) {
        lCtx.getIndex().putDependency(fop, ci,
            lCtx.getIndex().getDependency(inpOp, inp_cols.get(cnt++)));
      }

      return null;
    }
  }

  /**
   * Default processor. This basically passes the input dependencies as such
   * to the output dependencies.
   */
  public static class DefaultLineage implements NodeProcessor {

    @SuppressWarnings("unchecked")
    @Override
    public Object process(Node nd, Stack<Node> stack, NodeProcessorCtx procCtx,
        Object... nodeOutputs) throws SemanticException {
      // Assert that there is at least one item in the stack. This should never
      // be called for leafs.
      assert(!stack.isEmpty());

      // LineageCtx
      LineageCtx lCtx = (LineageCtx) procCtx;
      Operator<? extends OperatorDesc> op = (Operator<? extends OperatorDesc>)nd;

      // Get the row schema of the input operator.
      // The row schema of the parent operator
      Operator<? extends OperatorDesc> inpOp = getParent(stack);
      lCtx.getIndex().copyPredicates(inpOp, op);
      RowSchema rs = op.getSchema();
      ArrayList<ColumnInfo> inp_cols = inpOp.getSchema().getSignature();
      int cnt = 0;
      for(ColumnInfo ci : rs.getSignature()) {
        lCtx.getIndex().putDependency(op, ci,
            lCtx.getIndex().getDependency(inpOp, inp_cols.get(cnt++)));
      }
      return null;
    }
  }

  public static NodeProcessor getJoinProc() {
    return new JoinLineage();
  }

  public static NodeProcessor getLateralViewJoinProc() {
    return new LateralViewJoinLineage();
  }

  public static NodeProcessor getTSProc() {
    return new TableScanLineage();
  }

  public static NodeProcessor getTransformProc() {
    return new TransformLineage();
  }

  public static NodeProcessor getSelProc() {
    return new SelectLineage();
  }

  public static NodeProcessor getGroupByProc() {
    return new GroupByLineage();
  }

  public static NodeProcessor getUnionProc() {
    return new UnionLineage();
  }

  public static NodeProcessor getReduceSinkProc() {
    return new ReduceSinkLineage();
  }

  public static NodeProcessor getDefaultProc() {
    return new DefaultLineage();
  }

  public static NodeProcessor getFilterProc() {
    return new FilterLineage();
  }
}


text:
var mongoose = require("mongoose");

var Schema = mongoose.Schema;

var HopSchema = new Schema({
  name: {
    type: String
  },
  lbs: {
    type: String
  },
  ozs: {
    type: String
  },
  alphaAcid: {
    type: String
  },
  minutes: {
    type: String
  }
});

var Hop = mongoose.model("Hop", HopSchema);

module.exports = Hop;

redpajama_set_name: RedPajamaGithub


text:
var windowLoadProgress = window.onload;
window.onload = function () {
    if (windowLoadProgress) {
        windowLoadProgress();
    }

    var loadingElement = document.getElementById('loading'),
        loadingWrapper = document.getElementById('loadingWrapper'),
        resultElement = document.getElementById('result'),
        index = 0;

    test().then(function (data) {
        console.log("Success: " + data);
        loadingWrapper.style.visibility = 'hidden';
        resultElement.innerHTML = data;
    }, function (error) {
        console.log("Error: " + error);
    }, function (progress) {
        index += 1;
        console.log("Progress: " + progress);
        loadingElement.style.width = index * 50 + 'px';
    });

    function test() {
        var deferred = Q.defer();

        for (var i = 0; i < 15; i++) {
            setTimeout(function () {
                deferred.notify(i);
            }, i * 1000);
        }

        setTimeout(function () {
            deferred.resolve('IMPORTANT INFORMATION!!!');
        }, 10000)

        return deferred.promise;
    }
};


text:
require "test_helper"

class OrganisationUnitGroupSetsTest < Minitest::Test
  def test_group_sets
    group_sets = Dhis2.client.organisation_unit_group_sets.list(
      fields:    %w(id displayName code),
      page_size: 10_000
    )
    assert_equal true, group_sets.map(&:display_name).include?("Facility Type")
  end
end


text:
<?php
/**
 * checks if the current user has sudo privileges. returns TRUE or FALSE
 * @return boolean
 */
function ch_check_sudo() {
  return shell_exec('sudo -n uptime 2>&1|grep "load"|wc -l')*1 === 1;
}

/**
 * attempts to start collectd rrd stats for the current test iteration. returns
 * TRUE on success, FALSE otherwise
 * @param string $dir the base directory where collectd rrd files are stored
 * @param boolean $verbose enable verbose output
 * @return boolean
 */
function ch_collectd_rrd_start($dir, $verbose) {
  $started = FALSE;
  if (is_dir($dir) && ch_check_sudo()) {
    exec(sprintf('sudo rm -rf %s/*.bak', $dir));
    $d = dir($dir);
    while($entry = $d->read()) {
      if (!preg_match('/[a-zA-Z0-9]+/', $entry)) continue;
      $rdir = sprintf('%s/%s', $dir, $entry);
      if (is_dir($rdir) && !preg_match('/\.bak$/', $entry)) {
        $rdirBak = $rdir . '.bak';
        exec(sprintf('sudo mv %s %s', $rdir, $rdirBak));
        if (is_dir($rdirBak)) {
          $started = TRUE;
          print_msg(sprintf('Successfully renamed existing collectd rrd directory from %s to %s', $rdir, $rdirBak), $verbose, __FILE__, __LINE__);
        }
        else {
          $started = FALSE;
          print_msg(sprintf('Unable to rename existing collectd rrd directory from %s to %s', $rdir, $rdirBak), $verbose, __FILE__, __LINE__, TRUE);
        }
      }
    }
    $d->close();
  }
  return $started;
}

/**
 * attempts to stop collectd rrd stats for the current test iteration. returns
 * TRUE on success, FALSE otherwise
 * @param string $dir the base directory where collectd rrd files are stored
 * @param string $saveTo the directory where the rrd zip file should be created
 * @param array $options test options - used to construct collectd rrd results
 * directories
 * @param boolean $verbose enable verbose output
 * @return boolean
 */
function ch_collectd_rrd_stop($dir, $saveTo, $verbose) {
  $stopped = FALSE;
  if (is_dir($dir) && ch_check_sudo()) {
    $tdir = '/tmp/' . rand();
    exec(sprintf('sudo mkdir %s', $tdir));
    print_msg(sprintf('Attempting to save collectd rrd files in %s to %s/collectd-rrd.zip using tmp directory %s', $dir, $saveTo, $tdir), $verbose, __FILE__, __LINE__);

    $rename = array();
    $d = dir($dir);
    while($entry = $d->read()) {
      if (!preg_match('/[a-zA-Z0-9]+/', $entry)) continue;
      $rdir = sprintf('%s/%s', $dir, $entry);
      if (substr($rdir, -1) == '/') $rdir = substr($rdir, 0, -1);
      if (!is_dir($rdir)) continue;
      if (is_dir($rdir)) {
        print_msg(sprintf('Evaluating collectd rrd directory %s', $rdir), $verbose, __FILE__, __LINE__);
        if (preg_match('/\.bak$/', $entry)) $rename[] = $rdir;
        else {
          exec($cmd = sprintf('sudo mv %s %s', $rdir, $tdir));
          print_msg(sprintf('Successfully moved test collectd rrd directory %s to %s', basename($rdir), $tdir), $verbose, __FILE__, __LINE__);
        }
      }
    }
    $d->close();
    foreach($rename as $rdir) {
      $renameTo = substr($rdir, 0, -4);
      exec($cmd = sprintf('sudo rm -rf %s;sudo mv %s %s', $renameTo, $rdir, $renameTo));
      if (is_dir($renameTo)) print_msg(sprintf('Successfully renamed backup collectd rrd directory from %s to %s', $rdir, $renameTo), $verbose, __FILE__, __LINE__);
      else print_msg(sprintf('Unable to rename existing collectd rrd directory from %s to %s', $rdir, $renameTo), $verbose, __FILE__, __LINE__, TRUE);
    }

    if ((shell_exec(sprintf('find %s -maxdepth 1 -type d 2>/dev/null | wc -l', $tdir))*1 < 2)) print_msg(sprintf('collectd rrd directory %s did not contain any files', $dir), $verbose, __FILE__, __LINE__, TRUE);
    else {
      $zip = sprintf('%s/collectd-rrd.zip', $saveTo);
      exec($cmd = sprintf('cd %s;sudo zip -r collectd-rrd.zip *;sudo mv collectd-rrd.zip %s', $tdir, $saveTo, $tdir));
      if ($stopped = file_exists($zip) && filesize($zip)) print_msg(sprintf('Successfully saved collectd rrd files to %s', $zip), $verbose, __FILE__, __LINE__);
      else print_msg(sprintf('Unable to save collectd rrd files: %s', $cmd), $verbose, __FILE__, __LINE__, TRUE);
    }
  }
  else print_msg(sprintf('collectd rrd directory %s does not exist or user does not have sudo access', $dir), $verbose, __FILE__, __LINE__, TRUE);

  // sleep for 10 seconds to allow collectd to restart
  sleep(10);

  return $stopped;
}

/**
 * Invokes an http request and returns the status code (or response body if
 * $retBody is TRUE) on success, NULL on failure or FALSE if the response code
 * is not within the $success range
 * @param string  $url the target url
 * @param string $method the http method
 * @param array $headers optional request headers to include (hash or array)
 * @param string $file optional file to pipe into the curl process as the
 * body
 * @param string $auth optional [user]:[pswd] to use for http authentication
 * @param string $success the http response code/range that consistitutes
 * a successful request. defaults to 200 to 299. This parameter may be a comma
 * separated list of values or ranges (e.g. "200,404" or "200-299,404")
 * @param boolean $retBody whether or not to return the response body. If
 * FALSE (default), the status code is returned
 * @return mixed
 */
function ch_curl($url, $method='HEAD', $headers=NULL, $file=NULL, $auth=NULL, $success='200-299', $retBody=FALSE) {
  global $ch_curl_options;
  if (!isset($ch_curl_options)) $ch_curl_options = parse_args(array('v' => 'verbose'));

  if (!is_array($headers)) $headers = array();
  $ofile = $retBody ? '/tmp/' . rand() : '/dev/null';
  $curl = sprintf('curl -s -X %s%s -w "%s\n" -o %s', $method, $method == 'HEAD' ? ' -I' : '', '%{http_code}', $ofile);
  if ($auth) $curl .= sprintf(' -u "%s"', $auth);
  if (is_array($headers)) {
    foreach($headers as $header => $val) $curl .= sprintf(' -H "%s%s"', is_numeric($header) ? '' : $header . ':', $val);
  }
  // input file
  if (($method == 'POST' || $method == 'PUT') && file_exists($file)) {
    $curl .= sprintf(' --data-binary @%s', $file);
    if (!isset($headers['Content-Length']) && !isset($headers['content-length'])) $curl .= sprintf(' -H "Content-Length:%d"', filesize($file));
    if (!isset($headers['Content-Type']) && !isset($headers['content-type'])) $curl .= sprintf(' -H "Content-Type:%s"', get_mime_type($file));
  }
  $curl .= sprintf(' "%s"', $url);
  $ok = array();
  foreach(explode(',', $success) as $range) {
    if (is_numeric($range)) $ok[$range*1] = TRUE;
    else if (preg_match('/^([0-9]+)\s*\-\s*([0-9]+)$/', $range, $m) && $m[1] <= $m[2]) {
      for($i=$m[1]; $i<=$m[2]; $i++) $ok[$i] = TRUE;
    }
  }
  $ok = array_keys($ok);
  sort($ok);

  $cmd = sprintf('%s 2>/dev/null;echo $?', $curl);
  print_msg(sprintf('Invoking curl request: %s (expecting response %s)', $curl, $success), isset($ch_curl_options['verbose']), __FILE__, __LINE__);

  // execute curl
  $result = shell_exec($cmd);
  $output = explode("\n", trim($result));
  $response = NULL;

  // interpret callback response
  if (count($output) == 2) {
    $status = $output[0]*1;
    $ecode = $output[1]*1;
    if ($ecode) print_msg(sprintf('curl failed with exit code %d', $ecode), isset($ch_curl_options['verbose']), __FILE__, __LINE__, TRUE);
    else if (in_array($status, $ok)) {
      print_msg(sprintf('curl successful with status code %d', $status), isset($ch_curl_options['verbose']), __FILE__, __LINE__);
      $response = $retBody && file_exists($ofile) ? file_get_contents($ofile) : $status;
    }
    else {
      $response = FALSE;
      print_msg(sprintf('curl failed because to status code %d in not in allowed range %s', $status, $success), isset($ch_curl_options['verbose']), __FILE__, __LINE__, TRUE);
    }
  }
  if ($retBody && file_exists($ofile)) unlink($ofile);

  return $response;
}

/**
 * invokes 1 or more http requests using curl, waits until they are completed,
 * and returns the associated results. Return value is a hash containing the
 * following keys. Note: elements in urls, response and results may be arrays
 * if any 'url' values in $requests are arrays
 *   urls:     ordered array of URLs
 *   request:  ordered array of request headers (lowercase keys)
 *   response: ordered array of response headers (lowercase keys)
 *   results:  ordered array of curl result values - includes the following:
 *             speed:              transfer rate (bytes/sec)
 *             time:               total time for the operation
 *             transfer:           total bytes transferred
 *             url:                actual URL used
 *   status:   ordered array of status codes
 *   lowest_status: the lowest status code returned
 *   highest_status: the highest status code returned
 *   body:     response body (only included when $retBody is TRUE)
 * returns NULL if any of the curl commands fail
 * @param array $requests array defining the http requests to invoke. Each
 * element in this array is a hash with the following possible keys:
 *   method:  http method (default is GET)
 *   headers: hash or array defining http headers to append
 *   url:     the URL - may be an array to specify multiple (will use keep
 *            alive)
 *   input:   optional command to pipe into the curl process as the body
 *   body:    optional string or file to pipe into the curl process as the
 *            body. Alternatively, if this is a numeric value, a file will
 *            be created containing random bytes corresponding with the
 *            numeric value (created in $dir). This file will be deleted
 *            when the PHP process terminates
 *   range:   optional request byte range
 * @param int $timeout the max allowed time in seconds for each request (i.e.
 * --max-time). Default is 60. If < 1, no timeout will be set
 * @param string $dir optional directory where temporary files should be
 * written to - /tmp if not specified
 * @param boolean $retBody if TRUE, the response body will be included in the
 * return
 * @param boolean $insecure bypass certificate validation
 * @return array
 */
function ch_curl_mt($requests, $timeout=60, $dir='/tmp', $retBody=FALSE, $insecure=FALSE) {
  $fstart = microtime(TRUE);
  $script = sprintf('%s/%s', $dir, 'curl_script_' . rand());
  $fp = fopen($script, 'w');
  fwrite($fp, "#!/bin/sh\n");
  $ifiles = array();
  $ofiles = array();
  $bfiles = array();
  $result = array('urls' => array(), 'request' => array(), 'response' => array(), 'results' => array(), 'status' => array(), 'lowest_status' => 0, 'highest_status' => 0);
  if ($retBody) $result['body'] = array();
  foreach($requests as $i => $request) {
    if (isset($request['body'])) {
      if (file_exists($request['body'])) $file = $request['body'];
      // create random file
      else if (is_numeric($request['body']) && $request['body'] > 0) {
        $file = sprintf('%s/curl_input_%d', $dir, $request['body']);
        if (!file_exists($file)) {
          exec(sprintf('dd if=/dev/urandom of=%s bs=%d count=1 2>/dev/null', $file, $request['body']));
          if (file_exists($file) && filesize($file) != $request['body']) unlink($file);
          if (file_exists($file)) register_shutdown_function('unlink', $file);
          else $file = NULL;
        }
      }
      else {
        $ifiles[$i] = sprintf('%s/%s', $dir, 'curl_input_' . rand());
        $f = fopen($ifiles[$i], 'w');
        fwrite($f, $request['body']);
        fclose($f);
        $file = $ifiles[$i];
      }
      $request['input'] = 'cat ' . $file;
      $request['headers']['content-length'] = filesize($file);
    }
    if (!isset($request['headers'])) $request['headers'] = array();
    $method = isset($request['method']) ? strtoupper($request['method']) : 'GET';
    $body = '/dev/null';
    if ($retBody) {
      $bfiles[$i] = sprintf('%s/%s', $dir, 'curl_body_' . rand());
      $body = $bfiles[$i];
    }
    $cmd = (isset($request['input']) ? $request['input'] . ' | curl --data-binary @-' : 'curl') . ($method == 'HEAD' ? ' -I' : '') . ' -s -D - -w "transfer=%{' . ($method == 'GET' ? 'size_download' : 'size_upload') . '}\nspeed=%{' . ($method == 'GET' ? 'speed_download' : 'speed_upload') . '}\ntime=%{time_total}\nurl=%{url_effective}\n" -X ' . $method . ($insecure ? ' --insecure' : '') . (is_numeric($timeout) && $timeout>0 ? ' --max-time ' . $timeout : '');
    $result['request'][$i] = $request['headers'];
    foreach($request['headers'] as $header => $val) $cmd .= sprintf(' -H "%s%s"', is_numeric($header) ? '' : $header . ':', $val);
    if (isset($request['range'])) $cmd .= ' -r ' . $request['range'];
    $result['urls'][$i] = $request['url'];
    if (!is_array($request['url'])) $request['url'] = array($request['url']);
    foreach($request['url'] as $url) $cmd .= sprintf(' -o %s', $body);
    foreach($request['url'] as $url) $cmd .= sprintf(' "%s"', $url);
    $ofiles[$i] = sprintf('%s/%s', $dir, 'curl_output_' . rand());
    fwrite($fp, sprintf("%s > %s 2>&1 &\n", $cmd, $ofiles[$i]));
  }
  fwrite($fp, "wait\n");
  fclose($fp);
  exec(sprintf('chmod 755 %s', $script));
  $start = microtime(TRUE);
  exec($script);
  $curl_time = microtime(TRUE) - $start;
  foreach(array_keys($requests) as $i) {
    foreach(file($ofiles[$i]) as $line) {
      // status code
      if (preg_match('/HTTP[\S]+\s+([0-9]+)\s/', $line, $m)) {
        $status = $m[1]*1;
        if (isset($result['status'][$i]) && !is_array($result['status'][$i])) $result['status'][$i] = array($result['status'][$i]);
        if (isset($result['status'][$i]) && is_array($result['status'][$i])) $result['status'][$i][] = $status;
        else $result['status'][$i] = $status;

        if ($result['lowest_status'] === 0 || $status < $result['lowest_status']) $result['lowest_status'] = $status;
        if ($status > $result['highest_status']) $result['highest_status'] = $status;
      }
      // response header
      else if (preg_match('/^([^:]+):\s+"?([^"]+)"?$/', trim($line), $m)) {
        $k = trim(strtolower($m[1]));
        if (isset($result['response'][$i][$k]) && !is_array($result['response'][$i][$k])) $result['response'][$i][$k] = array($result['response'][$i][$k]);
        if (isset($result['response'][$i][$k]) && is_array($result['response'][$i][$k])) $result['response'][$i][$k][] = $m[2];
        else $result['response'][$i][$k] = $m[2];
      }
      // result value
      else if (preg_match('/^([^=]+)=(.*)$/', trim($line), $m)) {
        $k = trim(strtolower($m[1]));
        if (isset($result['results'][$i][$k]) && !is_array($result['results'][$i][$k])) $result['results'][$i][$k] = array($result['results'][$i][$k]);
        if (isset($result['results'][$i][$k]) && is_array($result['results'][$i][$k])) $result['results'][$i][$k][] = $m[2];
        else $result['results'][$i][$k] = $m[2];
      }
      // body
      if (isset($bfiles[$i]) && file_exists($bfiles[$i])) {
        $result['body'][$i] = file_get_contents($bfiles[$i]);
        unlink($bfiles[$i]);
      }
    }
    unlink($ofiles[$i]);
  }
  foreach($ifiles as $ifile) unlink($ifile);
  unlink($script);
  if (!$result['highest_status']) {
    $result = NULL;
  }

  return $result;
}

/**
 * returns the country and state associated with $hostname if the geoiplookup
 * command is present and returns such information. return value is a hash with
 * 2 keys: country and state on success, NULL on failure
 * @param string $hostname hostname to lookup
 * @param boolean $verbose verbose print option
 * @return array
 */
function geoiplookup($hostname, $verbose=FALSE) {
  $info = NULL;
  $cmd = sprintf('geoiplookup %s 2>/dev/null', $hostname);
  if ($buffer = shell_exec($cmd)) {
    foreach(explode("\n", $buffer) as $line) {
      if (preg_match('/\s+([A-Z]{2}),\s+([A-Z]{2}),/', $line, $m)) {
        $info = array('country' => $m[1], 'state' => $m[2]);
        print_msg(sprintf('Determined state %s and country %s for hostname %s', $info['state'], $info['country'], $hostname), $verbose, __FILE__, __LINE__);
        break;
      }
      else if (preg_match('/\s+([A-Z]{2}),/', $line, $m)) {
        $info = array('country' => $m[1]);
        print_msg(sprintf('Determined country %s for hostname %s', $info['country'], $hostname), $verbose, __FILE__, __LINE__);
      }
    }
  }
  return $info;
}

/**
 * returns the contents of benchmark.ini as a hash
 */
function get_benchmark_ini() {
  global $benchmark_ini;
  if (!isset($benchmark_ini)) {
    $dirs = array(dirname(__FILE__));
    while(($dir = dirname($dirs[count($dirs) - 1])) != '/') $dirs[] = $dir;
    foreach($dirs as $dir) {
      if (file_exists($file = sprintf('%s/benchmark.ini', $dir))) {
        $benchmark_ini = array();
        foreach(file($file) as $line) {
          if (preg_match('/^([A-Za-z][^=]+)=(.*)$/', trim($line), $m)) $benchmark_ini[$m[1]] = $m[2];
        }
        break;
      }
    }
  }
  return $benchmark_ini;
}

/**
 * returns the free space in MB for the directory or device specified by $dir
 * @param string $dir directory or device path to return free space for
 * @return float
 */
function get_free_space($dir) {
  $free = NULL;
  if (preg_match('/^\/dev/', $dir) && file_exists($sfile = sprintf('/sys/class/block/%s/size', basename($dir)))) {
    $free = ((trim(file_get_contents($sfile))*512)/1024)/1024;
  }
  else if (is_dir($dir)) {
  	$stats = array();
  	$dfm = shell_exec('df -m');
  	foreach(explode("\n", $dfm) as $line) {
  		if (isset($last) && preg_match('/^\s+[0-9]+/', $line)) $line = $last . ' ' . $line;
  		if (preg_match('/(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)/', $line, $m) && is_numeric($m[2]) && is_numeric($m[4]) && is_numeric($m[4])) {
  			$stats[$m[6]] = array('filesystem' => $m[1], 'free' => $m[4], 'mount' => $m[6], 'size' => $m[3] + $m[4], 'used' => $m[3], 'used_perc' => $m[5]);
  		}
  		else if (substr($line, 0, 1) == '/') $last = $line;
  		else $last = NULL;
  	}
		$dmount = '/';
		foreach(array_keys($stats) as $mountpoint) {
			if (strpos($dir, $mountpoint) === 0 && strlen($mountpoint) > strlen($dmount)) $dmount = $mountpoint;
		}
		$stats = $stats[$dmount];
  	$free = $stats ? $stats['free'] : NULL;
  }
  return $free;
}

/**
 * returns the hostname from a string containing either a hostname or a URL
 * @param string $url the url to return the hostname from
 * @return string
 */
function get_hostname($url) {
  $pieces = explode('/', preg_match('/^https?:\/\/([^:^\/]+)[:\/]/', $url, $m) || preg_match('/^https?:\/\/([^:^\/]+)$/', $url, $m) ? $m[1] : $url);
  return $pieces[0];
}

/**
 * returns a hash with the following keys representing Java version
 * information (using java -verison):
 *   version => the version identifier
 *   vendor => the Java software vendor: OpenJDK, Oracle or IBM
 * @return array
 */
function get_java_version() {
  // get java version
  $jversion = NULL;
  $jvendor = NULL;
  foreach(explode("\n", shell_exec('java -version 2>&1')) as $line) {
    if (preg_match('/"([0-9\._]+)"/', trim($line), $m)) $jversion = $m[1];
    else if (!$jvendor && preg_match('/openjdk/i', trim($line))) $jvendor = 'OpenJDK';
    else if (!$jvendor && preg_match('/hotspot/i', trim($line))) $jvendor = 'Oracle';
    else if (!$jvendor && preg_match('/ibm/i', trim($line))) $jvendor = 'IBM';
  }
  return $jversion && $jvendor ? array('version' => $jversion, 'vendor' => $jvendor) : NULL;
}

/**
 * returns the arithmetic mean value from an array of points
 * @param array $points an array of numeric data points
 * @param int $round desired rounding precision, default is 4
 * @access public
 * @return float
 */
function get_mean($points, $round=4) {
	$stat = array_sum($points)/count($points);
	if ($round) $stat = round($stat, $round);
	return $stat;
}

/**
 * returns the median value from an array of points
 * @param array $points an array of numeric data points
 * @param int $round desired rounding precision, default is 4
 * @access public
 * @return float
 */
function get_median($points, $round=4) {
	sort($points);
	$nmedians = count($points);
	$nmedians2 = floor($nmedians/2);
  $stat = $nmedians % 2 ? $points[$nmedians2] : ($points[$nmedians2 - 1] + $points[$nmedians2])/2;
	if ($round) $stat = round($stat, $round);
	return $stat;
}

/**
 * returns the mime type for the $file specified. uses /etc/mime.types
 * @param string $file the file to return the mime type for
 * @return string
 */
function get_mime_type($file) {
  $type = 'application/octet-stream';
  $pieces = explode('.', $file);
  $extension = strtolower($pieces[count($pieces) - 1]);
  foreach(file('/etc/mime.types') as $line) {
    if (preg_match('/^([a-z][\S]+)\s+([a-z].*)$/', $line, $m)) {
      $types = explode(' ', $m[2]);
      if (in_array($extension, $types)) {
        $type = $m[1];
        break;
      }
    }
  }
  return $type;
}

/**
 * returns a percentile from $values
 * @param array $values array of numeric values get $percentile from
 * @param string $percentile the percentile to return (1-100) - for example, if
 * $percentile == 90, the top 90th percentile value is returned
 * @param boolean $lowerIsBetter TRUE if a lower value is better
 * @return float
 */
function get_percentile($values, $percentile=50, $lowerIsBetter=FALSE) {
  $val = NULL;
	if (is_array($values) && $percentile >= 1 && $percentile < 100) {
		$lowerIsBetter ? rsort($values) : sort($values);
    $idx = round(count($values)*($percentile*.01)) - 1;
    if ($idx < 0) $idx = 0;
    else if ($idx >= count($values)) $idx = count($values) - 1;
    $val = $values[$idx];
	}
	return $val;
}

/**
 * returns all of the parameters prefixed with $prefix. To do so - both command
 * line arguments and values in env (prefixed with bm_param_$prefix) are
 * searched
 * @param string $prefix the prefix to search for
 * @return array
 */
function get_prefixed_params($prefix) {
  $params = array();
	foreach(string_to_hash(shell_exec('env')) as $key => $val) {
		if (preg_match('/^bm_param_' . $prefix . '(.*)$/', $key, $m)) $params[$m[1]] = strlen(trim($val)) ? trim($val) : TRUE;
	}
  foreach($_SERVER['argv'] as $arg) {
    if (preg_match('/^\-\-' . $prefix . '(.*)$/', $arg, $m)) {
      $pieces = explode('=', $m[1]);
      $params[trim(strtolower($pieces[0]))] = isset($pieces[1]) ? trim($pieces[1]) : TRUE;
    }
  }
  return $params;
}

/**
 * returns information about the cloud service associated with $hostname if
 * known, NULL otherwise. the return value is a hash with the following keys:
 *   providerId
 *   serviceId
 *   region (optional)
 *   city (optional)
 *   state (optional)
 *   country (optional)
 * @param string $hostname hostname to lookup
 * @param boolean $verbose verbose print option
 * @return array
 */
function get_service_info($hostname, $verbose=FALSE) {
  $info = NULL;
  $cache = sprintf('/tmp/.ch_service_lookup_' . $hostname);
  if (!file_exists($cache) || !($response = json_decode(file_get_contents($cache), TRUE))) {
    $cmd = sprintf('curl "https://cloudharmony.com/api/identify/%s" > %s 2>/dev/null', $hostname, $cache);
    print_msg(sprintf('Attempting to lookup service information for hostname %s', $hostname), $verbose, __FILE__, __LINE__);
    exec($cmd);
  }
  else print_msg(sprintf('Got service information for hostname %s from cache file %s', $hostname, $cache), $verbose, __FILE__, __LINE__);

  if ($response = json_decode(file_get_contents($cache), TRUE)) {
    print_msg(sprintf('Successfully retrieved service information for hostname %s: providerId %s; serviceId %s; serviceType %s; region %s; city %s; state %s; country %s', $hostname, $response['providerId'], $response['serviceId'], $response['serviceType'], isset($response['region']) ? $response['region'] : '', isset($response['city']) ? $response['city'] : '', isset($response['state']) ? $response['state'] : '', isset($response['country']) ? $response['country'] : ''), $verbose, __FILE__, __LINE__);
    $info = $response;
  }
  else {
    print_msg(sprintf('Failed to lookup service information for hostname %s', $hostname), $verbose, __FILE__, __LINE__, TRUE);
    if (file_exists($cache)) unlink($cache);
  }
  return $info;
}

/**
 * returns valid cloud service type identifiers
 */
function get_service_types() {
  return array('cdn', 'dns', 'compute', 'storage', 'paas', 'dbaas');
}

/**
 * computes a standard deviation for the $points specified
 * @param array $points an array of numeric data points
 * @param int $type the type of standard deviation metric to return. One of
 * the following numeric identifiers:
 *   1 = sample standard deviation (DEFAULT)
 *   2 = population standard deviation
 *   3 = relative sample standard deviation
 *   4 = relative population standard deviation
 *   5 = sample variance
 *   6 = population variance
 * @param int $round desired rounding precision, default is 6
 * @access public
 * @return float
 */
function get_std_dev($points, $type=1, $round=6) {
  if (count($points) == 1) return 0;

  $mean = array_sum($points)/count($points);
  $variance = 0.0;
  foreach ($points as $i) $variance += pow($i - $mean, 2);
  $variance /= ($type == 1 || $type == 3 || $type == 5 ? count($points) - 1 : count($points));
	if ($type == 5 || $type == 6) return $variance;
  $stddev = (float) sqrt($variance);
	if ($type > 2) $stddev = 100 * ($stddev/$mean);
	if ($round) $stddev = round($stddev, $round);
	return $stddev;
}

/**
 * returns the summation of squares of values in $points
 * @param array $points an array of numeric data points
 * @param int $round desired rounding precision, default is 4
 * @access public
 * @return float
 */
function get_sum_squares($points, $round=4) {
  $sum = 0;
  foreach($points as $point) $sum += ($point*$point);
  return round($sum, $round);
}

/**
 * returns system information. A hash containing the following keys:
 *   cpu        => CPU model information
 *   cpu_cache  => CPU cache size
 *   cpu_cores  => number of CPU cores
 *   cpu_speed  => CPU clock speed (MHz)
 *   hostname   => system hostname
 *   memory_gb  => system memory in gigabytes (rounded to whole number)
 *   memory_mb  => system memory in megabytes (rounded to whole number)
 *   os_info    => operating system name and version
 * @return array
 */
function get_sys_info() {
  global $sys_info;
  if (!is_array($sys_info)) {
	$sys_info = array();
	if  (preg_match('/[Bb][Ss][Dd]/', shell_exec('uname -s'))) {
		$sysinfo['cpu'] = shell_exec("sysctl -n hw.model");
		$sysinfo['cpu_cache'] = 0;
		$sysinfo['cpu_cores'] = shell_exec("sysctl -n hw.ncpu");
		$sysinfo['cpu_speed'] = shell_exec("sysctl -n dev.cpu.0.freq");
		$sys_info['hostname'] = trim(shell_exec('hostname'));
		$memkb = shell_exec("sysctl -n hw.physmem");
		$sys_info['memory_mb'] = round($memkb/1024/1024);
		$sys_info['memory_gb'] = round($memkb/1024/1024/1024);
		$sys_info['os_info'] = shell_exec("uname -vUKi");
        }
	else {

			if ($lines = explode("\n", file_get_contents('/proc/cpuinfo'))) {
				foreach($lines as $line) {
					if (preg_match('/(.*):(.*)/', trim($line), $m)) {
						$key = trim($m[1]);
						$val = preg_replace('/\s+/', ' ', trim($m[2]));
						foreach(array('cores' => 'processor',
													'name' => 'model name',
													'speed' => 'mhz',
													'cache' => 'cache size') as $k => $match) {
							if ($k == 'name') $val = str_replace('@ ', '', str_replace('CPU ', '', str_replace('Quad-Core ', '', str_replace('Processor ', '', str_replace('(tm)', '', str_replace('(R)', '', $val))))));
							if (preg_match("/$match/i", $key)) $sys_info[sprintf('cpu%s', $k != 'name' ? '_' . $k : '')] = $k == 'cores' ? $val + 1 : $val;
						}
					}
				}
			}
			$sys_info['hostname'] = trim(shell_exec('hostname'));
			if (preg_match('/Mem:\s+([0-9]+)\s+([0-9]+)\s+([0-9]+)/', shell_exec('free -m'), $m)) {
				$mb = $m[1]*1;
				$sys_info['memory_mb'] = round($m[1]);
				$sys_info['memory_gb'] = round($m[1]/1024);
			}
			$issue = file_get_contents('/etc/issue');
			foreach(explode("\n", $issue) as $line) {
				if (!isset($attr) && trim($line)) {
				  $attr = trim($line);
				  break;
			  }
			}
			// remove superfluous information
			if ($attr) {
				$attr = str_replace('(\l).', '', $attr);
				$attr = str_replace('\n', '', $attr);
				$attr = str_replace('\l', '', $attr);
				$attr = str_replace('\r', '', $attr);
				$attr = str_replace('Welcome to', '', $attr);
				$sys_info['os_info'] = trim($attr);
			}
	}
  }
  return $sys_info;
}

/**
 * returns TRUE if the Linux kernel is 64 bit, FALSE otherwise
 * @return boolean
 */
function is_64bit() {
  global $is_64bit;
  if (!isset($is_64bit)) {
    $is_64bit = preg_match('/64/', shell_exec('uname -i')) || preg_match('/64/', shell_exec('uname -m')) || preg_match('/64/', shell_exec('uname -p'));
  }
  return $is_64bit;
}

/**
 * merges config options into $options
 * @param array $options the options to merge into
 * @param string $config the config file to merge with
 * @return void
 */
function merge_options_with_config(&$options, $config) {
  foreach(explode("\n", shell_exec('cat ' . $config . ' 2>/dev/null')) as $line) {
    if (substr(trim($line), 0, 1) == '#') continue;
    if (preg_match('/([A-Za-z_]+)\s*=?\s*(.*)$/', $line, $m) && !isset($options[$key = strtolower($m[1])])) {
      print_msg(sprintf('Added option %s=%s from config %s', $key, preg_match('/pswd/', $key) || preg_match('/key/', $key) ? '***' : $m[2], $config), isset($options['verbose']), __FILE__, __LINE__);
      $options[$key] = $m[2] ? trim($m[2]) : TRUE;
    }
  }
}

/**
 * this method creates an arguments hash containing the command line args as
 * a where the key is the long argument name and the value is the value for
 * that argument. boolean arguments will automatically be converted to PHP bools
 * @param array $opts the options definition - a hash of short/long argument
 * names. if the key is numeric, it will be assumed to not have a short argument
 * option. if the argument name has a colon (:) at the end, it will be assumed to
 * be an argument that requires a value - otherwise it will be assumed to be a
 * flag argument
 * @param array $arrayArgs if specified, options with these names will be
 * forced to arrays even if they only contain a single argument value and
 * arguments that repeat that area not included in this argument will be set
 * to the first specified value (others will be discarded)
 * @param string $paramPrefix an optional prefix to apply when evaluating
 * bm_param_ environment variables
 * @return array
 */
function parse_args($opts, $arrayArgs=NULL, $paramPrefix='') {
  global $argv;
  $key = NULL;
  $val = NULL;
  $options = array();
  foreach($argv as $arg) {
   if (preg_match('/^\-\-?([^=]+)\=?(.*)$/', $arg, $m)) {
     if ($key && isset($options[$key])) {
       if (!is_array($options[$key])) $options[$key] = array($options[$key]);
       $options[$key][] = $val;
     }
     else if ($key) $options[$key] = $val;
     $key = $m[1];
     $val = isset($m[2]) ? $m[2] : '';
   }
   else if ($key) $val .= ' ' . $arg;
  }
  if ($key && isset($options[$key])) {
   if (!is_array($options[$key])) $options[$key] = array($options[$key]);
   $options[$key][] = $val;
  }
  else if ($key) $options[$key] = $val;

  foreach($opts as $short => $long) {
   $key = str_replace(':', '', $long);
   if (preg_match('/[a-z]:?$/', $short) && isset($options[$short = substr($short, 0, 1)])) {
     if (isset($options[$key])) {
       if (!is_array($options[$key])) $options[$key] = array($options[$key]);
       $options[$key][] = $options[$short];
     }
     else $options[$key] = $options[$short];
     unset($options[$short]);
   }
   // check for environment variable
   if (getenv("bm_param_${paramPrefix}${key}") !== FALSE && !isset($options[$key])) $options[$key] = getenv("bm_param_${paramPrefix}${key}");
   if (!isset($options[$key]) && preg_match('/^meta_/', $key) && getenv('bm_' . str_replace('meta_', '', $key)) !== FALSE) $options[$key] = getenv('bm_' . str_replace('meta_', '', $key));
   // convert booleans
   if (isset($options[$key]) && !strpos($long, ':')) $options[$key] = $options[$key] === '0' ? FALSE : TRUE;
   // set array parameters
   if (isset($arrayArgs) && is_array($arrayArgs)) {
     if (isset($options[$key]) && in_array($key, $arrayArgs) && !is_array($options[$key])) {
       $pieces = explode(preg_match('/\|/', $options[$key]) || preg_match('/,\s*[A-Z]{2}$/', $options[$key]) ? '|' : ',', $options[$key]);
       $options[$key] = array();
       foreach($pieces as $v) $options[$key][] = trim($v);
     }
     else if (isset($options[$key]) && !in_array($key, $arrayArgs) && is_array($options[$key])) $options[$key] = $options[$key][0];
   }
   // remove empty values
   if (!isset($options[$key])) unset($options[$key]);
  }

  // remove quotes
  foreach(array_keys($options) as $i) {
   if (is_array($options[$i])) {
     foreach(array_keys($options[$i]) as $n) $options[$i][$n] = strip_quotes($options[$i][$n]);
   }
   else $options[$i] = strip_quotes($options[$i]);
  }

  return $options;
}

/**
 * Prints a message to stdout
 * @param string $msg the message to print
 * @param boolean $verbose whether or not verbose output mode is enabled. If
 * not enabled, message will not be printed (unless $err==TRUE)
 * @param string $file optional name of the file generating the message
 * @param int $line optional line number in the file generating the message
 * @param boolean $err if this message an error?
 * @return void
 */
function print_msg($msg, $verbose=FALSE, $file=NULL, $line=NULL, $err=FALSE) {
  if ($verbose || $err) {
  	printf("%-24s %-8s %-24s %s\n",
  	       date('m/d/Y H:i:s T'),
  	       run_time() . 's',
  				 str_replace('.php', '', basename($file ? $file : __FILE__)) . ':' . ($line ? $line : __LINE__),
  				 ($err ? 'ERROR: ' : '') . $msg);
  }
}

/**
 * returns the current execution time
 * @return float
 */
$run_time_start = microtime(TRUE);
function run_time() {
	global $run_time_start;
	return round(microtime(TRUE) - $run_time_start);
}

/**
 * returns a numeric value representing megabytes expresses in $expr. The
 * following value suffixes are supported (not case-sensitive): B, KB, MB, GB,
 * TB. If not suffix, bytes will be assumed
 * @param string $expr the expression to return the size for
 * @return float
 */
function size_from_string($expr) {
  $mb = NULL;
  if (preg_match('/^([0-9\.]+)\s*([kmgtb]+)$/i', trim($expr), $m)) {
    switch(strtoupper(strtolower($m[2]))) {
      case 'TB':
      case 'T':
        $mb = ($m[1]*1024)*1024;
        break;
      case 'GB':
      case 'G':
        $mb = $m[1]*1024;
        break;
      case 'MB':
      case 'M':
        $mb = $m[1]*1;
        break;
      case 'KB':
      case 'K':
        $mb = $m[1]/1024;
        break;
      default:
        $mb = ($m[1]/1024)/1024;
        break;
    }
  }
  else if (is_numeric($expr)) $mb = ($expr/1024)/1024;
  return $mb;
}

/**
 * this function parses key/value pairs in the string $blob. the return value
 * is a hash the corresponding key/value pairs. empty lines, or lines
 * beginning with ; or # are ignored. for lines without an = character, the
 * entire line will be the key and the value will be TRUE
 * @param string $blob the string to parse
 * @param boolean $ini if true, the parsing will be segmented where sections
 * that begin with a bracket enclosed string define the segments. for example,
 * if the function encountered a line [globals], all of the key value pairs
 * following that line will be placed into a 'global' sub-hash in the return
 * value (until the next section is encountered)
 * @param array $excludeKeys array of regular expressions representing keys
 * that should not be included in the return hash
 * @param array $includeKeys array of regular expressions representing keys
 * that should be included in the return hash
 */
function string_to_hash($blob, $ini=FALSE, $excludeKeys=NULL, $includeKeys=NULL) {
	$hash = array();
	$iniSection = NULL;
	foreach(explode("\n", $blob) as $line) {
		$line = trim($line);
		$firstChar = $line ? substr($line, 0, 1) : NULL;
		if ($firstChar && $firstChar != ';' && $firstChar != '#') {
			// ini section
			if ($ini && preg_match('/^\[(.*)\]$/', $line, $m)) $iniSection = $m[1];
			else {
				if ($split = strpos($line, '=')) {
					$key = substr($line, 0, $split);
					$value = substr($line, $split + 1);
				}
				else {
					$key = $line;
					$value = TRUE;
				}
				if (is_array($excludeKeys)) {
					foreach($excludeKeys as $regex) if (preg_match($regex, $key)) $key = NULL;
				}
				if (is_array($includeKeys)) {
					$found = FALSE;
					foreach($includeKeys as $regex) if (preg_match($regex, $key)) $found = TRUE;
					if (!$found) $key = NULL;
				}
				if ($key) {
					if ($ini && $iniSection) {
						if (!isset($hash[$iniSection])) $hash[$iniSection] = array();
						$hash[$iniSection][$key] = $value;
					}
					else $hash[$key] = $value;
				}
			}
		}
	}
	return $hash;
}

/**
 * Trims and removes leading and trailing quotes from a string
 * (e.g. "some string" => some string; 'some string' => some string)
 * @param string $string the string to remove quotes from
 * @return string
 */
function strip_quotes($string) {
  $string = trim($string);
  if (preg_match('/^"(.*)"$/', $string, $m)) $string = $m[1];
  else if (preg_match("/^'(.*)'\$/", $string, $m)) $string = $m[1];
  return $string;
}

/**
 * removes a percentage of values from the bottom and top of $points
 * @param array $points an array of numeric data points
 * @param int $bottom percentage of values in $points to remove from the bottom
 * @param int $top percentage of values in $points to remove from the top
 * @access public
 * @return array
 */
function trim_points($points, $bottom=NULL, $top=NULL) {
  if (($bottom > 0 && $bottom < 40) || ($top > 0 && $top < 40)) {
    $numMetrics = count($points);
    if (($bottom > 0 && $bottom < 40) && ($discard = round($numMetrics*($bottom*0.01)))) $points = array_slice($points, $discard);
    if (($top > 0 && $top < 40) && ($discard = round($numMetrics*($top*0.01)))) $points = array_slice($points, 0, $discard*-1);
  }
  return $points;
}

/**
 * validate that the cli commands in the $dependencies array are present.
 * returns an array containing those commands that are not valid or an empty
 * array if they are all valid
 * @param array $dependencies the cli commands to validate. this is a hash
 * indexed by command where the value is the package name
 * @return array
 */
function validate_dependencies($dependencies) {
  if (is_array($dependencies)) {
    foreach($dependencies as $c => $dependency) {
      $cmd = sprintf('which %s; echo $?', $c);
      $ecode = trim(exec($cmd));
      if ($ecode == 0) unset($dependencies[$c]);
    }
  }
  return $dependencies;
}

/**
 * validate script options. returns an array populated with error messages
 * indexed by the argument name. If options are valid, the array returned
 * will be empty
 * @param array $options the option values to validate
 * @param array $validate validation hash - indexed by argument name where
 * the value is a hash of validation constraints. The following constraints
 * are supported:
 *   color:    argument is a hex color
 *   min:      argument numeric and >= this value
 *   max:      argument numeric and <= this value
 *   option:   argument must be found in this value (array)
 *   regex:    argument must match the provided regular expression
 *   required: argument is required
 *   url:      argument is a URL
 *   write:    argument is in the file system path and writeable
 *   writedir: same as write but parent directory should be writable
 * @return array
 */
function validate_options($options, $validate) {
  $invalid = array();
  foreach($validate as $arg => $constraints) {
    foreach($constraints as $constraint => $cval) {
      $err = NULL;
      $vals = isset($options[$arg]) ? $options[$arg] : NULL;
      if (!is_array($vals)) $vals = array($vals);
      foreach($vals as $val) {
        // printf("Validate --%s=%s using constraint %s\n", $arg, $val, $constraint);
        switch($constraint) {
          case 'color':
            if ($val && !preg_match('/^#[a-zA-Z0-9]{6}$/', $val)) $err = sprintf('%s is not a valid hex color (e.g. #ffffff)', $val);
            break;
          case 'min':
          case 'max':
            if ($val && !is_numeric($val)) $err = sprintf('%s is not numeric', $val);
            else if (is_numeric($val) && $constraint == 'min' && $val < $cval) $err = sprintf('%d is less then minimum permitted value %d', $val, $cval);
            else if (is_numeric($val) && $constraint == 'max' && $val > $cval) $err = sprintf('%d is greater then maximum permitted value %d', $val, $cval);
            break;
          case 'option':
            if ($val && !in_array($val, $cval)) $err = sprintf('%s must be one of the following: %s', $val, implode(', ', $cval));
            break;
          case 'regex':
            if ($val && !preg_match($cval, $val)) $err = sprintf('argument %s must match regular expression %s', $arg, $cval);
            break;
          case 'required':
            if ($val === NULL) $err = sprintf('argument %s is required', $arg);
            break;
          case 'write':
            if ($val && !file_exists($val)) $err = sprintf('%s is not a valid path', $val);
            else if ($val && !is_writable($val)) $err = sprintf('%s is not writable', $val);
            break;
          case 'writedir':
            $val = is_dir($val) ? $val : dirname($val);
            if ($val && !is_dir($val)) $err = sprintf('%s is not a valid directory', $val);
            else if ($val && !is_writable($val)) $err = sprintf('%s is not writable', $val);
            break;
          case 'url':
            if ($val && !preg_match('/\b(?:(?:https?|ftp):\/\/|www\.)[-a-z0-9+&@#\/%?=~_|!:,.;]*[-a-z0-9+&@#\/%=~_|]/i', $val)) $err = sprintf('%s is not a valid URL', $val);
            break;
        }
        if ($err) {
          $invalid[$arg] = $err;
          break;
        }
      }
    }
  }
  return $invalid;
}
?>


text:
Инсталяция на FreeBSD 10[¶](#freebsd-10-installation "Ссылка на этот заголовок")

================================================================================

Инсталяция из пакетов[¶](#install-from-packages "Ссылка на этот заголовок")

---------------------------------------------------------------------------

    $ pkg update

    $ pkg upgrade

    $ pkg install apache24 mod_php56 kanboard

Включите Apache в `/etc/rc.conf`{.docutils .literal}:

    $ echo apache24_enable="YES" >> /etc/rc.conf

Установите PHP для Apache:

    $ echo "AddType application/x-httpd-php .php" >> /usr/local/etc/apache24/Includes/php.conf

    $ echo "DirectoryIndex index.php index.html" >> /usr/local/etc/apache24/Includes/php.conf

Затем, запустите Apache:

    $ service apache24 start

Создайте символическую ссылку на каталог Kanboard в корне Apache:

    cd /usr/local/www/apache24/data

    ln -s /usr/local/www/kanboard

Готово. Можете перейти в <http:/>/вашвебсервер/kanboard и начинать работать!

*Примечание*: Если вы хотите добавить дополнительные возможности, типа интеграции LDAP, то нужно установить соответствующий PHP модуль. Также, вам необходимо настроить соответсвующие права на каталог data.

Установка из портов[¶](#installing-from-ports "Ссылка на этот заголовок")

-------------------------------------------------------------------------

Нужно установить 3 основных элемента:

-   Apache

-   mod\_php for Apache

-   Kanboard

Загрузите и распакуйте порты:

    $ portsnap fetch

    $ portsnap extract

или обновите имеющиеся:

    $ portsnap fetch

    $ portsnap update

Дополнительную информацию о дереве портов вы можете посмотреть на [FreeBSD Handbook](https://www.freebsd.org/doc/handbook/ports-using.html).

Установка Apache:

    $ cd /usr/ports/www/apache24

    $ make install clean

Включите Apache в `/etc/rc.conf`{.docutils .literal}:

    $ echo apache24_enable="YES" >> /etc/rc.conf

Установите mod\_php для Apache:

    $ cd /usr/ports/www/mod_php5

    $ make install clean

Установите Kanboard из портов:

    $ cd /usr/ports/www/kanboard

    $ make install clean

Установите PHP для Apache:

    $ echo "AddType application/x-httpd-php .php" >> /usr/local/etc/apache24/Includes/php.conf

    $ echo "DirectoryIndex index.php index.html" >> /usr/local/etc/apache24/Includes/php.conf

Затем, запустите Apache:

    $ service apache24 start

Готово. Можете перейти в <http:/>/вашвебсервер/kanboard и начинать работать!

*Примечание*: Если вы хотите использовать дополнительные возможности, типа интеграции LDAP, то нужно установить PHP модуль из `lang/php5-extensions`{.docutils .literal}.

Установка из архива[¶](#manual-installation "Ссылка на этот заголовок")

-----------------------------------------------------------------------

Начина с версии 1.0.16 Kanboard имеется в портах FreeBSD, поэтому нет необходимости устанавливать вручную.

Обратите внимание[¶](#please-note "Ссылка на этот заголовок")

-------------------------------------------------------------

-   Порт расположен на хостинге [bitbucket](https://bitbucket.org/if0/freebsd-kanboard/). Делайте комментарии, ответвления и предлагайте обновления!

-   Некоторые возможности Канборд требуют [запуск ежедневных фоновых задач](cronjob.markdown).

### [Оглавление](index.markdown)

-   [Инсталяция на FreeBSD 10](#)

    -   [Инсталяция из пакетов](#install-from-packages)

    -   [Установка из портов](#installing-from-ports)

    -   [Установка из архива](#manual-installation)

    -   [Обратите внимание](#please-note)

[Русская документация Kanboard](http://kanboard.ru/doc/)


text:
package io.jchat.android.controller;

import android.view.View;
import android.view.View.OnClickListener;
import java.util.ArrayList;
import java.util.List;
import io.jchat.android.activity.ContactsFragment;
import io.jchat.android.view.ContactsView;

public class ContactsController implements OnClickListener {

	private ContactsView mContactsView;
	private ContactsFragment mContactsActivity;

	public ContactsController(ContactsView mContactsView, ContactsFragment context) {
		this.mContactsView = mContactsView;
		this.mContactsActivity = context;
		initContacts();
	}

    public void initContacts() {
        //初始化用户名列表
        List<String> userNameList = new ArrayList<String>();
    }

	@Override
	public void onClick(View v) {
		switch(v.getId()){

		}

	}

}


text:
//! Water content for liquid + water vapor.
/*!

.. math::
  \Theta = (n_l s_l + n_i s_i) \phi V

Specified with evaluator type: `"liquid+ice water content`"

.. _field-evaluator-type-liquid-ice-water-content-spec:
.. admonition:: field-evaluator-type-liquid-ice-water-content-spec

   DEPENDENCIES:

   - `"porosity`"
   - `"molar density liquid`"
   - `"molar density ice`"
   - `"saturation liquid`"
   - `"saturation ice`"
   - `"cell volume`"

*/

#ifndef AMANZI_FLOW_LIQUID_ICE_WATER_CONTENT_EVALUATOR_HH_
#define AMANZI_FLOW_LIQUID_ICE_WATER_CONTENT_EVALUATOR_HH_

#include "Factory.hh"
#include "EvaluatorSecondaryMonotype.hh"

namespace Amanzi {
namespace Flow {
namespace Relations {

class LiquidIceWaterContentModel;

class LiquidIceWaterContentEvaluator : public EvaluatorSecondaryMonotypeCV {

 public:
  explicit
  LiquidIceWaterContentEvaluator(Teuchos::ParameterList& plist);
  LiquidIceWaterContentEvaluator(const LiquidIceWaterContentEvaluator& other) = default;
  virtual Teuchos::RCP<Evaluator> Clone() const override;

  Teuchos::RCP<LiquidIceWaterContentModel> get_model() { return model_; }

 protected:
  // Required methods from EvaluatorSecondaryMonotypeCV
  virtual void Evaluate_(const State& S,
          const std::vector<CompositeVector*>& result) override;
  virtual void EvaluatePartialDerivative_(const State& S,
          const Key& wrt_key, const Tag& wrt_tag,
          const std::vector<CompositeVector*>& result) override;

  void InitializeFromPlist_();

 protected:
  Key phi_key_;
  Key sl_key_;
  Key nl_key_;
  Key si_key_;
  Key ni_key_;
  Key cv_key_;

  Teuchos::RCP<LiquidIceWaterContentModel> model_;

 private:
  static Utils::RegisteredFactory<Evaluator,LiquidIceWaterContentEvaluator> reg_;

};

} //namespace
} //namespace
} //namespace

#endif


text:
<?xml version="1.0"?>
<project
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
  xmlns="http://maven.apache.org/POM/4.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>com.huanyu</groupId>
    <artifactId>java-learing</artifactId>
    <version>0.0.1-SNAPSHOT</version>
  </parent>
  <artifactId>huanyu-doc</artifactId>
  <name>huanyu-doc</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencies>

    <dependency>
      <groupId>com.huanyu</groupId>
      <artifactId>huanyu-common</artifactId>
    </dependency>

    <!--spring-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-beans</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
    </dependency>

    <!--apache-->
    <dependency>
      <groupId>org.apache.commons</groupId>
      <artifactId>commons-lang3</artifactId>
    </dependency>

    <!-- xml -->
    <dependency>
      <groupId>com.thoughtworks.xstream</groupId>
      <artifactId>xstream</artifactId>
    </dependency>

    <!-- guava -->
    <dependency>
      <groupId>com.google.guava</groupId>
      <artifactId>guava</artifactId>
    </dependency>

    <!--google-zxing-->
    <dependency>
      <groupId>com.google.zxing</groupId>
      <artifactId>core</artifactId>
    </dependency>
    <dependency>
      <groupId>com.google.zxing</groupId>
      <artifactId>javase</artifactId>
    </dependency>

    <!--alipay-sdk-->
    <dependency>
      <groupId>com.alipay.api</groupId>
      <artifactId>alipay-sdk</artifactId>
    </dependency>

    <!--aliyun-oss-->
    <dependency>
      <groupId>com.aliyun.oss</groupId>
      <artifactId>aliyun-sdk-oss</artifactId>
    </dependency>

    <!-- JSON -->
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>fastjson</artifactId>
    </dependency>

    <!--cglib-->
    <dependency>
      <groupId>cglib</groupId>
      <artifactId>cglib</artifactId>
    </dependency>

    <!--asm-->
    <dependency>
      <groupId>org.ow2.asm</groupId>
      <artifactId>asm-all</artifactId>
    </dependency>

    <!--log-->
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-log4j12</artifactId>
    </dependency>

    <!--test-->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
    </dependency>
    <dependency>
      <groupId>com.huanyu</groupId>
      <artifactId>huanyu-common</artifactId>
      <version>0.0.1-SNAPSHOT</version>
      <scope>test</scope>
    </dependency>

  </dependencies>
</project>


text:
TUIOSwift is a Swift Implementation of the [TUIO library](http://tuio.org/?software) by Martin Kalternbrunner. It is a 1:1 port of the original [TUIO 1.1 Java Library](http://github.com/mkalten/TUIO11_JAVA)

It also uses parts of the TUIO Simulator, to provide client-side and server-side code.

Currently the library is only partially finished and only of limited funcitonality.


text:
package edu.sibinfo.spring.web.module01;

import java.time.LocalDateTime;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
public class GreetingController {
    @RequestMapping("/greeting")
    public String greeting(@RequestParam(value="name", required=false, defaultValue="World") String name, Model model) {
    	model.addAttribute("timeStamp", LocalDateTime.now());
    	model.addAttribute("name", name);
        return "greeting";
    }
}


text:
class Contributor < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable, :timeoutable,
         :recoverable, :rememberable, :trackable, :validatable
	has_many :posts
	validates :name, presence: true
	validates_format_of :email, :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i

	def timeout_in
    2.hours
  end
end


text:
package org.gradoop.flink.model.impl.operators.sampling.statistics;

/**
 * Collected constants for sampling evaluation
 */
public class SamplingEvaluationConstants {

  /**
   * Key for density property generated by {@link GraphDensity}
   */
  public static final String PROPERTY_KEY_DENSITY = "density";

  /**
   * Filename for the saved density value of the graph
   */
  public static final String FILE_DENSITY = "graph_density";

  /**
   * Key for the summed up degrees property generated by {@link AverageDegree},
   * {@link AverageIncomingDegree} and {@link AverageOutgoingDegree}
   */
  public static final String PROPERTY_KEY_SUM_DEGREES = "sum_degrees";

  /**
   * Key for average degree property generated by {@link AverageDegree}
   */
  public static final String PROPERTY_KEY_AVERAGE_DEGREE = "average_degree";

  /**
   * Filename for the saved average degree value of the graph
   */
  public static final String FILE_AVERAGE_DEGREE = "average_degree";

  /**
   * Key for average incoming degree property generated by {@link AverageIncomingDegree}
   */
  public static final String PROPERTY_KEY_AVERAGE_INCOMING_DEGREE = "average_incoming_degree";

  /**
   * Filename for the saved average incoming degree value of the graph
   */
  public static final String FILE_AVERAGE_INCOMING_DEGREE = "average_incoming_degree";

  /**
   * Key for average outgoing degree property generated by {@link AverageOutgoingDegree}
   */
  public static final String PROPERTY_KEY_AVERAGE_OUTGOING_DEGREE = "average_outgoing_degree";

  /**
   * Filename for the saved average outgoing degree value of the graph
   */
  public static final String FILE_AVERAGE_OUTGOING_DEGREE = "average_outgoing_degree";

  /**
   * Key for weakly connected component id property generated by
   * {@link ConnectedComponentsDistribution}
   */
  public static final String PROPERTY_KEY_WCC_ID = "wcc_component_id";

  /**
   * Filename for the saved connected components distribution of the graph
   */
  public static final String FILE_CONNECTED_COMPONENTS_DIST = "connected_components_distribution";

  /**
   * Filename for the saved average clustering coefficient of the graph
   */
  public static final String FILE_CLUSTERING_COEFFICIENT_AVERAGE = "clustering_coefficient_average";

  /**
   * Filename for the saved global clustering coefficient of the graph
   */
  public static final String FILE_CLUSTERING_COEFFICIENT_GLOBAL = "clustering_coefficient_global";

  /**
   * Filename for the saved triangle count of the graph
   */
  public static final String FILE_TRIANGLE_COUNT = "triangle_count";

  /**
   * private Constructor
   */
  private SamplingEvaluationConstants() { }
}


text:
module Aws
  module SSM
    module Console
      class Command
        attr_reader :start_timeout, :execution_timeout, :instance_ids

        DEFAULT_START_TIMEOUT = 30
        DEFAULT_EXECUTION_TIMEOUT = 3600

        def initialize(instance_ids:, start_timeout: DEFAULT_START_TIMEOUT, execution_timeout: DEFAULT_EXECUTION_TIMEOUT)
          @instance_ids = instance_ids
          @start_timeout = start_timeout
          @execution_timeout = execution_timeout
        end

        def invoke(command)
          response = Aws::SSM::Console.client.send_command(
            document_name: 'AWS-RunShellScript',
            instance_ids: instance_ids,
            timeout_seconds: start_timeout,
            parameters: {
              commands: [command],
              executionTimeout: [execution_timeout.to_s],
            }
          )
          Aws::SSM::Console::Printer.new(response).print
        rescue Aws::SSM::Errors::ServiceError
          # TODO: error handling
          raise
        end
      end
    end
  end
end


text:
package org.jesterj.ingest.scanners;

import net.jini.space.JavaSpace;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.jesterj.ingest.config.Transient;
import org.jesterj.ingest.model.ConfiguredBuildable;
import org.jesterj.ingest.model.Document;
import org.jesterj.ingest.model.Router;
import org.jesterj.ingest.model.impl.DocumentImpl;
import org.jesterj.ingest.model.impl.ScannerImpl;

import java.io.File;
import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.MemoryUsage;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * Scanner for local filesystems. This scanner periodically does a full walk of the filesystem. No persistent
 * record of files detected during walking is kept, and all files will be visited on each scan,
 * so it is highly recommended to use this with the remembering option turned on unless a regular full re-index is
 * desired. If walking the filesystem takes longer than the scan interval, the time to walk will determine
 * the index latency instead. This scanner will not start a new scan until the current one completes.
 * Files to be processed must fit in JVM memory.
 */
@SuppressWarnings("SameParameterValue")
public class SimpleFileScanner extends ScannerImpl implements FileScanner {
  private static final Logger log = LogManager.getLogger();
  private final AtomicInteger opCountTrace = new AtomicInteger(0);

  private File rootDir;
  private transient volatile boolean scanning;
  private final MemoryUsage heapMemoryUsage;
  private int memWaitTimeout;

  @SuppressWarnings("WeakerAccess")
  protected SimpleFileScanner() {
    memWaitTimeout = 30000; // default
    MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean();
    heapMemoryUsage = memoryMXBean.getHeapMemoryUsage();
  }

  @Transient
  @Override
  public ScanOp getScanOperation() {
    //TODO: consider pulling this check up to ScannerImpl so its similar for
    // all ScannerImpl subclasses

    return new ScanOp(() -> {
      log.trace("Scan Op:{}" , opCountTrace::incrementAndGet);
      synchronized (SimpleFileScanner.this) {
        System.out.println("Acquired lock on " + SimpleFileScanner.this);
        setScanning(true); // ensure initial walk completes before new scans are started.
        try {
          log.trace("About to walk");
          Files.walkFileTree(rootDir.toPath(), new RootWalker());
        } catch (IOException e) {
          log.error("failed to walk filesystem!", e);
          throw new RuntimeException(e);
        } finally {
          setScanning(false);
        }
      }
    }, this);
  }

  @Override
  public boolean isScanning() {
    return this.scanning;
  }

  @Override
  public Optional<Document> fetchById(String id) {
    try {
      File file = new File(new URI(id));
      return makeDoc(file.toPath(), Document.Operation.NEW, Files.readAttributes(file.toPath(), BasicFileAttributes.class));
    } catch (URISyntaxException e) {
      log.error("Malformed doc id, can't fetch document: {}", id);
      return Optional.empty();
    } catch (IOException e) {
      log.error("Could not read file attributes! Document skipped!", e);
      return Optional.empty();
    }
  }

  protected void setScanning(boolean scanning) {
    this.scanning = scanning;
  }

  private class RootWalker extends SimpleFileVisitor<Path> {
    @Override
    public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
      return FileVisitResult.CONTINUE;
    }

    @Override
    public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
      log.trace("found file {}", file);
      Optional<Document> document = makeDoc(file, Document.Operation.NEW, attrs);
      log.trace("Created:{}", document::get);
      document.ifPresent(SimpleFileScanner.this::docFound);
      return FileVisitResult.CONTINUE;
    }

    @Override
    public FileVisitResult visitFileFailed(Path file, IOException exc) {
      log.warn("unable to scan file " + file, exc);
      return FileVisitResult.CONTINUE;
    }

    @Override
    public FileVisitResult postVisitDirectory(Path dir, IOException exc) {
      return FileVisitResult.CONTINUE;
    }
  }

  private Optional<Document> makeDoc(Path file, Document.Operation operation, BasicFileAttributes attributes) {
    byte[] rawData = new byte[0];
    try {
      long size = attributes.size();
      memThrottle(size, "Timed out waiting for available memory to process file (" + size + " bytes):" + file);
      rawData = Files.readAllBytes(file);
      log.trace("Bytes Read:{}", rawData.length);
    } catch (IOException e) {
      log.error("Could not read bytes from file:" + file, e);
    } catch (InterruptedException e) {
      log.error("Document failed (not processed) due to interrupted exception", e);
      throw new RuntimeException(e);
    }
    String id;
    try {
      id = file.toRealPath().toUri().toASCIIString();
      DocumentImpl doc = new DocumentImpl(
          rawData,
          id,
          getPlan(),
          operation,
          this
      );
      addAttrs(attributes, doc);
      return Optional.of(doc);
    } catch (IOException e) {
      // TODO: perhaps we still want to proceed with non-canonical version?
      log.error("Could not resolve file path. Skipping:" + file, e);
      return Optional.empty();
    }
  }

  private void memThrottle(long size, String message) throws InterruptedException {
    long memWaitStart = System.currentTimeMillis();
    int count = 0;
    while (true) {
      long l = heapMemoryUsage.getMax() - heapMemoryUsage.getUsed();
      if (!(size > l)) break;
      if ((count++ % 100) == 0) {
        log.warn("waiting for memory... ({} avail {} required for next doc)",
            l, size);
      }
      // hint to the JVM that we're waiting for memory to be available
      System.gc();
      //noinspection BusyWait
      Thread.sleep(10);
      if (System.currentTimeMillis() - memWaitStart < memWaitTimeout) {
        log.error("Unable to free up memory to load file within {} seconds", memWaitStart / 1000);
        log.error("Possible sources of FileScanner memory avaiability issue: " +
            "1) File is very large, " +
            "2) processing of prior files is slow or stalled, " +
            "3) Memory settings are too low");
        //noinspection BusyWait
        Thread.sleep(100);
        RuntimeException runtimeException = new RuntimeException(message);
        runtimeException.printStackTrace();
        throw runtimeException;
      }
    }
  }

  @SuppressWarnings("unused")
  public static class Builder extends ScannerImpl.Builder {

    private SimpleFileScanner obj;

    public Builder() {
      if (whoAmI() == this.getClass()) {
        obj = new SimpleFileScanner();
      }
    }

    @SuppressWarnings("rawtypes")
    private Class whoAmI() {
      return new Object() {
      }.getClass().getEnclosingMethod().getDeclaringClass();
    }

    public Builder withRoot(File root) {
      getObj().rootDir = root;
      return this;
    }

    @Override
    protected SimpleFileScanner getObj() {
      return obj;
    }

    @Override
    public SimpleFileScanner.Builder batchSize(int size) {
      super.batchSize(size);
      return this;
    }

    @Override
    public SimpleFileScanner.Builder outputSpace(JavaSpace outputSpace) {
      super.outputSpace(outputSpace);
      return this;
    }

    @Override
    public SimpleFileScanner.Builder inputSpace(JavaSpace inputSpace) {
      super.inputSpace(inputSpace);
      return this;
    }

    @Override
    public SimpleFileScanner.Builder named(String stepName) {
      super.named(stepName);
      return this;
    }

    @Override
    public SimpleFileScanner.Builder routingBy(ConfiguredBuildable<? extends Router> router) {
      super.routingBy(router);
      return this;
    }

    @Override
    public SimpleFileScanner.Builder scanFreqMS(long interval) {
      super.scanFreqMS(interval);
      return this;
    }

    public SimpleFileScanner.Builder memoryAvailabilityTimeout(int ms) {
      getObj().memWaitTimeout = ms;
      return this;
    }

    @Override
    public ScannerImpl build() {
      SimpleFileScanner tmp = obj;
      super.build();
      this.obj = new SimpleFileScanner();
      return tmp;
    }

  }

}


text:
export as namespace Split

// Module loader
export = Split

declare function Split(
    elements: Array<string | HTMLElement>,
    options?: Split.Options,
): Split.Instance

declare namespace Split {
    type Partial<T> = { [P in keyof T]?: T[P] }
    type CSSStyleDeclarationPartial = Partial<CSSStyleDeclaration>

    interface Options {
        // Initial sizes of each element in percents or CSS values.
        sizes?: number[]

        // Minimum size of each element.
        minSize?: number | number[]

        // Maximum size of each element.
        maxSize?: number | number[]

        expandToMin?: boolean

        // Gutter size in pixels.
        gutterSize?: number

        gutterAlign?: string

        // Snap to minimum size offset in pixels.
        snapOffset?: number | number[]

        dragInterval?: number

        // Direction to split: horizontal or vertical.
        direction?: 'horizontal' | 'vertical'

        // Cursor to display while dragging.
        cursor?: string

        // Callback on drag.
        onDrag?(sizes: number[]): void

        // Callback on drag start.
        onDragStart?(sizes: number[]): void

        // Callback on drag end.
        onDragEnd?(sizes: number[]): void

        // Called to create each gutter element
        gutter?(
            index: number,
            direction: 'horizontal' | 'vertical',
        ): HTMLElement

        // Called to set the style of each element.
        elementStyle?(
            dimension: 'width' | 'height',
            elementSize: number,
            gutterSize: number,
            index: number,
        ): CSSStyleDeclarationPartial

        // Called to set the style of the gutter.
        gutterStyle?(
            dimension: 'width' | 'height',
            gutterSize: number,
            index: number,
        ): CSSStyleDeclarationPartial
    }

    interface Instance {
        // setSizes behaves the same as the sizes configuration option, passing an array of percents or CSS values.
        // It updates the sizes of the elements in the split.
        setSizes(sizes: number[]): void

        // getSizes returns an array of percents, suitable for using with setSizes or creation.
        getSizes(): number[]

        // collapse changes the size of element at index to 0.
        // Every element except the last is collapsed towards the front (left or top).
        // The last is collapsed towards the back.
        collapse(index: number): void

        // Destroy the instance. It removes the gutter elements, and the size CSS styles Split.js set.
        destroy(preserveStyles?: boolean, preserveGutters?: boolean): void
    }
}


text:
@interface ZNavigationBar : UINavigationBar

@end


text:
from typing import List

from cerebralcortex.kernel.datatypes.datapoint import DataPoint
from cerebralcortex.kernel.datatypes.enumerations import StreamTypes
from cerebralcortex.kernel.datatypes.subtypes import StreamReference, DataDescriptor, ExecutionContext
from cerebralcortex.kernel.datatypes.user import User

class DataStream:
    def __init__(self,
                 identifier: int = None,
                 user: User = None,
                 name: str = None,
                 description: str = None,
                 data_descriptor: List[DataDescriptor] = None,
                 execution_context: ExecutionContext = None,
                 annotations: List[StreamReference] = None,
                 data: List[DataPoint] = None
                 ):
        self._identifier = identifier
        self._user = user
        self._name = name
        self._description = description
        self._data_descriptor = data_descriptor
        self._datastream_type = StreamTypes.DATASTREAM
        self._execution_context = execution_context
        self._annotations = annotations
        self._data = data

    def find_annotation_references(self, identifier: int = None, name: str = None):
        result = self._annotations
        found = False

        if identifier:
            found = True
            result = [a for a in result if a.stream_identifier == identifier]

        if name:
            found = True
            result = [a for a in result if a.name == name]

        if not found:
            return []

        return result

    @property
    def annotations(self):
        return self._annotations

    @annotations.setter
    def annotations(self, value):
        self._annotations = value

    @property
    def identifier(self):
        return self._identifier

    @property
    def user(self):
        return self._user

    @property
    def name(self):
        return self._name

    @name.setter
    def name(self, value):
        self._name = value

    @property
    def description(self):
        return self._description

    @description.setter
    def description(self, value):
        self._description = value

    @property
    def data_descriptor(self):
        return self._data_descriptor

    @data_descriptor.setter
    def data_descriptor(self, value):
        self._data_descriptor = value

    @property
    def execution_context(self):
        return self._execution_context

    @execution_context.setter
    def execution_context(self, value):
        self._execution_context = value

    @property
    def datastream_type(self):
        return self._datastream_type

    @property
    def data(self):
        return self._data

    @data.setter
    def data(self, value):
        result = []
        for dp in value:
            result.append(DataPoint(self._identifier, dp.start_time, dp.end_time, dp.sample))
        self._data = result

    @classmethod
    def from_datastream(cls, input_streams: List):
        result = cls(user=input_streams[0].user)

        # TODO: Something with provenance tracking from datastream list

        return result

    def __str__(self):
        return str(self.identifier) + " - " + str(self.user.identifier) + " - " + str(self.data)


text:
<?php

namespace OzairP\PayBud;

use Exception;

/**
 * Class VerificationException
 * @package OzairP\PayBud
 */
class VerificationException extends Exception
{

}