/**
* Copyright (c) 2016 committers of YAKINDU and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
* Contributors:
* committers of YAKINDU - initial API and implementation
*
*/
package org.yakindu.sct.domain.extension.impl;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ExecutionException;
import org.yakindu.sct.domain.extension.DomainStatus;
import org.yakindu.sct.domain.extension.IDomain;
import org.yakindu.sct.domain.extension.IDomainStatusProvider;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Module;
import com.google.inject.util.Modules;
/**
* @author andreas muelder - Initial contribution and API
*
*/
public class DomainImpl implements IDomain {
private String domainID;
private String name;
private String description;
private URL imagePath;
private IDomainStatusProvider statusProvider;
private Iterable<ModuleContribution> modules;
private LoadingCache<CacheKey, Injector> injectorCache;
protected static class CacheKey {
private String feature;
private String[] options;
public CacheKey(String feature, String[] options) {
this.feature = feature;
this.options = options;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((feature == null) ? 0 : feature.hashCode());
result = prime * result + Arrays.hashCode(options);
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
CacheKey other = (CacheKey) obj;
if (feature == null) {
if (other.feature != null)
return false;
} else if (!feature.equals(other.feature))
return false;
if (!Arrays.equals(options, other.options))
return false;
return true;
}
public String getFeature() {
return feature;
}
public String[] getOptions() {
return options;
}
}
public DomainImpl(String domainID, String name, String description, URL imagePath,
Iterable<ModuleContribution> modules) {
this(domainID, name, description, imagePath, modules, new IDomainStatusProvider.DefaultDomainStatusProvider());
}
public DomainImpl(String domainID, String name, String description, URL imagePath,
Iterable<ModuleContribution> modules, IDomainStatusProvider provider) {
this.domainID = domainID;
this.name = name;
this.description = description;
this.imagePath = imagePath;
this.modules = modules;
this.statusProvider = provider;
initializeCache();
}
protected void initializeCache() {
injectorCache = CacheBuilder.newBuilder().build(new CacheLoader<CacheKey, Injector>() {
@Override
public Injector load(CacheKey key) throws Exception {
return createInjector(key.getFeature(), key.getOptions());
}
});
}
@Override
public String getDomainID() {
return domainID;
}
@Override
public String getName() {
return name;
}
@Override
public String getDescription() {
return description;
}
@Override
public URL getImagePath() {
return imagePath;
}
@Override
public Injector getInjector(String feature, boolean useCache, String... options) {
if (useCache) {
try {
return injectorCache.get(new CacheKey(feature, options));
} catch (ExecutionException e) {
e.printStackTrace();
}
}
return createInjector(feature, options);
}
@Override
public Injector getInjector(String feature, String... options) {
return getInjector(feature, true, options);
}
public Injector createInjector(String feature, String... options) {
return Guice.createInjector(getModule(feature, options));
}
@Override
public Module getModule(String feature, String... options) {
List<Module> modules = new ArrayList<>();
for (ModuleContribution module : this.modules) {
if (feature.equals(module.getFeature())) {
modules.add(module.getModuleProvider().getModule(options));
}
}
Module result = Modules.combine(modules);
return result;
}
@Override
public DomainStatus getAvailabilityStatus() {
return statusProvider.getDomainStatus();
}
}