Commit 602ff559bbc868963f70144401537401e98dbfea

Authored by Edmar Moretti
1 parent e8d6bbe2

Ativação da opção de salvar querys no saiku

ferramentas/saiku/saiku-server/tomcat/webapps/ROOT/index.html
... ... @@ -302,9 +302,9 @@
302 302 <li><a href="#open_query"
303 303 class="i18n open button sprite"
304 304 title="Open query"></a></li>
305   - <!--<li><a href="#save_query"
  305 + <li><a href="#save_query"
306 306 class="i18n save button disabled_toolbar sprite"
307   - title="Save query"></a></li>-->
  307 + title="Save query"></a></li>
308 308 <li class="seperator"><a href="#run_query"
309 309 class="i18n run button disabled_toolbar sprite"
310 310 title="Run query"></a></li>
... ...
ferramentas/saiku/saiku-server/tomcat/webapps/ROOT/js/saiku/SessionWorkspace.js
... ... @@ -142,7 +142,7 @@ var SessionWorkspace = Backbone.Model.extend({
142 142 url: function() {
143 143 if (this.first) {
144 144 this.first = false;
145   - return encodeURI(Saiku.session.username + "/discover/");
  145 + return encodeURI(Saiku.session.username + "/discover");
146 146 }
147 147 else {
148 148 return encodeURI(Saiku.session.username + "/discover/refresh");
... ...
ferramentas/saiku/saiku-server/tomcat/webapps/ROOT/js/saiku/models/Dimension.js 0 → 100755
... ... @@ -0,0 +1,65 @@
  1 +/*
  2 + * Copyright 2012 OSBI Ltd
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +
  17 +/**
  18 + * Model which fetches the dimensions for a cube
  19 + */
  20 +var Dimension = Backbone.Model.extend({
  21 + initialize: function(args) {
  22 + this.url = Saiku.session.username + "/discover/" +
  23 + args.key + "/dimensions";
  24 + },
  25 +
  26 + parse: function(response) {
  27 + this.set({
  28 + template: _.template($("#template-dimensions").html())({
  29 + dimensions: response
  30 + }),
  31 +
  32 + data: response
  33 + });
  34 +
  35 + typeof localStorage !== "undefined" && localStorage && localStorage.setItem("dimension." + this.get('key'),
  36 + JSON.stringify(this));
  37 +
  38 + return response;
  39 + }
  40 +});
  41 +
  42 +/**
  43 + * Model which fetches the measures for a cube
  44 + */
  45 +var Measure = Backbone.Model.extend({
  46 + initialize: function(args) {
  47 + this.url = Saiku.session.username + "/discover/" +
  48 + args.key + "/measures";
  49 + },
  50 +
  51 + parse: function(response) {
  52 + this.set({
  53 + template: _.template($("#template-measures").html())({
  54 + measures: response
  55 + }),
  56 +
  57 + data: response
  58 + });
  59 +
  60 + typeof localStorage !== "undefined" && localStorage && localStorage.setItem("measure." + this.get('key'),
  61 + JSON.stringify(this));
  62 +
  63 + return response;
  64 + }
  65 +});
... ...
ferramentas/saiku/saiku-server/tomcat/webapps/ROOT/js/saiku/models/Member.js 0 → 100755
... ... @@ -0,0 +1,36 @@
  1 +/*
  2 + * Copyright 2012 OSBI Ltd
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +
  17 +/**
  18 + * Controls member selections
  19 + */
  20 +var Member = Backbone.Model.extend({
  21 + initialize: function(args, options) {
  22 + this.cube = options.cube;
  23 + var dimension = options.dimension.split("/");
  24 + this.dimension = dimension[0];
  25 + this.hierarchy = dimension[2];
  26 + this.level = dimension[3];
  27 + },
  28 +
  29 + url: function() {
  30 + var url = encodeURI(Saiku.session.username + "/discover/") +
  31 + this.cube + encodeURI("/dimensions/" + this.dimension +
  32 + "/hierarchies/" + this.hierarchy + "/levels/" + this.level);
  33 +
  34 + return url;
  35 + }
  36 +});
... ...
ferramentas/saiku/saiku-server/tomcat/webapps/ROOT/js/saiku/models/Properties.js 0 → 100755
... ... @@ -0,0 +1,66 @@
  1 +/*
  2 + * Copyright 2012 OSBI Ltd
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +
  17 +/**
  18 + * Maintains query properties like non empty and automatic execution
  19 + */
  20 +var Properties = Backbone.Model.extend({
  21 + initialize: function(args, options) {
  22 + // Keep track of parent query
  23 + this.query = options.query;
  24 +
  25 + // Update properties with defaults from settings
  26 + this.properties = {};
  27 + _.extend(this.properties, Settings.QUERY_PROPERTIES);
  28 + if (typeof args != "undefined" && args) {
  29 + _.extend(this.properties, args);
  30 + }
  31 + },
  32 +
  33 + toggle: function(key) {
  34 + // Toggle property
  35 + this.properties[key] = this.properties[key] === 'true' ?
  36 + 'false' : 'true';
  37 +
  38 + return this;
  39 + },
  40 +
  41 + update: function(async) {
  42 + // FIXME - this really sucks
  43 + // Why can't we just use the body?
  44 + this.attributes = {
  45 + properties: _.template(
  46 + "<% _.each(properties, function(property, name) { %>" +
  47 + "<%= name %> <%= property %>\n" +
  48 + "<% }); %>"
  49 + )({ properties: this.properties })
  50 + };
  51 + this.save({ async: async });
  52 + },
  53 +
  54 + parse: function(response) {
  55 + // FIXME - POST should return properties as well
  56 + if (typeof response == "object") {
  57 + _.extend(this.properties, response);
  58 + }
  59 +
  60 + this.query.workspace.trigger('properties:loaded');
  61 + },
  62 +
  63 + url: function() {
  64 + return encodeURI(this.query.url() + "/properties");
  65 + }
  66 +});
... ...
ferramentas/saiku/saiku-server/tomcat/webapps/ROOT/js/saiku/models/Query.js 0 → 100755
... ... @@ -0,0 +1,162 @@
  1 +/*
  2 + * Copyright 2012 OSBI Ltd
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +
  17 +/**
  18 + * Workspace query
  19 + */
  20 +var Query = Backbone.Model.extend({
  21 +
  22 + formatter: Settings.CELLSET_FORMATTER,
  23 + properties: null,
  24 +
  25 + initialize: function(args, options) {
  26 + // Save cube
  27 + _.extend(this, options);
  28 +
  29 + // Bind `this`
  30 + _.bindAll(this, "run", "move_dimension", "reflect_properties");
  31 +
  32 + // Generate a unique query id
  33 + this.uuid = 'xxxxxxxx-xxxx-xxxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g,
  34 + function (c) {
  35 + var r = Math.random() * 16 | 0,
  36 + v = c == 'x' ? r : (r & 0x3 | 0x8);
  37 + return v.toString(16);
  38 + }).toUpperCase();
  39 +
  40 + // Initialize properties, action handler, and result handler
  41 + this.action = new QueryAction({}, { query: this });
  42 + this.result = new Result({ limit: Settings.RESULT_LIMIT }, { query: this });
  43 + this.scenario = new QueryScenario({}, { query: this });
  44 +
  45 + this.set({type:'QM'});
  46 + },
  47 +
  48 + parse: function(response) {
  49 + // Assign id so Backbone knows to PUT instead of POST
  50 + this.id = this.uuid;
  51 +
  52 + this.set({
  53 + connection: response.cube.connectionName,
  54 + catalog: response.cube.catalogName,
  55 + schema: response.cube.schemaName,
  56 + cube: encodeURIComponent(response.cube.name),
  57 + axes: response.saikuAxes,
  58 + type: response.type
  59 + });
  60 +
  61 + if (typeof response.properties != "undefined" && "saiku.ui.formatter" in response.properties) {
  62 + this.set({formatter : response.properties['saiku.ui.formatter']});
  63 + }
  64 +
  65 + this.properties = new Properties(response.properties, { query: this });
  66 + this.reflect_properties();
  67 + },
  68 +
  69 + reflect_properties: function() {
  70 + this.workspace.trigger('properties:loaded');
  71 + },
  72 +
  73 + setProperty: function(key, value) {
  74 + if (typeof this.properties != "undefined" && this.properties.properties ) {
  75 + this.properties.properties[key] = value;
  76 + }
  77 + },
  78 +
  79 + run: function(force, mdx) {
  80 + // Check for automatic execution
  81 + Saiku.ui.unblock();
  82 + if (typeof this.properties != "undefined" && this.properties.properties['saiku.olap.query.automatic_execution'] === 'false'&&
  83 + ! (force === true)) {
  84 + return;
  85 + }
  86 + this.workspace.unblock();
  87 +
  88 + $(this.workspace.el).find(".workspace_results_info").empty();
  89 + this.workspace.trigger('query:run');
  90 + this.result.result = null;
  91 + // TODO - Validate query
  92 + // maybe we should sync it with the backend query JSON?
  93 + // this definitely needs improvement
  94 + if (this.get('type') != "MDX") {
  95 + var rows = $(this.workspace.el).find('.rows ul li').size();
  96 + var columns = $(this.workspace.el).find('.columns ul li').size();
  97 + if ((rows == 0 && columns == 0) && !this.workspace.other_dimension) {
  98 + var axes = this.get('axes');
  99 + if (axes) {
  100 + for (var axis_iter = 0; axis_iter < axes.length; axis_iter++) {
  101 + var axis = axes[axis_iter];
  102 + if (axis.name && axis.name == "ROWS") {
  103 + rows = axis.dimensionSelections.length;
  104 + }
  105 + if (axis.name && axis.name == "COLUMNS") {
  106 + columns = axis.dimensionSelections.length;
  107 + }
  108 + }
  109 + }
  110 + }
  111 + if (rows == 0 || columns == 0) {
  112 + $(this.workspace.table.el).html('');
  113 + $(this.workspace.processing).html('<span class="i18n">You need to put at least one level or measure on Columns and Rows for a valid query.</span>').show();
  114 + this.workspace.adjust();
  115 + Saiku.i18n.translate();
  116 + return;
  117 + }
  118 + }
  119 +
  120 +
  121 + // Run it
  122 + $(this.workspace.table.el)
  123 + .html('');
  124 + $(this.workspace.processing).html('<span class="processing_image">&nbsp;&nbsp;</span> <span class="i18n">Running query...</span> [&nbsp;<a class="cancel i18n" href="#cancel">Cancel</a>&nbsp;]').show();
  125 + this.workspace.adjust();
  126 + this.workspace.trigger('query:fetch');
  127 + Saiku.i18n.translate();
  128 + // <a class="cancel" href="#cancel">x</a>
  129 +
  130 + var message = '<span class="processing_image">&nbsp;&nbsp;</span> <span class="i18n">Running query...</span> [&nbsp;<a class="cancel i18n" href="#cancel">Cancel</a>&nbsp;]';
  131 + this.workspace.block(message);
  132 +
  133 +
  134 + if (this.get('type') == "MDX" && mdx != null) {
  135 + this.result.save({ mdx: mdx});
  136 + } else {
  137 + this.result.fetch();
  138 + }
  139 + },
  140 +
  141 + move_dimension: function(dimension, target, index) {
  142 + $(this.workspace.el).find('.run').removeClass('disabled_toolbar');
  143 + var url = "/axis/" + target + "/dimension/" + dimension;
  144 +
  145 + this.action.post(url, {
  146 + data: {
  147 + position: index
  148 + },
  149 +
  150 + success: function() {
  151 + if (('MODE' in Settings && (Settings.MODE == 'view' || Settings.MODE == 'table')) || (typeof this.query.properties != "undefined" && this.query.properties
  152 + .properties['saiku.olap.query.automatic_execution'] === 'true')) {
  153 + this.query.run(true);
  154 + }
  155 + }
  156 + });
  157 + },
  158 +
  159 + url: function() {
  160 + return encodeURI(Saiku.session.username + "/query/" + this.uuid);
  161 + }
  162 +});
... ...
ferramentas/saiku/saiku-server/tomcat/webapps/ROOT/js/saiku/models/QueryAction.js 0 → 100755
... ... @@ -0,0 +1,71 @@
  1 +/*
  2 + * Copyright 2012 OSBI Ltd
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +
  17 +/**
  18 + * Model which handles "special" actions against the query
  19 + * Ex.: selections, swap axis, mdx
  20 + */
  21 +var QueryAction = Backbone.Model.extend({
  22 + initialize: function(args, options) {
  23 + // Keep track of query
  24 + this.query = options.query;
  25 +
  26 + // Set default url
  27 + this.url = this.query.url;
  28 + },
  29 +
  30 + get: function(action, options) {
  31 + this.handle("fetch", action, options);
  32 + },
  33 +
  34 + post: function(action, options) {
  35 + this.handle("save", action, options);
  36 + },
  37 +
  38 + put: function(action, options) {
  39 + this.id = _.uniqueId('queryaction_');
  40 + this.handle("save", action, options);
  41 + delete this.id;
  42 + },
  43 +
  44 + del: function(action, options) {
  45 + this.id = _.uniqueId('queryaction_');
  46 + this.handle("delete", action, options);
  47 + delete this.id;
  48 + },
  49 +
  50 + // Call arbitrary actions against the query
  51 + handle: function(method, action, options) {
  52 + // Set query action
  53 + this.url = this.query.url() + action;
  54 +
  55 + // Clear out old attributes
  56 + this.attributes = options.data? options.data : {};
  57 +
  58 + // Initiate action
  59 + if (method == "save") {
  60 + // Handle response from server
  61 + this.parse = options.success;
  62 +
  63 + this.save();
  64 + } else if (method == "delete") {
  65 + this.destroy(options);
  66 + } else if (method == "fetch") {
  67 + this.parse = function() {};
  68 + this.fetch(options);
  69 + }
  70 + }
  71 +});
... ...
ferramentas/saiku/saiku-server/tomcat/webapps/ROOT/js/saiku/models/QueryScenario.js 0 → 100755
... ... @@ -0,0 +1,84 @@
  1 +/*
  2 + * Copyright 2012 OSBI Ltd
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +
  17 +var QueryScenario = Backbone.Model.extend({
  18 + initialize: function(args, options) {
  19 + // Maintain `this`
  20 + _.bindAll(this, "attach_listeners", "activate", "clicked_cell", "save_writeback",
  21 + "cancel_writeback", "check_input");
  22 +
  23 + this.query = options.query;
  24 + },
  25 +
  26 + activate: function() {
  27 + $(this.query.workspace.el).find("td.data").unbind('click').addClass('cellhighlight').click(this.clicked_cell);
  28 + },
  29 +
  30 + attach_listeners: function(args) {
  31 + if (args.workspace.query && args.workspace.query.properties &&
  32 + args.workspace.query.properties.properties['org.saiku.connection.scenario'] === "true" &&
  33 + $(args.workspace.el).find('.query_scenario').hasClass('on'))
  34 + $(args.workspace.el).find("td.data").click(this.clicked_cell);
  35 + },
  36 +
  37 + clicked_cell: function(event) {
  38 + $target = $(event.target).hasClass('data') ?
  39 + $(event.target).find('div') : $(event.target);
  40 + var value = $target.attr('alt');
  41 + var pos = $target.attr('rel');
  42 +
  43 + var $input = $("<input type='text' value='" + value + "' />")
  44 + .keyup(this.check_input)
  45 + .blur(this.cancel_writeback);
  46 + $target.html('').append($input);
  47 + $input.focus();
  48 + },
  49 +
  50 + check_input: function(event) {
  51 + if (event.which == 13) {
  52 + this.save_writeback(event);
  53 + } else if (event.which == 27 || event.which == 9) {
  54 + this.cancel_writeback(event);
  55 + }
  56 +
  57 + return false;
  58 + },
  59 +
  60 + save_writeback: function(event) {
  61 + var $input = $(event.target).closest('input');
  62 + this.set({
  63 + value: $input.val(),
  64 + position: $input.parent().attr('rel')
  65 + });
  66 + this.save();
  67 + var value = $input.val();
  68 + $input.parent().text(value);
  69 + },
  70 +
  71 + cancel_writeback: function(event) {
  72 + var $input = $(event.target).closest('input');
  73 + $input.parent().text($input.parent().attr('alt'));
  74 + },
  75 +
  76 + parse: function() {
  77 + this.query.run();
  78 + },
  79 +
  80 + url: function() {
  81 + return this.query.url() + "/cell/" + this.get('position') +
  82 + "/" + this.get('value');
  83 + }
  84 +});
... ...
ferramentas/saiku/saiku-server/tomcat/webapps/ROOT/js/saiku/models/Repository.js 0 → 100644
... ... @@ -0,0 +1,104 @@
  1 +/*
  2 + * Copyright 2012 OSBI Ltd
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +
  17 +/**
  18 + * Repository query
  19 + */
  20 +
  21 +var RepositoryObject = Backbone.Model.extend( {
  22 + url: function( ) {
  23 + var segment = Settings.BIPLUGIN ?
  24 + "/pentahorepository2/resource" : "/repository2/resource";
  25 + return encodeURI(Saiku.session.username + segment);
  26 + }
  27 +} );
  28 +
  29 +var RepositoryAclObject = Backbone.Model.extend( {
  30 + url: function( ) {
  31 + var segment = Settings.BIPLUGIN ?
  32 + "/pentahorepository2/resource" : "/repository2/resource/acl";
  33 + return encodeURI(Saiku.session.username + segment);
  34 + },
  35 + parse: function(response) {
  36 + if (response != "OK") {
  37 + _.extend(this.attributes, response);
  38 + }
  39 + }
  40 +} );
  41 +
  42 +var SavedQuery = Backbone.Model.extend({
  43 +
  44 + parse: function(response) {
  45 + //console.log("response: " + response);
  46 + //this.xml = response;
  47 + },
  48 +
  49 + url: function() {
  50 + var u = Settings.BIPLUGIN ?
  51 + encodeURI(Saiku.session.username + "/pentahorepository2/resource")
  52 + : encodeURI(Saiku.session.username + "/repository2/resource");
  53 + return u;
  54 + },
  55 +
  56 + move_query_to_workspace: function(model, response) {
  57 + var file = response;
  58 + var filename = model.get('file');
  59 + for (var key in Settings) {
  60 + if (key.match("^PARAM")=="PARAM") {
  61 + var variable = key.substring("PARAM".length, key.length);
  62 + var Re = new RegExp("\\$\\{" + variable + "\\}","g");
  63 + var Re2 = new RegExp("\\$\\{" + variable.toLowerCase() + "\\}","g");
  64 + file = file.replace(Re,Settings[key]);
  65 + file = file.replace(Re2,Settings[key]);
  66 +
  67 + }
  68 + }
  69 + //substitui o nome da conexao para usar a atual
  70 + //i3Geo
  71 + var xml1 = file.split("connection=");
  72 + var xml2 = file.split("cube=");
  73 + var file = xml1[0] + 'connection="' + Settings.NOMECONEXAO + '" cube=' + xml2[1];
  74 + var query = new Query({
  75 + xml: file,
  76 + formatter: Settings.CELLSET_FORMATTER
  77 + },{
  78 + name: filename
  79 + });
  80 +
  81 + var tab = Saiku.tabs.add(new Workspace({ query: query }));
  82 + }
  83 +});
  84 +
  85 +/**
  86 + * Repository adapter
  87 + */
  88 +var Repository = Backbone.Collection.extend({
  89 + model: SavedQuery,
  90 +
  91 + initialize: function(args, options) {
  92 + this.dialog = options.dialog;
  93 + },
  94 +
  95 + parse: function(response) {
  96 + this.dialog.populate(response);
  97 + },
  98 +
  99 + url: function() {
  100 + var segment = Settings.BIPLUGIN ?
  101 + "/pentahorepository2/?type=saiku" : "/repository2/?type=saiku";
  102 + return encodeURI(Saiku.session.username + segment);
  103 + }
  104 +});
... ...
ferramentas/saiku/saiku-server/tomcat/webapps/ROOT/js/saiku/models/Result.js 0 → 100755
... ... @@ -0,0 +1,54 @@
  1 +/*
  2 + * Copyright 2012 OSBI Ltd
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +
  17 +/**
  18 + * Holds the resultset for a query, and notifies plugins when resultset updated
  19 + */
  20 +var Result = Backbone.Model.extend({
  21 +
  22 + result: null,
  23 + firstRun: false,
  24 +
  25 + initialize: function(args, options) {
  26 + // Keep reference to query
  27 + this.query = options.query;
  28 + },
  29 +
  30 + parse: function(response) {
  31 + // Show the UI if hidden
  32 + $(this.workspace).unblock();
  33 + Saiku.ui.unblock();
  34 + this.result = response;
  35 + this.firstRun = true;
  36 + this.query.workspace.trigger('query:result', {
  37 + workspace: this.query.workspace,
  38 + data: response
  39 + });
  40 +
  41 + },
  42 +
  43 + hasRun: function() {
  44 + return this.firstRun;
  45 + },
  46 +
  47 + lastresult: function () {
  48 + return this.result;
  49 + },
  50 +
  51 + url: function() {
  52 + return encodeURI(this.query.url() + "/result/" + this.query.get('formatter'));
  53 + }
  54 +});
... ...
ferramentas/saiku/saiku-server/tomcat/webapps/ROOT/js/saiku/models/Session.js 0 → 100755
... ... @@ -0,0 +1,117 @@
  1 +/*
  2 + * Copyright 2012 OSBI Ltd
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +
  17 +/**
  18 + * Object which handles authentication and stores connections and cubes
  19 + * @param username
  20 + * @param password
  21 + * @returns {Session}
  22 + */
  23 +var Session = Backbone.Model.extend({
  24 + username: null,
  25 + password: null,
  26 + sessionid: null,
  27 +
  28 + initialize: function(args, options) {
  29 + // Attach a custom event bus to this model
  30 + _.extend(this, Backbone.Events);
  31 + _.bindAll(this, "check_session", "process_session", "load_session","login");
  32 + // Check if credentials are being injected into session
  33 + if (options && options.username && options.password) {
  34 + this.username = options.username;
  35 + this.password = options.password;
  36 + this.save({username:this.username, password:this.password},{success: this.check_session, error: this.check_session});
  37 +
  38 + } else {
  39 + this.check_session();
  40 + }
  41 + },
  42 +
  43 + check_session: function() {
  44 + if (this.sessionid === null || this.username === null || this.password === null) {
  45 + this.clear();
  46 + this.fetch({ success: this.process_session })
  47 + } else {
  48 + this.username = encodeURIComponent(options.username);
  49 + this.load_session();
  50 + }
  51 + },
  52 +
  53 + load_session: function() {
  54 + this.sessionworkspace = new SessionWorkspace();
  55 + },
  56 +
  57 + process_session: function(model, response) {
  58 + if ((response === null || response.sessionid == null)) {
  59 + // Open form and retrieve credentials
  60 + Saiku.ui.unblock();
  61 + this.form = new LoginForm({ session: this });
  62 + this.form.render().open();
  63 + } else {
  64 + this.sessionid = response.sessionid;
  65 + this.roles = response.roles;
  66 + this.username = encodeURIComponent(response.username);
  67 + this.language = response.language;
  68 + if (typeof this.language != "undefined" && this.language != Saiku.i18n.locale) {
  69 + Saiku.i18n.locale = this.language;
  70 + Saiku.i18n.automatic_i18n();
  71 + }
  72 + this.load_session();
  73 + }
  74 +
  75 + return this;
  76 + },
  77 +
  78 + error: function() {
  79 + $(this.form.el).dialog('open');
  80 + },
  81 +
  82 + login: function(username, password) {
  83 + // Set expiration on localStorage to one day in the future
  84 + var expires = (new Date()).getTime() +
  85 + Settings.LOCALSTORAGE_EXPIRATION;
  86 + typeof localStorage !== "undefined" && localStorage && localStorage.setItem('expiration', expires);
  87 +
  88 + this.save({username:username, password:password},{success: this.check_session, error: this.check_session});
  89 +
  90 + },
  91 +
  92 + logout: function() {
  93 + // FIXME - This is a hack (inherited from old UI)
  94 + Saiku.ui.unblock();
  95 + $('#header').empty().hide();
  96 + $('#tab_panel').remove();
  97 + Saiku.tabs = new TabSet();
  98 + Saiku.toolbar.remove();
  99 + Saiku.toolbar = new Toolbar();
  100 + typeof localStorage !== "undefined" && localStorage && localStorage.clear();
  101 + this.id = _.uniqueId('queryaction_');
  102 + this.clear();
  103 + this.sessionid = null;
  104 + this.username = null;
  105 + this.password = null;
  106 + this.destroy({async: false });
  107 + //console.log("REFRESH!");
  108 + document.location.reload(false)
  109 + delete this.id;
  110 +
  111 + },
  112 +
  113 + url: function() {
  114 +
  115 + return "session";
  116 + }
  117 +});
... ...
ferramentas/saiku/saiku-server/tomcat/webapps/ROOT/js/saiku/models/SessionWorkspace.js 0 → 100644
... ... @@ -0,0 +1,151 @@
  1 +/*
  2 + * Copyright 2012 OSBI Ltd
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +
  17 +/**
  18 + * Object which handles sessionworkspace and stores connections and cubes
  19 + * @param username
  20 + * @param password
  21 + * @returns {Session}
  22 + */
  23 +var SessionWorkspace = Backbone.Model.extend({
  24 +
  25 + initialize: function(args, options) {
  26 + // Attach a custom event bus to this model
  27 + _.extend(this, Backbone.Events);
  28 + _.bindAll(this, "process_datasources", "prefetch_dimensions");
  29 + this.initialized = false;
  30 + this.first = true;
  31 + // Check expiration on localStorage
  32 + if (typeof localStorage !== "undefined" && localStorage) {
  33 + if (localStorage.getItem('expiration') && !(localStorage.getItem('expiration') > (new Date()).getTime())) {
  34 + localStorage.clear();
  35 + } else if (!localStorage.getItem('saiku-version') || (localStorage.getItem('saiku-version') !== Settings.VERSION) ) {
  36 + localStorage.clear();
  37 + }
  38 + }
  39 + Saiku.ui.block("Loading datasources....");
  40 + this.fetch({success:this.process_datasources},{});
  41 + this.refresh();
  42 + },
  43 +
  44 + refresh: function() {
  45 + typeof localStorage !== "undefined" && localStorage && localStorage.clear();
  46 + this.clear();
  47 + localStorage.setItem('saiku-version', Settings.VERSION);
  48 + this.fetch({success:this.process_datasources},{});
  49 + },
  50 +
  51 + destroy: function() {
  52 + typeof localStorage !== "undefined" && localStorage && localStorage.clear();
  53 + return false;
  54 + },
  55 +
  56 + process_datasources: function(model, response) {
  57 + // Save session in localStorage for other tabs to use
  58 + if (typeof localStorage !== "undefined" && localStorage && localStorage.getItem('session') === null) {
  59 + localStorage.setItem('session', JSON.stringify(response));
  60 + }
  61 +
  62 + // Generate cube navigation for reuse
  63 + this.cube_navigation = _.template($("#template-cubes").html())({
  64 + connections: response
  65 + });
  66 +
  67 +
  68 + // Create cube objects
  69 + this.dimensions = {};
  70 + this.measures = {};
  71 + this.connections = response;
  72 + _.delay(this.prefetch_dimensions, 20);
  73 +
  74 + if (!this.initialized) {
  75 + // Show UI
  76 + $(Saiku.toolbar.el).prependTo($("#header"));
  77 + $("#header").show();
  78 + Saiku.ui.unblock();
  79 + // Add initial tab
  80 + Saiku.tabs.render();
  81 + if (! Settings.ACTION) {
  82 + Saiku.tabs.add(new Workspace());
  83 + }
  84 + // Notify the rest of the application that login was successful
  85 + Saiku.events.trigger('session:new', {
  86 + session: this
  87 + });
  88 + } else {
  89 + if (! Settings.ACTION) {
  90 + Saiku.tabs.add(new Workspace());
  91 + }
  92 +
  93 + }
  94 + },
  95 +
  96 + prefetch_dimensions: function() {
  97 + if (! this.measures || ! this.dimensions) {
  98 + Log.log({
  99 + Message: "measures or dimensions not initialized",
  100 + Session: JSON.stringify(this)
  101 + });
  102 + return;
  103 + }
  104 +
  105 + for(var i = 0; i < this.connections.length; i++) {
  106 + var connection = this.connections[i];
  107 + for(var j = 0; j < connection.catalogs.length; j++) {
  108 + var catalog = connection.catalogs[j];
  109 + for(var k = 0; k < catalog.schemas.length; k++) {
  110 + var schema = catalog.schemas[k];
  111 + for(var l = 0; l < schema.cubes.length; l++) {
  112 + var cube = schema.cubes[l];
  113 + var key = connection.name + "/" + catalog.name + "/"
  114 + + ((schema.name == "" || schema.name == null) ? "null" : schema.name)
  115 + + "/" + encodeURIComponent(cube.name);
  116 +
  117 + if (typeof localStorage !== "undefined" && localStorage &&
  118 + localStorage.getItem("dimension." + key) !== null &&
  119 + localStorage.getItem("measure." + key) !== null) {
  120 + this.dimensions[key] = new Dimension(JSON.parse(localStorage.getItem("dimension." + key)));
  121 + this.measures[key] = new Measure(JSON.parse(localStorage.getItem("measure." + key)));
  122 + } else {
  123 + this.dimensions[key] = new Dimension({ key: key });
  124 + this.measures[key] = new Measure({ key: key });
  125 + if (Settings.DIMENSION_PREFETCH === true) {
  126 + this.dimensions[key].fetch();
  127 + this.measures[key].fetch();
  128 + }
  129 + }
  130 + }
  131 + }
  132 + }
  133 + }
  134 +
  135 + // Start routing
  136 + if (!this.initialized && Backbone.history) {
  137 + Backbone.history.start();
  138 + this.initialized = true;
  139 + }
  140 + },
  141 +
  142 + url: function() {
  143 + if (this.first) {
  144 + this.first = false;
  145 + return encodeURI(Saiku.session.username + "/discover");
  146 + }
  147 + else {
  148 + return encodeURI(Saiku.session.username + "/discover/refresh");
  149 + }
  150 + }
  151 +});
... ...