Beispiel #1
0
 public int TotalCount() {
   if (this.IsObjectCachedByID())
     return (int)
         QueryHelper.stat_cache(
             CacheRegion(), OBJ_COUNT_CACHE_KEY, "SELECT COUNT(*) FROM " + TableName());
   return (int) QueryHelper.stat("SELECT COUNT(*) FROM " + TableName());
 }
Beispiel #2
0
  @Override
  public final List<T> findListByProperty(
      final Object[] values, final SingularAttribute<T, ? extends Object>... properties) {
    final CriteriaQuery<T> criteriaQuery = criteriaBuilder.createQuery(persistentClass);
    final Root<T> root = criteriaQuery.from(persistentClass);
    criteriaQuery.select(root);

    final Object value = values[0];
    final SingularAttribute<T, ? extends Object> property = properties[0];
    Predicate condition;

    condition =
        QueryHelper.equalsIgnoreCaseIfStringPredicate(criteriaBuilder, root, value, property);

    if (values.length > 1) {
      for (int i = 1; i < properties.length; i++) {
        final SingularAttribute<T, ? extends Object> property2 = properties[i];
        final Object value2 = values[i];
        final Predicate condition2 =
            QueryHelper.equalsIgnoreCaseIfStringPredicate(criteriaBuilder, root, value2, property2);

        condition = criteriaBuilder.and(condition, condition2);
      }
    }

    criteriaQuery.where(condition);

    final TypedQuery<T> typedQuery = getEntityManager().createQuery(criteriaQuery);
    addCacheHints(typedQuery, "findListByProperty");

    return typedQuery.getResultList();
  }
Beispiel #3
0
 public List List(int page, int size, String orderBy) {
   String sql = "SELECT * FROM " + TableName() + " ";
   if (StringUtils.isNotBlank(orderBy)) {
     sql += "ORDER BY " + orderBy;
   }
   return QueryHelper.query_slice(getClass(), sql, page, size);
 }
Beispiel #4
0
 @SuppressWarnings("unchecked")
 public <T extends POJO> T Get(long id) {
   if (id <= 0) return null;
   String sql = "SELECT * FROM " + TableName() + " WHERE id = ?";
   boolean cached = IsObjectCachedByID();
   return (T) QueryHelper.read_cache(getClass(), cached ? CacheRegion() : null, id, sql, id);
 }
Beispiel #5
0
  public boolean updateAttrs(String[] attrNames, Object[] attrValues) {
    int len = attrNames.length;
    List<String> kvs = new ArrayList<String>(len);
    for (String attr : attrNames) {
      kvs.add(attr + " = ?");
    }

    String sql = "update " + TableName() + " set " + StringUtils.join(kvs, ',') + " where id = ?";
    List<Object> vals = new ArrayList<Object>();
    for (Object val : attrValues) {
      vals.add(val);
    }
    vals.add(getId());

    int ret = QueryHelper.update(sql, vals.toArray());
    try {
      if (ret > 0) {
        for (int i = 0; i < len; i++) {
          BeanUtils.setProperty(this, attrNames[i], attrValues[i]);
        }
      } else {
        return false;
      }
    } catch (Exception e) {
      return false;
    }
    return true;
  }
  public ConditionQuery getTraceDownQuery() {

    if (traceDownConditionQuery != null) {
      return traceDownConditionQuery;
    }
    traceDownConditionQuery = (ConditionQuery) QueryHelper.wrapQueryEntity(getTraceDown());
    return traceDownConditionQuery;
  }
Beispiel #7
0
 public boolean Delete() {
   boolean dr =
       Evict(QueryHelper.update("DELETE FROM " + TableName() + " WHERE id = ?", getId()) == 1);
   if (dr) {
     CacheManager.evict(CacheRegion(), OBJ_COUNT_CACHE_KEY);
   }
   return dr;
 }
Beispiel #8
0
 public boolean updateAttr(String attrName, Object attrValue) {
   String sql = "update " + TableName() + " set " + attrName + " = ? where id = ?";
   int ret = QueryHelper.update(sql, attrValue, getId());
   try {
     if (ret > 0) {
       BeanUtils.setProperty(this, attrName, attrValue);
     } else {
       return false;
     }
   } catch (Exception e) {
     return false;
   }
   return true;
 }
Beispiel #9
0
  // 对这个cache的更新操作需要格外留意
  public List IDs(String afterFrom, Object... params) {
    String tbl = TableName();

    String cacheKey = afterFrom;
    for (Object obj : params) {
      cacheKey += obj;
    }

    String sql = "select id from " + tbl + " ";
    if (StringUtils.isNotBlank(afterFrom)) {
      sql += afterFrom;
    } else {
      cacheKey = "all" + cacheKey;
    }
    return QueryHelper.query_cache(Long.class, CacheRegion(), cacheKey, sql, params);
  }
Beispiel #10
0
 protected List<? extends POJO> BatchGet(List<Long> ids) {
   if (ids == null || ids.size() == 0) return null;
   StringBuilder sql = new StringBuilder("SELECT * FROM " + TableName() + " WHERE id IN (");
   for (int i = 1; i <= ids.size(); i++) {
     sql.append('?');
     if (i < ids.size()) sql.append(',');
   }
   sql.append(')');
   List<? extends POJO> beans =
       QueryHelper.query(getClass(), sql.toString(), ids.toArray(new Object[ids.size()]));
   if (IsObjectCachedByID()) {
     for (Object bean : beans) {
       CacheManager.set(CacheRegion(), ((POJO) bean).getId(), (Serializable) bean);
     }
   }
   return beans;
 }
Beispiel #11
0
 private static long _InsertObject(POJO obj) {
   Map<String, Object> pojo_bean = obj.ListInsertableFields();
   String[] fields = pojo_bean.keySet().toArray(new String[pojo_bean.size()]);
   StringBuilder sql = new StringBuilder("INSERT INTO ");
   sql.append(obj.TableName());
   sql.append('(');
   for (int i = 0; i < fields.length; i++) {
     if (i > 0) sql.append(',');
     sql.append(fields[i]);
   }
   sql.append(") VALUES(");
   for (int i = 0; i < fields.length; i++) {
     if (i > 0) sql.append(',');
     sql.append('?');
   }
   sql.append(')');
   PreparedStatement ps = null;
   ResultSet rs = null;
   try {
     ps =
         QueryHelper.getConnection()
             .prepareStatement(sql.toString(), PreparedStatement.RETURN_GENERATED_KEYS);
     for (int i = 0; i < fields.length; i++) {
       ps.setObject(i + 1, pojo_bean.get(fields[i]));
     }
     ps.executeUpdate();
     rs = ps.getGeneratedKeys();
     return rs.next() ? rs.getLong(1) : -1;
   } catch (SQLException e) {
     throw new DBException(e);
   } finally {
     DbUtils.closeQuietly(rs);
     DbUtils.closeQuietly(ps);
     sql = null;
     fields = null;
     pojo_bean = null;
   }
 }
Beispiel #12
0
 public <T extends POJO> T GetByAttr(String attrName, Object attrValue) {
   String sql = "SELECT * FROM " + TableName() + " WHERE " + attrName + " = ?";
   return (T) QueryHelper.read(getClass(), sql, attrValue);
 }
/**
 * A collection of wavelets, local and remote, held in memory.
 *
 * @author [email protected] (Soren Lassen)
 */
public class WaveMap implements SearchProvider {

  /**
   * Helper class that allows to add basic sort and filter functionality to the search.
   *
   * @author [email protected] (Yuri Z.)
   */
  private static class QueryHelper {

    @SuppressWarnings("serial")
    class InvalidQueryException extends Exception {

      public InvalidQueryException(String msg) {
        super(msg);
      }
    }

    /**
     * Unknown participantId used by {@link ASC_CREATOR_COMPARATOR} in case wave creator cannot be
     * found.
     */
    static final ParticipantId UNKNOWN_CREATOR = ParticipantId.ofUnsafe("*****@*****.**");

    /** Sorts search result in ascending order by LMT. */
    static final Comparator<WaveViewData> ASC_LMT_COMPARATOR =
        new Comparator<WaveViewData>() {
          @Override
          public int compare(WaveViewData arg0, WaveViewData arg1) {
            long lmt0 = computeLmt(arg0);
            long lmt1 = computeLmt(arg1);
            return Long.signum(lmt0 - lmt1);
          }

          private long computeLmt(WaveViewData wave) {
            long lmt = -1;
            for (ObservableWaveletData wavelet : wave.getWavelets()) {
              // Skip non conversational wavelets.
              if (!IdUtil.isConversationalId(wavelet.getWaveletId())) {
                continue;
              }
              lmt = lmt < wavelet.getLastModifiedTime() ? wavelet.getLastModifiedTime() : lmt;
            }
            return lmt;
          }
        };

    /** Sorts search result in descending order by LMT. */
    static final Comparator<WaveViewData> DESC_LMT_COMPARATOR =
        new Comparator<WaveViewData>() {
          @Override
          public int compare(WaveViewData arg0, WaveViewData arg1) {
            return -ASC_LMT_COMPARATOR.compare(arg0, arg1);
          }
        };

    /** Sorts search result in ascending order by creation time. */
    static final Comparator<WaveViewData> ASC_CREATED_COMPARATOR =
        new Comparator<WaveViewData>() {
          @Override
          public int compare(WaveViewData arg0, WaveViewData arg1) {
            long time0 = computeCreatedTime(arg0);
            long time1 = computeCreatedTime(arg1);
            return Long.signum(time0 - time1);
          }

          private long computeCreatedTime(WaveViewData wave) {
            long creationTime = -1;
            for (ObservableWaveletData wavelet : wave.getWavelets()) {
              creationTime =
                  creationTime < wavelet.getCreationTime()
                      ? wavelet.getCreationTime()
                      : creationTime;
            }
            return creationTime;
          }
        };

    /** Sorts search result in descending order by creation time. */
    static final Comparator<WaveViewData> DESC_CREATED_COMPARATOR =
        new Comparator<WaveViewData>() {
          @Override
          public int compare(WaveViewData arg0, WaveViewData arg1) {
            return -ASC_CREATED_COMPARATOR.compare(arg0, arg1);
          }
        };

    /** Sorts search result in ascending order by creator */
    static final Comparator<WaveViewData> ASC_CREATOR_COMPARATOR =
        new Comparator<WaveViewData>() {
          @Override
          public int compare(WaveViewData arg0, WaveViewData arg1) {
            ParticipantId creator0 = computeCreator(arg0);
            ParticipantId creator1 = computeCreator(arg1);
            return creator0.compareTo(creator1);
          }

          private ParticipantId computeCreator(WaveViewData wave) {
            for (ObservableWaveletData wavelet : wave.getWavelets()) {
              if (IdUtil.isConversationRootWaveletId(wavelet.getWaveletId())) {
                return wavelet.getCreator();
              }
            }
            // If not found creator - compare with UNKNOWN_CREATOR;
            return UNKNOWN_CREATOR;
          }
        };

    /** Sorts search result in descending order by creator */
    static final Comparator<WaveViewData> DESC_CREATOR_COMPARATOR =
        new Comparator<WaveViewData>() {
          @Override
          public int compare(WaveViewData arg0, WaveViewData arg1) {
            return -ASC_CREATOR_COMPARATOR.compare(arg0, arg1);
          }
        };

    /** Sorts search result by WaveId. */
    static final Comparator<WaveViewData> ID_COMPARATOR =
        new Comparator<WaveViewData>() {
          @Override
          public int compare(WaveViewData arg0, WaveViewData arg1) {
            return arg0.getWaveId().compareTo(arg1.getWaveId());
          }
        };

    /** Orders using {@link ASCENDING_DATE_COMPARATOR}. */
    static final Ordering<WaveViewData> ASC_LMT_ORDERING =
        Ordering.from(QueryHelper.ASC_LMT_COMPARATOR);

    /** Orders using {@link DESCENDING_DATE_COMPARATOR}. */
    static final Ordering<WaveViewData> DESC_LMT_ORDERING =
        Ordering.from(QueryHelper.DESC_LMT_COMPARATOR);

    /** Orders using {@link ASC_CREATED_COMPARATOR}. */
    static final Ordering<WaveViewData> ASC_CREATED_ORDERING =
        Ordering.from(QueryHelper.ASC_CREATED_COMPARATOR);

    /** Orders using {@link DESC_CREATED_COMPARATOR}. */
    static final Ordering<WaveViewData> DESC_CREATED_ORDERING =
        Ordering.from(QueryHelper.DESC_CREATED_COMPARATOR);

    /** Orders using {@link ASC_CREATOR_COMPARATOR}. */
    static final Ordering<WaveViewData> ASC_CREATOR_ORDERING =
        Ordering.from(QueryHelper.ASC_CREATOR_COMPARATOR);

    /** Orders using {@link DESC_CREATOR_COMPARATOR}. */
    static final Ordering<WaveViewData> DESC_CREATOR_ORDERING =
        Ordering.from(QueryHelper.DESC_CREATOR_COMPARATOR);

    /** Default ordering is by LMT descending. */
    static final Ordering<WaveViewData> DEFAULT_ORDERING = DESC_LMT_ORDERING;

    /** Valid search query types. */
    enum TokenQueryType {
      IN("in"),
      ORDERBY("orderby"),
      WITH("with"),
      CREATOR("creator");

      final String token;

      TokenQueryType(String token) {
        this.token = token;
      }

      String getToken() {
        return token;
      }

      private static final Map<String, TokenQueryType> reverseLookupMap =
          new HashMap<String, TokenQueryType>();

      static {
        for (TokenQueryType type : TokenQueryType.values()) {
          reverseLookupMap.put(type.getToken(), type);
        }
      }

      static TokenQueryType fromToken(String token) {
        TokenQueryType qyeryToken = reverseLookupMap.get(token);
        if (qyeryToken == null) {
          throw new IllegalArgumentException("Illegal query param: " + token);
        }
        return reverseLookupMap.get(token);
      }

      static boolean hasToken(String token) {
        return reverseLookupMap.keySet().contains(token);
      }
    }

    /** Registered order by parameter types and corresponding orderings. */
    enum OrderByValueType {
      DATEASC("dateasc", ASC_LMT_ORDERING),
      DATEDESC("datedesc", DESC_LMT_ORDERING),
      CREATEDASC("createdasc", ASC_CREATED_ORDERING),
      CREATEDDESC("createddesc", DESC_CREATED_ORDERING),
      CREATORASC("creatorasc", ASC_CREATOR_ORDERING),
      CREATORDESC("creatordesc", DESC_CREATOR_ORDERING);

      final String value;
      final Ordering<WaveViewData> ordering;

      OrderByValueType(String value, Ordering<WaveViewData> ordering) {
        this.value = value;
        this.ordering = ordering;
      }

      String getToken() {
        return value;
      }

      Ordering<WaveViewData> getOrdering() {
        return ordering;
      }

      private static final Map<String, OrderByValueType> reverseLookupMap =
          new HashMap<String, OrderByValueType>();

      static {
        for (OrderByValueType type : OrderByValueType.values()) {
          reverseLookupMap.put(type.getToken(), type);
        }
      }

      static OrderByValueType fromToken(String token) {
        OrderByValueType orderByValue = reverseLookupMap.get(token);
        if (orderByValue == null) {
          throw new IllegalArgumentException("Illegal 'orderby' value: " + token);
        }
        return reverseLookupMap.get(token);
      }
    }

    private QueryHelper() {}

    /** Static factory method. */
    static QueryHelper newQueryHelper() {
      return new QueryHelper();
    }

    /**
     * Parses the search query.
     *
     * @param query the query.
     * @return the result map with query tokens. Never returns null.
     * @throws InvalidQueryException if the query contains invalid params.
     */
    Map<TokenQueryType, Set<String>> parseQuery(String query) throws InvalidQueryException {
      Preconditions.checkArgument(query != null);
      query = query.trim();
      // If query is empty - return.
      if (query.isEmpty()) {
        return Collections.emptyMap();
      }
      String[] tokens = query.split("\\s+");
      Map<TokenQueryType, Set<String>> tokensMap = Maps.newEnumMap(TokenQueryType.class);
      for (String token : tokens) {
        String[] pair = token.split(":");
        if (pair.length != 2 || !TokenQueryType.hasToken(pair[0])) {
          String msg = "Invalid query param: " + token;
          throw new InvalidQueryException(msg);
        }
        String tokenValue = pair[1];
        TokenQueryType tokenType = TokenQueryType.fromToken(pair[0]);
        // Verify the orderby param.
        if (tokenType.equals(TokenQueryType.ORDERBY)) {
          try {
            OrderByValueType.fromToken(tokenValue);
          } catch (IllegalArgumentException e) {
            String msg = "Invalid orderby query value: " + tokenValue;
            throw new InvalidQueryException(msg);
          }
        }
        Set<String> valuesPerToken = tokensMap.get(tokenType);
        if (valuesPerToken == null) {
          valuesPerToken = Sets.newLinkedHashSet();
          tokensMap.put(tokenType, valuesPerToken);
        }
        valuesPerToken.add(tokenValue);
      }
      return tokensMap;
    }

    /**
     * Builds a list of participants to serve as the filter for the query.
     *
     * @param queryParams the query params.
     * @param queryType the filter for the query , i.e. 'with'.
     * @param localDomain the local domain of the logged in user.
     * @return the participants list for the filter.
     * @throws InvalidParticipantAddress if participant id passed to the query is invalid.
     */
    static List<ParticipantId> buildValidatedParticipantIds(
        Map<QueryHelper.TokenQueryType, Set<String>> queryParams,
        QueryHelper.TokenQueryType queryType,
        String localDomain)
        throws InvalidParticipantAddress {
      Set<String> tokenSet = queryParams.get(queryType);
      List<ParticipantId> participants = null;
      if (tokenSet != null) {
        participants = Lists.newArrayListWithCapacity(tokenSet.size());
        for (String token : tokenSet) {
          if (!token.isEmpty() && token.indexOf("@") == -1) {
            // If no domain was specified, assume that the participant is from the local domain.
            token = token + "@" + localDomain;
          } else if (token.equals("@")) {
            // "@" is a shortcut for the shared domain participant.
            token = "@" + localDomain;
          }
          ParticipantId otherUser = ParticipantId.of(token);
          participants.add(otherUser);
        }
      } else {
        participants = Collections.emptyList();
      }
      return participants;
    }

    /**
     * Computes ordering for the search results. If none are specified - then returns the default
     * ordering. The resulting ordering is always compounded with ordering by wave id for stability.
     */
    static Ordering<WaveViewData> computeSorter(
        Map<QueryHelper.TokenQueryType, Set<String>> queryParams) {
      Ordering<WaveViewData> ordering = null;
      Set<String> orderBySet = queryParams.get(QueryHelper.TokenQueryType.ORDERBY);
      if (orderBySet != null) {
        for (String orderBy : orderBySet) {
          QueryHelper.OrderByValueType orderingType =
              QueryHelper.OrderByValueType.fromToken(orderBy);
          if (ordering == null) {
            // Primary ordering.
            ordering = orderingType.getOrdering();
          } else {
            // All other ordering are compounded to the primary one.
            ordering = ordering.compound(orderingType.getOrdering());
          }
        }
      } else {
        ordering = QueryHelper.DEFAULT_ORDERING;
      }
      // For stability order also by wave id.
      ordering = ordering.compound(QueryHelper.ID_COMPARATOR);
      return ordering;
    }
  }

  private static final Log LOG = Log.get(WaveMap.class);

  private final QueryHelper queryHelper = QueryHelper.newQueryHelper();

  /** The wavelets in a wave. */
  private static final class Wave implements Iterable<WaveletContainer> {
    private class WaveletCreator<T extends WaveletContainer> implements Function<WaveletId, T> {
      private final WaveletContainer.Factory<T> factory;

      private final String waveDomain;

      public WaveletCreator(WaveletContainer.Factory<T> factory, String waveDomain) {
        this.factory = factory;
        this.waveDomain = waveDomain;
      }

      @Override
      public T apply(WaveletId waveletId) {
        return factory.create(notifiee, WaveletName.of(waveId, waveletId), waveDomain);
      }
    }

    private final WaveId waveId;
    /** Future providing already-existing wavelets in storage. */
    private final ListenableFuture<ImmutableSet<WaveletId>> lookedupWavelets;

    private final ConcurrentMap<WaveletId, LocalWaveletContainer> localWavelets;
    private final ConcurrentMap<WaveletId, RemoteWaveletContainer> remoteWavelets;
    private final WaveletNotificationSubscriber notifiee;

    /**
     * Creates a wave. The {@code lookupWavelets} future is examined only when a query is first
     * made.
     */
    public Wave(
        WaveId waveId,
        ListenableFuture<ImmutableSet<WaveletId>> lookedupWavelets,
        WaveletNotificationSubscriber notifiee,
        LocalWaveletContainer.Factory localFactory,
        RemoteWaveletContainer.Factory remoteFactory,
        String waveDomain) {
      this.waveId = waveId;
      this.lookedupWavelets = lookedupWavelets;
      this.notifiee = notifiee;
      this.localWavelets =
          new MapMaker()
              .makeComputingMap(
                  new WaveletCreator<LocalWaveletContainer>(localFactory, waveDomain));
      this.remoteWavelets =
          new MapMaker()
              .makeComputingMap(
                  new WaveletCreator<RemoteWaveletContainer>(remoteFactory, waveDomain));
    }

    @Override
    public Iterator<WaveletContainer> iterator() {
      return Iterators.unmodifiableIterator(
          Iterables.concat(localWavelets.values(), remoteWavelets.values()).iterator());
    }

    public LocalWaveletContainer getLocalWavelet(WaveletId waveletId) throws WaveletStateException {
      return getWavelet(waveletId, localWavelets);
    }

    public RemoteWaveletContainer getRemoteWavelet(WaveletId waveletId)
        throws WaveletStateException {
      return getWavelet(waveletId, remoteWavelets);
    }

    public LocalWaveletContainer getOrCreateLocalWavelet(WaveletId waveletId) {
      return localWavelets.get(waveletId);
    }

    public RemoteWaveletContainer getOrCreateRemoteWavelet(WaveletId waveletId) {
      return remoteWavelets.get(waveletId);
    }

    private <T extends WaveletContainer> T getWavelet(
        WaveletId waveletId, ConcurrentMap<WaveletId, T> waveletsMap) throws WaveletStateException {
      ImmutableSet<WaveletId> storedWavelets;
      try {
        storedWavelets =
            FutureUtil.getResultOrPropagateException(lookedupWavelets, PersistenceException.class);
      } catch (PersistenceException e) {
        throw new WaveletStateException(
            "Failed to lookup wavelet " + WaveletName.of(waveId, waveletId), e);
      } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
        throw new WaveletStateException(
            "Interrupted looking up wavelet " + WaveletName.of(waveId, waveletId), e);
      }
      // Since waveletsMap is a computing map, we must call containsKey(waveletId)
      // to tell if waveletId is mapped, we cannot test if get(waveletId) returns null.
      if (!storedWavelets.contains(waveletId) && !waveletsMap.containsKey(waveletId)) {
        return null;
      } else {
        T wavelet = waveletsMap.get(waveletId);
        Preconditions.checkNotNull(wavelet, "computingMap returned null");
        return wavelet;
      }
    }
  }

  /**
   * Returns a future whose result is the ids of stored wavelets in the given wave. Any failure is
   * reported as a {@link PersistenceException}.
   */
  private static ListenableFuture<ImmutableSet<WaveletId>> lookupWavelets(
      final WaveId waveId, final WaveletStore<?> waveletStore, Executor lookupExecutor) {
    ListenableFutureTask<ImmutableSet<WaveletId>> task =
        new ListenableFutureTask<ImmutableSet<WaveletId>>(
            new Callable<ImmutableSet<WaveletId>>() {
              @Override
              public ImmutableSet<WaveletId> call() throws PersistenceException {
                return waveletStore.lookup(waveId);
              }
            });
    lookupExecutor.execute(task);
    return task;
  }

  private final ConcurrentMap<WaveId, Wave> waves;
  private final WaveletStore<?> store;

  @Inject
  public WaveMap(
      final DeltaAndSnapshotStore waveletStore,
      final WaveletNotificationSubscriber notifiee,
      final LocalWaveletContainer.Factory localFactory,
      final RemoteWaveletContainer.Factory remoteFactory,
      @Named(CoreSettings.WAVE_SERVER_DOMAIN) final String waveDomain) {
    // NOTE(anorth): DeltaAndSnapshotStore is more specific than necessary, but
    // helps Guice out.
    // TODO(soren): inject a proper executor (with a pool of configurable size)
    this.store = waveletStore;
    final Executor lookupExecutor = Executors.newSingleThreadExecutor();
    waves =
        new MapMaker()
            .makeComputingMap(
                new Function<WaveId, Wave>() {
                  @Override
                  public Wave apply(WaveId waveId) {
                    ListenableFuture<ImmutableSet<WaveletId>> lookedupWavelets =
                        lookupWavelets(waveId, waveletStore, lookupExecutor);
                    return new Wave(
                        waveId,
                        lookedupWavelets,
                        notifiee,
                        localFactory,
                        remoteFactory,
                        waveDomain);
                  }
                });
  }

  /**
   * Loads all wavelets from storage.
   *
   * @throws WaveletStateException if storage access fails.
   */
  public void loadAllWavelets() throws WaveletStateException {
    try {
      ExceptionalIterator<WaveId, PersistenceException> itr = store.getWaveIdIterator();
      while (itr.hasNext()) {
        WaveId waveId = itr.next();
        lookupWavelets(waveId);
      }
    } catch (PersistenceException e) {
      throw new WaveletStateException("Failed to scan waves", e);
    }
  }

  @Override
  public Collection<WaveViewData> search(
      ParticipantId user, String query, int startAt, int numResults) {
    LOG.fine(
        "Search query '"
            + query
            + "' from user: "******" ["
            + startAt
            + ", "
            + (startAt + numResults - 1)
            + "]");
    Map<QueryHelper.TokenQueryType, Set<String>> queryParams = null;
    try {
      queryParams = queryHelper.parseQuery(query);
    } catch (QueryHelper.InvalidQueryException e1) {
      // Invalid query param - stop and return empty search results.
      LOG.warning("Invalid Query. " + e1.getMessage());
      return Collections.emptyList();
    }
    List<ParticipantId> withParticipantIds = null;
    List<ParticipantId> creatorParticipantIds = null;
    try {
      String localDomain = user.getDomain();
      // Build and validate.
      withParticipantIds =
          QueryHelper.buildValidatedParticipantIds(
              queryParams, QueryHelper.TokenQueryType.WITH, localDomain);
      creatorParticipantIds =
          QueryHelper.buildValidatedParticipantIds(
              queryParams, QueryHelper.TokenQueryType.CREATOR, localDomain);
    } catch (InvalidParticipantAddress e) {
      // Invalid address - stop and return empty search results.
      LOG.warning("Invalid participantId: " + e.getAddress() + " in query: " + query);
      return Collections.emptyList();
    }
    // Maybe should be changed in case other folders in addition to 'inbox' are added.
    boolean isAllQuery = !queryParams.containsKey(QueryHelper.TokenQueryType.IN);
    // Must use a map with stable ordering, since indices are meaningful.
    Map<WaveId, WaveViewData> results = Maps.newLinkedHashMap();
    for (Map.Entry<WaveId, Wave> entry : waves.entrySet()) {
      WaveId waveId = entry.getKey();
      Wave wave = entry.getValue();
      WaveViewData view = null; // Copy of the wave built up for search hits.
      for (WaveletContainer c : wave) {
        // TODO (Yuri Z.) This loop collects all the wavelets that match the
        // query, so the view is determined by the query. Instead we should
        // look at the user's wave view and determine if the view matches the query.
        ParticipantId sharedDomainParticipantId = c.getSharedDomainParticipant();
        try {
          // TODO (Yuri Z.) Need to explore how to avoid this copy, e.g., by
          // moving parts of the matches() logic into a WaveletContainer method.
          ObservableWaveletData wavelet = c.copyWaveletData();
          // Only filtering by participants is implemented for now.
          if (!matches(
              wavelet,
              user,
              sharedDomainParticipantId,
              withParticipantIds,
              creatorParticipantIds,
              isAllQuery)) {
            continue;
          }
          if (view == null) {
            view = WaveViewDataImpl.create(waveId);
          }
          // Just keep adding all the relevant wavelets in this wave.
          view.addWavelet(wavelet);
        } catch (WaveletStateException e) {
          LOG.warning("Failed to access wavelet " + c.getWaveletName(), e);
        }
      }
      // Filter out waves without conversational root wavelet from search result.
      if (WaveletDataUtil.hasConversationalRootWavelet(view)) {
        results.put(waveId, view);
      }
    }
    List<WaveViewData> searchResultslist = null;
    int searchResultSize = results.values().size();
    // Check if we have enough results to return.
    if (searchResultSize < startAt) {
      searchResultslist = Collections.emptyList();
    } else {
      int endAt = Math.min(startAt + numResults, searchResultSize);
      searchResultslist =
          QueryHelper.computeSorter(queryParams)
              .sortedCopy(results.values())
              .subList(startAt, endAt);
    }
    LOG.info(
        "Search response to '"
            + query
            + "': "
            + searchResultslist.size()
            + " results, user: "******"Failed to look up wave " + waveId, e);
    } catch (InterruptedException e) {
      Thread.currentThread().interrupt();
      throw new WaveletStateException("Interrupted while looking up wave " + waveId, e);
    }
  }

  public LocalWaveletContainer getLocalWavelet(WaveletName waveletName)
      throws WaveletStateException {
    return waves.get(waveletName.waveId).getLocalWavelet(waveletName.waveletId);
  }

  public RemoteWaveletContainer getRemoteWavelet(WaveletName waveletName)
      throws WaveletStateException {
    return waves.get(waveletName.waveId).getRemoteWavelet(waveletName.waveletId);
  }

  public LocalWaveletContainer getOrCreateLocalWavelet(WaveletName waveletName) {
    return waves.get(waveletName.waveId).getOrCreateLocalWavelet(waveletName.waveletId);
  }

  public RemoteWaveletContainer getOrCreateRemoteWavelet(WaveletName waveletName) {
    return waves.get(waveletName.waveId).getOrCreateRemoteWavelet(waveletName.waveletId);
  }
}
 @Override
 public Collection<WaveViewData> search(
     ParticipantId user, String query, int startAt, int numResults) {
   LOG.fine(
       "Search query '"
           + query
           + "' from user: "******" ["
           + startAt
           + ", "
           + (startAt + numResults - 1)
           + "]");
   Map<QueryHelper.TokenQueryType, Set<String>> queryParams = null;
   try {
     queryParams = queryHelper.parseQuery(query);
   } catch (QueryHelper.InvalidQueryException e1) {
     // Invalid query param - stop and return empty search results.
     LOG.warning("Invalid Query. " + e1.getMessage());
     return Collections.emptyList();
   }
   List<ParticipantId> withParticipantIds = null;
   List<ParticipantId> creatorParticipantIds = null;
   try {
     String localDomain = user.getDomain();
     // Build and validate.
     withParticipantIds =
         QueryHelper.buildValidatedParticipantIds(
             queryParams, QueryHelper.TokenQueryType.WITH, localDomain);
     creatorParticipantIds =
         QueryHelper.buildValidatedParticipantIds(
             queryParams, QueryHelper.TokenQueryType.CREATOR, localDomain);
   } catch (InvalidParticipantAddress e) {
     // Invalid address - stop and return empty search results.
     LOG.warning("Invalid participantId: " + e.getAddress() + " in query: " + query);
     return Collections.emptyList();
   }
   // Maybe should be changed in case other folders in addition to 'inbox' are added.
   boolean isAllQuery = !queryParams.containsKey(QueryHelper.TokenQueryType.IN);
   // Must use a map with stable ordering, since indices are meaningful.
   Map<WaveId, WaveViewData> results = Maps.newLinkedHashMap();
   for (Map.Entry<WaveId, Wave> entry : waves.entrySet()) {
     WaveId waveId = entry.getKey();
     Wave wave = entry.getValue();
     WaveViewData view = null; // Copy of the wave built up for search hits.
     for (WaveletContainer c : wave) {
       // TODO (Yuri Z.) This loop collects all the wavelets that match the
       // query, so the view is determined by the query. Instead we should
       // look at the user's wave view and determine if the view matches the query.
       ParticipantId sharedDomainParticipantId = c.getSharedDomainParticipant();
       try {
         // TODO (Yuri Z.) Need to explore how to avoid this copy, e.g., by
         // moving parts of the matches() logic into a WaveletContainer method.
         ObservableWaveletData wavelet = c.copyWaveletData();
         // Only filtering by participants is implemented for now.
         if (!matches(
             wavelet,
             user,
             sharedDomainParticipantId,
             withParticipantIds,
             creatorParticipantIds,
             isAllQuery)) {
           continue;
         }
         if (view == null) {
           view = WaveViewDataImpl.create(waveId);
         }
         // Just keep adding all the relevant wavelets in this wave.
         view.addWavelet(wavelet);
       } catch (WaveletStateException e) {
         LOG.warning("Failed to access wavelet " + c.getWaveletName(), e);
       }
     }
     // Filter out waves without conversational root wavelet from search result.
     if (WaveletDataUtil.hasConversationalRootWavelet(view)) {
       results.put(waveId, view);
     }
   }
   List<WaveViewData> searchResultslist = null;
   int searchResultSize = results.values().size();
   // Check if we have enough results to return.
   if (searchResultSize < startAt) {
     searchResultslist = Collections.emptyList();
   } else {
     int endAt = Math.min(startAt + numResults, searchResultSize);
     searchResultslist =
         QueryHelper.computeSorter(queryParams)
             .sortedCopy(results.values())
             .subList(startAt, endAt);
   }
   LOG.info(
       "Search response to '"
           + query
           + "': "
           + searchResultslist.size()
           + " results, user: "
           + user);
   // Memory management wise it's dangerous to return a sublist of a much
   // longer list, therefore, we return a 'defensive' copy.
   return ImmutableList.copyOf(searchResultslist);
 }
Beispiel #15
0
 public List BatchGetByAttr(String attrName, Object attrValue) {
   String sql = "SELECT * FROM " + TableName() + " WHERE " + attrName + " = ?";
   return QueryHelper.query(getClass(), sql, attrValue);
 }
Beispiel #16
0
 public int TotalCount(String filter, Object... params) {
   return (int)
       QueryHelper.stat("SELECT COUNT(*) FROM " + TableName() + " WHERE " + filter, params);
 }
Beispiel #17
0
 public List Filter(String filter, int page, int size) {
   String sql = "SELECT * FROM " + TableName() + " WHERE " + filter + " ORDER BY id DESC";
   return QueryHelper.query_slice(getClass(), sql, page, size);
 }