blob: 0a20e94bda02e15a8f6b5e91265c4944373312e8 [file] [log] [blame]
/*
* 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 angular from 'angular';
import jsSHA from 'jssha/src/sha512';
import Identicon from 'identicon.js/identicon';
const CACHE_NAME = 'brooklyn-ui.icon-cache';
const MODULE_NAME = 'br.utils.icon-generator';
angular.module(MODULE_NAME, [])
.provider('iconGenerator', iconGeneratorProvider)
.provider('iconService', iconServiceProvider)
.filter('iconGeneratorPipe', ['iconGenerator', iconGeneratorPipe]);
export default MODULE_NAME;
export function iconGeneratorProvider() {
let useSessionStorage = true;
let background = [0, 0, 0, 0];
let margin = 0.2;
let size = 128;
return {
background: function (value) {
background = value;
return this;
},
margin: function (value) {
margin = value;
return this;
},
size: function (value) {
size = value;
return this;
},
disableSessionStorage: function () {
useSessionStorage = false;
return this;
},
$get: ['$cacheFactory', function ($cacheFactory) {
if (useSessionStorage && typeof(Storage) !== "undefined") {
return new IconGenerator(new SessionsStorageWrapper(CACHE_NAME), background, margin, size);
} else {
return new IconGenerator($cacheFactory.get(CACHE_NAME) || $cacheFactory(CACHE_NAME), background, margin, size);
}
}]
};
}
export function iconGeneratorPipe(iconGenerator) {
return function (input, opts) {
let field, doNotAutogenerate=false;
if (opts) {
if (typeof opts === 'string') {
field = opts;
} else {
field = opts.field;
doNotAutogenerate = opts.doNotAutogenerate;
}
}
let generateFrom = input;
if (input && typeof(input) === 'object') {
if (input.hasOwnProperty('iconUrl') && input.iconUrl) {
return input.iconUrl;
} else if (input.hasOwnProperty('links') && input.links.hasOwnProperty('iconUrl') && input.links.iconUrl) {
return input.links.iconUrl;
} else if (input.hasOwnProperty(field || 'id')) {
generateFrom = input[field || 'id'];
}
}
if (doNotAutogenerate) {
return null;
}
return iconGenerator(generateFrom);
}
}
function IconGenerator(cache, background, margin, size) {
return function (salt) {
let icon;
if (angular.isDefined(salt)) {
icon = cache.get(salt);
}
if (angular.isUndefined(icon)) {
let hash = new jsSHA('SHA-512', 'TEXT');
let options = {
background: background,
margin: margin,
size: size
};
hash.update(salt || new Date().getTime());
icon = 'data:image/png;base64,' + new Identicon(hash.getHash('HEX'), options).toString();
if (angular.isDefined(salt)) {
cache.put(salt, icon);
}
}
return icon;
}
}
export function iconServiceProvider() {
return {
$get: ['$q', '$http', 'iconGenerator', '$log', function ($q, $http, iconGenerator, $log) {
return new IconService($q, $http, iconGenerator, $log, new SessionsStorageWrapper(CACHE_NAME));
}]
}
}
function IconService($q, $http, iconGenerator, $log, cache) {
this.get = getIcon;
function getIcon(entityOrTypeId, doNotAutogenerate) {
let deferred = $q.defer();
let id;
if (typeof entityOrTypeId === 'string') {
id = entityOrTypeId;
} else if (typeof entityOrTypeId === 'object') {
if (entityOrTypeId.iconUrl) {
deferred.resolve(entityOrTypeId.iconUrl);
return deferred.promise;
}
if (entityOrTypeId.links && entityOrTypeId.links.iconUrl) {
deferred.resolve(entityOrTypeId.links.iconUrl);
return deferred.promise;
}
if (entityOrTypeId.catalogItemId) {
id = entityOrTypeId.catalogItemId;
} else if (entityOrTypeId.symbolicName) {
id = entityOrTypeId.symbolicName;
} else if (entityOrTypeId.type) {
let entity = entityOrTypeId;
id = entity.type;
if (id === 'org.apache.brooklyn.entity.stock.BasicApplication' && entity.children && entity.children.length === 1) {
id = entity.children[0].catalogItemId || entity.children[0].type;
}
}
}
let icon;
if (angular.isDefined(id)) {
icon = cache.get(id);
} else {
$log.warn('No ID found for item, cannot make icon - '+entityOrTypeId, entityOrTypeId);
deferred.reject('No ID found for item, cannot make icon - '+entityOrTypeId);
return deferred.promise;
}
if (angular.isUndefined(icon)) {
let path = id.split(':');
$http({
method: 'GET',
cache: true,
url: '/v1/catalog/entities/' + path[0] + '/' + (path[1] || 'latest')
}).then((response)=> {
if (response.data.hasOwnProperty('iconUrl')) {
icon = response.data.iconUrl;
cache.put(id, icon);
} else if (doNotAutogenerate) {
icon = null;
} else {
icon = iconGenerator(id);
}
deferred.resolve(icon)
}, ()=> {
deferred.resolve(iconGenerator(id));
});
} else {
deferred.resolve(icon);
}
return deferred.promise;
}
}
function SessionsStorageWrapper(cacheName) {
this.get = getValue;
this.put = putValue;
function getValue(key, defaultValue) {
return sessionStorage.getItem(cacheName + '.' + key) || defaultValue || undefined;
}
function putValue(key, value) {
try {
sessionStorage.setItem(cacheName + '.' + key, value);
} catch (ex) {
sessionStorage.clear();
this.putValue(key, value);
}
}
}