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

org.opencastproject.assetmanager.impl.query.AQueryBuilderImpl 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 static org.opencastproject.assetmanager.impl.query.PropertyPredicates.NONE;
import static org.opencastproject.assetmanager.impl.query.PropertyPredicates.NO_VALUE;

import org.opencastproject.assetmanager.api.Availability;
import org.opencastproject.assetmanager.api.PropertyName;
import org.opencastproject.assetmanager.api.Value.ValueType;
import org.opencastproject.assetmanager.api.query.ADeleteQuery;
import org.opencastproject.assetmanager.api.query.AQueryBuilder;
import org.opencastproject.assetmanager.api.query.ASelectQuery;
import org.opencastproject.assetmanager.api.query.Field;
import org.opencastproject.assetmanager.api.query.Predicate;
import org.opencastproject.assetmanager.api.query.PropertyField;
import org.opencastproject.assetmanager.api.query.Target;
import org.opencastproject.assetmanager.api.query.VersionField;
import org.opencastproject.assetmanager.impl.AssetManagerImpl;
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 org.opencastproject.assetmanager.impl.query.DeleteQueryContribution.Where;
import org.opencastproject.util.RequireUtil;

import com.entwinemedia.fn.Fn;
import com.entwinemedia.fn.Stream;
import com.entwinemedia.fn.data.Opt;
import com.mysema.query.jpa.impl.JPAQueryFactory;
import com.mysema.query.support.Expressions;
import com.mysema.query.types.expr.BooleanExpression;

import java.util.Date;

import javax.annotation.Nonnull;

public final class AQueryBuilderImpl implements AQueryBuilder, EntityPaths {
  private static final Stream FROM_SNAPSHOT = $Q_SNAPSHOT;

  private final AssetManagerImpl am;

  public AQueryBuilderImpl(AssetManagerImpl am) {
    this.am = am;
  }

  /** Convert a {@link Target} into a Querydsl {@link com.mysema.query.types.Expression}. */
  private static Fn contributeSelect(final JPAQueryFactory f) {
    return new Fn() {
      @Override public SelectQueryContribution apply(Target t) {
        return RuntimeTypes.convert(t).contributeSelect(f);
      }
    };
  }

  @Override public ASelectQuery select(final Target... target) {
    return new AbstractASelectQuery(am) {
      @Override public SelectQueryContribution contributeSelect(JPAQueryFactory f) {
        final Stream c = $(target).map(AQueryBuilderImpl.contributeSelect(f));
        return SelectQueryContribution.mk()
                .fetch(c.bind(SelectQueryContribution.getFetch))
                .from(c.bind(SelectQueryContribution.getFrom))
                .join(c.bind(SelectQueryContribution.getJoin))
                .where(Opt.nul(JpaFns.allOf(c.bind(SelectQueryContribution.getWhere))));
      }
    };
  }

  @Override public ADeleteQuery delete(final String owner, final Target target) {
    RequireUtil.notEmpty(owner, "owner");
    return new AbstractADeleteQuery(am, owner) {
      @Override public DeleteQueryContribution contributeDelete(String owner) {
        final DeleteQueryContribution c = RuntimeTypes.convert(target).contributeDelete(owner);
        return DeleteQueryContribution.mk()
                .from(c.from)
                .targetPredicate(c.targetPredicate)
                .where(c.where);
//                .where(new Fn, BooleanExpression>() {
//                  @Override public BooleanExpression apply(EntityPath path) {
//                    // Wildcard deletion. Disabled as of ticket CERV-1158. Kept for potentially later reference.
//                    // return !"".equals(owner)
//                    //     ? Q_SNAPSHOT.owner.eq(owner).and(c.where.apply(path))
//                    //     : c.where.apply(path);
//                    return Q_SNAPSHOT.owner.eq(owner).and(c.where.apply(path));
//                  }
//                });
      }
    };
  }

  /* -- */
  @Override public Predicate mediaPackageIds(final String... mpIds) {
    return new AbstractPredicate() {
      /* SELECT */
      @Override public SelectQueryContribution contributeSelect(JPAQueryFactory f) {
        return SelectQueryContribution.mk().from(FROM_SNAPSHOT).where(Q_SNAPSHOT.mediaPackageId.in(mpIds));
      }

      /* DELETE */
      @Override public DeleteQueryContribution contributeDelete(String owner) {
        return DeleteQueryContribution.mk().where(new Where() {
          @Override public BooleanExpression fromSnapshot(@Nonnull QSnapshotDto e) {
            return e.mediaPackageId.in(mpIds);
          }

          @Override public BooleanExpression fromProperty(@Nonnull QPropertyDto p) {
            return p.mediaPackageId.in(mpIds);
          }
        });
      }

    };
  }

  @Override public Predicate mediaPackageId(final String mpId) {
    return new AbstractPredicate() {
      /* SELECT */
      @Override public SelectQueryContribution contributeSelect(JPAQueryFactory f) {
        return SelectQueryContribution.mk().from(FROM_SNAPSHOT).where(Q_SNAPSHOT.mediaPackageId.eq(mpId));
      }

      /* DELETE */
      @Override public DeleteQueryContribution contributeDelete(String owner) {
        return DeleteQueryContribution.mk().where(new Where() {
          @Override public BooleanExpression fromSnapshot(@Nonnull QSnapshotDto e) {
            return e.mediaPackageId.eq(mpId);
          }

          @Override public BooleanExpression fromProperty(@Nonnull QPropertyDto p) {
            return p.mediaPackageId.eq(mpId);
          }
        });
      }

    };
  }

  @Override public Field mediapackageId() {
    return new SimpleSnapshotField<>(Q_SNAPSHOT.mediaPackageId);
  }

  /**
   * A predicate that is based on a simple snapshot field expression.
   */
  private abstract static class SnapshotBasedPredicate extends AbstractPredicate {
    /* SELECT */
    @Override public SelectQueryContribution contributeSelect(JPAQueryFactory f) {
      return SelectQueryContribution.mk().from(FROM_SNAPSHOT).where(mkSnapshotFieldPredicate(Q_SNAPSHOT));
    }

    /* DELETE */
    @Override public DeleteQueryContribution contributeDelete(String owner) {
      return DeleteQueryContribution.mk().where(new Where() {
        @Override public BooleanExpression fromSnapshot(@Nonnull QSnapshotDto e) {
          return mkSnapshotFieldPredicate(e);
        }

        @Override public BooleanExpression fromProperty(@Nonnull QPropertyDto p) {
          return mkSnapshotFieldPredicate(Q_SNAPSHOT);
        }
      });
    }

    protected abstract BooleanExpression mkSnapshotFieldPredicate(QSnapshotDto e);
  }

  @Override public Field seriesId() {
    return new SimpleSnapshotField<>(Q_SNAPSHOT.seriesId);
  }

  @Override public Predicate organizationId(final String orgId) {
    return new SnapshotBasedPredicate() {
      @Override protected BooleanExpression mkSnapshotFieldPredicate(QSnapshotDto e) {
        return e.organizationId.eq(orgId);
      }
    };
  }

  @Override public Field organizationId() {
    return new SimpleSnapshotField<>(Q_SNAPSHOT.organizationId);
  }

  @Override public Field owner() {
    return new SimpleSnapshotField<>(Q_SNAPSHOT.owner);
  }

  @Override public Predicate availability(final Availability availability) {
    return new SnapshotBasedPredicate() {
      @Override protected BooleanExpression mkSnapshotFieldPredicate(QSnapshotDto e) {
        return e.availability.eq(availability.name());
      }
    };
  }

  @Override public Predicate storage(final String storage) {
    return new SnapshotBasedPredicate() {
      @Override protected BooleanExpression mkSnapshotFieldPredicate(QSnapshotDto e) {
        return e.storageId.eq(storage);
      }
    };
  }

  /* -- */

  // TODO DRY with #hasProperties
  @Override public Predicate hasPropertiesOf(final String namespace) {
    return new AbstractPredicate() {
      /* SELECT */
      @Override public SelectQueryContribution contributeSelect(JPAQueryFactory f) {
        return SelectQueryContribution.mk()
                .where(PropertyPredicates.mkWhereSelect(Opt.some(namespace), NONE, NO_VALUE));
      }

      /* DELETE */
      @Override public DeleteQueryContribution contributeDelete(String owner) {
        return DeleteQueryContribution.mk()
                .where(PropertyPredicates.mkWhereDelete(Opt.some(namespace), NONE, NO_VALUE));
      }
    };
  }

  // TODO DRY with #hasPropertiesOf
  @Override public Predicate hasProperties() {
    return new AbstractPredicate() {
      /* SELECT */
      @Override public SelectQueryContribution contributeSelect(JPAQueryFactory f) {
        return SelectQueryContribution.mk()
                .where(PropertyPredicates.mkWhereSelect(NONE, NONE, NO_VALUE));
      }

      /* DELETE */
      @Override public DeleteQueryContribution contributeDelete(String owner) {
        return DeleteQueryContribution.mk()
                .where(PropertyPredicates.mkWhereDelete(NONE, NONE, NO_VALUE));
      }
    };
  }

  @Override public Field archived() {
    return new SimpleSnapshotField<>(Q_SNAPSHOT.archivalDate);
  }

  @Override public VersionField version() {
    return new VersionFieldImpl();
  }

  @Override public  PropertyField property(ValueType ev, String namespace, String name) {
    return new PropertyFieldImpl<>(ev, PropertyName.mk(namespace, name));
  }

  @Override public  PropertyField property(ValueType ev, PropertyName fqn) {
    return new PropertyFieldImpl<>(ev, fqn);
  }

  @Override public Target snapshot() {
    return new AbstractTarget() {
      @Override public SelectQueryContribution contributeSelect(JPAQueryFactory f) {
        return SelectQueryContribution.mk().from(FROM_SNAPSHOT).fetch($Q_SNAPSHOT);
      }

      @Override public DeleteQueryContribution contributeDelete(String owner) {
        return DeleteQueryContribution.mk().from(FROM_SNAPSHOT).where(Q_SNAPSHOT.owner.eq(owner));
      }
    };
  }

  @Override public Target propertiesOf(final String... namespace) {
    return propertyTarget(namespace);
  }

  @Override public Target properties(PropertyName... fqn) {
    return propertyTarget(fqn);
  }

  @Override public Target nothing() {
    return new AbstractTarget() {
      @Override public SelectQueryContribution contributeSelect(JPAQueryFactory f) {
        return SelectQueryContribution.mk();
      }

      @Override public DeleteQueryContribution contributeDelete(String owner) {
        return DeleteQueryContribution.mk();
      }

    };
  }

  @Override public Predicate always() {
    return new AbstractPredicate() {
      /* SELECT */
      @Override public SelectQueryContribution contributeSelect(JPAQueryFactory f) {
        return SelectQueryContribution.mk().where(Expressions.booleanTemplate("true = true"));
      }

      /* DELETE */
      @Override public DeleteQueryContribution contributeDelete(String owner) {
        return DeleteQueryContribution.mk().where(Expressions.booleanTemplate("true = true"));
      }
    };
  }

  //
  //
  //

  static Target propertyTarget(String... namespace) {
    final Stream onExpressions = $(namespace).map(new Fn() {
      @Override public BooleanExpression apply(String namespace) {
        return Q_PROPERTY.namespace.eq(namespace);
      }
    });
    return propertyTarget(onExpressions);
  }

  static Target propertyTarget(PropertyName... fqn) {
    final Stream onExpressions = $(fqn).map(new Fn() {
      @Override public BooleanExpression apply(PropertyName name) {
        return Q_PROPERTY.namespace.eq(name.getNamespace()).and(Q_PROPERTY.propertyName.eq(name.getName()));
      }
    });
    return propertyTarget(onExpressions);
  }

  /**
   * Create a property target using the given, additional expressions for the join's on clause.
   * On expressions are combined with logical "or".
   */
  private static Target propertyTarget(final Stream onExpressions) {
    return new AbstractTarget() {
      @Override public SelectQueryContribution contributeSelect(JPAQueryFactory f) {
        // join on the media package ID and the given expressions
        final BooleanExpression on = Q_PROPERTY.mediaPackageId
            .eq(Q_SNAPSHOT.mediaPackageId)
            .and(JpaFns.anyOf(onExpressions));
        return SelectQueryContribution.mk().join($(new Join(Q_SNAPSHOT, Q_PROPERTY, on))).fetch($Q_PROPERTY);
      }

      @Override public DeleteQueryContribution contributeDelete(String owner) {
        return DeleteQueryContribution.mk().from($Q_PROPERTY).targetPredicate(JpaFns.anyOf(onExpressions));
      }
    };
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy