Spring MVC ResponseBodyAdvice for add header in specify return type - spring

I have a method in my Controller that return list of object .
This method support paging result and add HttpHeaders.LINK to HttpHeader for support Pagination Discoverability.
I be forced to add this lines for support that .
I think maybe ControllerAdvice or ResponseAdvice support to do this in that .
How can i check return of method? and if return type is QueryResult then add HttpHeader to that?
#RequestMapping(value = "/list", method = RequestMethod.GET)
public ResponseEntity<QueryResult<Personel>> search(
SearchOption searchOption) {
QueryResult<Personel> list=ipersonelService.search();
HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(list, "/api/personel");
return new ResponseEntity<>(list, headers, HttpStatus.OK);
}
this class generate Headers by Paging class
public static HttpHeaders generatePaginationHttpHeaders(QueryResult page, String baseUrl)
throws URISyntaxException {
HttpHeaders headers = new HttpHeaders();
headers.add("X-Total-Count", "" + page.getTotalElements());
String link = "";
if ((page.getPageNumber() + 1) < page.getTotalPages()) {
link = "<" + generateUri(baseUrl, page.getPageNumber() + 1, page.getPageSize()) + ">; rel=\"next\",";
}
// prev link
if ((page.getPageNumber()) > 0) {
link += "<" + generateUri(baseUrl, page.getPageNumber() - 1, page.getPageSize()) + ">; rel=\"prev\",";
}
// last and first link
int lastPage = 0;
if (page.getTotalPages() > 0) {
lastPage = page.getTotalPages() - 1;
}
link += "<" + generateUri(baseUrl, lastPage, page.getPageSize()) + ">; rel=\"last\",";
link += "<" + generateUri(baseUrl, 0, page.getPageSize()) + ">; rel=\"first\"";
headers.add(HttpHeaders.LINK, link);
return headers;
}
private static String generateUri(String baseUrl, int page, int size) throws URISyntaxException {
return UriComponentsBuilder.fromUriString(baseUrl).queryParam("page", page).queryParam("size", size).toUriString();
}
public class QueryResult<T> {
private int pageNumber;
private int totalElements;
private int totalPages;
private int pageSize;
#JsonProperty("rows")
private List<T> items;
public QueryResult() {
}
public int getPageNumber() {
return pageNumber;
}
public void setPageNumber(int pageNumber) {
this.pageNumber = pageNumber;
}
public int getTotalElements() {
return totalElements;
}
public void setTotalElements(int totalElements) {
this.totalElements = totalElements;
}
public int getPageSize() {
return pageSize;
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public List<T> getItems() {
return items;
}
public void setItems(List<T> items) {
this.items = items;
}
public int getTotalPages() {
if (this.getPageSize() > 0)
return this.getTotalElements() / this.getPageSize();
return 0;
}
public void setTotalPages(int totalPages) {
this.totalPages = totalPages;
}
}
i want to write method like this and automatic add link headers
#RequestMapping(value = "/list", method = RequestMethod.GET)
public QueryResult<Personel> search(
SearchOption searchOption) {
return ripersonelService.search();
}
after search i found this solution
#ControllerAdvice
public class BaseController implements ResponseBodyAdvice<Object> {
private final Logger logger = Logger.getLogger(BaseController.class);
#Override
public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
return true;
}
#Override
public Object beforeBodyWrite(
Object body,
MethodParameter returnType,
MediaType selectedContentType,
Class<? extends HttpMessageConverter<?>> selectedConverterType,
ServerHttpRequest request,
ServerHttpResponse response) {
if(body instanceof QueryResult){
QueryResult result =(QueryResult) body;
HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(result, request.getURI().getPath());
response.getHeaders().add(HttpHeaders.LINK, headers.getFirst(HttpHeaders.LINK));
response.getHeaders().add("X-Total-Count", headers.getFirst("X-Total-Count"));
}
return body;
}
}

You can use an implementation of ResponseBodyAdvice (typically also annotated with #ControllerAdvice). Your implementation's beforeBodyWrite method will be called with the response body and the ServerHttpResponse. The latter gives you access to the response headers and allows you to update them as appropriate.

Related

Checkmarx: Unsafe object binding

We are using Java Spring framework. We have an endpoint for passing email object.
#RequestMapping(method = RequestMethod.POST, path = "/api/messaging/v1/emailMessages/actions/send")
String sendEmail(#RequestBody Email email);
Here checkmarx says: The email may unintentionally allow setting the value of cc in LinkedList<>, in the object Email.
Email Object is as follow:
public class Email {
private List<String> bcc = new LinkedList<>();
private List<String> cc = new LinkedList<>();
private String content;
private ContentType contentType = ContentType.TXT;
private String from;
private String returnPath;
private Date sent;
private String subject;
private List<EmailAttachment> attachments = new LinkedList<>();
private List<String> to = new LinkedList<>();
public List<String> getBcc() {
return bcc;
}
public void setBcc(String bcc) {
this.bcc = Collections.singletonList(bcc);
}
public void setBcc(List<String> bcc) {
this.bcc = bcc;
}
public List<String> getCc() {
return cc;
}
public void setCc(String cc) {
this.cc = Collections.singletonList(cc);
}
public void setCc(List<String> cc) {
this.cc = cc;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public ContentType getContentType() {
return contentType;
}
public void setContentType(ContentType contentType) {
this.contentType = contentType;
}
public String getFrom() {
return from;
}
public void setFrom(String from) {
this.from = from;
}
public String getReturnPath() {
return returnPath;
}
public void setReturnPath(String returnPath) {
this.returnPath = returnPath;
}
public Date getSent() {
return sent;
}
public void setSent(Date sent) {
this.sent = sent;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public List<String> getTo() {
return to;
}
public void setTo(String to) {
this.to = Collections.singletonList(to);
}
public void setTo(List<String> to) {
this.to = to;
}
public List<EmailAttachment> getAttachments() {
return attachments;
}
public void setAttachments(List<EmailAttachment> attachments) {
this.attachments = attachments;
}
public boolean equals(Object object) {
boolean equals = false;
if (object instanceof Email) {
Email that = (Email) object;
equals = Objects.equal(this.from, that.from)
&& Objects.equal(this.to, that.to)
&& Objects.equal(this.subject, that.subject)
&& Objects.equal(this.content, that.content);
}
return equals;
}
}
I don't understand these findings, how to solve this.
I have added Lombok with #Getter & #Setter annotation to resolve this issue.

How to send a HTTP response in Zuul PRE_TYPE Filter

I want to prevent not logged user form accessing the proxy. I can throw an exception but the response is 404 instead of `401 or '403'. It it possible?
Filter code:
#Component
public class CustomZuulFilter extends ZuulFilter {
//FIXME - if 401,403 get the new token??, fallbackMethod = "fall",
#HystrixCommand(
commandProperties = {
#HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "5000"),
#HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "60")
}
)
#Override
public Object run() {
logger.debug("Adding zulu header");
String userName = getLoggedUser();
RequestContext ctx = RequestContext.getCurrentContext();
if (userName == null) {
// throw new RuntimeException("User not authenticated");
logger.info("User not authenticated");
ctx.setResponseStatusCode(401);
ctx.sendZuulResponse();
return null;
}
return null;
}
private String getLoggedUser() {
[...]
}
#Override
public boolean shouldFilter() {
return true;
}
#Override
public String filterType() {
return PRE_TYPE;
}
#Override
public int filterOrder() {
return PRE_DECORATION_FILTER_ORDER - 1;
}
}
It might be a bit late, but i think you can remove ctx.sendZuulResponse();
and add ctx.setSendZuulResponse(false);

Adding a new field to body of the request from Netflix Zuul Pre-filter

I'm trying to add a new field to request's body, in a Zuul Pre-filter.
I'm using one of the Neflix's Zuul sample projects from here, and my filter's implementation is very similar to UppercaseRequestEntityFilter from this sample.
I was able to apply a transformation such as uppercase, or even to completely modify the request, the only inconvenient is that I'm not able to modify the content of body's request that has a length more than the original length of the body's request.
This is my filter's implementation:
#Component
public class MyRequestEntityFilter extends ZuulFilter {
public String filterType() {
return "pre";
}
public int filterOrder() {
return 10;
}
public boolean shouldFilter() {
RequestContext context = getCurrentContext();
return true;
}
public Object run() {
try {
RequestContext context = getCurrentContext();
InputStream in = (InputStream) context.get("requestEntity");
if (in == null) {
in = context.getRequest().getInputStream();
}
String body = StreamUtils.copyToString(in, Charset.forName("UTF-8"));
body = body.replaceFirst("qqq", "qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq");
// body = body.toUpperCase();
context.set("requestEntity", new ServletInputStreamWrapper(body.getBytes("UTF-8")));
}
catch (IOException e) {
rethrowRuntimeException(e);
}
return null;
}
}
This is the request that I'm doing:
This is the response that I'm receiving:
I was able to obtain what I wanted, using the implementation of PrefixRequestEntityFilter, from sample-zuul-examples:
#Component
public class MyRequestEntityFilter extends ZuulFilter {
public String filterType() {
return "pre";
}
public int filterOrder() {
return 10;
}
public boolean shouldFilter() {
RequestContext context = getCurrentContext();
return true;
}
public Object run() {
try {
RequestContext context = getCurrentContext();
InputStream in = (InputStream) context.get("requestEntity");
if (in == null) {
in = context.getRequest().getInputStream();
}
String body = StreamUtils.copyToString(in, Charset.forName("UTF-8"));
body = body.replaceFirst("qqq", "qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq");
byte[] bytes = body.getBytes("UTF-8");
context.setRequest(new HttpServletRequestWrapper(getCurrentContext().getRequest()) {
#Override
public ServletInputStream getInputStream() throws IOException {
return new ServletInputStreamWrapper(bytes);
}
#Override
public int getContentLength() {
return bytes.length;
}
#Override
public long getContentLengthLong() {
return bytes.length;
}
});
}
catch (IOException e) {
rethrowRuntimeException(e);
}
return null;
}
}

java 8 nested null check list of objects

I am trying to do a nested null check and then clear the values in map in the nested object if the map is not null.
The following is my hypothetical code. I am wondering if this is the right way to do it or is there a more elegant solution to this.
package exp.myJavaLab.Experiments;
import java.util.*;
public class OptionalTest {
public Inner inner;
public static void main(String[] args) {
OptionalTest testObj = new OptionalTest();
Pojo pojo1 = new Pojo();
pojo1.id = 1;
Map<String, String> dataMap = new HashMap<>();
dataMap.put("a","b");
pojo1.dataMap = dataMap;
Pojo pojo2 = new Pojo();
pojo2.id = 2;
Inner inner = new Inner();
inner.pojoList = Arrays.asList(pojo1, pojo2);
testObj.inner = inner;
System.out.println(testObj);
Optional.ofNullable(testObj.inner)
.map(Inner::getPojoList)
.ifPresent(pojos -> pojos.forEach(pojo -> {
if (pojo.getDataMap() != null) {
pojo.getDataMap().clear();
}
}));
System.out.println(testObj);
}
#Override
public String toString() {
final StringBuilder sb = new StringBuilder("OptionalTest{");
sb.append("inner=").append(inner);
sb.append('}');
return sb.toString();
}
}
class Inner {
public List<Pojo> pojoList;
public List<Pojo> getPojoList() {
return pojoList;
}
#Override
public String toString() {
final StringBuilder sb = new StringBuilder("Inner{");
sb.append("pojoList=").append(pojoList);
sb.append('}');
return sb.toString();
}
}
class Pojo {
public Map<String, String> dataMap;
public int id;
#Override
public String toString() {
final StringBuilder sb = new StringBuilder("Pojo{");
sb.append("dataMap=").append(dataMap);
sb.append(", id=").append(id);
sb.append('}');
return sb.toString();
}
public Map<String, String> getDataMap() {
return dataMap;
}
public int getId() {
return id;
}
}
In my opinion Collections should never be null.
You could declare your pojoList and dataMap as private and instantiate them.
Your class then needs some add-methods. So you are sure getDataMap() never returns null:
class Pojo {
private Map<String, String> dataMap = new HashMap<>();
public Map<String, String> getDataMap() {
return dataMap;
}
public void add(String key, String value) {
dataMap.put(key, value);
}
}
Then you don't need to check for null:
Optional.ofNullable(testObj.inner)
.map(Inner::getPojoList)
.ifPresent(pojos -> pojos.forEach(pojo -> { pojo.getDataMap().clear(); }));

Does it exist a way for autowiring any Spring #Component inside a JPA repository?

The point is i have a Custom JPA Repository which is load using "#EnableJpaRepositories", but inside of this Custom JPA repository i do autowire another Spring Bean annotated with #Component, but it never comes filled, always bringing a null reference...
I read that JPA Repository does join and share the same Spring Application Context and so it cannot see those Beans loaded by the common Application Context... Is it really true? If so, is there any way to glue them and make Custom Repositories to inject my componentes properly???
Down here the relevant code:
public class DefaultCrudRepository<T extends IdentifiableEntity> extends QuerydslJpaRepository<T, BigInteger>
implements CrudRepository<T> {
private static final EntityPathResolver DEFAULT_ENTITY_PATH_RESOLVER = SimpleEntityPathResolver.INSTANCE;
private JpaEntityInformation<T, BigInteger> jpaEntityInformation;
private EntityManager entityManager;
private EntityPath<T> path;
private PathBuilder<T> builder;
private Querydsl querydsl;
#Autowired
private SortComponent sortComponent;
#Autowired
private PageComponent pageComponent;
#Autowired
private FilterComponent filterComponent;
#Autowired
private ExpandComponent expandComponent;
public DefaultCrudRepository(JpaEntityInformation<T, BigInteger> jpaEntityInformation, EntityManager entityManager,
EntityPathResolver resolver) {
super(jpaEntityInformation, entityManager, resolver);
this.jpaEntityInformation = jpaEntityInformation;
this.entityManager = entityManager;
this.path = resolver.createPath(jpaEntityInformation.getJavaType());
this.builder = new PathBuilder<T>(path.getType(), path.getMetadata());
this.querydsl = new Querydsl(entityManager, builder);
this.expandComponent = new DefaultExpandComponent(entityManager);
this.sortComponent = new DefaultSortComponent();
this.filterComponent = new DefaultFilterComponent();
this.pageComponent = new DefaultPageComponent();
init();
}
public DefaultCrudRepository(JpaEntityInformation<T, BigInteger> jpaEntityInformation,
EntityManager entityManager) {
this(jpaEntityInformation, entityManager, DEFAULT_ENTITY_PATH_RESOLVER);
this.jpaEntityInformation = jpaEntityInformation;
this.entityManager = entityManager;
}
/*
* private Class<?> getDomainClass(Class<?> clazz) { Type type =
* clazz.getGenericSuperclass(); if (type instanceof ParameterizedType) {
* ParameterizedType parameterizedType = (ParameterizedType) type; return
* (Class<?>) parameterizedType.getActualTypeArguments()[0]; } else { return
* getDomainClass(clazz.getSuperclass()); } }
*/
#PostConstruct
private void init() {
this.filterComponent.init(this.jpaEntityInformation.getJavaType());
this.expandComponent.init(this.jpaEntityInformation.getJavaType());
}
#Override
public <S extends T> List<S> save(Iterable<S> entities) {
List<S> savedEntities = super.save(entities);
super.flush();
this.entityManager.refresh(savedEntities);
return savedEntities;
}
#Override
public <S extends T> S save(S entity) {
S savedEntity = super.save(entity);
super.flush();
if (!this.jpaEntityInformation.isNew(entity)) {
this.entityManager.refresh(savedEntity);
}
return savedEntity;
}
protected JPQLQuery<T> createQuery(final Predicate predicate, final EntityGraph<?> entityGraph) {
JPQLQuery<?> query = createQuery(predicate);
if (entityGraph != null) {
((AbstractJPAQuery<?, ?>) query).setHint(EntityGraphType.LOAD.getKey(), entityGraph);
}
return query.select(path);
}
protected Page<T> findAll(final Pageable pageable, final Predicate predicate, final EntityGraph<?> entityGraph) {
final JPQLQuery<?> countQuery = createCountQuery(predicate);
JPQLQuery<T> query = querydsl.applyPagination(pageable, createQuery(predicate, entityGraph));
return PageableExecutionUtils.getPage(query.fetch(), pageable, new LongSupplier() {
#Override
public long getAsLong() {
return countQuery.fetchCount();
}
});
}
#Override
public Page<T> findAll(Integer pageNumber, Integer pageSize, BooleanExpression booleanExpression,
String filterExpression, String sortExpression, String expandExpression)
throws InvalidFilterExpressionException, InvalidSortExpressionException,
InvalidExpandExpressionException {
Sort sort = null;
if (sortExpression != null && !sortExpression.isEmpty()) {
sort = this.sortComponent.getSort(sortExpression);
}
Pageable pageable = this.pageComponent.getPage(pageNumber, pageSize, sort);
BooleanExpression filterBooleanExpression = null;
if (filterExpression != null) {
filterBooleanExpression = this.filterComponent.getBooleanExpression(filterExpression);
}
BooleanExpression mergedBooleanExpression = null;
if (booleanExpression != null && filterBooleanExpression != null) {
mergedBooleanExpression = booleanExpression.and(filterBooleanExpression);
} else if (booleanExpression != null && filterBooleanExpression == null) {
mergedBooleanExpression = booleanExpression;
} else if (booleanExpression == null && filterBooleanExpression != null) {
mergedBooleanExpression = filterBooleanExpression;
}
EntityGraph<?> entityGraph = null;
if (expandExpression != null && !expandExpression.isEmpty()) {
entityGraph = this.expandComponent.getEntityGraph(expandExpression);
}
return this.findAll(pageable, mergedBooleanExpression, entityGraph);
}
protected Predicate getPredicate(final BigInteger identifier, final Predicate predicate) {
Class<?> clazz = this.jpaEntityInformation.getJavaType();
String name = CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_CAMEL, clazz.getSimpleName());
Path<?> rootPath = Expressions.path(this.jpaEntityInformation.getJavaType(), name);
Class<?> idType = this.jpaEntityInformation.getIdType();
String idAttributeName = this.jpaEntityInformation.getIdAttribute().getName();
Path<?> leftPath = Expressions.path(idType, rootPath, idAttributeName);
Expression<?> rightExpression = Expressions.constant(identifier);
BooleanExpression booleanExpression = Expressions.predicate(Ops.EQ, leftPath, rightExpression);
BooleanBuilder booleanBuilder = new BooleanBuilder(booleanExpression);
booleanBuilder.and(predicate);
return booleanBuilder.getValue();
}
protected T findOne(final BigInteger identifier, final BooleanExpression booleanExpression,
final EntityGraph<?> entityGraph) {
Assert.notNull(identifier, "The given id must not be null!");
T object = null;
if (booleanExpression != null) {
Predicate mergedPredicate = getPredicate(identifier, booleanExpression);
JPQLQuery<T> query = createQuery(mergedPredicate, entityGraph);
object = query.fetchOne();
} else {
Map<String, Object> hints = new HashMap<String, Object>();
if (entityGraph != null) {
hints.put("javax.persistence.loadgraph", entityGraph);
}
object = this.entityManager.find(this.jpaEntityInformation.getJavaType(), identifier, hints);
}
return object;
}
#Override
public T findOne(final BigInteger identifier, final BooleanExpression booleanExpression,
final String expandExpression) throws InvalidExpandExpressionException {
EntityGraph<?> entityGraph = null;
if (booleanExpression != null) {
entityGraph = this.expandComponent.getEntityGraph(expandExpression);
}
return this.findOne(identifier, booleanExpression, entityGraph);
}
#Override
public Map<Number, T> findAllRevisions(final BigInteger identifier) {
Assert.notNull(identifier, "The given id must not be null!");
AuditReader auditReader = AuditReaderFactory.get(this.entityManager);
List<Number> revisionList = auditReader.getRevisions(this.jpaEntityInformation.getJavaType(), identifier);
if (revisionList == null || revisionList.isEmpty()) {
return null;
}
Set<Number> revisionSet = new LinkedHashSet<Number>(revisionList);
return auditReader.findRevisions(this.jpaEntityInformation.getJavaType(), revisionSet);
}
#Override
public void delete(Iterable<? extends T> entities) {
super.delete(entities);
super.flush();
}
#Override
public void delete(T entity) {
super.delete(entity);
super.flush();
}
}
public class AbstractCrudService<T extends IdentifiableEntity> implements CrudService<T> {
#Autowired(required=false)
private CrudRepository<T> repository;
#Autowired(required=false)
private NotificationComponent<T> notificationComponent;
private NotificationContext<T> geNotificationContext(String action, List<T> payload) {
DefaultNotificationContext<T> defaultNotificationContext = new DefaultNotificationContext<T>();
/*defaultNotificationContext.setAction(action);
defaultNotificationContext.setObject(this.domainClazz.getSimpleName());
defaultNotificationContext.setInstant(Instant.now());
defaultNotificationContext.setResponsibleId(null);
defaultNotificationContext.setPayload(payload);*/
return defaultNotificationContext;
}
private NotificationContext<T> geNotificationContext(String action, Page<T> payload) {
return geNotificationContext(action, payload.getContent());
}
private NotificationContext<T> geNotificationContext(String action, T payload) {
List<T> payloadList = new ArrayList<T>();
payloadList.add(payload);
return geNotificationContext(action, payloadList);
}
#Override
#Transactional(dontRollbackOn = LongTermRunningException.class)
#TypeTaskCriteria(pre = PreSaveTask.class, post = PostSaveTask.class, referenceGenericType = AbstractCrudService.class)
public List<T> save(List<T> objects)
throws ConcurrentModificationException, UnexpectedException {
List<T> savedObjectList = this.repository.save(objects);
if (this.notificationComponent != null) {
this.notificationComponent.notify(geNotificationContext(NotificationContext.SAVE, savedObjectList));
}
return savedObjectList;
}
#Override
#Transactional(dontRollbackOn = LongTermRunningException.class)
#TypeTaskCriteria(pre = PreSaveTask.class, post = PostSaveTask.class, referenceGenericType = AbstractCrudService.class)
public T save(T object) throws ConcurrentModificationException, UnexpectedException {
T savedObject = this.repository.save(object);
if (this.notificationComponent != null) {
this.notificationComponent.notify(geNotificationContext(NotificationContext.SAVE, savedObject));
}
return savedObject;
}
#Override
#TypeTaskCriteria(pre = PreRetrieveTask.class, post = PostRetrieveTask.class, referenceGenericType = AbstractCrudService.class)
public Page<T> retrieve(
#P(PAGE_NUMBER) final Integer pageNumber,
#P(PAGE_SIZE) final Integer pageSize,
#P(FILTER_EXPRESSION) final String filterExpression,
#P(SORT_EXPRESSION) final String sortExpression,
#P(EXPAND_EXPRESSION) final String expandExpression,
#P(PARAMETERS) final Map<String, String> parameters) throws InvalidParameterException, UnexpectedException {
DefaultRetrieveTaskContext context = TaskContextHolder.getContext();
BooleanExpression booleanExpression = context.getBooleanExpression();
Page<T> page = null;
try {
page = new Page<T>(this.repository.findAll(pageNumber, pageSize, booleanExpression, filterExpression, sortExpression, expandExpression));
} catch (InvalidFilterExpressionException | InvalidSortExpressionException
| InvalidExpandExpressionException e) {
throw new UnexpectedException(e);
}
if (this.notificationComponent != null) {
this.notificationComponent.notify(geNotificationContext(NotificationContext.RETRIEVE, page));
}
return page;
}
#Override
#TypeTaskCriteria(pre = PreRetrieveTask.class, post = PostRetrieveTask.class, referenceGenericType = AbstractCrudService.class)
public T retrieve(BigInteger identifyer, String expandExpression) throws NotFoundException, UnexpectedException {
RetrieveTaskContext context = TaskContextHolder.getContext();
BooleanExpression booleanExpression = context.getBooleanExpression();
T object = null;
try {
object = this.repository.findOne(identifyer, booleanExpression, expandExpression);
} catch (InvalidExpandExpressionException invalidExpandExpressionException) {
throw new UnexpectedException(invalidExpandExpressionException);
}
if (this.notificationComponent != null) {
this.notificationComponent.notify(geNotificationContext(NotificationContext.RETRIEVE, object));
}
return object;
}
#Override
#Transactional(dontRollbackOn = LongTermRunningException.class)
#TypeTaskCriteria(pre = PreDeleteTask.class, post = PostDeleteTask.class, referenceGenericType = AbstractCrudService.class)
public void delete(List<T> objects) throws ConcurrentModificationException, UnexpectedException {
this.repository.delete(objects);
if (this.notificationComponent != null) {
this.notificationComponent.notify(geNotificationContext(NotificationContext.DELETE, (List<T>) null));
}
}
#Override
#Transactional(dontRollbackOn = LongTermRunningException.class)
#TypeTaskCriteria(pre = PreDeleteTask.class, post = PostDeleteTask.class, referenceGenericType = AbstractCrudService.class)
public void delete(T object) throws ConcurrentModificationException, UnexpectedException {
this.repository.delete(object);
if (this.notificationComponent != null) {
this.notificationComponent.notify(geNotificationContext(NotificationContext.DELETE, (T) null));
}
}
}
#Configuration
#EnableTransactionManagement
#EnableJpaRepositories(value = "br.org.ccee", repositoryFactoryBeanClass = CrudRepositoryFactoryBean.class)
#EnableAspectJAutoProxy
public class ServiceConfiguration {
#Bean
//#Scope("request")
public ServiceContext serviceContext() {
DefaultServiceContext defaultServiceContext = new DefaultServiceContext();
defaultServiceContext.setInstant(Instant.now());
defaultServiceContext.setUserId(new BigInteger("33"));
defaultServiceContext.setTenantId(new BigInteger("69"));
return defaultServiceContext;
}
#Bean
public TenantEventListener tenantEventListener() {
return new TenantEventListener();
}
#Bean
public AuditEventListener auditEventListener() {
return new AuditEventListener();
}
#Bean
public EventListenerRegistry eventListenerRegistry(
LocalContainerEntityManagerFactoryBean entityManagerFactory,
TenantEventListener tenantEventListener,
AuditEventListener auditEventListener) {
SessionFactoryImpl sessionFactoryImpl = (SessionFactoryImpl) entityManagerFactory.getNativeEntityManagerFactory();
ServiceRegistryImplementor serviceRegistryImplementor = sessionFactoryImpl.getServiceRegistry();
EventListenerRegistry eventListenerRegistry = serviceRegistryImplementor.getService(EventListenerRegistry.class);
eventListenerRegistry.prependListeners(EventType.PRE_INSERT, auditEventListener);
eventListenerRegistry.prependListeners(EventType.PRE_INSERT, tenantEventListener);
eventListenerRegistry.prependListeners(EventType.PRE_UPDATE, auditEventListener);
return eventListenerRegistry;
}
}
public class DefaultCrudRepository<T extends IdentifiableEntity> extends QueryDslJpaRepository<T, BigInteger>
implements CrudRepository<T> {
private static final EntityPathResolver DEFAULT_ENTITY_PATH_RESOLVER = SimpleEntityPathResolver.INSTANCE;
private JpaEntityInformation<T, BigInteger> jpaEntityInformation;
private EntityManager entityManager;
private EntityPath<T> path;
private PathBuilder<T> builder;
private Querydsl querydsl;
#Autowired
private SortComponent sortComponent;
#Autowired
private PageComponent pageComponent;
#Autowired
private FilterComponent filterComponent;
#Autowired
private ExpandComponent expandComponent;

Resources