This is an automated email from the git hooks/post-receive script. New commit to branch develop in repository coselmar. See http://git.codelutin.com/coselmar.git commit 673e11b82b16207ef885f3bbb611391d7cbbf532 Author: Yannick Martel <martel@©odelutin.com> Date: Wed Nov 26 16:53:30 2014 +0100 #6140 add new metadata in document views --- .../src/main/xmi/coselmar-model.zargo | Bin 6487 -> 6490 bytes .../fr/ifremer/coselmar/beans/DocumentBean.java | 18 ++-- .../coselmar/converter/BeanEntityConverter.java | 2 +- .../coselmar/services/v1/DocumentsWebService.java | 36 ++++--- .../src/main/webapp/js/coselmar-controllers.js | 23 +++-- .../src/main/webapp/js/coselmar-services.js | 11 ++- .../src/main/webapp/views/documents/document.html | 34 ++++++- .../src/main/webapp/views/documents/documents.html | 6 +- .../main/webapp/views/documents/newdocument.html | 105 ++++++++++++++++++--- 9 files changed, 187 insertions(+), 48 deletions(-) diff --git a/coselmar-persistence/src/main/xmi/coselmar-model.zargo b/coselmar-persistence/src/main/xmi/coselmar-model.zargo index b07f229..9036e41 100644 Binary files a/coselmar-persistence/src/main/xmi/coselmar-model.zargo and b/coselmar-persistence/src/main/xmi/coselmar-model.zargo differ diff --git a/coselmar-rest/src/main/java/fr/ifremer/coselmar/beans/DocumentBean.java b/coselmar-rest/src/main/java/fr/ifremer/coselmar/beans/DocumentBean.java index 93528a0..6984fff 100644 --- a/coselmar-rest/src/main/java/fr/ifremer/coselmar/beans/DocumentBean.java +++ b/coselmar-rest/src/main/java/fr/ifremer/coselmar/beans/DocumentBean.java @@ -51,7 +51,7 @@ public class DocumentBean implements Serializable { protected Date publicationDate; // Document could be internal file or external link - protected boolean isFile; + protected boolean withFile; protected String mimeType; protected String externalUrl; @@ -59,7 +59,7 @@ public class DocumentBean implements Serializable { Date depositDate, Collection<String> keywords, String type, String summary, String language, Date publicationDate, String authors, String license, String copyright, - boolean isFile, String mimeType, String externalUrl) { + boolean withFile, String mimeType, String externalUrl) { this.id = id; this.name = name; this.ownerName = ownerName; @@ -81,11 +81,11 @@ public class DocumentBean implements Serializable { this.license = license; this.copyright = copyright; - if (isFile) { - this.isFile = true; + if (withFile) { + this.withFile = true; this.mimeType = mimeType; } else { - this.isFile = false; + this.withFile = false; this.externalUrl = externalUrl; } } @@ -205,12 +205,12 @@ public class DocumentBean implements Serializable { } } - public boolean isFile() { - return isFile; + public boolean isWithFile() { + return withFile; } - public void setFile(boolean isFile) { - this.isFile = isFile; + public void setWithFile(boolean isFile) { + this.withFile = isFile; } public String getExternalUrl() { diff --git a/coselmar-rest/src/main/java/fr/ifremer/coselmar/converter/BeanEntityConverter.java b/coselmar-rest/src/main/java/fr/ifremer/coselmar/converter/BeanEntityConverter.java index 61be990..bed5346 100644 --- a/coselmar-rest/src/main/java/fr/ifremer/coselmar/converter/BeanEntityConverter.java +++ b/coselmar-rest/src/main/java/fr/ifremer/coselmar/converter/BeanEntityConverter.java @@ -65,7 +65,7 @@ public class BeanEntityConverter { document.getLicense(), document.getCopyright(), - document.isIsFile(), + document.isWithFile(), document.getMimeType(), document.getExternalUrl() ); diff --git a/coselmar-rest/src/main/java/fr/ifremer/coselmar/services/v1/DocumentsWebService.java b/coselmar-rest/src/main/java/fr/ifremer/coselmar/services/v1/DocumentsWebService.java index d4dbb70..e3380b8 100644 --- a/coselmar-rest/src/main/java/fr/ifremer/coselmar/services/v1/DocumentsWebService.java +++ b/coselmar-rest/src/main/java/fr/ifremer/coselmar/services/v1/DocumentsWebService.java @@ -39,6 +39,7 @@ import fr.ifremer.coselmar.beans.DocumentBean; import fr.ifremer.coselmar.beans.UserWebToken; import fr.ifremer.coselmar.converter.BeanEntityConverter; import fr.ifremer.coselmar.persistence.entity.CoselmarUser; +import fr.ifremer.coselmar.persistence.entity.CoselmarUserRole; import fr.ifremer.coselmar.persistence.entity.Document; import fr.ifremer.coselmar.persistence.entity.DocumentPrivacy; import fr.ifremer.coselmar.services.CoselmarTechnicalException; @@ -46,6 +47,7 @@ import fr.ifremer.coselmar.services.CoselmarWebServiceSupport; import fr.ifremer.coselmar.services.errors.InvalidCredentialException; import fr.ifremer.coselmar.services.errors.UnauthorizedException; import org.apache.commons.io.FileUtils; +import org.apache.commons.lang3.StringUtils; import org.apache.commons.logging.Log; import org.debux.webmotion.server.call.UploadFile; import org.debux.webmotion.server.render.Render; @@ -61,6 +63,9 @@ public class DocumentsWebService extends CoselmarWebServiceSupport { private static final Log log = getLog(DocumentsWebService.class); + public static final List<String> DOCUMENT_ALLOWED_USER_ROLES = + Lists.newArrayList(CoselmarUserRole.EXPERT.name()); + public DocumentBean getDocument(String documentId) { // reconstitute full id @@ -99,7 +104,7 @@ public class DocumentsWebService extends CoselmarWebServiceSupport { // Only Expert or Supervisor can add document String userRole = userWebToken.getRole(); - if (!Lists.newArrayList().contains(userRole.toUpperCase())) { + if (!DOCUMENT_ALLOWED_USER_ROLES.contains(userRole.toUpperCase())) { String message = String.format("User %s %s ('%s') is not allowed to add document", userWebToken.getFirstName(), userWebToken.getLastName(), userWebToken.getUserId()); if (log.isWarnEnabled()) { @@ -130,7 +135,8 @@ public class DocumentsWebService extends CoselmarWebServiceSupport { String contentType = null; // If document has a file, manager it ! - if (document.isFile()) { + if (document.isWithFile()) { + documentName = uploadFile.getName(); contentType = managerDocumentFile(uploadFile, owner); } @@ -163,11 +169,11 @@ public class DocumentsWebService extends CoselmarWebServiceSupport { documentEntity.setLicense(document.getLicense()); // Document resource part - if (document.isFile()) { - documentEntity.setIsFile(true); + if (document.isWithFile()) { + documentEntity.setWithFile(true); documentEntity.setMimeType(contentType); } else { - documentEntity.setIsFile(false); + documentEntity.setWithFile(false); documentEntity.setExternalUrl(document.getExternalUrl()); } @@ -186,12 +192,11 @@ public class DocumentsWebService extends CoselmarWebServiceSupport { String fileName = document.getName(); Date depositeDate = document.getDepositDate(); - File dataDirectory = getCoselmarServicesConfig().getDataDirectory(); - String absolutePath = dataDirectory.getAbsolutePath(); + String userDocumentPath = getUserDocumentPath(document.getOwner()); String formatedDay = DateUtil.formatDate(depositeDate, "yyyymmdd"); String prefix = formatedDay + "-"; - File documentFile = new File(absolutePath + "/" + prefix + fileName); + File documentFile = new File(userDocumentPath + "/" + prefix + fileName); String fileMimeType = document.getMimeType(); try { @@ -221,6 +226,9 @@ public class DocumentsWebService extends CoselmarWebServiceSupport { Document document = getDocumentDao().forTopiaIdEquals(fullId).findUnique(); getDocumentDao().delete(document); + //TODO ymartel 20141126 : delete file + + commit(); } @@ -250,10 +258,7 @@ public class DocumentsWebService extends CoselmarWebServiceSupport { } // put the document in the good directory - // TODO ymartel 20141105 : with user management, put the document in a user specifique folder - File dataDirectory = getCoselmarServicesConfig().getDataDirectory(); - String absolutePath = dataDirectory.getAbsolutePath(); - String userPath = absolutePath + File.separator + owner.getFirstname() + "-" + owner.getName(); + String userPath = getUserDocumentPath(owner); Date now = getNow(); String formattedDay = DateUtil.formatDate(now, "yyyymmdd"); @@ -271,5 +276,12 @@ public class DocumentsWebService extends CoselmarWebServiceSupport { return contentType; } + protected String getUserDocumentPath(CoselmarUser user) { + File dataDirectory = getCoselmarServicesConfig().getDataDirectory(); + String absolutePath = dataDirectory.getAbsolutePath(); + String userFolder = StringUtils.replaceChars(user.getFirstname() + "-" + user.getName(), " ", "_"); + String userPath = absolutePath + File.separator + userFolder; + return userPath; + } } diff --git a/coselmar-ui/src/main/webapp/js/coselmar-controllers.js b/coselmar-ui/src/main/webapp/js/coselmar-controllers.js index e31d174..2be62f7 100644 --- a/coselmar-ui/src/main/webapp/js/coselmar-controllers.js +++ b/coselmar-ui/src/main/webapp/js/coselmar-controllers.js @@ -96,22 +96,33 @@ coselmarControllers.controller("DocumentsCtrl", ['$scope', '$route', '$routePara // Controller for new document View -coselmarControllers.controller("NewDocumentCtrl", ['$scope', '$route', 'documentService', function($scope, $route, documentService){ +coselmarControllers.controller("NewDocumentCtrl", ['$scope', '$location', 'documentService', function($scope, $location, documentService){ + + $scope.document = {'privacy': 'PUBLIC'}; + $scope.upload = {}; $scope.createNewDocument = function(){ - var documentMetadata = {'privacy':$scope.privacy, 'keywords':$scope.keywords}; // Call service to create a new document - documentService.createDocument(documentMetadata, $scope.documentFile, $scope); + documentService.createDocument( + $scope.document, $scope.upload.file, function() { + $location.path("/documents"); + + },function(error) { + //TODO ymartel 20141118 : deal with error.status or statusText + console.log("error occurs"); + console.log(error.s); + }); - // Reload the page - $route.reload(); }; }]); // Controller for single document View coselmarControllers.controller("DocumentViewCtrl", - ['$scope', '$route', '$location', 'documentService', '$routeParams', function($scope, $route, $location, documentService, $routeParams) { + ['$scope', '$route', '$location', 'documentService', '$routeParams', 'coselmar-config', + function($scope, $route, $location, documentService, $routeParams, coselmarConfig) { + + $scope.container = {baseUrl : coselmarConfig.BASE_URL}; documentService.getDocument($routeParams.documentId, $scope); diff --git a/coselmar-ui/src/main/webapp/js/coselmar-services.js b/coselmar-ui/src/main/webapp/js/coselmar-services.js index 5b4d262..2d236b3 100644 --- a/coselmar-ui/src/main/webapp/js/coselmar-services.js +++ b/coselmar-ui/src/main/webapp/js/coselmar-services.js @@ -33,11 +33,14 @@ function Document(resource, config){ var baseURL = config.BASE_URL + "/documents"; - this.createDocument = function(metadata, file, scope){ + this.createDocument = function(metadata, file, successFunction, failFunction) { var formData = new FormData(); - formData.append("uploadFile", file); + if (file) { + formData.append("uploadFile", file); + } formData.append("document", JSON.stringify(metadata)); + // Save the document var docResource = resource(baseURL, null, { 'upload': { @@ -48,9 +51,7 @@ function Document(resource, config){ } } }); - docResource.upload(formData, function(response){ - //manage result - }); + docResource.upload(null, formData, successFunction, failFunction); } this.getDocument = function(id, scope){ diff --git a/coselmar-ui/src/main/webapp/views/documents/document.html b/coselmar-ui/src/main/webapp/views/documents/document.html index 44b7690..d40c006 100644 --- a/coselmar-ui/src/main/webapp/views/documents/document.html +++ b/coselmar-ui/src/main/webapp/views/documents/document.html @@ -40,7 +40,7 @@ </tr> <tr> <td>Type</td> - <td>{{document.mimeType}}</td> + <td>{{document.type}}</td> </tr> <tr> <td>Keywords</td> @@ -54,9 +54,39 @@ <td>Deposite Date</td> <td>{{document.depositDate | date:'mediumDate'}}</td> </tr> + <tr> + <td>Summary</td> + <td>{{document.summary}}</td> + </tr> + <tr> + <td>Authors</td> + <td>{{document.authors}}</td> + </tr> + <tr> + <td>Copyright</td> + <td>{{document.copyright}}</td> + </tr> + <tr> + <td>License</td> + <td>{{document.lincese}}</td> + </tr> + <tr> + <td>Language</td> + <td>{{document.language}}</td> + </tr> + <tr> + <td>PublicationDate</td> + <td>{{document.publicationDate | date:'mediumDate'}}</td> + </tr> + <tr> + <td>Document type</td> + <td ng-if="document.withFile">{{document.mimeType}}</td> + <td ng-if="!document.withFile">External Link</td> + </tr> </table> <div style="padding-left: 200px"> - <a href="/v1/documents/{{document.id}}/file" class="btn btn-primary">Download</a> + <a href="{{container.baseUrl}}/documents/{{document.id}}/file" class="btn btn-primary" ng-if="document.withFile">Download</a> + <a href="{{document.externalUrl}}" target="_blank" class="btn btn-primary" ng-if="!document.withFile">Open Link</a> <a class="btn btn-danger" ng-click="deleteDocument(document.id)">Delete</a> </div> </div> diff --git a/coselmar-ui/src/main/webapp/views/documents/documents.html b/coselmar-ui/src/main/webapp/views/documents/documents.html index 9eed5c5..4c089ef 100644 --- a/coselmar-ui/src/main/webapp/views/documents/documents.html +++ b/coselmar-ui/src/main/webapp/views/documents/documents.html @@ -51,14 +51,16 @@ <th>Privacy</th> <th>Keywords</th> <th>Deposit Date</th> + <th>Related Question</th> <th></th> </tr> <tr ng-repeat="document in documents"> <td><a href="#/documents/{{document.id}}">{{document.name}}</a></td> <td>{{document.ownerName}}</td> <td>{{document.privacy}}</td> - <td>{{document.keywords}}</td> - <td>{{document.depositDate}}</td> + <td><span ng-repeat="keyword in document.keywords">{{keyword}} ,</span></td> + <td>{{document.depositDate | date:'mediumDate'}}</td> + <td>N/A</td> <td><a class="btn btn-danger" ng-click="deleteDocument(document.id)">Delete</a></td> </tr> </table> diff --git a/coselmar-ui/src/main/webapp/views/documents/newdocument.html b/coselmar-ui/src/main/webapp/views/documents/newdocument.html index 7465bdb..d619818 100644 --- a/coselmar-ui/src/main/webapp/views/documents/newdocument.html +++ b/coselmar-ui/src/main/webapp/views/documents/newdocument.html @@ -28,7 +28,7 @@ <div style="padding-top: 15px"> <!-- Summary goes here --> - Here you can upload a new document in the repository. For each document, + Here you can add a new document in the repository. For each document, some keywords are needed to make easier search of the document, and you can specify a privacy : <ul> @@ -41,21 +41,56 @@ <div class=""> - <form class="form-horizontal" role="form" ng-submit="createNewDocument()"> + <form class="form-horizontal" name="documentForm" role="form" ng-submit="createNewDocument()"> <div class="form-group"> + <label class="col-md-4 control-label">Name</label> + + <div class="col-md-5"> + <input type="text" class="form-control" name="name" ng-model="document.name" required/> + </div> + </div> + + <div class="form-group"> + <label class="col-md-4 control-label">Type</label> + + <div class="col-md-5"> + <input type="text" class="form-control" name="type" ng-model="document.type" required/> + </div> + </div> + + <div class="form-group"> + <label class="col-md-4 control-label">Attach File ?</label> + + <div class="col-md-5"> + <input type="checkbox" ng-model="document.withFile" ng-init="document.withFile = false" /> + </div> + </div> + + <div class="form-group" ng-if="document.withFile"> <label class="col-md-4 control-label">File</label> <div class="col-md-5"> - <input type="file" class="form-control" name="file" ng-file-model="documentFile" required/> + <input type="file" class="form-control" name="uploadFile" ng-file-model="upload.file" required /> </div> </div> + <div class="form-group" ng-if="!document.withFile"> + <label class="col-md-4 control-label">External URL</label> + + <div class="col-md-5"> + <input type="input" class="form-control" name="externalUrl" + ng-model="document.externalUrl" required /> + </div> + </div> + <div class="form-group"> - <label class="col-md-4 control-label">keyword</label> + <label class="col-md-4 control-label">keywords</label> <div class="col-md-5"> - <input type="text" class="form-control" name="keyword" ng-model="keywords" ng-list required/> + <input type="text" class="form-control" name="keyword" + ng-model="document.keywords" ng-list required + placeholder="keyword 1, keyword2" /> </div> </div> @@ -63,12 +98,12 @@ <label class="col-md-4 control-label">Privacy</label> <div class="col-md-5"> - <select class="form-control" name="privacy" ng-model="privacy"> - <option value="private">private</option> - <option value="public">public</option> - <option value="restricted">restricted</option> + <select class="form-control" name="privacy" ng-model="document.privacy"> + <option value="PRIVATE">private</option> + <option value="PUBLIC">public</option> + <option value="RESTRICTED">restricted</option> </select> - <div ng-if="privacy == 'restricted'"> + <div ng-if="privacy == 'RESTRICTED'"> Not Yet available </div> </div> @@ -76,8 +111,56 @@ </div> <div class="form-group"> + <label class="col-md-4 control-label">Authors</label> + + <div class="col-md-5"> + <input type="text" class="form-control" name="authors" ng-model="document.authors" required/> + </div> + </div> + + <div class="form-group"> + <label class="col-md-4 control-label">Copyright</label> + + <div class="col-md-5"> + <input type="text" class="form-control" name="copyright" ng-model="document.copyright" required/> + </div> + </div> + + <div class="form-group"> + <label class="col-md-4 control-label">Licence</label> + + <div class="col-md-5"> + <input type="text" class="form-control" name="licence" ng-model="document.licence" /> + </div> + </div> + + <div class="form-group"> + <label class="col-md-4 control-label">Language</label> + + <div class="col-md-5"> + <input type="text" class="form-control" name="language" ng-model="document.language" /> + </div> + </div> + + <div class="form-group"> + <label class="col-md-4 control-label">Publication date</label> + + <div class="col-md-5"> + <input type="date" class="form-control" name="publicationDate" ng-model="document.publicationDate" /> + </div> + </div> + + <div class="form-group"> + <label class="col-md-4 control-label">Summary</label> + + <div class="col-md-5"> + <textarea type="text" class="form-control" name="summary" ng-model="document.summary" required /> + </div> + </div> + + <div class="form-group"> <div style="padding-left: 200px"> - <input type="submit" value="Submit" class="btn btn-primary" ng-if="privacy != 'restricted'"/> + <input type="submit" value="Submit" class="btn btn-primary" ng-if="documentForm.$valid && privacy != 'RESTRICTED'"/> </div> </div> </form> -- To stop receiving notification emails like this one, please contact codelutin.com SCM administrator <admin+scm@codelutin.com>.