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

org.opencastproject.assetmanager.impl.query.AbstractSnapshotField Maven / Gradle / Ivy

There is a newer version: 16.7
Show newest version
/**
 * Licensed to The Apereo Foundation under one or more contributor license
 * agreements. See the NOTICE file distributed with this work for additional
 * information regarding copyright ownership.
 *
 *
 * The Apereo Foundation licenses this file to you under the Educational
 * Community 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://opensource.org/licenses/ecl2.txt
 *
 * 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.opencastproject.assetmanager.impl.query;

import static com.entwinemedia.fn.Stream.$;

import org.opencastproject.assetmanager.api.query.Field;
import org.opencastproject.assetmanager.api.query.Order;
import org.opencastproject.assetmanager.api.query.Predicate;
import org.opencastproject.assetmanager.api.query.PropertyField;
import org.opencastproject.assetmanager.impl.RuntimeTypes;
import org.opencastproject.assetmanager.impl.persistence.EntityPaths;
import org.opencastproject.assetmanager.impl.persistence.QPropertyDto;
import org.opencastproject.assetmanager.impl.persistence.QSnapshotDto;

import com.entwinemedia.fn.Fn;
import com.entwinemedia.fn.data.Opt;
import com.mysema.query.jpa.JPASubQuery;
import com.mysema.query.jpa.impl.JPAQueryFactory;
import com.mysema.query.types.ConstantImpl;
import com.mysema.query.types.EntityPath;
import com.mysema.query.types.Operator;
import com.mysema.query.types.Ops;
import com.mysema.query.types.expr.BooleanExpression;
import com.mysema.query.types.expr.BooleanOperation;
import com.mysema.query.types.expr.ComparableExpressionBase;

/**
 * Generic implementation to query {@link org.opencastproject.assetmanager.impl.persistence.SnapshotDto} fields.
 *
 * @param 
 *         The business type of the field, e.g. {@link org.opencastproject.assetmanager.api.Version}
 * @param 
 *         The JPA internal type of the field, e.g. {@link Long}
 */
public abstract class AbstractSnapshotField implements Field, EntityPaths {
  private final ComparableExpressionBase path;

  /**
   * Create a new snapshot field.
   *
   * @param path a path to a snapshot field
   */
  public AbstractSnapshotField(ComparableExpressionBase path) {
    this.path = path;
  }

  /**
   * Extract database type B from business type A.
   */
  protected abstract B extract(A a);

  @Override public Predicate eq(final A right) {
    return mkComparison(Ops.EQ, right);
  }

  @Override public Predicate eq(PropertyField right) {
    return mkComparison(Ops.EQ, right);
  }

  @Override public Predicate lt(A right) {
    return mkComparison(Ops.LT, right);
  }

  @Override public Predicate lt(PropertyField right) {
    return mkComparison(Ops.LT, right);
  }

  @Override public Predicate le(A right) {
    return mkComparison(Ops.LOE, right);
  }

  @Override public Predicate le(PropertyField right) {
    return mkComparison(Ops.LOE, right);
  }

  @Override public Predicate gt(A right) {
    return mkComparison(Ops.GT, right);
  }

  @Override public Predicate gt(PropertyField right) {
    return mkComparison(Ops.GT, right);
  }

  @Override public Predicate ge(A right) {
    return mkComparison(Ops.GOE, right);
  }

  @Override public Predicate ge(PropertyField right) {
    return mkComparison(Ops.GOE, right);
  }

  @Override public Predicate exists() {
    return mkPredicate(path.isNotNull());
  }

  @Override public Predicate notExists() {
    return mkPredicate(path.isNull());
  }

  @Override public Order desc() {
    return new AbstractOrder() {
      @Override public SelectQueryContribution contributeSelect(JPAQueryFactory f) {
        return SelectQueryContribution.mk().order($(path.desc()));
      }
    };
  }

  @Override public Order asc() {
    return new AbstractOrder() {
      @Override public SelectQueryContribution contributeSelect(JPAQueryFactory f) {
        return SelectQueryContribution.mk().order($(path.asc()));
      }
    };
  }

  protected static Predicate mkPredicate(final BooleanExpression where) {
    return new AbstractPredicate() {
      @Override public SelectQueryContribution contributeSelect(JPAQueryFactory f) {
        return SelectQueryContribution.mk().from($Q_SNAPSHOT).where(where);
      }

      @Override public DeleteQueryContribution contributeDelete(String owner) {
        return DeleteQueryContribution.mk().where(new Fn, BooleanExpression>() {
          @Override public BooleanExpression apply(EntityPath from) {
            if (from instanceof QSnapshotDto) {
              return where;
            } else if (from instanceof QPropertyDto) {
              return new JPASubQuery().from(Q_SNAPSHOT)
                  .where(Q_SNAPSHOT.mediaPackageId.eq(Q_PROPERTY.mediaPackageId).and(where))
                  .exists();
            } else {
              throw new RuntimeException("BUG");
            }
          }
        });
      }
    };
  }

  /**
   * Create a predicate for comparisons with a constant value.
   */
  private Predicate mkComparison(final Operator op, A right) {
    return mkPredicate(BooleanOperation.create(op, path, ConstantImpl.create(extract(right))));
  }

  /**
   * Create a predicate for comparisons with a property field.
   */
  private Predicate mkComparison(final Operator op, final PropertyField right) {
    return mkPredicate(PropertyPredicates.mkWhereSelect(right.name(), new Fn>() {
      @Override public Opt apply(QPropertyDto qPropertyDto) {
        return Opt.some(BooleanOperation.create(op, path, RuntimeTypes.convert(right).getPath(qPropertyDto)));
      }
    }));
  }
}