/** * Return annotation from class, parents or package. * * @param record the record * @param annotationClass the annotation class * @param <A> genericClass * @return the annotation */ public <A extends Annotation> A getAnnotation(PersistentResource record, Class<A> annotationClass) { return getAnnotation(record.getResourceClass(), annotationClass); }
/** * Return annotation from class, parents or package. * * @param record the record * @param annotationClass the annotation class * @param <A> genericClass * @return the annotation */ public <A extends Annotation> A getAnnotation(PersistentResource record, Class<A> annotationClass) { return getAnnotation(record.getResourceClass(), annotationClass); }
/** * Set resource ID. * * @param id resource id */ public void setId(String id) { this.setValue(dictionary.getIdFieldName(getResourceClass()), id); }
/** * Set resource ID. * * @param id resource id */ public void setId(String id) { this.setValue(dictionary.getIdFieldName(getResourceClass()), id); }
@Override public void onNext(CRUDEvent event) { ArrayList<LifeCycleHook> hooks = new ArrayList<>(); //Collect all the hooks that are keyed on a specific field. hooks.addAll(dictionary.getTriggers( event.getResource().getResourceClass(), this.annotation, event.getFieldName())); //Collect all the hooks that are keyed on any field. if (!event.getFieldName().isEmpty()) { hooks.addAll(dictionary.getTriggers(event.getResource().getResourceClass(), this.annotation)); } try { //Invoke all the hooks hooks.forEach((hook) -> { hook.execute( event.getResource().getObject(), event.getResource().getRequestScope(), event.getChanges()); }); } catch (RuntimeException e) { exception = Optional.of(e); if (throwsExceptions) { throw e; } } }
@Override public Object processFetch(Environment context, PersistentResourceFetcher fetcher) { EntityDictionary dictionary = context.requestScope.getDictionary(); Class parentClass = context.parentResource.getResourceClass(); String fieldName = context.field.getName(); String idFieldName = dictionary.getIdFieldName(parentClass); if (dictionary.isAttribute(parentClass, fieldName)) { /* fetch attribute properties */ Object attribute = context.parentResource.getAttribute(fieldName); if (attribute instanceof Map) { return ((Map<Object, Object>) attribute).entrySet().stream() .map(MapEntryContainer::new) .collect(Collectors.toList()); } return attribute; } if (dictionary.isRelation(parentClass, fieldName)) { /* fetch relationship properties */ boolean generateTotals = requestContainsPageInfo(context.field); return fetcher.fetchRelationship(context, context.parentResource, fieldName, context.ids, context.offset, context.first, context.sort, context.filters, generateTotals); } if (Objects.equals(idFieldName, fieldName)) { return new DeferredId(context.parentResource); } throw new BadRequestException("Unrecognized object: " + fieldName + " for: " + parentClass.getName() + " in node"); } }
@Override public Object processFetch(Environment context, PersistentResourceFetcher fetcher) { EntityDictionary dictionary = context.requestScope.getDictionary(); Class parentClass = context.parentResource.getResourceClass(); String fieldName = context.field.getName(); String idFieldName = dictionary.getIdFieldName(parentClass); if (dictionary.isAttribute(parentClass, fieldName)) { /* fetch attribute properties */ Object attribute = context.parentResource.getAttribute(fieldName); if (attribute instanceof Map) { return ((Map<Object, Object>) attribute).entrySet().stream() .map(MapEntryContainer::new) .collect(Collectors.toList()); } return attribute; } if (dictionary.isRelation(parentClass, fieldName)) { /* fetch relationship properties */ boolean generateTotals = requestContainsPageInfo(context.field); return fetcher.fetchRelationship(context, context.parentResource, fieldName, context.ids, context.offset, context.first, context.sort, context.filters, generateTotals); } if (Objects.equals(idFieldName, fieldName)) { return new DeferredId(context.parentResource); } throw new BadRequestException("Unrecognized object: " + fieldName + " for: " + parentClass.getName() + " in node"); } }
@Override public void onNext(CRUDEvent event) { ArrayList<LifeCycleHook> hooks = new ArrayList<>(); //Collect all the hooks that are keyed on a specific field. hooks.addAll(dictionary.getTriggers( event.getResource().getResourceClass(), this.annotation, event.getFieldName())); //Collect all the hooks that are keyed on any field. if (!event.getFieldName().isEmpty()) { hooks.addAll(dictionary.getTriggers(event.getResource().getResourceClass(), this.annotation)); } try { //Invoke all the hooks hooks.forEach((hook) -> { hook.execute( event.getResource().getObject(), event.getResource().getRequestScope(), event.getChanges()); }); } catch (RuntimeException e) { exception = Optional.of(e); if (throwsExceptions) { throw e; } } }
/** * Audit an action on an entity. * * @param action the action * @param changeSpec the change that occurred */ protected void auditClass(Audit.Action action, ChangeSpec changeSpec) { Audit[] annotations = getResourceClass().getAnnotationsByType(Audit.class); if (annotations == null) { return; } for (Audit annotation : annotations) { for (Audit.Action auditAction : annotation.action()) { if (auditAction == action) { // compare object reference LogMessage message = new LogMessage(annotation, this, Optional.ofNullable(changeSpec)); getRequestScope().getAuditLogger().log(message); } } } }
/** * Audit an action on an entity. * * @param action the action * @param changeSpec the change that occurred */ protected void auditClass(Audit.Action action, ChangeSpec changeSpec) { Audit[] annotations = getResourceClass().getAnnotationsByType(Audit.class); if (annotations == null) { return; } for (Audit annotation : annotations) { for (Audit.Action auditAction : annotation.action()) { if (auditAction == action) { // compare object reference LogMessage message = new LogMessage(annotation, this, Optional.ofNullable(changeSpec)); getRequestScope().getAuditLogger().log(message); } } } }
/** * Update attribute in existing resource. * * @param fieldName the field name * @param newVal the new val * @return true if object updated, false otherwise */ public boolean updateAttribute(String fieldName, Object newVal) { Class<?> fieldClass = dictionary.getType(getResourceClass(), fieldName); newVal = coerce(newVal, fieldName, fieldClass); Object val = getValueUnchecked(fieldName); checkFieldAwareDeferPermissions(UpdatePermission.class, fieldName, newVal, val); if (!Objects.equals(val, newVal)) { this.setValueChecked(fieldName, newVal); this.markDirty(); //Hooks for customize logic for setAttribute/Relation if (dictionary.isAttribute(obj.getClass(), fieldName)) { transaction.setAttribute(obj, fieldName, newVal, requestScope); } return true; } return false; }
/** * Update attribute in existing resource. * * @param fieldName the field name * @param newVal the new val * @return true if object updated, false otherwise */ public boolean updateAttribute(String fieldName, Object newVal) { Class<?> fieldClass = dictionary.getType(getResourceClass(), fieldName); newVal = coerce(newVal, fieldName, fieldClass); Object val = getValueUnchecked(fieldName); checkFieldAwareDeferPermissions(UpdatePermission.class, fieldName, newVal, val); if (!Objects.equals(val, newVal)) { this.setValueChecked(fieldName, newVal); this.markDirty(); //Hooks for customize logic for setAttribute/Relation if (dictionary.isAttribute(obj.getClass(), fieldName)) { transaction.setAttribute(obj, fieldName, newVal, requestScope); } return true; } return false; }
inverseResource.setValueChecked(inverseName, Collections.singleton(this.getObject())); } else if (inverseType.isAssignableFrom(this.getResourceClass())) { inverseResource.setValueChecked(inverseName, this.getObject()); } else {
if (dictionary.cascadeDeletes(getResourceClass(), relationName)) { continue; String inverseRelationName = dictionary.getRelationInverse(getResourceClass(), relationName); if (!"".equals(inverseRelationName)) { for (PersistentResource inverseResource : getRelationCheckedUnfiltered(relationName)) {
inverseResource.setValueChecked(inverseName, Collections.singleton(this.getObject())); } else if (inverseType.isAssignableFrom(this.getResourceClass())) { inverseResource.setValueChecked(inverseName, this.getObject()); } else {
if (dictionary.cascadeDeletes(getResourceClass(), relationName)) { continue; String inverseRelationName = dictionary.getRelationInverse(getResourceClass(), relationName); if (!"".equals(inverseRelationName)) { for (PersistentResource inverseResource : getRelationCheckedUnfiltered(relationName)) {
} else if (inverseType.isAssignableFrom(this.getResourceClass())) { inverseResource.nullValue(inverseField, this); } else {
} else if (inverseType.isAssignableFrom(this.getResourceClass())) { inverseResource.nullValue(inverseField, this); } else {
/** * Audit an action on field. * * @param changeSpec Change spec for audit */ protected void auditField(final ChangeSpec changeSpec) { final String fieldName = changeSpec.getFieldName(); Audit[] annotations = dictionary.getAttributeOrRelationAnnotations(getResourceClass(), Audit.class, fieldName ); if (annotations == null || annotations.length == 0) { // Default to class-level annotation for action auditClass(Audit.Action.UPDATE, changeSpec); return; } for (Audit annotation : annotations) { if (annotation.action().length == 1 && annotation.action()[0] == Audit.Action.UPDATE) { LogMessage message = new LogMessage(annotation, this, Optional.of(changeSpec)); getRequestScope().getAuditLogger().log(message); } else { throw new InvalidSyntaxException("Only Audit.Action.UPDATE is allowed on fields."); } } }
/** * Audit an action on field. * * @param changeSpec Change spec for audit */ protected void auditField(final ChangeSpec changeSpec) { final String fieldName = changeSpec.getFieldName(); Audit[] annotations = dictionary.getAttributeOrRelationAnnotations(getResourceClass(), Audit.class, fieldName ); if (annotations == null || annotations.length == 0) { // Default to class-level annotation for action auditClass(Audit.Action.UPDATE, changeSpec); return; } for (Audit annotation : annotations) { if (annotation.action().length == 1 && annotation.action()[0] == Audit.Action.UPDATE) { LogMessage message = new LogMessage(annotation, this, Optional.of(changeSpec)); getRequestScope().getAuditLogger().log(message); } else { throw new InvalidSyntaxException("Only Audit.Action.UPDATE is allowed on fields."); } } }