blob: 1db625f6b115dc9b20fd1edb971e38b36a440a33 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2008, 2017 xored software, Inc. and others.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* xored software, Inc. - initial API and Implementation (Andrei Sobolev)
*******************************************************************************/
package org.eclipse.dltk.internal.ui;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.dltk.core.SimpleClassDLTKExtensionManager;
import org.eclipse.dltk.core.SimpleDLTKExtensionManager.ElementInfo;
import org.eclipse.dltk.ui.DLTKUIPlugin;
import org.eclipse.dltk.ui.IModelCompareProvider;
import org.eclipse.dltk.ui.IModelContentProvider;
import org.eclipse.jface.viewers.ILabelProvider;
/**
* Used to provide or replace some model elements in structure model.
*/
public class UIModelProviderManager {
private static final IModelCompareProvider[] NONE_MODEL_COMPARE_PROVIDERS = new IModelCompareProvider[0];
private static final ILabelProvider[] NONE_LABEL_PROVIDERS = new ILabelProvider[0];
private static final IModelContentProvider[] NONE_MODEL_CONTENT_PROVIDERS = new IModelContentProvider[0];
private static final String REQUIRES = "requires"; //$NON-NLS-1$
private static final String ID = "id"; //$NON-NLS-1$
private static final String LANGUAGE = "language"; //$NON-NLS-1$
private static SimpleClassDLTKExtensionManager contentProviderManager = new SimpleClassDLTKExtensionManager(
DLTKUIPlugin.PLUGIN_ID + ".modelContentProvider"); //$NON-NLS-1$
private static SimpleClassDLTKExtensionManager labelProviderManager = new SimpleClassDLTKExtensionManager(
DLTKUIPlugin.PLUGIN_ID + ".modelLabelProvider"); //$NON-NLS-1$
private static SimpleClassDLTKExtensionManager compareProviderManager = new SimpleClassDLTKExtensionManager(
DLTKUIPlugin.PLUGIN_ID + ".modelCompareProvider"); //$NON-NLS-1$
private static Map<String, List<IModelContentProvider>> contentProviders = null;
private static Map<String, List<ILabelProvider>> labelProviders = null;
private static Map<String, List<IModelCompareProvider>> compareProviders = null;
public synchronized static IModelContentProvider[] getContentProviders(
String lang) {
if (contentProviders == null) {
contentProviders = initializeProviders(contentProviderManager);
}
if (lang == null) {
List<IModelContentProvider> providers = new ArrayList<>();
for (List<IModelContentProvider> elements : contentProviders
.values()) {
providers.addAll(elements);
}
return providers
.toArray(new IModelContentProvider[providers.size()]);
}
List<IModelContentProvider> result = contentProviders.get(lang);
if (result != null) {
return result.toArray(new IModelContentProvider[result.size()]);
}
return NONE_MODEL_CONTENT_PROVIDERS;
}
public synchronized static ILabelProvider[] getLabelProviders(String lang) {
if (labelProviders == null) {
labelProviders = initializeProviders(labelProviderManager);
}
if (lang == null) {
List<ILabelProvider> providers = new ArrayList<>();
for (List<ILabelProvider> elements : labelProviders.values()) {
providers.addAll(elements);
}
return providers.toArray(new ILabelProvider[providers.size()]);
}
List<ILabelProvider> result = labelProviders.get(lang);
if (result != null) {
return result.toArray(new ILabelProvider[result.size()]);
}
return NONE_LABEL_PROVIDERS;
}
public synchronized static IModelCompareProvider[] getCompareProviders(
String lang) {
if (compareProviders == null) {
compareProviders = initializeProviders(compareProviderManager);
}
if (lang == null) {
List<IModelCompareProvider> providers = new ArrayList<>();
for (List<IModelCompareProvider> elements : compareProviders
.values()) {
providers.addAll(elements);
}
return providers
.toArray(new IModelCompareProvider[providers.size()]);
}
List<IModelCompareProvider> result = compareProviders.get(lang);
if (result != null) {
return result.toArray(new IModelCompareProvider[result.size()]);
}
return NONE_MODEL_COMPARE_PROVIDERS;
}
private synchronized static <T> Map<String, List<T>> initializeProviders(
SimpleClassDLTKExtensionManager manager) {
Map<String, List<T>> providers = new HashMap<>();
ElementInfo[] infos = manager.getElementInfos();
Map<String, List<ElementInfo>> langToElementList = new HashMap<>();
// Fill element names and sort elements by language
for (int i = 0; i < infos.length; i++) {
String langauge = infos[i].getConfig().getAttribute(LANGUAGE);
List<ElementInfo> elements = langToElementList.get(langauge);
if (elements == null) {
elements = new ArrayList<>();
langToElementList.put(langauge, elements);
}
elements.add(infos[i]);
}
for (Map.Entry<String, List<ElementInfo>> entry : langToElementList
.entrySet()) {
String language = entry.getKey();
List<ElementInfo> elements = entry.getValue();
// Contains map for all ids
Set<String> allIds = new HashSet<>();
for (ElementInfo info : elements) {
allIds.add(info.getConfig().getAttribute(ID));
}
// Final IModelProvider elements
List<T> result = new ArrayList<>();
// Contains names for added elements
Set<String> added = new HashSet<>();
// Process elements and keep dependencies
List<ElementInfo> toProcess = new ArrayList<>(elements);
while (!toProcess.isEmpty()) {
ElementInfo info = toProcess.remove(0);
String requires = info.getConfig().getAttribute(REQUIRES);
if (requires == null) {
@SuppressWarnings("unchecked")
final T obj = (T) manager.getInitObject(info);
if (obj != null) {
result.add(obj);
added.add(info.getConfig().getAttribute(ID));
}
} else {
requires = requires.trim();
if (added.contains(requires)) {
@SuppressWarnings("unchecked")
final T obj = (T) manager.getInitObject(info);
if (obj != null) {
result.add(obj);
added.add(info.getConfig().getAttribute(ID));
}
} else if (allIds.contains(requires)) { // Dependency exist
// Add element to end of process
toProcess.add(info);
// FIXME check endless loops
} else {
// Dependency doesn't exists so add to results
@SuppressWarnings("unchecked")
final T obj = (T) manager.getInitObject(info);
if (obj != null) {
result.add(obj);
added.add(info.getConfig().getAttribute(ID));
}
}
}
}
providers.put(language, result);
}
return providers;
}
}