use of org.structr.core.GraphObject in project structr by structr.
the class BatchExpression method evaluate.
@Override
public Object evaluate(final ActionContext ctx, final GraphObject entity) throws FrameworkException, UnlicensedException {
if (batchExpression == null || sizeExpression == null) {
return ERROR_MESSAGE_SLICE;
}
final Object value = sizeExpression.evaluate(ctx, entity);
if (value != null && value instanceof Number) {
// store batch size for children to use
this.batchSize = ((Number) value).intValue();
// initialize holders to store results from worker thread (must be final)
final StaticValue<FrameworkException> exception = new StaticValue<>(null);
final StaticValue result = new StaticValue(null);
final Thread workerThread = new Thread(() -> {
try {
result.set(null, batchExpression.evaluate(ctx, entity));
} catch (FrameworkException fex) {
exception.set(null, fex);
}
});
workerThread.start();
try {
workerThread.join();
} catch (Throwable t) {
t.printStackTrace();
}
if (exception.get(null) != null) {
throw exception.get(null);
}
// result holder
return result.get(null);
} else {
throw new FrameworkException(422, "Error in batch(): invalid batch size, expecting number.");
}
}
use of org.structr.core.GraphObject in project structr by structr.
the class EachExpression method evaluate.
@Override
public Object evaluate(final ActionContext ctx, final GraphObject entity) throws FrameworkException, UnlicensedException {
if (listExpression == null) {
return ERROR_MESSAGE_EACH;
}
Object listSource = listExpression.evaluate(ctx, entity);
if (listSource != null && listSource.getClass().isArray()) {
listSource = Arrays.asList((Object[]) listSource);
}
if (listSource != null && listSource instanceof Iterable) {
final Iterable source = (Iterable) listSource;
final Object oldDataValue = ctx.getConstant("data");
if (isBatched()) {
final App app = StructrApp.getInstance(ctx.getSecurityContext());
final Iterator iterator = source.iterator();
int count = 0;
while (iterator.hasNext()) {
try (final Tx tx = app.tx()) {
while (iterator.hasNext()) {
ctx.setConstant("data", iterator.next());
eachExpression.evaluate(ctx, entity);
if ((++count % getBatchSize()) == 0) {
break;
}
}
tx.success();
} catch (FrameworkException fex) {
logger.warn(fex.getMessage());
logger.warn(fex.toString());
fex.printStackTrace();
}
logger.debug("Committing batch after {} objects", count);
// reset count
count = 0;
}
} else {
for (Object obj : source) {
ctx.setConstant("data", obj);
eachExpression.evaluate(ctx, entity);
}
}
// restore previous value of data keyword
ctx.setConstant("data", oldDataValue);
}
return null;
}
use of org.structr.core.GraphObject in project structr by structr.
the class FunctionExpression method evaluate.
@Override
public Object evaluate(final ActionContext ctx, final GraphObject entity) throws FrameworkException, UnlicensedException {
final ArrayList<Object> results = new ArrayList<>();
for (Expression expr : expressions) {
final Object result = expr.evaluate(ctx, entity);
results.add(result);
}
if (results.isEmpty() && expressions.size() > 0) {
return function.usage(ctx.isJavaScriptContext());
}
if (function instanceof BatchableFunction) {
// enable batching if batchable function is found
((BatchableFunction) function).setBatchSize(getBatchSize());
((BatchableFunction) function).setBatched(isBatched());
// batchable functions must create their own transaction when in batched mode
return function.apply(ctx, entity, results.toArray());
} else if (isBatched()) {
// when in batched mode,
try (final Tx tx = StructrApp.getInstance(ctx.getSecurityContext()).tx()) {
final Object result = function.apply(ctx, entity, results.toArray());
tx.success();
return result;
}
} else {
// default execution path: enclosing transaction exists, no batching
return function.apply(ctx, entity, results.toArray());
}
}
use of org.structr.core.GraphObject in project structr by structr.
the class CypherQueryProperty method getProperty.
@Override
public List<GraphObject> getProperty(SecurityContext securityContext, GraphObject obj, boolean applyConverter, Predicate<GraphObject> predicate) {
if (obj instanceof AbstractNode) {
try {
final String query = Scripting.replaceVariables(new ActionContext(securityContext), obj, this.format);
final Map<String, Object> parameters = new LinkedHashMap<>();
parameters.put("id", obj.getUuid());
parameters.put("type", obj.getType());
return StructrApp.getInstance(securityContext).command(CypherQueryCommand.class).execute(query, parameters);
} catch (Throwable t) {
logger.warn("", t);
}
}
return null;
}
use of org.structr.core.GraphObject in project structr by structr.
the class EndNode method getSearchAttribute.
@Override
public SearchAttribute getSearchAttribute(SecurityContext securityContext, Occurrence occur, T searchValue, boolean exactMatch, final Query query) {
final Predicate<GraphObject> predicate = query != null ? query.toPredicate() : null;
final SourceSearchAttribute attr = new SourceSearchAttribute(occur);
final Set<GraphObject> intersectionResult = new LinkedHashSet<>();
boolean alreadyAdded = false;
if (searchValue != null && !StringUtils.isBlank(searchValue.toString())) {
if (exactMatch) {
switch(occur) {
case REQUIRED:
if (!alreadyAdded) {
// the first result is the basis of all subsequent intersections
intersectionResult.addAll(getRelatedNodesReverse(securityContext, searchValue, declaringClass, predicate));
// the next additions are intersected with this one
alreadyAdded = true;
} else {
intersectionResult.retainAll(getRelatedNodesReverse(securityContext, searchValue, declaringClass, predicate));
}
break;
case OPTIONAL:
intersectionResult.addAll(getRelatedNodesReverse(securityContext, searchValue, declaringClass, predicate));
break;
case FORBIDDEN:
break;
}
} else {
intersectionResult.addAll(getRelatedNodesReverse(securityContext, searchValue, declaringClass, predicate));
}
attr.setResult(intersectionResult);
} else {
// value in the given field
return new EmptySearchAttribute(this, null);
}
return attr;
}
Aggregations