All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.lens.cube.metadata.DerivedCube Maven / Gradle / Ivy

The newest version!
/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.lens.cube.metadata;

import java.util.*;

import org.apache.lens.cube.error.LensCubeErrorCode;
import org.apache.lens.server.api.error.LensException;

import org.apache.commons.lang.StringUtils;
import org.apache.hadoop.hive.metastore.api.FieldSchema;
import org.apache.hadoop.hive.ql.metadata.Table;

import com.google.common.collect.Lists;

public class DerivedCube extends AbstractCubeTable implements CubeInterface {

  private static final List COLUMNS = new ArrayList<>();

  static {
    COLUMNS.add(new FieldSchema("dummy", "string", "dummy column"));
  }

  private final Cube parent;
  private final Set measures = new HashSet<>();
  private final Set dimensions = new HashSet<>();

  public DerivedCube(String name, Set measures, Set dimensions, Cube parent) throws LensException {
    this(name, measures, dimensions, new HashMap(), 0L, parent);
  }

  public DerivedCube(String name, Set measures, Set dimensions, Map properties,
    double weight, Cube parent) throws LensException {
    super(name, COLUMNS, properties, weight);
    for (String msr : measures) {
      this.measures.add(msr.toLowerCase());
    }
    for (String dim : dimensions) {
      this.dimensions.add(dim.toLowerCase());
    }
    this.parent = parent;
    validate();
    addProperties();
  }

  public void validate() throws LensException {
    List measuresNotInParentCube = Lists.newArrayList();
    List dimAttributesNotInParentCube = Lists.newArrayList();
    for (String msr : measures) {
      if (parent.getMeasureByName(msr) == null) {
        measuresNotInParentCube.add(msr);
      }
    }
    for (String dim : dimensions) {
      if (parent.getDimAttributeByName(dim) == null) {
        dimAttributesNotInParentCube.add(dim);
      }
    }
    StringBuilder validationErrorStringBuilder = new StringBuilder();
    String sep = "";
    boolean invalid = false;
    if (!measuresNotInParentCube.isEmpty()) {
      validationErrorStringBuilder.append(sep).append("Measures ").append(measuresNotInParentCube);
      sep = " and ";
      invalid = true;
    }
    if (!dimAttributesNotInParentCube.isEmpty()) {
      validationErrorStringBuilder.append(sep).append("Dim Attributes ").append(dimAttributesNotInParentCube);
      invalid = true;
    }
    if (invalid) {
      throw new LensException(LensCubeErrorCode.ERROR_IN_ENTITY_DEFINITION.getLensErrorInfo(),
        "Derived cube invalid: " + validationErrorStringBuilder.append(" were not present in " + "parent cube ")
          .append(parent));
    }
  }

  public DerivedCube(Table tbl, Cube parent) {
    super(tbl);
    this.measures.addAll(getMeasures(getName(), getProperties()));
    this.dimensions.addAll(getDimensions(getName(), getProperties()));
    this.parent = parent;
  }

  private Set cachedMeasures = new HashSet<>();
  private Set cachedDims = new HashSet<>();

  public Set getMeasures() {
    synchronized (measures) {
      if (cachedMeasures.isEmpty()) {
        for (String msr : measures) {
          cachedMeasures.add(parent.getMeasureByName(msr));
        }
      }
    }
    return cachedMeasures;
  }

  public Set getDimAttributes() {
    synchronized (dimensions) {
      if (cachedDims.isEmpty()) {
        for (String dim : dimensions) {
          cachedDims.add(parent.getDimAttributeByName(dim));
        }
      }
    }
    return cachedDims;
  }

  @Override
  public CubeTableType getTableType() {
    return CubeTableType.CUBE;
  }

  @Override
  public Set getStorages() {
    return null;
  }

  @Override
  public void addProperties() {
    super.addProperties();
    updateMeasureProperties();
    updateDimAttributeProperties();
    getProperties().put(MetastoreUtil.getParentCubeNameKey(getName()), parent.getName().toLowerCase());
    getProperties().put(MetastoreUtil.getParentCubeNameKey(getName()), parent.getName().toLowerCase());
  }
  public void updateDimAttributeProperties() {
    MetastoreUtil.addNameStrings(getProperties(), MetastoreUtil.getCubeDimensionListKey(getName()),
      MetastoreUtil.getNamedSetFromStringSet(dimensions));
  }
  public void updateMeasureProperties() {
    MetastoreUtil.addNameStrings(getProperties(), MetastoreUtil.getCubeMeasureListKey(getName()),
      MetastoreUtil.getNamedSetFromStringSet(measures));
  }

  public static Set getMeasures(String name, Map props) {
    Set measures = new HashSet<>();
    String measureStr = MetastoreUtil.getNamedStringValue(props, MetastoreUtil.getCubeMeasureListKey(name));
    measures.addAll(Arrays.asList(StringUtils.split(measureStr, ',')));
    return measures;
  }

  public Set getTimedDimensions() {
    String str = getProperties().get(MetastoreUtil.getCubeTimedDimensionListKey(getName()));
    if (str != null) {
      Set timedDimensions = new HashSet<>();
      timedDimensions.addAll(Arrays.asList(StringUtils.split(str, ',')));
      return timedDimensions;
    } else {
      return parent.getTimedDimensions();
    }
  }

  public static Set getDimensions(String name, Map props) {
    Set dimensions = new HashSet<>();
    String dimStr = MetastoreUtil.getNamedStringValue(props, MetastoreUtil.getCubeDimensionListKey(name));
    dimensions.addAll(Arrays.asList(StringUtils.split(dimStr, ',')));
    return dimensions;
  }

  public Cube getParent() {
    return parent;
  }

  @Override
  public int hashCode() {
    return super.hashCode();
  }

  @Override
  public boolean equals(Object obj) {
    if (!super.equals(obj)) {
      return false;
    }
    DerivedCube other = (DerivedCube) obj;
    if (!this.getParent().equals(other.getParent())) {
      return false;
    }
    if (this.getMeasureNames() == null) {
      if (other.getMeasureNames() != null) {
        return false;
      }
    } else if (!this.getMeasureNames().equals(other.getMeasureNames())) {
      return false;
    }
    if (this.getDimAttributeNames() == null) {
      if (other.getDimAttributeNames() != null) {
        return false;
      }
    } else if (!this.getDimAttributeNames().equals(other.getDimAttributeNames())) {
      return false;
    }
    return true;
  }

  public CubeDimAttribute getDimAttributeByName(String dimension) {
    if (dimensions.contains(dimension.toLowerCase())) {
      return parent.getDimAttributeByName(dimension);
    }
    return null;
  }

  public CubeMeasure getMeasureByName(String measure) {
    if (measures.contains(measure.toLowerCase())) {
      return parent.getMeasureByName(measure);
    }
    return null;
  }

  public CubeColumn getColumnByName(String column) {
    CubeColumn cubeCol = (CubeColumn) getMeasureByName(column);
    if (cubeCol == null) {
      cubeCol = (CubeColumn) getDimAttributeByName(column);
    }
    return cubeCol;
  }

  /**
   * Add a new measure
   *
   * @param measure measure name
   */
  public void addMeasure(String measure) {
    measures.add(measure.toLowerCase());
    updateMeasureProperties();
  }

  /**
   * Add a new dimension
   *
   * @param dimension attribute name
   */
  public void addDimension(String dimension) {
    dimensions.add(dimension.toLowerCase());
    updateDimAttributeProperties();
  }

  /**
   * Remove the dimension with name specified
   *
   * @param dimName
   */
  public void removeDimension(String dimName) {
    dimensions.remove(dimName.toLowerCase());
    updateDimAttributeProperties();
  }

  /**
   * Remove the measure with name specified
   *
   * @param msrName
   */
  public void removeMeasure(String msrName) {
    measures.remove(msrName.toLowerCase());
    updateMeasureProperties();
  }

  @Override
  public boolean isDerivedCube() {
    return true;
  }

  @Override
  public Set getMeasureNames() {
    return measures;
  }

  @Override
  public Set getDimAttributeNames() {
    Set dimNames = new HashSet<>();
    for (CubeDimAttribute f : getDimAttributes()) {
      MetastoreUtil.addColumnNames(f, dimNames);
    }
    return dimNames;
  }

  @Override
  public boolean allFieldsQueriable() {
    return true;
  }

  @Override
  public Set getExpressions() {
    return null;
  }

  @Override
  public ExprColumn getExpressionByName(String exprName) {
    return null;
  }

  @Override
  public Set getAllFieldNames() {
    Set fieldNames = new HashSet<>();
    fieldNames.addAll(getMeasureNames());
    fieldNames.addAll(getDimAttributeNames());
    fieldNames.addAll(getTimedDimensions());
    return fieldNames;
  }

  @Override
  public Set getExpressionNames() {
    // TODO Auto-generated method stub
    return null;
  }

  @Override
  public Set getJoinChains() {
    // TODO Auto-generated method stub
    return null;
  }

  @Override
  public JoinChain getChainByName(String chainName) {
    // TODO Auto-generated method stub
    return null;
  }

  @Override
  public Set getJoinChainNames() {
    // TODO Auto-generated method stub
    return null;
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy