Repository: ambari
Updated Branches:
  refs/heads/trunk 187ab949d -> 701ea2bd8


AMBARI-16422. Hive View : Upload table : show UI validation errors while 
creating table. (Nitiraj Rathore via pallavkul)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/701ea2bd
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/701ea2bd
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/701ea2bd

Branch: refs/heads/trunk
Commit: 701ea2bd82e68465118308d7d9e136630f79eeee
Parents: 187ab94
Author: Pallav Kulshreshtha <pallav....@gmail.com>
Authored: Wed May 18 12:27:24 2016 +0530
Committer: Pallav Kulshreshtha <pallav....@gmail.com>
Committed: Wed May 18 12:27:24 2016 +0530

----------------------------------------------------------------------
 .../ui/hive-web/app/adapters/file-upload.js     |   1 -
 .../ui/hive-web/app/adapters/upload-table.js    |   6 +-
 .../app/components/validated-text-field.js      |  60 ++++++++
 .../ui/hive-web/app/controllers/upload-table.js | 152 +++++++++----------
 .../ui/hive-web/app/initializers/i18n.js        |  62 +++++++-
 .../resources/ui/hive-web/app/styles/app.scss   |   4 +
 .../components/validated-text-field.hbs         |  23 +++
 .../ui/hive-web/app/templates/upload-table.hbs  |  41 +++--
 8 files changed, 245 insertions(+), 104 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/701ea2bd/contrib/views/hive/src/main/resources/ui/hive-web/app/adapters/file-upload.js
----------------------------------------------------------------------
diff --git 
a/contrib/views/hive/src/main/resources/ui/hive-web/app/adapters/file-upload.js 
b/contrib/views/hive/src/main/resources/ui/hive-web/app/adapters/file-upload.js
index 1bd8eee..7bb6e0b 100644
--- 
a/contrib/views/hive/src/main/resources/ui/hive-web/app/adapters/file-upload.js
+++ 
b/contrib/views/hive/src/main/resources/ui/hive-web/app/adapters/file-upload.js
@@ -25,7 +25,6 @@ export default EmberUploader.Uploader.extend({
   // Override
   _ajax: function(settings) {
     settings = Ember.merge(settings, this.getProperties('headers'));
-    console.log("_ajax : settings: " + JSON.stringify(settings));
     return this._super(settings);
   }
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/701ea2bd/contrib/views/hive/src/main/resources/ui/hive-web/app/adapters/upload-table.js
----------------------------------------------------------------------
diff --git 
a/contrib/views/hive/src/main/resources/ui/hive-web/app/adapters/upload-table.js
 
b/contrib/views/hive/src/main/resources/ui/hive-web/app/adapters/upload-table.js
index ef4df43..76fce50 100644
--- 
a/contrib/views/hive/src/main/resources/ui/hive-web/app/adapters/upload-table.js
+++ 
b/contrib/views/hive/src/main/resources/ui/hive-web/app/adapters/upload-table.js
@@ -30,9 +30,7 @@ export default application.extend({
   uploadFiles: function (path, files, extras) {
     var uploadUrl = this.buildUploadURL(path);
 
-    console.log("uplaoder : uploadURL : ", uploadUrl);
-    console.log("uploader : extras : ", extras);
-    console.log("uploader : files : ", files);
+    console.log("uplaoder : uploadURL : ", uploadUrl, " extras : ", extras , 
"files : ", files);
 
     var hdrs = Ember.$.extend(true, {},this.get('headers'));
     delete hdrs['Content-Type'];
@@ -72,10 +70,8 @@ export default application.extend({
                      headers: self.get('headers'),
                      dataType : 'json'
                  }).done(function(data) {
-                     console.log( "inside done : data : ", data );
                      resolve(data);
                  }).fail(function(error) {
-                     console.log( "inside fail error :  ", error );
                      reject(error);
                  });
               });

http://git-wip-us.apache.org/repos/asf/ambari/blob/701ea2bd/contrib/views/hive/src/main/resources/ui/hive-web/app/components/validated-text-field.js
----------------------------------------------------------------------
diff --git 
a/contrib/views/hive/src/main/resources/ui/hive-web/app/components/validated-text-field.js
 
b/contrib/views/hive/src/main/resources/ui/hive-web/app/components/validated-text-field.js
new file mode 100644
index 0000000..50cea36
--- /dev/null
+++ 
b/contrib/views/hive/src/main/resources/ui/hive-web/app/components/validated-text-field.js
@@ -0,0 +1,60 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+import Ember from 'ember';
+
+/** Example :
+ * {{#validated-text-field
+ * inputValue=bindedTextValue invalidClass='form-control red-border' 
validClass='form-control' regex="^[a-z]+$"
+ * allowEmpty=false tooltip="Enter valid word" errorMessage="Please enter 
valid word" placeholder="Enter Word"}}
+ * {{/validated-text-field}}
+ */
+export default Ember.Component.extend({
+  allowEmpty: true,
+  valid: true,
+  setValid: function () {
+    this.set("valid", true);
+    this.set("inputClass", this.get("validClass"));
+    this.set("message", this.get("tooltip"));
+  },
+  setInvalid: function () {
+    this.set("valid", false);
+    this.set("inputClass", this.get("invalidClass"));
+    this.set("message", this.get("errorMessage"));
+  },
+  onChangeInputValue: function () {
+    var regStr = this.get("regex");
+    var regExp = new RegExp(regStr, "g");
+    if (this.get("inputValue")) {
+      var arr = this.get("inputValue").match(regExp);
+      if (arr != null && arr.length == 1) {
+        this.setValid();
+      }
+      else {
+        this.setInvalid();
+      }
+    } else {
+      if (this.get("allowEmpty")) {
+        this.setValid();
+      } else {
+        this.setInvalid();
+      }
+    }
+  }.observes("inputValue").on('init')
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/701ea2bd/contrib/views/hive/src/main/resources/ui/hive-web/app/controllers/upload-table.js
----------------------------------------------------------------------
diff --git 
a/contrib/views/hive/src/main/resources/ui/hive-web/app/controllers/upload-table.js
 
b/contrib/views/hive/src/main/resources/ui/hive-web/app/controllers/upload-table.js
index 361de7b..f08aa18 100644
--- 
a/contrib/views/hive/src/main/resources/ui/hive-web/app/controllers/upload-table.js
+++ 
b/contrib/views/hive/src/main/resources/ui/hive-web/app/controllers/upload-table.js
@@ -22,6 +22,8 @@ import constants from 'hive/utils/constants';
 
 
 export default Ember.Controller.extend({
+  COLUMN_NAME_REGEX:"^[a-zA-Z]{1}[a-zA-Z0-9_]*$",
+  TABLE_NAME_REGEX:"^[a-zA-Z]{1}[a-zA-Z0-9_]*$",
   isLocalUpload : Ember.computed.equal("uploadSource","local"),
   uploadSource : "local",
   COLUMN_NAME_PREFIX : "column",
@@ -93,7 +95,6 @@ export default Ember.Controller.extend({
     }, this);
   },
   isFirstRowHeaderDidChange: function () {
-    console.log("inside onFirstRowHeader : isFirstRowHeader : " + 
this.get('isFirstRowHeader'));
     if (this.get('isFirstRowHeader') != null && typeof 
this.get('isFirstRowHeader') !== 'undefined') {
       if (this.get('isFirstRowHeader') == false) {
         if (this.get('rows')) {
@@ -112,16 +113,13 @@ export default Ember.Controller.extend({
 
   popUploadProgressInfos : function(){
     var msg = this.get('uploadProgressInfos').popObject();
-   // console.log("popedup message : " + msg);
   },
 
   pushUploadProgressInfos : function(info){
     this.get('uploadProgressInfos').pushObject(info);
-   // console.log("pushed message : " + info);
   },
 
   clearUploadProgressModal : function(){
-  //  console.log("inside clearUploadProgressModal 
this.get('uploadProgressInfos') : " + this.get('uploadProgressInfos'));
     var len = this.get('uploadProgressInfos').length;
     for( var i = 0 ; i < len ; i++){
       this.popUploadProgressInfos();
@@ -129,7 +127,6 @@ export default Ember.Controller.extend({
   },
 
   hideUploadModal : function(){
-    console.log("hiding the modal ....");
     this.clearUploadProgressModal();
     Ember.$("#uploadProgressModal").modal("hide");
   },
@@ -156,13 +153,10 @@ export default Ember.Controller.extend({
   },
 
   printValues: function () {
-    console.log("printing all values : ");
-    console.log("header : ", this.get('header'));
-    console.log("rows : ", this.get('rows'));
-    console.log("error : ", this.get('error'));
-    console.log("isFirstRowHeader : ", this.get('isFirstRowHeader'));
-    console.log("files : ", this.get('files'));
-    console.log("firstRow : ", this.get('firstRow'));
+    console.log("header : ", this.get('header'),
+      ". rows : ",this.get('rows'),". error : ", this.get('error'),
+      " isFirstRowHeader : ", this.get('isFirstRowHeader'),
+      "firstRow : ", this.get('firstRow'));
   },
 
   generateTempTableName : function(){
@@ -180,16 +174,12 @@ export default Ember.Controller.extend({
     var self = this;
     var fetchJobPromise = this.get('jobService').fetchJobStatus(jobId);
       fetchJobPromise.then(function (data) {
-        console.log("waitForJobStatus : data : ", data);
         var status = data.jobStatus;
         if (status == "Succeeded") {
-          console.log("resolving waitForJobStatus with : " , status);
           resolve(status);
         } else if (status == "Canceled" || status == "Closed" || status == 
"Error") {
-          console.log("rejecting waitForJobStatus with : " + status);
           reject(new Error(status));
         } else {
-          console.log("retrying waitForJobStatus : ");
           self.waitForJobStatus(jobId, resolve, reject);
         }
       }, function (error) {
@@ -229,7 +219,7 @@ export default Ember.Controller.extend({
   waitForGeneratingPreview: function () {
     console.log("waitForGeneratingPreview");
     this.showUploadModal();
-    this.pushUploadProgressInfos("<li> Generating Preview .... </li>")
+    
this.pushUploadProgressInfos(this.formatMessage('hive.messages.generatingPreview'))
   },
 
   previewTable: function (data) {
@@ -241,7 +231,6 @@ export default Ember.Controller.extend({
     this.set("defaultColumnNames",defaultColumnNames);
     this.set("header", data.header);
     this.set("firstRow", data.rows[0].row);
-    console.log("firstRow : ", this.get('firstRow'));
     this.set('isFirstRowHeader', data.isFirstRowHeader);
     this.set('tableName',data.tableName);
     if(data.isFirstRowHeader == true){
@@ -264,13 +253,13 @@ export default Ember.Controller.extend({
     this.setError(error);
   },
 
-  createTable: function () {
-    console.log("table headers : ", this.get('header'));
+  createActualTable : function(){
+    console.log("createActualTable");
+    
this.pushUploadProgressInfos(this.formatMessage('hive.messages.startingToCreateActualTable'));
     var headers = this.get('header');
-
     var selectedDatabase = this.get('selectedDatabase');
-    if (null == selectedDatabase || typeof selectedDatabase === 'undefined') {
-      throw new Error(Ember.I18n.t('hive.errors.emptyDatabase'));
+    if (!selectedDatabase) {
+      throw new Error(this.translate('hive.errors.emptyDatabase', {database : 
this.translate("hive.words.database")}));
     }
 
     this.set('databaseName', this.get('selectedDatabase').get('name'));
@@ -279,17 +268,8 @@ export default Ember.Controller.extend({
     var isFirstRowHeader = this.get('isFirstRowHeader');
     var filetype = this.get("selectedFileType");
 
-    if (null == databaseName || typeof databaseName === 'undefined' || 
databaseName == '') {
-      throw new Error(Ember.I18n.t('hive.errors.emptyDatabase'));
-    }
-    if (null == tableName || typeof tableName === 'undefined' || tableName == 
'') {
-      throw new Error(Ember.I18n.t('hive.errors.emptyTableName'));
-    }
-    if (null == isFirstRowHeader || typeof isFirstRowHeader === 'undefined') {
-      throw new Error(Ember.I18n.t('hive.errors.emptyIsFirstRow'));
-    }
-
-    this.validateColumns();
+    this.validateInput(headers,tableName,databaseName,isFirstRowHeader);
+    this.showUploadModal();
 
     return this.get('uploader').createTable({
       "isFirstRowHeader": isFirstRowHeader,
@@ -300,16 +280,10 @@ export default Ember.Controller.extend({
     });
   },
 
-  createActualTable : function(){
-    console.log("createActualTable");
-    this.pushUploadProgressInfos("<li> Starting to create Actual table.... 
</li>");
-    return this.createTable();
-  },
-
   waitForCreateActualTable: function (jobId) {
     console.log("waitForCreateActualTable");
     this.popUploadProgressInfos();
-    this.pushUploadProgressInfos("<li> Waiting for creation of Actual 
table.... </li>");
+    
this.pushUploadProgressInfos(this.formatMessage('hive.messages.waitingToCreateActualTable'));
     var self = this;
     var p = new Ember.RSVP.Promise(function (resolve, reject) {
       self.waitForJobStatus(jobId, resolve, reject);
@@ -321,19 +295,19 @@ export default Ember.Controller.extend({
   onCreateActualTableSuccess : function(){
     console.log("onCreateTableSuccess");
     this.popUploadProgressInfos();
-    this.pushUploadProgressInfos("<li> Successfully created Actual table. 
</li>");
+    
this.pushUploadProgressInfos(this.formatMessage('hive.messages.successfullyCreatedActualTable'));
   },
 
   onCreateActualTableFailure : function(error){
     console.log("onCreateActualTableFailure");
     this.popUploadProgressInfos();
-    this.pushUploadProgressInfos("<li> Failed to create Actual table. </li>");
+    
this.pushUploadProgressInfos(this.formatMessage('hive.messages.failedToCreateActualTable'));
     this.setError(error);
   },
 
   createTempTable : function(){
     console.log("createTempTable");
-    this.pushUploadProgressInfos("<li> Starting to create Temporary table.... 
</li>");
+    
this.pushUploadProgressInfos(this.formatMessage('hive.messages.startingToCreateTemporaryTable'));
     var tempTableName = this.generateTempTableName();
     this.set('tempTableName',tempTableName);
     return this.get('uploader').createTable({
@@ -348,7 +322,7 @@ export default Ember.Controller.extend({
   waitForCreateTempTable: function (jobId) {
     console.log("waitForCreateTempTable");
     this.popUploadProgressInfos();
-    this.pushUploadProgressInfos("<li> Waiting for creation of Temporary 
table.... </li>");
+    
this.pushUploadProgressInfos(this.formatMessage('hive.messages.waitingToCreateTemporaryTable'));
     var self = this;
     var p = new Ember.RSVP.Promise(function (resolve, reject) {
       self.waitForJobStatus(jobId, resolve, reject);
@@ -360,11 +334,11 @@ export default Ember.Controller.extend({
   onCreateTempTableSuccess : function(){
     console.log("onCreateTempTableSuccess");
     this.popUploadProgressInfos();
-    this.pushUploadProgressInfos("<li> Successfully created Temporary table. 
</li>");
+    
this.pushUploadProgressInfos(this.formatMessage('hive.messages.successfullyCreatedTemporaryTable'));
   },
 
   deleteTable : function(databaseName, tableName){
-    console.log("deleting table " + databaseName + "." + tableName);
+    console.log("deleting table ", databaseName , "." , tableName);
 
     return this.get('uploader').deleteTable({
       "database":  databaseName,
@@ -375,7 +349,7 @@ export default Ember.Controller.extend({
   deleteTableOnError : function(databaseName,tableName, tableLabel){
       //delete table and wait for delete job
     var self = this;
-    this.pushUploadProgressInfos("<li> Deleting " + tableLabel + " table...  
</li>");
+    
this.pushUploadProgressInfos(this.formatMessage('hive.messages.deletingTable',{table:tableLabel}));
 
     return this.deleteTable(databaseName,tableName).then(function(data){
       return new Ember.RSVP.Promise(function(resolve,reject){
@@ -383,26 +357,31 @@ export default Ember.Controller.extend({
       });
     }).then(function(){
       self.popUploadProgressInfos();
-      self.pushUploadProgressInfos("<li> Successfully deleted " + tableLabel + 
" table. </li>");
+      
self.pushUploadProgressInfos(this.formatMessage('hive.messages.succesfullyDeletedTable',{table:tableLabel}));
       return Ember.RSVP.Promise.resolve();
     },function(err){
       self.popUploadProgressInfos();
-      self.pushUploadProgressInfos("<li> Failed to delete " + tableLabel + " 
table. </li>");
+      
self.pushUploadProgressInfos(this.formatMessage('hive.messages.failedToDeleteTable',{table:tableLabel}));
       self.setError(err);
       return Ember.RSVP.Promise.reject();
     });
   },
 
   rollBackActualTableCreation : function(){
-    return 
this.deleteTableOnError(this.get("databaseName"),this.get("tableName"),"Actual");
+    return 
this.deleteTableOnError(this.get("databaseName"),this.get("tableName"),this.translate('hive.words.actual'));
   },
 
-
+  translate : function(str,vars){
+    return Ember.I18n.t(str,vars);
+  },
+  formatMessage : function(messageId, vars){
+    return "<li>" + this.translate(messageId,vars) + "</li>";
+  },
   onCreateTempTableFailure : function(error){
     console.log("onCreateTempTableFailure");
     this.setError(error);
     this.popUploadProgressInfos();
-    this.pushUploadProgressInfos("<li> Failed to create temporary table. 
</li>");
+    this.pushUploadProgressInfos();
     return this.rollBackActualTableCreation().then(function(data){
       return Ember.RSVP.Promise.reject(error); // always reject for the flow 
to stop
     },function(err){
@@ -412,7 +391,7 @@ export default Ember.Controller.extend({
 
   uploadFile : function(){
     console.log("uploadFile");
-    this.pushUploadProgressInfos("<li> Starting to upload the file .... 
</li>");
+    
this.pushUploadProgressInfos(this.formatMessage('hive.messages.startingToUploadFile'));
     if( this.get("isLocalUpload")){
       return this.uploadTable();
     }else{
@@ -423,7 +402,7 @@ export default Ember.Controller.extend({
   waitForUploadingFile: function (data) {
     console.log("waitForUploadingFile");
     this.popUploadProgressInfos();
-    this.pushUploadProgressInfos("<li> Waiting for uploading file .... </li>");
+    
this.pushUploadProgressInfos(this.formatMessage('hive.messages.waitingToUploadFile'));
     if( data.jobId ){
       var self = this;
           var p = new Ember.RSVP.Promise(function (resolve, reject) {
@@ -438,12 +417,12 @@ export default Ember.Controller.extend({
   onUploadingFileSuccess: function () {
     console.log("onUploadingFileSuccess");
     this.popUploadProgressInfos();
-    this.pushUploadProgressInfos("<li> Successfully uploaded file. </li>");
+    
this.pushUploadProgressInfos(this.formatMessage('hive.messages.successfullyUploadedFile')
 );
   },
 
   rollBackTempTableCreation : function(){
     var self = this;
-    return 
this.deleteTableOnError(this.get("databaseName"),this.get("tempTableName"),"Temporary").then(function(data){
+    return 
this.deleteTableOnError(this.get("databaseName"),this.get("tempTableName"),this.translate('hive.words.temporary')).then(function(data){
       return self.rollBackActualTableCreation();
     },function(err){
       return self.rollBackActualTableCreation();
@@ -454,7 +433,7 @@ export default Ember.Controller.extend({
     console.log("onUploadingFileFailure");
     this.setError(error);
     this.popUploadProgressInfos();
-    this.pushUploadProgressInfos("<li> Failed to upload file. </li>");
+    
this.pushUploadProgressInfos(this.formatMessage('hive.messages.failedToUploadFile'));
     return this.rollBackTempTableCreation().then(function(data){
       return Ember.RSVP.Promise.reject(error); // always reject for the flow 
to stop
     },function(err){
@@ -468,7 +447,7 @@ export default Ember.Controller.extend({
 
   insertIntoTable : function(){
     console.log("insertIntoTable");
-    this.pushUploadProgressInfos("<li> Starting to Insert rows from temporary 
table to actual table .... </li>");
+    
this.pushUploadProgressInfos(this.formatMessage('hive.messages.startingToInsertRows'));
 
     return this.get('uploader').insertIntoTable({
       "fromDatabase":  this.get("databaseName"),
@@ -481,7 +460,7 @@ export default Ember.Controller.extend({
   waitForInsertIntoTable: function (jobId) {
     console.log("waitForInsertIntoTable");
     this.popUploadProgressInfos();
-    this.pushUploadProgressInfos("<li> Waiting for Insertion of rows from 
temporary table to actual table .... </li>");
+    
this.pushUploadProgressInfos(this.formatMessage('hive.messages.waitingToInsertRows'));
     var self = this;
     var p = new Ember.RSVP.Promise(function (resolve, reject) {
       self.waitForJobStatus(jobId, resolve, reject);
@@ -493,14 +472,14 @@ export default Ember.Controller.extend({
   onInsertIntoTableSuccess : function(){
     console.log("onInsertIntoTableSuccess");
     this.popUploadProgressInfos();
-    this.pushUploadProgressInfos("<li> Successfully inserted rows from 
temporary table to actual table. </li>");
+    
this.pushUploadProgressInfos(this.formatMessage('hive.messages.successfullyInsertedRows'));
   },
 
   onInsertIntoTableFailure : function(error){
     console.log("onInsertIntoTableFailure");
     this.setError(error);
     this.popUploadProgressInfos();
-    this.pushUploadProgressInfos("<li> Failed to insert rows from temporary 
table to actual table. </li>");
+    
this.pushUploadProgressInfos(this.formatMessage('hive.messages.failedToInsertRows'));
     return this.rollBackUploadFile().then(function(data){
       return Ember.RSVP.Promise.reject(error); // always reject for the flow 
to stop
     },function(err){
@@ -510,7 +489,7 @@ export default Ember.Controller.extend({
 
   deleteTempTable : function(){
     console.log("deleteTempTable");
-    this.pushUploadProgressInfos("<li> Starting to delete temporary table .... 
</li>");
+    
this.pushUploadProgressInfos(this.formatMessage('hive.messages.startingToDeleteTemporaryTable'));
 
     return this.deleteTable(
       this.get("databaseName"),
@@ -521,7 +500,7 @@ export default Ember.Controller.extend({
   waitForDeleteTempTable: function (jobId) {
     console.log("waitForDeleteTempTable");
     this.popUploadProgressInfos();
-    this.pushUploadProgressInfos("<li> Waiting for deletion of temporary table 
.... </li>");
+    
this.pushUploadProgressInfos(this.formatMessage('hive.messages.waitingToDeleteTemporaryTable'));
     var self = this;
     var p = new Ember.RSVP.Promise(function (resolve, reject) {
       self.waitForJobStatus(jobId, resolve, reject);
@@ -533,31 +512,28 @@ export default Ember.Controller.extend({
   onDeleteTempTableSuccess : function(){
     console.log("onDeleteTempTableSuccess");
     this.popUploadProgressInfos();
-    this.pushUploadProgressInfos("<li>Successfully inserted row. </li>");
+    
this.pushUploadProgressInfos(this.formatMessage('hive.messages.successfullyDeletedTemporaryTable'));
     this.onUploadSuccessfull();
   },
 
   onDeleteTempTableFailure : function(error){
     console.log("onDeleteTempTableFailure");
     this.setError(error);
-    this.setError("You will have to manually delete the table " + 
this.get("databaseName") + "." + this.get("tempTableName"));
+    
this.setError(this.formatMessage('hive.messages.manuallyDeleteTable',{databaseName:this.get('databaseName'),
 tableName: this.get("tempTableName")}));
   },
 
   createTableAndUploadFile : function(){
     var self = this;
     self.setError();
-    self.showUploadModal();
     self.createActualTable()
       .then(function(data){
-        console.log("1. received data : ", data);
         return self.waitForCreateActualTable(data.jobId);
       },function(error){
-        self.onCreateActualTableFailure(error);
         console.log("Error occurred: ", error);
+        self.onCreateActualTableFailure(error);
         throw error;
       })
       .then(function(data){
-        console.log("2. received data : ", data);
         self.onCreateActualTableSuccess(data);
         return self.createTempTable(data);
       },function(error){
@@ -568,7 +544,6 @@ export default Ember.Controller.extend({
         throw error;
       })
       .then(function(data){
-        console.log("3. received data : ", data);
         return self.waitForCreateTempTable(data.jobId);
       },function(error){
         if(!self.get('error')){
@@ -578,7 +553,6 @@ export default Ember.Controller.extend({
         throw error;
       })
       .then(function(data){
-        console.log("4. received data : ", data);
         self.onCreateTempTableSuccess(data);
         return self.uploadFile(data);
       },function(error){
@@ -588,7 +562,6 @@ export default Ember.Controller.extend({
         }
         throw error;
       }).then(function(data){
-        console.log("4.5 received data : ", data);
         return self.waitForUploadingFile(data);
       },function(error){
         if(!self.get('error')){
@@ -598,7 +571,6 @@ export default Ember.Controller.extend({
         throw error;
       })
       .then(function(data){
-        console.log("5. received data : ", data);
         self.onUploadingFileSuccess(data);
         return self.insertIntoTable(data);
       },function(error){
@@ -609,7 +581,6 @@ export default Ember.Controller.extend({
         throw error;
       })
       .then(function(data){
-        console.log("6. received data : ", data);
         return self.waitForInsertIntoTable(data.jobId);
       },function(error){
         if(!self.get('error')){
@@ -619,7 +590,6 @@ export default Ember.Controller.extend({
         throw error;
       })
       .then(function(data){
-        console.log("7. received data : ", data);
         self.onInsertIntoTableSuccess(data);
         return self.deleteTempTable(data);
       },function(error){
@@ -630,7 +600,6 @@ export default Ember.Controller.extend({
         throw error;
       })
       .then(function(data){
-        console.log("8. received data : ", data);
         return self.waitForDeleteTempTable(data.jobId);
       },function(error){
         if(!self.get('error')){
@@ -640,7 +609,6 @@ export default Ember.Controller.extend({
         throw error;
       })
       .then(function(data){
-        console.log("9. received data : ", data);
         self.onDeleteTempTableSuccess(data);
       },function(error){
         if(!self.get('error')){
@@ -656,9 +624,30 @@ export default Ember.Controller.extend({
       });
   },
 
-  validateColumns: function () {
+  validateInput: function (headers,tableName,databaseName,isFirstRowHeader) {
     // throw exception if invalid.
+    if(!headers || headers.length == 0) throw new 
Error(this.translate('hive.errors.emptyHeaders'));
+
+    var regex = new RegExp(this.get("COLUMN_NAME_REGEX"),"g");
+
+    headers.forEach(function(column,index){
+      if( !column  ) throw new 
Error(this.translate('hive.errors.emptyColumnName'));
+      var matchArr = column.name.match(regex);
+      if(matchArr == null || matchArr.length != 1 ) throw new 
Error(this.translate('hive.errors.illegalColumnName',{ columnName : 
column.name, index : (index + 1)}));
+    },this);
+
+    if(!tableName) throw new 
Error(this.translate('hive.errors.emptyTableName', {tableNameField : 
this.translate('hive.ui.tableName')}));
+    var tableRegex = new RegExp(this.get("TABLE_NAME_REGEX"),"g");
+    var mArr = tableName.match(tableRegex);
+    if(mArr == null || mArr.length != 1 ) throw new 
Error(this.translate('hive.errors.illegalTableName', 
{tableNameField:this.translate('hive.ui.tableName'),tableName:tableName}) );
+
+    if(!databaseName) throw new 
Error(this.translate('hive.errors.emptyDatabase', 
{database:this.translate('hive.words.database')}));
+
+    if (null == isFirstRowHeader || typeof isFirstRowHeader === 'undefined') { 
//this can be true or false. so explicitly checking for null/ undefined.
+      throw new Error(this.translate('hive.errors.emptyIsFirstRow', 
{isFirstRowHeaderField:this.translate('hive.ui.isFirstRowHeader')}));
+    }
   },
+
   setError: function (error) {
     if(error){
       console.log("upload table error : ", error);
@@ -676,7 +665,7 @@ export default Ember.Controller.extend({
   uploadTableFromHdfs : function(){
     console.log("uploadTableFromHdfs called.");
     if(!(this.get("inputFileTypeCSV") == true && this.get("isFirstRowHeader") 
== false) ){
-      this.pushUploadProgressInfos("<li>Uploading file .... </li>");
+      this.pushUploadProgressInfos(this.formatMessage('uploadingFromHdfs'));
     }
     return  this.get('uploader').uploadFromHDFS({
         "isFirstRowHeader": this.get("isFirstRowHeader"),
@@ -698,7 +687,8 @@ export default Ember.Controller.extend({
 
   onUploadSuccessfull: function (data) {
     console.log("onUploadSuccessfull : ", data);
-    this.get('notifyService').success("Uploaded Successfully", "Table " + 
this.get('tableName') + " created in database " + this.get("databaseName"));
+    
this.get('notifyService').success(this.translate('hive.messages.successfullyUploadedTableHeader'),
+      this.translate('hive.messages.successfullyUploadedTableMessage' 
,{tableName:this.get('tableName') ,databaseName:this.get("databaseName")}));
     this.clearFields();
   },
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/701ea2bd/contrib/views/hive/src/main/resources/ui/hive-web/app/initializers/i18n.js
----------------------------------------------------------------------
diff --git 
a/contrib/views/hive/src/main/resources/ui/hive-web/app/initializers/i18n.js 
b/contrib/views/hive/src/main/resources/ui/hive-web/app/initializers/i18n.js
index b3630c1..d2f6aaf 100644
--- a/contrib/views/hive/src/main/resources/ui/hive-web/app/initializers/i18n.js
+++ b/contrib/views/hive/src/main/resources/ui/hive-web/app/initializers/i18n.js
@@ -244,9 +244,65 @@ TRANSLATIONS = {
   hive: {
     errors: {
       'no.query': "No query to process.",
-      'emptyDatabase' : "Please select Database.",
-      'emptyTableName' : "Please enter tableName.",
-      'emptyIsFirstRow' : "Please select is First Row Header?"
+      'emptyDatabase' : "Please select {{ database }}.",
+      'emptyTableName' : "Please enter {{ tableNameField }}.",
+      'illegalTableName':"Illegal {{ tableNameField }} : '{{ tableName }}'",
+      'emptyIsFirstRow' : "{{isFirstRowHeaderField}} cannot be null.",
+      'emptyHeaders':"Headers (containing column names) cannot be null.",
+      'emptyColumnName':"Column name cannot be null.",
+      'illegalColumnName':"Illegal column name : '{{columnName}}' in column 
number {{index}}",
+    },
+    messages : {
+      'generatingPreview':"Generating Preview.",
+      'startingToCreateActualTable' : "Starting to create Actual table",
+      'waitingToCreateActualTable' : "Waiting for creation of Actual table",
+      'successfullyCreatedActualTable' : "Successfully created Actual table.",
+      'failedToCreateActualTable' : "Failed to create Actual table.",
+      'startingToCreateTemporaryTable' : "Starting to create Temporary table.",
+      'waitingToCreateTemporaryTable' : "Waiting for creation of Temporary 
table.",
+      'successfullyCreatedTemporaryTable' : "Successfully created Temporary 
table.",
+      'failedToCreateTemporaryTable' : " Failed to create temporary table.",
+      'deletingTable' :  "Deleting {{table}} table.",
+      'succesfullyDeletedTable' :  "Successfully deleted {{ table}} table.",
+      'failedToDeleteTable' :  "Failed to delete {{table}} table.",
+      'startingToUploadFile' :  "Starting to upload the file.",
+      'waitingToUploadFile' :  "Waiting for uploading file.",
+      'successfullyUploadedFile' :  "Successfully uploaded file.",
+      'failedToUploadFile' :  "Failed to upload file.",
+      'startingToInsertRows' :  "Starting to insert rows from temporary table 
to actual table.",
+      'waitingToInsertRows' :  "Waiting for insertion of rows from temporary 
table to actual table.",
+      'successfullyInsertedRows' :  "Successfully inserted rows from temporary 
table to actual table.",
+      'failedToInsertRows' :  "Failed to insert rows from temporary table to 
actual table.",
+      'startingToDeleteTemporaryTable' :  "Starting to delete temporary 
table.",
+      'waitingToDeleteTemporaryTable' :  "Waiting for deletion of temporary 
table.",
+      'successfullyDeletedTemporaryTable' :  "Successfully deleted temporary 
table",
+      'manuallyDeleteTable' :  "You will have to manually delete the table 
{{databaseName}}.{{tableName}}",
+      'uploadingFromHdfs' :  "Uploading file from HDFS ",
+      'successfullyUploadedTableMessage' : "Table {{tableName}} created in 
database {{databaseName}}",
+      'successfullyUploadedTableHeader' : "Uploaded Successfully"
+    },
+    words :{
+      temporary : "Temporary",
+      actual : "Actual",
+      database : "Database",
+    },
+    ui : {
+      'uploadProgress' : "Upload Progress",
+      'uploadFromLocal':"Upload from Local",
+      'uploadFromHdfs':"Upload from HDFS",
+      'selectFileType':"Select File Type",
+      'fileType':"File type",
+      'selectFromLocal':"Select from local",
+      'hdfsPath':"HDFS Path",
+      'selectDatabase':"Select a Database",
+      'tableName':"Table name",
+      'tableNameErrorMessage':"Only alphanumeric and underscore characters are 
allowed in table name.",
+      'tableNameTooltip':"Enter valid (alphanumeric + underscore) table name.",
+      'storedAs':"Stored as",
+      'isFirstRowHeader':"Is first row header ?",
+      'columnNameTooltip':"Enter valid (alphanumeric + underscore) column 
name.",
+      'columnNameErrorMessage':"Only alphanumeric and underscore characters 
are allowed in column names.",
+
     }
   },
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/701ea2bd/contrib/views/hive/src/main/resources/ui/hive-web/app/styles/app.scss
----------------------------------------------------------------------
diff --git 
a/contrib/views/hive/src/main/resources/ui/hive-web/app/styles/app.scss 
b/contrib/views/hive/src/main/resources/ui/hive-web/app/styles/app.scss
index ec4f201..d0a6fb7 100644
--- a/contrib/views/hive/src/main/resources/ui/hive-web/app/styles/app.scss
+++ b/contrib/views/hive/src/main/resources/ui/hive-web/app/styles/app.scss
@@ -683,3 +683,7 @@ td.data-upload-form-field {
 table.no-border, table.no-border tr, table.no-border tr td {
   border: none;
 }
+
+.red-border {
+  border-color :red;
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/701ea2bd/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/components/validated-text-field.hbs
----------------------------------------------------------------------
diff --git 
a/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/components/validated-text-field.hbs
 
b/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/components/validated-text-field.hbs
new file mode 100644
index 0000000..7cf0fcf
--- /dev/null
+++ 
b/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/components/validated-text-field.hbs
@@ -0,0 +1,23 @@
+{{!
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements.  See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership.  The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License.  You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+}}
+
+{{!
+* see example in validated-text-field.js component file
+}}
+
+{{input class=inputClass value=inputValue title=message 
placeholder=placeholder}}

http://git-wip-us.apache.org/repos/asf/ambari/blob/701ea2bd/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/upload-table.hbs
----------------------------------------------------------------------
diff --git 
a/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/upload-table.hbs
 
b/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/upload-table.hbs
index eb95292..0fffed4 100644
--- 
a/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/upload-table.hbs
+++ 
b/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/upload-table.hbs
@@ -30,7 +30,7 @@
     <!-- Modal content-->
     <div class="modal-content">
       <div class="modal-header">
-        <h4 class="modal-title">Upload Progress</h4>
+        <h4 class="modal-title">{{t "hive.ui.uploadProgress"}}</h4>
       </div>
       <div class="modal-body">
         <p>
@@ -51,29 +51,30 @@
   <div>
     <table class="table data-upload-form pull-left">
       <tr>
-        <td class="data-upload-form-label"><label>Upload from 
Local</label></td>
+        <td class="data-upload-form-label"><label>{{t 
"hive.ui.uploadFromLocal"}}</label></td>
         <td  class="data-upload-form-field"> {{radio-button value='local' 
checked=uploadSource}}</td>
 
-        <td class="data-upload-form-label"><label>Upload from HDFS</label></td>
+        <td class="data-upload-form-label"><label>{{t 
"hive.ui.uploadFromHdfs"}}</label></td>
         <td  class="data-upload-form-field">{{radio-button value='hdfs' 
checked=uploadSource}}</td>
       </tr>
       <tr>
-        <td class="data-upload-form-label"><label>File type</label></td>
+        <td class="data-upload-form-label"><label>{{t 
"hive.ui.fileType"}}</label></td>
         <td class="data-upload-form-field">
           {{typeahead-widget
           content=inputFileTypes
           optionValuePath="id"
           optionLabelPath="name"
           selection=inputFileType
-          placeholder="Select File Type"}}
+          placeholder=(t "hive.ui.uploadFromHdfs")
+          }}
         </td>
 
 
         {{#if isLocalUpload }}
-          <td class="data-upload-form-label"><label>Select from 
local</label></td>
+          <td class="data-upload-form-label"><label>{{t 
"hive.ui.selectFromLocal"}}</label></td>
           <td class="data-upload-form-field">{{file-upload  
filesUploaded="filesUploaded"}}</td>
         {{else}}
-          <td class="data-upload-form-label"><label>HDFS Path</label></td>
+          <td class="data-upload-form-label"><label>{{t 
"hive.ui.hdfsPath"}}</label></td>
           <td class="data-upload-form-field" id="hdfs-param">{{input 
type="text" class="form-control" placeholder="Enter full HDFS path" 
value=hdfsPath }}
             <button style="margin-left: 5px; padding-top: 6px;padding-bottom: 
6px; padding-right: 10px; padding-left: 10px;" type="button" {{action 
"previewFromHdfs"}}
             {{bind-attr class=":btn :btn-sm :btn-default"}}>{{t 
"buttons.showPreview"}}</button></td>
@@ -81,30 +82,36 @@
       </tr>
       {{#if showPreview}}
         <tr>
-          <td class="data-upload-form-label"><label>Database</label></td>
+          <td class="data-upload-form-label"><label>{{t 
"hive.words.database"}}</label></td>
           <td class="data-upload-form-field">
             {{typeahead-widget
             content=controllers.databases.databases
             optionValuePath="id"
             optionLabelPath="name"
             selection=selectedDatabase
-            placeholder="Select a Database"
+            placeholder=(t "hive.ui.selectDatabase")
             }}
           </td>
 
-          <td class="data-upload-form-label"><label>Table name</label></td>
+          <td class="data-upload-form-label"><label>{{t 
"hive.ui.tableName"}}</label></td>
           <td
-            class="data-upload-form-field">{{input type="text" 
class="form-control" placeholder="Table Name" value=tableName }}</td>
+            class="data-upload-form-field">
+            {{#validated-text-field inputValue=tableName allowEmpty=false
+            tooltip=(t "hive.ui.tableNameTooltip")
+            invalidClass='form-control red-border' validClass='form-control' 
regex=TABLE_NAME_REGEX
+            errorMessage=(t "hive.ui.tableNameErrorMessage") }}
+            {{/validated-text-field}}
+          </td>
         </tr>
         <tr>
-          <td class="data-upload-form-label"><label>Stored as</label></td>
+          <td class="data-upload-form-label"><label>{{t 
"hive.ui.storedAs"}}</label></td>
           <td class="data-upload-form-field">
             {{typeahead-widget
             content=fileTypes
             selection=selectedFileType}}
           </td>
           {{#if inputFileTypeCSV }}
-            <td class="data-upload-form-label"><label>Is first row header 
?</label></td>
+            <td class="data-upload-form-label"><label>{{t 
"hive.ui.isFirstRowHeader"}}</label></td>
             <td class="data-upload-form-field">
               {{input id="isFirstRowHeader" type="checkbox" 
checked=isFirstRowHeader }}
             </td>
@@ -133,7 +140,13 @@
           <thead>
           <tr>
             {{#each column in header}}
-              <th>{{input placeholder="column-name" type="text" 
class="form-control" value=column.name}}</th>
+              <th>
+                {{#validated-text-field inputValue=column.name allowEmpty=false
+                tooltip=(t "hive.ui.columnNameTooltip")
+                invalidClass='form-control red-border' 
validClass='form-control' regex=COLUMN_NAME_REGEX
+                errorMessage=(t "hive.ui.columnNameErrorMessage")}}
+                {{/validated-text-field}}
+              </th>
             {{/each}}
           </tr>
           <tr id="upload-controls">

Reply via email to