diff --git a/.gitignore b/.gitignore
index 776c258..884b522 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,3 +8,4 @@ app/bower_components
target
.checkDependencies
test-results.xml
+private/
\ No newline at end of file
diff --git a/app/frameset.html b/app/frameset.html
new file mode 100644
index 0000000..1a20dd4
--- /dev/null
+++ b/app/frameset.html
@@ -0,0 +1,19 @@
+
+
+
+ Scenario Analysis
+
+
+
+
+
+
+
+
+
+
diff --git a/app/index.html b/app/index.html
index 4b6bd21..d55fe6d 100644
--- a/app/index.html
+++ b/app/index.html
@@ -563,6 +563,8 @@
+
+
diff --git a/app/scripts/controllers/drupalContextProviderDirectiveController.js b/app/scripts/controllers/drupalContextProviderDirectiveController.js
new file mode 100644
index 0000000..c9b97c8
--- /dev/null
+++ b/app/scripts/controllers/drupalContextProviderDirectiveController.js
@@ -0,0 +1,486 @@
+angular.module(
+ 'eu.myclimateservice.csis.scenario-analysis.controllers'
+ ).controller(
+ 'eu.myclimateservice.csis.scenario-analysis.controllers.drupalContextProviderDirectiveController',
+ [
+ '$scope',
+ '$timeout',
+ 'de.cismet.crisma.ICMM.services.icmm',
+ 'de.cismet.crisma.ICMM.Worldstates',
+ 'eu.myclimateservice.csis.scenario-analysis.services.drupalService',
+ function ($scope, $timeout, Icmm, Worldstates, drupalService) {
+ 'use strict';
+ var showIndicatorFileLoadingError, showFileLoading, loadIndicatorObjects, loadIndicatorObject, onloadCfFile, onloadDsFile;
+ var restApi = drupalService.restApi;
+
+ //initialize the bindings
+ $scope.selectedWorldstates = [];
+ $scope.worldstates = [];
+ $scope.criteriaFunctions = [];
+ $scope.decisionStrategies = [];
+ $scope.showDummyListItem = true;
+ $scope.removeSelectionBtnDisabled = true;
+ $scope.removeSelectionButtonStyle = {
+ 'color': '#888'
+ };
+ $scope.noIndicatorsLoaded = true;
+ /*
+ * the indicator maps keeps track of the indicators that each object
+ * (e.g. indicator object, criteriaFunction and decisionStrategy) that are loaded by this directive
+ * must provide
+ */
+ $scope.tooltipRename = {
+ title: 'Rename criteria function'
+ };
+ $scope.tooltipRenameDone = {
+ title: 'Done'
+ };
+ $scope.tooltipDeleteSelection = {
+ title: 'Done'
+ };
+ $scope.tooltipDeleteSelection = {
+ title: 'Remove selection'
+ };
+ $scope.tooltipAdd = {
+ title: 'Add Icc Objects from file'
+ };
+ $scope.editable = [];
+ $scope.toggleSelection = function (index) {
+ var wsToToggle, i, isSelected;
+ wsToToggle = $scope.worldstates[index];
+ //check if the worldstate is already contained in the selectedWorldstates array..
+ isSelected = -1;
+ for (i = 0; i < $scope.selectedWorldstates.length; i++) {
+ if ($scope.selectedWorldstates[i].id === wsToToggle.id) {
+ isSelected = i;
+ break;
+ }
+ }
+
+ if (isSelected >= 0) {
+ $scope.selectedWorldstates.splice(isSelected, 1);
+ } else {
+ $scope.selectedWorldstates.push(wsToToggle);
+ }
+ };
+
+ $scope.$watchCollection('selectedWorldstates', function () {
+ //if no indicator objects are selected anymore whe need to disable the button
+ if ($scope.selectedWorldstates.length <= 0) {
+ $scope.removeSelectionBtnDisabled = true;
+ $scope.removeSelectionButtonStyle = {
+ 'color': '#CCC'
+ };
+ } else {
+ $scope.removeSelectionBtnDisabled = false;
+ $scope.removeSelectionButtonStyle = {};
+ }
+ });
+
+ $scope.getItemStyle = function (index) {
+ var c = 'list-group-item';
+ var wsToToggle, i, isSelected;
+ wsToToggle = $scope.worldstates[index];
+ //check if the worldstate is already contained in the selectedWorldstates array..
+ isSelected = -1;
+ for (i = 0; i < $scope.selectedWorldstates.length; i++) {
+ if ($scope.selectedWorldstates[i].id === wsToToggle.id) {
+ isSelected = i;
+ }
+ }
+
+ if (isSelected >= 0) {
+ c += ' list-group-item-info';
+ }
+
+ return c;
+ };
+
+ //check if the File API is available
+ $scope.fileAPIAvailable = (window.File && window.FileReader && window.FileList && window.Blob) ? true : false;
+
+ $scope.removeSelectedDummyWS = function () {
+ var i, j, indexToRemove;
+ if ($scope.removeSelectionBtnDisabled) {
+ return;
+ }
+ indexToRemove = [];
+ for (i = 0; i < $scope.selectedWorldstates.length; i++) {
+ for (j = 0; j < $scope.worldstates.length; j++) {
+ if (angular.equals($scope.worldstates[j], $scope.selectedWorldstates[i])) {
+ indexToRemove.push(j);
+ }
+ }
+ }
+ for (i = indexToRemove.length - 1; i >= 0; i--) {
+ $scope.worldstates.splice(indexToRemove[i], 1);
+ }
+ $scope.selectedWorldstates = [];
+ };
+
+ /*
+ * be carefull calling this function from angular contexts
+ * @param {type} file that could not be loaded properly...
+ * @returns {undefined}
+ */
+ showIndicatorFileLoadingError = function (message) {
+ $scope.fileLoadError = true;
+ $scope.errorMessage = message;
+ $scope.$apply();
+ };
+
+ showFileLoading = function () {
+ $scope.fileLoadError = false;
+ $scope.fileLoading = true;
+ };
+
+ $scope.fileLoadError = false;
+ $scope.fileLoading = false;
+
+ $scope.showCfFileLoadingError = function (message) {
+ $scope.cfFileLoadError = true;
+ $scope.cfFileLoadErrorMsg = 'Criteria functions not loaded. ' + message;
+ $scope.$apply();
+ };
+
+ $scope.showDsFileLoadingError = function (message) {
+ $scope.dsFileLoadError = true;
+ $scope.dsFileLoadErrorMsg = 'Decision strategies not loaded. ' + message;
+ $scope.$apply();
+ };
+
+ loadIndicatorObjects = function (indicatorObjects) {
+ var arrayLength = indicatorObjects.length;
+ for (var i = 0; i < arrayLength; i++) {
+ loadIndicatorObject(indicatorObjects[i]);
+ }
+ };
+
+ loadIndicatorObject = function (indicatorObject) {
+ var worldstateDummy, indicatorProp, indicator, origLoadedIndicators, indicatorGroup,
+ loadedIndicatorLength, indicatorMapLength, containsIndicator, msg;
+ try {
+
+ /*
+ *
+ * accept two differnt kind of files.
+ * 1. A plain icc data object.
+ * In that case we apply a standard name to this object
+ *
+ * 2. A worldstate Dummy object that already has a name
+ */
+
+ if (indicatorObject.name && indicatorObject.iccdata) {
+ worldstateDummy = indicatorObject;
+ origLoadedIndicators = indicatorObject.iccdata;
+ worldstateDummy.iccdata = {
+ // this is a total mess: serialise the deserialized icc data again
+ // so that it can be deserilaized by icmm helper library
+ actualaccessinfo: JSON.stringify(worldstateDummy.iccdata)
+ };
+ } else {
+ //generate a uniqe id...
+ origLoadedIndicators = indicatorObject;
+ worldstateDummy = {
+ name: 'Nonamed indicator data',
+ iccdata: {
+ actualaccessinfo: JSON.stringify(indicatorObject)
+ }
+ };
+ }
+ var tmp;
+ if ($scope.worldstates && $scope.worldstates.length > 0) {
+ tmp = Worldstates.utils.stripIccData([$scope.worldstates[0]])[0].data;
+ } else {
+ tmp = origLoadedIndicators;
+ }
+ $scope.indicatorMap = {};
+ for (indicatorGroup in tmp) {
+ if (tmp.hasOwnProperty(indicatorGroup)) {
+ for (indicatorProp in tmp[indicatorGroup]) {
+ if (tmp[indicatorGroup].hasOwnProperty(indicatorProp)) {
+ if (indicatorProp !== 'displayName' && indicatorProp !== 'iconResource') {
+ $scope.indicatorMap[indicatorProp] = tmp[indicatorGroup][indicatorProp];
+ }
+ }
+ }
+ }
+ }
+ loadedIndicatorLength = 0;
+ indicatorMapLength = 0;
+ for (indicator in $scope.indicatorMap) {
+ if ($scope.indicatorMap.hasOwnProperty(indicator)) {
+ containsIndicator = false;
+ indicatorMapLength++;
+ for (indicatorGroup in origLoadedIndicators) {
+ if (origLoadedIndicators.hasOwnProperty(indicatorGroup)) {
+ for (indicatorProp in origLoadedIndicators[indicatorGroup]) {
+ if (origLoadedIndicators[indicatorGroup].hasOwnProperty(indicatorProp)) {
+ if (indicatorProp !== 'displayName' && indicatorProp !== 'iconResource') {
+ if ($scope.indicatorMap[indicator].displayName === origLoadedIndicators[indicatorGroup][indicatorProp].displayName) {
+ loadedIndicatorLength++;
+ containsIndicator = true;
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ if (!containsIndicator) {
+ msg = 'Could not load indicator file. It contains no indicator data for ' + indicator;
+ console.error(msg);
+ showIndicatorFileLoadingError(msg);
+ return;
+ }
+ }
+ }
+ if (loadedIndicatorLength !== indicatorMapLength) {
+ msg = 'indicator data in file has more indicators defined that the first loaded indicator set.';
+ console.error(msg);
+ showIndicatorFileLoadingError(msg);
+ return;
+ }
+
+ // we need an id to distinct the icc objects. eg. the ranking table use this id
+ // to keep track of the indicator objects
+ if (!worldstateDummy.id) {
+ worldstateDummy.id = Math.floor((Math.random() * 1000000) + 1);
+ }
+
+ // an excellent example on technical debt and accidental complexity:
+ // instead of adressing the root cause of the problem, we
+ // introduce additional inadequateness and ambiguity
+ Icmm.convertToCorrectIccDataFormat(worldstateDummy);
+
+ if ($scope.worldstates) {
+ $scope.worldstates.push(worldstateDummy);
+ $scope.editable.push(false);
+ } else {
+ $scope.editable.push(false);
+ $scope.worldstates = [worldstateDummy];
+ }
+ $scope.showDummyListItem = false;
+ $scope.noIndicatorsLoaded = false;
+ // when indicator objects are added we want them to be selected by default
+ $scope.selectedWorldstates.splice(0, $scope.selectedWorldstates.length);
+ $scope.worldstates.forEach(function (object, index) {
+ $scope.toggleSelection(index);
+ });
+
+ //$scope.$apply();
+
+ } catch (err) {
+ // show an error in the gui...
+ showIndicatorFileLoadingError(err.toString());
+ }
+ };
+
+ onloadCfFile = function (theFile) {
+ return function (e) {
+ var cfSet, cf, i, j, indicatorProp, indicatorFound, cfIndicator, msg, indicatorMapLength,
+ cfIndicatorLength;
+ try {
+ cfSet = JSON.parse(e.target.result);
+
+ if (Object.prototype.toString.call(cfSet) === '[object Array]') {
+ indicatorMapLength = 0;
+ for (indicatorProp in $scope.indicatorMap) {
+ if ($scope.indicatorMap.hasOwnProperty(indicatorProp)) {
+ indicatorMapLength++;
+ }
+ }
+ // we need to check if the criteria Functions defined in the file
+ // match to the indicators of the loaded indicator files...
+ for (indicatorProp in $scope.indicatorMap) {
+ if ($scope.indicatorMap.hasOwnProperty(indicatorProp)) {
+ for (i = 0; i < cfSet.length; i++) {
+ cf = cfSet[i];
+ cfIndicatorLength = cf.criteriaFunctions.length;
+ for (j = 0; j < cf.criteriaFunctions.length; j++) {
+ cfIndicator = cf.criteriaFunctions[j].indicator;
+ indicatorFound = false;
+
+ if ($scope.indicatorMap[indicatorProp].displayName === cfIndicator) {
+ indicatorFound = true;
+ break;
+ }
+ }
+ if (!indicatorFound) {
+ msg = 'Could not find indicator "' + $scope.indicatorMap[indicatorProp].displayName + '" in criteria function "' + cf.name + '"';
+ console.error(msg);
+ $scope.showCfFileLoadingError(msg);
+ return;
+ }
+ if (cfIndicatorLength !== indicatorMapLength) {
+ msg = 'Criteria Function :"' + cf.name + '" contains more indicators than the loaded indicator files.';
+ console.error(msg);
+ $scope.showCfFileLoadingError(msg);
+ return;
+ }
+ }
+ }
+ }
+ $scope.criteriaFunctions = cfSet;
+ $scope.loadedCfFile = theFile.name;
+
+ }
+ $scope.$apply();
+ } catch (err) {
+ // show an error in the gui...
+ console.error('Could not read Criteria Function Config File: ' + theFile.name);
+ }
+ };
+ };
+
+ onloadDsFile = function (theFile) {
+ return function (e) {
+ var ds, s, i, j, indicatorProp, indicatorFound, cfIndicator, msg, indicatorMapLength, dsIndicatorLength;
+ try {
+ ds = JSON.parse(e.target.result);
+
+ if (Object.prototype.toString.call(ds) === '[object Array]') {
+ indicatorMapLength = 0;
+ for (indicatorProp in $scope.indicatorMap) {
+ if ($scope.indicatorMap.hasOwnProperty(indicatorProp)) {
+ indicatorMapLength++;
+ }
+ }
+ // we need to check if the decision strategies defined in the file
+ // match to the indicators of the loaded indicator files...
+ for (indicatorProp in $scope.indicatorMap) {
+ for (i = 0; i < ds.length; i++) {
+ s = ds[i];
+ dsIndicatorLength = s.criteriaEmphases.length;
+ for (j = 0; j < s.criteriaEmphases.length; j++) {
+ cfIndicator = s.criteriaEmphases[j].indicator.displayName;
+ indicatorFound = false;
+
+ if ($scope.indicatorMap[indicatorProp].displayName === cfIndicator) {
+ indicatorFound = true;
+ break;
+ }
+ }
+ if (s.satisfactionEmphasis.length !== indicatorMapLength) {
+ msg = 'Satisfaction Emphasis Vector for decision strategy :"' + ds.name + '" contains more elements than indicator are defined';
+ console.error(msg);
+ $scope.showDsFileLoadingError(msg);
+ return;
+ }
+ if (!indicatorFound) {
+ msg = 'Could not find indicator "' + $scope.indicatorMap[indicatorProp].displayName + '" in decision strategy "' + s.name + '"';
+ console.error(msg);
+ $scope.showDsFileLoadingError(msg);
+ return;
+ }
+ if (dsIndicatorLength !== indicatorMapLength) {
+ msg = 'Decision strategy :"' + ds.name + '" contains more indicators than the loaded indicator files.';
+ console.error(msg);
+ $scope.showDsFileLoadingError(msg);
+ return;
+ }
+ }
+ }
+ $scope.loadedDsfFile = theFile.name;
+ $scope.decisionStrategies = ds;
+ }
+ $scope.$apply();
+ } catch (err) {
+ // show an error in the gui...
+ console.error('Could not read Decision Strategy Config File: ' + theFile.name);
+ }
+ };
+ };
+
+ /*
+ * When the newFile property has changed the User want's to add a new list of files.
+ */
+ $scope.$watch('iccObjects', function (newVal, oldVal) {
+ /*var i, file, reader;
+ if (!angular.equals(newVal, oldVal) && newVal) {
+ showFileLoading();
+
+ for (i = 0; i < $scope.iccObjects.length; i++) {
+
+ file = $scope.iccObjects[i];
+
+ reader = new FileReader();
+ reader.onload = onloadIccObjects(file);
+ try {
+ //we assume that the file is utf-8 encoded
+ reader.readAsText(file);
+ } catch (err) {
+ // show an error in the gui...
+ showIndicatorFileLoadingError(err.toString());
+ }
+
+ }
+
+ }*/
+ }, true);
+
+ $scope.$watch('cfConfigFile', function () {
+ var file;
+ $scope.cfFileLoadError = false;
+ $scope.loadedCfFile = false;
+ if ($scope.cfConfigFile) {
+ showFileLoading();
+
+ file = $scope.cfConfigFile[0];
+
+ var reader = new FileReader();
+ reader.onload = onloadCfFile(file);
+
+ try {
+ //we assume that the file is utf-8 encoded
+ reader.readAsText(file);
+ } catch (err) {
+ // show an error in the gui...
+ console.error('Could not read Criteria Function Config File: ' + file.name);
+ }
+ }
+
+ }, true);
+
+ $scope.$watch('dsConfigFile', function () {
+ var file;
+ $scope.dsFileLoadError = false;
+ $scope.loadedDsfFile = false;
+ if ($scope.dsConfigFile) {
+ showFileLoading();
+
+ file = $scope.dsConfigFile[0];
+
+ var reader = new FileReader();
+ reader.onload = onloadDsFile(file);
+
+ try {
+ //we assume that the file is utf-8 encoded
+ reader.readAsText(file);
+ } catch (err) {
+ // show an error in the gui...
+ console.error('Could not read Decision Strategy Config File: ' + file.name);
+ }
+
+ }
+
+ }, true);
+
+
+ $timeout(function () {
+ restApi.getStudy(1).then(function (study) {
+ var indicatorArray = drupalService.studyHelper.getIndicatorArray(study);
+ loadIndicatorObjects(indicatorArray);
+ }, function (error) {
+ console.log(error.data.message);
+ showIndicatorFileLoadingError(error.data.message.toString());
+ });
+ }, 1000);
+
+
+
+ }
+ ]
+ );
+
+
diff --git a/app/scripts/controllers/mainController.js b/app/scripts/controllers/mainController.js
index 47f69c3..fbe64ef 100644
--- a/app/scripts/controllers/mainController.js
+++ b/app/scripts/controllers/mainController.js
@@ -19,8 +19,9 @@ angular.module(
'$q',
'eu.myclimateservice.csis.scenario-analysis.services.IcmmPersistanceService',
'eu.myclimateservice.csis.scenario-analysis.services.FilesPersistanceService',
+ 'eu.myclimateservice.csis.scenario-analysis.services.drupalService',
'ngDialog',
- function ($window, $scope, $resource, $http, $timeout, $q, IcmmPersistanceService, FilesPersistanceService, ngDialog) {
+ function ($window, $scope, $resource, $http, $timeout, $q, IcmmPersistanceService, FilesPersistanceService, drupalService, ngDialog) {
'use strict';
var parent = window.seamless.connect();
@@ -30,8 +31,9 @@ angular.module(
// Print out the data that was received.
console.log('child recieved: ' + data + event);
});
-
- var drupal = 'http://roberto:8080';
+
+ var restApi = drupalService.restApi;
+
var createChartModels;
// we bind to the container object since the provider directives are nested in angular-bootstrap tabs
@@ -270,12 +272,12 @@ angular.module(
$window.html2canvas(document.getElementById(elementId), {logging: true, foreignObjectRendering: foreignObjectRendering}).then(canvas => {
document.body.appendChild(canvas);
var imageBlob = canvas.toDataURL().replace(/^data:image\/(png|jpg);base64,/, '');
-
+
//console.log(dataURL);
var payload = {
'_links': {
'type': {
- 'href': drupal + '/rest/type/file/image'
+ 'href': restApi.host + '/rest/type/file/image'
}
},
'filename': [
@@ -298,10 +300,10 @@ angular.module(
/**
* 1) get the X-CSRF-Token
*/
- $http({method: 'GET', url: drupal + '/rest/session/token'})
+ $http({method: 'GET', url: restApi.host + '/rest/session/token'})
.then(function tokenSuccessCallback(response) {
- var uploadImage = $resource(drupal + '/entity/file',
+ var uploadImage = $resource(restApi.host + '/entity/file',
{
_format: 'hal_json'
}, {
@@ -325,8 +327,8 @@ angular.module(
// return the image id
return response.fid[0];
}, function uploadImageError(response) {
- console.log('error uploading Image: ' + response);
- $q.reject(response);
+ console.log('error uploading Image: ' + response.data.message);
+ $q.reject(response.data);
});
}, function tokenErrorCallback(response) {
console.log('error retrieving X-CSRF-Token: ' + response);
@@ -338,7 +340,7 @@ angular.module(
*/
function successCallback(response) {
console.log('image id: ' + response);
-
+
// TODO UPDATE Resource
},
function errorCallback(response) {
@@ -360,7 +362,5 @@ angular.module(
});*/
});
};
-
}
- ]
- );
+ ]);
diff --git a/app/scripts/directives/fileBasedAnalysisContextProvider.js b/app/scripts/directives/fileBasedAnalysisContextProvider.js
index f358fbf..c32bf1a 100644
--- a/app/scripts/directives/fileBasedAnalysisContextProvider.js
+++ b/app/scripts/directives/fileBasedAnalysisContextProvider.js
@@ -19,7 +19,8 @@ angular.module(
scope: scope,
restrict: 'E',
templateUrl: 'templates/fileContextProviderTemplate.html',
- controller: 'eu.myclimateservice.csis.scenario-analysis.controllers.FileContextProviderDirectiveController'
+ //controller: 'eu.myclimateservice.csis.scenario-analysis.controllers.FileContextProviderDirectiveController'
+ controller: 'eu.myclimateservice.csis.scenario-analysis.controllers.drupalContextProviderDirectiveController'
};
}
]
diff --git a/app/scripts/services/drupalDecisionStrategies.js b/app/scripts/services/drupalDecisionStrategies.js
new file mode 100644
index 0000000..56edb05
--- /dev/null
+++ b/app/scripts/services/drupalDecisionStrategies.js
@@ -0,0 +1,93 @@
+angular.module(
+ 'eu.myclimateservice.csis.scenario-analysis.services'
+ ).factory(
+ 'eu.myclimateservice.csis.scenario-analysis.services.DecisionStrategies',
+ [
+ '$resource',
+ 'eu.myclimateservice.csis.scenario-analysis.services.configurationService',
+ function ($resource, configurationService) {
+ 'use strict';
+ var decisionStrategy, transformResponse, decisionStrategyFacade, createResource;
+ transformResponse = function (studyJsonString) {
+ var study;
+ if (studyJsonString) {
+ study = JSON.parse(studyJsonString);
+
+ return JSON.parse(study.decisionStrategies);
+ }
+ return null;
+
+ };
+
+
+
+ createResource = function () {
+ var r;
+
+ r = $resource(configurationService.$this.drupalRestApi.host + '/' + configurationService.getDomain() + '.decisionstrategies/1', {
+ decisionStrategyId: '@id',
+ deduplicate: false,
+ omitNullValues: 'false'
+ }, {
+ 'query': {
+ method: 'GET',
+ isArray: true,
+ params: {
+ level: '1',
+ omitNullValues: 'true'
+ },
+ transformResponse: transformResponse
+ },
+ 'update': {
+ method: 'PUT',
+ transformRequest: function (data) {
+ var transformedData, study;
+ study = {
+ $self: '/CRISMA.decisionstrategies/1',
+ id: 1,
+ decisionStrategies: angular.toJson(data)
+ };
+ transformedData = JSON.stringify(study, function (k, v) {
+ // we have to take care of angular properties by ourselves
+ if (k.substring(0, 1) === '$' && !(k === '$self' || k === '$ref')) {
+ return undefined;
+ }
+
+ return v;
+ });
+ return transformedData;
+ }
+ }
+ });
+
+ r.getId = function () {
+ return Icmm.getNextId(configurationService.getIcmmApi() + '/' + configurationService.getDomain(), '.decisionstrategies');
+ };
+
+ return r;
+ };
+
+ decisionStrategy = createResource();
+ decisionStrategyFacade = {
+ 'get': function () {
+ return decisionStrategy.get.apply(this, arguments);
+ },
+ 'query': function () {
+ return decisionStrategy.query.apply(this, arguments);
+ },
+ 'update': function () {
+ return decisionStrategy.update.apply(this, arguments);
+ },
+ 'getId': function () {
+ return decisionStrategy.getId.apply(this, arguments);
+ }
+ };
+
+ configurationService.addApiListener(function () {
+ decisionStrategy = createResource();
+ });
+
+ return decisionStrategyFacade;
+ }
+ ]
+ );
diff --git a/app/scripts/services/drupalService.js b/app/scripts/services/drupalService.js
new file mode 100644
index 0000000..db2c178
--- /dev/null
+++ b/app/scripts/services/drupalService.js
@@ -0,0 +1,106 @@
+/*
+ * ***************************************************
+ *
+ * cismet GmbH, Saarbruecken, Germany
+ *
+ * ... and it just works.
+ *
+ * ***************************************************
+ */
+
+/*global angular*/
+/*jshint sub:true*/
+
+angular.module(
+ 'eu.myclimateservice.csis.scenario-analysis.services'
+ ).factory('eu.myclimateservice.csis.scenario-analysis.services.drupalService',
+ ['$http', '$resource', '$q', function ($http, $resource, $q) {
+ 'use strict';
+
+ var $this;
+ $this = this;
+
+ //
+ $this.drupalRestApi = {};
+ $this.drupalRestApi.host = ''; //http://roberto:8080';
+ $this.drupalRestApi.token = undefined;
+ //
+
+ $this.drupalRestApi.initToken = function () {
+ return $http({method: 'GET', url: $this.drupalRestApi.host + '/rest/session/token'})
+ .then(function tokenSuccessCallback(response) {
+ $this.drupalRestApi.token = response.data;
+ console.log('X-CSRF-Token recieved from API: ' + $this.drupalRestApi.token);
+ return response.data;
+ }, function tokenErrorCallback(response) {
+ $this.drupalRestApi.token = undefined;
+ console.log('error retrieving X-CSRF-Token: ' + response);
+ $q.reject(undefined);
+ });
+ };
+
+ /**
+ * return a promise!
+ */
+ $this.drupalRestApi.getToken = function () {
+ if (!$this.drupalRestApi.token || $this.drupalRestApi.token === null || $this.drupalRestApi.token === undefined) {
+ return $this.drupalRestApi.initToken();
+ } else {
+ $q.when($this.drupalRestApi.token);
+ }
+ };
+
+ $this.drupalRestApi.getStudy = function (studyId) {
+
+ return $this.drupalRestApi.getToken().then(function tokenSuccessCallback(token) {
+ var studyResource = $resource($this.drupalRestApi.host + '/study/:studyId',
+ {
+ studyId: '@studyId',
+ _format: 'hal_json'
+
+ }, {
+ get: {
+ method: 'GET',
+ isArray: false,
+ headers: {
+ 'Content-Type': 'application/hal+json',
+ 'X-CSRF-Token': token
+ }
+ }
+ });
+
+ var studyInstance = studyResource.get({studyId: studyId});
+ return studyInstance.$promise;
+
+ }, function tokenErrorCallback(response) {
+ return $q.reject(response);
+ });
+ };
+
+ // init the token
+ //$this.drupalRestApi.initToken();
+
+ $this.drupalStudyHelper = {};
+ $this.drupalStudyHelper.getIndicatorArray = function (study) {
+ if (!study || study === null || study === undefined ||
+ !study.field_indicators || study.field_indicators === null || study.field_indicators === undefined) {
+ return [];
+ } else {
+ var studyIndicators = [];
+ for(var i = 0; i < study.field_indicators.length; i++) {
+ // this is madness: parse into object and later stringify again
+ // so that it can be used by the akward ICMM library (won't touch this thing!)
+ var studyIndicator = JSON.parse(study.field_indicators[i].value);
+ studyIndicators.push(studyIndicator);
+ }
+ return studyIndicators;
+ }
+
+ };
+
+ return {
+ restApi: $this.drupalRestApi,
+ studyHelper: $this.drupalStudyHelper
+ };
+ }
+ ]);
diff --git a/karma.conf.js b/karma.conf.js
index 0e0ff63..e91665c 100644
--- a/karma.conf.js
+++ b/karma.conf.js
@@ -80,6 +80,8 @@ basePath: '',
'target/dist/scripts/services/icmmPersistanceService.js',
'target/dist/scripts/services/icmmCriteriaFunctions.js',
'target/dist/scripts/services/icmmDecisionStrategies.js',
+ 'target/dist/scripts/services/drupalService.js',
+ 'target/dist/scripts/services/drupalContextProviderDirectiveController.js',
'target/dist/bower_components/angular-mocks/angular-mocks.js',
'app/templates/criteriaEmphasesTemplate.html',
'app/templates/criteriaFunctionManagerTemplate.html',