2fd4c1005c1616c15ee66af42d4154b6d8079417
[JavaForFun] /
1 package org.resthub.web.controller;
2
3 import org.resthub.common.exception.NotFoundException;
4 import org.slf4j.Logger;
5 import org.slf4j.LoggerFactory;
6 import org.springframework.data.domain.Page;
7 import org.springframework.data.domain.PageRequest;
8 import org.springframework.data.domain.Sort;
9 import org.springframework.data.repository.PagingAndSortingRepository;
10 import org.springframework.util.Assert;
11 import org.springframework.web.bind.annotation.PathVariable;
12 import org.springframework.web.bind.annotation.RequestBody;
13 import org.springframework.web.bind.annotation.RequestParam;
14
15 import java.io.Serializable;
16 import java.util.Set;
17
18 /**
19  * Abstract REST controller using a repository implementation
20  * <p/>
21  * <p>
22  * You should extend this class when you want to use a 2 layers pattern : Repository and Controller. This is the default
23  * controller implementation to use if you have no service (also called business) layer. You will be able to transform
24  * it to a ServiceBasedRestController later easily if needed.
25  * </p>
26  *
27  * <p>Default implementation uses "id" field (usually a Long) in order to identify resources in web request.
28  * If your want to identity resources by a slug (human readable identifier), your should override findById() method with for example :
29  *
30  * <pre>
31  * <code>
32    {@literal @}Override
33    public Sample findById({@literal @}PathVariable String id) {
34         Sample sample = this.repository.findByName(id);
35         if (sample == null) {
36             throw new NotFoundException();
37         }
38         return sample;
39    }
40    </code>
41  * </pre>
42  *
43  *
44  * @param <T>  Your resource class to manage, maybe an entity or DTO class
45  * @param <ID> Resource id type, usually Long or String
46  * @param <R>  The repository class
47  * @see ServiceBasedRestController
48  */
49 public abstract class RepositoryBasedRestController<T, ID extends Serializable, R extends PagingAndSortingRepository>
50         implements RestController<T, ID> {
51
52     protected R repository;
53
54     protected Logger logger = LoggerFactory.getLogger(RepositoryBasedRestController.class);
55
56     /**
57      * You should override this setter in order to inject your repository with @Inject annotation
58      *
59      * @param repository The repository to be injected
60      */
61     public void setRepository(R repository) {
62         this.repository = repository;
63     }
64
65     /**
66      * {@inheritDoc}
67      */
68     @Override
69     public T create(@RequestBody T resource) {
70         return (T)this.repository.save(resource);
71     }
72
73     /**
74      * {@inheritDoc}
75      */
76     @Override
77     public T update(@PathVariable ID id, @RequestBody T resource) {
78         Assert.notNull(id, "id cannot be null");
79
80         T retrievedResource = this.findById(id);
81         if (retrievedResource == null) {
82             throw new NotFoundException();
83         }
84
85         return (T)this.repository.save(resource);
86     }
87
88     /**
89      * {@inheritDoc}
90      */
91     @Override
92     public Iterable<T> findAll() {
93         return repository.findAll();
94     }
95
96     /**
97      * {@inheritDoc}
98      */
99     @Override
100     public Page<T> findPaginated(@RequestParam(value = "page", required = false, defaultValue = "1") Integer page,
101                                  @RequestParam(value = "size", required = false, defaultValue = "10") Integer size,
102                                  @RequestParam(value = "direction", required = false, defaultValue = "") String direction,
103                                  @RequestParam(value = "properties", required = false) String properties) {
104         Assert.isTrue(page > 0, "Page index must be greater than 0");
105         Assert.isTrue(direction.isEmpty() || direction.equalsIgnoreCase(Sort.Direction.ASC.toString()) || direction.equalsIgnoreCase(Sort.Direction.DESC.toString()), "Direction should be ASC or DESC");
106         if(direction.isEmpty()) {
107             return this.repository.findAll(new PageRequest(page - 1, size));
108         } else {
109             Assert.notNull(properties);
110             return this.repository.findAll(new PageRequest(page - 1, size, new Sort(Sort.Direction.fromString(direction.toUpperCase()), properties.split(","))));
111         }
112     }
113
114     /**
115      * {@inheritDoc}
116      */
117     @Override
118     public T findById(@PathVariable ID id) {
119         T entity = (T)this.repository.findOne(id);
120         if (entity == null) {
121             throw new NotFoundException();
122         }
123
124         return entity;
125     }
126
127     /**
128      * {@inheritDoc}
129      */
130     @Override
131     public Iterable<T> findByIds(@RequestParam(value="ids[]") Set<ID> ids){
132         Assert.notNull(ids, "ids list cannot be null");
133         return this.repository.findAll(ids);
134     }
135
136     /**
137      * {@inheritDoc}
138      */
139     @Override
140     public void delete() {
141         Iterable<T> list = repository.findAll();
142         for (T entity : list) {
143             repository.delete(entity);
144         }
145     }
146
147     /**
148      * {@inheritDoc}
149      */
150     @Override
151     public void delete(@PathVariable ID id) {
152         T resource = this.findById(id);
153         this.repository.delete(resource);
154     }
155
156 }