Roberto Sánchez
2014-01-26 6d8aff7b3657332020ef215eb1b2fc16017e4cc8
#395 feature - Added license history entity and new angular directive to
load file content
1 files added
8 files modified
changed files
securis/src/main/java/net/curisit/securis/db/License.java patch | view | blame | history
securis/src/main/java/net/curisit/securis/db/LicenseHistory.java patch | view | blame | history
securis/src/main/java/net/curisit/securis/security/SecurityInterceptor.java patch | view | blame | history
securis/src/main/java/net/curisit/securis/services/LicenseResource.java patch | view | blame | history
securis/src/main/resources/db/schema.sql patch | view | blame | history
securis/src/main/resources/static/js/catalogs.js patch | view | blame | history
securis/src/main/resources/static/js/licenses.js patch | view | blame | history
securis/src/main/resources/static/js/main.js patch | view | blame | history
securis/src/main/resources/static/licenses.html patch | view | blame | history
securis/src/main/java/net/curisit/securis/db/License.java
....@@ -2,15 +2,18 @@
22
33 import java.io.Serializable;
44 import java.util.Date;
5
+import java.util.List;
56
67 import javax.persistence.Column;
78 import javax.persistence.Entity;
9
+import javax.persistence.FetchType;
810 import javax.persistence.GeneratedValue;
911 import javax.persistence.Id;
1012 import javax.persistence.JoinColumn;
1113 import javax.persistence.ManyToOne;
1214 import javax.persistence.NamedQueries;
1315 import javax.persistence.NamedQuery;
16
+import javax.persistence.OneToMany;
1417 import javax.persistence.Table;
1518
1619 import org.codehaus.jackson.annotate.JsonAutoDetect;
....@@ -77,19 +80,13 @@
7780 @Column(name = "modification_timestamp")
7881 private Date modificationTimestamp;
7982
80
- @Column(name = "activation_timestamp")
81
- private Date activationTimestamp;
82
-
83
- @Column(name = "cancelation_timestamp")
84
- private Date cancelationTimestamp;
85
-
86
- @Column(name = "send_timestamp")
87
- private Date sendTimestamp;
88
-
8983 @Column(name = "last_access_timestamp")
9084 private Date lastAccessTimestamp;
9185
9286 private String comments;
87
+
88
+ @OneToMany(fetch = FetchType.LAZY, mappedBy = "license")
89
+ private List<LicenseHistory> history;
9390
9491 public int getId() {
9592 return id;
....@@ -209,22 +206,6 @@
209206 this.email = email;
210207 }
211208
212
- public Date getActivationTimestamp() {
213
- return activationTimestamp;
214
- }
215
-
216
- public void setActivationTimestamp(Date activationTimestamp) {
217
- this.activationTimestamp = activationTimestamp;
218
- }
219
-
220
- public Date getSendTimestamp() {
221
- return sendTimestamp;
222
- }
223
-
224
- public void setSendTimestamp(Date sendTimestamp) {
225
- this.sendTimestamp = sendTimestamp;
226
- }
227
-
228209 public void setId(int id) {
229210 this.id = id;
230211 }
....@@ -235,14 +216,6 @@
235216
236217 public void setCanceledBy(User canceledBy) {
237218 this.canceledBy = canceledBy;
238
- }
239
-
240
- public Date getCancelationTimestamp() {
241
- return cancelationTimestamp;
242
- }
243
-
244
- public void setCancelationTimestamp(Date cancelationTimestamp) {
245
- this.cancelationTimestamp = cancelationTimestamp;
246219 }
247220
248221 public Date getLastAccessTimestamp() {
....@@ -277,6 +250,14 @@
277250 this.comments = comments;
278251 }
279252
253
+ public List<LicenseHistory> getHistory() {
254
+ return history;
255
+ }
256
+
257
+ public void setHistory(List<LicenseHistory> history) {
258
+ this.history = history;
259
+ }
260
+
280261 public static class Status {
281262 public static final int CREATED = 0;
282263 public static final int SENT = 1;
securis/src/main/java/net/curisit/securis/db/LicenseHistory.java
....@@ -0,0 +1,117 @@
1
+package net.curisit.securis.db;
2
+
3
+import java.io.Serializable;
4
+import java.util.Date;
5
+
6
+import javax.persistence.Entity;
7
+import javax.persistence.GeneratedValue;
8
+import javax.persistence.Id;
9
+import javax.persistence.JoinColumn;
10
+import javax.persistence.ManyToOne;
11
+import javax.persistence.NamedQueries;
12
+import javax.persistence.NamedQuery;
13
+import javax.persistence.Table;
14
+
15
+import org.codehaus.jackson.annotate.JsonAutoDetect;
16
+import org.codehaus.jackson.annotate.JsonIgnore;
17
+import org.codehaus.jackson.annotate.JsonIgnoreProperties;
18
+import org.codehaus.jackson.annotate.JsonProperty;
19
+import org.codehaus.jackson.map.annotate.JsonSerialize;
20
+
21
+/**
22
+ * Entity implementation class for Entity: license
23
+ *
24
+ */
25
+@JsonAutoDetect
26
+@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
27
+@Entity
28
+@Table(name = "license_history")
29
+@JsonIgnoreProperties(ignoreUnknown = true)
30
+@NamedQueries(
31
+ { @NamedQuery(name = "list-license-history", query = "SELECT lh FROM LicenseHistory lh where lh.license.id = :licId") })
32
+public class LicenseHistory implements Serializable {
33
+
34
+ private static final long serialVersionUID = 1L;
35
+
36
+ @Id
37
+ @GeneratedValue
38
+ private int id;
39
+
40
+ @JsonIgnore
41
+ @ManyToOne
42
+ @JoinColumn(name = "license_id")
43
+ private License license;
44
+
45
+ @JsonIgnore
46
+ @ManyToOne
47
+ @JoinColumn(name = "username")
48
+ private User user;
49
+
50
+ private String action;
51
+ private String comments;
52
+
53
+ private Date timestamp;
54
+
55
+ public int getId() {
56
+ return id;
57
+ }
58
+
59
+ public License getLicense() {
60
+ return license;
61
+ }
62
+
63
+ public void setLicense(License license) {
64
+ this.license = license;
65
+ }
66
+
67
+ public User getUser() {
68
+ return user;
69
+ }
70
+
71
+ @JsonProperty("username")
72
+ public String getUsername() {
73
+ return user == null ? null : user.getUsername();
74
+ }
75
+
76
+ public void setUser(User user) {
77
+ this.user = user;
78
+ }
79
+
80
+ public String getAction() {
81
+ return action;
82
+ }
83
+
84
+ public void setAction(String action) {
85
+ this.action = action;
86
+ }
87
+
88
+ public String getComments() {
89
+ return comments;
90
+ }
91
+
92
+ public void setComments(String comments) {
93
+ this.comments = comments;
94
+ }
95
+
96
+ public Date getTimestamp() {
97
+ return timestamp;
98
+ }
99
+
100
+ public void setTimestamp(Date timestamp) {
101
+ this.timestamp = timestamp;
102
+ }
103
+
104
+ public void setId(int id) {
105
+ this.id = id;
106
+ }
107
+
108
+ public static class Actions {
109
+ public static final String CREATE = "creation";
110
+ public static final String ADD_REQUEST = "request";
111
+ public static final String SEND = "send";
112
+ public static final String MODIFY = "modify";
113
+ public static final String ACTIVATE = "activate";
114
+ public static final String CANCEL = "cancel";
115
+ public static final String DELETE = "delete";
116
+ }
117
+}
securis/src/main/java/net/curisit/securis/security/SecurityInterceptor.java
....@@ -52,9 +52,6 @@
5252 com.google.inject.Provider<EntityManager> emProvider;
5353
5454 public void filter(ContainerRequestContext containerRequestContext) throws IOException {
55
- // log.info("scw {}, {}", scw, scw.getClass());
56
- log.info("MACHED res: {}", containerRequestContext.getUriInfo().getMatchedResources());
57
- // dispatcher.getDefaultContextObjects().remove(SecurityContextWrapper.class);
5855 ResourceMethodInvoker methodInvoker = (ResourceMethodInvoker) containerRequestContext.getProperty("org.jboss.resteasy.core.ResourceMethodInvoker");
5956 Method method = methodInvoker.getMethod();
6057
....@@ -82,11 +79,8 @@
8279 scw.setOrganizationsIds(orgs);
8380 containerRequestContext.setSecurityContext(scw);
8481 // Next line provide injection in resource methods
85
- log.info("TEST context {}", ResteasyProviderFactory.getContextData(BasicSecurityContext.class));
8682 ResteasyProviderFactory.pushContext(BasicSecurityContext.class, scw);
87
- // log.info("{}", dispatcher.getDefaultContextObjects());
88
- // dispatcher.getDefaultContextObjects().put(SecurityContextWrapper.class, secContext);
89
- log.info("Added custom SecurityContext for user {}", username);
83
+ log.debug("Added custom SecurityContext for user {}, orgs: {}", username, orgs);
9084 }
9185 }
9286
securis/src/main/java/net/curisit/securis/services/LicenseResource.java
....@@ -1,5 +1,6 @@
11 package net.curisit.securis.services;
22
3
+import java.io.IOException;
34 import java.util.Date;
45 import java.util.List;
56
....@@ -21,6 +22,7 @@
2122 import javax.ws.rs.core.Response;
2223 import javax.ws.rs.core.Response.Status;
2324
25
+import net.curisit.integrity.commons.JsonUtils;
2426 import net.curisit.integrity.commons.Utils;
2527 import net.curisit.integrity.exception.CurisException;
2628 import net.curisit.securis.DefaultExceptionHandler;
....@@ -31,6 +33,7 @@
3133 import net.curisit.securis.security.Securable;
3234 import net.curisit.securis.utils.TokenHelper;
3335
36
+import org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataInput;
3437 import org.slf4j.Logger;
3538 import org.slf4j.LoggerFactory;
3639
....@@ -124,7 +127,7 @@
124127 { MediaType.APPLICATION_JSON })
125128 @Transactional
126129 public Response create(License lic, @Context BasicSecurityContext bsc) {
127
- log.info("Creating new organization");
130
+ log.info("Creating new license from create()");
128131 EntityManager em = emProvider.get();
129132 Pack pack = null;
130133 if (lic.getPackId() != null) {
....@@ -143,7 +146,7 @@
143146 }
144147
145148 try {
146
- User createdBy = getUser(lic.getCreatedById(), em);
149
+ User createdBy = getUser(bsc.getUserPrincipal().getName(), em);
147150 lic.setCreatedBy(createdBy);
148151 } catch (CurisException ex) {
149152 String createdByUsername = lic.getCreatedById();
....@@ -161,6 +164,31 @@
161164 return Response.ok(lic).build();
162165 }
163166
167
+ @POST
168
+ @Path("/")
169
+ @Consumes(MediaType.MULTIPART_FORM_DATA)
170
+ @Securable
171
+ @Produces(
172
+ { MediaType.APPLICATION_JSON })
173
+ @Transactional
174
+ public Response createWithFile(MultipartFormDataInput mpfdi, @Context BasicSecurityContext bsc) throws IOException {
175
+ License lic = new License();
176
+ lic.setCode(mpfdi.getFormDataPart("code", String.class, null));
177
+ lic.setRequestData(mpfdi.getFormDataPart("request_data", String.class, null));
178
+ lic.setPackId(mpfdi.getFormDataPart("pack_id", Integer.class, null));
179
+ lic.setFullName(mpfdi.getFormDataPart("full_name", String.class, null));
180
+ lic.setEmail(mpfdi.getFormDataPart("email", String.class, null));
181
+ lic.setComments(mpfdi.getFormDataPart("comments", String.class, null));
182
+ try {
183
+ log.info("File content: {}", lic.getRequestData());
184
+ log.info("License read from multipart: {}", JsonUtils.toJSON(lic));
185
+ } catch (CurisException e) {
186
+ // TODO Auto-generated catch block
187
+ e.printStackTrace();
188
+ }
189
+ return create(lic, bsc);
190
+ }
191
+
164192 private User getUser(String username, EntityManager em) throws CurisException {
165193 User user = null;
166194 if (username != null) {
securis/src/main/resources/db/schema.sql
....@@ -76,14 +76,22 @@
7676 email VARCHAR(100) NOT NULL,
7777 comments VARCHAR(1024) NULL ,
7878 creation_timestamp DATETIME NOT NULL ,
79
- send_timestamp DATETIME NULL ,
8079 modification_timestamp DATETIME NULL ,
81
- activation_timestamp DATETIME NULL ,
82
- cancelation_timestamp DATETIME NULL ,
8380 last_access_timestamp DATETIME NULL ,
8481 canceled_by varchar(45) NULL ,
8582 created_by varchar(45) NULL ,
86
- status VARCHAR(3) NOT NULL default 0,
83
+ status INT NOT NULL default 0,
84
+ PRIMARY KEY (id));
85
+
86
+
87
+drop table IF EXISTS license_history;
88
+CREATE TABLE IF NOT EXISTS license_history (
89
+ id INT NOT NULL auto_increment,
90
+ license_id INT NOT NULL,
91
+ username VARCHAR(45) NOT NULL,
92
+ timestamp DATETIME NOT NULL ,
93
+ action VARCHAR(40) ,
94
+ comments VARCHAR(512) ,
8795 PRIMARY KEY (id));
8896
8997
securis/src/main/resources/static/js/catalogs.js
....@@ -159,8 +159,7 @@
159159 **********************************************/
160160
161161 function _success(response) {
162
- console.log('$resource')
163
- console.log(response)
162
+ console.debug('$resource action success')
164163 }
165164 function _fail(response) {
166165 console
....@@ -244,9 +243,6 @@
244243 promises.push(refs[f.name].$promise);
245244 });
246245
247
- console.log('promises: ' + promises.length
248
- + ' ')
249
- console.log(promises)
250246 $q.all(promises)
251247 .then(function() {
252248 for(var i in refsFields) {
....@@ -254,10 +250,7 @@
254250 var rf = refsFields[i];
255251 var cat = that.getResource(rf.resource);
256252 var pk = that.getPk(that.getMetadata(rf.resource))
257
- console.log('PK field for '
258
- + rf.name
259
- + ' is '
260
- + pk)
253
+ //console.log('PK field for ' + rf.name + ' is ' + pk)
261254 var comboData = []
262255 refs[rf.name].forEach(function(row) {
263256 comboData.push({
....@@ -271,8 +264,6 @@
271264 });
272265 })
273266 refs[rf.name] = comboData;
274
- console.log('Ready for combo for ' + rf.name)
275
- console.log(comboData);
276267 }
277268 _current && _current.fields.forEach(function(f) {
278269 if (f.values)
....@@ -280,7 +271,6 @@
280271 });
281272 })
282273
283
- console.log(refs);
284274 return refs;
285275 }
286276
securis/src/main/resources/static/js/licenses.js
....@@ -9,6 +9,44 @@
99 }
1010
1111 var app = angular.module('securis');
12
+
13
+ app.directive('fileLoader',
14
+ function($timeout, $parse) {
15
+ return {
16
+ restrict : 'A', // only activate on element attribute
17
+ require : '',
18
+ link : function(scope, element, attrs) {
19
+ console.log('scope.license: ' + scope.$parent.license);
20
+ var setter = $parse(attrs.fileLoader).assign;
21
+ element.bind('change', function(evt) {
22
+ console.log('scope.license: ' + scope.$parent.license);
23
+ var field = $parse(attrs.fileLoader);
24
+ console.log('field: ' + field);
25
+ var fileList = evt.target.files;
26
+ if (fileList != null && fileList[0]) {
27
+ var reader = new FileReader();
28
+ reader.onerror = function(data) {
29
+ setter(scope.$parent, 'ERROR');
30
+ scope.$apply();
31
+ }
32
+ reader.onload = function(data) {
33
+ setter(scope.$parent, reader.result);
34
+ scope.$apply();
35
+ }
36
+
37
+ reader.readAsText(fileList[0]);
38
+ } else {
39
+ console.log('NO FILE: ');
40
+ field = '';
41
+ scope.$apply();
42
+ }
43
+ });
44
+
45
+ }
46
+ };
47
+ });
48
+
49
+ console.log(' OK ????? ');
1250
1351 app.controller('PackAndLicensesCtrl', [
1452 '$scope',
....@@ -17,38 +55,6 @@
1755 '$store',
1856 '$L',
1957 function($scope, $http, toaster, $store, $L) {
20
- $scope.licenses = [
21
- {id: 1,
22
- "code": "BP-SA-001-AKSJMS234",
23
- "user_fullname": "Johnny Belmonte",
24
- "user_email": "jb@curisit.net",
25
- "status": 3},
26
- {id: 2,
27
- "code": "BP-SA-001-KAJSDHAJS",
28
- "user_fullname": "Walter Simons",
29
- "user_email": "ws@curisit.net",
30
- "status": 1},
31
- {id: 3,
32
- "code": "BP-SA-001-ASKDGHKA",
33
- "user_fullname": "Frank Belmonte",
34
- "user_email": "fb@curisit.net",
35
- "status": 2},
36
- {id: 4,
37
- "code": "BP-SA-001-BBBGGGG",
38
- "user_fullname": "John Dalton",
39
- "user_email": "jd@curisit.net",
40
- "status": 3},
41
- {id: 5,
42
- "code": "BP-SA-001-AKADNAJANA",
43
- "user_fullname": "Walter Martins",
44
- "user_email": "wm@curisit.net",
45
- "status": 3},
46
- {id: 6,
47
- "code": "BP-SA-001-AKANDAKS",
48
- "user_fullname": "Joe Bolton",
49
- "user_email": "jbol@curisit.net",
50
- "status": 2}
51
- ];
5258
5359 $scope.maxLengthErrorMsg = function(displayname, fieldMaxlength) {
5460 return $L.get("{0} length is too long (max: {1}).", $L.get(displayname), fieldMaxlength);
....@@ -171,7 +177,6 @@
171177 function($scope, $http, $resource, toaster, $store, $L) {
172178 $scope.$on('pack_changed', function(evt, message) {
173179 $scope.licenses = licenseResource.query({packId: $scope.currentPack.id});
174
- console.log('on pack_changed');
175180 if ($scope.showForm) {
176181 if ($scope.isNew) {
177182 $scope.license.pack_id = $scope.currentPack.id
....@@ -183,6 +188,25 @@
183188
184189 var licenseResource = $resource('/license/:licenseId', {
185190 licenseId : '@id'
191
+ }, {
192
+ save_w_upload: {
193
+ method: "POST",
194
+ transformRequest: function(data, headersGetter) {
195
+ // To use an object without FormData, follow: https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest?redirectlocale=en-US&redirectslug=DOM%2FXMLHttpRequest%2FUsing_XMLHttpRequest#Submitting_forms_and_uploading_files
196
+ var formData = new FormData();
197
+ angular.forEach(data, function(value, key) {
198
+ if (key !== 'request_data')
199
+ formData.append(key, value)
200
+ else
201
+ formData.append(key, $('input#request_data_file').get(0).files[0]);
202
+ })
203
+
204
+ return formData;
205
+ },
206
+ headers: {
207
+ 'Content-Type': undefined
208
+ }
209
+ }
186210 });
187211 $scope.mandatory = {
188212 code: true
....@@ -202,12 +226,28 @@
202226 if ($scope.currentPack)
203227 $scope.licenses = licenseResource.query({packId: $scope.currentPack.id});
204228
229
+// $(document).on('change', '#request_data_file', function(newValue, oldValue) {
230
+// console.log('File changed!!!!');
231
+// var reader = new FileReader();
232
+// reader.onload = function(data) {
233
+// console.log('LOAD complete: ' + data);
234
+// console.log('LOAD reader.result: ' + reader.result);
235
+// $('input#request_data').val(reader.result)
236
+// }
237
+// console.log('file: ' + $('input#request_data_file').get(0).files[0]);
238
+// console.log('file2: ' + $scope.request_data_file);
239
+// reader.readAsText($('input#request_data_file').get(0).files[0]);
240
+// });
241
+
205242 $scope.save = function() {
243
+ $( "form#licenseForm" )
244
+ .attr( "enctype", "multipart/form-data" )
245
+ .attr( "encoding", "multipart/form-data" );
206246 var _success = function() {
207247 if (!$scope.isNew) $scope.showForm = false;
208248 $scope.licenses = licenseResource.query({packId: $scope.currentPack.id});
209249 }
210
- licenseResource.save($scope.license, _success)
250
+ licenseResource.save_w_upload($scope.license, _success)
211251 }
212252
213253 $scope.newLicense = function() {
securis/src/main/resources/static/js/main.js
....@@ -37,7 +37,7 @@
3737 $location.path('/login');
3838 toaster.pop('warning', 'Session has expired', null, 4000);
3939 } else {
40
- console.log('Last access recent');
40
+ console.debug('Last access recent');
4141 }
4242 }
4343 $store.set('last_access', now);
....@@ -61,7 +61,7 @@
6161 });
6262
6363 m.config(function($routeProvider, $locationProvider, $httpProvider) {
64
- console.log('Configuring routes...');
64
+ console.debug('Configuring routes...');
6565 $routeProvider.when('/login', {
6666 templateUrl: 'login.html',
6767 controller: 'LoginCtrl'
securis/src/main/resources/static/licenses.html
....@@ -163,7 +163,7 @@
163163 </div>
164164
165165 </div>
166
-
166
+{{license | json}}
167167 <div id="licenses_section" class="col-md-6" ng-controller="LicensesCtrl">
168168 <nav class="navbar navbar-default navbar-static-top" ng-disabled="!currentPack">
169169 <!-- Brand and toggle get grouped for better mobile display -->
....@@ -253,12 +253,13 @@
253253 </div>
254254 </div>
255255 </div>
256
-
256
+{{request_data}}
257257 <div class="form-group" ng-if="isNew || !license.request_data" >
258258 <label class="col-md-3 control-label" for="request_data" i18n>Request data</label>
259259 <div class="col-md-8">
260
- <textarea type="string" id="request_data" name="request_data" placeholder=""
260
+ <textarea id="request_data" name="request_data" placeholder=""
261261 class="form-control" ng-model="license.request_data" rows="2" ng-required="mandatory.request_data" ng-maxlength="{{maxlength.request_data}}"></textarea>
262
+ <input file-loader="license.request_data" type="file" title="" >
262263 <div class="alert inline-alert alert-warning" ng-show="licenseForm.request_data.$invalid">
263264 <span class="glyphicon glyphicon-warning-sign"></span>
264265 <span ng-show="licenseForm.request_data.$error.maxlength" ng-bind="maxlengthErrorMsg('Request data', maxlength.request_data)"></span>
....@@ -272,6 +273,7 @@
272273 <div class="col-md-8">
273274 <textarea type="string" id="comments" name="comments" placeholder=""
274275 class="form-control" ng-model="license.comments" rows="2" ng-required="mandatory.comments" ng-maxlength="{{maxlength.comments}}"></textarea>
276
+
275277 <div class="alert inline-alert alert-warning" ng-show="licenseForm.comments.$invalid">
276278 <span class="glyphicon glyphicon-warning-sign"></span>
277279 <span ng-show="licenseForm.comments.$error.maxlength" ng-bind="maxlengthErrorMsg('Comments', maxlength.comments)"></span>