Example usage for org.hibernate Criteria setFirstResult

List of usage examples for org.hibernate Criteria setFirstResult

Introduction

In this page you can find the example usage for org.hibernate Criteria setFirstResult.

Prototype

public Criteria setFirstResult(int firstResult);

Source Link

Document

Set the first result to be retrieved.

Usage

From source file:com.eucalyptus.objectstorage.DbObjectManagerImpl.java

License:Open Source License

@Override
public PaginatedResult<ObjectEntity> listVersionsPaginated(final Bucket bucket, int maxEntries, String prefix,
        String delimiter, String fromKeyMarker, String fromVersionId, boolean latestOnly) throws Exception {

    EntityTransaction db = Entities.get(ObjectEntity.class);
    try {//  w  w w .jav a2  s .co  m
        PaginatedResult<ObjectEntity> result = new PaginatedResult<ObjectEntity>();
        HashSet<String> commonPrefixes = new HashSet<String>();

        // Include zero since 'istruncated' is still valid
        if (maxEntries >= 0) {
            final int queryStrideSize = maxEntries + 1;
            ObjectEntity searchObj = new ObjectEntity();
            searchObj.setBucketName(bucket.getBucketName());

            // Return latest version, so exclude delete markers as well.
            // This makes listVersion act like listObjects
            if (latestOnly) {
                searchObj.setDeleted(false);
                searchObj.setIsLatest(true);
            }

            Criteria objCriteria = Entities.createCriteria(ObjectEntity.class);
            objCriteria.setReadOnly(true);
            objCriteria.setFetchSize(queryStrideSize);
            objCriteria.add(Example.create(searchObj));
            objCriteria.add(ObjectEntity.QueryHelpers.getNotPendingRestriction());
            objCriteria.add(ObjectEntity.QueryHelpers.getNotDeletingRestriction());
            objCriteria.addOrder(Order.asc("objectKey"));
            objCriteria.addOrder(Order.desc("objectModifiedTimestamp"));
            objCriteria.setMaxResults(queryStrideSize);

            if (!Strings.isNullOrEmpty(fromKeyMarker)) {
                objCriteria.add(Restrictions.gt("objectKey", fromKeyMarker));
            } else {
                fromKeyMarker = "";
            }

            if (!Strings.isNullOrEmpty(fromVersionId)) {
                objCriteria.add(Restrictions.gt("versionId", fromVersionId));
            } else {
                fromVersionId = "";
            }

            if (!Strings.isNullOrEmpty(prefix)) {
                objCriteria.add(Restrictions.like("objectKey", prefix, MatchMode.START));
            } else {
                prefix = "";
            }

            // Ensure not null.
            if (Strings.isNullOrEmpty(delimiter)) {
                delimiter = "";
            }

            List<ObjectEntity> objectInfos = null;
            int resultKeyCount = 0;
            String[] parts = null;
            String prefixString = null;
            boolean useDelimiter = !Strings.isNullOrEmpty(delimiter);
            int pages = 0;

            // Iterate over result sets of size maxkeys + 1 since
            // commonPrefixes collapse the list, we may examine many more
            // records than maxkeys + 1
            do {
                parts = null;
                prefixString = null;

                // Skip ahead the next page of 'queryStrideSize' results.
                objCriteria.setFirstResult(pages++ * queryStrideSize);

                objectInfos = (List<ObjectEntity>) objCriteria.list();
                if (objectInfos == null) {
                    // nothing to do.
                    break;
                }

                for (ObjectEntity objectRecord : objectInfos) {
                    if (useDelimiter) {
                        // Check if it will get aggregated as a commonprefix
                        parts = objectRecord.getObjectKey().substring(prefix.length()).split(delimiter);
                        if (parts.length > 1) {
                            prefixString = prefix + parts[0] + delimiter;
                            if (!commonPrefixes.contains(prefixString)) {
                                if (resultKeyCount == maxEntries) {
                                    // This is a new record, so we know
                                    // we're truncating if this is true
                                    result.setIsTruncated(true);
                                    resultKeyCount++;
                                    break;
                                } else {
                                    // Add it to the common prefix set
                                    commonPrefixes.add(prefixString);
                                    result.lastEntry = prefixString;
                                    // count the unique commonprefix as a
                                    // single return entry
                                    resultKeyCount++;
                                }
                            } else {
                                // Already have this prefix, so skip
                            }
                            continue;
                        }
                    }

                    if (resultKeyCount == maxEntries) {
                        // This is a new (non-commonprefix) record, so
                        // we know we're truncating
                        result.setIsTruncated(true);
                        resultKeyCount++;
                        break;
                    }

                    result.entityList.add(objectRecord);
                    result.lastEntry = objectRecord;
                    resultKeyCount++;
                }

                if (resultKeyCount <= maxEntries && objectInfos.size() <= maxEntries) {
                    break;
                }
            } while (resultKeyCount <= maxEntries);

            // Sort the prefixes from the hashtable and add to the reply
            if (commonPrefixes != null) {
                result.getCommonPrefixes().addAll(commonPrefixes);
                Collections.sort(result.getCommonPrefixes());
            }
        } else {
            throw new IllegalArgumentException("MaxKeys must be positive integer");
        }

        return result;
    } catch (Exception e) {
        LOG.error("Error generating paginated object list of bucket " + bucket.getBucketName(), e);
        throw e;
    } finally {
        db.rollback();
    }
}

From source file:com.eucalyptus.objectstorage.metadata.DbMpuPartMetadataManagerImpl.java

License:Open Source License

@Override
public PaginatedResult<PartEntity> listPartsForUpload(final Bucket bucket, final String objectKey,
        final String uploadId, final Integer partNumberMarker, final Integer maxParts) throws Exception {

    EntityTransaction db = Entities.get(PartEntity.class);
    try {/*from  w  w w . j av  a  2  s .c o  m*/
        PaginatedResult<PartEntity> result = new PaginatedResult<PartEntity>();
        HashSet<String> commonPrefixes = new HashSet<String>();

        // Include zero since 'istruncated' is still valid
        if (maxParts >= 0) {
            final int queryStrideSize = maxParts + 1;
            PartEntity searchPart = new PartEntity(bucket, objectKey, uploadId).withState(ObjectState.extant);

            Criteria objCriteria = Entities.createCriteria(PartEntity.class);
            objCriteria.setReadOnly(true);
            objCriteria.setFetchSize(queryStrideSize);
            objCriteria.add(Example.create(searchPart));
            objCriteria.addOrder(Order.asc("partNumber"));
            objCriteria.addOrder(Order.desc("objectModifiedTimestamp"));
            objCriteria.setMaxResults(queryStrideSize);

            if (partNumberMarker != null) {
                objCriteria.add(Restrictions.gt("partNumber", partNumberMarker));
            }
            objCriteria = getSearchByBucket(objCriteria, bucket);

            List<PartEntity> partInfos = null;
            int resultKeyCount = 0;
            String[] parts = null;
            int pages = 0;

            // Iterate over result sets of size maxkeys + 1 since
            // commonPrefixes collapse the list, we may examine many more
            // records than maxkeys + 1
            do {
                parts = null;

                // Skip ahead the next page of 'queryStrideSize' results.
                objCriteria.setFirstResult(pages++ * queryStrideSize);

                partInfos = (List<PartEntity>) objCriteria.list();
                if (partInfos == null) {
                    // nothing to do.
                    break;
                }

                for (PartEntity partRecord : partInfos) {

                    if (resultKeyCount == maxParts) {
                        result.setIsTruncated(true);
                        resultKeyCount++;
                        break;
                    }

                    result.getEntityList().add(partRecord);
                    result.setLastEntry(partRecord);
                    resultKeyCount++;
                }

                if (resultKeyCount <= maxParts && partInfos.size() <= maxParts) {
                    break;
                }
            } while (resultKeyCount <= maxParts);
        } else {
            throw new IllegalArgumentException("MaxKeys must be positive integer");
        }

        return result;
    } catch (Exception e) {
        LOG.error("Error generating paginated parts list for upload ID " + uploadId, e);
        throw e;
    } finally {
        db.rollback();
    }
}

From source file:com.eucalyptus.objectstorage.metadata.DbObjectMetadataManagerImpl.java

License:Open Source License

@Override
public PaginatedResult<ObjectEntity> listUploads(Bucket bucket, int maxUploads, String prefix, String delimiter,
        String keyMarker, String uploadIdMarker) throws Exception {

    try (TransactionResource trans = Entities.transactionFor(ObjectEntity.class)) {
        PaginatedResult<ObjectEntity> result = new PaginatedResult<ObjectEntity>();
        HashSet<String> commonPrefixes = new HashSet<String>();

        // Include zero since 'istruncated' is still valid
        if (maxUploads >= 0) {
            final int queryStrideSize = maxUploads + 1;
            ObjectEntity searchObj = new ObjectEntity();
            searchObj.withBucket(bucket); //This doesn't actually filter, but do it anyway
            searchObj.withState(ObjectState.mpu_pending);

            Criteria objCriteria = Entities.createCriteria(ObjectEntity.class);
            objCriteria.setReadOnly(true);
            objCriteria.setFetchSize(queryStrideSize);
            objCriteria.add(Example.create(searchObj));
            objCriteria.addOrder(Order.asc("objectKey"));
            objCriteria.setMaxResults(queryStrideSize);

            if (!Strings.isNullOrEmpty(keyMarker)) {
                objCriteria.add(Restrictions.gt("objectKey", keyMarker));
            } else {
                keyMarker = "";
            }//w  w w . j a va2s  .co  m

            if (!Strings.isNullOrEmpty(uploadIdMarker)) {
                objCriteria.add(Restrictions.gt("uploadId", uploadIdMarker));
            } else {
                uploadIdMarker = "";
            }

            if (!Strings.isNullOrEmpty(prefix)) {
                objCriteria.add(Restrictions.like("objectKey", prefix, MatchMode.START));
            } else {
                prefix = "";
            }

            //Be sure to add the bucket restriction last
            objCriteria = getSearchByBucket(objCriteria, bucket);

            // Ensure not null.
            if (Strings.isNullOrEmpty(delimiter)) {
                delimiter = "";
            }

            List<ObjectEntity> objectInfos = null;
            int resultKeyCount = 0;
            String[] parts = null;
            String prefixString = null;
            boolean useDelimiter = !Strings.isNullOrEmpty(delimiter);
            int pages = 0;

            // Iterate over result sets of size maxkeys + 1 since
            // commonPrefixes collapse the list, we may examine many more
            // records than maxkeys + 1
            do {
                parts = null;
                prefixString = null;

                // Skip ahead the next page of 'queryStrideSize' results.
                objCriteria.setFirstResult(pages++ * queryStrideSize);

                objectInfos = (List<ObjectEntity>) objCriteria.list();
                if (objectInfos == null) {
                    // nothing to do.
                    break;
                }

                for (ObjectEntity objectRecord : objectInfos) {
                    if (useDelimiter) {
                        // Check if it will get aggregated as a commonprefix
                        parts = objectRecord.getObjectKey().substring(prefix.length()).split(delimiter);
                        if (parts.length > 1) {
                            prefixString = prefix + parts[0] + delimiter;
                            if (!prefixString.equals(keyMarker) && !commonPrefixes.contains(prefixString)) {
                                if (resultKeyCount == maxUploads) {
                                    // This is a new record, so we know
                                    // we're truncating if this is true
                                    result.setIsTruncated(true);
                                    resultKeyCount++;
                                    break;
                                } else {
                                    // Add it to the common prefix set
                                    commonPrefixes.add(prefixString);
                                    result.setLastEntry(prefixString);
                                    // count the unique commonprefix as a
                                    // single return entry
                                    resultKeyCount++;
                                }
                            } else {
                                // Already have this prefix, so skip
                            }
                            continue;
                        }
                    }

                    if (resultKeyCount == maxUploads) {
                        // This is a new (non-commonprefix) record, so
                        // we know we're truncating
                        result.setIsTruncated(true);
                        resultKeyCount++;
                        break;
                    }

                    result.getEntityList().add(objectRecord);
                    result.setLastEntry(objectRecord);
                    resultKeyCount++;
                }

                if (resultKeyCount <= maxUploads && objectInfos.size() <= maxUploads) {
                    break;
                }
            } while (resultKeyCount <= maxUploads);

            // Sort the prefixes from the hashtable and add to the reply
            if (commonPrefixes != null) {
                result.getCommonPrefixes().addAll(commonPrefixes);
                Collections.sort(result.getCommonPrefixes());
            }
        } else {
            throw new IllegalArgumentException("max uploads must be positive integer");
        }

        return result;
    } catch (Exception e) {
        LOG.error("Error generating paginated multipart upload list for bucket " + bucket.getBucketName(), e);
        throw e;
    }
}

From source file:com.eucalyptus.objectstorage.metadata.DbObjectMetadataManagerImpl.java

License:Open Source License

@Override
public PaginatedResult<ObjectEntity> listVersionsPaginated(final Bucket bucket, int maxEntries, String prefix,
        String delimiter, String fromKeyMarker, String fromVersionId, boolean latestOnly) throws Exception {

    EntityTransaction db = Entities.get(ObjectEntity.class);
    try {/*from  w  ww .ja  v  a  2s.com*/
        PaginatedResult<ObjectEntity> result = new PaginatedResult<ObjectEntity>();
        HashSet<String> commonPrefixes = new HashSet<String>();

        // Include zero since 'istruncated' is still valid
        if (maxEntries >= 0) {
            final int queryStrideSize = maxEntries + 1;
            ObjectEntity searchObj = new ObjectEntity().withBucket(bucket).withState(ObjectState.extant);

            // Return latest version, so exclude delete markers as well.
            // This makes listVersion act like listObjects
            if (latestOnly) {
                searchObj.setIsLatest(true);
                searchObj.setIsDeleteMarker(false);
            }

            Criteria objCriteria = Entities.createCriteria(ObjectEntity.class);
            objCriteria.setReadOnly(true);
            objCriteria.setFetchSize(queryStrideSize);
            objCriteria.add(Example.create(searchObj));
            objCriteria.addOrder(Order.asc("objectKey"));
            objCriteria.addOrder(Order.desc("objectModifiedTimestamp"));
            objCriteria.setMaxResults(queryStrideSize);

            if (!Strings.isNullOrEmpty(fromKeyMarker)) {
                if (!Strings.isNullOrEmpty(fromVersionId)) {
                    // Look for the key that matches the key-marker and version-id-marker
                    ObjectEntity searchObject = new ObjectEntity(bucket, fromKeyMarker, fromVersionId);
                    ObjectEntity matchingObject = null;
                    try {
                        matchingObject = Entities.uniqueResult(searchObject);
                        if (matchingObject == null || matchingObject.getObjectModifiedTimestamp() == null) {
                            throw new NoSuchKeyException(bucket.getBucketName() + "/" + fromKeyMarker
                                    + "?versionId=" + fromVersionId);
                        }
                    } catch (Exception e) {
                        LOG.warn("No matching object found for key-marker=" + fromKeyMarker
                                + " and version-id-marker=" + fromVersionId);
                        throw new NoSuchKeyException(
                                bucket.getBucketName() + "/" + fromKeyMarker + "?versionId=" + fromVersionId);
                    }

                    // The result set should be exclusive of the key with the key-marker version-id-marker pair. Look for keys that chronologically
                    // follow the version-id-marker for the given key-marker and also the keys that follow the key-marker.
                    objCriteria.add(Restrictions.or(
                            Restrictions.and(Restrictions.eq("objectKey", fromKeyMarker),
                                    Restrictions.lt("objectModifiedTimestamp",
                                            matchingObject.getObjectModifiedTimestamp())),
                            Restrictions.gt("objectKey", fromKeyMarker)));
                } else { // No version-id-marker, just set the criteria the key-marker
                    objCriteria.add(Restrictions.gt("objectKey", fromKeyMarker));
                }
            } else {
                // No criteria to be set
            }

            if (!Strings.isNullOrEmpty(prefix)) {
                objCriteria.add(Restrictions.like("objectKey", prefix, MatchMode.START));
            } else {
                prefix = "";
            }

            objCriteria = getSearchByBucket(objCriteria, bucket);

            // Ensure not null.
            if (Strings.isNullOrEmpty(delimiter)) {
                delimiter = "";
            }

            List<ObjectEntity> objectInfos = null;
            int resultKeyCount = 0;
            String[] parts = null;
            String prefixString = null;
            boolean useDelimiter = !Strings.isNullOrEmpty(delimiter);
            int pages = 0;

            // Iterate over result sets of size maxkeys + 1 since
            // commonPrefixes collapse the list, we may examine many more
            // records than maxkeys + 1
            do {
                parts = null;
                prefixString = null;

                // Skip ahead the next page of 'queryStrideSize' results.
                objCriteria.setFirstResult(pages++ * queryStrideSize);

                objectInfos = (List<ObjectEntity>) objCriteria.list();
                if (objectInfos == null) {
                    // nothing to do.
                    break;
                }

                for (ObjectEntity objectRecord : objectInfos) {
                    if (useDelimiter) {
                        // Check if it will get aggregated as a commonprefix
                        parts = objectRecord.getObjectKey().substring(prefix.length()).split(delimiter);
                        if (parts.length > 1) {
                            prefixString = prefix + parts[0] + delimiter;
                            if (!prefixString.equals(fromKeyMarker) && !commonPrefixes.contains(prefixString)) {
                                if (resultKeyCount == maxEntries) {
                                    // This is a new record, so we know
                                    // we're truncating if this is true
                                    result.setIsTruncated(true);
                                    resultKeyCount++;
                                    break;
                                } else {
                                    // Add it to the common prefix set
                                    commonPrefixes.add(prefixString);
                                    result.setLastEntry(prefixString);
                                    // count the unique commonprefix as a
                                    // single return entry
                                    resultKeyCount++;
                                }
                            } else {
                                // Already have this prefix, so skip
                            }
                            continue;
                        }
                    }

                    if (resultKeyCount == maxEntries) {
                        // This is a new (non-commonprefix) record, so
                        // we know we're truncating
                        result.setIsTruncated(true);
                        resultKeyCount++;
                        break;
                    }

                    result.getEntityList().add(objectRecord);
                    result.setLastEntry(objectRecord);
                    resultKeyCount++;
                }

                if (resultKeyCount <= maxEntries && objectInfos.size() <= maxEntries) {
                    break;
                }
            } while (resultKeyCount <= maxEntries);

            // Sort the prefixes from the hashtable and add to the reply
            if (commonPrefixes != null) {
                result.getCommonPrefixes().addAll(commonPrefixes);
                Collections.sort(result.getCommonPrefixes());
            }
        } else {
            throw new IllegalArgumentException("MaxKeys must be positive integer");
        }

        return result;
    } catch (Exception e) {
        LOG.error("Error generating paginated object list of bucket " + bucket.getBucketName(), e);
        throw e;
    } finally {
        db.rollback();
    }
}

From source file:com.eucalyptus.objectstorage.WalrusManager.java

License:Open Source License

public ListBucketResponseType listBucket(ListBucketType request) throws EucalyptusCloudException {
    ListBucketResponseType reply = (ListBucketResponseType) request.getReply();

    EntityWrapper<BucketInfo> db = EntityWrapper.get(BucketInfo.class);

    try {/*  ww w .  ja  v  a  2 s.  c o  m*/
        String bucketName = request.getBucket();
        BucketInfo bucketInfo = new BucketInfo(bucketName);
        bucketInfo.setHidden(false);
        List<BucketInfo> bucketList = db.queryEscape(bucketInfo);

        Context ctx = Contexts.lookup();
        Account account = ctx.getAccount();

        int maxKeys = -1;
        String maxKeysString = request.getMaxKeys();
        if (maxKeysString != null) {
            maxKeys = Integer.parseInt(maxKeysString);
            if (maxKeys < 0) {
                throw new InvalidArgumentException("max-keys",
                        "Argument max-keys must be an integer between 0 and " + Integer.MAX_VALUE);
            }
        } else {
            maxKeys = WalrusProperties.MAX_KEYS;
        }

        if (bucketList.size() > 0) {
            BucketInfo bucket = bucketList.get(0);
            BucketLogData logData = bucket.getLoggingEnabled() ? request.getLogData() : null;
            if (ctx.hasAdministrativePrivileges() || (bucket.canRead(account.getAccountNumber())
                    && (bucket.isGlobalRead() || Lookups.checkPrivilege(PolicySpec.S3_LISTBUCKET,
                            PolicySpec.VENDOR_S3, PolicySpec.S3_RESOURCE_BUCKET, bucketName, null)))) {
                if (logData != null) {
                    updateLogData(bucket, logData);
                    reply.setLogData(logData);
                }

                if (Contexts.lookup().hasAdministrativePrivileges()) {
                    try {
                        if (bucketHasSnapshots(bucketName)) {
                            db.rollback();
                            throw new NoSuchBucketException(bucketName);
                        }
                    } catch (Exception e) {
                        db.rollback();
                        throw new EucalyptusCloudException(e);
                    }
                }

                String prefix = request.getPrefix();
                String delimiter = request.getDelimiter();
                String marker = request.getMarker();

                reply.setName(bucketName);
                reply.setIsTruncated(false);
                reply.setPrefix(prefix);
                reply.setMarker(marker);
                reply.setDelimiter(delimiter);
                reply.setMaxKeys(maxKeys);

                if (maxKeys == 0) {
                    // No keys requested, so just return
                    reply.setContents(new ArrayList<ListEntry>());
                    reply.setCommonPrefixesList(new ArrayList<CommonPrefixesEntry>());
                    db.commit();
                    return reply;
                }

                final int queryStrideSize = maxKeys + 1;
                EntityWrapper<ObjectInfo> dbObject = db.recast(ObjectInfo.class);

                ObjectInfo searchObj = new ObjectInfo();
                searchObj.setBucketName(bucketName);
                searchObj.setLast(true);
                searchObj.setDeleted(false);

                Criteria objCriteria = dbObject.createCriteria(ObjectInfo.class);
                objCriteria.add(Example.create(searchObj));
                objCriteria.addOrder(Order.asc("objectKey"));
                objCriteria.setMaxResults(queryStrideSize); // add one to, hopefully, indicate truncation in one call

                if (!Strings.isNullOrEmpty(marker)) {
                    // The result set should be exclusive of the marker. marker could be a common prefix from a previous response. Look for keys that
                    // lexicographically follow the marker and don't contain the marker as the prefix.
                    objCriteria.add(Restrictions.and(Restrictions.gt("objectKey", marker),
                            Restrictions.not(Restrictions.like("objectKey", marker, MatchMode.START))));
                } else {
                    marker = "";
                }

                if (!Strings.isNullOrEmpty(prefix)) {
                    objCriteria.add(Restrictions.like("objectKey", prefix, MatchMode.START));
                } else {
                    prefix = "";
                }

                // Ensure not null.
                if (Strings.isNullOrEmpty(delimiter)) {
                    delimiter = "";
                }

                List<ObjectInfo> objectInfos = null;
                int resultKeyCount = 0;
                ArrayList<ListEntry> contents = new ArrayList<ListEntry>(); // contents for reply
                String nextMarker = null;
                TreeSet<String> commonPrefixes = new TreeSet<String>();
                int firstResult = -1;

                // Iterate over result sets of size maxkeys + 1
                do {
                    // Start listing from the 0th element and increment the first element to be listed by the query size
                    objCriteria.setFirstResult(queryStrideSize * (++firstResult));
                    objectInfos = (List<ObjectInfo>) objCriteria.list();

                    if (objectInfos.size() > 0) {
                        for (ObjectInfo objectInfo : objectInfos) {
                            String objectKey = objectInfo.getObjectKey();

                            // Check if it will get aggregated as a commonprefix
                            if (!Strings.isNullOrEmpty(delimiter)) {
                                String[] parts = objectKey.substring(prefix.length()).split(delimiter);
                                if (parts.length > 1) {
                                    String prefixString = prefix + parts[0] + delimiter;
                                    if (!commonPrefixes.contains(prefixString)) {
                                        if (resultKeyCount == maxKeys) {
                                            // This is a new record, so we know we're truncating if this is true
                                            reply.setNextMarker(nextMarker);
                                            reply.setIsTruncated(true);
                                            resultKeyCount++;
                                            break;
                                        }

                                        commonPrefixes.add(prefixString);
                                        resultKeyCount++; // count the unique commonprefix as a single return entry

                                        // If max keys have been collected, set the next-marker. It might be needed for the response if the list is
                                        // truncated
                                        // If the common prefixes hit the limit set by max-keys, next-marker is the last common prefix
                                        if (resultKeyCount == maxKeys) {
                                            nextMarker = prefixString;
                                        }
                                    }
                                    continue;
                                }
                            }

                            if (resultKeyCount == maxKeys) {
                                // This is a new (non-commonprefix) record, so we know we're truncating
                                reply.setNextMarker(nextMarker);
                                reply.setIsTruncated(true);
                                resultKeyCount++;
                                break;
                            }

                            // Process the entry as a full key listing
                            ListEntry listEntry = new ListEntry();
                            listEntry.setKey(objectKey);
                            listEntry.setEtag(objectInfo.getEtag());
                            listEntry.setLastModified(DateUtils.format(objectInfo.getLastModified().getTime(),
                                    DateUtils.ALT_ISO8601_DATE_PATTERN));
                            listEntry.setStorageClass(objectInfo.getStorageClass());
                            listEntry.setSize(objectInfo.getSize());
                            listEntry.setStorageClass(objectInfo.getStorageClass());
                            try {
                                Account ownerAccount = Accounts.lookupAccountById(objectInfo.getOwnerId());
                                listEntry.setOwner(new CanonicalUserType(ownerAccount.getCanonicalId(),
                                        ownerAccount.getName()));
                            } catch (AuthException e) {
                                db.rollback();
                                throw new AccessDeniedException("Bucket", bucketName, logData);
                            }
                            contents.add(listEntry);

                            resultKeyCount++;

                            // If max keys have been collected, set the next-marker. It might be needed for the response if the list is truncated
                            if (resultKeyCount == maxKeys) {
                                nextMarker = objectKey;
                            }
                        }
                    }

                    if (resultKeyCount <= maxKeys && objectInfos.size() <= maxKeys) {
                        break;
                    }
                } while (resultKeyCount <= maxKeys);

                reply.setContents(contents);

                // Prefixes are already sorted, add them to the proper data structures and populate the reply
                if (!commonPrefixes.isEmpty()) {
                    ArrayList<CommonPrefixesEntry> commonPrefixesList = new ArrayList<CommonPrefixesEntry>();
                    for (String prefixEntry : commonPrefixes) {
                        commonPrefixesList.add(new CommonPrefixesEntry().add(new PrefixEntry(prefixEntry)));
                    }
                    reply.setCommonPrefixesList(commonPrefixesList);
                }
            } else {
                db.rollback();
                throw new AccessDeniedException("Bucket", bucketName, logData);
            }
        } else {
            db.rollback();
            throw new NoSuchBucketException(bucketName);
        }
        db.commit();
        return reply;
    } finally {
        if (db.isActive()) {
            db.rollback();
        }
    }
}

From source file:com.eucalyptus.objectstorage.WalrusManager.java

License:Open Source License

public ListVersionsResponseType listVersions(ListVersionsType request) throws EucalyptusCloudException {
    ListVersionsResponseType reply = (ListVersionsResponseType) request.getReply();

    EntityWrapper<BucketInfo> db = EntityWrapper.get(BucketInfo.class);

    try {/* w w  w  . j a  v a  2  s.  c o m*/
        String bucketName = request.getBucket();
        BucketInfo bucketInfo = new BucketInfo(bucketName);
        bucketInfo.setHidden(false);
        List<BucketInfo> bucketList = db.queryEscape(bucketInfo);

        Context ctx = Contexts.lookup();
        Account account = ctx.getAccount();

        int maxKeys = -1;
        String maxKeysString = request.getMaxKeys();
        if (maxKeysString != null) {
            maxKeys = Integer.parseInt(maxKeysString);
            if (maxKeys < 0) {
                throw new InvalidArgumentException("max-keys",
                        "Argument max-keys must be an integer between 0 and " + Integer.MAX_VALUE);
            }
        } else {
            maxKeys = WalrusProperties.MAX_KEYS;
        }

        if (bucketList.size() > 0) {
            BucketInfo bucket = bucketList.get(0);
            BucketLogData logData = bucket.getLoggingEnabled() ? request.getLogData() : null;

            if (ctx.hasAdministrativePrivileges() || (bucket.canRead(account.getAccountNumber())
                    && (bucket.isGlobalRead() || Lookups.checkPrivilege(PolicySpec.S3_LISTBUCKETVERSIONS,
                            PolicySpec.VENDOR_S3, PolicySpec.S3_RESOURCE_BUCKET, bucketName, null)))) {

                if (logData != null) {
                    updateLogData(bucket, logData);
                    reply.setLogData(logData);
                }

                if (Contexts.lookup().hasAdministrativePrivileges()) {
                    try {
                        if (bucketHasSnapshots(bucketName)) {
                            db.rollback();
                            throw new NoSuchBucketException(bucketName);
                        }
                    } catch (Exception e) {
                        db.rollback();
                        throw new EucalyptusCloudException(e);
                    }
                }

                String prefix = request.getPrefix();
                String keyMarker = request.getKeyMarker();
                String versionMarker = request.getVersionIdMarker();
                String delimiter = request.getDelimiter();

                reply.setName(bucketName);
                reply.setIsTruncated(false);
                reply.setPrefix(prefix);
                reply.setMaxKeys(maxKeys);
                reply.setDelimiter(delimiter);
                reply.setKeyMarker(keyMarker);
                reply.setVersionIdMarker(versionMarker);

                if (bucket.isVersioningDisabled()) {
                    db.commit();
                    return reply;
                }

                if (maxKeys == 0) {
                    // No keys requested, so just return
                    reply.setKeyEntries(new ArrayList<KeyEntry>());
                    reply.setCommonPrefixesList(new ArrayList<CommonPrefixesEntry>());
                    db.commit();
                    return reply;
                }

                final int queryStrideSize = maxKeys + 1;
                EntityWrapper<ObjectInfo> dbObject = db.recast(ObjectInfo.class);

                ObjectInfo searchObj = new ObjectInfo();
                searchObj.setBucketName(bucketName);

                Criteria objCriteria = dbObject.createCriteria(ObjectInfo.class);
                objCriteria.add(Example.create(searchObj));
                objCriteria.addOrder(Order.asc("objectKey"));
                objCriteria.addOrder(Order.desc("lastModified"));
                objCriteria.setMaxResults(queryStrideSize); // add one to, hopefully, indicate truncation in one call

                // Ensure these aren't null
                keyMarker = (Strings.isNullOrEmpty(keyMarker) ? "" : keyMarker);
                prefix = (Strings.isNullOrEmpty(prefix) ? "" : prefix);
                versionMarker = (Strings.isNullOrEmpty(versionMarker) ? "" : versionMarker);

                if (!Strings.isNullOrEmpty(keyMarker)) {
                    if (!Strings.isNullOrEmpty(versionMarker)) {
                        Date resumeDate = null;
                        try {
                            ObjectInfo markerObj = new ObjectInfo();
                            markerObj.setBucketName(bucketName);
                            markerObj.setVersionId(versionMarker);
                            markerObj.setObjectKey(keyMarker);
                            ObjectInfo lastFromPrevObj = dbObject.uniqueResultEscape(markerObj);
                            if (lastFromPrevObj != null && lastFromPrevObj.getLastModified() != null) {
                                resumeDate = lastFromPrevObj.getLastModified();
                            } else {
                                dbObject.rollback();
                                throw new NoSuchEntityException("VersionIDMarker " + versionMarker
                                        + " does not match an existing object version");
                            }
                        } catch (TransactionException e) {
                            LOG.error(e);
                            dbObject.rollback();
                            throw new EucalyptusCloudException(
                                    "Next-Key-Marker or Next-Version-Id marker invalid");
                        }
                        // The result set should be exclusive of the key with the key-marker version-id-marker pair. Look for keys that lexicographically
                        // follow the version-id-marker for a given key-marker and also the keys that follow the key-marker.
                        objCriteria.add(Restrictions.or(
                                Restrictions.and(Restrictions.eq("objectKey", keyMarker),
                                        Restrictions.lt("lastModified", resumeDate)),
                                Restrictions.gt("objectKey", keyMarker)));
                    } else {
                        // The result set should be exclusive of the key-marker. key-marker could be a common prefix from a previous response. Look for keys
                        // that lexicographically follow the key-marker and don't contain the key-marker as the prefix.
                        objCriteria.add(Restrictions.and(Restrictions.gt("objectKey", keyMarker),
                                Restrictions.not(Restrictions.like("objectKey", keyMarker, MatchMode.START))));
                    }
                }

                if (!Strings.isNullOrEmpty(prefix)) {
                    objCriteria.add(Restrictions.like("objectKey", prefix, MatchMode.START));
                } else {
                    prefix = ""; // ensure not null has already been set in the reply, so this is safe
                }

                List<ObjectInfo> objectInfos = null;
                int resultKeyCount = 0;
                ArrayList<KeyEntry> keyEntries = new ArrayList<KeyEntry>();
                String nextKeyMarker = null;
                String nextVersionIdMarker = null;
                TreeSet<String> commonPrefixes = new TreeSet<String>();
                int firstResult = -1;

                // Iterate over result sets of size maxkeys + 1
                do {
                    // Start listing from the 0th element and increment the first element to be listed by the query size
                    objCriteria.setFirstResult(queryStrideSize * (++firstResult));
                    objectInfos = (List<ObjectInfo>) objCriteria.list();

                    if (objectInfos.size() > 0) {

                        for (ObjectInfo objectInfo : objectInfos) {
                            String objectKey = objectInfo.getObjectKey();

                            // Check if it will get aggregated as a commonprefix
                            if (!Strings.isNullOrEmpty(delimiter)) {
                                String[] parts = objectKey.substring(prefix.length()).split(delimiter);
                                if (parts.length > 1) {
                                    String prefixString = prefix + parts[0] + delimiter;
                                    if (!commonPrefixes.contains(prefixString)) {
                                        if (resultKeyCount == maxKeys) {
                                            // This is a new record, so we know we're truncating if this is true
                                            reply.setNextKeyMarker(nextKeyMarker);
                                            reply.setNextVersionIdMarker(nextVersionIdMarker);
                                            reply.setIsTruncated(true);
                                            resultKeyCount++;
                                            break;
                                        }

                                        commonPrefixes.add(prefixString);
                                        resultKeyCount++; // count the unique commonprefix as a single return entry

                                        // If max keys have been collected, set the next-key-marker. It might be needed for the response if the list is
                                        // truncated
                                        // If the common prefixes hit the limit set by max-keys, next-key-marker is the last common prefix and there is no
                                        // version-id-marker
                                        if (resultKeyCount == maxKeys) {
                                            nextKeyMarker = prefixString;
                                            nextVersionIdMarker = null;
                                        }
                                    }
                                    continue;
                                }
                            }

                            if (resultKeyCount == maxKeys) {
                                // This is a new (non-commonprefix) record, so we know we're truncating
                                reply.setNextKeyMarker(nextKeyMarker);
                                reply.setNextVersionIdMarker(nextVersionIdMarker);
                                reply.setIsTruncated(true);
                                resultKeyCount++;
                                break;
                            }

                            // This is either a version entry or a delete marker
                            KeyEntry keyEntry = null;
                            if (!objectInfo.getDeleted()) {
                                keyEntry = new VersionEntry();
                                ((VersionEntry) keyEntry).setEtag(objectInfo.getEtag());
                                ((VersionEntry) keyEntry).setSize(objectInfo.getSize());
                                ((VersionEntry) keyEntry).setStorageClass(objectInfo.getStorageClass());
                            } else {
                                keyEntry = new DeleteMarkerEntry();
                            }
                            keyEntry.setKey(objectKey);
                            keyEntry.setVersionId(objectInfo.getVersionId());
                            keyEntry.setIsLatest(objectInfo.getLast());
                            keyEntry.setLastModified(DateUtils.format(objectInfo.getLastModified().getTime(),
                                    DateUtils.ALT_ISO8601_DATE_PATTERN));
                            try {
                                Account ownerAccount = Accounts.lookupAccountById(objectInfo.getOwnerId());
                                keyEntry.setOwner(new CanonicalUserType(ownerAccount.getCanonicalId(),
                                        ownerAccount.getName()));
                            } catch (AuthException e) {
                                db.rollback();
                                throw new AccessDeniedException("Bucket", bucketName, logData);
                            }
                            keyEntries.add(keyEntry);

                            resultKeyCount++;

                            // If max keys have been collected, set the next- markers. They might be needed for the response if the list is truncated
                            if (resultKeyCount == maxKeys) {
                                nextKeyMarker = objectKey;
                                nextVersionIdMarker = objectInfo.getVersionId();
                            }
                        }
                    }
                    if (resultKeyCount <= maxKeys && objectInfos.size() <= maxKeys) {
                        break;
                    }
                } while (resultKeyCount <= maxKeys);

                reply.setKeyEntries(keyEntries);

                // Prefixes are already sorted, add them to the proper data structures and populate the reply
                if (!commonPrefixes.isEmpty()) {
                    ArrayList<CommonPrefixesEntry> commonPrefixesList = new ArrayList<CommonPrefixesEntry>();
                    for (String prefixEntry : commonPrefixes) {
                        commonPrefixesList.add(new CommonPrefixesEntry().add(new PrefixEntry(prefixEntry)));
                    }
                    reply.setCommonPrefixesList(commonPrefixesList);
                }
            } else {
                db.rollback();
                throw new AccessDeniedException("Bucket", bucketName, logData);
            }
        } else {
            db.rollback();
            throw new NoSuchBucketException(bucketName);
        }
        db.commit();
        return reply;
    } finally {
        if (db.isActive()) {
            db.rollback();
        }
    }
}

From source file:com.eucalyptus.walrus.WalrusFSManager.java

License:Open Source License

@Override
public ListBucketResponseType listBucket(ListBucketType request) throws WalrusException {
    ListBucketResponseType reply = (ListBucketResponseType) request.getReply();

    EntityWrapper<BucketInfo> db = EntityWrapper.get(BucketInfo.class);

    try {/*from   w  w w  .j ava  2 s  .c o m*/
        String bucketName = request.getBucket();
        BucketInfo bucketInfo = new BucketInfo(bucketName);
        bucketInfo.setHidden(false);
        List<BucketInfo> bucketList = db.queryEscape(bucketInfo);

        Context ctx = Contexts.lookup();
        Account account = ctx.getAccount();

        int maxKeys = -1;
        String maxKeysString = request.getMaxKeys();
        if (maxKeysString != null) {
            maxKeys = Integer.parseInt(maxKeysString);
            if (maxKeys < 0) {
                throw new InvalidArgumentException("max-keys",
                        "Argument max-keys must be an integer between 0 and " + Integer.MAX_VALUE);
            }
        } else {
            maxKeys = WalrusProperties.MAX_KEYS;
        }

        if (bucketList.size() > 0) {
            BucketInfo bucket = bucketList.get(0);
            BucketLogData logData = bucket.getLoggingEnabled() ? request.getLogData() : null;
            if (logData != null) {
                updateLogData(bucket, logData);
                reply.setLogData(logData);
            }

            if (Contexts.lookup().hasAdministrativePrivileges()) {
                try {
                    if (bucketHasSnapshots(bucketName)) {
                        db.rollback();
                        throw new NoSuchBucketException(bucketName);
                    }
                } catch (Exception e) {
                    db.rollback();
                    throw new InternalErrorException(e);
                }
            }

            String prefix = request.getPrefix();
            String delimiter = request.getDelimiter();
            String marker = request.getMarker();

            reply.setName(bucketName);
            reply.setIsTruncated(false);
            reply.setPrefix(prefix);
            reply.setMarker(marker);
            reply.setDelimiter(delimiter);
            reply.setMaxKeys(maxKeys);

            if (maxKeys == 0) {
                // No keys requested, so just return
                reply.setContents(new ArrayList<ListEntry>());
                reply.setCommonPrefixesList(new ArrayList<CommonPrefixesEntry>());
                db.commit();
                return reply;
            }

            final int queryStrideSize = maxKeys + 1;
            EntityWrapper<ObjectInfo> dbObject = db.recast(ObjectInfo.class);

            ObjectInfo searchObj = new ObjectInfo();
            searchObj.setBucketName(bucketName);
            searchObj.setLast(true);
            searchObj.setDeleted(false);

            Criteria objCriteria = dbObject.createCriteria(ObjectInfo.class);
            objCriteria.add(Example.create(searchObj));
            objCriteria.addOrder(Order.asc("objectKey"));
            objCriteria.setMaxResults(queryStrideSize); // add one to, hopefully, indicate truncation in one call

            if (!Strings.isNullOrEmpty(marker)) {
                // The result set should be exclusive of the marker. marker could be a common prefix from a previous response. Look for keys that
                // lexicographically follow the marker and don't contain the marker as the prefix.
                objCriteria.add(Restrictions.gt("objectKey", marker));
            } else {
                marker = "";
            }

            if (!Strings.isNullOrEmpty(prefix)) {
                objCriteria.add(Restrictions.like("objectKey", prefix, MatchMode.START));
            } else {
                prefix = "";
            }

            // Ensure not null.
            if (Strings.isNullOrEmpty(delimiter)) {
                delimiter = "";
            }

            List<ObjectInfo> objectInfos = null;
            int resultKeyCount = 0;
            ArrayList<ListEntry> contents = new ArrayList<ListEntry>(); // contents for reply
            String nextMarker = null;
            TreeSet<String> commonPrefixes = new TreeSet<String>();
            int firstResult = -1;

            // Iterate over result sets of size maxkeys + 1
            do {
                // Start listing from the 0th element and increment the first element to be listed by the query size
                objCriteria.setFirstResult(queryStrideSize * (++firstResult));
                objectInfos = (List<ObjectInfo>) objCriteria.list();

                if (objectInfos.size() > 0) {
                    for (ObjectInfo objectInfo : objectInfos) {
                        String objectKey = objectInfo.getObjectKey();

                        // Check if it will get aggregated as a commonprefix
                        if (!Strings.isNullOrEmpty(delimiter)) {
                            String[] parts = objectKey.substring(prefix.length()).split(delimiter);
                            if (parts.length > 1) {
                                String prefixString = prefix + parts[0] + delimiter;
                                if (!StringUtils.equals(prefixString, marker)
                                        && !commonPrefixes.contains(prefixString)) {
                                    if (resultKeyCount == maxKeys) {
                                        // This is a new record, so we know we're truncating if this is true
                                        reply.setNextMarker(nextMarker);
                                        reply.setIsTruncated(true);
                                        resultKeyCount++;
                                        break;
                                    }

                                    commonPrefixes.add(prefixString);
                                    resultKeyCount++; // count the unique commonprefix as a single return entry

                                    // If max keys have been collected, set the next-marker. It might be needed for the response if the list is
                                    // truncated
                                    // If the common prefixes hit the limit set by max-keys, next-marker is the last common prefix
                                    if (resultKeyCount == maxKeys) {
                                        nextMarker = prefixString;
                                    }
                                }
                                continue;
                            }
                        }

                        if (resultKeyCount == maxKeys) {
                            // This is a new (non-commonprefix) record, so we know we're truncating
                            reply.setNextMarker(nextMarker);
                            reply.setIsTruncated(true);
                            resultKeyCount++;
                            break;
                        }

                        // Process the entry as a full key listing
                        ListEntry listEntry = new ListEntry();
                        listEntry.setKey(objectKey);
                        listEntry.setEtag(objectInfo.getEtag());
                        listEntry.setLastModified(
                                DateFormatter.dateToListingFormattedString(objectInfo.getLastModified()));
                        listEntry.setStorageClass(objectInfo.getStorageClass());
                        listEntry.setSize(objectInfo.getSize());
                        listEntry.setStorageClass(objectInfo.getStorageClass());
                        try {
                            Account ownerAccount = Accounts.lookupAccountById(objectInfo.getOwnerId());
                            listEntry.setOwner(
                                    new CanonicalUser(ownerAccount.getCanonicalId(), ownerAccount.getName()));
                        } catch (AuthException e) {
                            db.rollback();
                            throw new AccessDeniedException("Bucket", bucketName, logData);
                        }
                        contents.add(listEntry);

                        resultKeyCount++;

                        // If max keys have been collected, set the next-marker. It might be needed for the response if the list is truncated
                        if (resultKeyCount == maxKeys) {
                            nextMarker = objectKey;
                        }
                    }
                }

                if (resultKeyCount <= maxKeys && objectInfos.size() <= maxKeys) {
                    break;
                }
            } while (resultKeyCount <= maxKeys);

            reply.setContents(contents);

            // Prefixes are already sorted, add them to the proper data structures and populate the reply
            if (!commonPrefixes.isEmpty()) {
                ArrayList<CommonPrefixesEntry> commonPrefixesList = new ArrayList<CommonPrefixesEntry>();
                for (String prefixEntry : commonPrefixes) {
                    commonPrefixesList.add(new CommonPrefixesEntry(prefixEntry));
                }
                reply.setCommonPrefixesList(commonPrefixesList);
            }
        } else {
            db.rollback();
            throw new NoSuchBucketException(bucketName);
        }
        db.commit();
        return reply;
    } finally {
        if (db.isActive()) {
            db.rollback();
        }
    }
}

From source file:com.eucalyptus.walrus.WalrusFSManager.java

License:Open Source License

@Override
public ListVersionsResponseType listVersions(ListVersionsType request) throws WalrusException {
    ListVersionsResponseType reply = (ListVersionsResponseType) request.getReply();
    EntityWrapper<BucketInfo> db = EntityWrapper.get(BucketInfo.class);

    try {//from   w ww .  j av  a  2 s  .c  o m
        String bucketName = request.getBucket();
        BucketInfo bucketInfo = new BucketInfo(bucketName);
        bucketInfo.setHidden(false);
        List<BucketInfo> bucketList = db.queryEscape(bucketInfo);

        Context ctx = Contexts.lookup();
        Account account = ctx.getAccount();

        int maxKeys = -1;
        String maxKeysString = request.getMaxKeys();
        if (maxKeysString != null) {
            maxKeys = Integer.parseInt(maxKeysString);
            if (maxKeys < 0) {
                throw new InvalidArgumentException("max-keys",
                        "Argument max-keys must be an integer between 0 and " + Integer.MAX_VALUE);
            }
        } else {
            maxKeys = WalrusProperties.MAX_KEYS;
        }

        if (bucketList.size() > 0) {
            BucketInfo bucket = bucketList.get(0);
            BucketLogData logData = bucket.getLoggingEnabled() ? request.getLogData() : null;

            if (logData != null) {
                updateLogData(bucket, logData);
                reply.setLogData(logData);
            }

            String prefix = request.getPrefix();
            String keyMarker = request.getKeyMarker();
            String versionMarker = request.getVersionIdMarker();
            String delimiter = request.getDelimiter();

            reply.setName(bucketName);
            reply.setIsTruncated(false);
            reply.setPrefix(prefix);
            reply.setMaxKeys(maxKeys);
            reply.setDelimiter(delimiter);
            reply.setKeyMarker(keyMarker);
            reply.setVersionIdMarker(versionMarker);

            if (bucket.isVersioningDisabled()) {
                db.commit();
                return reply;
            }

            if (maxKeys == 0) {
                // No keys requested, so just return
                reply.setKeyEntries(new ArrayList<KeyEntry>());
                reply.setCommonPrefixesList(new ArrayList<CommonPrefixesEntry>());
                db.commit();
                return reply;
            }

            final int queryStrideSize = maxKeys + 1;
            EntityWrapper<ObjectInfo> dbObject = db.recast(ObjectInfo.class);

            ObjectInfo searchObj = new ObjectInfo();
            searchObj.setBucketName(bucketName);

            Criteria objCriteria = dbObject.createCriteria(ObjectInfo.class);
            objCriteria.add(Example.create(searchObj));
            objCriteria.addOrder(Order.asc("objectKey"));
            objCriteria.addOrder(Order.desc("lastModified"));
            objCriteria.setMaxResults(queryStrideSize); // add one to, hopefully, indicate truncation in one call

            // Ensure these aren't null
            keyMarker = (Strings.isNullOrEmpty(keyMarker) ? "" : keyMarker);
            prefix = (Strings.isNullOrEmpty(prefix) ? "" : prefix);
            versionMarker = (Strings.isNullOrEmpty(versionMarker) ? "" : versionMarker);

            if (!Strings.isNullOrEmpty(keyMarker)) {
                if (!Strings.isNullOrEmpty(versionMarker)) {
                    Date resumeDate = null;
                    try {
                        ObjectInfo markerObj = new ObjectInfo();
                        markerObj.setBucketName(bucketName);
                        markerObj.setVersionId(versionMarker);
                        markerObj.setObjectKey(keyMarker);
                        ObjectInfo lastFromPrevObj = dbObject.uniqueResultEscape(markerObj);
                        if (lastFromPrevObj != null && lastFromPrevObj.getLastModified() != null) {
                            resumeDate = lastFromPrevObj.getLastModified();
                        } else {
                            dbObject.rollback();
                            throw new NoSuchEntityException("VersionIDMarker " + versionMarker
                                    + " does not match an existing object version");
                        }
                    } catch (TransactionException e) {
                        LOG.error(e);
                        dbObject.rollback();
                        throw new InternalErrorException("Next-Key-Marker or Next-Version-Id marker invalid");
                    }
                    // The result set should be exclusive of the key with the key-marker version-id-marker pair. Look for keys that lexicographically
                    // follow the version-id-marker for a given key-marker and also the keys that follow the key-marker.
                    objCriteria.add(Restrictions.or(
                            Restrictions.and(Restrictions.eq("objectKey", keyMarker),
                                    Restrictions.lt("lastModified", resumeDate)),
                            Restrictions.gt("objectKey", keyMarker)));
                } else {
                    // The result set should be exclusive of the key-marker. key-marker could be a common prefix from a previous response. Look for keys
                    // that lexicographically follow the key-marker and don't contain the key-marker as the prefix.
                    objCriteria.add(Restrictions.gt("objectKey", keyMarker));
                }
            }

            if (!Strings.isNullOrEmpty(prefix)) {
                objCriteria.add(Restrictions.like("objectKey", prefix, MatchMode.START));
            } else {
                prefix = ""; // ensure not null has already been set in the reply, so this is safe
            }

            List<ObjectInfo> objectInfos = null;
            int resultKeyCount = 0;
            ArrayList<KeyEntry> keyEntries = new ArrayList<KeyEntry>();
            String nextKeyMarker = null;
            String nextVersionIdMarker = null;
            TreeSet<String> commonPrefixes = new TreeSet<String>();
            int firstResult = -1;

            // Iterate over result sets of size maxkeys + 1
            do {
                // Start listing from the 0th element and increment the first element to be listed by the query size
                objCriteria.setFirstResult(queryStrideSize * (++firstResult));
                objectInfos = (List<ObjectInfo>) objCriteria.list();

                if (objectInfos.size() > 0) {

                    for (ObjectInfo objectInfo : objectInfos) {
                        String objectKey = objectInfo.getObjectKey();

                        // Check if it will get aggregated as a commonprefix
                        if (!Strings.isNullOrEmpty(delimiter)) {
                            String[] parts = objectKey.substring(prefix.length()).split(delimiter);
                            if (parts.length > 1) {
                                String prefixString = prefix + parts[0] + delimiter;
                                if (!StringUtils.equals(prefixString, keyMarker)
                                        && !commonPrefixes.contains(prefixString)) {
                                    if (resultKeyCount == maxKeys) {
                                        // This is a new record, so we know we're truncating if this is true
                                        reply.setNextKeyMarker(nextKeyMarker);
                                        reply.setNextVersionIdMarker(nextVersionIdMarker);
                                        reply.setIsTruncated(true);
                                        resultKeyCount++;
                                        break;
                                    }

                                    commonPrefixes.add(prefixString);
                                    resultKeyCount++; // count the unique commonprefix as a single return entry

                                    // If max keys have been collected, set the next-key-marker. It might be needed for the response if the list is
                                    // truncated
                                    // If the common prefixes hit the limit set by max-keys, next-key-marker is the last common prefix and there is no
                                    // version-id-marker
                                    if (resultKeyCount == maxKeys) {
                                        nextKeyMarker = prefixString;
                                        nextVersionIdMarker = null;
                                    }
                                }
                                continue;
                            }
                        }

                        if (resultKeyCount == maxKeys) {
                            // This is a new (non-commonprefix) record, so we know we're truncating
                            reply.setNextKeyMarker(nextKeyMarker);
                            reply.setNextVersionIdMarker(nextVersionIdMarker);
                            reply.setIsTruncated(true);
                            resultKeyCount++;
                            break;
                        }

                        // This is either a version entry or a delete marker
                        KeyEntry keyEntry = null;
                        if (!objectInfo.getDeleted()) {
                            keyEntry = new VersionEntry();
                            ((VersionEntry) keyEntry).setEtag(objectInfo.getEtag());
                            ((VersionEntry) keyEntry).setSize(objectInfo.getSize());
                            ((VersionEntry) keyEntry).setStorageClass(objectInfo.getStorageClass());
                        } else {
                            keyEntry = new DeleteMarkerEntry();
                        }
                        keyEntry.setKey(objectKey);
                        keyEntry.setVersionId(objectInfo.getVersionId());
                        keyEntry.setIsLatest(objectInfo.getLast());
                        keyEntry.setLastModified(
                                DateFormatter.dateToListingFormattedString(objectInfo.getLastModified()));
                        try {
                            Account ownerAccount = Accounts.lookupAccountById(objectInfo.getOwnerId());
                            keyEntry.setOwner(
                                    new CanonicalUser(ownerAccount.getCanonicalId(), ownerAccount.getName()));
                        } catch (AuthException e) {
                            db.rollback();
                            throw new AccessDeniedException("Bucket", bucketName, logData);
                        }
                        keyEntries.add(keyEntry);

                        resultKeyCount++;

                        // If max keys have been collected, set the next- markers. They might be needed for the response if the list is truncated
                        if (resultKeyCount == maxKeys) {
                            nextKeyMarker = objectKey;
                            nextVersionIdMarker = objectInfo.getVersionId();
                        }
                    }
                }
                if (resultKeyCount <= maxKeys && objectInfos.size() <= maxKeys) {
                    break;
                }
            } while (resultKeyCount <= maxKeys);

            reply.setKeyEntries(keyEntries);

            // Prefixes are already sorted, add them to the proper data structures and populate the reply
            if (!commonPrefixes.isEmpty()) {
                ArrayList<CommonPrefixesEntry> commonPrefixesList = new ArrayList<CommonPrefixesEntry>();
                for (String prefixEntry : commonPrefixes) {
                    commonPrefixesList.add(new CommonPrefixesEntry(prefixEntry));
                }
                reply.setCommonPrefixesList(commonPrefixesList);
            }
        } else {
            db.rollback();
            throw new NoSuchBucketException(bucketName);
        }
        db.commit();
        return reply;
    } finally {
        if (db.isActive()) {
            db.rollback();
        }
    }
}

From source file:com.evolveum.midpoint.repo.sql.helpers.LookupTableHelper.java

License:Apache License

public <T extends ObjectType> void updateLoadedLookupTable(PrismObject<T> object,
        Collection<SelectorOptions<GetOperationOptions>> options, Session session) throws SchemaException {
    if (!SelectorOptions.hasToLoadPath(LookupTableType.F_ROW, options)) {
        return;/*from ww w. j  a va 2 s .c  o m*/
    }

    LOGGER.debug("Loading lookup table data.");

    GetOperationOptions getOption = findLookupTableGetOption(options);
    RelationalValueSearchQuery queryDef = getOption == null ? null : getOption.getRelationalValueSearchQuery();
    Criteria criteria = setupLookupTableRowsQuery(session, queryDef, object.getOid());
    if (queryDef != null && queryDef.getPaging() != null) {
        ObjectPaging paging = queryDef.getPaging();

        if (paging.getOffset() != null) {
            criteria.setFirstResult(paging.getOffset());
        }
        if (paging.getMaxSize() != null) {
            criteria.setMaxResults(paging.getMaxSize());
        }

        ItemPath orderByPath = paging.getOrderBy();
        if (paging.getDirection() != null && orderByPath != null && !orderByPath.isEmpty()) {
            if (orderByPath.size() > 1 || !(orderByPath.first() instanceof NameItemPathSegment)) {
                throw new SchemaException("OrderBy has to consist of just one naming segment");
            }
            String orderBy = ((NameItemPathSegment) (orderByPath.first())).getName().getLocalPart();
            switch (paging.getDirection()) {
            case ASCENDING:
                criteria.addOrder(Order.asc(orderBy));
                break;
            case DESCENDING:
                criteria.addOrder(Order.desc(orderBy));
                break;
            }
        }
    }

    List<RLookupTableRow> rows = criteria.list();
    if (rows == null || rows.isEmpty()) {
        return;
    }

    LookupTableType lookup = (LookupTableType) object.asObjectable();
    List<LookupTableRowType> jaxbRows = lookup.getRow();
    for (RLookupTableRow row : rows) {
        LookupTableRowType jaxbRow = row.toJAXB();
        jaxbRows.add(jaxbRow);
    }
}

From source file:com.evolveum.midpoint.repo.sql.query.custom.ShadowQueryWithDisjunction.java

License:Apache License

public <T extends ObjectType> Criteria updatePagingAndSorting(Criteria query, Class<T> type,
        ObjectPaging paging) {/*w w  w .  ja  va  2s.c  om*/
    if (paging == null) {
        return query;
    }
    if (paging.getOffset() != null) {
        query = query.setFirstResult(paging.getOffset());
    }
    if (paging.getMaxSize() != null) {
        query = query.setMaxResults(paging.getMaxSize());
    }

    if (paging.getDirection() == null && paging.getOrderBy() == null) {
        return query;
    }

    QueryDefinitionRegistry registry = QueryDefinitionRegistry.getInstance();
    // PropertyPath path = new
    // XPathHolder(paging.getOrderBy()).toPropertyPath();
    if (paging.getOrderBy() == null) {
        LOGGER.warn("Ordering by property path with size not equal 1 is not supported '" + paging.getOrderBy()
                + "'.");
        return query;
    }
    EntityDefinition definition = registry.findDefinition(type, null, EntityDefinition.class);
    Definition def = definition.findDefinition(paging.getOrderBy(), Definition.class);
    if (def == null) {
        LOGGER.warn("Unknown path '" + paging.getOrderBy() + "', couldn't find definition for it, "
                + "list will not be ordered by it.");
        return query;
    }

    String propertyName = def.getJpaName();
    if (PolyString.class.equals(def.getJaxbType())) {
        propertyName += ".orig";
    }

    if (paging.getDirection() != null) {
        switch (paging.getDirection()) {
        case ASCENDING:
            query = query.addOrder(Order.asc(propertyName));
            break;
        case DESCENDING:
            query = query.addOrder(Order.desc(propertyName));
            break;
        }
    } else {
        query = query.addOrder(Order.asc(propertyName));
    }

    return query;
}