/*
* Copyright (c) 2008-2019 Emmanuel Dupuy.
* This project is distributed under the GPLv3 license.
* This is a Copyleft license that gives the user the right to use,
* copy and modify the code freely for non-commercial purposes.
*/
package org.jd.gui.service.type;
import org.jd.gui.api.model.Container;
import org.jd.gui.service.extension.ExtensionService;
import org.jd.gui.spi.TypeFactory;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class TypeFactoryService {
protected static final TypeFactoryService TYPE_FACTORY_SERVICE = new TypeFactoryService();
protected Map<String, TypeFactories> mapProviders;
public static TypeFactoryService getInstance() {
return TYPE_FACTORY_SERVICE;
}
protected TypeFactoryService() {
Collection<TypeFactory> providers = ExtensionService.getInstance().load(TypeFactory.class);
mapProviders = new HashMap<>();
for (TypeFactory provider : providers) {
for (String selector : provider.getSelectors()) {
TypeFactories typeFactories = mapProviders.get(selector);
if (typeFactories == null) {
mapProviders.put(selector, typeFactories=new TypeFactories());
}
typeFactories.add(provider);
}
}
}
public TypeFactory get(Container.Entry entry) {
TypeFactory typeFactory = get(entry.getContainer().getType(), entry);
return (typeFactory != null) ? typeFactory : get("*", entry);
}
public TypeFactory get(String containerType, Container.Entry entry) {
String path = entry.getPath();
String type = entry.isDirectory() ? "dir" : "file";
String prefix = containerType + ':' + type + ':';
TypeFactories typeFactories = mapProviders.get(prefix + path);
TypeFactory factory = null;
if (typeFactories != null) {
factory = typeFactories.match(path);
}
if (factory == null) {
int lastSlashIndex = path.lastIndexOf('/');
String name = path.substring(lastSlashIndex+1);
typeFactories = mapProviders.get(prefix + "*/" + name);
if (typeFactories != null) {
factory = typeFactories.match(path);
}
if (factory == null) {
int index = name.lastIndexOf('.');
if (index != -1) {
String extension = name.substring(index + 1);
typeFactories = mapProviders.get(prefix + "*." + extension);
if (typeFactories != null) {
factory = typeFactories.match(path);
}
}
if (factory == null) {
typeFactories = mapProviders.get(prefix + '*');
if (typeFactories != null) {
factory = typeFactories.match(path);
}
}
}
}
return factory;
}
protected static class TypeFactories {
protected HashMap<String, TypeFactory> factories = new HashMap<>();
protected TypeFactory defaultFactory;
public void add(TypeFactory factory) {
Pattern pathPattern = factory.getPathPattern();
if (pathPattern != null) {
factories.put(pathPattern.pattern(), factory);
} else {
defaultFactory = factory;
}
}
public TypeFactory match(String path) {
for (TypeFactory factory : factories.values()) {
Matcher matcher = factory.getPathPattern().matcher(path);
if (matcher.matches()) {
return factory;
}
}
return defaultFactory;
}
}
}