use of com.yahoo.elide.core.exceptions.InvalidValueException in project elide by yahoo.
the class PaginationImpl method parseQueryParams.
/**
* Given json-api paging params, generate page and pageSize values from query params.
*
* @param entityClass The collection type.
* @param queryParams The page queryParams.
* @param elideSettings Elide settings containing pagination default limits
* @return The new Pagination object.
* @throws InvalidValueException invalid query parameter
*/
public static PaginationImpl parseQueryParams(Type<?> entityClass, final MultivaluedMap<String, String> queryParams, ElideSettings elideSettings) throws InvalidValueException {
if (queryParams.isEmpty()) {
return getDefaultPagination(entityClass, elideSettings);
}
final Map<PaginationKey, Integer> pageData = new HashMap<>();
queryParams.entrySet().forEach(paramEntry -> {
final String queryParamKey = paramEntry.getKey();
if (PAGE_KEYS.containsKey(queryParamKey)) {
PaginationKey paginationKey = PAGE_KEYS.get(queryParamKey);
if (paginationKey.equals(PaginationKey.totals)) {
// page[totals] is a valueless parameter, use value of 0 just so that its presence can
// be recorded in the map
pageData.put(paginationKey, 0);
} else {
final String value = paramEntry.getValue().get(0);
try {
int intValue = Integer.parseInt(value, 10);
pageData.put(paginationKey, intValue);
} catch (NumberFormatException e) {
throw new InvalidValueException("page values must be integers");
}
}
} else if (queryParamKey.startsWith("page[")) {
throw new InvalidValueException("Invalid Pagination Parameter. Accepted values are " + PAGE_KEYS_CSV);
}
});
return getPagination(entityClass, pageData, elideSettings);
}
use of com.yahoo.elide.core.exceptions.InvalidValueException in project elide by yahoo.
the class SortingImpl method getValidSortingRules.
/**
* Given the sorting rules validate sorting rules against the entities bound to the entityClass.
* @param entityClass The root class for sorting (eg. /book?sort=-title this would be package.Book)
* @param attributes The attributes that are being requested for the sorted model
* @param dictionary The elide entity dictionary
* @param <T> The entityClass
* @return The valid sorting rules - validated through the entity dictionary, or empty dictionary
* @throws InvalidValueException when sorting values are not valid for the jpa entity
*/
private <T> Map<Path, SortOrder> getValidSortingRules(final Type<T> entityClass, final Set<Attribute> attributes, final EntityDictionary dictionary) throws InvalidValueException {
Map<Path, SortOrder> returnMap = new LinkedHashMap<>();
for (Map.Entry<String, SortOrder> entry : replaceIdRule(dictionary.getIdFieldName(entityClass)).entrySet()) {
String dotSeparatedPath = entry.getKey();
SortOrder order = entry.getValue();
Path path;
if (dotSeparatedPath.contains(".")) {
// Creating a path validates that the dot separated path is valid.
path = new Path(entityClass, dictionary, dotSeparatedPath);
} else {
Attribute attribute = attributes.stream().filter(attr -> attr.getName().equals(dotSeparatedPath) || attr.getAlias().equals(dotSeparatedPath)).findFirst().orElse(null);
if (attribute == null) {
path = new Path(entityClass, dictionary, dotSeparatedPath);
} else {
path = new Path(entityClass, dictionary, attribute.getName(), attribute.getAlias(), attribute.getArguments());
}
}
if (!isValidSortRulePath(path, dictionary)) {
throw new InvalidValueException("Cannot sort across a to-many relationship: " + path.getFieldPath());
}
returnMap.put(path, order);
}
return returnMap;
}
use of com.yahoo.elide.core.exceptions.InvalidValueException in project elide by yahoo.
the class PersistentResourceFetcher method upsertObject.
/**
* updates or creates existing/new entities.
* @param entity Resource entity
* @param context The request context
* @return {@link PersistentResource} object
*/
private PersistentResource upsertObject(Entity entity, Environment context) {
Set<Entity.Attribute> attributes = entity.getAttributes();
Optional<String> id = entity.getId();
RequestScope requestScope = entity.getRequestScope();
PersistentResource upsertedResource;
EntityDictionary dictionary = requestScope.getDictionary();
PersistentResource parentResource = entity.getParentResource().map(Entity::toPersistentResource).orElse(null);
if (!id.isPresent()) {
// If the ID is generated, it is safe to assign a temporary UUID. Otherwise the client must provide one.
if (dictionary.isIdGenerated(entity.getEntityClass())) {
// Assign a temporary UUID.
entity.setId();
id = entity.getId();
}
upsertedResource = PersistentResource.createObject(parentResource, context.field.getName(), entity.getEntityClass(), requestScope, id);
} else {
try {
Set<PersistentResource> loadedResource = fetchObject(requestScope, entity.getProjection(), Optional.of(Collections.singletonList(id.get()))).getPersistentResources();
upsertedResource = loadedResource.iterator().next();
// The ID doesn't exist yet. Let's create the object.
} catch (InvalidObjectIdentifierException | InvalidValueException e) {
upsertedResource = PersistentResource.createObject(parentResource, context.field.getName(), entity.getEntityClass(), requestScope, id);
}
}
return updateAttributes(upsertedResource, entity, attributes);
}
use of com.yahoo.elide.core.exceptions.InvalidValueException in project elide by yahoo.
the class RootCollectionFetchQueryBuilder method build.
/**
* Constructs a query that fetches a root collection.
*
* @return the constructed query
*/
@Override
public Query build() {
Type<?> entityClass = this.entityProjection.getType();
String entityName = entityClass.getCanonicalName();
String entityAlias = getTypeAlias(entityClass);
Query query;
FilterExpression filterExpression = entityProjection.getFilterExpression();
if (filterExpression != null) {
PredicateExtractionVisitor extractor = new PredicateExtractionVisitor();
Collection<FilterPredicate> predicates = filterExpression.accept(extractor);
// Build the WHERE clause
String filterClause = WHERE + new FilterTranslator(dictionary).apply(filterExpression, USE_ALIAS);
// Build the JOIN clause
String joinClause = getJoinClauseFromFilters(filterExpression) + getJoinClauseFromSort(entityProjection.getSorting()) + extractToOneMergeJoins(entityClass, entityAlias);
boolean requiresDistinct = entityProjection.getPagination() != null && containsOneToMany(filterExpression);
boolean sortOverRelationship = entityProjection.getSorting() != null && entityProjection.getSorting().getSortingPaths().keySet().stream().anyMatch(path -> path.getPathElements().size() > 1);
if (requiresDistinct && sortOverRelationship) {
// SQL does not support distinct and order by on columns which are not selected
throw new InvalidValueException("Combination of pagination, sorting over relationship and" + " filtering over toMany relationships unsupported");
}
query = session.createQuery(SELECT + (requiresDistinct ? DISTINCT : "") + entityAlias + FROM + entityName + AS + entityAlias + SPACE + joinClause + SPACE + filterClause + SPACE + getSortClause(entityProjection.getSorting()));
// Fill in the query parameters
supplyFilterQueryParameters(query, predicates);
} else {
query = session.createQuery(SELECT + entityAlias + FROM + entityName + AS + entityAlias + SPACE + getJoinClauseFromSort(entityProjection.getSorting()) + extractToOneMergeJoins(entityClass, entityAlias) + SPACE + getSortClause(entityProjection.getSorting()));
}
addPaginationToQuery(query);
return query;
}
use of com.yahoo.elide.core.exceptions.InvalidValueException in project elide by yahoo.
the class AddressSerde method deserialize.
@Override
public Address deserialize(String val) {
byte[] decodedBytes = Base64.getDecoder().decode(val);
String decodedString = new String(decodedBytes);
Matcher matcher = ADDRESS_PATTERN.matcher(decodedString);
if (!matcher.matches()) {
throw new InvalidValueException(decodedString);
}
long number = Long.parseLong(matcher.group(1));
String street = matcher.group(2);
long zipCode = Long.parseLong(matcher.group(3));
return new Address(number, street, zipCode);
}
Aggregations